diff --git a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt index 27079b7..3fd00f0 100644 --- a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt +++ b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt @@ -27,6 +27,7 @@ public expect class BytesBuffer { public fun readLong(endian: ByteOrder = ByteOrder.BIG_ENDIAN): Long public fun readBytes(length: Int): ByteArray public fun readBoolean(): Boolean + public fun readRemainingBytes(): ByteArray public fun toByteArray(): ByteArray public fun hasRemaining(): Boolean diff --git a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/packet/PacketRegistry.kt b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/packet/PacketRegistry.kt index a6c3530..c3bd108 100644 --- a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/packet/PacketRegistry.kt +++ b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/packet/PacketRegistry.kt @@ -29,13 +29,8 @@ public class PacketRegistry { register(id, T::class, codec) } - public fun decodePacket(packetId: Int, buffer: BytesBuffer): MinecraftPacket { - val codec = idToCodec[packetId] - if (codec != null) return codec.decode(buffer) else { -// println("Ignored unknown packet 0x${packetId.toString(16).uppercase()}") - return UnknownPacket(packetId, buffer.readBytes(buffer.remaining.toInt())) - } - } + public fun decodePacket(packetId: Int, buffer: BytesBuffer): MinecraftPacket = + idToCodec[packetId]?.decode(buffer) ?: UnknownPacket(packetId, buffer.readBytes(buffer.remaining.toInt())) public fun encodePacket(buffer: BytesBuffer, packet: T) { @Suppress("UNCHECKED_CAST") diff --git a/libmc-common/src/jvmMain/kotlin/cn/rtast/libmc/common/buffer.jvm.kt b/libmc-common/src/jvmMain/kotlin/cn/rtast/libmc/common/buffer.jvm.kt index 594a296..ce813a5 100644 --- a/libmc-common/src/jvmMain/kotlin/cn/rtast/libmc/common/buffer.jvm.kt +++ b/libmc-common/src/jvmMain/kotlin/cn/rtast/libmc/common/buffer.jvm.kt @@ -93,6 +93,12 @@ public actual class BytesBuffer { public actual fun readBoolean(): Boolean = this.readByte() != 0x00.toByte() + public actual fun readRemainingBytes(): ByteArray { + val array = ensureReadArray() + if (readOffset >= array.size) return byteArrayOf() + return array.copyOfRange(readOffset, array.size) + } + public actual fun toByteArray(): ByteArray = outStream.toByteArray() public actual fun hasRemaining(): Boolean = readOffset < ensureReadArray().size diff --git a/libmc-common/src/nativeMain/kotlin/cn/rtast/libmc/common/buffer.native.kt b/libmc-common/src/nativeMain/kotlin/cn/rtast/libmc/common/buffer.native.kt index fb0ae73..e11658c 100644 --- a/libmc-common/src/nativeMain/kotlin/cn/rtast/libmc/common/buffer.native.kt +++ b/libmc-common/src/nativeMain/kotlin/cn/rtast/libmc/common/buffer.native.kt @@ -60,6 +60,7 @@ public actual class BytesBuffer { public actual fun readBytes(length: Int): ByteArray = _delegateBuf.readByteArray(length) public actual fun readBoolean(): Boolean = _delegateBuf.readByte() != 0x00.toByte() + public actual fun readRemainingBytes(): ByteArray = this.toByteArray() public actual fun toByteArray(): ByteArray { val copy = _delegateBuf.peek() diff --git a/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt b/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt index 2e078aa..847398b 100644 --- a/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt +++ b/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt @@ -77,6 +77,12 @@ public fun NBTInput.readRootCompound(): NBTCompound { } public fun NBTInput.readNetworkCompound(): NBTCompound { - val root = readCompound() - return NBTCompound("", root) + return when (val type = NBTType.fromId(readByte().toInt() and 0xFF)) { + NBTType.Compound -> NBTCompound("", readCompoundTag()) + NBTType.String -> NBTCompound( + "", NBTTag.CompoundTag(linkedMapOf("text" to NBTTag.StringTag(readStringTag()))) + ) + + else -> throw UnsupportedOperationException("Unsupported network nbt tag 0x${type.id.toString(16).uppercase()}") + } } \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt index 73a59fa..337a033 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt @@ -55,6 +55,7 @@ public class MinecraftClient internal constructor( } catch (e: Exception) { if (e is CancellationException) throw e if (isActive) { + e.printStackTrace() println("Network read loop exception: ${e.message}") close() } diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt index 24ea553..0591b87 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt @@ -9,14 +9,14 @@ package cn.rtast.libmc.protocol.packet.login import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec -import cn.rtast.libmc.common.readMcString +import cn.rtast.libmc.nbt.NBTCompound +import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound -public data class ClientboundDisconnectLoginPacket(val reason: String) : ClientboundLoginPacket { +public data class ClientboundDisconnectLoginPacket(val reason: NBTCompound) : ClientboundLoginPacket { public companion object Codec : PacketCodec { override fun encode(buffer: BytesBuffer, value: ClientboundDisconnectLoginPacket) {} override fun decode(buffer: BytesBuffer): ClientboundDisconnectLoginPacket { - val reasonJson = buffer.readMcString() - return ClientboundDisconnectLoginPacket(reason = reasonJson) + return ClientboundDisconnectLoginPacket(reason = buffer.readNetworkNBTCompound()) } } } \ No newline at end of file diff --git a/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt b/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt index e616dd6..c5bf604 100644 --- a/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt +++ b/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt @@ -8,6 +8,7 @@ package test import cn.rtast.libmc.protocol.client.createMinecraftClient +import cn.rtast.libmc.protocol.packet.play.ClientboundDisconnectPlayPacket import cn.rtast.libmc.protocol.packet.play.ClientboundLoginPlayPacket import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest @@ -23,6 +24,9 @@ class TestClient { cli.on { println(it) } + cli.on { + println(it) + } while (true) { } }