diff options
author | Jake Potrebic <[email protected]> | 2024-07-16 16:39:57 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2024-07-16 16:39:57 -0700 |
commit | 506f1651e549c290142df8d1e2e8ea831bc381c0 (patch) | |
tree | 250f8cb16a8e94a588aa9df694e199f3e45ae824 /patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch | |
parent | a6ceda12c54cd8b7d272fe50e744c9b9a26d0838 (diff) | |
download | Paper-506f1651e549c290142df8d1e2e8ea831bc381c0.tar.gz Paper-506f1651e549c290142df8d1e2e8ea831bc381c0.zip |
Don't store removed components in multiple places (#11091)
Diffstat (limited to 'patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch')
-rw-r--r-- | patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch new file mode 100644 index 0000000000..bb97ac9fc5 --- /dev/null +++ b/patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch @@ -0,0 +1,266 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <[email protected]> +Date: Wed, 12 Jun 2024 10:29:40 -0700 +Subject: [PATCH] Make a PDC view accessible directly from ItemStack + + +diff --git a/src/main/java/io/papermc/paper/persistence/PaperPersistentDataContainerView.java b/src/main/java/io/papermc/paper/persistence/PaperPersistentDataContainerView.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fac401280d3f3689b00e16c19155ca753faa06e0 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/persistence/PaperPersistentDataContainerView.java +@@ -0,0 +1,86 @@ ++package io.papermc.paper.persistence; ++ ++import com.google.common.base.Preconditions; ++import java.io.ByteArrayOutputStream; ++import java.io.DataOutputStream; ++import java.io.IOException; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.NbtIo; ++import net.minecraft.nbt.Tag; ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.persistence.CraftPersistentDataAdapterContext; ++import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; ++import org.bukkit.persistence.PersistentDataAdapterContext; ++import org.bukkit.persistence.PersistentDataType; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.checker.nullness.qual.Nullable; ++import org.checkerframework.framework.qual.DefaultQualifier; ++ ++@DefaultQualifier(NonNull.class) ++public abstract class PaperPersistentDataContainerView implements PersistentDataContainerView { ++ ++ protected final CraftPersistentDataTypeRegistry registry; ++ protected final CraftPersistentDataAdapterContext adapterContext; ++ ++ public PaperPersistentDataContainerView(final CraftPersistentDataTypeRegistry registry) { ++ this.registry = registry; ++ this.adapterContext = new CraftPersistentDataAdapterContext(this.registry); ++ } ++ ++ public abstract @Nullable Tag getTag(final String key); ++ ++ public abstract CompoundTag toTagCompound(); ++ ++ @Override ++ public <P, C> boolean has(final NamespacedKey key, final PersistentDataType<P, C> type) { ++ Preconditions.checkArgument(key != null, "The NamespacedKey key cannot be null"); ++ Preconditions.checkArgument(type != null, "The provided type cannot be null"); ++ ++ final @Nullable Tag value = this.getTag(key.toString()); ++ if (value == null) { ++ return false; ++ } ++ ++ return this.registry.isInstanceOf(type, value); ++ } ++ ++ @Override ++ public boolean has(final NamespacedKey key) { ++ Preconditions.checkArgument(key != null, "The provided key for the custom value was null"); // Paper ++ return this.getTag(key.toString()) != null; ++ } ++ ++ @Override ++ public <P, C> @Nullable C get(final NamespacedKey key, final PersistentDataType<P, C> type) { ++ Preconditions.checkArgument(key != null, "The NamespacedKey key cannot be null"); ++ Preconditions.checkArgument(type != null, "The provided type cannot be null"); ++ ++ final @Nullable Tag value = this.getTag(key.toString()); ++ if (value == null) { ++ return null; ++ } ++ ++ return type.fromPrimitive(this.registry.extract(type, value), this.adapterContext); ++ } ++ ++ @Override ++ public <P, C> C getOrDefault(final NamespacedKey key, final PersistentDataType<P, C> type, final C defaultValue) { ++ final C c = this.get(key, type); ++ return c != null ? c : defaultValue; ++ } ++ ++ @Override ++ public PersistentDataAdapterContext getAdapterContext() { ++ return this.adapterContext; ++ } ++ ++ @Override ++ public byte[] serializeToBytes() throws IOException { ++ final net.minecraft.nbt.CompoundTag root = this.toTagCompound(); ++ final ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream(); ++ try (final DataOutputStream dataOutput = new DataOutputStream(byteArrayOutput)) { ++ NbtIo.write(root, dataOutput); ++ return byteArrayOutput.toByteArray(); ++ } ++ } ++} +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +index 22b0febba8fbfc9b2ab1a623932ffff32ca8040c..4a7daf90eaee1c1134c643ea3b227e56a849a0fb 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +@@ -480,4 +480,63 @@ public final class CraftItemStack extends ItemStack { + return mirrored; + } + // Paper end ++ ++ // Paper start - pdc ++ private net.minecraft.nbt.CompoundTag getPdcTag() { ++ if (this.handle == null) { ++ return new net.minecraft.nbt.CompoundTag(); ++ } ++ final net.minecraft.world.item.component.CustomData customData = this.handle.getOrDefault(DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY); ++ // getUnsafe is OK here because we are only ever *reading* the data so immutability is preserved ++ //noinspection deprecation ++ return customData.getUnsafe().getCompound("PublicBukkitValues"); ++ } ++ ++ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); ++ private final io.papermc.paper.persistence.PaperPersistentDataContainerView pdcView = new io.papermc.paper.persistence.PaperPersistentDataContainerView(REGISTRY) { ++ ++ @Override ++ public net.minecraft.nbt.CompoundTag toTagCompound() { ++ return CraftItemStack.this.getPdcTag(); ++ } ++ ++ @Override ++ public net.minecraft.nbt.Tag getTag(final String key) { ++ return CraftItemStack.this.getPdcTag().get(key); ++ } ++ ++ @Override ++ public java.util.Set<org.bukkit.NamespacedKey> getKeys() { ++ java.util.Set<org.bukkit.NamespacedKey> keys = new java.util.HashSet<>(); ++ CraftItemStack.this.getPdcTag().getAllKeys().forEach(key -> { ++ final String[] keyData = key.split(":", 2); ++ if (keyData.length == 2) { ++ keys.add(new org.bukkit.NamespacedKey(keyData[0], keyData[1])); ++ } ++ }); ++ return java.util.Collections.unmodifiableSet(keys); ++ }; ++ ++ @Override ++ public boolean isEmpty() { ++ return CraftItemStack.this.getPdcTag().isEmpty(); ++ } ++ ++ @Override ++ public void copyTo(final org.bukkit.persistence.PersistentDataContainer other, final boolean replace) { ++ Preconditions.checkArgument(other != null, "The target container cannot be null"); ++ final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer target = (org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer) other; ++ final net.minecraft.nbt.CompoundTag pdcTag = org.bukkit.craftbukkit.inventory.CraftItemStack.this.getPdcTag(); ++ for (final String key : pdcTag.getAllKeys()) { ++ if (replace || !target.getRaw().containsKey(key)) { ++ target.getRaw().put(key, pdcTag.get(key).copy()); ++ } ++ } ++ } ++ }; ++ @Override ++ public io.papermc.paper.persistence.PersistentDataContainerView getPersistentDataContainer() { ++ return this.pdcView; ++ } ++ // Paper end - pdc + } +diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java +index f55fdd57ced259ad5a95878840e98ffaa3db2e05..9d867f1659433ea15f281c8b441db7e339013100 100644 +--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java ++++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java +@@ -16,11 +16,10 @@ import org.bukkit.persistence.PersistentDataContainer; + import org.bukkit.persistence.PersistentDataType; + import org.jetbrains.annotations.NotNull; + +-public class CraftPersistentDataContainer implements PersistentDataContainer { ++public class CraftPersistentDataContainer extends io.papermc.paper.persistence.PaperPersistentDataContainerView implements PersistentDataContainer { // Paper - split up view and mutable + + private final Map<String, Tag> customDataTags = new HashMap<>(); +- private final CraftPersistentDataTypeRegistry registry; +- private final CraftPersistentDataAdapterContext adapterContext; ++ // Paper - move to PersistentDataContainerView + + public CraftPersistentDataContainer(Map<String, Tag> customTags, CraftPersistentDataTypeRegistry registry) { + this(registry); +@@ -28,10 +27,15 @@ public class CraftPersistentDataContainer implements PersistentDataContainer { + } + + public CraftPersistentDataContainer(CraftPersistentDataTypeRegistry registry) { +- this.registry = registry; +- this.adapterContext = new CraftPersistentDataAdapterContext(this.registry); ++ super(registry); // Paper - move to PersistentDataContainerView + } + ++ // Paper start ++ @Override ++ public Tag getTag(final String key) { ++ return this.customDataTags.get(key); ++ } ++ // Paper end + + @Override + public <T, Z> void set(@NotNull NamespacedKey key, @NotNull PersistentDataType<T, Z> type, @NotNull Z value) { +@@ -42,44 +46,7 @@ public class CraftPersistentDataContainer implements PersistentDataContainer { + this.customDataTags.put(key.toString(), this.registry.wrap(type, type.toPrimitive(value, this.adapterContext))); + } + +- @Override +- public <T, Z> boolean has(@NotNull NamespacedKey key, @NotNull PersistentDataType<T, Z> type) { +- Preconditions.checkArgument(key != null, "The NamespacedKey key cannot be null"); +- Preconditions.checkArgument(type != null, "The provided type cannot be null"); +- +- Tag value = this.customDataTags.get(key.toString()); +- if (value == null) { +- return false; +- } +- +- return this.registry.isInstanceOf(type, value); +- } +- +- @Override +- public boolean has(NamespacedKey key) { +- Preconditions.checkArgument(key != null, "The provided key for the custom value was null"); // Paper +- return this.customDataTags.get(key.toString()) != null; +- } +- +- @Override +- public <T, Z> Z get(@NotNull NamespacedKey key, @NotNull PersistentDataType<T, Z> type) { +- Preconditions.checkArgument(key != null, "The NamespacedKey key cannot be null"); +- Preconditions.checkArgument(type != null, "The provided type cannot be null"); +- +- Tag value = this.customDataTags.get(key.toString()); +- if (value == null) { +- return null; +- } +- +- return type.fromPrimitive(this.registry.extract(type, value), this.adapterContext); +- } +- +- @NotNull +- @Override +- public <T, Z> Z getOrDefault(@NotNull NamespacedKey key, @NotNull PersistentDataType<T, Z> type, @NotNull Z defaultValue) { +- Z z = this.get(key, type); +- return z != null ? z : defaultValue; +- } ++ // Paper - move to PersistentDataContainerView + + @NotNull + @Override +@@ -186,16 +153,7 @@ public class CraftPersistentDataContainer implements PersistentDataContainer { + // Paper end + + // Paper start - byte array serialization +- @Override +- public byte[] serializeToBytes() throws java.io.IOException { +- final net.minecraft.nbt.CompoundTag root = this.toTagCompound(); +- final java.io.ByteArrayOutputStream byteArrayOutput = new java.io.ByteArrayOutputStream(); +- try (final java.io.DataOutputStream dataOutput = new java.io.DataOutputStream(byteArrayOutput)) { +- net.minecraft.nbt.NbtIo.write(root, dataOutput); +- return byteArrayOutput.toByteArray(); +- } +- } +- ++ // Paper - move to PersistentDataContainerView + @Override + public void readFromBytes(final byte[] bytes, final boolean clear) throws java.io.IOException { + if (clear) { |