Merge Player and Connection
This commit is contained in:
parent
bd8d0e58df
commit
0b961b72ae
src/main/kotlin/ru/dbotthepony/kstarbound
@ -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),
|
||||
|
@ -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 }
|
||||
|
@ -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) {
|
||||
|
@ -1,6 +0,0 @@
|
||||
package ru.dbotthepony.kstarbound.client.network
|
||||
|
||||
import ru.dbotthepony.kstarbound.network.Player
|
||||
|
||||
class LocalPlayer(connection: ClientConnection) : Player<ClientConnection>(connection, connection.localUUID) {
|
||||
}
|
@ -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
|
||||
|
@ -29,7 +29,7 @@ object PacketRegistry {
|
||||
val size: Int
|
||||
get() = packets.size
|
||||
|
||||
fun <T : IPacket> add(type: KClass<T>, reader: IPacketReader<T>, direction: PacketDirection = PacketDirection.get(type)): PacketRegistry {
|
||||
private fun <T : IPacket> add(type: KClass<T>, reader: IPacketReader<T>, 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 <reified T : IPacket> add(reader: IPacketReader<T>, direction: PacketDirection = PacketDirection.get(T::class)): PacketRegistry {
|
||||
private inline fun <reified T : IPacket> add(reader: IPacketReader<T>, direction: PacketDirection = PacketDirection.get(T::class)): PacketRegistry {
|
||||
return add(T::class, reader, direction)
|
||||
}
|
||||
|
||||
|
@ -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<T : Connection>(val connection: T, val uuid: UUID) {
|
||||
var avatar: Avatar? = null
|
||||
var character: PlayerEntity? = null
|
||||
}
|
@ -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()
|
||||
|
@ -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<ChunkPos, ServerWorld.ITicket>()
|
||||
private val sentChunks = ObjectOpenHashSet<ChunkPos>()
|
||||
|
||||
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<ChunkPos>()
|
||||
|
||||
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 {
|
||||
|
@ -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<ServerConnection>(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<ChunkPos, ServerWorld.ITicket>()
|
||||
private val sentChunks = ObjectOpenHashSet<ChunkPos>()
|
||||
|
||||
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<ChunkPos>()
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,6 @@ data class TrackedPositionPacket(val pos: Vector2d) : IServerPacket {
|
||||
}
|
||||
|
||||
override fun play(connection: ServerConnection) {
|
||||
connection.player.trackedPosition = pos
|
||||
connection.trackedPosition = pos
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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<ServerPlayer>()
|
||||
val players = ObjectArraySet<ServerConnection>()
|
||||
|
||||
val thread = Thread(::runThread, "Starbound Server World $seed")
|
||||
var isStopped: Boolean = false
|
||||
|
Loading…
Reference in New Issue
Block a user