Add event dispatcher

This commit is contained in:
2026-09-05 14:19:51 +08:00
parent 799edce45f
commit 206db390e9
18 files changed
+353 -318

No files matched your search

@@ -7,4 +7,4 @@
package cn.rtast.libmc.common.packet
public interface MinecraftPacket
public interface MinecraftPacket : PacketEvent
@@ -0,0 +1,10 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.common.packet
public interface PacketEvent
@@ -7,4 +7,8 @@
package cn.rtast.libmc.common
internal expect fun ByteArray.zlibDecompress(): ByteArray
public expect fun ByteArray.zlibDecompress(): ByteArray
public expect fun ByteArray.zlibDecompress(expectedSize: Int): ByteArray
public expect fun ByteArray.zlibCompress(): ByteArray
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package test
import cn.rtast.libmc.common.zlibCompress
import cn.rtast.libmc.common.zlibDecompress
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class TestZlib {
@Test
fun `test zlib compress decompress`() {
val originalText = "Minecraft Protocol Compression".repeat(10)
val originalBytes = originalText.encodeToByteArray()
val compressedBytes = originalBytes.zlibCompress()
assertTrue(compressedBytes.size < originalBytes.size)
val decompressedBytes = compressedBytes.zlibDecompress(originalBytes.size)
assertEquals(originalBytes.size, decompressedBytes.size)
assertContentEquals(originalBytes, decompressedBytes)
}
}
@@ -8,6 +8,7 @@ package cn.rtast.libmc.common
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.util.zip.Deflater
import java.util.zip.GZIPInputStream
import java.util.zip.Inflater
@@ -41,4 +42,27 @@ private fun ByteArray.gzipDecompress(): ByteArray {
return outputStream.toByteArray()
}
}
}
public actual fun ByteArray.zlibDecompress(expectedSize: Int): ByteArray {
val inflater = Inflater()
inflater.setInput(this)
val result = ByteArray(expectedSize)
try {
val resultLength = inflater.inflate(result)
check(resultLength == expectedSize) { "Decompression failed: expected $expectedSize bytes, but got $resultLength" }
return result
} finally {
inflater.end()
}
}
public actual fun ByteArray.zlibCompress(): ByteArray {
val deflater = Deflater()
deflater.setInput(this)
deflater.finish()
val output = ByteArray(this.size + 64)
val compressedSize = deflater.deflate(output)
deflater.end()
return output.copyOf(compressedSize)
}
@@ -4,11 +4,12 @@
* Date: 2026/9/4
*/
@file:OptIn(ExperimentalForeignApi::class)
@file:OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
package cn.rtast.libmc.common
import kotlinx.cinterop.*
import platform.posix.u_longVar
import platform.zlib.*
private const val ENABLE_ZLIB_GZIP_HEADER = 15 + 32
@@ -65,4 +66,39 @@ public actual fun ByteArray.zlibDecompress(): ByteArray {
inputPinned.unpin()
}
}
}
public actual fun ByteArray.zlibDecompress(expectedSize: Int): ByteArray {
val result = ByteArray(expectedSize)
if (this.isEmpty()) return result
memScoped {
val destLen = alloc<u_longVar>()
destLen.value = expectedSize.toUInt()
val res = uncompress(
result.refTo(0).getPointer(this).reinterpret(),
destLen.ptr,
this@zlibDecompress.refTo(0).getPointer(this).reinterpret(),
this@zlibDecompress.size.toUInt()
)
check(res == Z_OK) { "zlib uncompress failed with error code: $res" }
}
return result
}
public actual fun ByteArray.zlibCompress(): ByteArray {
if (this.isEmpty()) return byteArrayOf()
val maxCompressedLen = compressBound(this.size.toUInt()).toInt()
val output = ByteArray(maxCompressedLen)
memScoped {
val destLen = alloc<u_longVar>()
destLen.value = maxCompressedLen.toUInt()
val res = compress(
output.refTo(0).getPointer(this).reinterpret(),
destLen.ptr,
this@zlibCompress.refTo(0).getPointer(this).reinterpret(),
this@zlibCompress.size.toUInt()
)
check(res == Z_OK) { "zlib compress failed with error code: $res" }
return output.copyOf(destLen.value.toInt())
}
}