mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-04 22:22:18 -07:00
Delegate ItemStack (#10852)
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/persistence/PaperPersistentDataContainerView.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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) {
|
Reference in New Issue
Block a user