Ensure blockmap uniqueness across TE values

This commit is contained in:
Alexander Brandes 2023-05-20 21:00:35 +02:00
parent 7f43e448d5
commit 5e3222c55d
No known key found for this signature in database
GPG Key ID: 158F5701A6AAD00C
2 changed files with 21 additions and 1 deletions

View File

@ -170,7 +170,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
return old;
}
int oldId = commonMap.put(key, internalId);
return assumeAsBlock(oldId);
return BlockStateIdAccess.isValidInternalId(oldId) ? assumeAsBlock(oldId) : uncommonMap.remove(key);
}
@Override

View File

@ -21,6 +21,8 @@
package com.sk89q.worldedit.util.collection;
import com.google.common.collect.ImmutableMap;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.platform.PlatformsRegisteredEvent;
import com.sk89q.worldedit.extension.platform.Capability;
@ -100,6 +102,7 @@ class BlockMapTest {
registerBlock("minecraft:air");
registerBlock("minecraft:oak_wood");
registerBlock("minecraft:chest");
}
@AfterAll
@ -123,6 +126,7 @@ class BlockMapTest {
private final BaseBlock air = checkNotNull(BlockTypes.AIR).getDefaultState().toBaseBlock();
private final BaseBlock oakWood = checkNotNull(BlockTypes.OAK_WOOD).getDefaultState().toBaseBlock();
private final BaseBlock chestWithNbt = checkNotNull(BlockTypes.CHEST).getDefaultState().toBaseBlock(new CompoundTag(ImmutableMap.of("dummy", new StringTag("value"))));
private AutoCloseable mocks;
@ -748,6 +752,22 @@ class BlockMapTest {
});
}
@SuppressWarnings("OverwrittenKey")
@Test
@DisplayName("put with valid and invalid keys doesn't duplicate")
void putWithInvalidAndValid() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
// This tests https://github.com/EngineHub/WorldEdit/issues/2250
// Due to two internal maps, a bug existed where both could have the same value
map.put(vec, chestWithNbt);
map.put(vec, air);
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
});
}
}
@Test