More work on legacy protocol
This commit is contained in:
parent
c2dc7c2e11
commit
fd233b9ab5
@ -2,7 +2,7 @@ kotlin.code.style=official
|
|||||||
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m
|
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m
|
||||||
|
|
||||||
kotlinVersion=1.9.0
|
kotlinVersion=1.9.0
|
||||||
kommonsVersion=2.1.5
|
kommonsVersion=2.1.8
|
||||||
|
|
||||||
ffiVersion=2.2.13
|
ffiVersion=2.2.13
|
||||||
lwjglVersion=3.3.0
|
lwjglVersion=3.3.0
|
||||||
|
@ -83,7 +83,8 @@ fun main() {
|
|||||||
//item.movement.applyVelocity(Vector2d(rand.nextDouble() * 1000.0 - 500.0, rand.nextDouble() * 1000.0 - 500.0))
|
//item.movement.applyVelocity(Vector2d(rand.nextDouble() * 1000.0 - 500.0, rand.nextDouble() * 1000.0 - 500.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
client.connectToLocalServer(server.channels.createLocalChannel(), UUID.randomUUID())
|
//client.connectToLocalServer(server.channels.createLocalChannel(), UUID.randomUUID())
|
||||||
|
client.connectToRemoteServer(InetSocketAddress("127.0.0.1", 21025), UUID.randomUUID())
|
||||||
//client2.connectToLocalServer(server.channels.createLocalChannel(), UUID.randomUUID())
|
//client2.connectToLocalServer(server.channels.createLocalChannel(), UUID.randomUUID())
|
||||||
server.channels.createChannel(InetSocketAddress(21060))
|
server.channels.createChannel(InetSocketAddress(21060))
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ class ClientConnection(val client: StarboundClient, type: ConnectionType, uuid:
|
|||||||
sendAndFlush(ProtocolRequestPacket(Starbound.LEGACY_PROTOCOL_VERSION))
|
sendAndFlush(ProtocolRequestPacket(Starbound.LEGACY_PROTOCOL_VERSION))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var connectionID: Int = -1
|
||||||
|
|
||||||
override fun inGame() {
|
override fun inGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ package ru.dbotthepony.kstarbound.client.network.packets
|
|||||||
|
|
||||||
import ru.dbotthepony.kommons.io.readCollection
|
import ru.dbotthepony.kommons.io.readCollection
|
||||||
import ru.dbotthepony.kommons.io.writeCollection
|
import ru.dbotthepony.kommons.io.writeCollection
|
||||||
|
import ru.dbotthepony.kommons.io.writeStruct2i
|
||||||
import ru.dbotthepony.kstarbound.client.ClientConnection
|
import ru.dbotthepony.kstarbound.client.ClientConnection
|
||||||
import ru.dbotthepony.kstarbound.network.IClientPacket
|
import ru.dbotthepony.kstarbound.network.IClientPacket
|
||||||
import ru.dbotthepony.kstarbound.io.readChunkPos
|
import ru.dbotthepony.kstarbound.io.readChunkPos
|
||||||
import ru.dbotthepony.kstarbound.io.writeVec2i
|
|
||||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE
|
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE
|
||||||
import ru.dbotthepony.kstarbound.world.Chunk
|
import ru.dbotthepony.kstarbound.world.Chunk
|
||||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||||
@ -25,7 +25,7 @@ class ChunkCellsPacket(val pos: ChunkPos, val data: List<ImmutableCell>) : IClie
|
|||||||
})
|
})
|
||||||
|
|
||||||
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
stream.writeVec2i(pos)
|
stream.writeStruct2i(pos)
|
||||||
stream.writeCollection(data) { it.write(stream) }
|
stream.writeCollection(data) { it.write(stream) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package ru.dbotthepony.kstarbound.client.network.packets
|
package ru.dbotthepony.kstarbound.client.network.packets
|
||||||
|
|
||||||
|
import ru.dbotthepony.kommons.io.writeStruct2i
|
||||||
import ru.dbotthepony.kstarbound.client.ClientConnection
|
import ru.dbotthepony.kstarbound.client.ClientConnection
|
||||||
import ru.dbotthepony.kstarbound.network.IClientPacket
|
import ru.dbotthepony.kstarbound.network.IClientPacket
|
||||||
import ru.dbotthepony.kstarbound.io.readChunkPos
|
import ru.dbotthepony.kstarbound.io.readChunkPos
|
||||||
import ru.dbotthepony.kstarbound.io.writeVec2i
|
|
||||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
@ -12,7 +12,7 @@ class ForgetChunkPacket(val pos: ChunkPos) : IClientPacket {
|
|||||||
constructor(stream: DataInputStream, isLegacy: Boolean) : this(stream.readChunkPos())
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(stream.readChunkPos())
|
||||||
|
|
||||||
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
stream.writeVec2i(pos)
|
stream.writeStruct2i(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun play(connection: ClientConnection) {
|
override fun play(connection: ClientConnection) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package ru.dbotthepony.kstarbound.defs
|
package ru.dbotthepony.kstarbound.defs
|
||||||
|
|
||||||
|
import ru.dbotthepony.kommons.io.readVector2i
|
||||||
import ru.dbotthepony.kommons.io.writeStruct2i
|
import ru.dbotthepony.kommons.io.writeStruct2i
|
||||||
import ru.dbotthepony.kommons.vector.Vector2i
|
import ru.dbotthepony.kommons.vector.Vector2i
|
||||||
import ru.dbotthepony.kstarbound.io.readVec2i
|
|
||||||
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
|
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
@ -19,8 +19,8 @@ data class CelestialBaseInformation(
|
|||||||
stream.readInt(),
|
stream.readInt(),
|
||||||
stream.readInt(),
|
stream.readInt(),
|
||||||
stream.readInt(),
|
stream.readInt(),
|
||||||
stream.readVec2i(),
|
stream.readVector2i(),
|
||||||
stream.readVec2i(),
|
stream.readVector2i(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
|
@ -19,6 +19,15 @@ data class ShipUpgrades(
|
|||||||
val shipSpeed: Int = 0,
|
val shipSpeed: Int = 0,
|
||||||
val capabilities: ImmutableSet<String> = ImmutableSet.of()
|
val capabilities: ImmutableSet<String> = ImmutableSet.of()
|
||||||
) {
|
) {
|
||||||
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
||||||
|
stream.readInt(),
|
||||||
|
stream.readInt(),
|
||||||
|
stream.readInt(),
|
||||||
|
if (isLegacy) stream.readFloat().toDouble() else stream.readDouble(),
|
||||||
|
stream.readInt(),
|
||||||
|
ImmutableSet.copyOf(stream.readCollection { readBinaryString() })
|
||||||
|
)
|
||||||
|
|
||||||
fun apply(upgrades: ShipUpgrades): ShipUpgrades {
|
fun apply(upgrades: ShipUpgrades): ShipUpgrades {
|
||||||
return ShipUpgrades(
|
return ShipUpgrades(
|
||||||
shipLevel = shipLevel.coerceAtLeast(upgrades.shipLevel),
|
shipLevel = shipLevel.coerceAtLeast(upgrades.shipLevel),
|
||||||
@ -43,17 +52,4 @@ data class ShipUpgrades(
|
|||||||
stream.writeInt(shipSpeed)
|
stream.writeInt(shipSpeed)
|
||||||
stream.writeCollection(capabilities) { writeBinaryString(it) }
|
stream.writeCollection(capabilities) { writeBinaryString(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun read(stream: DataInputStream, isLegacy: Boolean): ShipUpgrades {
|
|
||||||
return ShipUpgrades(
|
|
||||||
stream.readInt(),
|
|
||||||
stream.readInt(),
|
|
||||||
stream.readInt(),
|
|
||||||
if (isLegacy) stream.readFloat().toDouble() else stream.readDouble(),
|
|
||||||
stream.readInt(),
|
|
||||||
ImmutableSet.copyOf(stream.readCollection { readBinaryString() })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,24 +37,6 @@ fun InputStream.readHeader(header: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun OutputStream.writeVec2i(value: IStruct2i) {
|
|
||||||
writeSignedVarInt(value.component1())
|
|
||||||
writeSignedVarInt(value.component2())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun OutputStream.writeVec2d(value: IStruct2d) {
|
|
||||||
writeDouble(value.component1())
|
|
||||||
writeDouble(value.component2())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun InputStream.readVec2i(): Vector2i {
|
|
||||||
return Vector2i(readSignedVarInt(), readSignedVarInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun InputStream.readVec2d(): Vector2d {
|
|
||||||
return Vector2d(readDouble(), readDouble())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun InputStream.readChunkPos(): ChunkPos {
|
fun InputStream.readChunkPos(): ChunkPos {
|
||||||
return ChunkPos(readSignedVarInt(), readSignedVarInt())
|
return ChunkPos(readSignedVarInt(), readSignedVarInt())
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import java.util.LinkedList
|
|||||||
*/
|
*/
|
||||||
fun DataInputStream.readJsonElement(): JsonElement {
|
fun DataInputStream.readJsonElement(): JsonElement {
|
||||||
return when (val id = read()) {
|
return when (val id = read()) {
|
||||||
BinaryJsonReader.TYPE_NULL -> JsonNull.INSTANCE
|
BinaryJsonReader.TYPE_INVALID, BinaryJsonReader.TYPE_NULL -> JsonNull.INSTANCE
|
||||||
BinaryJsonReader.TYPE_DOUBLE -> JsonPrimitive(readDouble())
|
BinaryJsonReader.TYPE_DOUBLE -> JsonPrimitive(readDouble())
|
||||||
BinaryJsonReader.TYPE_BOOLEAN -> InternedJsonElementAdapter.of(readBoolean())
|
BinaryJsonReader.TYPE_BOOLEAN -> InternedJsonElementAdapter.of(readBoolean())
|
||||||
BinaryJsonReader.TYPE_INT -> JsonPrimitive(readSignedVarLong())
|
BinaryJsonReader.TYPE_INT -> JsonPrimitive(readSignedVarLong())
|
||||||
@ -388,6 +388,7 @@ class BinaryJsonReader(private val stream: DataInputStream) : JsonReader(unreada
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val TYPE_INVALID = 0x00
|
||||||
const val TYPE_NULL = 0x01
|
const val TYPE_NULL = 0x01
|
||||||
const val TYPE_DOUBLE = 0x02
|
const val TYPE_DOUBLE = 0x02
|
||||||
const val TYPE_BOOLEAN = 0x03
|
const val TYPE_BOOLEAN = 0x03
|
||||||
|
@ -35,7 +35,7 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType, va
|
|||||||
private val legacySerializer = PacketRegistry.LEGACY.Serializer(side)
|
private val legacySerializer = PacketRegistry.LEGACY.Serializer(side)
|
||||||
|
|
||||||
fun setupLegacy() {
|
fun setupLegacy() {
|
||||||
LOGGER.info("Handshake successful from ${channel.remoteAddress()}, channel is using legacy protocol")
|
LOGGER.info("Handshake successful on ${channel.remoteAddress()}, channel is using legacy protocol")
|
||||||
|
|
||||||
if (type == ConnectionType.MEMORY) {
|
if (type == ConnectionType.MEMORY) {
|
||||||
channel.pipeline().remove(handshakeValidator)
|
channel.pipeline().remove(handshakeValidator)
|
||||||
@ -49,7 +49,7 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType, va
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setupNative() {
|
fun setupNative() {
|
||||||
LOGGER.info("Handshake successful from ${channel.remoteAddress()}, channel is using native protocol")
|
LOGGER.info("Handshake successful on ${channel.remoteAddress()}, channel is using native protocol")
|
||||||
|
|
||||||
if (type == ConnectionType.MEMORY) {
|
if (type == ConnectionType.MEMORY) {
|
||||||
channel.pipeline().remove(handshakeValidator)
|
channel.pipeline().remove(handshakeValidator)
|
||||||
|
@ -7,12 +7,15 @@ import io.netty.channel.ChannelDuplexHandler
|
|||||||
import io.netty.channel.ChannelHandlerContext
|
import io.netty.channel.ChannelHandlerContext
|
||||||
import io.netty.channel.ChannelPromise
|
import io.netty.channel.ChannelPromise
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
|
||||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.kommons.io.readSignedVarInt
|
import ru.dbotthepony.kommons.io.readSignedVarInt
|
||||||
|
import ru.dbotthepony.kommons.io.readVarInt
|
||||||
import ru.dbotthepony.kommons.io.writeSignedVarInt
|
import ru.dbotthepony.kommons.io.writeSignedVarInt
|
||||||
|
import ru.dbotthepony.kommons.io.writeVarInt
|
||||||
import ru.dbotthepony.kstarbound.client.network.packets.ForgetChunkPacket
|
import ru.dbotthepony.kstarbound.client.network.packets.ForgetChunkPacket
|
||||||
import ru.dbotthepony.kstarbound.client.network.packets.ChunkCellsPacket
|
import ru.dbotthepony.kstarbound.client.network.packets.ChunkCellsPacket
|
||||||
import ru.dbotthepony.kstarbound.client.network.packets.ForgetEntityPacket
|
import ru.dbotthepony.kstarbound.client.network.packets.ForgetEntityPacket
|
||||||
@ -25,6 +28,7 @@ import ru.dbotthepony.kstarbound.network.packets.serverbound.HandshakeResponsePa
|
|||||||
import ru.dbotthepony.kstarbound.network.packets.ProtocolRequestPacket
|
import ru.dbotthepony.kstarbound.network.packets.ProtocolRequestPacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.ProtocolResponsePacket
|
import ru.dbotthepony.kstarbound.network.packets.ProtocolResponsePacket
|
||||||
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.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
|
||||||
@ -37,6 +41,7 @@ import kotlin.reflect.KClass
|
|||||||
|
|
||||||
class PacketRegistry(val isLegacy: Boolean) {
|
class PacketRegistry(val isLegacy: Boolean) {
|
||||||
private val packets = ArrayList<Type<*>?>()
|
private val packets = ArrayList<Type<*>?>()
|
||||||
|
private val missingNames = Int2ObjectArrayMap<String>()
|
||||||
private val clazz2Type = Reference2ObjectOpenHashMap<KClass<*>, Type<*>>()
|
private val clazz2Type = Reference2ObjectOpenHashMap<KClass<*>, Type<*>>()
|
||||||
|
|
||||||
private data class Type<T : IPacket>(val id: Int, val type: KClass<T>, val factory: IPacketReader<T>, val direction: PacketDirection)
|
private data class Type<T : IPacket>(val id: Int, val type: KClass<T>, val factory: IPacketReader<T>, val direction: PacketDirection)
|
||||||
@ -67,6 +72,11 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun skip(name: String) {
|
||||||
|
missingNames[packets.size] = name
|
||||||
|
packets.add(null)
|
||||||
|
}
|
||||||
|
|
||||||
inner class Serializer(val side: ConnectionSide) : ChannelDuplexHandler() {
|
inner class Serializer(val side: ConnectionSide) : ChannelDuplexHandler() {
|
||||||
private val backlog = ByteArrayList()
|
private val backlog = ByteArrayList()
|
||||||
private var discardBytes = 0
|
private var discardBytes = 0
|
||||||
@ -121,12 +131,19 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
val type = packets.getOrNull(packetType)
|
val type = packets.getOrNull(packetType)
|
||||||
|
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
LOGGER.error("Unknown packet type $packetType! Discarding ${dataLength.absoluteValue} bytes")
|
val name = missingNames[packetType]
|
||||||
|
|
||||||
|
if (name != null)
|
||||||
|
LOGGER.error("Unknown packet type $packetType ($name)! Discarding ${dataLength.absoluteValue} bytes")
|
||||||
|
else
|
||||||
|
LOGGER.error("Unknown packet type $packetType! Discarding ${dataLength.absoluteValue} bytes")
|
||||||
|
|
||||||
discardBytes = dataLength.absoluteValue
|
discardBytes = dataLength.absoluteValue
|
||||||
} else if (!type.direction.acceptedOn(side)) {
|
} else if (!type.direction.acceptedOn(side)) {
|
||||||
LOGGER.error("Packet type $packetType (${type.type}) can not be accepted on side $side! Discarding ${dataLength.absoluteValue} bytes")
|
LOGGER.error("Packet type $packetType (${type.type}) can not be accepted on side $side! Discarding ${dataLength.absoluteValue} bytes")
|
||||||
discardBytes = dataLength.absoluteValue
|
discardBytes = dataLength.absoluteValue
|
||||||
} else {
|
} else {
|
||||||
|
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
|
||||||
@ -159,6 +176,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)
|
||||||
ctx.write(buff, promise)
|
ctx.write(buff, promise)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,92 +231,100 @@ class PacketRegistry(val isLegacy: Boolean) {
|
|||||||
HANDSHAKE.add(::ProtocolRequestPacket)
|
HANDSHAKE.add(::ProtocolRequestPacket)
|
||||||
HANDSHAKE.add(::ProtocolResponsePacket)
|
HANDSHAKE.add(::ProtocolResponsePacket)
|
||||||
|
|
||||||
LEGACY.skip() // ProtocolRequest
|
// legacy protocol handshake looks like this
|
||||||
LEGACY.skip() // ProtocolResponse
|
// --> ProtocolRequest
|
||||||
|
// <-- ProtocolResponse
|
||||||
|
// --> ClientConnect
|
||||||
|
// <-- HandshakeChallenge *
|
||||||
|
// --> HandshakeResponse *
|
||||||
|
// <-- ConnectSuccess / ConnectFailure
|
||||||
|
|
||||||
|
LEGACY.skip("ProtocolRequest")
|
||||||
|
LEGACY.skip("ProtocolResponse")
|
||||||
|
|
||||||
// Packets sent universe server -> universe client
|
// Packets sent universe server -> universe client
|
||||||
LEGACY.add(::ServerDisconnectPacket) // ServerDisconnect
|
LEGACY.add(::ServerDisconnectPacket) // ServerDisconnect
|
||||||
LEGACY.add(::ConnectSuccessPacket) // ConnectSuccess
|
LEGACY.add(::ConnectSuccessPacket) // ConnectSuccess
|
||||||
LEGACY.skip() // ConnectFailure
|
LEGACY.skip("ConnectFailure")
|
||||||
LEGACY.add(::HandshakeChallengePacket) // HandshakeChallenge
|
LEGACY.add(::HandshakeChallengePacket) // HandshakeChallenge
|
||||||
LEGACY.skip() // ChatReceive
|
LEGACY.skip("ChatReceive")
|
||||||
LEGACY.skip() // UniverseTimeUpdate
|
LEGACY.skip("UniverseTimeUpdate")
|
||||||
LEGACY.skip() // CelestialResponse
|
LEGACY.skip("CelestialResponse")
|
||||||
LEGACY.skip() // PlayerWarpResult
|
LEGACY.skip("PlayerWarpResult")
|
||||||
LEGACY.skip() // PlanetTypeUpdate
|
LEGACY.skip("PlanetTypeUpdate")
|
||||||
LEGACY.skip() // Pause
|
LEGACY.skip("Pause")
|
||||||
LEGACY.skip() // ServerInfo
|
LEGACY.skip("ServerInfo")
|
||||||
|
|
||||||
// Packets sent universe client -> universe server
|
// Packets sent universe client -> universe server
|
||||||
LEGACY.add(::ClientConnectPacket) // ClientConnect
|
LEGACY.add(::ClientConnectPacket) // ClientConnect
|
||||||
LEGACY.skip() // ClientDisconnectRequest
|
LEGACY.skip("ClientDisconnectRequest")
|
||||||
LEGACY.add(::HandshakeResponsePacket) // HandshakeResponse
|
LEGACY.add(::HandshakeResponsePacket) // HandshakeResponse
|
||||||
LEGACY.skip() // PlayerWarp
|
LEGACY.skip("PlayerWarp")
|
||||||
LEGACY.skip() // FlyShip
|
LEGACY.skip("FlyShip")
|
||||||
LEGACY.skip() // ChatSend
|
LEGACY.skip("ChatSend")
|
||||||
LEGACY.skip() // CelestialRequest
|
LEGACY.skip("CelestialRequest")
|
||||||
|
|
||||||
// Packets sent bidirectionally between the universe client and the universe
|
// Packets sent bidirectionally between the universe client and the universe
|
||||||
// server
|
// server
|
||||||
LEGACY.skip() // ClientContextUpdate
|
LEGACY.skip("ClientContextUpdate")
|
||||||
|
|
||||||
// Packets sent world server -> world client
|
// Packets sent world server -> world client
|
||||||
LEGACY.skip() // WorldStart
|
LEGACY.add(::WorldStartPacket) // WorldStart
|
||||||
LEGACY.skip() // WorldStop
|
LEGACY.skip("WorldStop")
|
||||||
LEGACY.skip() // WorldLayoutUpdate
|
LEGACY.skip("WorldLayoutUpdate")
|
||||||
LEGACY.skip() // WorldParametersUpdate
|
LEGACY.skip("WorldParametersUpdate")
|
||||||
LEGACY.skip() // CentralStructureUpdate
|
LEGACY.skip("CentralStructureUpdate")
|
||||||
LEGACY.skip() // TileArrayUpdate
|
LEGACY.skip("TileArrayUpdate")
|
||||||
LEGACY.skip() // TileUpdate
|
LEGACY.skip("TileUpdate")
|
||||||
LEGACY.skip() // TileLiquidUpdate
|
LEGACY.skip("TileLiquidUpdate")
|
||||||
LEGACY.skip() // TileDamageUpdate
|
LEGACY.skip("TileDamageUpdate")
|
||||||
LEGACY.skip() // TileModificationFailure
|
LEGACY.skip("TileModificationFailure")
|
||||||
LEGACY.skip() // GiveItem
|
LEGACY.skip("GiveItem")
|
||||||
LEGACY.skip() // EnvironmentUpdate
|
LEGACY.skip("EnvironmentUpdate")
|
||||||
LEGACY.skip() // UpdateTileProtection
|
LEGACY.skip("UpdateTileProtection")
|
||||||
LEGACY.skip() // SetDungeonGravity
|
LEGACY.skip("SetDungeonGravity")
|
||||||
LEGACY.skip() // SetDungeonBreathable
|
LEGACY.skip("SetDungeonBreathable")
|
||||||
LEGACY.skip() // SetPlayerStart
|
LEGACY.skip("SetPlayerStart")
|
||||||
LEGACY.skip() // FindUniqueEntityResponse
|
LEGACY.skip("FindUniqueEntityResponse")
|
||||||
LEGACY.skip() // Pong
|
LEGACY.skip("Pong")
|
||||||
|
|
||||||
// Packets sent world client -> world server
|
// Packets sent world client -> world server
|
||||||
LEGACY.skip() // ModifyTileList
|
LEGACY.skip("ModifyTileList")
|
||||||
LEGACY.skip() // DamageTileGroup
|
LEGACY.skip("DamageTileGroup")
|
||||||
LEGACY.skip() // CollectLiquid
|
LEGACY.skip("CollectLiquid")
|
||||||
LEGACY.skip() // RequestDrop
|
LEGACY.skip("RequestDrop")
|
||||||
LEGACY.skip() // SpawnEntity
|
LEGACY.skip("SpawnEntity")
|
||||||
LEGACY.skip() // ConnectWire
|
LEGACY.skip("ConnectWire")
|
||||||
LEGACY.skip() // DisconnectAllWires
|
LEGACY.skip("DisconnectAllWires")
|
||||||
LEGACY.skip() // WorldClientStateUpdate
|
LEGACY.skip("WorldClientStateUpdate")
|
||||||
LEGACY.skip() // FindUniqueEntity
|
LEGACY.skip("FindUniqueEntity")
|
||||||
LEGACY.skip() // WorldStartAcknowledge
|
LEGACY.skip("WorldStartAcknowledge")
|
||||||
LEGACY.skip() // Ping
|
LEGACY.skip("Ping")
|
||||||
|
|
||||||
// Packets sent bidirectionally between world client and world server
|
// Packets sent bidirectionally between world client and world server
|
||||||
LEGACY.skip() // EntityCreate
|
LEGACY.skip("EntityCreate")
|
||||||
LEGACY.skip() // EntityUpdateSet
|
LEGACY.skip("EntityUpdateSet")
|
||||||
LEGACY.skip() // EntityDestroy
|
LEGACY.skip("EntityDestroy")
|
||||||
LEGACY.skip() // EntityInteract
|
LEGACY.skip("EntityInteract")
|
||||||
LEGACY.skip() // EntityInteractResult
|
LEGACY.skip("EntityInteractResult")
|
||||||
LEGACY.skip() // HitRequest
|
LEGACY.skip("HitRequest")
|
||||||
LEGACY.skip() // DamageRequest
|
LEGACY.skip("DamageRequest")
|
||||||
LEGACY.skip() // DamageNotification
|
LEGACY.skip("DamageNotification")
|
||||||
LEGACY.skip() // EntityMessage
|
LEGACY.skip("EntityMessage")
|
||||||
LEGACY.skip() // EntityMessageResponse
|
LEGACY.skip("EntityMessageResponse")
|
||||||
LEGACY.skip() // UpdateWorldProperties
|
LEGACY.skip("UpdateWorldProperties")
|
||||||
LEGACY.skip() // StepUpdate
|
LEGACY.skip("StepUpdate")
|
||||||
|
|
||||||
// Packets sent system server -> system client
|
// Packets sent system server -> system client
|
||||||
LEGACY.skip() // SystemWorldStart
|
LEGACY.skip("SystemWorldStart")
|
||||||
LEGACY.skip() // SystemWorldUpdate
|
LEGACY.skip("SystemWorldUpdate")
|
||||||
LEGACY.skip() // SystemObjectCreate
|
LEGACY.skip("SystemObjectCreate")
|
||||||
LEGACY.skip() // SystemObjectDestroy
|
LEGACY.skip("SystemObjectDestroy")
|
||||||
LEGACY.skip() // SystemShipCreate
|
LEGACY.skip("SystemShipCreate")
|
||||||
LEGACY.skip() // SystemShipDestroy
|
LEGACY.skip("SystemShipDestroy")
|
||||||
|
|
||||||
// Packets sent system client -> system server
|
// Packets sent system client -> system server
|
||||||
LEGACY.skip() // SystemObjectSpawn
|
LEGACY.skip("SystemObjectSpawn")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,9 @@ data class ProtocolResponsePacket(val allowed: Boolean) : IClientPacket {
|
|||||||
playerSpecies = "hylotl",
|
playerSpecies = "hylotl",
|
||||||
shipChunks = HashMap(),
|
shipChunks = HashMap(),
|
||||||
shipUpgrades = ShipUpgrades(),
|
shipUpgrades = ShipUpgrades(),
|
||||||
introComplete = false,
|
introComplete = true,
|
||||||
account = ""
|
account = ""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
connection.setupNative()
|
connection.setupNative()
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package ru.dbotthepony.kstarbound.network.packets.clientbound
|
package ru.dbotthepony.kstarbound.network.packets.clientbound
|
||||||
|
|
||||||
import ru.dbotthepony.kommons.io.readUUID
|
import ru.dbotthepony.kommons.io.readUUID
|
||||||
|
import ru.dbotthepony.kommons.io.readVarInt
|
||||||
import ru.dbotthepony.kommons.io.writeUUID
|
import ru.dbotthepony.kommons.io.writeUUID
|
||||||
|
import ru.dbotthepony.kommons.io.writeVarInt
|
||||||
import ru.dbotthepony.kstarbound.client.ClientConnection
|
import ru.dbotthepony.kstarbound.client.ClientConnection
|
||||||
import ru.dbotthepony.kstarbound.defs.CelestialBaseInformation
|
import ru.dbotthepony.kstarbound.defs.CelestialBaseInformation
|
||||||
import ru.dbotthepony.kstarbound.network.IClientPacket
|
import ru.dbotthepony.kstarbound.network.IClientPacket
|
||||||
@ -11,18 +13,18 @@ import java.util.UUID
|
|||||||
|
|
||||||
class ConnectSuccessPacket(val connectionID: Int, val serverUUID: UUID, val celestialInformation: CelestialBaseInformation) : IClientPacket {
|
class ConnectSuccessPacket(val connectionID: Int, val serverUUID: UUID, val celestialInformation: CelestialBaseInformation) : IClientPacket {
|
||||||
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
||||||
stream.readUnsignedShort(),
|
stream.readVarInt(),
|
||||||
stream.readUUID(),
|
stream.readUUID(),
|
||||||
CelestialBaseInformation(stream, isLegacy)
|
CelestialBaseInformation(stream, isLegacy)
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
stream.writeShort(connectionID)
|
stream.writeVarInt(connectionID)
|
||||||
stream.writeUUID(serverUUID)
|
stream.writeUUID(serverUUID)
|
||||||
celestialInformation.write(stream, isLegacy)
|
celestialInformation.write(stream, isLegacy)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun play(connection: ClientConnection) {
|
override fun play(connection: ClientConnection) {
|
||||||
TODO("Not yet implemented")
|
connection.connectionID = connectionID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package ru.dbotthepony.kstarbound.network.packets.clientbound
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2BooleanAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
||||||
|
import ru.dbotthepony.kommons.io.readByteArray
|
||||||
|
import ru.dbotthepony.kommons.io.readCollection
|
||||||
|
import ru.dbotthepony.kommons.io.readMap
|
||||||
|
import ru.dbotthepony.kommons.io.readVector2d
|
||||||
|
import ru.dbotthepony.kommons.io.readVector2f
|
||||||
|
import ru.dbotthepony.kommons.io.writeByteArray
|
||||||
|
import ru.dbotthepony.kommons.io.writeCollection
|
||||||
|
import ru.dbotthepony.kommons.io.writeMap
|
||||||
|
import ru.dbotthepony.kommons.io.writeStruct2d
|
||||||
|
import ru.dbotthepony.kommons.io.writeStruct2f
|
||||||
|
import ru.dbotthepony.kommons.vector.Vector2d
|
||||||
|
import ru.dbotthepony.kstarbound.client.ClientConnection
|
||||||
|
import ru.dbotthepony.kstarbound.json.readJsonElement
|
||||||
|
import ru.dbotthepony.kstarbound.json.writeJsonElement
|
||||||
|
import ru.dbotthepony.kstarbound.network.IClientPacket
|
||||||
|
import java.io.DataInputStream
|
||||||
|
import java.io.DataOutputStream
|
||||||
|
|
||||||
|
class WorldStartPacket(
|
||||||
|
val templateData: JsonElement, val skyData: ByteArray, val weatherData: ByteArray,
|
||||||
|
val playerStart: Vector2d, val playerRespawn: Vector2d, val respawnInWorld: Boolean,
|
||||||
|
val dungeonGravity: Map<Int, Vector2d>, val dungeonBreathable: Map<Int, Boolean>,
|
||||||
|
val protectedDungeonIDs: Set<Int>, val worldProperties: JsonElement, val connectionID: Int,
|
||||||
|
val localInterpolationMode: Boolean,
|
||||||
|
) : IClientPacket {
|
||||||
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
||||||
|
stream.readJsonElement(),
|
||||||
|
stream.readByteArray(),
|
||||||
|
stream.readByteArray(),
|
||||||
|
if (isLegacy) stream.readVector2f().toDoubleVector() else stream.readVector2d(),
|
||||||
|
if (isLegacy) stream.readVector2f().toDoubleVector() else stream.readVector2d(),
|
||||||
|
stream.readBoolean(),
|
||||||
|
if (isLegacy) stream.readMap({ readUnsignedShort() }, { Vector2d(0.0, readFloat().toDouble()) }, ::Int2ObjectOpenHashMap) else stream.readMap({ readInt() }, { readVector2d() }, { Int2ObjectAVLTreeMap() }),
|
||||||
|
if (isLegacy) stream.readMap({ readUnsignedShort() }, { readBoolean() }, ::Int2ObjectOpenHashMap) else stream.readMap({ readInt() }, { readBoolean() }, { Int2BooleanAVLTreeMap() }),
|
||||||
|
if (isLegacy) stream.readCollection({ readUnsignedShort() }, { IntAVLTreeSet() }) else stream.readCollection({ readInt() }, { IntAVLTreeSet() }),
|
||||||
|
stream.readJsonElement(),
|
||||||
|
stream.readUnsignedShort(),
|
||||||
|
stream.readBoolean()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
|
stream.writeJsonElement(templateData)
|
||||||
|
stream.writeByteArray(skyData)
|
||||||
|
stream.writeByteArray(weatherData)
|
||||||
|
|
||||||
|
if (isLegacy) {
|
||||||
|
stream.writeStruct2f(playerStart.toFloatVector())
|
||||||
|
stream.writeStruct2f(playerRespawn.toFloatVector())
|
||||||
|
stream.writeBoolean(respawnInWorld)
|
||||||
|
stream.writeMap(dungeonGravity, { writeShort(it) }, { writeFloat(it.y.toFloat()) })
|
||||||
|
stream.writeMap(dungeonBreathable, { writeShort(it) }, { writeBoolean(it) })
|
||||||
|
stream.writeCollection(protectedDungeonIDs) { writeShort(it) }
|
||||||
|
} else {
|
||||||
|
stream.writeStruct2d(playerStart)
|
||||||
|
stream.writeStruct2d(playerRespawn)
|
||||||
|
stream.writeBoolean(respawnInWorld)
|
||||||
|
stream.writeMap(dungeonGravity, { writeInt(it) }, { writeStruct2d(it) })
|
||||||
|
stream.writeMap(dungeonBreathable, { writeInt(it) }, { writeBoolean(it) })
|
||||||
|
stream.writeCollection(protectedDungeonIDs) { writeInt(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.writeJsonElement(worldProperties)
|
||||||
|
stream.writeShort(connectionID)
|
||||||
|
stream.writeBoolean(localInterpolationMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(connection: ClientConnection) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,7 @@ data class ClientConnectPacket(
|
|||||||
stream.readBinaryString(),
|
stream.readBinaryString(),
|
||||||
stream.readBinaryString(),
|
stream.readBinaryString(),
|
||||||
stream.readMap(InputStream::readByteKey, { readKOptional { readByteArray() } }, { HashMap(it) }),
|
stream.readMap(InputStream::readByteKey, { readKOptional { readByteArray() } }, { HashMap(it) }),
|
||||||
ShipUpgrades.read(stream, isLegacy),
|
ShipUpgrades(stream, isLegacy),
|
||||||
stream.readBoolean(),
|
stream.readBoolean(),
|
||||||
stream.readBinaryString()
|
stream.readBinaryString()
|
||||||
)
|
)
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package ru.dbotthepony.kstarbound.server.network.packets
|
package ru.dbotthepony.kstarbound.server.network.packets
|
||||||
|
|
||||||
|
import ru.dbotthepony.kommons.io.readVector2d
|
||||||
|
import ru.dbotthepony.kommons.io.writeStruct2d
|
||||||
import ru.dbotthepony.kommons.vector.Vector2d
|
import ru.dbotthepony.kommons.vector.Vector2d
|
||||||
import ru.dbotthepony.kstarbound.network.IServerPacket
|
import ru.dbotthepony.kstarbound.network.IServerPacket
|
||||||
import ru.dbotthepony.kstarbound.server.ServerConnection
|
import ru.dbotthepony.kstarbound.server.ServerConnection
|
||||||
import ru.dbotthepony.kstarbound.io.readVec2d
|
|
||||||
import ru.dbotthepony.kstarbound.io.writeVec2d
|
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
|
|
||||||
data class TrackedPositionPacket(val pos: Vector2d) : IServerPacket {
|
data class TrackedPositionPacket(val pos: Vector2d) : IServerPacket {
|
||||||
constructor(stream: DataInputStream, isLegacy: Boolean) : this(stream.readVec2d())
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(stream.readVector2d())
|
||||||
|
|
||||||
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
||||||
stream.writeVec2d(pos)
|
stream.writeStruct2d(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun play(connection: ServerConnection) {
|
override fun play(connection: ServerConnection) {
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
package ru.dbotthepony.kstarbound.world
|
package ru.dbotthepony.kstarbound.world
|
||||||
|
|
||||||
|
import ru.dbotthepony.kommons.io.readVector2i
|
||||||
|
import ru.dbotthepony.kommons.io.writeStruct2i
|
||||||
import ru.dbotthepony.kommons.util.IStruct2d
|
import ru.dbotthepony.kommons.util.IStruct2d
|
||||||
import ru.dbotthepony.kommons.util.IStruct2f
|
import ru.dbotthepony.kommons.util.IStruct2f
|
||||||
import ru.dbotthepony.kommons.util.IStruct2i
|
import ru.dbotthepony.kommons.util.IStruct2i
|
||||||
import ru.dbotthepony.kommons.vector.Vector2d
|
import ru.dbotthepony.kommons.vector.Vector2d
|
||||||
import ru.dbotthepony.kommons.vector.Vector2i
|
import ru.dbotthepony.kommons.vector.Vector2i
|
||||||
import ru.dbotthepony.kstarbound.io.readVec2i
|
|
||||||
import ru.dbotthepony.kstarbound.io.writeVec2i
|
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
|
|
||||||
data class WorldGeometry(val size: Vector2i, val loopX: Boolean, val loopY: Boolean) {
|
data class WorldGeometry(val size: Vector2i, val loopX: Boolean, val loopY: Boolean) {
|
||||||
constructor(buff: DataInputStream) : this(buff.readVec2i(), buff.readBoolean(), buff.readBoolean())
|
constructor(buff: DataInputStream) : this(buff.readVector2i(), buff.readBoolean(), buff.readBoolean())
|
||||||
|
|
||||||
val x: CoordinateMapper = if (loopX) CoordinateMapper.Wrapper(size.x) else CoordinateMapper.Clamper(size.x)
|
val x: CoordinateMapper = if (loopX) CoordinateMapper.Wrapper(size.x) else CoordinateMapper.Clamper(size.x)
|
||||||
val y: CoordinateMapper = if (loopY) CoordinateMapper.Wrapper(size.y) else CoordinateMapper.Clamper(size.y)
|
val y: CoordinateMapper = if (loopY) CoordinateMapper.Wrapper(size.y) else CoordinateMapper.Clamper(size.y)
|
||||||
|
|
||||||
fun write(buff: DataOutputStream) {
|
fun write(buff: DataOutputStream) {
|
||||||
buff.writeVec2i(size)
|
buff.writeStruct2i(size)
|
||||||
buff.writeBoolean(loopX)
|
buff.writeBoolean(loopX)
|
||||||
buff.writeBoolean(loopY)
|
buff.writeBoolean(loopY)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user