Added ExtendedPersistentDataContainer
This commit is contained in:
@@ -2,6 +2,7 @@ package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
|
||||
import com.willfp.eco.core.data.ProfileHandler;
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry;
|
||||
import com.willfp.eco.core.drops.DropQueueFactory;
|
||||
@@ -23,6 +24,7 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -280,6 +282,14 @@ public interface Handler {
|
||||
* @param <T> The mob type.
|
||||
* @return The controlled entity.
|
||||
*/
|
||||
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
|
||||
|
||||
/**
|
||||
* Adapt base PDC to extended PDC.
|
||||
*
|
||||
* @param container The container.
|
||||
* @return The extended container.
|
||||
*/
|
||||
@NotNull
|
||||
<T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
|
||||
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface ExtendedPersistentDataContainer extends PersistentDataContainer {
|
||||
/**
|
||||
* Set a key.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param value The value.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
*/
|
||||
<T, Z> void set(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z value);
|
||||
|
||||
/**
|
||||
* Get if there is a key.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return If the key is present.
|
||||
*/
|
||||
<T, Z> boolean has(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
|
||||
|
||||
/**
|
||||
* Get a value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return The value, or null if not found.
|
||||
*/
|
||||
@Nullable <T, Z> Z get(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
|
||||
|
||||
/**
|
||||
* Get a value or default if not present.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param defaultValue The default value.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return The value, or the default if not found.
|
||||
*/
|
||||
@NotNull <T, Z> Z getOrDefault(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z defaultValue);
|
||||
|
||||
/**
|
||||
* Get all keys, including namespaced keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
@NotNull
|
||||
Set<String> getAllKeys();
|
||||
|
||||
/**
|
||||
* Remove a key.
|
||||
*
|
||||
* @param key The key.
|
||||
*/
|
||||
void remove(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Convert regular persistent data container to extended persistent data container.
|
||||
* <p>
|
||||
* Only use this with FastItemStack, you're likely to create problems otherwise.
|
||||
*
|
||||
* @param base The base container.
|
||||
* @return The extended container.
|
||||
*/
|
||||
static ExtendedPersistentDataContainer wrap(@NotNull PersistentDataContainer base) {
|
||||
return Eco.getHandler().adaptPdc(base);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.core.fast;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
@@ -203,7 +204,7 @@ public interface FastItemStack extends PersistentDataHolder {
|
||||
*
|
||||
* @return The base NBT tag.
|
||||
*/
|
||||
PersistentDataContainer getBaseTag();
|
||||
ExtendedPersistentDataContainer getBaseTag();
|
||||
|
||||
/**
|
||||
* Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer.
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.items;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
|
||||
import com.willfp.eco.core.fast.FastItemStack;
|
||||
import com.willfp.eco.core.items.args.LookupArgParser;
|
||||
import com.willfp.eco.core.items.provider.ItemProvider;
|
||||
@@ -530,8 +531,8 @@ public final class Items {
|
||||
public static ItemStack setDestroySpeedMultiplier(@NotNull final ItemStack itemStack,
|
||||
final double multiplier) {
|
||||
FastItemStack fis = FastItemStack.wrap(itemStack);
|
||||
PersistentDataContainer tag = fis.getBaseTag();
|
||||
tag.set(NamespacedKeyUtils.createEcoKey("break_speed"), PersistentDataType.DOUBLE, multiplier);
|
||||
ExtendedPersistentDataContainer tag = fis.getBaseTag();
|
||||
tag.set("BreakSpeed", PersistentDataType.DOUBLE, multiplier);
|
||||
fis.setBaseTag(tag);
|
||||
return fis.unwrap();
|
||||
}
|
||||
@@ -544,9 +545,9 @@ public final class Items {
|
||||
*/
|
||||
public static double getDestroySpeedMultiplier(@NotNull final ItemStack itemStack) {
|
||||
FastItemStack fis = FastItemStack.wrap(itemStack);
|
||||
PersistentDataContainer tag = fis.getBaseTag();
|
||||
ExtendedPersistentDataContainer tag = fis.getBaseTag();
|
||||
return Objects.requireNonNullElse(
|
||||
tag.get(NamespacedKeyUtils.createEcoKey("break_speed"), PersistentDataType.DOUBLE),
|
||||
tag.get("BreakSpeed", PersistentDataType.DOUBLE),
|
||||
1.0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -108,21 +108,25 @@ class CommonsInitializer : CommonsInitializerProxy {
|
||||
return compound
|
||||
}
|
||||
|
||||
pdc as CraftPersistentDataContainer?
|
||||
val container = when (pdc) {
|
||||
is CraftPersistentDataContainer? -> pdc
|
||||
is ExtendedPersistentDataContainerFactory.EcoPersistentDataContainer? -> pdc?.handle
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (item != null) {
|
||||
if (pdc != null && !pdc.isEmpty) {
|
||||
if (container != null && !container.isEmpty) {
|
||||
for (key in tag.allKeys.toSet()) {
|
||||
tag.remove(key)
|
||||
}
|
||||
|
||||
tag.merge(pdc.toTag())
|
||||
tag.merge(container.toTag())
|
||||
} else {
|
||||
item.setTag(null)
|
||||
}
|
||||
} else {
|
||||
if (pdc != null && !pdc.isEmpty) {
|
||||
tag.put("PublicBukkitValues", pdc.toTag())
|
||||
if (container != null && !container.isEmpty) {
|
||||
tag.put("PublicBukkitValues", container.toTag())
|
||||
} else {
|
||||
tag.remove("PublicBukkitValues")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
|
||||
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
|
||||
import net.minecraft.nbt.Tag
|
||||
import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataContainer
|
||||
import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataTypeRegistry
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
is ExtendedPersistentDataContainer -> pdc
|
||||
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
|
||||
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
|
||||
}
|
||||
}
|
||||
|
||||
class EcoPersistentDataContainer(
|
||||
val handle: CraftPersistentDataContainer
|
||||
) : ExtendedPersistentDataContainer, PersistentDataContainer by handle {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val customDataTags: MutableMap<String, Tag> =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
|
||||
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val registry: CraftPersistentDataTypeRegistry =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(handle) as CraftPersistentDataTypeRegistry
|
||||
|
||||
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
|
||||
customDataTags[key] = registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, adapterContext))
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
|
||||
val value = customDataTags[key] ?: return false
|
||||
return registry.isInstanceOf(dataType.primitiveType, value)
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
|
||||
val value = customDataTags[key] ?: return null
|
||||
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), adapterContext)
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> getOrDefault(
|
||||
key: String,
|
||||
dataType: PersistentDataType<T, Z>,
|
||||
defaultValue: Z
|
||||
): Z {
|
||||
return get(key, dataType) ?: defaultValue
|
||||
}
|
||||
|
||||
override fun remove(key: String) {
|
||||
customDataTags.remove(key)
|
||||
}
|
||||
|
||||
override fun getAllKeys(): MutableSet<String> {
|
||||
return customDataTags.keys
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,21 +108,25 @@ class CommonsInitializer : CommonsInitializerProxy {
|
||||
return compound
|
||||
}
|
||||
|
||||
pdc as CraftPersistentDataContainer?
|
||||
val container = when (pdc) {
|
||||
is CraftPersistentDataContainer? -> pdc
|
||||
is ExtendedPersistentDataContainerFactory.EcoPersistentDataContainer? -> pdc?.handle
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (item != null) {
|
||||
if (pdc != null && !pdc.isEmpty) {
|
||||
if (container != null && !container.isEmpty) {
|
||||
for (key in tag.allKeys.toSet()) {
|
||||
tag.remove(key)
|
||||
}
|
||||
|
||||
tag.merge(pdc.toTag())
|
||||
tag.merge(container.toTag())
|
||||
} else {
|
||||
item.setTag(null)
|
||||
}
|
||||
} else {
|
||||
if (pdc != null && !pdc.isEmpty) {
|
||||
tag.put("PublicBukkitValues", pdc.toTag())
|
||||
if (container != null && !container.isEmpty) {
|
||||
tag.put("PublicBukkitValues", container.toTag())
|
||||
} else {
|
||||
tag.remove("PublicBukkitValues")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
|
||||
import net.minecraft.nbt.Tag
|
||||
import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataContainer
|
||||
import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataTypeRegistry
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
is ExtendedPersistentDataContainer -> pdc
|
||||
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
|
||||
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
|
||||
}
|
||||
}
|
||||
|
||||
class EcoPersistentDataContainer(
|
||||
val handle: CraftPersistentDataContainer
|
||||
) : ExtendedPersistentDataContainer, PersistentDataContainer by handle {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val customDataTags: MutableMap<String, Tag> =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
|
||||
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val registry: CraftPersistentDataTypeRegistry =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(handle) as CraftPersistentDataTypeRegistry
|
||||
|
||||
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
|
||||
customDataTags[key] = registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, adapterContext))
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
|
||||
val value = customDataTags[key] ?: return false
|
||||
return registry.isInstanceOf(dataType.primitiveType, value)
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
|
||||
val value = customDataTags[key] ?: return null
|
||||
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), adapterContext)
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> getOrDefault(
|
||||
key: String,
|
||||
dataType: PersistentDataType<T, Z>,
|
||||
defaultValue: Z
|
||||
): Z {
|
||||
return get(key, dataType) ?: defaultValue
|
||||
}
|
||||
|
||||
override fun remove(key: String) {
|
||||
customDataTags.remove(key)
|
||||
}
|
||||
|
||||
override fun getAllKeys(): MutableSet<String> {
|
||||
return customDataTags.keys
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,21 +108,25 @@ class CommonsInitializer : CommonsInitializerProxy {
|
||||
return compound
|
||||
}
|
||||
|
||||
pdc as CraftPersistentDataContainer?
|
||||
val container = when (pdc) {
|
||||
is CraftPersistentDataContainer? -> pdc
|
||||
is ExtendedPersistentDataContainerFactory.EcoPersistentDataContainer? -> pdc?.handle
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (item != null) {
|
||||
if (pdc != null && !pdc.isEmpty) {
|
||||
if (container != null && !container.isEmpty) {
|
||||
for (key in tag.allKeys.toSet()) {
|
||||
tag.remove(key)
|
||||
}
|
||||
|
||||
tag.merge(pdc.toTag())
|
||||
tag.merge(container.toTag())
|
||||
} else {
|
||||
item.setTag(null)
|
||||
}
|
||||
} else {
|
||||
if (pdc != null && !pdc.isEmpty) {
|
||||
tag.put("PublicBukkitValues", pdc.toTag())
|
||||
if (container != null && !container.isEmpty) {
|
||||
tag.put("PublicBukkitValues", container.toTag())
|
||||
} else {
|
||||
tag.remove("PublicBukkitValues")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
|
||||
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
|
||||
import net.minecraft.nbt.Tag
|
||||
import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataContainer
|
||||
import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataTypeRegistry
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
is ExtendedPersistentDataContainer -> pdc
|
||||
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
|
||||
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
|
||||
}
|
||||
}
|
||||
|
||||
class EcoPersistentDataContainer(
|
||||
val handle: CraftPersistentDataContainer
|
||||
) : ExtendedPersistentDataContainer, PersistentDataContainer by handle {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val customDataTags: MutableMap<String, Tag> =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
|
||||
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val registry: CraftPersistentDataTypeRegistry =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(handle) as CraftPersistentDataTypeRegistry
|
||||
|
||||
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
|
||||
customDataTags[key] = registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, adapterContext))
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
|
||||
val value = customDataTags[key] ?: return false
|
||||
return registry.isInstanceOf(dataType.primitiveType, value)
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
|
||||
val value = customDataTags[key] ?: return null
|
||||
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), adapterContext)
|
||||
}
|
||||
|
||||
override fun <T : Any, Z : Any> getOrDefault(
|
||||
key: String,
|
||||
dataType: PersistentDataType<T, Z>,
|
||||
defaultValue: Z
|
||||
): Z {
|
||||
return get(key, dataType) ?: defaultValue
|
||||
}
|
||||
|
||||
override fun remove(key: String) {
|
||||
customDataTags.remove(key)
|
||||
}
|
||||
|
||||
override fun getAllKeys(): MutableSet<String> {
|
||||
return customDataTags.keys
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.Handler
|
||||
import com.willfp.eco.core.PluginProps
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||
import com.willfp.eco.core.entities.ai.EntityController
|
||||
import com.willfp.eco.core.fast.FastItemStack
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
|
||||
@@ -32,6 +33,7 @@ import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
|
||||
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||
@@ -40,6 +42,7 @@ import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.Entity
|
||||
import org.bukkit.entity.Mob
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import java.util.logging.Logger
|
||||
|
||||
@Suppress("UNUSED")
|
||||
@@ -150,4 +153,7 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
|
||||
|
||||
override fun formatMiniMessage(message: String): String =
|
||||
getProxy(MiniMessageTranslatorProxy::class.java).format(message)
|
||||
|
||||
override fun adaptPdc(container: PersistentDataContainer): ExtendedPersistentDataContainer =
|
||||
getProxy(ExtendedPersistentDataContainerFactoryProxy::class.java).adapt(container)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.willfp.eco.internal.spigot.proxy
|
||||
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
|
||||
interface ExtendedPersistentDataContainerFactoryProxy {
|
||||
fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer
|
||||
}
|
||||
Reference in New Issue
Block a user