aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/1040-Fix-ItemFlags.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/1040-Fix-ItemFlags.patch')
-rw-r--r--patches/server/1040-Fix-ItemFlags.patch204
1 files changed, 204 insertions, 0 deletions
diff --git a/patches/server/1040-Fix-ItemFlags.patch b/patches/server/1040-Fix-ItemFlags.patch
new file mode 100644
index 0000000000..0e894f8bc2
--- /dev/null
+++ b/patches/server/1040-Fix-ItemFlags.patch
@@ -0,0 +1,204 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <[email protected]>
+Date: Sat, 27 Apr 2024 12:16:38 -0700
+Subject: [PATCH] Fix ItemFlags
+
+Re-adds missing functionality for HIDE_DESTROYS and
+HIDE_PLACED_ON. Also adds new flag in HIDE_STORED_ENCHANTS
+which was split from HIDE_ADDITIONAL_TOOLTIP.
+
+== AT ==
+public net.minecraft.world.item.AdventureModePredicate predicates
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
+index fca0cfba14dd2cc6f24b56eaf269594b2d87fd04..8734f0b777432cd8639094b75a3da1b9595823ed 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
+@@ -39,7 +39,7 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage
+ getOrEmpty(tag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS).ifPresent((itemEnchantments) -> {
+ this.enchantments = buildEnchantments(itemEnchantments);
+ if (!itemEnchantments.showInTooltip) {
+- this.addItemFlags(ItemFlag.HIDE_ADDITIONAL_TOOLTIP);
++ this.addItemFlags(ItemFlag.HIDE_STORED_ENCHANTS); // Paper - new ItemFlag
+ }
+ });
+ }
+@@ -54,7 +54,7 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage
+ void applyToItem(CraftMetaItem.Applicator itemTag) {
+ super.applyToItem(itemTag);
+
+- this.applyEnchantments(this.enchantments, itemTag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS, ItemFlag.HIDE_ADDITIONAL_TOOLTIP);
++ this.applyEnchantments(this.enchantments, itemTag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS, ItemFlag.HIDE_STORED_ENCHANTS);
+ }
+
+ @Override
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+index dd17d7d88ad43e0c426a7a508709fc8993d3a5c9..58de351fd2a4008296aa87f231396d272a1362c3 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+@@ -224,6 +224,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ static final ItemMetaKeyType<Unit> HIDE_ADDITIONAL_TOOLTIP = new ItemMetaKeyType(DataComponents.HIDE_ADDITIONAL_TOOLTIP);
+ @Specific(Specific.To.NBT)
+ static final ItemMetaKeyType<CustomData> CUSTOM_DATA = new ItemMetaKeyType<>(DataComponents.CUSTOM_DATA);
++ // Paper start - fix ItemFlags
++ static final ItemMetaKeyType<net.minecraft.world.item.AdventureModePredicate> CAN_PLACE_ON = new ItemMetaKeyType<>(DataComponents.CAN_PLACE_ON);
++ static final ItemMetaKeyType<net.minecraft.world.item.AdventureModePredicate> CAN_BREAK = new ItemMetaKeyType<>(DataComponents.CAN_BREAK);
++ private List<net.minecraft.advancements.critereon.BlockPredicate> canPlaceOnPredicates;
++ private List<net.minecraft.advancements.critereon.BlockPredicate> canBreakPredicates;
++ // Paper end - fix ItemFlags
+
+ // We store the raw original JSON representation of all text data. See SPIGOT-5063, SPIGOT-5656, SPIGOT-5304
+ private Component displayName;
+@@ -296,6 +302,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ this.customTag = meta.customTag;
+
+ this.version = meta.version;
++ // Paper start
++ this.canPlaceOnPredicates = meta.canPlaceOnPredicates;
++ this.canBreakPredicates = meta.canBreakPredicates;
++ // Paper end
+ }
+
+ CraftMetaItem(DataComponentPatch tag) {
+@@ -388,6 +398,20 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ this.customTag = null;
+ }
+ });
++ // Paper start - fix ItemFlags
++ CraftMetaItem.getOrEmpty(tag, CraftMetaItem.CAN_PLACE_ON).ifPresent(data -> {
++ this.canPlaceOnPredicates = List.copyOf(data.predicates);
++ if (!data.showInTooltip()) {
++ this.addItemFlags(ItemFlag.HIDE_PLACED_ON);
++ }
++ });
++ CraftMetaItem.getOrEmpty(tag, CraftMetaItem.CAN_BREAK).ifPresent(data -> {
++ this.canBreakPredicates = List.copyOf(data.predicates);
++ if (!data.showInTooltip()) {
++ this.addItemFlags(ItemFlag.HIDE_DESTROYS);
++ }
++ });
++ // Paper end - fix ItemFlags
+
+ Set<Map.Entry<DataComponentType<?>, Optional<?>>> keys = tag.entrySet();
+ for (Map.Entry<DataComponentType<?>, Optional<?>> key : keys) {
+@@ -569,10 +593,19 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+
+ String unhandled = SerializableMeta.getString(map, "unhandled", true);
+ if (unhandled != null) {
+- ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(internal));
++ ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(unhandled)); // Paper - fix deserializing unhandled tags
+ try {
+ CompoundTag unhandledTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap());
+- this.unhandledTags.copy(DataComponentPatch.CODEC.parse(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), unhandledTag).result().get());
++ // Paper start
++ final net.minecraft.core.component.DataComponentPatch patch = net.minecraft.core.component.DataComponentPatch.CODEC.parse(net.minecraft.server.MinecraftServer.getDefaultRegistryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE), unhandledTag).result().get();
++ CraftMetaItem.getOrEmpty(patch, CraftMetaItem.CAN_PLACE_ON).ifPresent(data -> {
++ this.canPlaceOnPredicates = List.copyOf(data.predicates);
++ });
++ CraftMetaItem.getOrEmpty(patch, CraftMetaItem.CAN_BREAK).ifPresent(data -> {
++ this.canBreakPredicates = List.copyOf(data.predicates);
++ });
++ this.unhandledTags.copy(patch.forget(type -> type == CraftMetaItem.CAN_PLACE_ON.TYPE || type == CraftMetaItem.CAN_BREAK.TYPE));
++ // Paper end
+ } catch (IOException ex) {
+ Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
+ }
+@@ -788,6 +821,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ itemTag.put(CraftMetaItem.MAX_DAMAGE, this.maxDamage);
+ }
+
++ // Paper start
++ if (this.canPlaceOnPredicates != null && !this.canPlaceOnPredicates.isEmpty()) {
++ itemTag.put(CraftMetaItem.CAN_PLACE_ON, new net.minecraft.world.item.AdventureModePredicate(this.canPlaceOnPredicates, !this.hasItemFlag(ItemFlag.HIDE_PLACED_ON)));
++ }
++ if (this.canBreakPredicates != null && !this.canBreakPredicates.isEmpty()) {
++ itemTag.put(CraftMetaItem.CAN_BREAK, new net.minecraft.world.item.AdventureModePredicate(this.canBreakPredicates, !this.hasItemFlag(ItemFlag.HIDE_DESTROYS)));
++ }
++ // Paper end
++
+ for (Map.Entry<DataComponentType<?>, Optional<?>> e : this.unhandledTags.build().entrySet()) {
+ e.getValue().ifPresentOrElse((value) -> {
+ itemTag.builder.set((DataComponentType) e.getKey(), value);
+@@ -859,7 +901,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+
+ @Overridden
+ boolean isEmpty() {
+- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null);
++ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper
+ }
+
+ // Paper start
+@@ -1468,6 +1510,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ && (this.hasFood() ? that.hasFood() && this.food.equals(that.food) : !that.hasFood())
+ && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage())
+ && (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage())
++ && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper
++ && (this.canBreakPredicates != null ? that.canBreakPredicates != null && this.canBreakPredicates.equals(that.canBreakPredicates) : that.canBreakPredicates == null) // Paper
+ && (this.version == that.version);
+ }
+
+@@ -1510,6 +1554,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ hash = 61 * hash + (this.hasDamage() ? this.damage : 0);
+ hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237);
+ hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
++ hash = 61 * hash + (this.canPlaceOnPredicates != null ? this.canPlaceOnPredicates.hashCode() : 0); // Paper
++ hash = 61 * hash + (this.canBreakPredicates != null ? this.canBreakPredicates.hashCode() : 0); // Paper
+ hash = 61 * hash + this.version;
+ return hash;
+ }
+@@ -1547,6 +1593,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ clone.damage = this.damage;
+ clone.maxDamage = this.maxDamage;
+ clone.version = this.version;
++ // Paper start
++ if (this.canPlaceOnPredicates != null) {
++ clone.canPlaceOnPredicates = List.copyOf(this.canPlaceOnPredicates);
++ }
++ if (this.canBreakPredicates != null) {
++ clone.canBreakPredicates = List.copyOf(this.canBreakPredicates);
++ }
++ // Paper end
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ throw new Error(e);
+@@ -1656,6 +1710,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ }
+ }
+
++ // Paper start
++ final boolean canBreakAddToUnhandled = this.canBreakPredicates != null && !this.canBreakPredicates.isEmpty();
++ if (canBreakAddToUnhandled) {
++ this.unhandledTags.set(DataComponents.CAN_BREAK, new net.minecraft.world.item.AdventureModePredicate(this.canBreakPredicates, !this.hasItemFlag(ItemFlag.HIDE_DESTROYS)));
++ }
++ final boolean canPlaceOnAddToUnhandled = this.canPlaceOnPredicates != null && !this.canPlaceOnPredicates.isEmpty();
++ if (canPlaceOnAddToUnhandled) {
++ this.unhandledTags.set(DataComponents.CAN_PLACE_ON, new net.minecraft.world.item.AdventureModePredicate(this.canPlaceOnPredicates, !this.hasItemFlag(ItemFlag.HIDE_PLACED_ON)));
++ }
++ // Paper end
+ if (!this.unhandledTags.isEmpty()) {
+ Tag unhandled = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), this.unhandledTags.build()).getOrThrow(IllegalStateException::new);
+ try {
+@@ -1666,6 +1730,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
++ // Paper start
++ if (canBreakAddToUnhandled) {
++ this.unhandledTags.clear(DataComponents.CAN_BREAK);
++ }
++ if (canPlaceOnAddToUnhandled) {
++ this.unhandledTags.clear(DataComponents.CAN_PLACE_ON);
++ }
++ // Paper end
+
+ if (!this.persistentDataContainer.isEmpty()) { // Store custom tags, wrapped in their compound
+ builder.put(CraftMetaItem.BUKKIT_CUSTOM_TAG.BUKKIT, this.persistentDataContainer.serialize());
+@@ -1807,6 +1879,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ 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,