Now original game client can properly connect and be on server, and also can request a disconnect
This commit is contained in:
parent
66aa99acc2
commit
21f3a66283
@ -16,6 +16,7 @@ import ru.dbotthepony.kstarbound.network.ConnectionType
|
|||||||
import ru.dbotthepony.kstarbound.network.IClientPacket
|
import ru.dbotthepony.kstarbound.network.IClientPacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.ClientContextUpdatePacket
|
import ru.dbotthepony.kstarbound.network.packets.ClientContextUpdatePacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.ProtocolRequestPacket
|
import ru.dbotthepony.kstarbound.network.packets.ProtocolRequestPacket
|
||||||
|
import ru.dbotthepony.kstarbound.network.packets.serverbound.ClientDisconnectRequestPacket
|
||||||
import java.net.SocketAddress
|
import java.net.SocketAddress
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -50,15 +51,47 @@ class ClientConnection(val client: StarboundClient, type: ConnectionType) : Conn
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun flush() {
|
override fun flush() {
|
||||||
val entries = rpc.write()
|
if (!pendingDisconnect) {
|
||||||
|
val entries = rpc.write()
|
||||||
|
|
||||||
if (entries != null) {
|
if (entries != null) {
|
||||||
channel.write(ClientContextUpdatePacket(entries, KOptional(), KOptional()))
|
channel.write(ClientContextUpdatePacket(entries, KOptional(), KOptional()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.flush()
|
super.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var pendingDisconnect = false
|
||||||
|
|
||||||
|
fun disconnectNow() {
|
||||||
|
pendingDisconnect = false
|
||||||
|
|
||||||
|
if (channel.isOpen) {
|
||||||
|
channel.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun disconnect(reason: String) {
|
||||||
|
if (pendingDisconnect)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (channel.isOpen) {
|
||||||
|
pendingDisconnect = true
|
||||||
|
sendAndFlush(ClientDisconnectRequestPacket)
|
||||||
|
} else {
|
||||||
|
disconnectNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onChannelClosed() {
|
||||||
|
super.onChannelClosed()
|
||||||
|
|
||||||
|
if (pendingDisconnect) {
|
||||||
|
disconnectNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LOGGER = LogManager.getLogger()
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType) :
|
|||||||
|
|
||||||
val hasChannel get() = ::channel.isInitialized
|
val hasChannel get() = ::channel.isInitialized
|
||||||
lateinit var channel: Channel
|
lateinit var channel: Channel
|
||||||
protected set
|
private set
|
||||||
|
|
||||||
var isLegacy: Boolean = true
|
var isLegacy: Boolean = true
|
||||||
protected set
|
protected set
|
||||||
@ -113,10 +113,7 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType) :
|
|||||||
channel.flush()
|
channel.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disconnect(reason: String) {
|
abstract fun disconnect(reason: String = "")
|
||||||
channel.flush()
|
|
||||||
channel.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
channel.close()
|
channel.close()
|
||||||
|
@ -33,6 +33,7 @@ import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePac
|
|||||||
import ru.dbotthepony.kstarbound.network.packets.clientbound.ServerDisconnectPacket
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.ServerDisconnectPacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.clientbound.WorldStartPacket
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.WorldStartPacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.clientbound.WorldStopPacket
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.WorldStopPacket
|
||||||
|
import ru.dbotthepony.kstarbound.network.packets.serverbound.ClientDisconnectRequestPacket
|
||||||
import ru.dbotthepony.kstarbound.server.network.packets.TrackedPositionPacket
|
import ru.dbotthepony.kstarbound.server.network.packets.TrackedPositionPacket
|
||||||
import ru.dbotthepony.kstarbound.server.network.packets.TrackedSizePacket
|
import ru.dbotthepony.kstarbound.server.network.packets.TrackedSizePacket
|
||||||
import java.io.BufferedInputStream
|
import java.io.BufferedInputStream
|
||||||
@ -202,7 +203,7 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
LOGGER.error("Packet ($packetType/${type.type}) of ${dataLength.absoluteValue} bytes is bigger than maximum allowed $MAX_PACKET_SIZE bytes")
|
LOGGER.error("Packet ($packetType/${type.type}) of ${dataLength.absoluteValue} bytes is bigger than maximum allowed $MAX_PACKET_SIZE bytes")
|
||||||
discardBytes = dataLength.absoluteValue
|
discardBytes = dataLength.absoluteValue
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("Packet type {} ({}) received on {} (size {} bytes)", packetType, type.type, side, dataLength.absoluteValue)
|
// LOGGER.debug("Packet type {} ({}) received on {} (size {} bytes)", packetType, type.type, side, dataLength.absoluteValue)
|
||||||
readingType = type
|
readingType = type
|
||||||
readableBytes = dataLength.absoluteValue
|
readableBytes = dataLength.absoluteValue
|
||||||
isCompressed = dataLength < 0
|
isCompressed = dataLength < 0
|
||||||
@ -252,7 +253,7 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
stream2.writeByte(type.id)
|
stream2.writeByte(type.id)
|
||||||
stream2.writeSignedVarInt(-buffers.size)
|
stream2.writeSignedVarInt(-buffers.size)
|
||||||
stream2.write(buffers.elements(), 0, buffers.size)
|
stream2.write(buffers.elements(), 0, buffers.size)
|
||||||
LOGGER.debug("Packet type {} ({}) sent from {} (size {} bytes / COMPRESSED size {} bytes)", type.id, type.type, side, stream.length, buffers.size)
|
// LOGGER.debug("Packet type {} ({}) sent from {} (size {} bytes / COMPRESSED size {} bytes)", type.id, type.type, side, stream.length, buffers.size)
|
||||||
ctx.write(buff, promise)
|
ctx.write(buff, promise)
|
||||||
} else {
|
} else {
|
||||||
// send as-is
|
// send as-is
|
||||||
@ -261,7 +262,7 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
stream2.writeByte(type.id)
|
stream2.writeByte(type.id)
|
||||||
stream2.writeSignedVarInt(stream.length)
|
stream2.writeSignedVarInt(stream.length)
|
||||||
stream2.write(stream.array, 0, stream.length)
|
stream2.write(stream.array, 0, stream.length)
|
||||||
LOGGER.debug("Packet type {} ({}) sent from {} (size {} bytes)", type.id, type.type, side, stream.length)
|
// LOGGER.debug("Packet type {} ({}) sent from {} (size {} bytes)", type.id, type.type, side, stream.length)
|
||||||
ctx.write(buff, promise)
|
ctx.write(buff, promise)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,7 +350,7 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
|
|
||||||
// Packets sent universe client -> universe server
|
// Packets sent universe client -> universe server
|
||||||
LEGACY.add(::ClientConnectPacket) // ClientConnect
|
LEGACY.add(::ClientConnectPacket) // ClientConnect
|
||||||
LEGACY.skip("ClientDisconnectRequest")
|
LEGACY.add(ClientDisconnectRequestPacket::read)
|
||||||
LEGACY.add(::HandshakeResponsePacket) // HandshakeResponse
|
LEGACY.add(::HandshakeResponsePacket) // HandshakeResponse
|
||||||
LEGACY.skip("PlayerWarp")
|
LEGACY.skip("PlayerWarp")
|
||||||
LEGACY.skip("FlyShip")
|
LEGACY.skip("FlyShip")
|
||||||
|
@ -15,6 +15,6 @@ class ServerDisconnectPacket(val reason: String = "") : IClientPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun play(connection: ClientConnection) {
|
override fun play(connection: ClientConnection) {
|
||||||
TODO("Not yet implemented")
|
connection.disconnectNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package ru.dbotthepony.kstarbound.network.packets.serverbound
|
||||||
|
|
||||||
|
import ru.dbotthepony.kstarbound.network.IServerPacket
|
||||||
|
import ru.dbotthepony.kstarbound.server.ServerConnection
|
||||||
|
import java.io.DataInputStream
|
||||||
|
import java.io.DataOutputStream
|
||||||
|
|
||||||
|
object ClientDisconnectRequestPacket : IServerPacket {
|
||||||
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
|
if (isLegacy) stream.writeBoolean(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(connection: ServerConnection) {
|
||||||
|
connection.disconnect("Disconnect by user.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun read(stream: DataInputStream, isLegacy: Boolean): ClientDisconnectRequestPacket {
|
||||||
|
if (isLegacy) stream.readBoolean()
|
||||||
|
return ClientDisconnectRequestPacket
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.kstarbound.server
|
package ru.dbotthepony.kstarbound.server
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
import io.netty.channel.ChannelHandlerContext
|
import io.netty.channel.ChannelHandlerContext
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||||
@ -20,6 +21,7 @@ import ru.dbotthepony.kstarbound.network.ConnectionType
|
|||||||
import ru.dbotthepony.kstarbound.network.IServerPacket
|
import ru.dbotthepony.kstarbound.network.IServerPacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.ClientContextUpdatePacket
|
import ru.dbotthepony.kstarbound.network.packets.ClientContextUpdatePacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileArrayUpdatePacket
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileArrayUpdatePacket
|
||||||
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.ServerDisconnectPacket
|
||||||
import ru.dbotthepony.kstarbound.server.world.IChunkSource
|
import ru.dbotthepony.kstarbound.server.world.IChunkSource
|
||||||
import ru.dbotthepony.kstarbound.server.world.LegacyChunkSource
|
import ru.dbotthepony.kstarbound.server.world.LegacyChunkSource
|
||||||
import ru.dbotthepony.kstarbound.server.world.ServerWorld
|
import ru.dbotthepony.kstarbound.server.world.ServerWorld
|
||||||
@ -41,6 +43,10 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
connectionID = server.nextConnectionID.incrementAndGet()
|
connectionID = server.nextConnectionID.incrementAndGet()
|
||||||
|
|
||||||
|
rpc.add("team.fetchTeamStatus") {
|
||||||
|
JsonObject()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@ -145,6 +151,28 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun disconnect(reason: String) {
|
||||||
|
if (channel.isOpen) {
|
||||||
|
// send pending updates
|
||||||
|
flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
tickets.values.forEach { it.cancel() }
|
||||||
|
tickets.clear()
|
||||||
|
pendingSend.clear()
|
||||||
|
|
||||||
|
if (::shipWorld.isInitialized) {
|
||||||
|
shipWorld.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel.isOpen) {
|
||||||
|
// say goodbye
|
||||||
|
channel.write(ServerDisconnectPacket(reason))
|
||||||
|
channel.flush()
|
||||||
|
channel.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun recomputeTrackedChunks() {
|
private fun recomputeTrackedChunks() {
|
||||||
val world = world ?: return
|
val world = world ?: return
|
||||||
val trackedPositionChunk = world.geometry.chunkFromCell(trackedPosition)
|
val trackedPositionChunk = world.geometry.chunkFromCell(trackedPosition)
|
||||||
|
@ -4,6 +4,7 @@ import com.google.gson.JsonObject
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
|
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet
|
import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.kommons.collect.chainOptionalFutures
|
import ru.dbotthepony.kommons.collect.chainOptionalFutures
|
||||||
import ru.dbotthepony.kommons.util.KOptional
|
import ru.dbotthepony.kommons.util.KOptional
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
@ -126,6 +127,8 @@ class ServerWorld(
|
|||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
if (isClosed.compareAndSet(false, true)) {
|
if (isClosed.compareAndSet(false, true)) {
|
||||||
|
LOGGER.info("Shutting down $this")
|
||||||
|
|
||||||
super.close()
|
super.close()
|
||||||
spinner.unpause()
|
spinner.unpause()
|
||||||
|
|
||||||
@ -135,6 +138,7 @@ class ServerWorld(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server.worlds.remove(this)
|
||||||
LockSupport.unpark(thread)
|
LockSupport.unpark(thread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -394,4 +398,8 @@ class ServerWorld(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user