Login into server complete

This commit is contained in:
2026-09-05 00:17:22 +08:00
parent dd760b7b9b
commit 15aefbb869
57 files changed
+1622 -65

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
kotlin {
explicitApi()
withSourcesJar()
linuxX64()
linuxArm64()
macosArm64()
mingwX64()
iosArm64()
iosSimulatorArm64()
jvm { compilerOptions.jvmTarget = JvmTarget.JVM_1_8 }
sourceSets {
commonMain.dependencies {
implementation(project(":common"))
}
jvmMain.dependencies {
}
commonTest.dependencies {
implementation(kotlin("test"))
implementation(libs.kotlinx.coroutines.test)
}
}
}
@@ -0,0 +1,95 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.nbt
import cn.rtast.libmc.common._Buffer
import cn.rtast.libmc.common.readVarInt
public class NbtReader(
private val buffer: _Buffer,
private val variant: NbtVariant = NbtVariant.JAVA,
) {
private fun readShort(): Short = buffer.readShort(variant.order)
private fun readInt(): Int = buffer.readInt(variant.order)
private fun readLong(): Long = buffer.readLong(variant.order)
private fun readFloat(): Float = Float.fromBits(readInt())
private fun readDouble(): Double = Double.fromBits(readLong())
private fun readString(): String {
val length = if (variant.isNetwork) buffer.readVarInt() else readShort().toInt() and 0xFFFF
if (length == 0) return ""
return buffer.readBytes(length).decodeToString()
}
private fun readTagType(): Byte = if (variant.isNetwork) buffer.readVarInt().toByte() else buffer.readByte()
public fun readRoot(): Pair<String, NbtCompound> {
val type = readTagType()
require(type == NBTType.COMPOUND) { "Expected Compound Tag (10), got $type" }
val name = readString()
val root = readCompound()
return name to root
}
private fun readCompound(): NbtCompound {
val map = mutableMapOf<String, NBTElement>()
while (true) {
val type = readTagType()
if (type == NBTType.END) break
val name = readString()
map[name] = readPayload(type)
}
return NbtCompound(map)
}
private fun readList(): NbtList {
val elementType = readTagType()
val size = if (variant.isNetwork) buffer.readVarInt() else readInt()
if (size <= 0) return NbtList(elementType, emptyList())
val list = mutableListOf<NBTElement>()
(0 until size).forEach { _ -> list.add(readPayload(elementType)) }
return NbtList(elementType, list)
}
private fun readPayload(type: Byte): NBTElement {
return when (type) {
NBTType.BYTE -> NbtByte(buffer.readByte())
NBTType.SHORT -> NbtShort(readShort())
NBTType.INT -> {
val value = if (variant.isNetwork) buffer.readVarInt().decodeZigZag() else readInt()
NbtInt(value)
}
NBTType.LONG -> NbtLong(readLong())
NBTType.FLOAT -> NbtFloat(readFloat())
NBTType.DOUBLE -> NbtDouble(readDouble())
NBTType.BYTE_ARRAY -> {
val len = if (variant.isNetwork) buffer.readVarInt() else readInt()
NbtByteArray(buffer.readBytes(len))
}
NBTType.STRING -> NbtString(readString())
NBTType.LIST -> readList()
NBTType.COMPOUND -> readCompound()
NBTType.INT_ARRAY -> {
val len = if (variant.isNetwork) buffer.readVarInt() else readInt()
val array = IntArray(len) { readInt() }
NbtIntArray(array)
}
NBTType.LONG_ARRAY -> {
val len = if (variant.isNetwork) buffer.readVarInt() else readInt()
val array = LongArray(len) { readLong() }
NbtLongArray(array)
}
else -> throw IllegalArgumentException("Unknown Tag type: $type")
}
}
}
@@ -0,0 +1,66 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.nbt
public sealed interface NBTElement {
public val typeId: NBTTypeID
}
public data class NbtByte(val value: Byte) : NBTElement {
override val typeId: NBTTypeID = NBTType.BYTE
}
public data class NbtShort(val value: Short) : NBTElement {
override val typeId: NBTTypeID = NBTType.SHORT
}
public data class NbtInt(val value: Int) : NBTElement {
override val typeId: NBTTypeID = NBTType.INT
}
public data class NbtLong(val value: Long) : NBTElement {
override val typeId: NBTTypeID = NBTType.LONG
}
public data class NbtFloat(val value: Float) : NBTElement {
override val typeId: NBTTypeID = NBTType.FLOAT
}
public data class NbtDouble(val value: Double) : NBTElement {
override val typeId: NBTTypeID = NBTType.DOUBLE
}
public data class NbtByteArray(val value: ByteArray) : NBTElement {
override val typeId: NBTTypeID = NBTType.BYTE_ARRAY
override fun equals(other: Any?): Boolean = other is NbtByteArray && value.contentEquals(other.value)
override fun hashCode(): Int = value.contentHashCode()
}
public data class NbtString(val value: String) : NBTElement {
override val typeId: NBTTypeID = NBTType.STRING
}
public data class NbtList(val elementType: Byte, val elements: List<NBTElement>) : NBTElement {
override val typeId: NBTTypeID = NBTType.LIST
}
public data class NbtCompound(val map: Map<String, NBTElement>) : NBTElement {
override val typeId: NBTTypeID = NBTType.COMPOUND
}
public data class NbtIntArray(val value: IntArray) : NBTElement {
override val typeId: NBTTypeID = NBTType.INT_ARRAY
override fun equals(other: Any?): Boolean = other is NbtIntArray && value.contentEquals(other.value)
override fun hashCode(): Int = value.contentHashCode()
}
public data class NbtLongArray(val value: LongArray) : NBTElement {
override val typeId: NBTTypeID = NBTType.LONG_ARRAY
override fun equals(other: Any?): Boolean = other is NbtLongArray && value.contentEquals(other.value)
override fun hashCode(): Int = value.contentHashCode()
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.nbt
public typealias NBTTypeID = Byte
public object NBTType {
public const val END: NBTTypeID = 0
public const val BYTE: NBTTypeID = 1
public const val SHORT: NBTTypeID = 2
public const val INT: NBTTypeID = 3
public const val LONG: NBTTypeID = 4
public const val FLOAT: NBTTypeID = 5
public const val DOUBLE: NBTTypeID = 6
public const val BYTE_ARRAY: NBTTypeID = 7
public const val STRING: NBTTypeID = 8
public const val LIST: NBTTypeID = 9
public const val COMPOUND: NBTTypeID = 10
public const val INT_ARRAY: NBTTypeID = 11
public const val LONG_ARRAY: NBTTypeID = 12
}
@@ -0,0 +1,19 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.nbt
import cn.rtast.libmc.common.ByteOrder
public enum class NbtVariant(
public val order: ByteOrder,
public val isNetwork: Boolean,
) {
JAVA(ByteOrder.BIG_ENDIAN, isNetwork = false),
BEDROCK_DISK(ByteOrder.LITTLE_ENDIAN, isNetwork = false),
BEDROCK_NETWORK(ByteOrder.LITTLE_ENDIAN, isNetwork = true)
}
@@ -0,0 +1,11 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.nbt
internal fun Int.decodeZigZag(): Int = (this ushr 1) xor -(this and 1)
internal fun Int.encodeZigZag(): Int = (this shl 1) xor (this shr 31)
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package test
import cn.rtast.libmc.common.wrap
import cn.rtast.libmc.nbt.NbtReader
import org.junit.Test
import java.io.File
class TestNBTReader {
private val javaNBTBuffer = File("src/commonTest/resources/level.dat").readBytes().wrap()
@Test
fun `test read java nbt`() {
val readRoot = NbtReader(javaNBTBuffer).readRoot()
println(readRoot)
}
}