From 3fdb41e7855ffc3dc0cd30e40bc8aded7a0bdf5d Mon Sep 17 00:00:00 2001 From: masmc05 Date: Sun, 30 Apr 2023 15:26:52 +0300 Subject: [PATCH 1/3] Metadata is evil --- .../kotlin/com/willfp/libreforge/PDCUtils.kt | 85 +++++++++++++++++++ .../libreforge/TriggerPlaceholderListener.kt | 22 ++--- .../impl/EffectDamageNearbyEntities.kt | 12 +-- .../effects/impl/EffectGlowNearbyBlocks.kt | 27 +++--- .../libreforge/effects/impl/EffectIgnite.kt | 15 ++-- .../impl/EffectPermanentPotionEffect.kt | 61 ++++++++++--- .../effects/impl/EffectSpawnMobs.kt | 26 +++--- .../effects/impl/EffectTraceback.kt | 66 +++++++++++--- .../effects/templates/MineBlockEffect.kt | 9 +- .../triggers/impl/TriggerTridentAttack.kt | 17 ++-- 10 files changed, 252 insertions(+), 88 deletions(-) create mode 100644 core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt diff --git a/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt b/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt new file mode 100644 index 000000000..eca0f7c53 --- /dev/null +++ b/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt @@ -0,0 +1,85 @@ +package com.willfp.libreforge + +import org.bukkit.NamespacedKey +import org.bukkit.block.Block +import org.bukkit.persistence.PersistentDataContainer +import org.bukkit.persistence.PersistentDataHolder +import org.bukkit.persistence.PersistentDataType +import org.jetbrains.annotations.Contract +import java.util.UUID + +val PersistentDataHolder.pdc get() = this.persistentDataContainer +fun PersistentDataContainer.setBool(key: NamespacedKey, value: Boolean) { + this.set(key, PersistentDataType.BYTE, if (value) 1 else 0) +} +fun PersistentDataContainer.getBool(key: NamespacedKey, default: Boolean = false) : Boolean { + val value = get(key, PersistentDataType.BYTE) ?: return default + return value == 1.toByte() +} +fun PersistentDataContainer.hasBool(key: NamespacedKey): Boolean { + return has(key, PersistentDataType.BYTE) +} +fun PersistentDataContainer.setUUID(key: NamespacedKey, uuid: UUID) { + this.set(key, PersistentDataType.LONG_ARRAY, longArrayOf(uuid.leastSignificantBits, uuid.mostSignificantBits)) +} +fun PersistentDataContainer.getUUID(key: NamespacedKey) : UUID? { + val arr = get(key, PersistentDataType.LONG_ARRAY) ?: return null + if (arr.size != 2) return null + return UUID(arr[1], arr[0]) +} +fun PersistentDataContainer.hasUUID(key: NamespacedKey) : Boolean { + return has(key, PersistentDataType.LONG_ARRAY) +} +fun PersistentDataContainer.setDouble(key: NamespacedKey, double: Double) { + this.set(key, PersistentDataType.DOUBLE, double) +} +fun PersistentDataContainer.getDouble(key: NamespacedKey) : Double? { + return get(key, PersistentDataType.DOUBLE) +} +fun PersistentDataContainer.hasDouble(key: NamespacedKey) : Boolean { + return has(key, PersistentDataType.DOUBLE) +} +fun PersistentDataContainer.setFloat(key: NamespacedKey, float: Float) { + this.set(key, PersistentDataType.FLOAT, float) +} +fun PersistentDataContainer.getFloat(key: NamespacedKey) : Float? { + return get(key, PersistentDataType.FLOAT) +} +fun PersistentDataContainer.hasFloat(key: NamespacedKey) : Boolean { + return has(key, PersistentDataType.FLOAT) +} +fun PersistentDataContainer.setInt(key: NamespacedKey, int: Int) { + this.set(key, PersistentDataType.INTEGER, int) +} +fun PersistentDataContainer.getInt(key: NamespacedKey) : Int? { + return get(key, PersistentDataType.INTEGER) +} +fun PersistentDataContainer.hasInt(key: NamespacedKey) : Boolean { + return has(key, PersistentDataType.INTEGER) +} +fun PersistentDataContainer.setString(key: NamespacedKey, string: String) { + this.set(key, PersistentDataType.STRING, string) +} +fun PersistentDataContainer.getString(key: NamespacedKey) : String? { + return get(key, PersistentDataType.STRING) +} +fun PersistentDataContainer.hasString(key: NamespacedKey) : Boolean { + return has(key, PersistentDataType.STRING) +} + +@Contract("_,true->!null") +fun PersistentDataContainer.getPDC(key: NamespacedKey, save: Boolean = true): PersistentDataContainer? { + var pdc = get(key, PersistentDataType.TAG_CONTAINER) + if (pdc == null && save) { + pdc = this.adapterContext.newPersistentDataContainer() + set(key, PersistentDataType.TAG_CONTAINER, pdc) + } + return pdc +} + +val Block.pdc : PersistentDataContainer get() { + return this.chunk.pdc.getPDC(NamespacedKey(plugin, "block:$x;$y;$z"))!! +} +fun Block.getPDCNoSave(): PersistentDataContainer? { + return this.chunk.pdc.getPDC(NamespacedKey(plugin, "block:$x;$y;$z"), false) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt b/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt index de7f0e15b..772d1fec9 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt @@ -4,6 +4,7 @@ import com.willfp.libreforge.triggers.event.TriggerDispatchEvent import com.willfp.libreforge.triggers.impl.TriggerBowAttack import com.willfp.libreforge.triggers.impl.TriggerMeleeAttack import com.willfp.libreforge.triggers.impl.TriggerTridentAttack +import org.bukkit.NamespacedKey import org.bukkit.attribute.Attribute import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player @@ -12,7 +13,6 @@ import org.bukkit.event.Listener import java.util.UUID object TriggerPlaceholderListener : Listener { - private const val HITS_META_KEY = "libreforge_tracked_hits" @EventHandler fun handle(event: TriggerDispatchEvent) { @@ -82,21 +82,17 @@ object TriggerPlaceholderListener : Listener { val entity = event.trigger.data.victim ?: return @Suppress("UNCHECKED_CAST") - val map = entity.getMetadata(HITS_META_KEY).firstOrNull()?.value() as? MutableMap ?: mutableMapOf() - val hits = entity.getHits(player) - if (entity.health >= entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)!!.value) { - map[player.uniqueId] = 1 - } else { - map[player.uniqueId] = hits + 1 - } + val hits = + if (entity.health >= entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)!!.value) { + 0 + } else { + entity.getHits(player) + } - entity.removeMetadata(HITS_META_KEY, plugin) - entity.setMetadata(HITS_META_KEY, plugin.createMetadataValue(map)) + entity.pdc.setInt(NamespacedKey(plugin, "HITS:${player.uniqueId}"), hits) } private fun LivingEntity.getHits(player: Player): Int { - @Suppress("UNCHECKED_CAST") - val map = this.getMetadata(HITS_META_KEY).firstOrNull()?.value() as? MutableMap ?: mutableMapOf() - return map[player.uniqueId] ?: 0 + return this.pdc.getInt(NamespacedKey(plugin, "HITS:${player.uniqueId}")) ?: 0 } } diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectDamageNearbyEntities.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectDamageNearbyEntities.kt index 56bb3eef7..540e15773 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectDamageNearbyEntities.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectDamageNearbyEntities.kt @@ -3,19 +3,19 @@ package com.willfp.libreforge.effects.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.entities.Entities import com.willfp.eco.core.entities.TestableEntity -import com.willfp.libreforge.ViolationContext -import com.willfp.libreforge.arguments +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect -import com.willfp.libreforge.getDoubleFromExpression import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter +import org.bukkit.NamespacedKey import org.bukkit.entity.LivingEntity object EffectDamageNearbyEntities : Effect>("damage_nearby_entities") { override val parameters = setOf( TriggerParameter.LOCATION, TriggerParameter.PLAYER ) + private val ignoreNearbyDamage = NamespacedKey(plugin, "ignore-nearby-damage") override val arguments = arguments { require("radius", "You must specify the radius!") @@ -34,7 +34,7 @@ object EffectDamageNearbyEntities : Effect>("damage_n val damageSelf = config.getBoolOrNull("damage_self") ?: true for (entity in world.getNearbyEntities(location, radius, radius, radius)) { - if (entity.hasMetadata("ignore-nearby-damage")) { + if (entity.pdc.hasBool(ignoreNearbyDamage)) { continue } @@ -48,8 +48,8 @@ object EffectDamageNearbyEntities : Effect>("damage_n } } - entity.setMetadata("ignore-nearby-damage", plugin.metadataValueFactory.create(true)) - plugin.scheduler.runLater(5) { entity.removeMetadata("ignore-nearby-damage", plugin) } + entity.pdc.setBool(ignoreNearbyDamage, true) + plugin.scheduler.runLater(5) { entity.pdc.remove(ignoreNearbyDamage) } if (!damageSelf && (entity == player)) { continue diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectGlowNearbyBlocks.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectGlowNearbyBlocks.kt index 61e1bce89..482ceeb46 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectGlowNearbyBlocks.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectGlowNearbyBlocks.kt @@ -2,16 +2,15 @@ package com.willfp.libreforge.effects.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.util.TeamUtils -import com.willfp.libreforge.NoCompileData -import com.willfp.libreforge.arguments +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect -import com.willfp.libreforge.getIntFromExpression import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter import org.bukkit.Bukkit import org.bukkit.ChatColor import org.bukkit.Material +import org.bukkit.NamespacedKey import org.bukkit.block.Block import org.bukkit.entity.EntityType import org.bukkit.entity.LivingEntity @@ -20,6 +19,8 @@ import org.bukkit.event.EventHandler import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.world.ChunkLoadEvent import org.bukkit.event.world.ChunkUnloadEvent +import org.bukkit.persistence.PersistentDataContainer +import org.bukkit.persistence.PersistentDataType import org.bukkit.scoreboard.Team import java.util.UUID @@ -27,6 +28,8 @@ object EffectGlowNearbyBlocks : Effect("glow_nearby_blocks") { override val parameters = setOf( TriggerParameter.LOCATION ) + private val shulker = NamespacedKey(plugin, "gnb-shulker") + val uuid = NamespacedKey(plugin, "gnb-uuid") override val arguments = arguments { require("radius", "You must specify the radius!") @@ -79,13 +82,13 @@ object EffectGlowNearbyBlocks : Effect("glow_nearby_blocks") { shulker.setGravity(false) shulker.isGlowing = true shulker.isInvisible = true - shulker.setMetadata("gnb-shulker", plugin.metadataValueFactory.create(true)) + shulker.pdc.setBool(this.shulker, true) team.addEntry(shulker.uniqueId.toString()) - block.setMetadata("gnb-uuid", plugin.metadataValueFactory.create(shulker.uniqueId)) + block.pdc.setUUID(uuid, shulker.uniqueId) plugin.scheduler.runLater(duration.toLong()) { shulker.remove() - block.removeMetadata("gnb-uuid", plugin) + block.pdc.remove(uuid) } } @@ -95,14 +98,14 @@ object EffectGlowNearbyBlocks : Effect("glow_nearby_blocks") { @EventHandler fun handleChunkUnload(event: ChunkUnloadEvent) { event.chunk.entities.filterIsInstance() - .filter { it.hasMetadata("gnb-shulker") } + .filter { it.pdc.hasBool(shulker) } .forEach { it.remove() } } @EventHandler fun handleChunkLoad(event: ChunkLoadEvent) { event.chunk.entities.filterIsInstance() - .filter { it.hasMetadata("gnb-shulker") } + .filter { it.pdc.hasBool(shulker) } .forEach { it.remove() } } @@ -110,13 +113,11 @@ object EffectGlowNearbyBlocks : Effect("glow_nearby_blocks") { fun onBreak(event: BlockBreakEvent) { val block = event.block - if (!block.hasMetadata("gnb-uuid")) { + if (block.getPDCNoSave()?.hasUUID(uuid) != true) { return } - val uuid = block.getMetadata("gnb-uuid").firstOrNull { - it.value() is UUID - }?.value() as? UUID ?: return + val uuid = block.pdc.getUUID(uuid) ?: return Bukkit.getServer().getEntity(uuid)?.remove() @@ -125,7 +126,7 @@ object EffectGlowNearbyBlocks : Effect("glow_nearby_blocks") { 2.0, 2.0, 2.0 - ) { it.hasMetadata("gnb-shulker") }) { + ) { it.pdc.hasBool(shulker) }) { shulker.remove() } } diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectIgnite.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectIgnite.kt index 8d52399ae..f5e26331d 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectIgnite.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectIgnite.kt @@ -1,14 +1,12 @@ package com.willfp.libreforge.effects.impl import com.willfp.eco.core.config.interfaces.Config -import com.willfp.libreforge.NoCompileData -import com.willfp.libreforge.arguments +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect -import com.willfp.libreforge.getDoubleFromExpression -import com.willfp.libreforge.getIntFromExpression import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter +import org.bukkit.NamespacedKey import org.bukkit.event.EventHandler import org.bukkit.event.entity.EntityDamageEvent @@ -17,6 +15,7 @@ object EffectIgnite : Effect("ignite") { TriggerParameter.VICTIM, TriggerParameter.PLAYER ) + private val ignite = NamespacedKey(plugin, "libreforge-ignite") override val arguments = arguments { require("damage_per_tick", "You must specify the damage per fire tick!") @@ -29,7 +28,7 @@ object EffectIgnite : Effect("ignite") { val duration = config.getIntFromExpression("ticks", data) victim.fireTicks = duration - victim.setMetadata("libreforge-ignite", plugin.createMetadataValue(damage)) + victim.pdc.setDouble(ignite, damage) return true } @@ -39,10 +38,6 @@ object EffectIgnite : Effect("ignite") { if (event.cause != EntityDamageEvent.DamageCause.FIRE_TICK) { return } - if (!event.entity.hasMetadata("libreforge-ignite")) { - return - } - - event.damage = event.entity.getMetadata("libreforge-ignite")[0].asDouble() + event.damage = event.entity.pdc.getDouble(ignite) ?: return } } diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectPermanentPotionEffect.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectPermanentPotionEffect.kt index 5b53edecb..9e2b0561f 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectPermanentPotionEffect.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectPermanentPotionEffect.kt @@ -2,15 +2,17 @@ package com.willfp.libreforge.effects.impl import com.willfp.eco.core.Prerequisite import com.willfp.eco.core.config.interfaces.Config -import com.willfp.libreforge.NoCompileData -import com.willfp.libreforge.ProvidedHolder -import com.willfp.libreforge.arguments +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect import com.willfp.libreforge.effects.Identifiers import com.willfp.libreforge.plugin +import org.bukkit.NamespacedKey import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.player.PlayerRespawnEvent +import org.bukkit.persistence.PersistentDataAdapterContext +import org.bukkit.persistence.PersistentDataContainer +import org.bukkit.persistence.PersistentDataType import org.bukkit.potion.PotionEffect import org.bukkit.potion.PotionEffectType import java.util.UUID @@ -29,7 +31,7 @@ object EffectPermanentPotionEffect : Effect("permanent_potion_eff require("level", "You must specify the effect level!") } - private val metaKey = "libreforge_${this.id}" + private val storageKey = NamespacedKey(plugin, "libreforge_${this.id}") private val duration = if (Prerequisite.HAS_1_19_4.isMet) { -1 @@ -41,8 +43,7 @@ object EffectPermanentPotionEffect : Effect("permanent_potion_eff fun onRespawn(event: PlayerRespawnEvent) { val player = event.player - val meta = player.getMetadata(metaKey).firstOrNull()?.value() - as? MutableMap> ?: mutableMapOf() + val meta = player.pdc.get(storageKey, Storage) ?: mutableMapOf() for ((_, pair) in meta) { val (effectType, level) = pair @@ -83,17 +84,15 @@ object EffectPermanentPotionEffect : Effect("permanent_potion_eff player.addPotionEffect(effect) - val meta = player.getMetadata(metaKey).firstOrNull()?.value() - as? MutableMap> ?: mutableMapOf() + val meta = player.pdc.get(storageKey, Storage) ?: mutableMapOf() meta[identifiers.uuid] = Pair(effectType, level) - player.setMetadata(metaKey, plugin.metadataValueFactory.create(meta)) + player.pdc.set(storageKey, Storage, meta) } override fun onDisable(player: Player, identifiers: Identifiers, holder: ProvidedHolder) { - val meta = player.getMetadata(metaKey).firstOrNull()?.value() - as? MutableMap> ?: mutableMapOf() + val meta = player.pdc.get(storageKey, Storage) ?: mutableMapOf() val (toRemove, _) = meta[identifiers.uuid] ?: return @@ -110,8 +109,46 @@ object EffectPermanentPotionEffect : Effect("permanent_potion_eff } meta.remove(identifiers.uuid) - player.setMetadata(metaKey, plugin.metadataValueFactory.create(meta)) + player.pdc.set(storageKey, Storage, meta) player.removePotionEffect(toRemove) } + + object Storage : PersistentDataType>> { + override fun getPrimitiveType() = PersistentDataContainer::class.java + + override fun getComplexType(): Class>> { + return MutableMap::class.java as Class>> + } + private val namespace = plugin.name.lowercase() + + override fun fromPrimitive( + primitive: PersistentDataContainer, + context: PersistentDataAdapterContext + ): MutableMap> { + val map = mutableMapOf>() + for (key in primitive.keys) { + if (key.namespace != namespace) continue + val uuid = UUID.fromString(key.key) + val pair = primitive.getString(key) ?: continue + val index = pair.lastIndexOf(';') + val type = PotionEffectType.getByName(pair.substring(0 until index)) ?: continue + val power = pair.substring(index + 1).toInt() + map[uuid] = type to power + } + return map + } + + override fun toPrimitive( + complex: MutableMap>, + context: PersistentDataAdapterContext + ): PersistentDataContainer { + val new = context.newPersistentDataContainer() + for ((id, pair) in complex) { + new.setString(NamespacedKey(plugin, id.toString()), "${pair.first};${pair.second}") + } + return new + } + + } } diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectSpawnMobs.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectSpawnMobs.kt index c64100876..0d8bffdc9 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectSpawnMobs.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectSpawnMobs.kt @@ -4,14 +4,13 @@ import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.entities.Entities import com.willfp.eco.core.entities.TestableEntity import com.willfp.eco.util.NumberUtils -import com.willfp.libreforge.ViolationContext -import com.willfp.libreforge.arguments +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect -import com.willfp.libreforge.getDoubleFromExpression -import com.willfp.libreforge.getIntFromExpression import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter +import org.bukkit.Bukkit +import org.bukkit.NamespacedKey import org.bukkit.attribute.Attribute import org.bukkit.entity.LivingEntity import org.bukkit.entity.Mob @@ -34,6 +33,8 @@ object EffectSpawnMobs : Effect("spawn_mobs") { require("range", "You must specify the range to spawn in!") require("entity", "You must specify the mob to spawn!") } + private val target = NamespacedKey(plugin, "spawn-mobs-target") + private val avoid = NamespacedKey(plugin, "spawn-mobs-avoid") override fun onTrigger(config: Config, data: TriggerData, compileData: TestableEntity): Boolean { val location = data.location ?: return false @@ -42,7 +43,7 @@ object EffectSpawnMobs : Effect("spawn_mobs") { val player = data.player if (victim != null) { - if (victim.getMetadata("spawn-mobs-target").isNotEmpty()) { + if (victim.pdc.hasUUID(target)) { return false } } @@ -66,11 +67,11 @@ object EffectSpawnMobs : Effect("spawn_mobs") { if (victim != null) { mob.target = victim - mob.setMetadata("spawn-mobs-target", plugin.createMetadataValue(victim)) + mob.pdc.setUUID(target, victim.uniqueId) } if (player != null) { - mob.setMetadata("spawn-mobs-avoid", plugin.createMetadataValue(player.uniqueId)) + mob.pdc.setUUID(avoid, player.uniqueId) } mob.health = health @@ -87,13 +88,14 @@ object EffectSpawnMobs : Effect("spawn_mobs") { @EventHandler fun onSwitchTarget(event: EntityTargetEvent) { - if (event.entity.getMetadata("spawn-mobs-target").isNotEmpty()) { - val target = event.entity.getMetadata("spawn-mobs-target")[0].value() as? LivingEntity ?: return + if (event.entity.pdc.hasUUID(target)) { + val uuid = event.entity.pdc.getUUID(target) ?: return + val target = Bukkit.getEntity(uuid) as? LivingEntity ?: return event.target = target } - if (event.entity.getMetadata("spawn-mobs-avoid").isNotEmpty()) { - val uuid = event.entity.getMetadata("spawn-mobs-avoid")[0].value() as? UUID ?: return + if (event.entity.pdc.hasUUID(avoid)) { + val uuid = event.entity.pdc.getUUID(avoid) ?: return if (event.target?.uniqueId == uuid) { event.isCancelled = true } @@ -102,7 +104,7 @@ object EffectSpawnMobs : Effect("spawn_mobs") { @EventHandler(priority = EventPriority.LOW) fun onDropItem(event: EntityDeathEvent) { - if (event.entity.getMetadata("spawn-mobs-target").isEmpty()) { + if (event.entity.pdc.hasUUID(target)) { return } diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectTraceback.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectTraceback.kt index a55bc97ab..1d1909a20 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectTraceback.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/impl/EffectTraceback.kt @@ -1,15 +1,20 @@ package com.willfp.libreforge.effects.impl import com.willfp.eco.core.config.interfaces.Config -import com.willfp.libreforge.NoCompileData -import com.willfp.libreforge.arguments +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect -import com.willfp.libreforge.getDoubleFromExpression import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter import org.bukkit.Bukkit import org.bukkit.Location +import org.bukkit.NamespacedKey +import org.bukkit.persistence.PersistentDataAdapterContext +import org.bukkit.persistence.PersistentDataContainer +import org.bukkit.persistence.PersistentDataType +import java.util.stream.Collector +import java.util.stream.Collectors +import java.util.stream.Stream object EffectTraceback : Effect("traceback") { override val parameters = setOf( @@ -20,15 +25,14 @@ object EffectTraceback : Effect("traceback") { require("seconds", "You must specify the amount of seconds to go back in time (1-30)!") } - private val key = "libreforge_traceback" + private val key = NamespacedKey(plugin, "libreforge_traceback") override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean { val player = data.player ?: return false val time = config.getDoubleFromExpression("seconds", data).toInt().coerceIn(1..30) - @Suppress("UNCHECKED_CAST") - val times = player.getMetadata(key).getOrNull(0)?.value() as? List ?: emptyList() + val times = player.pdc.get(key, Times)?: emptyList() // Most recent is last val index = times.size - time @@ -43,13 +47,55 @@ object EffectTraceback : Effect("traceback") { override fun postRegister() { plugin.scheduler.runTimer(20, 20) { for (player in Bukkit.getOnlinePlayers()) { - @Suppress("UNCHECKED_CAST") - val times = player.getMetadata(key).getOrNull(0)?.value() as? List ?: emptyList() + val times = player.pdc.get(key, Times) ?: emptyList() val newTimes = (if (times.size < 29) times else times.drop(1)) + player.location - player.removeMetadata(key, plugin) - player.setMetadata(key, plugin.metadataValueFactory.create(newTimes)) + player.pdc.set(key, Times, newTimes) } } } + + private object Times : PersistentDataType, List> { + override fun getPrimitiveType() = Array ::class.java + + @Suppress("UNCHECKED_CAST") + override fun getComplexType() = List::class.java as Class> + private val x = NamespacedKey(plugin, "x") + private val y = NamespacedKey(plugin, "y") + private val z = NamespacedKey(plugin, "z") + private val yaw = NamespacedKey(plugin, "yaw") + private val pitch = NamespacedKey(plugin, "pitch") + private val world = NamespacedKey(plugin, "world") + override fun fromPrimitive( + primitive: Array, + context: PersistentDataAdapterContext + ): List = Stream.of(*primitive) + .map { + val world = it.getString(world) + Location( + if (world == null) null else Bukkit.getWorld(world), + it.getDouble(x)!!, + it.getDouble(y)!!, + it.getDouble(z)!!, + it.getFloat(yaw)!!, + it.getFloat(pitch)!! + ) + }.toList() + + override fun toPrimitive( + complex: List, + context: PersistentDataAdapterContext + ): Array = complex.stream() + .map { + val pdc = context.newPersistentDataContainer() + if (it.world != null) pdc.setString(world, it.world.name) + pdc.setDouble(x, it.x) + pdc.setDouble(y, it.y) + pdc.setDouble(z, it.z) + pdc.setFloat(yaw, it.yaw) + pdc.setFloat(pitch, it.pitch) + pdc + }.toList().toTypedArray() + + } } diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/templates/MineBlockEffect.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/templates/MineBlockEffect.kt index 1a4d77a7b..510017f14 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/templates/MineBlockEffect.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/templates/MineBlockEffect.kt @@ -2,10 +2,12 @@ package com.willfp.libreforge.effects.templates import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.util.runExempted +import com.willfp.libreforge.* import com.willfp.libreforge.effects.Effect import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter +import org.bukkit.NamespacedKey import org.bukkit.block.Block import org.bukkit.entity.Player @@ -13,18 +15,19 @@ abstract class MineBlockEffect(id: String) : Effect(id) { override val parameters = setOf( TriggerParameter.PLAYER ) + private val ignore = NamespacedKey(plugin, "block-ignore") override fun shouldTrigger(config: Config, data: TriggerData, compileData: T): Boolean { val block = data.block ?: data.location?.block ?: return false - return !block.hasMetadata("block-ignore") + return block.getPDCNoSave()?.hasBool(ignore) != true } protected fun Player.breakBlocksSafely(blocks: Collection) { this.runExempted { for (block in blocks) { - block.setMetadata("block-ignore", plugin.createMetadataValue(true)) + block.pdc.setBool(ignore, true) this.breakBlock(block) - block.removeMetadata("block-ignore", plugin) + block.pdc.remove(ignore) } } } diff --git a/core/src/main/kotlin/com/willfp/libreforge/triggers/impl/TriggerTridentAttack.kt b/core/src/main/kotlin/com/willfp/libreforge/triggers/impl/TriggerTridentAttack.kt index 9740b6e59..4e313c00d 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/triggers/impl/TriggerTridentAttack.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/triggers/impl/TriggerTridentAttack.kt @@ -6,14 +6,15 @@ import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.Trigger import com.willfp.libreforge.triggers.TriggerData import com.willfp.libreforge.triggers.TriggerParameter +import org.bukkit.NamespacedKey import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player import org.bukkit.entity.Trident import org.bukkit.event.EventHandler import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.ProjectileLaunchEvent +import java.util.WeakHashMap -private const val META_KEY = "libreforge_trident_holders" object TriggerTridentAttack : Trigger("trident_attack") { override val parameters = setOf( @@ -25,6 +26,7 @@ object TriggerTridentAttack : Trigger("trident_attack") { TriggerParameter.ITEM, TriggerParameter.VELOCITY ) + private val map = mutableMapOf>() @EventHandler(ignoreCancelled = true) fun onProjectileLaunch(event: ProjectileLaunchEvent) { @@ -35,12 +37,10 @@ object TriggerTridentAttack : Trigger("trident_attack") { return } - trident.setMetadata( - META_KEY, - plugin.metadataValueFactory.create( - shooter.holders - ) - ) + map[trident] = shooter.holders + plugin.scheduler.runLater(6_000L) { //5 minutes + map.remove(trident) + } } @EventHandler(ignoreCancelled = true) @@ -50,7 +50,6 @@ object TriggerTridentAttack : Trigger("trident_attack") { val shooter = trident.shooter as? Player ?: return - @Suppress("UNCHECKED_CAST") this.dispatch( shooter, TriggerData( @@ -63,7 +62,7 @@ object TriggerTridentAttack : Trigger("trident_attack") { velocity = trident.velocity, value = event.finalDamage ), - forceHolders = trident.getMetadata(META_KEY).firstOrNull()?.value() as? Collection + forceHolders = map[trident] ) } } From 251c145f015d7aefb7b909df0a2e1932be7a9119 Mon Sep 17 00:00:00 2001 From: masmc05 Date: Sun, 30 Apr 2023 15:28:33 +0300 Subject: [PATCH 2/3] fix hits --- .../com/willfp/libreforge/TriggerPlaceholderListener.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt b/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt index 772d1fec9..74ff91af3 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt @@ -10,7 +10,6 @@ import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.Listener -import java.util.UUID object TriggerPlaceholderListener : Listener { @@ -81,10 +80,9 @@ object TriggerPlaceholderListener : Listener { val player = event.trigger.data.player ?: return val entity = event.trigger.data.victim ?: return - @Suppress("UNCHECKED_CAST") val hits = if (entity.health >= entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)!!.value) { - 0 + 1 } else { entity.getHits(player) } From 342b5794f9ef4daa40134d76ff0fc9dc0f56c333 Mon Sep 17 00:00:00 2001 From: masmc05 Date: Mon, 1 May 2023 23:39:31 +0300 Subject: [PATCH 3/3] fix key to match regex --- core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt | 4 ++-- .../com/willfp/libreforge/TriggerPlaceholderListener.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt b/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt index eca0f7c53..5503a580e 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt @@ -78,8 +78,8 @@ fun PersistentDataContainer.getPDC(key: NamespacedKey, save: Boolean = true): Pe } val Block.pdc : PersistentDataContainer get() { - return this.chunk.pdc.getPDC(NamespacedKey(plugin, "block:$x;$y;$z"))!! + return this.chunk.pdc.getPDC(NamespacedKey(plugin, "block/$x/$y/$z"))!! } fun Block.getPDCNoSave(): PersistentDataContainer? { - return this.chunk.pdc.getPDC(NamespacedKey(plugin, "block:$x;$y;$z"), false) + return this.chunk.pdc.getPDC(NamespacedKey(plugin, "block/$x/$y/$z"), false) } \ No newline at end of file diff --git a/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt b/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt index 74ff91af3..6225e83d3 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/TriggerPlaceholderListener.kt @@ -87,10 +87,10 @@ object TriggerPlaceholderListener : Listener { entity.getHits(player) } - entity.pdc.setInt(NamespacedKey(plugin, "HITS:${player.uniqueId}"), hits) + entity.pdc.setInt(NamespacedKey(plugin, "HITS/${player.uniqueId}"), hits) } private fun LivingEntity.getHits(player: Player): Int { - return this.pdc.getInt(NamespacedKey(plugin, "HITS:${player.uniqueId}")) ?: 0 + return this.pdc.getInt(NamespacedKey(plugin, "HITS/${player.uniqueId}")) ?: 0 } }