entity data dynamic converter

fixes crashes on old servers
This commit is contained in:
Moritz Zwerger 2023-11-18 17:46:09 +01:00
parent 8c428d8383
commit 03f9736fc2
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 20 additions and 8 deletions

View File

@ -120,8 +120,8 @@ class EntityData(
observersLock.unlock() observersLock.unlock()
} }
inline operator fun <reified V> invoke(field: EntityDataField, default: V): EntityDataDelegate<V> { inline operator fun <reified V> invoke(field: EntityDataField, default: V, noinline converter: ((Any) -> V)? = null): EntityDataDelegate<V> {
val value = this.get(field, default) val value = this.get(field, default)
return EntityDataDelegate(value, field, this) return EntityDataDelegate(value, field, this, converter)
} }
} }

View File

@ -20,10 +20,18 @@ class EntityDataDelegate<V>(
default: V, default: V,
val field: EntityDataField, val field: EntityDataField,
val data: EntityData, val data: EntityData,
val converter: ((Any) -> V)? = null,
) : DataObserver<V>(default) { ) : DataObserver<V>(default) {
init { init {
data.observe<V>(field) { set(it ?: default) } data.observe<V>(field) {
if (it == null) {
set(default)
return@observe
}
val value = if (converter == null) it else converter.invoke(it)
set(value)
}
} }
override fun setValue(thisRef: Any, property: KProperty<*>, value: V) { override fun setValue(thisRef: Any, property: KProperty<*>, value: V) {

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.data.entities.entities package de.bixilon.minosoft.data.entities.entities
import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.primitive.BooleanUtil.toBoolean
import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.data.EntityData import de.bixilon.minosoft.data.entities.data.EntityData
import de.bixilon.minosoft.data.entities.data.EntityDataField import de.bixilon.minosoft.data.entities.data.EntityDataField
@ -22,7 +23,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
abstract class AgeableMob(connection: PlayConnection, entityType: EntityType, data: EntityData, position: Vec3d, rotation: EntityRotation) : PathfinderMob(connection, entityType, data, position, rotation) { abstract class AgeableMob(connection: PlayConnection, entityType: EntityType, data: EntityData, position: Vec3d, rotation: EntityRotation) : PathfinderMob(connection, entityType, data, position, rotation) {
@get:SynchronizedEntityData @get:SynchronizedEntityData
open val isBaby: Boolean by data(BABY, false) open val isBaby: Boolean by data(BABY, false) { it.toBoolean() }
companion object { companion object {

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.entities.entities
import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.observer.DataObserver.Companion.observe import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.kutil.primitive.BooleanUtil.toBoolean
import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.data.EntityData import de.bixilon.minosoft.data.entities.data.EntityData
import de.bixilon.minosoft.data.entities.data.EntityDataField import de.bixilon.minosoft.data.entities.data.EntityDataField
@ -32,7 +33,7 @@ class AreaEffectCloud(connection: PlayConnection, entityType: EntityType, data:
private set private set
@get:SynchronizedEntityData @get:SynchronizedEntityData
val ignoreRadius: Boolean by data(IGNORE_RADIUS_DATA, false) val ignoreRadius: Boolean by data(IGNORE_RADIUS_DATA, false) { it.toBoolean() }
@get:SynchronizedEntityData @get:SynchronizedEntityData
val radius: Float by data(RADIUS_DATA, 0.5f) val radius: Float by data(RADIUS_DATA, 0.5f)

View File

@ -18,6 +18,7 @@ import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.bit.BitByte.isBitMask import de.bixilon.kutil.bit.BitByte.isBitMask
import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.cast.CastUtil.unsafeNull import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.kutil.primitive.BooleanUtil.toBoolean
import de.bixilon.kutil.reflection.ReflectionUtil.forceSet import de.bixilon.kutil.reflection.ReflectionUtil.forceSet
import de.bixilon.kutil.reflection.ReflectionUtil.jvmField import de.bixilon.kutil.reflection.ReflectionUtil.jvmField
import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.kutil.time.TimeUtil.millis
@ -161,16 +162,17 @@ abstract class Entity(
get() = data.get(AIR_SUPPLY_DATA, 300) get() = data.get(AIR_SUPPLY_DATA, 300)
@get:SynchronizedEntityData @get:SynchronizedEntityData
val customName: ChatComponent? by data(CUSTOM_NAME_DATA, null) val customName: ChatComponent? by data(CUSTOM_NAME_DATA, null) { ChatComponent.of(it) }
@get:SynchronizedEntityData @get:SynchronizedEntityData
open val isNameVisible: Boolean by data(CUSTOM_NAME_VISIBLE_DATA, false) open val isNameVisible: Boolean by data(CUSTOM_NAME_VISIBLE_DATA, false) { it.toBoolean() }
@get:SynchronizedEntityData @get:SynchronizedEntityData
val isSilent: Boolean val isSilent: Boolean
get() = data.get(SILENT_DATA, false) get() = data.get(SILENT_DATA, false)
private var _hasNoGravity by data(NO_GRAVITY_DATA, false) private var _hasNoGravity by data(NO_GRAVITY_DATA, false) { it.toBoolean() }
@get:SynchronizedEntityData @get:SynchronizedEntityData
open val hasGravity: Boolean get() = !_hasNoGravity open val hasGravity: Boolean get() = !_hasNoGravity