Login into server complete
This commit is contained in:
57 files changed
+1622
-65
No files matched your search
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user