Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata is evil #96

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions core/src/main/kotlin/com/willfp/libreforge/PDCUtils.kt
Original file line number Diff line number Diff line change
@@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ 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
import org.bukkit.event.EventHandler
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) {
Expand Down Expand Up @@ -81,22 +80,17 @@ object TriggerPlaceholderListener : Listener {
val player = event.trigger.data.player ?: return
val entity = event.trigger.data.victim ?: return

@Suppress("UNCHECKED_CAST")
val map = entity.getMetadata(HITS_META_KEY).firstOrNull()?.value() as? MutableMap<UUID, Int> ?: 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) {
1
} 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<UUID, Int> ?: mutableMapOf()
return map[player.uniqueId] ?: 0
return this.pdc.getInt(NamespacedKey(plugin, "HITS/${player.uniqueId}")) ?: 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Collection<TestableEntity>>("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!")
Expand All @@ -34,7 +34,7 @@ object EffectDamageNearbyEntities : Effect<Collection<TestableEntity>>("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
}

Expand All @@ -48,8 +48,8 @@ object EffectDamageNearbyEntities : Effect<Collection<TestableEntity>>("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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -20,13 +19,17 @@ 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

object EffectGlowNearbyBlocks : Effect<NoCompileData>("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!")
Expand Down Expand Up @@ -79,13 +82,13 @@ object EffectGlowNearbyBlocks : Effect<NoCompileData>("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)
}
}

Expand All @@ -95,28 +98,26 @@ object EffectGlowNearbyBlocks : Effect<NoCompileData>("glow_nearby_blocks") {
@EventHandler
fun handleChunkUnload(event: ChunkUnloadEvent) {
event.chunk.entities.filterIsInstance<LivingEntity>()
.filter { it.hasMetadata("gnb-shulker") }
.filter { it.pdc.hasBool(shulker) }
.forEach { it.remove() }
}

@EventHandler
fun handleChunkLoad(event: ChunkLoadEvent) {
event.chunk.entities.filterIsInstance<LivingEntity>()
.filter { it.hasMetadata("gnb-shulker") }
.filter { it.pdc.hasBool(shulker) }
.forEach { it.remove() }
}

@EventHandler
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()

Expand All @@ -125,7 +126,7 @@ object EffectGlowNearbyBlocks : Effect<NoCompileData>("glow_nearby_blocks") {
2.0,
2.0,
2.0
) { it.hasMetadata("gnb-shulker") }) {
) { it.pdc.hasBool(shulker) }) {
shulker.remove()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -17,6 +15,7 @@ object EffectIgnite : Effect<NoCompileData>("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!")
Expand All @@ -29,7 +28,7 @@ object EffectIgnite : Effect<NoCompileData>("ignite") {
val duration = config.getIntFromExpression("ticks", data)

victim.fireTicks = duration
victim.setMetadata("libreforge-ignite", plugin.createMetadataValue(damage))
victim.pdc.setDouble(ignite, damage)

return true
}
Expand All @@ -39,10 +38,6 @@ object EffectIgnite : Effect<NoCompileData>("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
}
}
Loading