#639: Deep clone itemmetas persistent container on clone

After this commit, spigot now creates a deep copy of the
itemmeta's persistent data container when the itemmeta
instance is cloned.

This change fixes the bug that, after cloning itemmeta, the container
instance the cloned meta would point to was equal to the original one.
This resulted in two itemmeta instances sharing a single persistent
container.
This commit is contained in:
Bjarne Koll 2020-03-01 17:23:54 +01:00 committed by md_5
parent 3d61a853e3
commit 6b00b14539
2 changed files with 18 additions and 1 deletions

View File

@ -279,7 +279,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
private NBTTagCompound internalTag;
private final Map<String, NBTBase> unhandledTags = new HashMap<String, NBTBase>();
private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
private CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
private int version = CraftMagicNumbers.INSTANCE.getDataVersion(); // Internal use only
@ -1197,6 +1197,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (this.hasAttributeModifiers()) {
clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers);
}
clone.persistentDataContainer = new CraftPersistentDataContainer(this.persistentDataContainer.getRaw(), DATA_TYPE_REGISTRY);
clone.hideFlag = this.hideFlag;
clone.unbreakable = this.unbreakable;
clone.damage = this.damage;

View File

@ -310,4 +310,20 @@ public class PersistentDataContainerTest extends AbstractTestingBase {
return primitive;
}
}
@Test
public void testItemMetaClone() {
ItemMeta itemMeta = createNewItemMeta();
PersistentDataContainer container = itemMeta.getPersistentDataContainer();
itemMeta.getPersistentDataContainer().set(VALID_KEY, PersistentDataType.STRING, "notch");
ItemMeta clonedMeta = itemMeta.clone();
PersistentDataContainer clonedContainer = clonedMeta.getPersistentDataContainer();
assertNotSame(container, clonedContainer);
assertEquals(container, clonedContainer);
clonedContainer.set(VALID_KEY, PersistentDataType.STRING, "dinnerbone");
assertNotEquals(container, clonedContainer);
}
}