summaryrefslogtreecommitdiffhomepage
path: root/patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch')
-rw-r--r--patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch428
1 files changed, 428 insertions, 0 deletions
diff --git a/patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch
new file mode 100644
index 0000000000..0c48106249
--- /dev/null
+++ b/patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch
@@ -0,0 +1,428 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <[email protected]>
+Date: Wed, 12 Jun 2024 10:29:30 -0700
+Subject: [PATCH] Make a PDC view accessible directly from ItemStack
+
+
+diff --git a/src/main/java/io/papermc/paper/persistence/PersistentDataContainerView.java b/src/main/java/io/papermc/paper/persistence/PersistentDataContainerView.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..061ffc1f050a950e041ceef217b5f335e3cd0af1
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/persistence/PersistentDataContainerView.java
+@@ -0,0 +1,160 @@
++package io.papermc.paper.persistence;
++
++import java.util.Set;
++import org.bukkit.NamespacedKey;
++import org.bukkit.persistence.PersistentDataAdapterContext;
++import org.bukkit.persistence.PersistentDataContainer;
++import org.bukkit.persistence.PersistentDataHolder;
++import org.bukkit.persistence.PersistentDataType;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
++
++/**
++ * This represents a view of a persistent data container. No
++ * methods on this interface mutate the container.
++ *
++ * @see PersistentDataContainer
++ */
++@NullMarked
++public interface PersistentDataContainerView {
++
++ /**
++ * Returns if the persistent metadata provider has metadata registered
++ * matching the provided parameters.
++ * <p>
++ * This method will only return true if the found value has the same primitive
++ * data type as the provided key.
++ * <p>
++ * Storing a value using a custom {@link PersistentDataType} implementation
++ * will not store the complex data type. Therefore storing a UUID (by
++ * storing a byte[]) will match has("key" ,
++ * {@link PersistentDataType#BYTE_ARRAY}). Likewise a stored byte[] will
++ * always match your UUID {@link PersistentDataType} even if it is not 16
++ * bytes long.
++ * <p>
++ * This method is only usable for custom object keys. Overwriting existing
++ * tags, like the display name, will not work as the values are stored
++ * using your namespace.
++ *
++ * @param key the key the value is stored under
++ * @param type the type the primative stored value has to match
++ * @param <P> the generic type of the stored primitive
++ * @param <C> the generic type of the eventually created complex object
++ * @return if a value with the provided key and type exists
++ * @throws IllegalArgumentException if the key to look up is null
++ * @throws IllegalArgumentException if the type to cast the found object to is
++ * null
++ */
++ <P, C> boolean has(NamespacedKey key, PersistentDataType<P, C> type);
++
++ /**
++ * Returns if the persistent metadata provider has metadata registered matching
++ * the provided parameters.
++ * <p>
++ * This method will return true as long as a value with the given key exists,
++ * regardless of its type.
++ * <p>
++ * This method is only usable for custom object keys. Overwriting existing tags,
++ * like the display name, will not work as the values are stored using your
++ * namespace.
++ *
++ * @param key the key the value is stored under
++ * @return if a value with the provided key exists
++ * @throws IllegalArgumentException if the key to look up is null
++ */
++ boolean has(NamespacedKey key);
++
++ /**
++ * Returns the metadata value that is stored on the
++ * {@link PersistentDataHolder} instance.
++ *
++ * @param key the key to look up in the custom tag map
++ * @param type the type the value must have and will be casted to
++ * @param <P> the generic type of the stored primitive
++ * @param <C> the generic type of the eventually created complex object
++ * @return the value or {@code null} if no value was mapped under the given
++ * value
++ * @throws IllegalArgumentException if the key to look up is null
++ * @throws IllegalArgumentException if the type to cast the found object to is
++ * null
++ * @throws IllegalArgumentException if a value exists under the given key,
++ * but cannot be accessed using the given type
++ * @throws IllegalArgumentException if no suitable adapter was found for
++ * the {@link
++ * PersistentDataType#getPrimitiveType()}
++ */
++ <P, C> @Nullable C get(NamespacedKey key, PersistentDataType<P, C> type);
++
++ /**
++ * Returns the metadata value that is stored on the
++ * {@link PersistentDataHolder} instance. If the value does not exist in the
++ * container, the default value provided is returned.
++ *
++ * @param key the key to look up in the custom tag map
++ * @param type the type the value must have and will be casted to
++ * @param defaultValue the default value to return if no value was found for
++ * the provided key
++ * @param <P> the generic type of the stored primitive
++ * @param <C> the generic type of the eventually created complex object
++ * @return the value or the default value if no value was mapped under the
++ * given key
++ * @throws IllegalArgumentException if the key to look up is null
++ * @throws IllegalArgumentException if the type to cast the found object to is
++ * null
++ * @throws IllegalArgumentException if a value exists under the given key,
++ * but cannot be accessed using the given type
++ * @throws IllegalArgumentException if no suitable adapter was found for
++ * the {@link PersistentDataType#getPrimitiveType()}
++ */
++ <P, C> C getOrDefault(NamespacedKey key, PersistentDataType<P, C> type, C defaultValue);
++
++ /**
++ * Get the set of keys present on this {@link PersistentDataContainer}
++ * instance.
++ * <p>
++ * Any changes made to the returned set will not be reflected on the
++ * instance.
++ *
++ * @return the key set
++ */
++ Set<NamespacedKey> getKeys();
++
++ /**
++ * Returns if the container instance is empty, therefore has no entries
++ * inside it.
++ *
++ * @return the boolean
++ */
++ boolean isEmpty();
++
++ /**
++ * Copies all values from this {@link PersistentDataContainer} to the provided
++ * container.
++ * <p>
++ * This method only copies custom object keys. Existing tags, like the display
++ * name, will not be copied as the values are stored using your namespace.
++ *
++ * @param other the container to copy to
++ * @param replace whether to replace any matching values in the target container
++ * @throws IllegalArgumentException if the other container is null
++ */
++ void copyTo(PersistentDataContainer other, boolean replace);
++
++ /**
++ * Returns the adapter context this tag container uses.
++ *
++ * @return the tag context
++ */
++ PersistentDataAdapterContext getAdapterContext();
++
++ /**
++ * Serialize this {@link PersistentDataContainer} instance to a
++ * byte array.
++ *
++ * @return a binary representation of this container
++ * @throws java.io.IOException if we fail to write this container to a byte array
++ */
++ byte[] serializeToBytes() throws java.io.IOException;
++}
+diff --git a/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java b/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..05bc2ac326fb58ea429cee825520e70f7f211f0d
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java
+@@ -0,0 +1,24 @@
++package io.papermc.paper.persistence;
++
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
++
++/**
++ * The {@link PersistentDataViewHolder} interface defines an object that can view
++ * custom persistent data on it.
++ */
++@NullMarked
++public interface PersistentDataViewHolder {
++
++ /**
++ * Returns a custom tag container view capable of viewing tags on the object.
++ * <p>
++ * Note that the tags stored on this container are all stored under their
++ * own custom namespace therefore modifying default tags using this
++ * {@link PersistentDataViewHolder} is impossible.
++ *
++ * @return the persistent data container view
++ */
++ PersistentDataContainerView getPersistentDataContainer();
++}
+diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
+index 6fc8bddfcabca8c363e0d9f958f0ce7bc39099f1..7f63a3a37eb06049bd5de10466c6dd96cb5dd4ee 100644
+--- a/src/main/java/org/bukkit/inventory/ItemStack.java
++++ b/src/main/java/org/bukkit/inventory/ItemStack.java
+@@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
+ * use this class to encapsulate Materials for which {@link Material#isItem()}
+ * returns false.</b>
+ */
+-public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowItem>, net.kyori.adventure.translation.Translatable { // Paper
++public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowItem>, net.kyori.adventure.translation.Translatable, io.papermc.paper.persistence.PersistentDataViewHolder { // Paper
+ private ItemStack craftDelegate; // Paper - always delegate to server-backed stack
+ private MaterialData data = null;
+
+@@ -61,6 +61,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
+ }
+ // Paper end
+
++ // Paper start - pdc
++ @Override
++ public io.papermc.paper.persistence.@NotNull PersistentDataContainerView getPersistentDataContainer() {
++ return this.craftDelegate.getPersistentDataContainer();
++ }
++ // Paper end - pdc
++
+ @Utility
+ protected ItemStack() {}
+
+diff --git a/src/main/java/org/bukkit/persistence/PersistentDataContainer.java b/src/main/java/org/bukkit/persistence/PersistentDataContainer.java
+index decf3b1949d4653a9fb01684b93ff91048137076..0f40eb52f6e2a5b6932cf9f223c1bbe9ab9eab1b 100644
+--- a/src/main/java/org/bukkit/persistence/PersistentDataContainer.java
++++ b/src/main/java/org/bukkit/persistence/PersistentDataContainer.java
+@@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
+ * This interface represents a map like object, capable of storing custom tags
+ * in it.
+ */
+-public interface PersistentDataContainer {
++public interface PersistentDataContainer extends io.papermc.paper.persistence.PersistentDataContainerView { // Paper - split up view and mutable
+
+ /**
+ * Stores a metadata value on the {@link PersistentDataHolder} instance.
+@@ -33,118 +33,7 @@ public interface PersistentDataContainer {
+ * the {@link PersistentDataType#getPrimitiveType()}
+ */
+ <P, C> void set(@NotNull NamespacedKey key, @NotNull PersistentDataType<P, C> type, @NotNull C value);
+-
+- /**
+- * Returns if the persistent metadata provider has metadata registered
+- * matching the provided parameters.
+- * <p>
+- * This method will only return true if the found value has the same primitive
+- * data type as the provided key.
+- * <p>
+- * Storing a value using a custom {@link PersistentDataType} implementation
+- * will not store the complex data type. Therefore storing a UUID (by
+- * storing a byte[]) will match has("key" ,
+- * {@link PersistentDataType#BYTE_ARRAY}). Likewise a stored byte[] will
+- * always match your UUID {@link PersistentDataType} even if it is not 16
+- * bytes long.
+- * <p>
+- * This method is only usable for custom object keys. Overwriting existing
+- * tags, like the display name, will not work as the values are stored
+- * using your namespace.
+- *
+- * @param key the key the value is stored under
+- * @param type the type the primative stored value has to match
+- * @param <P> the generic type of the stored primitive
+- * @param <C> the generic type of the eventually created complex object
+- *
+- * @return if a value with the provided key and type exists
+- *
+- * @throws IllegalArgumentException if the key to look up is null
+- * @throws IllegalArgumentException if the type to cast the found object to is
+- * null
+- */
+- <P, C> boolean has(@NotNull NamespacedKey key, @NotNull PersistentDataType<P, C> type);
+-
+- /**
+- * Returns if the persistent metadata provider has metadata registered matching
+- * the provided parameters.
+- * <p>
+- * This method will return true as long as a value with the given key exists,
+- * regardless of its type.
+- * <p>
+- * This method is only usable for custom object keys. Overwriting existing tags,
+- * like the display name, will not work as the values are stored using your
+- * namespace.
+- *
+- * @param key the key the value is stored under
+- *
+- * @return if a value with the provided key exists
+- *
+- * @throws IllegalArgumentException if the key to look up is null
+- */
+- boolean has(@NotNull NamespacedKey key);
+-
+- /**
+- * Returns the metadata value that is stored on the
+- * {@link PersistentDataHolder} instance.
+- *
+- * @param key the key to look up in the custom tag map
+- * @param type the type the value must have and will be casted to
+- * @param <P> the generic type of the stored primitive
+- * @param <C> the generic type of the eventually created complex object
+- *
+- * @return the value or {@code null} if no value was mapped under the given
+- * value
+- *
+- * @throws IllegalArgumentException if the key to look up is null
+- * @throws IllegalArgumentException if the type to cast the found object to is
+- * null
+- * @throws IllegalArgumentException if a value exists under the given key,
+- * but cannot be accessed using the given type
+- * @throws IllegalArgumentException if no suitable adapter was found for
+- * the {@link
+- * PersistentDataType#getPrimitiveType()}
+- */
+- @Nullable
+- <P, C> C get(@NotNull NamespacedKey key, @NotNull PersistentDataType<P, C> type);
+-
+- /**
+- * Returns the metadata value that is stored on the
+- * {@link PersistentDataHolder} instance. If the value does not exist in the
+- * container, the default value provided is returned.
+- *
+- * @param key the key to look up in the custom tag map
+- * @param type the type the value must have and will be casted to
+- * @param defaultValue the default value to return if no value was found for
+- * the provided key
+- * @param <P> the generic type of the stored primitive
+- * @param <C> the generic type of the eventually created complex object
+- *
+- * @return the value or the default value if no value was mapped under the
+- * given key
+- *
+- * @throws IllegalArgumentException if the key to look up is null
+- * @throws IllegalArgumentException if the type to cast the found object to is
+- * null
+- * @throws IllegalArgumentException if a value exists under the given key,
+- * but cannot be accessed using the given type
+- * @throws IllegalArgumentException if no suitable adapter was found for
+- * the {@link PersistentDataType#getPrimitiveType()}
+- */
+- @NotNull
+- <P, C> C getOrDefault(@NotNull NamespacedKey key, @NotNull PersistentDataType<P, C> type, @NotNull C defaultValue);
+-
+- /**
+- * Get the set of keys present on this {@link PersistentDataContainer}
+- * instance.
+- *
+- * Any changes made to the returned set will not be reflected on the
+- * instance.
+- *
+- * @return the key set
+- */
+- @NotNull
+- Set<NamespacedKey> getKeys();
++ // Paper - move to PersistentDataContainerView
+
+ /**
+ * Removes a custom key from the {@link PersistentDataHolder} instance.
+@@ -154,47 +43,10 @@ public interface PersistentDataContainer {
+ * @throws IllegalArgumentException if the provided key is null
+ */
+ void remove(@NotNull NamespacedKey key);
+-
+- /**
+- * Returns if the container instance is empty, therefore has no entries
+- * inside it.
+- *
+- * @return the boolean
+- */
+- boolean isEmpty();
+-
+- /**
+- * Copies all values from this {@link PersistentDataContainer} to the provided
+- * container.
+- * <p>
+- * This method only copies custom object keys. Existing tags, like the display
+- * name, will not be copied as the values are stored using your namespace.
+- *
+- * @param other the container to copy to
+- * @param replace whether to replace any matching values in the target container
+- *
+- * @throws IllegalArgumentException if the other container is null
+- */
+- void copyTo(@NotNull PersistentDataContainer other, boolean replace);
+-
+- /**
+- * Returns the adapter context this tag container uses.
+- *
+- * @return the tag context
+- */
+- @NotNull
+- PersistentDataAdapterContext getAdapterContext();
++ // Paper - move to PersistentDataContainerView
+
+ // Paper start - byte array serialization
+- /**
+- * Serialize this {@link PersistentDataContainer} instance to a
+- * byte array.
+- *
+- * @return a binary representation of this container
+- * @throws java.io.IOException if we fail to write this container to a byte array
+- */
+- byte @NotNull [] serializeToBytes() throws java.io.IOException;
+-
++ // Paper - move to PersistentDataContainerView
+ /**
+ * Read values from a serialised byte array into this
+ * {@link PersistentDataContainer} instance.
+diff --git a/src/main/java/org/bukkit/persistence/PersistentDataHolder.java b/src/main/java/org/bukkit/persistence/PersistentDataHolder.java
+index 80b277cc57f092f04fbf7810ac78d250b207b775..71f33c1265bc753ef40108ffce0d4bd8656d2903 100644
+--- a/src/main/java/org/bukkit/persistence/PersistentDataHolder.java
++++ b/src/main/java/org/bukkit/persistence/PersistentDataHolder.java
+@@ -5,8 +5,10 @@ import org.jetbrains.annotations.NotNull;
+ /**
+ * The {@link PersistentDataHolder} interface defines an object that can store
+ * custom persistent meta data on it.
++ * <p>Prefer using {@link io.papermc.paper.persistence.PersistentDataViewHolder} for read-only operations
++ * as it covers more types.</p>
+ */
+-public interface PersistentDataHolder {
++public interface PersistentDataHolder extends io.papermc.paper.persistence.PersistentDataViewHolder { // Paper
+
+ /**
+ * Returns a custom tag container capable of storing tags on the object.