pyhsics: use cached entity id

This finally fixes the deadlock caused by movement packets. Not sure why we need to send our own entity id, but I guess the answer is minecraft.
This commit is contained in:
Moritz Zwerger 2025-04-13 20:16:31 +02:00
parent 32f1b1fbfc
commit ed07b152d4
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
8 changed files with 14 additions and 24 deletions

View File

@ -13,7 +13,6 @@
package de.bixilon.minosoft.camera.target package de.bixilon.minosoft.camera.target
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.cast.CastUtil.nullCast import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.kutil.observer.DataObserver.Companion.observed import de.bixilon.kutil.observer.DataObserver.Companion.observed
@ -71,14 +70,12 @@ class TargetHandler(
private fun raycastEntity(origin: Vec3d, front: Vec3d, maxDistance: Double): EntityTarget? { private fun raycastEntity(origin: Vec3d, front: Vec3d, maxDistance: Double): EntityTarget? {
var target: EntityTarget? = null var target: EntityTarget? = null
val originF = Vec3(origin)
val world = camera.session.world val world = camera.session.world
world.entities.lock.acquire() world.entities.lock.acquire()
for (entity in world.entities) { for (entity in world.entities) {
if (entity is LocalPlayerEntity) continue
if (!entity.canRaycast) continue if (!entity.canRaycast) continue
if (Vec3dUtil.distance2(entity.renderInfo.position, originF) > MAX_ENTITY_DISTANCE) { if (Vec3dUtil.distance2(entity.renderInfo.position, origin) > MAX_ENTITY_DISTANCE) {
continue continue
} }
val aabb = entity.renderInfo.cameraAABB val aabb = entity.renderInfo.cameraAABB

View File

@ -60,7 +60,7 @@ abstract class Entity(
protected val random = Random() protected val random = Random()
var _id: Int? = null var _id: Int? = null
var _uuid: UUID? = null var _uuid: UUID? = null
val id: Int? open val id: Int?
get() { get() {
if (_id != null) return _id if (_id != null) return _id
_id = session.world.entities.getId(this) _id = session.world.entities.getId(this)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger * Copyright (C) 2020-2025 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 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.
* *
@ -58,6 +58,7 @@ class LocalPlayerEntity(
var inputActions = MovementInputActions() var inputActions = MovementInputActions()
override val clientControlled get() = true override val clientControlled get() = true
override val canRaycast get() = false
override var pose: Poses? = Poses.STANDING override var pose: Poses? = Poses.STANDING
@ -68,6 +69,8 @@ class LocalPlayerEntity(
override val uuid: UUID override val uuid: UUID
get() = super.uuid ?: session.account.uuid get() = super.uuid ?: session.account.uuid
override var id: Int = -1
override var isSprinting: Boolean = false override var isSprinting: Boolean = false
set(value) { set(value) {
if (value == field) { if (value == field) {

View File

@ -51,7 +51,7 @@ class MovementPacketSender(
if (this.sprinting == sprinting) { if (this.sprinting == sprinting) {
return return
} }
session.connection.send(EntityActionC2SP(player, session, sprinting.decide(EntityActionC2SP.EntityActions.START_SPRINTING, EntityActionC2SP.EntityActions.STOP_SPRINTING))) session.connection.send(EntityActionC2SP(player.id, sprinting.decide(EntityActionC2SP.EntityActions.START_SPRINTING, EntityActionC2SP.EntityActions.STOP_SPRINTING)))
this.sprinting = sprinting this.sprinting = sprinting
} }
@ -59,7 +59,7 @@ class MovementPacketSender(
if (this.sneaking == sneaking) { if (this.sneaking == sneaking) {
return return
} }
session.connection.send(EntityActionC2SP(player, session, sneaking.decide(EntityActionC2SP.EntityActions.START_SNEAKING, EntityActionC2SP.EntityActions.STOP_SNEAKING))) session.connection.send(EntityActionC2SP(player.id, sneaking.decide(EntityActionC2SP.EntityActions.START_SNEAKING, EntityActionC2SP.EntityActions.STOP_SNEAKING)))
this.sneaking = sneaking this.sneaking = sneaking
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger * Copyright (C) 2020-2025 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 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.
* *
@ -34,8 +34,7 @@ object ElytraPhysics {
private fun LocalPlayerPhysics.startElytraFalling() { private fun LocalPlayerPhysics.startElytraFalling() {
entity.isFlyingWithElytra = true entity.isFlyingWithElytra = true
val id = entity.session.world.entities.getId(entity) ?: return entity.session.connection.send(EntityActionC2SP(entity.id, EntityActionC2SP.EntityActions.START_ELYTRA_FLYING))
entity.session.connection.send(EntityActionC2SP(id, EntityActionC2SP.EntityActions.START_ELYTRA_FLYING))
} }
private fun LocalPlayerPhysics.canStartElytraFlight(): Boolean { private fun LocalPlayerPhysics.canStartElytraFlight(): Boolean {

View File

@ -27,9 +27,6 @@ import de.bixilon.minosoft.protocol.protocol.DefaultPacketMapping
import de.bixilon.minosoft.protocol.protocol.buffers.InByteBuffer import de.bixilon.minosoft.protocol.protocol.buffers.InByteBuffer
import de.bixilon.minosoft.protocol.versions.Version import de.bixilon.minosoft.protocol.versions.Version
import de.bixilon.minosoft.util.KUtil.readByteArray import de.bixilon.minosoft.util.KUtil.readByteArray
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.MessageToMessageDecoder import io.netty.handler.codec.MessageToMessageDecoder
import java.lang.reflect.InvocationTargetException import java.lang.reflect.InvocationTargetException
@ -56,11 +53,7 @@ class PacketDecoder(
} }
private fun decode(packetId: Int, length: Int, data: ByteArray): QueuedS2CP<S2CPacket>? { private fun decode(packetId: Int, length: Int, data: ByteArray): QueuedS2CP<S2CPacket>? {
val state = client.connection.state val state = client.connection.state ?: return null
if (state == null) {
Log.log(LogMessageType.NETWORK_IN, LogLevels.VERBOSE) { "Tried decoding a packet while being not connected. Skipping." }
return null
}
val type = version?.s2c?.get(state, packetId) ?: DefaultPacketMapping.S2C_PACKET_MAPPING[state, packetId] ?: throw UnknownPacketIdException(packetId, state, version) val type = version?.s2c?.get(state, packetId) ?: DefaultPacketMapping.S2C_PACKET_MAPPING[state, packetId] ?: throw UnknownPacketIdException(packetId, state, version)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger * Copyright (C) 2020-2025 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 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.
* *
@ -14,8 +14,6 @@ package de.bixilon.minosoft.protocol.packets.c2s.play.entity
import de.bixilon.kutil.enums.EnumUtil import de.bixilon.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.protocol.network.session.play.PlaySession
import de.bixilon.minosoft.protocol.packets.c2s.PlayC2SPacket import de.bixilon.minosoft.protocol.packets.c2s.PlayC2SPacket
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayOutByteBuffer import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayOutByteBuffer
@ -28,7 +26,6 @@ class EntityActionC2SP(
val action: EntityActions, val action: EntityActions,
val parameter: Int = 0, // currently used as jump boost for horse jumping val parameter: Int = 0, // currently used as jump boost for horse jumping
) : PlayC2SPacket { ) : PlayC2SPacket {
constructor(entity: Entity, session: PlaySession, action: EntityActions, parameter: Int = 0) : this(session.world.entities.getId(entity)!!, action, parameter)
override fun write(buffer: PlayOutByteBuffer) { override fun write(buffer: PlayOutByteBuffer) {
buffer.writeEntityId(entityId) buffer.writeEntityId(entityId)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger * Copyright (C) 2020-2025 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 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.
* *
@ -179,6 +179,7 @@ class InitializeS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
session.world.entities.clear(session, local = true) session.world.entities.clear(session, local = true)
session.world.entities.add(entityId, null, playerEntity) session.world.entities.add(entityId, null, playerEntity)
playerEntity.id = entityId
session.world.biomes.updateNoise(hashedSeed) session.world.biomes.updateNoise(hashedSeed)
session.world.border.reset() session.world.border.reset()