mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 07:20:24 +01:00
Make a PDC view accessible directly from ItemStack
This commit is contained in:
parent
9e5e007003
commit
cb339661cc
5 changed files with 199 additions and 154 deletions
|
@ -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
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
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();
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
* use this class to encapsulate Materials for which {@link Material#isItem()}
|
* use this class to encapsulate Materials for which {@link Material#isItem()}
|
||||||
* returns false.</b>
|
* 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 ItemStack craftDelegate; // Paper - always delegate to server-backed stack
|
||||||
private MaterialData data = null;
|
private MaterialData data = null;
|
||||||
|
|
||||||
|
@ -61,6 +61,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||||||
}
|
}
|
||||||
// Paper end
|
// Paper end
|
||||||
|
|
||||||
|
// Paper start - pdc
|
||||||
|
@Override
|
||||||
|
public io.papermc.paper.persistence.@NotNull PersistentDataContainerView getPersistentDataContainer() {
|
||||||
|
return this.craftDelegate.getPersistentDataContainer();
|
||||||
|
}
|
||||||
|
// Paper end - pdc
|
||||||
|
|
||||||
@Utility
|
@Utility
|
||||||
protected ItemStack() {}
|
protected ItemStack() {}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
* This interface represents a map like object, capable of storing custom tags
|
* This interface represents a map like object, capable of storing custom tags
|
||||||
* in it.
|
* 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.
|
* Stores a metadata value on the {@link PersistentDataHolder} instance.
|
||||||
|
@ -33,118 +33,7 @@ public interface PersistentDataContainer {
|
||||||
* the {@link PersistentDataType#getPrimitiveType()}
|
* the {@link PersistentDataType#getPrimitiveType()}
|
||||||
*/
|
*/
|
||||||
<P, C> void set(@NotNull NamespacedKey key, @NotNull PersistentDataType<P, C> type, @NotNull C value);
|
<P, C> void set(@NotNull NamespacedKey key, @NotNull PersistentDataType<P, C> type, @NotNull C value);
|
||||||
|
// Paper - move to 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(@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();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a custom key from the {@link PersistentDataHolder} instance.
|
* Removes a custom key from the {@link PersistentDataHolder} instance.
|
||||||
|
@ -154,47 +43,10 @@ public interface PersistentDataContainer {
|
||||||
* @throws IllegalArgumentException if the provided key is null
|
* @throws IllegalArgumentException if the provided key is null
|
||||||
*/
|
*/
|
||||||
void remove(@NotNull NamespacedKey key);
|
void remove(@NotNull NamespacedKey key);
|
||||||
|
// Paper - move to PersistentDataContainerView
|
||||||
/**
|
|
||||||
* 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 start - byte array serialization
|
// Paper start - byte array serialization
|
||||||
/**
|
// Paper - move to PersistentDataContainerView
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read values from a serialised byte array into this
|
* Read values from a serialised byte array into this
|
||||||
* {@link PersistentDataContainer} instance.
|
* {@link PersistentDataContainer} instance.
|
||||||
|
|
|
@ -5,8 +5,10 @@ import org.jetbrains.annotations.NotNull;
|
||||||
/**
|
/**
|
||||||
* The {@link PersistentDataHolder} interface defines an object that can store
|
* The {@link PersistentDataHolder} interface defines an object that can store
|
||||||
* custom persistent meta data on it.
|
* 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.
|
* Returns a custom tag container capable of storing tags on the object.
|
||||||
|
|
Loading…
Reference in a new issue