diff options
author | Jake Potrebic <[email protected]> | 2024-06-17 12:12:42 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2024-06-17 21:12:42 +0200 |
commit | bf8552f0f074e6e3a5151c0c1407041d64399dee (patch) | |
tree | 9af42dbb76dc10a6250c1a33444b3beb6636bd57 /patches/api/0479-Make-a-PDC-view-accessible-directly-from-ItemStack.patch | |
parent | 13992b17c7f318645ee87c0ff4daf60fe65b4cf2 (diff) | |
download | Paper-bf8552f0f074e6e3a5151c0c1407041d64399dee.tar.gz Paper-bf8552f0f074e6e3a5151c0c1407041d64399dee.zip |
Delegate ItemStack (#10852)
Diffstat (limited to 'patches/api/0479-Make-a-PDC-view-accessible-directly-from-ItemStack.patch')
-rw-r--r-- | patches/api/0479-Make-a-PDC-view-accessible-directly-from-ItemStack.patch | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/patches/api/0479-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/api/0479-Make-a-PDC-view-accessible-directly-from-ItemStack.patch new file mode 100644 index 0000000000..a37a724014 --- /dev/null +++ b/patches/api/0479-Make-a-PDC-view-accessible-directly-from-ItemStack.patch @@ -0,0 +1,434 @@ +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..4a4949fde3f03e2ea9d2dde245f7dea119e202bf +--- /dev/null ++++ b/src/main/java/io/papermc/paper/persistence/PersistentDataContainerView.java +@@ -0,0 +1,167 @@ ++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.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * This represents a view of a persistent data container. No ++ * methods on this interface mutate the container. ++ * @see PersistentDataContainer ++ */ ++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(@NonNull NamespacedKey key, @NonNull 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(@NonNull 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(@NonNull NamespacedKey key, @NonNull 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> @NonNull C getOrDefault(@NonNull NamespacedKey key, @NonNull PersistentDataType<P, C> type, @NonNull 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 ++ */ ++ @NonNull 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(@NonNull PersistentDataContainer other, boolean replace); ++ ++ /** ++ * Returns the adapter context this tag container uses. ++ * ++ * @return the tag context ++ */ ++ @NonNull 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 @NonNull [] 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..9789916f949374bfb50da535b076180700f7ae73 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java +@@ -0,0 +1,23 @@ ++package io.papermc.paper.persistence; ++ ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * The {@link PersistentDataViewHolder} interface defines an object that can view ++ * custom persistent data on it. ++ */ ++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 ++ */ ++ @NonNull PersistentDataContainerView getPersistentDataContainer(); ++} +diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java +index da91938ff941bb5903dcbd430c68c5980c01b57b..f603b5b6ba80af919f415322583a8345a5b1358a 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. |