From 03f9736fc2b002f5787dc6117d68c8b74e239e6b Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Sat, 18 Nov 2023 17:46:09 +0100 Subject: [PATCH] entity data dynamic converter fixes crashes on old servers --- .../bixilon/minosoft/data/entities/data/EntityData.kt | 4 ++-- .../minosoft/data/entities/data/EntityDataDelegate.kt | 10 +++++++++- .../minosoft/data/entities/entities/AgeableMob.kt | 3 ++- .../minosoft/data/entities/entities/AreaEffectCloud.kt | 3 ++- .../bixilon/minosoft/data/entities/entities/Entity.kt | 8 +++++--- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/entities/data/EntityData.kt b/src/main/java/de/bixilon/minosoft/data/entities/data/EntityData.kt index 6e857c089..47c3ecfeb 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/data/EntityData.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/data/EntityData.kt @@ -120,8 +120,8 @@ class EntityData( observersLock.unlock() } - inline operator fun invoke(field: EntityDataField, default: V): EntityDataDelegate { + inline operator fun invoke(field: EntityDataField, default: V, noinline converter: ((Any) -> V)? = null): EntityDataDelegate { val value = this.get(field, default) - return EntityDataDelegate(value, field, this) + return EntityDataDelegate(value, field, this, converter) } } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataDelegate.kt b/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataDelegate.kt index c7d7bd753..ff1acc43d 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataDelegate.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataDelegate.kt @@ -20,10 +20,18 @@ class EntityDataDelegate( default: V, val field: EntityDataField, val data: EntityData, + val converter: ((Any) -> V)? = null, ) : DataObserver(default) { init { - data.observe(field) { set(it ?: default) } + data.observe(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) { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/AgeableMob.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/AgeableMob.kt index b080ae896..51d192342 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/AgeableMob.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/AgeableMob.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.data.entities.entities 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.data.EntityData 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) { @get:SynchronizedEntityData - open val isBaby: Boolean by data(BABY, false) + open val isBaby: Boolean by data(BABY, false) { it.toBoolean() } companion object { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/AreaEffectCloud.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/AreaEffectCloud.kt index 55dac4ac3..15b808a98 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/AreaEffectCloud.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/AreaEffectCloud.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.entities.entities import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3d 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.data.EntityData import de.bixilon.minosoft.data.entities.data.EntityDataField @@ -32,7 +33,7 @@ class AreaEffectCloud(connection: PlayConnection, entityType: EntityType, data: private set @get:SynchronizedEntityData - val ignoreRadius: Boolean by data(IGNORE_RADIUS_DATA, false) + val ignoreRadius: Boolean by data(IGNORE_RADIUS_DATA, false) { it.toBoolean() } @get:SynchronizedEntityData val radius: Float by data(RADIUS_DATA, 0.5f) diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt index 38e88346d..482a5f6bd 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt @@ -18,6 +18,7 @@ import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kutil.bit.BitByte.isBitMask import de.bixilon.kutil.cast.CastUtil.unsafeCast 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.jvmField import de.bixilon.kutil.time.TimeUtil.millis @@ -161,16 +162,17 @@ abstract class Entity( get() = data.get(AIR_SUPPLY_DATA, 300) @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 - 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 val isSilent: Boolean 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 open val hasGravity: Boolean get() = !_hasNoGravity