Implemented 0x30-ClientboundLightUpdatePacket
This commit is contained in:
4 files changed
+138
-4
No files matched your search
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright © 2026 RTAkland
|
||||
* Author: RTAkland
|
||||
* Date: 2026/9/11
|
||||
*/
|
||||
|
||||
|
||||
package cn.rtast.libmc.protocol.packet.play.clientbound
|
||||
|
||||
import cn.rtast.libmc.network.BytesBuffer
|
||||
import cn.rtast.libmc.packet.MinecraftPacket
|
||||
import cn.rtast.libmc.packet.PacketCodec
|
||||
import cn.rtast.libmc.primitives.readVarInt
|
||||
import cn.rtast.libmc.protocol.protocol.game.world.LightData
|
||||
|
||||
public data class ClientboundLightUpdatePacket(
|
||||
/**
|
||||
* Chunk coordinate (block coordinate divided by 16, rounded down)
|
||||
*/
|
||||
val chunkX: Int,
|
||||
/**
|
||||
* Chunk coordinate (block coordinate divided by 16, rounded down)
|
||||
*/
|
||||
val chunkZ: Int,
|
||||
val data: LightData,
|
||||
) : MinecraftPacket {
|
||||
internal companion object Codec : PacketCodec<ClientboundLightUpdatePacket> {
|
||||
override fun encode(buffer: BytesBuffer, value: ClientboundLightUpdatePacket) {}
|
||||
override fun decode(buffer: BytesBuffer): ClientboundLightUpdatePacket {
|
||||
val chunkX = buffer.readVarInt()
|
||||
val chunkZ = buffer.readVarInt()
|
||||
val data = LightData.decode(buffer)
|
||||
return ClientboundLightUpdatePacket(chunkX, chunkZ, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright © 2026 RTAkland
|
||||
* Author: RTAkland
|
||||
* Date: 2026/9/11
|
||||
*/
|
||||
|
||||
|
||||
package cn.rtast.libmc.protocol.protocol.game.world
|
||||
|
||||
import cn.rtast.libmc.network.BytesBuffer
|
||||
import cn.rtast.libmc.packet.PacketCodec
|
||||
import cn.rtast.libmc.primitives.*
|
||||
|
||||
public data class LightData(
|
||||
val skyLightMask: BitSet,
|
||||
val blockLightMask: BitSet,
|
||||
val emptySkyLightMask: BitSet,
|
||||
val emptyBlockLightMask: BitSet,
|
||||
val skyLightArrays: List<ByteArray>, // fixed 2048
|
||||
val blockLightArrays: List<ByteArray>, // fixed 2048
|
||||
) {
|
||||
internal companion object Codec : PacketCodec<LightData> {
|
||||
private const val LIGHT_ARRAY_SIZE = 2048
|
||||
override fun encode(buffer: BytesBuffer, value: LightData) {
|
||||
buffer.writeBitSet(value.skyLightMask)
|
||||
buffer.writeBitSet(value.blockLightMask)
|
||||
buffer.writeBitSet(value.emptySkyLightMask)
|
||||
buffer.writeBitSet(value.emptyBlockLightMask)
|
||||
buffer.writeVarInt(value.skyLightArrays.size)
|
||||
buffer.writePrefixed(value.skyLightArrays) { array ->
|
||||
require(array.size == LIGHT_ARRAY_SIZE)
|
||||
writeVarInt(array.size)
|
||||
writeBytes(array)
|
||||
}
|
||||
|
||||
buffer.writePrefixed(value.blockLightArrays) { array ->
|
||||
require(array.size == LIGHT_ARRAY_SIZE)
|
||||
writeVarInt(array.size)
|
||||
writeBytes(array)
|
||||
}
|
||||
}
|
||||
|
||||
override fun decode(buffer: BytesBuffer): LightData {
|
||||
val skyLightMask = buffer.readBitSet()
|
||||
val blockLightMask = buffer.readBitSet()
|
||||
val emptySkyLightMask = buffer.readBitSet()
|
||||
val emptyBlockLightMask = buffer.readBitSet()
|
||||
val skyLightArrays = buffer.readPrefixed {
|
||||
val length = readVarInt()
|
||||
require(length == LIGHT_ARRAY_SIZE)
|
||||
readBytes(length)
|
||||
}
|
||||
val blockLightArrays = buffer.readPrefixed {
|
||||
val length = readVarInt()
|
||||
require(length == LIGHT_ARRAY_SIZE)
|
||||
readBytes(length)
|
||||
}
|
||||
return LightData(
|
||||
skyLightMask, blockLightMask, emptySkyLightMask,
|
||||
emptyBlockLightMask, skyLightArrays, blockLightArrays
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public fun hasSkyLight(sectionY: Int, minSectionY: Int): Boolean {
|
||||
val bitIndex = sectionY - (minSectionY - 1)
|
||||
return skyLightMask.getBit(bitIndex)
|
||||
}
|
||||
|
||||
|
||||
public fun hasBlockLight(sectionY: Int, minSectionY: Int): Boolean {
|
||||
val bitIndex = sectionY - (minSectionY - 1)
|
||||
return blockLightMask.getBit(bitIndex)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || this::class != other::class) return false
|
||||
other as LightData
|
||||
if (!skyLightMask.contentEquals(other.skyLightMask)) return false
|
||||
if (!blockLightMask.contentEquals(other.blockLightMask)) return false
|
||||
if (!emptySkyLightMask.contentEquals(other.emptySkyLightMask)) return false
|
||||
if (!emptyBlockLightMask.contentEquals(other.emptyBlockLightMask)) return false
|
||||
if (skyLightArrays != other.skyLightArrays) return false
|
||||
if (blockLightArrays != other.blockLightArrays) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = skyLightMask.contentHashCode()
|
||||
result = 31 * result + blockLightMask.contentHashCode()
|
||||
result = 31 * result + emptySkyLightMask.contentHashCode()
|
||||
result = 31 * result + emptyBlockLightMask.contentHashCode()
|
||||
result = 31 * result + skyLightArrays.hashCode()
|
||||
result = 31 * result + blockLightArrays.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -108,7 +108,7 @@ internal object GamePacketsProtocolRegistry {
|
||||
// register(0x2D, ClientboundLevelChunkUpdateWithLightPacket)
|
||||
register(0x2E, ClientboundLevelEventPacket)
|
||||
register(0x2F, ClientboundLevelParticlePacket)
|
||||
// register(0x30, ClientboundLightUpdatePacket)
|
||||
register(0x30, ClientboundLightUpdatePacket)
|
||||
register(0x31, ClientboundLoginPlayPacket)
|
||||
register(0x32, ClientboundLowDiskSpaceWarningPacket)
|
||||
register(0x33, ClientboundMapItemDataPacket)
|
||||
|
||||
@@ -11,6 +11,7 @@ import cn.rtast.libmc.crypto.AuthenticationProvider
|
||||
import cn.rtast.libmc.protocol.client.createMinecraftClient
|
||||
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundContainerSetSlotPacket
|
||||
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundLevelParticlePacket
|
||||
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundLightUpdatePacket
|
||||
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayerChatMessagePacket
|
||||
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundStepTickPacket
|
||||
import cn.rtast.libmc.protocol.protocol.session.SessionEvent
|
||||
@@ -101,9 +102,8 @@ class TestClient {
|
||||
println(it)
|
||||
}
|
||||
cli.onPacket<ClientboundPlayerChatMessagePacket> { chatTracker.onReceivePlayerChat(it.messageSignature) }
|
||||
cli.onPacket<ClientboundContainerSetSlotPacket> { println(it) }
|
||||
cli.onPacket<ClientboundLevelParticlePacket> { println(it) }
|
||||
// cli.on { packet, direction -> println("$direction -> $packet") }
|
||||
cli.onPacket<ClientboundLightUpdatePacket> { println(it) }
|
||||
cli.on { packet, direction -> println("$direction -> $packet") }
|
||||
cli.connect()
|
||||
|
||||
// awaitCancellation()
|
||||
|
||||
Reference in New Issue
Block a user