Added PersistentDataHolder to FastItemStack

This commit is contained in:
Auxilor
2022-04-13 13:21:37 +01:00
parent 496d878a14
commit f9ed174e31
6 changed files with 149 additions and 2 deletions

View File

@@ -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.
*

View File

@@ -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

View File

@@ -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<Enchantment, Int> {
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 <T : Any, Z : Any> set(key: NamespacedKey, type: PersistentDataType<T, Z>, value: Z) {
handle.set(key, type, value)
fis.apply()
}
override fun remove(key: NamespacedKey) {
handle.remove(key)
fis.apply()
}
}

View File

@@ -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<String, Tag> = pdc.raw
for ((key, value) in rawPublicMap) {
bukkitCustomCompound.put(key, value)
}
tag.put("PublicBukkitValues", bukkitCustomCompound)
}
}
}
}

View File

@@ -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<String, Tag> = pdc.raw
for ((key, value) in rawPublicMap) {
bukkitCustomCompound.put(key, value)
}
tag.put("PublicBukkitValues", bukkitCustomCompound)
}
}
}
}

View File

@@ -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<String, Tag> = pdc.raw
for ((key, value) in rawPublicMap) {
bukkitCustomCompound.put(key, value)
}
tag.put("PublicBukkitValues", bukkitCustomCompound)
}
}
}
}