From 0b961b72ae14e7261a862b9a03a5eb039fac846a Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 2 Feb 2024 17:00:02 +0700 Subject: [PATCH] Merge Player and Connection --- .../kotlin/ru/dbotthepony/kstarbound/Main.kt | 16 +-- .../kstarbound/client/StarboundClient.kt | 1 - .../client/network/ClientConnection.kt | 5 - .../kstarbound/client/network/LocalPlayer.kt | 6 - .../kstarbound/network/Connection.kt | 7 +- .../kstarbound/network/PacketRegistry.kt | 4 +- .../dbotthepony/kstarbound/network/Player.kt | 10 -- .../kstarbound/server/StarboundServer.kt | 7 +- .../server/network/ServerConnection.kt | 124 ++++++++++++++++- .../kstarbound/server/network/ServerPlayer.kt | 127 ------------------ .../network/packets/TrackedPositionPacket.kt | 2 +- .../network/packets/TrackedSizePacket.kt | 4 +- .../kstarbound/server/world/ServerWorld.kt | 7 +- 13 files changed, 140 insertions(+), 180 deletions(-) delete mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/client/network/LocalPlayer.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/network/Player.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerPlayer.kt diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt index 1b12d2ba..ab600d1b 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt @@ -68,8 +68,6 @@ fun main() { Starbound.initializeGame() - var ply: PlayerEntity? = null - Starbound.mailboxInitialized.submit { //ply = PlayerEntity(client.world!!) @@ -139,7 +137,7 @@ fun main() { //item.movement.applyVelocity(Vector2d(rand.nextDouble() * 1000.0 - 500.0, rand.nextDouble() * 1000.0 - 500.0)) } - client.connectToLocalServer(client, server.channels.createLocalChannel(), UUID(0L, 0L)) + client.connectToLocalServer(client, server.channels.createLocalChannel(), UUID.randomUUID()) } //ent.position += Vector2d(y = 14.0, x = -10.0) @@ -163,12 +161,14 @@ fun main() { } while (client.renderFrame()) { - if (ply != null) { - client.camera.pos = ply!!.position + val ply = client.activeConnection?.character - ply!!.movement.controlMove = if (client.input.KEY_A_DOWN) Direction.LEFT else if (client.input.KEY_D_DOWN) Direction.RIGHT else null - ply!!.movement.controlJump = client.input.KEY_SPACE_DOWN - ply!!.movement.controlRun = !client.input.KEY_LEFT_SHIFT_DOWN + if (ply != null) { + client.camera.pos = ply.position + + ply.movement.controlMove = if (client.input.KEY_A_DOWN) Direction.LEFT else if (client.input.KEY_D_DOWN) Direction.RIGHT else null + ply.movement.controlJump = client.input.KEY_SPACE_DOWN + ply.movement.controlRun = !client.input.KEY_LEFT_SHIFT_DOWN } else { client.camera.pos += Vector2d( (if (client.input.KEY_A_DOWN) -Starbound.TICK_TIME_ADVANCE * 32f / client.settings.zoom else 0.0) + (if (client.input.KEY_D_DOWN) Starbound.TICK_TIME_ADVANCE * 32f / client.settings.zoom else 0.0), diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt index 1d425bf0..122d5176 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt @@ -1001,7 +1001,6 @@ class StarboundClient : Closeable { if (activeConnection != null) { activeConnection.send(TrackedPositionPacket(camera.pos)) - activeConnection.send(TrackedSizePacket(2, 2)) } uberShaderPrograms.forEachValid { it.viewMatrix = viewportMatrixScreen } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/ClientConnection.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/ClientConnection.kt index 8bdab58a..f50e2809 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/ClientConnection.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/ClientConnection.kt @@ -25,15 +25,10 @@ class ClientConnection(val client: StarboundClient, type: ConnectionType, uuid: helloListener = HelloListener(this, channel!!).sendHello(localUUID) } - override var player: LocalPlayer by Delegates.notNull() - private set - override fun onHelloReceived(helloPacket: HelloPacket) { - player = LocalPlayer(this) } override fun inGame() { - } override fun channelRead(ctx: ChannelHandlerContext, msg: Any) { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/LocalPlayer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/LocalPlayer.kt deleted file mode 100644 index cca97171..00000000 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/network/LocalPlayer.kt +++ /dev/null @@ -1,6 +0,0 @@ -package ru.dbotthepony.kstarbound.client.network - -import ru.dbotthepony.kstarbound.network.Player - -class LocalPlayer(connection: ClientConnection) : Player(connection, connection.localUUID) { -} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/network/Connection.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/network/Connection.kt index 0d408e6f..20d3f587 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/network/Connection.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/network/Connection.kt @@ -9,17 +9,20 @@ import org.apache.logging.log4j.LogManager import ru.dbotthepony.kstarbound.network.packets.DisconnectPacket import ru.dbotthepony.kstarbound.network.packets.HelloListener import ru.dbotthepony.kstarbound.network.packets.HelloPacket +import ru.dbotthepony.kstarbound.player.Avatar +import ru.dbotthepony.kstarbound.world.entities.PlayerEntity import java.util.* abstract class Connection(val side: ConnectionSide, val type: ConnectionType, val localUUID: UUID) : ChannelInboundHandlerAdapter(), IConnectionDetails { abstract override fun channelRead(ctx: ChannelHandlerContext, msg: Any) + var avatar: Avatar? = null + var character: PlayerEntity? = null + protected var channel: Channel? = null protected var otherSide: HelloPacket? = null protected var helloListener: HelloListener? = null - abstract val player: Player<*> - override val protocolVersion: Int get() = otherSide?.protocolVersion ?: 0 override val engineVersion: String diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt index a24ced89..023bba6f 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt @@ -29,7 +29,7 @@ object PacketRegistry { val size: Int get() = packets.size - fun add(type: KClass, reader: IPacketReader, direction: PacketDirection = PacketDirection.get(type)): PacketRegistry { + private fun add(type: KClass, reader: IPacketReader, direction: PacketDirection = PacketDirection.get(type)): PacketRegistry { if (packets.size >= 255) throw IndexOutOfBoundsException("Unable to add any more packet types! 255 is the max") @@ -42,7 +42,7 @@ object PacketRegistry { return this } - inline fun add(reader: IPacketReader, direction: PacketDirection = PacketDirection.get(T::class)): PacketRegistry { + private inline fun add(reader: IPacketReader, direction: PacketDirection = PacketDirection.get(T::class)): PacketRegistry { return add(T::class, reader, direction) } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/network/Player.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/network/Player.kt deleted file mode 100644 index 99359936..00000000 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/network/Player.kt +++ /dev/null @@ -1,10 +0,0 @@ -package ru.dbotthepony.kstarbound.network - -import ru.dbotthepony.kstarbound.player.Avatar -import ru.dbotthepony.kstarbound.world.entities.PlayerEntity -import java.util.UUID - -abstract class Player(val connection: T, val uuid: UUID) { - var avatar: Avatar? = null - var character: PlayerEntity? = null -} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/StarboundServer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/StarboundServer.kt index 2cd4e271..f8c59049 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/StarboundServer.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/StarboundServer.kt @@ -1,9 +1,8 @@ package ru.dbotthepony.kstarbound.server -import ru.dbotthepony.kstarbound.client.network.packets.InitialChunkDataPacket import ru.dbotthepony.kstarbound.client.network.packets.JoinWorldPacket import ru.dbotthepony.kstarbound.server.network.ServerChannels -import ru.dbotthepony.kstarbound.server.network.ServerPlayer +import ru.dbotthepony.kstarbound.server.network.ServerConnection import ru.dbotthepony.kstarbound.server.world.ServerWorld import ru.dbotthepony.kstarbound.util.MailboxExecutorService import java.io.Closeable @@ -41,11 +40,11 @@ abstract class StarboundServer(val root: File) : Closeable { thread.start() } - fun playerInGame(player: ServerPlayer) { + fun playerInGame(player: ServerConnection) { val world = worlds.first() player.world = world world.players.add(player) - player.connection.send(JoinWorldPacket(world)) + player.send(JoinWorldPacket(world)) } protected abstract fun close0() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerConnection.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerConnection.kt index c69f8a23..7897e5d7 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerConnection.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerConnection.kt @@ -1,18 +1,132 @@ package ru.dbotthepony.kstarbound.server.network import io.netty.channel.ChannelHandlerContext +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import org.apache.logging.log4j.LogManager +import ru.dbotthepony.kstarbound.client.network.packets.ForgetChunkPacket +import ru.dbotthepony.kstarbound.client.network.packets.InitialChunkDataPacket +import ru.dbotthepony.kstarbound.client.network.packets.SpawnWorldObjectPacket import ru.dbotthepony.kstarbound.network.Connection import ru.dbotthepony.kstarbound.network.ConnectionSide import ru.dbotthepony.kstarbound.network.ConnectionType import ru.dbotthepony.kstarbound.network.IServerPacket import ru.dbotthepony.kstarbound.network.packets.HelloPacket import ru.dbotthepony.kstarbound.server.StarboundServer +import ru.dbotthepony.kstarbound.server.world.ServerWorld +import ru.dbotthepony.kstarbound.world.ChunkPos +import ru.dbotthepony.kvector.vector.Vector2d import java.util.* -import kotlin.properties.Delegates -// server -> client class ServerConnection(val server: StarboundServer, type: ConnectionType) : Connection(ConnectionSide.SERVER, type, UUID(0L, 0L)) { + var world: ServerWorld? = null + set(value) { + field = value + needsToRecomputeTrackedChunks = true + } + + var trackedPosition: Vector2d = Vector2d(238.0, 685.0) + set(value) { + if (field != value) { + field = value + needsToRecomputeTrackedChunks = true + } + } + + var trackedPositionChunk: ChunkPos = ChunkPos.ZERO + private set + + var trackedChunksWidth = 4 + set(value) { + if (field != value) { + field = value + needsToRecomputeTrackedChunks = true + } + } + + var trackedChunksHeight = 4 + set(value) { + if (field != value) { + field = value + needsToRecomputeTrackedChunks = true + } + } + + private val tickets = Object2ObjectOpenHashMap() + private val sentChunks = ObjectOpenHashSet() + + private var needsToRecomputeTrackedChunks = true + + private fun recomputeTrackedChunks() { + val world = world ?: return + val trackedPositionChunk = world.geometry.chunkFromCell(trackedPosition) + needsToRecomputeTrackedChunks = false + if (trackedPositionChunk == this.trackedPositionChunk) return + + val tracked = ObjectOpenHashSet() + + for (x in -trackedChunksWidth .. trackedChunksWidth) { + for (y in -trackedChunksHeight .. trackedChunksHeight) { + tracked.add(world.geometry.wrap(trackedPositionChunk + ChunkPos(x, y))) + } + } + + val itr = tickets.entries.iterator() + + for ((pos, ticket) in itr) { + if (pos !in tracked) { + ticket.cancel() + itr.remove() + } + } + + for (pos in tracked) { + if (pos !in tickets) { + tickets[pos] = world.permanentChunkTicket(pos) + } + } + } + + fun tick() { + val world = world + + if (world == null) { + tickets.values.forEach { it.cancel() } + tickets.clear() + sentChunks.clear() + return + } + + if (needsToRecomputeTrackedChunks) { + recomputeTrackedChunks() + } + + for (pos in tickets.keys) { + if (pos !in sentChunks) { + val chunk = world.chunkMap[pos] + + if (chunk != null) { + send(InitialChunkDataPacket(chunk)) + + chunk.objects.forEach { + send(SpawnWorldObjectPacket(it.serialize())) + } + + sentChunks.add(pos) + } + } + } + + val itr = sentChunks.iterator() + + for (pos in itr) { + if (pos !in tickets) { + send(ForgetChunkPacket(pos)) + itr.remove() + } + } + } + override fun channelRead(ctx: ChannelHandlerContext, msg: Any) { if (msg is IServerPacket) { try { @@ -27,15 +141,11 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn } } - override var player: ServerPlayer by Delegates.notNull() - private set - override fun inGame() { - server.playerInGame(player) + server.playerInGame(this) } override fun onHelloReceived(helloPacket: HelloPacket) { - player = ServerPlayer(this) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerPlayer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerPlayer.kt deleted file mode 100644 index db080856..00000000 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/ServerPlayer.kt +++ /dev/null @@ -1,127 +0,0 @@ -package ru.dbotthepony.kstarbound.server.network - -import it.unimi.dsi.fastutil.longs.LongOpenHashSet -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet -import ru.dbotthepony.kstarbound.client.network.packets.ForgetChunkPacket -import ru.dbotthepony.kstarbound.client.network.packets.InitialChunkDataPacket -import ru.dbotthepony.kstarbound.client.network.packets.SpawnWorldObjectPacket -import ru.dbotthepony.kstarbound.network.Player -import ru.dbotthepony.kstarbound.server.StarboundServer -import ru.dbotthepony.kstarbound.server.world.ServerWorld -import ru.dbotthepony.kstarbound.world.ChunkPos -import ru.dbotthepony.kvector.vector.Vector2d -import kotlin.concurrent.withLock - -class ServerPlayer(connection: ServerConnection) : Player(connection, connection.uuid) { - inline val server: StarboundServer - get() = connection.server - - var world: ServerWorld? = null - set(value) { - field = value - needsToRecomputeTrackedChunks = true - } - - var trackedPosition: Vector2d = Vector2d(238.0, 685.0) - set(value) { - if (field != value) { - field = value - needsToRecomputeTrackedChunks = true - } - } - - var trackedPositionChunk: ChunkPos = ChunkPos.ZERO - private set - - var trackedChunksWidth = 1 - set(value) { - if (field != value) { - field = value - needsToRecomputeTrackedChunks = true - } - } - - var trackedChunksHeight = 1 - set(value) { - if (field != value) { - field = value - needsToRecomputeTrackedChunks = true - } - } - - private val tickets = Object2ObjectOpenHashMap() - private val sentChunks = ObjectOpenHashSet() - - private var needsToRecomputeTrackedChunks = true - - private fun recomputeTrackedChunks() { - val world = world ?: return - val trackedPositionChunk = world.geometry.chunkFromCell(trackedPosition) - needsToRecomputeTrackedChunks = false - if (trackedPositionChunk == this.trackedPositionChunk) return - - val tracked = ObjectOpenHashSet() - - for (x in -trackedChunksWidth .. trackedChunksWidth) { - for (y in -trackedChunksHeight .. trackedChunksHeight) { - tracked.add(world.geometry.wrap(trackedPositionChunk + ChunkPos(x, y))) - } - } - - val itr = tickets.entries.iterator() - - for ((pos, ticket) in itr) { - if (pos !in tracked) { - ticket.cancel() - itr.remove() - } - } - - for (pos in tracked) { - if (pos !in tickets) { - tickets[pos] = world.permanentChunkTicket(pos) - } - } - } - - fun tick() { - val world = world - - if (world == null) { - tickets.values.forEach { it.cancel() } - tickets.clear() - sentChunks.clear() - return - } - - if (needsToRecomputeTrackedChunks) { - recomputeTrackedChunks() - } - - for (pos in tickets.keys) { - if (pos !in sentChunks) { - val chunk = world.chunkMap[pos] - - if (chunk != null) { - connection.send(InitialChunkDataPacket(chunk)) - - chunk.objects.forEach { - connection.send(SpawnWorldObjectPacket(it.serialize())) - } - - sentChunks.add(pos) - } - } - } - - val itr = sentChunks.iterator() - - for (pos in itr) { - if (pos !in tickets) { - connection.send(ForgetChunkPacket(pos)) - itr.remove() - } - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedPositionPacket.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedPositionPacket.kt index fa0a3a33..0400b5c9 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedPositionPacket.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedPositionPacket.kt @@ -16,6 +16,6 @@ data class TrackedPositionPacket(val pos: Vector2d) : IServerPacket { } override fun play(connection: ServerConnection) { - connection.player.trackedPosition = pos + connection.trackedPosition = pos } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedSizePacket.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedSizePacket.kt index b3c2a1f6..d1877874 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedSizePacket.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/network/packets/TrackedSizePacket.kt @@ -19,7 +19,7 @@ data class TrackedSizePacket(val width: Int, val height: Int) : IServerPacket { } override fun play(connection: ServerConnection) { - connection.player.trackedChunksWidth = width - connection.player.trackedChunksHeight = height + connection.trackedChunksWidth = width + connection.trackedChunksHeight = height } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt index 39a73dba..ad07e647 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt @@ -6,15 +6,12 @@ import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet import it.unimi.dsi.fastutil.objects.ObjectArraySet import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.server.StarboundServer -import ru.dbotthepony.kstarbound.server.network.ServerPlayer +import ru.dbotthepony.kstarbound.server.network.ServerConnection import ru.dbotthepony.kstarbound.util.KOptional import ru.dbotthepony.kstarbound.util.composeFutures import ru.dbotthepony.kstarbound.world.ChunkPos -import ru.dbotthepony.kstarbound.world.IChunkSubscriber import ru.dbotthepony.kstarbound.world.World import ru.dbotthepony.kstarbound.world.WorldGeometry -import ru.dbotthepony.kstarbound.world.entities.Entity -import ru.dbotthepony.kstarbound.world.entities.WorldObject import java.io.Closeable import java.util.concurrent.CompletableFuture import java.util.concurrent.atomic.AtomicInteger @@ -31,7 +28,7 @@ class ServerWorld( server.worlds.add(this) } - val players = ObjectArraySet() + val players = ObjectArraySet() val thread = Thread(::runThread, "Starbound Server World $seed") var isStopped: Boolean = false