From ae4acc6aeb299c7d9dd0bed182611cd5f05eaea1 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 10 Jul 2023 16:10:15 -0700 Subject: [PATCH] improve checking handled tags in itemmeta --- .../craftbukkit/inventory/CraftItemMetas.java | 58 +++---- .../craftbukkit/inventory/CraftItemStack.java | 25 ++- .../craftbukkit/inventory/CraftItemType.java | 4 +- .../craftbukkit/inventory/CraftMetaArmor.java | 4 +- .../inventory/CraftMetaArmorStand.java | 4 +- .../inventory/CraftMetaAxolotlBucket.java | 4 +- .../inventory/CraftMetaBanner.java | 4 +- .../inventory/CraftMetaBlockState.java | 4 +- .../craftbukkit/inventory/CraftMetaBook.java | 4 +- .../inventory/CraftMetaBookSigned.java | 4 +- .../inventory/CraftMetaBundle.java | 4 +- .../inventory/CraftMetaCharge.java | 4 +- .../inventory/CraftMetaColorableArmor.java | 4 +- .../inventory/CraftMetaCompass.java | 4 +- .../inventory/CraftMetaCrossbow.java | 4 +- .../inventory/CraftMetaEnchantedBook.java | 4 +- .../inventory/CraftMetaEntityTag.java | 4 +- .../inventory/CraftMetaFirework.java | 4 +- .../craftbukkit/inventory/CraftMetaItem.java | 151 ++++++++++-------- .../inventory/CraftMetaKnowledgeBook.java | 4 +- .../inventory/CraftMetaLeatherArmor.java | 4 +- .../craftbukkit/inventory/CraftMetaMap.java | 4 +- .../inventory/CraftMetaMusicInstrument.java | 4 +- .../inventory/CraftMetaOminousBottle.java | 4 +- .../inventory/CraftMetaPotion.java | 4 +- .../inventory/CraftMetaShield.java | 4 +- .../craftbukkit/inventory/CraftMetaSkull.java | 4 +- .../inventory/CraftMetaSpawnEgg.java | 4 +- .../inventory/CraftMetaSuspiciousStew.java | 4 +- .../CraftMetaTropicalFishBucket.java | 4 +- .../DeprecatedItemMetaCustomValueTest.java | 2 +- .../inventory/MetaHandledTagsTest.java | 33 ++++ .../PersistentDataContainerTest.java | 6 +- 33 files changed, 225 insertions(+), 158 deletions(-) create mode 100644 paper-server/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java index d29f4dd980..1fd6e5a1ad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java @@ -40,120 +40,120 @@ import org.bukkit.inventory.meta.TropicalFishBucketMeta; public final class CraftItemMetas { - public record ItemMetaData(Class metaClass, Function fromItemStack, + public record ItemMetaData(Class metaClass, BiFunction>, I> fromItemStack, BiFunction, CraftMetaItem, I> fromItemMeta) { } private static final ItemMetaData EMPTY_META_DATA = new ItemMetaData<>(ItemMeta.class, - item -> null, + (item, extras) -> null, (type, meta) -> null); private static final ItemMetaData ITEM_META_DATA = new ItemMetaData<>(ItemMeta.class, - item -> new CraftMetaItem(item.getComponentsPatch()), + (item, extras) -> new CraftMetaItem(item.getComponentsPatch(), extras), (type, meta) -> new CraftMetaItem(meta)); private static final ItemMetaData SIGNED_BOOK_META_DATA = new ItemMetaData<>(BookMeta.class, - item -> new CraftMetaBookSigned(item.getComponentsPatch()), + (item, extras) -> new CraftMetaBookSigned(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaBookSigned signed ? signed : new CraftMetaBookSigned(meta)); private static final ItemMetaData WRITABLE_BOOK_META_DATA = new ItemMetaData<>(BookMeta.class, - item -> new CraftMetaBook(item.getComponentsPatch()), + (item, extras) -> new CraftMetaBook(item.getComponentsPatch(), extras), (type, meta) -> meta != null && meta.getClass().equals(CraftMetaBook.class) ? (BookMeta) meta : new CraftMetaBook(meta)); private static final ItemMetaData SKULL_META_DATA = new ItemMetaData<>(SkullMeta.class, - item -> new CraftMetaSkull(item.getComponentsPatch()), + (item, extras) -> new CraftMetaSkull(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaSkull skull ? skull : new CraftMetaSkull(meta)); private static final ItemMetaData ARMOR_META_DATA = new ItemMetaData<>(ArmorMeta.class, - item -> new CraftMetaArmor(item.getComponentsPatch()), + (item, extras) -> new CraftMetaArmor(item.getComponentsPatch(), extras), (type, meta) -> meta != null && meta.getClass().equals(CraftMetaArmor.class) ? (ArmorMeta) meta : new CraftMetaArmor(meta)); private static final ItemMetaData COLORABLE_ARMOR_META_DATA = new ItemMetaData<>(ColorableArmorMeta.class, - item -> new CraftMetaColorableArmor(item.getComponentsPatch()), + (item, extras) -> new CraftMetaColorableArmor(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof ColorableArmorMeta colorable ? colorable : new CraftMetaColorableArmor(meta)); private static final ItemMetaData LEATHER_ARMOR_META_DATA = new ItemMetaData<>(LeatherArmorMeta.class, - item -> new CraftMetaLeatherArmor(item.getComponentsPatch()), + (item, extras) -> new CraftMetaLeatherArmor(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaLeatherArmor leather ? leather : new CraftMetaLeatherArmor(meta)); private static final ItemMetaData POTION_META_DATA = new ItemMetaData<>(PotionMeta.class, - item -> new CraftMetaPotion(item.getComponentsPatch()), + (item, extras) -> new CraftMetaPotion(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaPotion potion ? potion : new CraftMetaPotion(meta)); private static final ItemMetaData MAP_META_DATA = new ItemMetaData<>(MapMeta.class, - item -> new CraftMetaMap(item.getComponentsPatch()), + (item, extras) -> new CraftMetaMap(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaMap map ? map : new CraftMetaMap(meta)); private static final ItemMetaData FIREWORK_META_DATA = new ItemMetaData<>(FireworkMeta.class, - item -> new CraftMetaFirework(item.getComponentsPatch()), + (item, extras) -> new CraftMetaFirework(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaFirework firework ? firework : new CraftMetaFirework(meta)); private static final ItemMetaData CHARGE_META_DATA = new ItemMetaData<>(FireworkEffectMeta.class, - item -> new CraftMetaCharge(item.getComponentsPatch()), + (item, extras) -> new CraftMetaCharge(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaCharge charge ? charge : new CraftMetaCharge(meta)); private static final ItemMetaData ENCHANTED_BOOK_META_DATA = new ItemMetaData<>(EnchantmentStorageMeta.class, - item -> new CraftMetaEnchantedBook(item.getComponentsPatch()), + (item, extras) -> new CraftMetaEnchantedBook(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaEnchantedBook enchantedBook ? enchantedBook : new CraftMetaEnchantedBook(meta)); private static final ItemMetaData BANNER_META_DATA = new ItemMetaData<>(BannerMeta.class, - item -> new CraftMetaBanner(item.getComponentsPatch()), + (item, extras) -> new CraftMetaBanner(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaBanner banner ? banner : new CraftMetaBanner(meta)); private static final ItemMetaData SPAWN_EGG_META_DATA = new ItemMetaData<>(SpawnEggMeta.class, - item -> new CraftMetaSpawnEgg(item.getComponentsPatch()), + (item, extras) -> new CraftMetaSpawnEgg(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaSpawnEgg spawnEgg ? spawnEgg : new CraftMetaSpawnEgg(meta)); private static final ItemMetaData ARMOR_STAND_META_DATA = new ItemMetaData<>(ArmorStandMeta.class, // paper - item -> new CraftMetaArmorStand(item.getComponentsPatch()), + (item, extras) -> new CraftMetaArmorStand(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaArmorStand armorStand ? armorStand : new CraftMetaArmorStand(meta)); private static final ItemMetaData KNOWLEDGE_BOOK_META_DATA = new ItemMetaData<>(KnowledgeBookMeta.class, - item -> new CraftMetaKnowledgeBook(item.getComponentsPatch()), + (item, extras) -> new CraftMetaKnowledgeBook(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaKnowledgeBook knowledgeBook ? knowledgeBook : new CraftMetaKnowledgeBook(meta)); private static final ItemMetaData BLOCK_STATE_META_DATA = new ItemMetaData<>(BlockStateMeta.class, - item -> new CraftMetaBlockState(item.getComponentsPatch(), CraftItemType.minecraftToBukkit(item.getItem())), + (item, extras) -> new CraftMetaBlockState(item.getComponentsPatch(), CraftItemType.minecraftToBukkit(item.getItem()), extras), (type, meta) -> new CraftMetaBlockState(meta, type.asMaterial())); private static final ItemMetaData SHIELD_META_DATA = new ItemMetaData<>(ShieldMeta.class, - item -> new CraftMetaShield(item.getComponentsPatch()), + (item, extras) -> new CraftMetaShield(item.getComponentsPatch(), extras), (type, meta) -> new CraftMetaShield(meta)); private static final ItemMetaData TROPICAL_FISH_BUCKET_META_DATA = new ItemMetaData<>(TropicalFishBucketMeta.class, - item -> new CraftMetaTropicalFishBucket(item.getComponentsPatch()), + (item, extras) -> new CraftMetaTropicalFishBucket(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaTropicalFishBucket tropicalFishBucket ? tropicalFishBucket : new CraftMetaTropicalFishBucket(meta)); private static final ItemMetaData AXOLOTL_BUCKET_META_DATA = new ItemMetaData<>(AxolotlBucketMeta.class, - item -> new CraftMetaAxolotlBucket(item.getComponentsPatch()), + (item, extras) -> new CraftMetaAxolotlBucket(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaAxolotlBucket axolotlBucket ? axolotlBucket : new CraftMetaAxolotlBucket(meta)); private static final ItemMetaData CROSSBOW_META_DATA = new ItemMetaData<>(CrossbowMeta.class, - item -> new CraftMetaCrossbow(item.getComponentsPatch()), + (item, extras) -> new CraftMetaCrossbow(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaCrossbow crossbow ? crossbow : new CraftMetaCrossbow(meta)); private static final ItemMetaData SUSPICIOUS_STEW_META_DATA = new ItemMetaData<>(SuspiciousStewMeta.class, - item -> new CraftMetaSuspiciousStew(item.getComponentsPatch()), + (item, extras) -> new CraftMetaSuspiciousStew(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaSuspiciousStew suspiciousStew ? suspiciousStew : new CraftMetaSuspiciousStew(meta)); private static final ItemMetaData ENTITY_TAG_META_DATA = new ItemMetaData<>(ItemMeta.class, - item -> new CraftMetaEntityTag(item.getComponentsPatch()), + (item, extras) -> new CraftMetaEntityTag(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaEntityTag entityTag ? entityTag : new CraftMetaEntityTag(meta)); private static final ItemMetaData COMPASS_META_DATA = new ItemMetaData<>(CompassMeta.class, - item -> new CraftMetaCompass(item.getComponentsPatch()), + (item, extras) -> new CraftMetaCompass(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaCompass compass ? compass : new CraftMetaCompass(meta)); private static final ItemMetaData BUNDLE_META_DATA = new ItemMetaData<>(BundleMeta.class, - item -> new CraftMetaBundle(item.getComponentsPatch()), + (item, extras) -> new CraftMetaBundle(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaBundle bundle ? bundle : new CraftMetaBundle(meta)); private static final ItemMetaData MUSIC_INSTRUMENT_META_DATA = new ItemMetaData<>(MusicInstrumentMeta.class, - item -> new CraftMetaMusicInstrument(item.getComponentsPatch()), + (item, extras) -> new CraftMetaMusicInstrument(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaMusicInstrument musicInstrument ? musicInstrument : new CraftMetaMusicInstrument(meta)); private static final ItemMetaData OMINOUS_BOTTLE_META_DATA = new ItemMetaData<>(OminousBottleMeta.class, - item -> new CraftMetaOminousBottle(item.getComponentsPatch()), + (item, extras) -> new CraftMetaOminousBottle(item.getComponentsPatch(), extras), (type, meta) -> meta instanceof CraftMetaOminousBottle musicInstrument ? musicInstrument : new CraftMetaOminousBottle(meta)); // We use if instead of a set, since the result gets cached in CraftItemType, diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 7228d43d33..dfdabf8643 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -173,10 +173,11 @@ public final class CraftItemStack extends ItemStack { } else if (this.handle == null) { this.handle = new net.minecraft.world.item.ItemStack(CraftItemType.bukkitToMinecraft(type), 1); } else { + final Material oldType = CraftMagicNumbers.getMaterial(this.handle.getItem()); // Paper this.handle.setItem(CraftItemType.bukkitToMinecraft(type)); if (this.hasItemMeta()) { // This will create the appropriate item meta, which will contain all the data we intend to keep - CraftItemStack.setItemMeta(this.handle, CraftItemStack.getItemMeta(this.handle)); + this.adjustTagForItemMeta(oldType); // Paper } } this.setData(null); @@ -337,6 +338,19 @@ public final class CraftItemStack extends ItemStack { public ItemMeta getItemMeta() { return CraftItemStack.getItemMeta(this.handle); } + // Paper start - improve handled tags on type change + public void adjustTagForItemMeta(final Material oldType) { + final CraftMetaItem oldMeta = (CraftMetaItem) CraftItemFactory.instance().getItemMeta(oldType); + final ItemMeta newMeta; + if (oldMeta == null) { + newMeta = getItemMeta(this.handle); + } else { + final java.util.Set> extraHandledDcts = new java.util.HashSet<>(CraftMetaItem.getTopLevelHandledDcts(oldMeta.getClass())); + newMeta = getItemMeta(this.handle, CraftItemType.minecraftToBukkitNew(this.handle.getItem()), extraHandledDcts); + } + this.setItemMeta(newMeta); + } + // Paper end - improve handled tags on type change // Paper start public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta itemMeta) { final CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator(); @@ -349,12 +363,17 @@ public final class CraftItemStack extends ItemStack { } public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, org.bukkit.inventory.ItemType metaForType) { // Paper end + // Paper start - handled tags on type change + return getItemMeta(item, metaForType, null); + } + public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, org.bukkit.inventory.ItemType metaForType, final java.util.Set> extraHandledDcts) { + // Paper end - handled tags on type change if (!CraftItemStack.hasItemMeta(item)) { return CraftItemFactory.instance().getItemMeta(CraftItemStack.getType(item)); } - if (metaForType != null) { return ((CraftItemType) metaForType).getItemMeta(item); } // Paper - return ((CraftItemType) CraftItemType.minecraftToBukkitNew(item.getItem())).getItemMeta(item); + if (metaForType != null) { return ((CraftItemType) metaForType).getItemMeta(item, extraHandledDcts); } // Paper + return ((CraftItemType) CraftItemType.minecraftToBukkitNew(item.getItem())).getItemMeta(item, extraHandledDcts); // Paper } static Material getType(net.minecraft.world.item.ItemStack item) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java index 6d76cc1db3..f4a6ee6dfc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java @@ -114,8 +114,8 @@ public class CraftItemType implements ItemType.Typed, Han return this.item; } - public M getItemMeta(net.minecraft.world.item.ItemStack itemStack) { - return this.itemMetaData.get().fromItemStack().apply(itemStack); + public M getItemMeta(net.minecraft.world.item.ItemStack itemStack, final java.util.Set> extraHandledDcts) { + return this.itemMetaData.get().fromItemStack().apply(itemStack, extraHandledDcts); } public M getItemMeta(ItemMeta itemMeta) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java index 0fdd9dd475..6532bdaf6c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java @@ -34,8 +34,8 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { } } - CraftMetaArmor(DataComponentPatch tag) { - super(tag); + CraftMetaArmor(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaArmor.TRIM).ifPresent((trimCompound) -> { TrimMaterial trimMaterial = CraftTrimMaterial.minecraftHolderToBukkit(trimCompound.material()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java index ecce5d0da9..00b5c4ab61 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java @@ -35,8 +35,8 @@ public class CraftMetaArmorStand extends CraftMetaItem implements com.destroysto this.entityTag = armorStand.entityTag; } - CraftMetaArmorStand(DataComponentPatch tag) { - super(tag); + CraftMetaArmorStand(DataComponentPatch tag, final java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaArmorStand.ENTITY_TAG).ifPresent((nbt) -> { this.entityTag = nbt.copyTag(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java index c4beb94d8e..169fefb64e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java @@ -36,8 +36,8 @@ public class CraftMetaAxolotlBucket extends CraftMetaItem implements AxolotlBuck this.bucketEntityTag = bucket.bucketEntityTag; } - CraftMetaAxolotlBucket(DataComponentPatch tag) { - super(tag); + CraftMetaAxolotlBucket(DataComponentPatch tag, final java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaAxolotlBucket.ENTITY_TAG).ifPresent((nbt) -> { this.entityTag = nbt.copyTag(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java index eb44c19f6a..d0a8cd89da 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java @@ -34,8 +34,8 @@ public class CraftMetaBanner extends CraftMetaItem implements BannerMeta { this.patterns = new ArrayList(banner.patterns); } - CraftMetaBanner(DataComponentPatch tag) { - super(tag); + CraftMetaBanner(DataComponentPatch tag, final java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaBanner.PATTERNS).ifPresent((entityTag) -> { List patterns = entityTag.layers(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java index 3985e5b4e2..413e41f113 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -73,8 +73,8 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta this.position = te.position; } - CraftMetaBlockState(DataComponentPatch tag, Material material) { - super(tag); + CraftMetaBlockState(DataComponentPatch tag, Material material, final Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper this.material = material; getOrEmpty(tag, CraftMetaBlockState.BLOCK_ENTITY_TAG).ifPresent((blockTag) -> { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java index 32e5188442..257c835bc2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java @@ -64,8 +64,8 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta, WritableBo } } - CraftMetaBook(DataComponentPatch tag) { - super(tag); + CraftMetaBook(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaBook.BOOK_CONTENT).ifPresent((writable) -> { List> pages = writable.pages(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java index fd3b12477c..cbb3d80cc7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java @@ -78,8 +78,8 @@ public class CraftMetaBookSigned extends CraftMetaItem implements BookMeta { } } - CraftMetaBookSigned(DataComponentPatch tag) { - super(tag); + CraftMetaBookSigned(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaBookSigned.BOOK_CONTENT).ifPresent((written) -> { this.title = written.title().raw(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java index 30533ce683..2736a87a6c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java @@ -34,8 +34,8 @@ public class CraftMetaBundle extends CraftMetaItem implements BundleMeta { } } - CraftMetaBundle(DataComponentPatch tag) { - super(tag); + CraftMetaBundle(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaBundle.ITEMS).ifPresent((bundle) -> { bundle.items().forEach((item) -> { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java index 72340e7269..56c6784e29 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java @@ -29,8 +29,8 @@ class CraftMetaCharge extends CraftMetaItem implements FireworkEffectMeta { this.setEffect(SerializableMeta.getObject(FireworkEffect.class, map, CraftMetaCharge.EXPLOSION.BUKKIT, true)); } - CraftMetaCharge(DataComponentPatch tag) { - super(tag); + CraftMetaCharge(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaCharge.EXPLOSION).ifPresent((f) -> { try { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java index 366fec1aee..6517ec4933 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java @@ -18,8 +18,8 @@ public class CraftMetaColorableArmor extends CraftMetaArmor implements Colorable CraftMetaLeatherArmor.readColor(this, meta); } - CraftMetaColorableArmor(DataComponentPatch tag) { - super(tag); + CraftMetaColorableArmor(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper CraftMetaLeatherArmor.readColor(this, tag); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java index 607e230403..69a112b3a9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java @@ -50,8 +50,8 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { this.tracked = compassMeta.tracked; } - CraftMetaCompass(DataComponentPatch tag) { - super(tag); + CraftMetaCompass(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaCompass.LODESTONE_TARGET).ifPresent((lodestoneTarget) -> { lodestoneTarget.target().ifPresent((target) -> { this.lodestoneWorld = target.dimension(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java index c278af5193..0807c2172c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java @@ -36,8 +36,8 @@ public class CraftMetaCrossbow extends CraftMetaItem implements CrossbowMeta { } } - CraftMetaCrossbow(DataComponentPatch tag) { - super(tag); + CraftMetaCrossbow(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaCrossbow.CHARGED_PROJECTILES).ifPresent((p) -> { List list = p.getItems(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java index 19af55ec2b..c93f769ee6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java @@ -32,8 +32,8 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage } } - CraftMetaEnchantedBook(DataComponentPatch tag) { - super(tag); + CraftMetaEnchantedBook(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS).ifPresent((itemEnchantments) -> { this.enchantments = buildEnchantments(itemEnchantments); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java index 3ff0340c40..3f6c5cbbf6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java @@ -39,8 +39,8 @@ public class CraftMetaEntityTag extends CraftMetaItem { this.entityTag = entity.entityTag; } - CraftMetaEntityTag(DataComponentPatch tag) { - super(tag); + CraftMetaEntityTag(DataComponentPatch tag, final java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaEntityTag.ENTITY_TAG).ifPresent((nbt) -> { this.entityTag = nbt.copyTag(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java index 4941e0afff..566d893a41 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java @@ -60,8 +60,8 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { } } - CraftMetaFirework(DataComponentPatch tag) { - super(tag); + CraftMetaFirework(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaFirework.FIREWORKS).ifPresent((fireworks) -> { this.power = fireworks.flightDuration(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index cf85cd7426..22f2376365 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -393,7 +393,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper end } - CraftMetaItem(DataComponentPatch tag) { + CraftMetaItem(DataComponentPatch tag, Set> extraHandledTags) { // Paper - improve handled tags on type changes CraftMetaItem.getOrEmpty(tag, CraftMetaItem.NAME).ifPresent((component) -> { this.displayName = component; }); @@ -525,9 +525,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { }); // Paper end - fix ItemFlags + // Paper start - improve checking handled data component types + Set> handledTags = getTopLevelHandledDcts(this.getClass()); + if (extraHandledTags != null) { + extraHandledTags.addAll(handledTags); + handledTags = extraHandledTags; + } + // Paper end - improve checking handled data component types Set, Optional>> keys = tag.entrySet(); for (Map.Entry, Optional> key : keys) { - if (!CraftMetaItem.getHandledTags().contains(key.getKey())) { + if (!handledTags.contains(key.getKey())) { // Paper - improve checking handled data component types key.getValue().ifPresent((value) -> { this.unhandledTags.set((DataComponentType) key.getKey(), value); }); @@ -2372,75 +2379,83 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.version = version; } - public static Set getHandledTags() { - synchronized (CraftMetaItem.HANDLED_TAGS) { - if (CraftMetaItem.HANDLED_TAGS.isEmpty()) { - CraftMetaItem.HANDLED_TAGS.addAll(Arrays.asList( - CraftMetaItem.NAME.TYPE, - CraftMetaItem.ITEM_NAME.TYPE, - CraftMetaItem.LORE.TYPE, - CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, - CraftMetaItem.ENCHANTABLE.TYPE, - CraftMetaItem.BLOCK_DATA.TYPE, - CraftMetaItem.REPAIR.TYPE, - CraftMetaItem.ENCHANTMENTS.TYPE, - CraftMetaItem.HIDE_ADDITIONAL_TOOLTIP.TYPE, - CraftMetaItem.HIDE_TOOLTIP.TYPE, - CraftMetaItem.TOOLTIP_STYLE.TYPE, - CraftMetaItem.ITEM_MODEL.TYPE, - CraftMetaItem.UNBREAKABLE.TYPE, - CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE, - CraftMetaItem.GLIDER.TYPE, - CraftMetaItem.DAMAGE_RESISTANT.TYPE, - CraftMetaItem.MAX_STACK_SIZE.TYPE, - CraftMetaItem.RARITY.TYPE, - CraftMetaItem.USE_REMAINDER.TYPE, - CraftMetaItem.USE_COOLDOWN.TYPE, - CraftMetaItem.FOOD.TYPE, - CraftMetaItem.TOOL.TYPE, - CraftMetaItem.EQUIPPABLE.TYPE, - CraftMetaItem.JUKEBOX_PLAYABLE.TYPE, - CraftMetaItem.DAMAGE.TYPE, - CraftMetaItem.MAX_DAMAGE.TYPE, - CraftMetaItem.CUSTOM_DATA.TYPE, - CraftMetaItem.ATTRIBUTES.TYPE, - CraftMetaItem.CAN_PLACE_ON.TYPE, // Paper - CraftMetaItem.CAN_BREAK.TYPE, // Paper - CraftMetaArmor.TRIM.TYPE, - CraftMetaArmorStand.ENTITY_TAG.TYPE, - CraftMetaBanner.PATTERNS.TYPE, - CraftMetaEntityTag.ENTITY_TAG.TYPE, - CraftMetaLeatherArmor.COLOR.TYPE, - CraftMetaMap.MAP_POST_PROCESSING.TYPE, - CraftMetaMap.MAP_COLOR.TYPE, - CraftMetaMap.MAP_ID.TYPE, - CraftMetaPotion.POTION_CONTENTS.TYPE, - CraftMetaShield.BASE_COLOR.TYPE, - CraftMetaSkull.SKULL_PROFILE.TYPE, - CraftMetaSkull.NOTE_BLOCK_SOUND.TYPE, - CraftMetaSpawnEgg.ENTITY_TAG.TYPE, - CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE, - CraftMetaBook.BOOK_CONTENT.TYPE, - CraftMetaBookSigned.BOOK_CONTENT.TYPE, - CraftMetaFirework.FIREWORKS.TYPE, - CraftMetaEnchantedBook.STORED_ENCHANTMENTS.TYPE, - CraftMetaCharge.EXPLOSION.TYPE, - CraftMetaKnowledgeBook.BOOK_RECIPES.TYPE, - CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE, - CraftMetaTropicalFishBucket.BUCKET_ENTITY_TAG.TYPE, - CraftMetaAxolotlBucket.ENTITY_TAG.TYPE, - CraftMetaAxolotlBucket.BUCKET_ENTITY_TAG.TYPE, - CraftMetaCrossbow.CHARGED_PROJECTILES.TYPE, - CraftMetaSuspiciousStew.EFFECTS.TYPE, - CraftMetaCompass.LODESTONE_TARGET.TYPE, - CraftMetaBundle.ITEMS.TYPE, - CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.TYPE, - CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER.TYPE - )); + // Paper start - improve checking handled tags + @org.jetbrains.annotations.VisibleForTesting + public static final Map, Set>> HANDLED_DCTS_PER_TYPE = new HashMap<>(); + private static final Set> DEFAULT_HANDLED_DCTS = Set.of( + CraftMetaItem.NAME.TYPE, + CraftMetaItem.ITEM_NAME.TYPE, + CraftMetaItem.LORE.TYPE, + CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, + CraftMetaItem.ENCHANTABLE.TYPE, + CraftMetaItem.BLOCK_DATA.TYPE, + CraftMetaItem.REPAIR.TYPE, + CraftMetaItem.ENCHANTMENTS.TYPE, + CraftMetaItem.HIDE_ADDITIONAL_TOOLTIP.TYPE, + CraftMetaItem.HIDE_TOOLTIP.TYPE, + CraftMetaItem.TOOLTIP_STYLE.TYPE, + CraftMetaItem.ITEM_MODEL.TYPE, + CraftMetaItem.UNBREAKABLE.TYPE, + CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE, + CraftMetaItem.GLIDER.TYPE, + CraftMetaItem.DAMAGE_RESISTANT.TYPE, + CraftMetaItem.MAX_STACK_SIZE.TYPE, + CraftMetaItem.RARITY.TYPE, + CraftMetaItem.USE_REMAINDER.TYPE, + CraftMetaItem.USE_COOLDOWN.TYPE, + CraftMetaItem.FOOD.TYPE, + CraftMetaItem.TOOL.TYPE, + CraftMetaItem.EQUIPPABLE.TYPE, + CraftMetaItem.JUKEBOX_PLAYABLE.TYPE, + CraftMetaItem.DAMAGE.TYPE, + CraftMetaItem.MAX_DAMAGE.TYPE, + CraftMetaItem.CUSTOM_DATA.TYPE, + CraftMetaItem.ATTRIBUTES.TYPE, + CraftMetaItem.CAN_PLACE_ON.TYPE, // Paper + CraftMetaItem.CAN_BREAK.TYPE // Paper + ); + public static Set> getTopLevelHandledDcts(final Class clazz) { + synchronized (HANDLED_DCTS_PER_TYPE) { + if (HANDLED_DCTS_PER_TYPE.isEmpty()) { + final Map, Set>> map = new HashMap<>(); + map.put(CraftMetaArmor.class, Set.of(CraftMetaArmor.TRIM.TYPE)); + map.put(CraftMetaArmorStand.class, Set.of(CraftMetaArmorStand.ENTITY_TAG.TYPE)); + map.put(CraftMetaAxolotlBucket.class, Set.of(CraftMetaAxolotlBucket.ENTITY_TAG.TYPE, CraftMetaAxolotlBucket.BUCKET_ENTITY_TAG.TYPE)); + map.put(CraftMetaBanner.class, Set.of(CraftMetaBanner.PATTERNS.TYPE)); // banner uses same tag as block state + map.put(CraftMetaShield.class, Set.of(CraftMetaShield.BASE_COLOR.TYPE, CraftMetaBanner.PATTERNS.TYPE)); + map.put(CraftMetaBlockState.class, Set.of(CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE)); + map.put(CraftMetaBook.class, Set.of(CraftMetaBook.BOOK_CONTENT.TYPE)); + map.put(CraftMetaBookSigned.class, Set.of(CraftMetaBookSigned.BOOK_CONTENT.TYPE)); + map.put(CraftMetaBundle.class, Set.of(CraftMetaBundle.ITEMS.TYPE)); + map.put(CraftMetaCharge.class, Set.of(CraftMetaCharge.EXPLOSION.TYPE)); + map.put(CraftMetaColorableArmor.class, Set.of(CraftMetaArmor.TRIM.TYPE, CraftMetaLeatherArmor.COLOR.TYPE)); + map.put(CraftMetaCompass.class, Set.of(CraftMetaCompass.LODESTONE_TARGET.TYPE)); + map.put(CraftMetaCrossbow.class, Set.of(CraftMetaCrossbow.CHARGED_PROJECTILES.TYPE)); + map.put(CraftMetaEnchantedBook.class, Set.of(CraftMetaEnchantedBook.STORED_ENCHANTMENTS.TYPE)); + map.put(CraftMetaEntityTag.class, Set.of(CraftMetaEntityTag.ENTITY_TAG.TYPE)); + map.put(CraftMetaFirework.class, Set.of(CraftMetaFirework.FIREWORKS.TYPE)); + map.put(CraftMetaKnowledgeBook.class, Set.of(CraftMetaKnowledgeBook.BOOK_RECIPES.TYPE)); + map.put(CraftMetaLeatherArmor.class, Set.of(CraftMetaLeatherArmor.COLOR.TYPE)); + map.put(CraftMetaMap.class, Set.of(CraftMetaMap.MAP_COLOR.TYPE, CraftMetaMap.MAP_POST_PROCESSING.TYPE, CraftMetaMap.MAP_ID.TYPE)); + map.put(CraftMetaMusicInstrument.class, Set.of(CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.TYPE)); + map.put(CraftMetaOminousBottle.class, Set.of(CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER.TYPE)); + map.put(CraftMetaPotion.class, Set.of(CraftMetaPotion.POTION_CONTENTS.TYPE)); + map.put(CraftMetaSkull.class, Set.of(CraftMetaSkull.SKULL_PROFILE.TYPE, CraftMetaSkull.NOTE_BLOCK_SOUND.TYPE)); + map.put(CraftMetaSpawnEgg.class, Set.of(CraftMetaSpawnEgg.ENTITY_TAG.TYPE)); + map.put(CraftMetaSuspiciousStew.class, Set.of(CraftMetaSuspiciousStew.EFFECTS.TYPE)); + map.put(CraftMetaTropicalFishBucket.class, Set.of(CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE, CraftMetaTropicalFishBucket.BUCKET_ENTITY_TAG.TYPE)); + + for (final Map.Entry, Set>> entry : map.entrySet()) { + final ArrayList> topLevelTags = new ArrayList<>(entry.getValue()); + // add tags common to CraftMetaItem to all + topLevelTags.addAll(DEFAULT_HANDLED_DCTS); + HANDLED_DCTS_PER_TYPE.put(entry.getKey(), Set.copyOf(topLevelTags)); + } } - return CraftMetaItem.HANDLED_TAGS; + return HANDLED_DCTS_PER_TYPE.getOrDefault(clazz, DEFAULT_HANDLED_DCTS); } } + // Paper end - improve checking handled data component types protected static Optional getOrEmpty(DataComponentPatch tag, ItemMetaKeyType type) { Optional result = tag.get(type.TYPE); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java index 68c0a6d5e0..4dc7adb626 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java @@ -32,8 +32,8 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo } } - CraftMetaKnowledgeBook(DataComponentPatch tag) { - super(tag); + CraftMetaKnowledgeBook(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaKnowledgeBook.BOOK_RECIPES).ifPresent((pages) -> { for (int i = 0; i < pages.size(); i++) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java index 75a8ad6990..e8c950aa74 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java @@ -25,8 +25,8 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { CraftMetaLeatherArmor.readColor(this, meta); } - CraftMetaLeatherArmor(DataComponentPatch tag) { - super(tag); + CraftMetaLeatherArmor(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper CraftMetaLeatherArmor.readColor(this, tag); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java index 08e18dcabb..149356981e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java @@ -44,8 +44,8 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta { this.color = map.color; } - CraftMetaMap(DataComponentPatch tag) { - super(tag); + CraftMetaMap(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaMap.MAP_ID).ifPresent((mapId) -> { this.mapId = mapId.id(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java index 478059eb3a..8423c6b67a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java @@ -26,8 +26,8 @@ public class CraftMetaMusicInstrument extends CraftMetaItem implements MusicInst } } - CraftMetaMusicInstrument(DataComponentPatch tag) { - super(tag); + CraftMetaMusicInstrument(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT).ifPresent((instrument) -> { this.instrument = CraftMusicInstrument.minecraftHolderToBukkit(instrument); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java index ed272c7eb4..b118d8ecb5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java @@ -24,8 +24,8 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott this.ominousBottleAmplifier = bottleMeta.ominousBottleAmplifier; } - CraftMetaOminousBottle(DataComponentPatch tag) { - super(tag); + CraftMetaOminousBottle(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER).ifPresent((amplifier) -> { this.ominousBottleAmplifier = amplifier.value(); }); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java index 96ad0f53d3..fd7b7f53c5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java @@ -54,8 +54,8 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { } } - CraftMetaPotion(DataComponentPatch tag) { - super(tag); + CraftMetaPotion(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaPotion.POTION_CONTENTS).ifPresent((potionContents) -> { potionContents.potion().ifPresent((potion) -> { this.type = CraftPotionType.minecraftHolderToBukkit(potion); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaShield.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaShield.java index bcd6cc29e4..967d8940ae 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaShield.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaShield.java @@ -42,8 +42,8 @@ public class CraftMetaShield extends CraftMetaItem implements ShieldMeta, BlockS } } - CraftMetaShield(DataComponentPatch tag) { - super(tag); + CraftMetaShield(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper - improve checking handled tags in item meta + super(tag, extraHandledDcts); // Paper - improve checking handled tags in item meta getOrEmpty(tag, CraftMetaShield.BASE_COLOR).ifPresent((color) -> { this.banner = CraftMetaShield.getBlockState(DyeColor.getByWoolData((byte) color.getId())); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java index ca714e165e..302906467b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java @@ -48,8 +48,8 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { this.noteBlockSound = skullMeta.noteBlockSound; } - CraftMetaSkull(DataComponentPatch tag) { - super(tag); + CraftMetaSkull(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaSkull.SKULL_PROFILE).ifPresent(this::setProfile); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java index 6c2c3b514b..8ddf091b3f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java @@ -33,8 +33,8 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { this.entityTag = egg.entityTag; } - CraftMetaSpawnEgg(DataComponentPatch tag) { - super(tag); + CraftMetaSpawnEgg(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaSpawnEgg.ENTITY_TAG).ifPresent((nbt) -> { this.entityTag = nbt.copyTag(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java index 248efddbad..7a43e326e5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java @@ -33,8 +33,8 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious } } - CraftMetaSuspiciousStew(DataComponentPatch tag) { - super(tag); + CraftMetaSuspiciousStew(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaSuspiciousStew.EFFECTS).ifPresent((suspiciousStewEffects) -> { List list = suspiciousStewEffects.effects(); int length = list.size(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java index a514fe98d3..17705059b8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java @@ -38,8 +38,8 @@ class CraftMetaTropicalFishBucket extends CraftMetaItem implements TropicalFishB this.bucketEntityTag = bucket.bucketEntityTag; } - CraftMetaTropicalFishBucket(DataComponentPatch tag) { - super(tag); + CraftMetaTropicalFishBucket(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaTropicalFishBucket.ENTITY_TAG).ifPresent((nbt) -> { this.entityTag = nbt.copyTag(); diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java index 91cfa32272..9cc1ef5c92 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java @@ -97,7 +97,7 @@ public class DeprecatedItemMetaCustomValueTest { CraftMetaItem.Applicator compound = new CraftMetaItem.Applicator(); itemMeta.applyToItem(compound); - assertEquals(itemMeta, new CraftMetaItem(compound.build())); + assertEquals(itemMeta, new CraftMetaItem(compound.build(), null)); // Paper } @Test diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java new file mode 100644 index 0000000000..df20446af3 --- /dev/null +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java @@ -0,0 +1,33 @@ +package org.bukkit.craftbukkit.inventory; + +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.ClassInfoList; +import io.github.classgraph.ScanResult; +import org.bukkit.support.environment.AllFeatures; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +// in cb package because of package-private stuff +@AllFeatures +class MetaHandledTagsTest { + + @Test + public void checkAllMetasHaveHandledTags() { + try (final ScanResult result = new ClassGraph() + .whitelistPackages("org.bukkit.craftbukkit.inventory") + .enableClassInfo().scan()) { + final ClassInfoList subclasses = result.getSubclasses(CraftMetaItem.class.getName()); + assertFalse(subclasses.isEmpty(), "found 0 sub types"); + for (final ClassInfo subclass : subclasses) { + final Class clazz = subclass.loadClass(CraftMetaItem.class); + CraftMetaItem.getTopLevelHandledDcts(clazz); // load into map + assertTrue(CraftMetaItem.HANDLED_DCTS_PER_TYPE.containsKey(clazz), subclass.getName() + " not found in handled tags map"); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java index 5b16e6f5e5..130c4500a5 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java @@ -131,7 +131,7 @@ public class PersistentDataContainerTest { CraftMetaItem.Applicator compound = new CraftMetaItem.Applicator(); itemMeta.applyToItem(compound); - assertEquals(itemMeta, new CraftMetaItem(compound.build())); + assertEquals(itemMeta, new CraftMetaItem(compound.build(), null)); // Paper } @Test @@ -464,7 +464,7 @@ public class PersistentDataContainerTest { @Test public void testEmptyListApplicationToAnyType() throws IOException { - final CraftMetaItem craftItem = new CraftMetaItem(DataComponentPatch.EMPTY); + final CraftMetaItem craftItem = new CraftMetaItem(DataComponentPatch.EMPTY, null); // Paper final PersistentDataContainer container = craftItem.getPersistentDataContainer(); container.set(PersistentDataContainerTest.requestKey("list"), PersistentDataType.LIST.strings(), List.of()); @@ -477,7 +477,7 @@ public class PersistentDataContainerTest { final CraftMetaItem.Applicator storage = new CraftMetaItem.Applicator(); craftItem.applyToItem(storage); - final CraftMetaItem readItem = new CraftMetaItem(storage.build()); + final CraftMetaItem readItem = new CraftMetaItem(storage.build(), null); // Paper final PersistentDataContainer readContainer = readItem.getPersistentDataContainer(); assertTrue(readContainer.has(PersistentDataContainerTest.requestKey("list"), PersistentDataType.LIST.strings()));