From f31d937b14f6cf6f4cdda5ea3f49448595aeda8f Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 25 Apr 2022 11:18:10 +0200 Subject: [PATCH] wip improved entity data mapping --- .../minosoft/data/entities/data/EntityData.kt | 54 +++++++++++++------ .../data/entities/data/EntityDataField.kt | 18 +++++++ .../minosoft/data/entities/entities/Entity.kt | 11 +++- .../minosoft/data/player/LocalPlayerEntity.kt | 3 +- .../entities/DefaultEntityFactories.kt | 22 ++++++++ .../data/registries/entities/EntityType.kt | 45 +++++++++++++--- .../data/registries/factory/DefaultFactory.kt | 8 ++- .../data/registries/registries/Registries.kt | 8 +-- .../entity/spawn/EntityExperienceOrbS2CP.kt | 2 + .../play/entity/spawn/EntityPaintingS2CP.kt | 3 +- .../entity/spawn/GlobalEntitySpawnS2CP.kt | 7 +-- 11 files changed, 147 insertions(+), 34 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataField.kt 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 e8b2e2758..6993c4d9c 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 @@ -14,7 +14,6 @@ package de.bixilon.minosoft.data.entities.data import de.bixilon.kotlinglm.vec3.Vec3i -import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.concurrent.lock.simple.SimpleLock import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.direction.Directions @@ -61,23 +60,48 @@ class EntityData( return sets.toString() } + @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") + inline fun get(field: EntityDataField, default: K?): K? { + lock.acquire() + try { + val type = connection.registries.getEntityDataIndex(field) ?: return default // field is not present (in this version) + val data = this.data[type] ?: return default + if (data !is K) { + Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Entity data $data can not be casted to ${K::class}" } + return default + } + return data + } finally { + lock.release() + } + } + + fun getBoolean(field: EntityDataField, default: Boolean): Boolean { + val data: Any = this.get(field, default) ?: return default + if (data is Boolean) { + return data + } + if (data is Number) { + return data == 0x01 + } + Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Invalid boolean $data" } + return default + } + + fun getBitMask(field: EntityDataField, bitMask: Int, default: Byte): Boolean { + val byte: Byte = get(field, default) ?: default + return BitByte.isBitMask(byte.toInt(), bitMask) + } + + fun getChatComponent(field: EntityDataField, default: Any?): ChatComponent { + return ChatComponent.of(get(field, default)) + } + + @Deprecated("refactor") inner class EntityDataHashMap : Int2ObjectOpenHashMap() { inline operator fun get(field: EntityDataFields): K { - lock.acquire() - try { - val index: Int = this@EntityData.connection.registries.getEntityMetaDataIndex(field) ?: return field.defaultValue.unsafeCast() // Can not find field. - get(index)?.let { - try { - return it as K - } catch (exception: ClassCastException) { - Log.log(LogMessageType.OTHER, level = LogLevels.WARN, message = exception) - } - } - return field.defaultValue as K - } finally { - lock.release() - } + throw TODO() } fun getPose(field: EntityDataFields): Poses? { diff --git a/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataField.kt b/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataField.kt new file mode 100644 index 000000000..6cc542cb6 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/entities/data/EntityDataField.kt @@ -0,0 +1,18 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.entities.data + +class EntityDataField(val names: List) { + constructor(name: String) : this(listOf(name)) +} 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 152e8a5b8..9cedcea09 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 @@ -29,6 +29,7 @@ import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.data.entities.Poses import de.bixilon.minosoft.data.entities.StatusEffectInstance import de.bixilon.minosoft.data.entities.data.EntityData +import de.bixilon.minosoft.data.entities.data.EntityDataField import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.entities.entities.vehicle.boat.Boat import de.bixilon.minosoft.data.physics.PhysicsEntity @@ -207,7 +208,7 @@ abstract class Entity( } private fun getEntityFlag(bitMask: Int): Boolean { - return data.sets.getBitMask(EntityDataFields.ENTITY_FLAGS, bitMask) + return data.getBitMask(FLAGS_DATA, bitMask, 0x00) } @get:SynchronizedEntityData(name = "On fire") @@ -634,6 +635,14 @@ abstract class Entity( companion object { + private val FLAGS_DATA = EntityDataField("ENTITY_FLAGS") + private val AIR_SUPPLY_DATA = EntityDataField("ENTITY_AIR_SUPPLY") + private val CUSTOM_NAME_DATA = EntityDataField("ENTITY_CUSTOM_NAME") + private val CUSTOM_NAME_VISIBLE_DATA = EntityDataField("ENTITY_CUSTOM_NAME_VISIBLE") + private val SILENT_DATA = EntityDataField("ENTITY_SILENT") + private val NO_GRAVITY_DATA = EntityDataField("ENTITY_NO_GRAVITY") + private val POSE_DATA = EntityDataField("ENTITY_POSE") + private val TICKS_FROZEN_DATA = EntityDataField("ENTITY_TICKS_FROZEN") private val BELOW_POSITION_MINUS = Vec3(0, 0.2f, 0) } } diff --git a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt index e447cbf5a..5fd0cc35c 100644 --- a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt @@ -40,6 +40,7 @@ import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.container.types.PlayerInventory import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.entities.EntityRotation +import de.bixilon.minosoft.data.entities.data.EntityData import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.entities.entities.player.RemotePlayerEntity import de.bixilon.minosoft.data.physics.PhysicsConstants @@ -75,7 +76,7 @@ import kotlin.math.pow class LocalPlayerEntity( account: Account, connection: PlayConnection, -) : PlayerEntity(connection, connection.registries.entityTypeRegistry[RemotePlayerEntity.RESOURCE_LOCATION]!!, Vec3d.EMPTY, EntityRotation(0.0, 0.0), account.username) { +) : PlayerEntity(connection, connection.registries.entityTypeRegistry[RemotePlayerEntity.RESOURCE_LOCATION]!!, EntityData(connection), Vec3d.EMPTY, EntityRotation(0.0, 0.0), account.username) { val healthCondition = PlayerHealthCondition() val experienceCondition = PlayerExperienceCondition() var spawnPosition: Vec3i = Vec3i.EMPTY diff --git a/src/main/java/de/bixilon/minosoft/data/registries/entities/DefaultEntityFactories.kt b/src/main/java/de/bixilon/minosoft/data/registries/entities/DefaultEntityFactories.kt index 13b778d14..c8b1b2d2d 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/entities/DefaultEntityFactories.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/entities/DefaultEntityFactories.kt @@ -31,9 +31,11 @@ import de.bixilon.minosoft.data.entities.entities.item.FallingBlockEntity import de.bixilon.minosoft.data.entities.entities.item.ItemEntity import de.bixilon.minosoft.data.entities.entities.item.PrimedTNT import de.bixilon.minosoft.data.entities.entities.monster.* +import de.bixilon.minosoft.data.entities.entities.monster.piglin.AbstractPiglin import de.bixilon.minosoft.data.entities.entities.monster.piglin.Piglin import de.bixilon.minosoft.data.entities.entities.monster.piglin.PiglinBrute import de.bixilon.minosoft.data.entities.entities.monster.raid.* +import de.bixilon.minosoft.data.entities.entities.npc.villager.AbstractVillager import de.bixilon.minosoft.data.entities.entities.npc.villager.Villager import de.bixilon.minosoft.data.entities.entities.npc.villager.WanderingTrader import de.bixilon.minosoft.data.entities.entities.player.RemotePlayerEntity @@ -44,6 +46,7 @@ import de.bixilon.minosoft.data.entities.entities.vehicle.boat.ChestBoat import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.factory.DefaultFactory import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +import de.bixilon.minosoft.util.KUtil.toResourceLocation @SuppressWarnings("deprecation") object DefaultEntityFactories : DefaultFactory>( @@ -181,4 +184,23 @@ object DefaultEntityFactories : DefaultFactory>( val tweakedEntityType = connection.registries.entityTypeRegistry[tweakedResourceLocation] ?: throw UnknownEntityException("Can not find tweaked entity type data in ${connection.version}: $tweakedResourceLocation for $factory") return tweakedFactory.build(connection, tweakedEntityType, data ?: EntityData(connection), position, rotation) } + + val ABSTRACT_ENTITY_META_CLASSES = mapOf( + "Entity".toResourceLocation() to Entity::class, + "LivingEntity".toResourceLocation() to LivingEntity::class, + "PersistentProjectileEntity".toResourceLocation() to Projectile::class, + "MobEntity".toResourceLocation() to Mob::class, + "PassiveEntity".toResourceLocation() to AgeableMob::class, + "TameableEntity".toResourceLocation() to TamableAnimal::class, + "FishEntity".toResourceLocation() to AbstractFish::class, + "AbstractDonkeyEntity".toResourceLocation() to AbstractChestedHorse::class, + "HorseBaseEntity".toResourceLocation() to AbstractHorse::class, + "SpellcastingIllagerEntity".toResourceLocation() to SpellcasterIllager::class, + "RaiderEntity".toResourceLocation() to Raider::class, + "AbstractFireballEntity".toResourceLocation() to Fireball::class, + "AbstractMinecartEntity".toResourceLocation() to AbstractMinecart::class, + "AbstractPiglinEntity".toResourceLocation() to AbstractPiglin::class, + "ThrownItemEntity".toResourceLocation() to ThrowableItemProjectile::class, + "MerchantEntity".toResourceLocation() to AbstractVillager::class, + ) } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt b/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt index 395ae8a9e..fee4b04c2 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt @@ -18,9 +18,10 @@ import de.bixilon.kutil.cast.CastUtil.nullCast import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.json.JsonUtil.toJsonObject import de.bixilon.kutil.primitive.BooleanUtil.toBoolean -import de.bixilon.minosoft.data.entities.EntityDataFields +import de.bixilon.kutil.primitive.IntUtil.toInt import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.data.entities.data.EntityData +import de.bixilon.minosoft.data.entities.data.EntityDataField import de.bixilon.minosoft.data.entities.entities.Entity import de.bixilon.minosoft.data.language.Translatable import de.bixilon.minosoft.data.registries.ResourceLocation @@ -31,7 +32,10 @@ import de.bixilon.minosoft.data.registries.registries.registry.ResourceLocationD import de.bixilon.minosoft.datafixer.EntityAttributeFixer.fix import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.util.KUtil.toResourceLocation -import java.util.* +import de.bixilon.minosoft.util.logging.Log +import de.bixilon.minosoft.util.logging.LogLevels +import de.bixilon.minosoft.util.logging.LogMessageType +import java.lang.reflect.Modifier data class EntityType( override val resourceLocation: ResourceLocation, @@ -45,7 +49,6 @@ data class EntityType( val spawnEgg: SpawnEggItem?, ) : RegistryItem(), Translatable { - override fun toString(): String { return resourceLocation.toString() } @@ -57,11 +60,35 @@ data class EntityType( companion object : ResourceLocationDeserializer { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: Map): EntityType? { check(registries != null) { "Registries is null!" } + val factory = DefaultEntityFactories[resourceLocation] data["meta"]?.toJsonObject()?.let { - for ((minosoftFieldName, index) in it) { - val minosoftField = EntityDataFields[minosoftFieldName.lowercase(Locale.getDefault())] - registries.entityMetaIndexMap[minosoftField] = index.unsafeCast() + val fields: MutableMap = mutableMapOf() + val metaClass = factory?.javaClass ?: DefaultEntityFactories.ABSTRACT_ENTITY_META_CLASSES[resourceLocation]?.java + if (metaClass == null) { + Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Can not find class for entity data ($resourceLocation)" } + return@let + } + for (field in metaClass.declaredFields) { + if (!Modifier.isStatic(field.modifiers)) { + continue + } + if (field.type != EntityDataField::class.java) { + continue + } + field.isAccessible = true + val dataField = field.get(null) as EntityDataField + for (name in dataField.names) { + fields[name] = dataField + } + } + for ((fieldName, index) in it) { + val fieldType = fields[fieldName] + if (fieldType == null) { + Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Can not find entity data $fieldName for $resourceLocation" } + continue + } + registries.entityDataIndexMap[fieldType] = index.toInt() } } if (data["width"] == null) { @@ -69,6 +96,10 @@ data class EntityType( return null } + if (factory == null) { + throw NullPointerException("Can not find entity factory for $resourceLocation") + } + val attributes: MutableMap = mutableMapOf() data["attributes"]?.toJsonObject()?.let { @@ -85,7 +116,7 @@ data class EntityType( fireImmune = data["fire_immune"]?.toBoolean() ?: false, sizeFixed = data["size_fixed"]?.toBoolean() ?: false, attributes = attributes.toMap(), - factory = DefaultEntityFactories[resourceLocation] ?: error("Can not find entity factory for $resourceLocation"), + factory = factory, spawnEgg = registries.itemRegistry[data["spawn_egg_item"]]?.nullCast(), // ToDo: Not yet in PixLyzer ) } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt b/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt index ffbd42124..b558e66d5 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.registries.CompanionResourceLocation import de.bixilon.minosoft.data.registries.MultiResourceLocationAble import de.bixilon.minosoft.data.registries.ResourceLocation -open class DefaultFactory(vararg factories: T) { +open class DefaultFactory(vararg factories: T) : Iterable { private val factories = factories private val factoryMap: Map @@ -46,4 +46,8 @@ open class DefaultFactory(vararg factories: T) { operator fun get(index: Int): T { return factories[index] } + + override fun iterator(): Iterator { + return factories.iterator() + } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt b/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt index 1b28a7745..7a2fb2138 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt @@ -16,8 +16,8 @@ import de.bixilon.kutil.cast.CastUtil.nullCast import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.json.JsonUtil.toJsonObject import de.bixilon.minosoft.data.container.InventorySlots -import de.bixilon.minosoft.data.entities.EntityDataFields import de.bixilon.minosoft.data.entities.block.BlockDataDataType +import de.bixilon.minosoft.data.entities.data.EntityDataField import de.bixilon.minosoft.data.entities.data.types.EntityDataDataTypes import de.bixilon.minosoft.data.registries.* import de.bixilon.minosoft.data.registries.biomes.Biome @@ -92,7 +92,7 @@ class Registries { val blockStateRegistry = BlockStateRegistry(false) - val entityMetaIndexMap: MutableMap = mutableMapOf() + val entityDataIndexMap: MutableMap = mutableMapOf() val entityTypeRegistry: Registry = Registry() val blockEntityTypeRegistry = BlockEntityTypeRegistry() @@ -117,8 +117,8 @@ class Registries { } } - fun getEntityMetaDataIndex(field: EntityDataFields): Int? { - return entityMetaIndexMap[field] ?: parentRegistries?.getEntityMetaDataIndex(field) + fun getEntityDataIndex(field: EntityDataField): Int? { + return entityDataIndexMap[field] ?: parentRegistries?.getEntityDataIndex(field) } private fun > loadEnumRegistry(version: Version, data: Any?, registry: EnumRegistry, alternative: PerVersionEnumRegistry) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityExperienceOrbS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityExperienceOrbS2CP.kt index 80a481de9..349aae1ff 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityExperienceOrbS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityExperienceOrbS2CP.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.entity.spawn import de.bixilon.kotlinglm.vec3.Vec3d +import de.bixilon.minosoft.data.entities.data.EntityData import de.bixilon.minosoft.data.entities.entities.ExperienceOrb import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -30,6 +31,7 @@ class EntityExperienceOrbS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val entity: ExperienceOrb = ExperienceOrb( connection = buffer.connection, entityType = buffer.connection.registries.entityTypeRegistry[ExperienceOrb.RESOURCE_LOCATION]!!, + data = EntityData(buffer.connection), position = if (buffer.versionId < ProtocolVersions.V_16W06A) { Vec3d(buffer.readFixedPointNumberInt(), buffer.readFixedPointNumberInt(), buffer.readFixedPointNumberInt()) } else { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityPaintingS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityPaintingS2CP.kt index b70c0cd00..bfd35b3c1 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityPaintingS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/EntityPaintingS2CP.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.entity.spawn import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.direction.Directions.Companion.byId +import de.bixilon.minosoft.data.entities.data.EntityData import de.bixilon.minosoft.data.entities.entities.decoration.Painting import de.bixilon.minosoft.data.registries.Motive import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent @@ -54,7 +55,7 @@ class EntityPaintingS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { position = buffer.readBlockPosition() direction = byId(buffer.readUnsignedByte()) } - entity = Painting(buffer.connection, buffer.connection.registries.entityTypeRegistry[Painting.RESOURCE_LOCATION]!!, position, direction, motive!!) + entity = Painting(buffer.connection, buffer.connection.registries.entityTypeRegistry[Painting.RESOURCE_LOCATION]!!, EntityData(buffer.connection), position, direction, motive!!) } override fun handle(connection: PlayConnection) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/GlobalEntitySpawnS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/GlobalEntitySpawnS2CP.kt index f08ff1e87..b119a770b 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/GlobalEntitySpawnS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/entity/spawn/GlobalEntitySpawnS2CP.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.entity.spawn import de.bixilon.kotlinglm.vec3.Vec3d +import de.bixilon.minosoft.data.entities.data.EntityData import de.bixilon.minosoft.data.entities.entities.LightningBolt import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -27,17 +28,17 @@ import de.bixilon.minosoft.util.logging.LogMessageType @LoadPacket(threadSafe = false) class GlobalEntitySpawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val entityId: Int = buffer.readVarInt() + val type = buffer.readByte() val entity: LightningBolt init { - val type = buffer.readByte() val position: Vec3d = if (buffer.versionId < ProtocolVersions.V_16W06A) { Vec3d(buffer.readFixedPointNumberInt(), buffer.readFixedPointNumberInt(), buffer.readFixedPointNumberInt()) } else { buffer.readVec3d() } - entity = LightningBolt(buffer.connection, buffer.connection.registries.entityTypeRegistry[LightningBolt.RESOURCE_LOCATION]!!, position) + entity = LightningBolt(buffer.connection, buffer.connection.registries.entityTypeRegistry[LightningBolt.RESOURCE_LOCATION]!!, EntityData(buffer.connection), position) } override fun handle(connection: PlayConnection) { @@ -47,6 +48,6 @@ class GlobalEntitySpawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } override fun log(reducedLog: Boolean) { - Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Global entity spawn (entityId=$entity, entity=$entity)" } + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Global entity spawn (entityId=$entity, type=$type, entity=$entity)" } } }