From dfd0478a876f58da6386291418d8c42e0c0bd966 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 5 May 2024 12:56:46 -0700 Subject: [PATCH] Fix BlockStateMeta (#10647) * Fixes CraftMetaBlockState block entity data components * rebase and merge into general item meta fix * Add javadoc notice * Update message --------- Co-authored-by: Bjarne Koll --- patches/api/Fix-upstream-javadocs.patch | 16 +++++++++ patches/server/General-ItemMeta-fixes.patch | 38 +++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/patches/api/Fix-upstream-javadocs.patch b/patches/api/Fix-upstream-javadocs.patch index afc735a93b..ef356ba2c1 100644 --- a/patches/api/Fix-upstream-javadocs.patch +++ b/patches/api/Fix-upstream-javadocs.patch @@ -1449,6 +1449,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 * * @param input The input choice. * @return The changed recipe, so you can chain calls. +diff --git a/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java b/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java +@@ -0,0 +0,0 @@ public interface BlockStateMeta extends ItemMeta { + * @param blockState the block state to attach to the block. + * @throws IllegalArgumentException if the blockState is null + * or invalid for this item. ++ * ++ * @apiNote As of 1.20.5 the block state carries a copy of the item's data deviations. ++ * As such, setting the block state via this method will reset secondary deviations of the item meta. ++ * This can manifest in the addition to an existing lore failing or a change of a previously added display name. ++ * It is hence recommended to first mutate the block state, set it back, and then mutate the item meta. + */ + void setBlockState(@NotNull BlockState blockState); + } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java diff --git a/patches/server/General-ItemMeta-fixes.patch b/patches/server/General-ItemMeta-fixes.patch index 99611a2d16..3a93d513d2 100644 --- a/patches/server/General-ItemMeta-fixes.patch +++ b/patches/server/General-ItemMeta-fixes.patch @@ -135,7 +135,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end for (TypedDataComponent component : this.blockEntityTag.collectComponents()) { ++ if (CraftMetaItem.DEFAULT_HANDLED_DCTS.contains(component.type())) continue; // Paper - if the component type was already handled by CraftMetaItem, don't add it again tag.builder.set(component); + } + } +@@ -0,0 +0,0 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta + Preconditions.checkArgument(blockStateType == blockState.getClass() && blockState instanceof CraftBlockEntityState, "Invalid blockState for " + this.material); + + this.blockEntityTag = (CraftBlockEntityState) blockState; ++ // Paper start - when a new BlockState is set, the components from that block entity ++ // have to be used to update the fields on CraftMetaItem ++ final PatchedDataComponentMap patchedMap = new net.minecraft.core.component.PatchedDataComponentMap(this.blockEntityTag.getHandle().getBlock().asItem().components()); ++ final net.minecraft.core.component.DataComponentMap map = this.blockEntityTag.collectComponents(); ++ patchedMap.setAll(map); ++ this.updateFromPatch(patchedMap.asPatch(), null); ++ // Paper end + } + + private static Material shieldToBannerHack() { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java @@ -259,6 +276,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Applicator put(ItemMetaKeyType key, T value) { this.builder.set(key.TYPE, value); @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + } + + CraftMetaItem(DataComponentPatch tag, Set> extraHandledTags) { // Paper - improve handled tags on type changes ++ // Paper start - properly support data components in BlockEntity ++ this.updateFromPatch(tag, extraHandledTags); ++ } ++ protected final void updateFromPatch(DataComponentPatch tag, Set> extraHandledTags) { ++ // Paper end - properly support data components in BlockEntity + CraftMetaItem.getOrEmpty(tag, CraftMetaItem.NAME).ifPresent((component) -> { + this.displayName = component; + }); +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { void applyModifiers(Multimap modifiers, CraftMetaItem.Applicator tag) { if (modifiers == null || modifiers.isEmpty()) { @@ -302,6 +331,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.applyToItem(tag); DataComponentPatch patch = tag.build(); Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow(); +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + // 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( ++ protected static final Set> DEFAULT_HANDLED_DCTS = Set.of( + CraftMetaItem.NAME.TYPE, + CraftMetaItem.ITEM_NAME.TYPE, + CraftMetaItem.LORE.TYPE, diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java