Update player entity positions server-side
This commit is contained in:
parent
818939267a
commit
fb047b22a3
19 changed files with 115 additions and 17 deletions
|
@ -84,6 +84,16 @@ class EntitiesGenerator(
|
|||
.initializer("Type")
|
||||
.build()
|
||||
)
|
||||
.addProperty(
|
||||
PropertySpec.builder(
|
||||
"dataStorage",
|
||||
ClassName("$BASE_PACKAGE.data", "DataStorage").parameterizedBy(ClassName(ENTITY_PACKAGE, name)),
|
||||
KModifier.OVERRIDE
|
||||
)
|
||||
.addAnnotation(AnnotationSpec.builder(Suppress::class).addMember("\"LeakingThis\"").build())
|
||||
.initializer("%T(this)", ClassName("$BASE_PACKAGE.data", "DataStorage"))
|
||||
.build()
|
||||
)
|
||||
.addType(
|
||||
TypeSpec.companionObjectBuilder("Type")
|
||||
.superclass(ClassName(ENTITY_PACKAGE, name + "Type"))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
package space.uranos.entity
|
||||
package space.uranos
|
||||
|
||||
enum class PaintingMotive(val width: Int, val height: Int) {
|
||||
// Order is important
|
|
@ -38,15 +38,12 @@ class DataStorage<ContextT : Any>(val context: ContextT) {
|
|||
@Suppress("UNCHECKED_CAST")
|
||||
val entry = map[key] as Entry<V>?
|
||||
|
||||
println(key)
|
||||
println(value)
|
||||
|
||||
if (entry == null) map[key] = Entry(key, value)
|
||||
else entry.value = value
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <V> get(key: DataStorageKey<ContextT, V>) = map[key] as V
|
||||
fun <V> get(key: DataStorageKey<ContextT, V>) = (map[key] as Entry<V>?)!!.value
|
||||
|
||||
suspend fun tick() {
|
||||
val actions = map.values.mapNotNull { it.tick() }
|
||||
|
@ -58,4 +55,7 @@ class DataStorage<ContextT : Any>(val context: ContextT) {
|
|||
key.tick(context, values)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
|
||||
inline fun <T : Any> cast() = this as DataStorage<T>
|
||||
}
|
|
@ -8,6 +8,7 @@ package space.uranos.entity
|
|||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import space.uranos.Uranos
|
||||
import space.uranos.data.DataStorage
|
||||
import space.uranos.world.World
|
||||
import java.util.*
|
||||
|
||||
|
@ -23,6 +24,7 @@ abstract class Entity internal constructor() {
|
|||
open val uuid: UUID = UUID.randomUUID()
|
||||
|
||||
abstract val type: EntityType
|
||||
abstract val dataStorage: DataStorage<out Entity>
|
||||
|
||||
private val worldMutex = Mutex()
|
||||
var world: World? = null; protected set
|
||||
|
|
|
@ -6,9 +6,13 @@
|
|||
package space.uranos.entity
|
||||
|
||||
import space.uranos.Position
|
||||
import space.uranos.data.DataStorage
|
||||
|
||||
open class ItemEntity(override var position: Position) : ObjectEntity() {
|
||||
final override val type: EntityType = Type
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
public override val dataStorage: DataStorage<ItemEntity> = DataStorage(this)
|
||||
|
||||
companion object Type : ItemEntityType()
|
||||
}
|
||||
|
|
|
@ -3,13 +3,29 @@
|
|||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
@file:Suppress("LeakingThis")
|
||||
|
||||
package space.uranos.entity
|
||||
|
||||
import space.uranos.Position
|
||||
import space.uranos.Vector
|
||||
import space.uranos.data.DataStorage
|
||||
import space.uranos.data.createDataStorageKey
|
||||
|
||||
abstract class LivingEntity : Entity(), Mobile {
|
||||
abstract var headPitch: Float
|
||||
abstract override var position: Position
|
||||
abstract override var velocity: Vector
|
||||
abstract override val dataStorage: DataStorage<out LivingEntity>
|
||||
|
||||
override var position: Position
|
||||
get() = dataStorage.cast<LivingEntity>().get(DataStorageKeys.position)
|
||||
set(value) = dataStorage.cast<LivingEntity>().set(DataStorageKeys.position, value)
|
||||
|
||||
object DataStorageKeys {
|
||||
val position = createDataStorageKey("position") { entity: LivingEntity, value: Position ->
|
||||
// TODO: Send the position to players
|
||||
println(value)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
package space.uranos.entity
|
||||
|
||||
import space.uranos.CardinalDirection
|
||||
import space.uranos.PaintingMotive
|
||||
import space.uranos.data.DataStorage
|
||||
import space.uranos.world.VoxelLocation
|
||||
|
||||
class PaintingEntity(
|
||||
|
@ -15,7 +17,8 @@ class PaintingEntity(
|
|||
) : Entity() {
|
||||
override val type: EntityType = Type
|
||||
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
override val dataStorage: DataStorage<PaintingEntity> = DataStorage(this)
|
||||
|
||||
companion object Type : PaintingEntityType()
|
||||
}
|
||||
|
|
|
@ -7,11 +7,12 @@ package space.uranos.entity
|
|||
|
||||
import space.uranos.Position
|
||||
import space.uranos.Vector
|
||||
import space.uranos.data.DataStorage
|
||||
import space.uranos.player.Player
|
||||
import space.uranos.world.World
|
||||
|
||||
open class PlayerEntity(
|
||||
override var position: Position,
|
||||
position: Position,
|
||||
/**
|
||||
* The player to which this entity belongs.
|
||||
*
|
||||
|
@ -23,6 +24,13 @@ open class PlayerEntity(
|
|||
final override val type: EntityType = Type
|
||||
override var velocity: Vector = Vector.ZERO
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
override val dataStorage: DataStorage<PlayerEntity> = DataStorage(this)
|
||||
|
||||
init {
|
||||
this.position = position
|
||||
}
|
||||
|
||||
/**
|
||||
* Because [world] is never `null` for player entities, you can use this property instead of writing `world!!`.
|
||||
*/
|
||||
|
|
|
@ -11,7 +11,7 @@ import space.uranos.net.packet.IncomingPacketCodec
|
|||
object PlayerOrientationPacketCodec :
|
||||
IncomingPacketCodec<PlayerOrientationPacket>(0x14, PlayerOrientationPacket::class) {
|
||||
override fun decode(msg: ByteBuf): PlayerOrientationPacket = PlayerOrientationPacket(
|
||||
360 - msg.readFloat() % 360,
|
||||
(360 - msg.readFloat()) % 360,
|
||||
msg.readFloat(),
|
||||
msg.readBoolean()
|
||||
)
|
||||
|
|
|
@ -7,8 +7,8 @@ package space.uranos.net.packet.play
|
|||
|
||||
import io.netty.buffer.ByteBuf
|
||||
import space.uranos.CardinalDirection
|
||||
import space.uranos.PaintingMotive
|
||||
import space.uranos.entity.PaintingEntity
|
||||
import space.uranos.entity.PaintingMotive
|
||||
import space.uranos.net.MinecraftProtocolDataTypes.writeUUID
|
||||
import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt
|
||||
import space.uranos.net.MinecraftProtocolDataTypes.writeVoxelLocation
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
package space.uranos.net.packet.play
|
||||
|
||||
import space.uranos.CardinalDirection
|
||||
import space.uranos.Location
|
||||
import space.uranos.entity.PaintingMotive
|
||||
import space.uranos.PaintingMotive
|
||||
import space.uranos.net.packet.OutgoingPacket
|
||||
import space.uranos.world.VoxelLocation
|
||||
import java.util.*
|
||||
|
|
|
@ -125,6 +125,7 @@ class UranosServer internal constructor() : Server() {
|
|||
private fun startDataStorageTicking() {
|
||||
scheduler.executeRepeating(1, 0) {
|
||||
players.forEach { it.dataStorage.tick() }
|
||||
entities.forEach { it.dataStorage.tick() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright 2020-2021 Moritz Ruth and Uranos contributors
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
package space.uranos.net.packet.play
|
||||
|
||||
import space.uranos.net.PacketReceivedEventHandler
|
||||
import space.uranos.net.UranosSession
|
||||
|
||||
object IncomingPlayerPositionPacketHandler : PacketReceivedEventHandler<IncomingPlayerPositionPacket>() {
|
||||
override suspend fun handle(session: UranosSession, packet: IncomingPlayerPositionPacket) {
|
||||
session.player!!.entity.position = packet.position
|
||||
}
|
||||
}
|
|
@ -11,7 +11,10 @@ import space.uranos.net.ProtocolPacketReceivedEventHandler
|
|||
object PlayProtocolHandler : ProtocolPacketReceivedEventHandler(
|
||||
mapOf(
|
||||
ClientSettingsPacket::class to ClientSettingsPacketHandler,
|
||||
IncomingKeepAlivePacket::class to IncomingKeepAlivePacketHandler,
|
||||
IncomingPlayerPositionPacket::class to IncomingPlayerPositionPacketHandler,
|
||||
IncomingPluginMessagePacket::class to IncomingPluginMessagePacketHandler,
|
||||
IncomingKeepAlivePacket::class to IncomingKeepAlivePacketHandler
|
||||
PlayerOrientationPacket::class to PlayerOrientationPacketHandler,
|
||||
PlayerLocationPacket::class to PlayerLocationPacketHandler
|
||||
)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2020-2021 Moritz Ruth and Uranos contributors
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
package space.uranos.net.packet.play
|
||||
|
||||
import space.uranos.net.PacketReceivedEventHandler
|
||||
import space.uranos.net.UranosSession
|
||||
|
||||
object PlayerLocationPacketHandler : PacketReceivedEventHandler<PlayerLocationPacket>() {
|
||||
override suspend fun handle(session: UranosSession, packet: PlayerLocationPacket) {
|
||||
val player = session.player!!
|
||||
player.entity.position = player.entity.position.copy(
|
||||
x = packet.location.x,
|
||||
y = packet.location.y,
|
||||
z = packet.location.z
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright 2020-2021 Moritz Ruth and Uranos contributors
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
package space.uranos.net.packet.play
|
||||
|
||||
import space.uranos.net.PacketReceivedEventHandler
|
||||
import space.uranos.net.UranosSession
|
||||
|
||||
object PlayerOrientationPacketHandler : PacketReceivedEventHandler<PlayerOrientationPacket>() {
|
||||
override suspend fun handle(session: UranosSession, packet: PlayerOrientationPacket) {
|
||||
val player = session.player!!
|
||||
player.entity.position = player.entity.position.copy(yaw = packet.yaw, pitch = packet.pitch)
|
||||
}
|
||||
}
|
|
@ -70,6 +70,7 @@ class UranosPlayer(
|
|||
|
||||
init {
|
||||
this.selectedHotbarSlot = selectedHotbarSlot
|
||||
this.playerListName = null
|
||||
}
|
||||
|
||||
override var currentlyViewedChunks = emptyList<Chunk>()
|
||||
|
|
Reference in a new issue