From bf0ea33de65075db5d6abd0fe99639fe2378d238 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 29 Jun 2019 16:55:36 +1000 Subject: [PATCH] SPIGOT-5105: The EntityTag nbt tag disappears from preset armor_stand items. --- .../inventory/CraftItemFactory.java | 2 + .../craftbukkit/inventory/CraftItemStack.java | 2 + .../inventory/CraftMetaArmorStand.java | 123 ++++++++++++++++++ .../craftbukkit/inventory/ItemMetaTest.java | 10 ++ 4 files changed, 137 insertions(+) create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 133a80ee0..e3bb1dffd 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -199,6 +199,8 @@ public final class CraftItemFactory implements ItemFactory { case ZOMBIE_SPAWN_EGG: case ZOMBIE_VILLAGER_SPAWN_EGG: return meta instanceof CraftMetaSpawnEgg ? meta : new CraftMetaSpawnEgg(meta); + case ARMOR_STAND: + return meta instanceof CraftMetaArmorStand ? meta : new CraftMetaArmorStand(meta); case KNOWLEDGE_BOOK: return meta instanceof CraftMetaKnowledgeBook ? meta : new CraftMetaKnowledgeBook(meta); case FURNACE: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 2a9e2ab58..c3a3fbde0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -450,6 +450,8 @@ public final class CraftItemStack extends ItemStack { case ZOMBIE_SPAWN_EGG: case ZOMBIE_VILLAGER_SPAWN_EGG: return new CraftMetaSpawnEgg(item.getTag()); + case ARMOR_STAND: + return new CraftMetaArmorStand(item.getTag()); case KNOWLEDGE_BOOK: return new CraftMetaKnowledgeBook(item.getTag()); case FURNACE: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java new file mode 100644 index 000000000..f70052284 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java @@ -0,0 +1,123 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.collect.ImmutableMap.Builder; +import java.util.Map; +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaArmorStand extends CraftMetaItem { + + static final ItemMetaKey ENTITY_TAG = new ItemMetaKey("EntityTag", "entity-tag"); + NBTTagCompound entityTag; + + CraftMetaArmorStand(CraftMetaItem meta) { + super(meta); + } + + CraftMetaArmorStand(NBTTagCompound tag) { + super(tag); + + if (tag.hasKey(ENTITY_TAG.NBT)) { + entityTag = tag.getCompound(ENTITY_TAG.NBT); + } + } + + CraftMetaArmorStand(Map map) { + super(map); + } + + @Override + void deserializeInternal(NBTTagCompound tag, Object context) { + super.deserializeInternal(tag, context); + + if (tag.hasKey(ENTITY_TAG.NBT)) { + entityTag = tag.getCompound(ENTITY_TAG.NBT); + } + } + + @Override + void serializeInternal(Map internalTags) { + if (entityTag != null && !entityTag.isEmpty()) { + internalTags.put(ENTITY_TAG.NBT, entityTag); + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + if (entityTag != null) { + tag.set(ENTITY_TAG.NBT, entityTag); + } + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case ARMOR_STAND: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isArmorStandEmpty(); + } + + boolean isArmorStandEmpty() { + return !(entityTag != null); + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaArmorStand) { + CraftMetaArmorStand that = (CraftMetaArmorStand) meta; + + return entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : entityTag == null; + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaArmorStand || isArmorStandEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (entityTag != null) { + hash = 73 * hash + entityTag.hashCode(); + } + + return original != hash ? CraftMetaArmorStand.class.hashCode() ^ hash : hash; + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + return builder; + } + + @Override + public CraftMetaArmorStand clone() { + CraftMetaArmorStand clone = (CraftMetaArmorStand) super.clone(); + + if (entityTag != null) { + clone.entityTag = entityTag.clone(); + } + + return clone; + } +} diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java index 6abde9030..dd4ba3874 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java +++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java @@ -12,6 +12,7 @@ import net.minecraft.server.ITileEntity; import net.minecraft.server.Item; import net.minecraft.server.ItemBlock; import net.minecraft.server.ItemBlockWallable; +import net.minecraft.server.NBTTagCompound; import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.DyeColor; @@ -344,6 +345,15 @@ public class ItemMetaTest extends AbstractTestingBase { cleanStack.setItemMeta(meta); return cleanStack; } + }, + new StackProvider(Material.ARMOR_STAND) { + @Override ItemStack operate(ItemStack cleanStack) { + final CraftMetaArmorStand meta = (CraftMetaArmorStand) cleanStack.getItemMeta(); + meta.entityTag = new NBTTagCompound(); + meta.entityTag.setBoolean("Small", true); + cleanStack.setItemMeta(meta); + return cleanStack; + } } );