From f9ed174e311c06a01a4895d1a3abbb47c4ae15f9 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Wed, 13 Apr 2022 13:21:37 +0100 Subject: [PATCH] Added PersistentDataHolder to FastItemStack --- .../willfp/eco/core/fast/FastItemStack.java | 3 +- .../spigot/proxy/common/NMSCommons.kt | 12 +++++++ .../proxy/common/fast/EcoFastItemStack.kt | 31 +++++++++++++++- .../proxy/v1_17_R1/CommonsInitializer.kt | 35 +++++++++++++++++++ .../proxy/v1_18_R1/CommonsInitializer.kt | 35 +++++++++++++++++++ .../proxy/v1_18_R2/CommonsInitializer.kt | 35 +++++++++++++++++++ 6 files changed, 149 insertions(+), 2 deletions(-) diff --git a/eco-api/src/main/java/com/willfp/eco/core/fast/FastItemStack.java b/eco-api/src/main/java/com/willfp/eco/core/fast/FastItemStack.java index 72b0049a..95a2b09f 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/fast/FastItemStack.java +++ b/eco-api/src/main/java/com/willfp/eco/core/fast/FastItemStack.java @@ -6,6 +6,7 @@ import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataHolder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,7 +18,7 @@ import java.util.Set; /** * FastItemStack contains methods to modify and read items faster than in default bukkit. */ -public interface FastItemStack { +public interface FastItemStack extends PersistentDataHolder { /** * Get all enchantments on an item. * diff --git a/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/NMSCommons.kt b/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/NMSCommons.kt index d2f5d73e..f8814693 100644 --- a/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/NMSCommons.kt +++ b/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/NMSCommons.kt @@ -5,6 +5,7 @@ import com.willfp.eco.core.entities.ai.TargetGoal import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory import net.minecraft.core.Registry +import net.minecraft.nbt.CompoundTag import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.PathfinderMob @@ -13,6 +14,7 @@ import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.entity.Mob import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataContainer private lateinit var impl: CommonsProvider @@ -50,9 +52,19 @@ fun Material.toItem(): Item = .orElseThrow { IllegalArgumentException("Material is not item!") } } +fun CompoundTag.makePdc(): PersistentDataContainer = + impl.makePdc(this) + +fun CompoundTag.setPdc(pdc: PersistentDataContainer) = + impl.setPdc(this, pdc) + interface CommonsProvider { val nbtTagString: Int + fun makePdc(tag: CompoundTag): PersistentDataContainer + + fun setPdc(tag: CompoundTag, pdc: PersistentDataContainer) + fun toPathfinderMob(mob: Mob): PathfinderMob? fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation diff --git a/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/fast/EcoFastItemStack.kt b/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/fast/EcoFastItemStack.kt index f9451fad..1fb56be1 100644 --- a/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/fast/EcoFastItemStack.kt +++ b/eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/fast/EcoFastItemStack.kt @@ -3,7 +3,9 @@ package com.willfp.eco.internal.spigot.proxy.common.fast import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.internal.spigot.proxy.common.NBT_TAG_STRING import com.willfp.eco.internal.spigot.proxy.common.asNMSStack +import com.willfp.eco.internal.spigot.proxy.common.makePdc import com.willfp.eco.internal.spigot.proxy.common.mergeIfNeeded +import com.willfp.eco.internal.spigot.proxy.common.setPdc import com.willfp.eco.internal.spigot.proxy.common.toItem import com.willfp.eco.util.NamespacedKeyUtils import com.willfp.eco.util.StringUtils @@ -16,8 +18,11 @@ import net.minecraft.nbt.StringTag import net.minecraft.world.item.EnchantedBookItem import net.minecraft.world.item.Item import net.minecraft.world.item.Items +import org.bukkit.NamespacedKey import org.bukkit.enchantments.Enchantment import org.bukkit.inventory.ItemFlag +import org.bukkit.persistence.PersistentDataContainer +import org.bukkit.persistence.PersistentDataType import kotlin.experimental.and @Suppress("UsePropertyAccessSyntax") @@ -25,6 +30,7 @@ class EcoFastItemStack( private val bukkit: org.bukkit.inventory.ItemStack ) : FastItemStack { private val handle = bukkit.asNMSStack() + private val pdc = (if (handle.hasTag()) handle.getTag()!! else CompoundTag()).makePdc() override fun getEnchants(checkStored: Boolean): Map { val enchantmentNBT = @@ -196,6 +202,10 @@ class EcoFastItemStack( handle.setRepairCost(cost) } + override fun getPersistentDataContainer(): PersistentDataContainer { + return ContinuallyAppliedPersistentDataContainer(this.pdc, this) + } + override fun equals(other: Any?): Boolean { if (other !is EcoFastItemStack) { return false @@ -209,7 +219,11 @@ class EcoFastItemStack( return handle.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem())) } - private fun apply() { + internal fun apply() { + if (handle.hasTag()) { + handle.getTag()?.setPdc(this.pdc) + } + bukkit.mergeIfNeeded(handle) } @@ -221,3 +235,18 @@ class EcoFastItemStack( return bukkit } } + +private class ContinuallyAppliedPersistentDataContainer( + val handle: PersistentDataContainer, + val fis: EcoFastItemStack +) : PersistentDataContainer by handle { + override fun set(key: NamespacedKey, type: PersistentDataType, value: Z) { + handle.set(key, type, value) + fis.apply() + } + + override fun remove(key: NamespacedKey) { + handle.remove(key) + fis.apply() + } +} diff --git a/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/CommonsInitializer.kt b/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/CommonsInitializer.kt index 2e9c751c..5f35d2a4 100644 --- a/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/CommonsInitializer.kt +++ b/eco-core/core-nms/v1_17_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_17_R1/CommonsInitializer.kt @@ -2,6 +2,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1 import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.Tag import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.PathfinderMob import org.bukkit.Bukkit @@ -10,11 +12,14 @@ import org.bukkit.craftbukkit.v1_17_R1.CraftServer import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity import org.bukkit.craftbukkit.v1_17_R1.entity.CraftMob import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack +import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataContainer +import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataTypeRegistry import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_17_R1.util.CraftNamespacedKey import org.bukkit.entity.LivingEntity import org.bukkit.entity.Mob import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataContainer import java.lang.reflect.Field class CommonsInitializer : CommonsInitializerProxy { @@ -27,6 +32,10 @@ class CommonsInitializer : CommonsInitializerProxy { isAccessible = true } + private val pdcRegsitry: Field = Class.forName("org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMetaItem") + .getDeclaredField("DATA_TYPE_REGISTRY") + .apply { isAccessible = true } + override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING override fun toPathfinderMob(mob: Mob): PathfinderMob? { @@ -57,5 +66,31 @@ class CommonsInitializer : CommonsInitializerProxy { override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? = CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity + + override fun makePdc(tag: CompoundTag): PersistentDataContainer { + val pdc = CraftPersistentDataContainer(pdcRegsitry.get(null) as CraftPersistentDataTypeRegistry) + if (tag.contains("PublicBukkitValues")) { + val compound = tag.getCompound("PublicBukkitValues") + val keys = compound.allKeys + for (key in keys) { + pdc.put(key, compound[key]) + } + } + + return pdc + } + + override fun setPdc(tag: CompoundTag, pdc: PersistentDataContainer) { + pdc as CraftPersistentDataContainer + + if (!pdc.isEmpty) { + val bukkitCustomCompound = CompoundTag() + val rawPublicMap: Map = pdc.raw + for ((key, value) in rawPublicMap) { + bukkitCustomCompound.put(key, value) + } + tag.put("PublicBukkitValues", bukkitCustomCompound) + } + } } } diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/CommonsInitializer.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/CommonsInitializer.kt index 221ac130..8f4d4c01 100644 --- a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/CommonsInitializer.kt +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/CommonsInitializer.kt @@ -2,6 +2,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R1 import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.Tag import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.PathfinderMob import org.bukkit.Bukkit @@ -10,11 +12,14 @@ import org.bukkit.craftbukkit.v1_18_R1.CraftServer import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity import org.bukkit.craftbukkit.v1_18_R1.entity.CraftMob import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack +import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataContainer +import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataTypeRegistry import org.bukkit.craftbukkit.v1_18_R1.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey import org.bukkit.entity.LivingEntity import org.bukkit.entity.Mob import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataContainer import java.lang.reflect.Field class CommonsInitializer : CommonsInitializerProxy { @@ -27,6 +32,10 @@ class CommonsInitializer : CommonsInitializerProxy { isAccessible = true } + private val pdcRegsitry: Field = Class.forName("org.bukkit.craftbukkit.v1_18_R1.inventory.CraftMetaItem") + .getDeclaredField("DATA_TYPE_REGISTRY") + .apply { isAccessible = true } + override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING override fun toPathfinderMob(mob: Mob): PathfinderMob? { @@ -57,5 +66,31 @@ class CommonsInitializer : CommonsInitializerProxy { override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? = CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity + + override fun makePdc(tag: CompoundTag): PersistentDataContainer { + val pdc = CraftPersistentDataContainer(pdcRegsitry.get(null) as CraftPersistentDataTypeRegistry) + if (tag.contains("PublicBukkitValues")) { + val compound = tag.getCompound("PublicBukkitValues") + val keys = compound.allKeys + for (key in keys) { + pdc.put(key, compound[key]) + } + } + + return pdc + } + + override fun setPdc(tag: CompoundTag, pdc: PersistentDataContainer) { + pdc as CraftPersistentDataContainer + + if (!pdc.isEmpty) { + val bukkitCustomCompound = CompoundTag() + val rawPublicMap: Map = pdc.raw + for ((key, value) in rawPublicMap) { + bukkitCustomCompound.put(key, value) + } + tag.put("PublicBukkitValues", bukkitCustomCompound) + } + } } } diff --git a/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/CommonsInitializer.kt b/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/CommonsInitializer.kt index 88124a96..19675728 100644 --- a/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/CommonsInitializer.kt +++ b/eco-core/core-nms/v1_18_R2/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R2/CommonsInitializer.kt @@ -2,6 +2,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R2 import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.Tag import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.PathfinderMob import org.bukkit.Bukkit @@ -10,11 +12,14 @@ import org.bukkit.craftbukkit.v1_18_R2.CraftServer import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity import org.bukkit.craftbukkit.v1_18_R2.entity.CraftMob import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack +import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataContainer +import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataTypeRegistry import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey import org.bukkit.entity.LivingEntity import org.bukkit.entity.Mob import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataContainer import java.lang.reflect.Field class CommonsInitializer : CommonsInitializerProxy { @@ -27,6 +32,10 @@ class CommonsInitializer : CommonsInitializerProxy { isAccessible = true } + private val pdcRegsitry: Field = Class.forName("org.bukkit.craftbukkit.v1_18_R2.inventory.CraftMetaItem") + .getDeclaredField("DATA_TYPE_REGISTRY") + .apply { isAccessible = true } + override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING override fun toPathfinderMob(mob: Mob): PathfinderMob? { @@ -57,5 +66,31 @@ class CommonsInitializer : CommonsInitializerProxy { override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? = CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity + + override fun makePdc(tag: CompoundTag): PersistentDataContainer { + val pdc = CraftPersistentDataContainer(pdcRegsitry.get(null) as CraftPersistentDataTypeRegistry) + if (tag.contains("PublicBukkitValues")) { + val compound = tag.getCompound("PublicBukkitValues") + val keys = compound.allKeys + for (key in keys) { + pdc.put(key, compound[key]) + } + } + + return pdc + } + + override fun setPdc(tag: CompoundTag, pdc: PersistentDataContainer) { + pdc as CraftPersistentDataContainer + + if (!pdc.isEmpty) { + val bukkitCustomCompound = CompoundTag() + val rawPublicMap: Map = pdc.raw + for ((key, value) in rawPublicMap) { + bukkitCustomCompound.put(key, value) + } + tag.put("PublicBukkitValues", bukkitCustomCompound) + } + } } }