Add packet codecs across Handshake, Login, Configuration, and Play stages

This commit is contained in:
2026-09-06 21:42:13 +08:00
parent 4a9f35ffdd
commit a88888ba4d
261 files changed
+4387 -343

No files matched your search

@@ -124,6 +124,15 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) {
is ClientboundEntityAnimationPacket -> {}
is ClientboundSpawnEntityPacket -> {}
is ClientboundShowDialogPacket -> {}
is ClientboundBlockEventPacket -> TODO()
is ClientboundBlockUpdatePacket -> TODO()
is ClientboundBossEventPacket -> TODO()
is ClientboundChangeDifficultyPacket -> TODO()
is ClientboundChunkBatchFinishedPacket -> TODO()
ClientboundChunkBatchStartPacket -> TODO()
is ClientboundChunksBiomesPacket -> TODO()
is ClientboundClearTitlesPacket -> TODO()
is ClientboundCommandSuggestionsPacket -> TODO()
}
}
}
@@ -13,7 +13,7 @@ import cn.rtast.libmc.common.readMcString
import cn.rtast.libmc.common.writeMcString
public data class KnownPacks(val namespace: String, val id: String, val version: String) {
public companion object Codec : PacketCodec<KnownPacks> {
internal companion object Codec : PacketCodec<KnownPacks> {
override fun encode(buffer: BytesBuffer, value: KnownPacks) {
buffer.writeMcString(value.namespace)
buffer.writeMcString(value.id)
@@ -19,7 +19,7 @@ public data class ClientboundAddResourcePackPacket(
val forced: Boolean,
val prompt: NBTCompound,
) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundAddResourcePackPacket> {
internal companion object Codec : PacketCodec<ClientboundAddResourcePackPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundAddResourcePackPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundAddResourcePackPacket {
val uuid = buffer.readUuid()
@@ -12,7 +12,7 @@ import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readMcString
public data class ClientboundCodeOfConductPacket(val codeOfConduct: String) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundCodeOfConductPacket> {
internal companion object Codec : PacketCodec<ClientboundCodeOfConductPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCodeOfConductPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCodeOfConductPacket {
return ClientboundCodeOfConductPacket(buffer.readMcString())
@@ -13,7 +13,7 @@ import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundConfigurationShowDialogPacket(val dialog: NBTCompound) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundConfigurationShowDialogPacket> {
internal companion object Codec : PacketCodec<ClientboundConfigurationShowDialogPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundConfigurationShowDialogPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundConfigurationShowDialogPacket {
return ClientboundConfigurationShowDialogPacket(buffer.readNetworkNBTCompound())
@@ -13,7 +13,7 @@ import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
public data class ClientboundCookieRequestPacket(val key: Identifier) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundCookieRequestPacket> {
internal companion object Codec : PacketCodec<ClientboundCookieRequestPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCookieRequestPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCookieRequestPacket {
return ClientboundCookieRequestPacket(key = buffer.readIdentifier())
@@ -9,14 +9,15 @@ package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
public data class ClientboundCustomPayloadPacket(
val channel: Identifier,
val data: ByteArray,
) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundCustomPayloadPacket> {
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundCustomPayloadPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCustomPayloadPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCustomPayloadPacket {
val channel = buffer.readIdentifier()
@@ -8,13 +8,11 @@
package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.*
import kotlinx.serialization.Serializable
public data class ClientboundCustomReportDetailsPacket(val details: List<ReportDetail>) :
ClientboundConfigurationPacket {
@Serializable
public data class ReportDetail(val title: String, val description: String) {
public companion object Codec : PacketCodec<ReportDetail> {
internal companion object Codec : PacketCodec<ReportDetail> {
override fun encode(buffer: BytesBuffer, value: ReportDetail) {
buffer.writeMcString(value.title)
buffer.writeMcString(value.description)
@@ -28,7 +26,7 @@ public data class ClientboundCustomReportDetailsPacket(val details: List<ReportD
}
}
public companion object Codec : PacketCodec<ClientboundCustomReportDetailsPacket> {
internal companion object Codec : PacketCodec<ClientboundCustomReportDetailsPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCustomReportDetailsPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCustomReportDetailsPacket {
val detailCount = buffer.readVarInt()
@@ -13,7 +13,7 @@ import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundDisconnectConfigurationPacket(val reason: NBTCompound) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundDisconnectConfigurationPacket> {
internal companion object Codec : PacketCodec<ClientboundDisconnectConfigurationPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundDisconnectConfigurationPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundDisconnectConfigurationPacket {
return ClientboundDisconnectConfigurationPacket(reason = buffer.readNetworkNBTCompound())
@@ -11,7 +11,7 @@ import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
public data class ClientboundKeepAliveConfigurationPacket(val id: Long) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundKeepAliveConfigurationPacket> {
internal companion object Codec : PacketCodec<ClientboundKeepAliveConfigurationPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundKeepAliveConfigurationPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundKeepAliveConfigurationPacket {
return ClientboundKeepAliveConfigurationPacket(buffer.readLong())
@@ -11,7 +11,7 @@ import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
public data class ClientboundPingConfigurationPacket(val id: Int) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundPingConfigurationPacket> {
internal companion object Codec : PacketCodec<ClientboundPingConfigurationPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPingConfigurationPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPingConfigurationPacket {
return ClientboundPingConfigurationPacket(id = buffer.readInt())
@@ -21,7 +21,7 @@ public data class ClientboundRegistryDataPacket(
val registryId: Identifier,
val entries: List<RegistryEntry>,
) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundRegistryDataPacket> {
internal companion object Codec : PacketCodec<ClientboundRegistryDataPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundRegistryDataPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundRegistryDataPacket {
val id = buffer.readIdentifier()
@@ -13,7 +13,7 @@ import cn.rtast.libmc.common.readUuid
import kotlin.uuid.Uuid
public data class ClientboundRemoveResourcePackPacket(val uuid: Uuid) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundRemoveResourcePackPacket> {
internal companion object Codec : PacketCodec<ClientboundRemoveResourcePackPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundRemoveResourcePackPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundRemoveResourcePackPacket {
val uuid = buffer.readUuid()
@@ -13,7 +13,7 @@ import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.packet.configuration.KnownPacks
public data class ClientboundSelectKnownPacksPacket(val knownPacks: List<KnownPacks>) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundSelectKnownPacksPacket> {
internal companion object Codec : PacketCodec<ClientboundSelectKnownPacksPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSelectKnownPacksPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSelectKnownPacksPacket {
val packsCount = buffer.readVarInt()
@@ -13,7 +13,7 @@ import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.registry.report.ServerLink
public data class ClientboundServerLinksPacket(val links: List<ServerLink>) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundServerLinksPacket> {
internal companion object Codec : PacketCodec<ClientboundServerLinksPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundServerLinksPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundServerLinksPacket {
val count = buffer.readVarInt()
@@ -20,7 +20,7 @@ public data class ClientboundStoreCookiePacket(
*/
val payload: ByteArray,
) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundStoreCookiePacket> {
internal companion object Codec : PacketCodec<ClientboundStoreCookiePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundStoreCookiePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundStoreCookiePacket {
val key = buffer.readIdentifier()
@@ -13,7 +13,7 @@ import cn.rtast.libmc.common.readMcString
import cn.rtast.libmc.common.readVarInt
public data class ClientboundTransferPacket(val host: String, val port: Int) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundTransferPacket> {
internal companion object Codec : PacketCodec<ClientboundTransferPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundTransferPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundTransferPacket {
val host = buffer.readMcString()
@@ -15,7 +15,7 @@ import cn.rtast.libmc.protocol.protocol.game.readIdentifier
public data class ClientboundUpdateEnabledFeaturesPacket(val features: List<Identifier>) :
ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundUpdateEnabledFeaturesPacket> {
internal companion object Codec : PacketCodec<ClientboundUpdateEnabledFeaturesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundUpdateEnabledFeaturesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundUpdateEnabledFeaturesPacket {
val featureCount = buffer.readVarInt()
@@ -14,12 +14,10 @@ import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
import kotlinx.serialization.Serializable
public data class ClientboundUpdateTagsPacket(val registries: List<TaggedRegistry>) : ClientboundConfigurationPacket {
@Serializable
public data class TaggedRegistry(val registryId: Identifier, val tags: List<Tag>) {
public companion object Codec : PacketCodec<TaggedRegistry> {
internal companion object Codec : PacketCodec<TaggedRegistry> {
override fun encode(buffer: BytesBuffer, value: TaggedRegistry) {
buffer.writeIdentifier(value.registryId)
buffer.writeVarInt(value.tags.size)
@@ -36,9 +34,8 @@ public data class ClientboundUpdateTagsPacket(val registries: List<TaggedRegistr
}
}
@Serializable
public data class Tag(val name: Identifier, val entries: IntArray) {
public companion object Codec : PacketCodec<Tag> {
internal companion object Codec : PacketCodec<Tag> {
override fun encode(buffer: BytesBuffer, value: Tag) {
buffer.writeIdentifier(value.name)
buffer.writeVarInt(value.entries.size)
@@ -70,7 +67,7 @@ public data class ClientboundUpdateTagsPacket(val registries: List<TaggedRegistr
}
}
public companion object Codec : PacketCodec<ClientboundUpdateTagsPacket> {
internal companion object Codec : PacketCodec<ClientboundUpdateTagsPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundUpdateTagsPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundUpdateTagsPacket {
val registryCount = buffer.readVarInt()
@@ -15,7 +15,7 @@ import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
public data class ServerboundCookieResponsePacket(val key: Identifier, val payload: ByteArray?) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundCookieResponsePacket> {
internal companion object Codec : PacketCodec<ServerboundCookieResponsePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundCookieResponsePacket) {
buffer.writeIdentifier(value.key)
if (value.payload != null) {
@@ -12,7 +12,7 @@ import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ServerboundKeepAliveConfigurationPacket(val id: Long) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundKeepAliveConfigurationPacket> {
internal companion object Codec : PacketCodec<ServerboundKeepAliveConfigurationPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundKeepAliveConfigurationPacket) {
buffer.writeLong(value.id)
}
@@ -12,7 +12,7 @@ import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ServerboundPongConfigurationPacket(val id: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPongConfigurationPacket> {
internal companion object Codec : PacketCodec<ServerboundPongConfigurationPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPongConfigurationPacket) {
buffer.writeInt(value.id)
}
@@ -14,7 +14,7 @@ import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.packet.configuration.KnownPacks
public data class ServerboundSelectKnownPacksPacket(val knownPacks: List<KnownPacks>) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSelectKnownPacksPacket> {
internal companion object Codec : PacketCodec<ServerboundSelectKnownPacksPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSelectKnownPacksPacket) {
buffer.writeVarInt(value.knownPacks.size)
value.knownPacks.forEach { KnownPacks.encode(buffer, it) }
@@ -20,7 +20,7 @@ public data class ServerboundHandshakePacket(
val serverPort: UShort,
val intent: HandshakeIntent,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundHandshakePacket> {
internal companion object Codec : PacketCodec<ServerboundHandshakePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundHandshakePacket) {
buffer.writeVarInt(value.protocolVersion)
buffer.writeMcString(value.serverAddress)
@@ -18,7 +18,7 @@ public data class ClientboundCustomQueryPacket(
val channel: Identifier,
val data: ByteArray,
) : ClientboundLoginPacket {
public companion object Codec : PacketCodec<ClientboundCustomQueryPacket> {
internal companion object Codec : PacketCodec<ClientboundCustomQueryPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCustomQueryPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCustomQueryPacket {
val messageId = buffer.readVarInt()
@@ -13,7 +13,7 @@ import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundDisconnectLoginPacket(val reason: NBTCompound) : ClientboundLoginPacket {
public companion object Codec : PacketCodec<ClientboundDisconnectLoginPacket> {
internal companion object Codec : PacketCodec<ClientboundDisconnectLoginPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundDisconnectLoginPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundDisconnectLoginPacket {
return ClientboundDisconnectLoginPacket(reason = buffer.readNetworkNBTCompound())
@@ -25,7 +25,7 @@ public data class ClientboundHelloPacket(
*/
val shouldAuthenticate: Boolean,
) : ClientboundLoginPacket {
public companion object Codec : PacketCodec<ClientboundHelloPacket> {
internal companion object Codec : PacketCodec<ClientboundHelloPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundHelloPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundHelloPacket {
val serverId = buffer.readMcString()
@@ -15,7 +15,7 @@ import kotlin.uuid.Uuid
public data class ClientboundLoginSuccessPacket(val gameProfile: GameProfile, val sessionId: Uuid) :
ClientboundLoginPacket {
public companion object Codec : PacketCodec<ClientboundLoginSuccessPacket> {
internal companion object Codec : PacketCodec<ClientboundLoginSuccessPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundLoginSuccessPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundLoginSuccessPacket {
val gameProfile = GameProfile.decode(buffer)
@@ -13,7 +13,7 @@ import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.common.writeVarInt
public data class ClientboundSetCompressionPacket(val threshold: Int) : ClientboundLoginPacket {
public companion object Codec : PacketCodec<ClientboundSetCompressionPacket> {
internal companion object Codec : PacketCodec<ClientboundSetCompressionPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetCompressionPacket) {
buffer.writeVarInt(value.threshold)
}
@@ -14,7 +14,7 @@ import cn.rtast.libmc.common.writeOptionalPrefixedByteArray
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundCustomQueryAnswerPacket(val messageId: Int, val data: ByteArray?) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundCustomQueryAnswerPacket> {
internal companion object Codec : PacketCodec<ServerboundCustomQueryAnswerPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundCustomQueryAnswerPacket) {
buffer.writeVarInt(value.messageId)
buffer.writeOptionalPrefixedByteArray(value.data)
@@ -16,7 +16,7 @@ import cn.rtast.libmc.common.writePrefixedByteArray
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Encryption
*/
public data class ServerboundKeyPacket(val sharedSecret: ByteArray, val verifyToken: ByteArray) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundKeyPacket> {
internal companion object Codec : PacketCodec<ServerboundKeyPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundKeyPacket) {
buffer.writePrefixedByteArray(value.sharedSecret)
buffer.writePrefixedByteArray(value.verifyToken)
@@ -15,7 +15,7 @@ import cn.rtast.libmc.common.writeUuid
import kotlin.uuid.Uuid
public data class ServerboundLoginStartPacket(val username: String, val playerUuid: Uuid) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundLoginStartPacket> {
internal companion object Codec : PacketCodec<ServerboundLoginStartPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundLoginStartPacket) {
buffer.writeMcString(value.username)
buffer.writeUuid(value.playerUuid)
@@ -15,7 +15,7 @@ import cn.rtast.libmc.common.readVarInt
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Acknowledge_Block_Change
*/
public data class ClientboundAcknowledgeBlockChangePacket(val sequenceId: Int) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundAcknowledgeBlockChangePacket> {
internal companion object Codec : PacketCodec<ClientboundAcknowledgeBlockChangePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundAcknowledgeBlockChangePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundAcknowledgeBlockChangePacket {
return ClientboundAcknowledgeBlockChangePacket(buffer.readVarInt())
@@ -16,7 +16,7 @@ import cn.rtast.libmc.protocol.protocol.game.StatisticsEntry
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Award_Statistics
*/
public data class ClientboundAwardStatisticsPacket(val stats: List<StatisticsEntry>) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundAwardStatisticsPacket> {
internal companion object Codec : PacketCodec<ClientboundAwardStatisticsPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundAwardStatisticsPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundAwardStatisticsPacket {
val count = buffer.readVarInt()
@@ -22,7 +22,7 @@ public data class ClientboundBlockDestructionPacket(
val location: BlockPos,
val stage: BlockDestroyStage,
) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundBlockDestructionPacket> {
internal companion object Codec : PacketCodec<ClientboundBlockDestructionPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundBlockDestructionPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBlockDestructionPacket {
val entityId = buffer.readVarInt()
@@ -17,7 +17,7 @@ import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundBlockEntityDataPacket(val location: BlockPos, val type: Int, val data: NBTCompound) :
ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundBlockEntityDataPacket> {
internal companion object Codec : PacketCodec<ClientboundBlockEntityDataPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundBlockEntityDataPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBlockEntityDataPacket {
val location = buffer.readBlockPos()
@@ -0,0 +1,43 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
public data class ClientboundBlockEventPacket(
val location: BlockPos,
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Block_actions
*/
val actionId: UByte,
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Block_actions
*/
val actionParameter: UByte,
/**
* ID in the minecraft:block registry.
* This value is unused by the vanilla client,
* as it will infer the type of block based on the given position.
*/
val blockType: Int,
) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundBlockEventPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundBlockEventPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBlockEventPacket {
val location = buffer.readBlockPos()
val actionId = buffer.readUByte()
val actionParameter = buffer.readUByte()
val blockType = buffer.readVarInt()
return ClientboundBlockEventPacket(location, actionId, actionParameter, blockType)
}
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
public data class ClientboundBlockUpdatePacket(val location: BlockPos, val blockId: Int) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundBlockUpdatePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundBlockUpdatePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBlockUpdatePacket {
val position = buffer.readBlockPos()
val blockId = buffer.readVarInt()
return ClientboundBlockUpdatePacket(position, blockId)
}
}
}
@@ -0,0 +1,53 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readUuid
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.bossbar.BossBarAction
import cn.rtast.libmc.protocol.protocol.game.bossbar.BossBarColor
import cn.rtast.libmc.protocol.protocol.game.bossbar.BossBarDivision
import cn.rtast.libmc.protocol.protocol.game.bossbar.BossBarFlags
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
import kotlin.uuid.Uuid
public data class ClientboundBossEventPacket(val uuid: Uuid, val action: BossBarAction) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundBossEventPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundBossEventPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBossEventPacket {
val uuid = buffer.readUuid()
val action = when (val actionId = buffer.readVarInt()) {
BossBarAction.ADD_ID -> {
val title = buffer.readNetworkNBTCompound()
val health = buffer.readFloat()
val color = BossBarColor.fromID(buffer.readVarInt())
val division = BossBarDivision.fromID(buffer.readVarInt())
val flags = BossBarFlags.fromBitmask(buffer.readByte().toInt() and 0xFF)
BossBarAction.Add(title, health, color, division, flags)
}
BossBarAction.REMOVE_ID -> BossBarAction.Remove
BossBarAction.UPDATE_TITLE_ID -> BossBarAction.UpdateTitle(buffer.readNetworkNBTCompound())
BossBarAction.UPDATE_STYLE_ID -> {
val color = BossBarColor.fromID(buffer.readVarInt())
val division = BossBarDivision.fromID(buffer.readVarInt())
BossBarAction.UpdateStyle(color, division)
}
BossBarAction.UPDATE_FLAGS_ID -> {
BossBarAction.UpdateFlags(BossBarFlags.fromBitmask(buffer.readByte().toInt() and 0xFF))
}
else -> throw IllegalArgumentException("Unknown action $actionId")
}
return ClientboundBossEventPacket(uuid, action)
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.protocol.registry.GameDifficulty
public data class ClientboundChangeDifficultyPacket(val difficulty: GameDifficulty, val locked: Boolean) :
ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundChangeDifficultyPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundChangeDifficultyPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundChangeDifficultyPacket {
val difficulty = GameDifficulty.fromID(buffer.readByte())
val locked = buffer.readBoolean()
return ClientboundChangeDifficultyPacket(difficulty, locked)
}
}
}
@@ -0,0 +1,21 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
public data class ClientboundChunkBatchFinishedPacket(val batchSize: Int) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundChunkBatchFinishedPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundChunkBatchFinishedPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundChunkBatchFinishedPacket {
return ClientboundChunkBatchFinishedPacket(buffer.readVarInt())
}
}
}
@@ -0,0 +1,17 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
public data object ClientboundChunkBatchStartPacket : ClientboundPlayPacket,
PacketCodec<ClientboundChunkBatchStartPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundChunkBatchStartPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundChunkBatchStartPacket = ClientboundChunkBatchStartPacket
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.chunk.ChunkBiomeData
public data class ClientboundChunksBiomesPacket(val chunkBiomes: List<ChunkBiomeData>) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundChunksBiomesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundChunksBiomesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundChunksBiomesPacket {
val chunkCount = buffer.readVarInt()
val chunks = ArrayList<ChunkBiomeData>(chunkCount)
repeat(chunkCount) { chunks.add(ChunkBiomeData.decode(buffer)) }
return ClientboundChunksBiomesPacket(chunks)
}
}
}
@@ -0,0 +1,20 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
public data class ClientboundClearTitlesPacket(val reset: Boolean) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundClearTitlesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundClearTitlesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundClearTitlesPacket {
return ClientboundClearTitlesPacket(buffer.readBoolean())
}
}
}
@@ -0,0 +1,50 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.*
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
import cn.rtast.libmc.protocol.protocol.util.writeNetworkNBTCompound
public data class ClientboundCommandSuggestionsPacket(
val id: Int,
val start: Int,
val length: Int,
val matches: List<CommandSuggestionMatch>,
) : ClientboundPlayPacket {
public data class CommandSuggestionMatch(val match: String, val tooltip: NBTCompound?) {
internal companion object Codec : PacketCodec<CommandSuggestionMatch> {
override fun encode(buffer: BytesBuffer, value: CommandSuggestionMatch) {
buffer.writeMcString(value.match)
buffer.writeBoolean(value.tooltip != null)
if (value.tooltip != null) buffer.writeNetworkNBTCompound(value.tooltip)
}
override fun decode(buffer: BytesBuffer): CommandSuggestionMatch {
val match = buffer.readMcString()
val hasTooltip = buffer.readBoolean()
val tooltip = if (hasTooltip) buffer.readNetworkNBTCompound() else null
return CommandSuggestionMatch(match, tooltip)
}
}
}
internal companion object Codec : PacketCodec<ClientboundCommandSuggestionsPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCommandSuggestionsPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCommandSuggestionsPacket {
val id = buffer.readVarInt()
val start = buffer.readVarInt()
val length = buffer.readVarInt()
val matchCount = buffer.readVarInt()
val matches = ArrayList<CommandSuggestionMatch>(matchCount)
repeat(matchCount) { matches.add(CommandSuggestionMatch.decode(buffer)) }
return ClientboundCommandSuggestionsPacket(id, start, length, matches)
}
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Close_Container
* This is the ID of the window that was closed. 0 for inventory.
*/
public data class ClientboundContainerClosePacket(val windowId: Int) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundContainerClosePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundContainerClosePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundContainerClosePacket {
return ClientboundContainerClosePacket(buffer.readVarInt())
}
}
}
@@ -0,0 +1,38 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.inventory.Slot
import cn.rtast.libmc.protocol.protocol.game.inventory.readSlot
public data class ClientboundContainerSetContentPacket(
val windowId: Int,
/**
* A server-managed sequence number used to avoid desynchronization
* see https://minecraft.wiki/w/Java_Edition_protocol/Packets#Click_Container
*/
val stateId: Int,
val slotData: List<Slot>,
val carriedItem: Slot,
) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundContainerSetContentPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetContentPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundContainerSetContentPacket {
val windowId = buffer.readVarInt()
val stateId = buffer.readVarInt()
val slotDataCount = buffer.readVarInt()
val slotData = ArrayList<Slot>(slotDataCount)
repeat(slotDataCount) { slotData.add(buffer.readSlot()) }
val carriedItem = buffer.readSlot()
return ClientboundContainerSetContentPacket(windowId, stateId, slotData, carriedItem)
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Set_Container_Property
*/
public data class ClientboundContainerSetDataPacket(
val windowId: Int,
val property: Short,
val value: Short,
) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundContainerSetDataPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetDataPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundContainerSetDataPacket {
val windowId = buffer.readVarInt()
val property = buffer.readShort()
val value = buffer.readShort()
return ClientboundContainerSetDataPacket(windowId, property, value)
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.inventory.Slot
import cn.rtast.libmc.protocol.protocol.game.inventory.readSlot
public data class ClientboundContainerSetSlotPacket(
val windowId: Int,
val stateId: Int,
val slot: Short,
val slotData: Slot,
) : ClientboundPlayPacket {
internal companion object Codec : PacketCodec<ClientboundContainerSetSlotPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetSlotPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundContainerSetSlotPacket {
val windowId = buffer.readVarInt()
val stateId = buffer.readVarInt()
val slot = buffer.readShort()
val slotData = buffer.readSlot()
return ClientboundContainerSetSlotPacket(windowId, stateId, slot, slotData)
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
public data class ClientboundCooldownPacket(
val group: Identifier,
/**
* 0 to clear the cooldown.
*/
val ticks: Int,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundCooldownPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCooldownPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCooldownPacket {
val group = buffer.readIdentifier()
val ticks = buffer.readVarInt()
return ClientboundCooldownPacket(group, ticks)
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readPrefixedStringArray
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.chat.ChatAction
public data class ClientboundCustomChatCompletionsPacket(val action: ChatAction, val entries: List<String>) :
MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundCustomChatCompletionsPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundCustomChatCompletionsPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundCustomChatCompletionsPacket {
val action = ChatAction.fromID(buffer.readVarInt())
val entries = buffer.readPrefixedStringArray()
return ClientboundCustomChatCompletionsPacket(action, entries)
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.math.Vec3d
import cn.rtast.libmc.protocol.protocol.game.math.readVec3d
public data class ClientboundDamageEventPacket(
val entityId: Int,
val sourceTypeId: Int,
val sourceCauseId: Int?,
val sourceDirectId: Int?,
val position: Vec3d?,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundDamageEventPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundDamageEventPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundDamageEventPacket {
val entityId = buffer.readVarInt()
val sourceTypeId = buffer.readVarInt()
val rawCauseId = buffer.readVarInt()
val sourceCauseId = if (rawCauseId > 0) rawCauseId - 1 else null
val rawDirectId = buffer.readVarInt()
val sourceDirectId = if (rawDirectId > 0) rawDirectId - 1 else null
val position = buffer.readVec3d(true)
return ClientboundDamageEventPacket(entityId, sourceTypeId, sourceCauseId, sourceDirectId, position)
}
}
}
@@ -0,0 +1,43 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readOptional
import cn.rtast.libmc.common.readVarInt
public data class ClientboundDeleteChatPacket(val messageId: Int, val signature: ByteArray?) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundDeleteChatPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundDeleteChatPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundDeleteChatPacket {
val messageId = buffer.readVarInt()
val signature = buffer.readOptional { buffer.readBytes(256) }
return ClientboundDeleteChatPacket(messageId, signature)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as ClientboundDeleteChatPacket
if (messageId != other.messageId) return false
if (!signature.contentEquals(other.signature)) return false
return true
}
override fun hashCode(): Int {
var result = messageId
result = 31 * result + (signature?.contentHashCode() ?: 0)
return result
}
}
@@ -13,7 +13,7 @@ import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundDisconnectPlayPacket(val reason: NBTCompound) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundDisconnectPlayPacket> {
internal companion object Codec : PacketCodec<ClientboundDisconnectPlayPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundDisconnectPlayPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundDisconnectPlayPacket {
return ClientboundDisconnectPlayPacket(reason = buffer.readNetworkNBTCompound())
@@ -0,0 +1,33 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.*
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.game.chat.InlineChatType
import cn.rtast.libmc.protocol.protocol.game.chat.readInlineChatType
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundDisguisedChatMessagePacket(
val message: NBTCompound,
val chatType: IdOrX<InlineChatType>,
val senderName: NBTCompound,
val targetName: NBTCompound?,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundDisguisedChatMessagePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundDisguisedChatMessagePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundDisguisedChatMessagePacket {
val message = buffer.readNetworkNBTCompound()
val chatType = buffer.readIdOrX { readInlineChatType() }
val senderName = buffer.readNetworkNBTCompound()
val targetName = buffer.readOptional { readNetworkNBTCompound() }
return ClientboundDisguisedChatMessagePacket(message, chatType, senderName, targetName)
}
}
}
@@ -17,7 +17,7 @@ import cn.rtast.libmc.protocol.protocol.game.Animations
*/
public data class ClientboundEntityAnimationPacket(val entityId: Int, val animation: Animations) :
ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundEntityAnimationPacket> {
internal companion object Codec : PacketCodec<ClientboundEntityAnimationPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundEntityAnimationPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundEntityAnimationPacket {
val entityId = buffer.readVarInt()
@@ -0,0 +1,38 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.effect.EntityEffectFlags
import cn.rtast.libmc.protocol.tick.ticks
import kotlin.time.Duration
public data class ClientboundEntityEffectPacket(
val entityId: Int,
val effectId: Int,
val amplifier: Int,
val durationTicks: Int,
val flags: EntityEffectFlags,
) : MinecraftPacket {
public val duration: Duration get() = if (durationTicks == -1) Duration.INFINITE else durationTicks.ticks
internal companion object Codec : PacketCodec<ClientboundEntityEffectPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundEntityEffectPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundEntityEffectPacket {
val entityId = buffer.readVarInt()
val effectId = buffer.readVarInt()
val amplifier = buffer.readVarInt()
val durationTicks = buffer.readVarInt()
val flags = EntityEffectFlags.fromByte(buffer.readByte())
return ClientboundEntityEffectPacket(entityId, effectId, amplifier, durationTicks, flags)
}
}
}
@@ -0,0 +1,30 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ClientboundEntityEventPacket(
val entityId: Int,
/**
* to get status id,
* see https://minecraft.wiki/w/Java_Edition_protocol/Entity_statuses#Entity_statuses
*/
val status: Byte,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundEntityEventPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundEntityEventPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundEntityEventPacket {
val entityId = buffer.readInt()
val status = buffer.readByte()
return ClientboundEntityEventPacket(entityId, status)
}
}
}
@@ -0,0 +1,36 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.*
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.protocol.game.sound.SoundCategory
import cn.rtast.libmc.protocol.protocol.game.sound.SoundEvent
import cn.rtast.libmc.protocol.protocol.game.sound.readSoundEvent
public data class ClientboundEntitySoundEffectPacket(
val soundEvent: IdOrX<SoundEvent>,
val category: SoundCategory,
val entityId: Int,
val volume: Float,
val pitch: Float,
val seed: Long,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundEntitySoundEffectPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundEntitySoundEffectPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundEntitySoundEffectPacket {
val soundEvent = buffer.readIdOrX { readSoundEvent() }
val category = SoundCategory.fromID(buffer.readVarInt())
val entityId = buffer.readVarInt()
val volume = buffer.readFloat()
val pitch = buffer.readFloat()
val seed = buffer.readLong()
return ClientboundEntitySoundEffectPacket(soundEvent, category, entityId, volume, pitch, seed)
}
}
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Game_Event
*/
public data class ClientboundGameEventPacket(val event: UByte, val value: Float) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundGameEventPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundGameEventPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundGameEventPacket {
val event = buffer.readUByte()
val value = buffer.readFloat()
return ClientboundGameEventPacket(event, value)
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.gamerule.GameRuleEntry
import cn.rtast.libmc.protocol.protocol.game.gamerule.readGameRule
public data class ClientboundGameRuleValuesPacket(val rules: List<GameRuleEntry>) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundGameRuleValuesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundGameRuleValuesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundGameRuleValuesPacket {
val count = buffer.readVarInt()
val rules = ArrayList<GameRuleEntry>(count)
repeat(count) { rules.add(buffer.readGameRule()) }
return ClientboundGameRuleValuesPacket(rules)
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundHurtAnimationPacket(val entityId: Int, val yaw: Float) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundHurtAnimationPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundHurtAnimationPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundHurtAnimationPacket {
val entityId = buffer.readVarInt()
val yaw = buffer.readFloat()
return ClientboundHurtAnimationPacket(entityId, yaw)
}
}
}
@@ -0,0 +1,45 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.common.readVarLong
public data class ClientboundInitializeWorldBorderPacket(
val centerX: Double,
val centerZ: Double,
val oldDiameter: Double,
val newDiameter: Double,
val speed: Long,
val portalTeleportBoundary: Int,
val warningBlocks: Int,
val warningTime: Int,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundInitializeWorldBorderPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundInitializeWorldBorderPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundInitializeWorldBorderPacket {
val centerX = buffer.readDouble()
val centerZ = buffer.readDouble()
val oldDiameter = buffer.readDouble()
val newDiameter = buffer.readDouble()
val speed = buffer.readVarLong()
val portalTeleportBoundary = buffer.readVarInt()
val warningBlocks = buffer.readVarInt()
val warningTime = buffer.readVarInt()
return ClientboundInitializeWorldBorderPacket(
centerX, centerZ, oldDiameter,
newDiameter, speed,
portalTeleportBoundary,
warningBlocks, warningTime
)
}
}
}
@@ -11,11 +11,8 @@ import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
public data class ClientboundKeepAlivePlayPacket(val id: Long) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundKeepAlivePlayPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundKeepAlivePlayPacket) {
buffer.writeLong(value.id)
}
internal companion object Codec : PacketCodec<ClientboundKeepAlivePlayPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundKeepAlivePlayPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundKeepAlivePlayPacket =
ClientboundKeepAlivePlayPacket(buffer.readLong())
}
@@ -0,0 +1,35 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
public data class ClientboundLevelEventPacket(
/**
* see https://minecraft.wiki/w/Java_Edition_protocol/Packets#World_Event
*/
val eventId: Int,
val location: BlockPos,
val data: Int,
val disableRelativeVolume: Boolean,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundLevelEventPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundLevelEventPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundLevelEventPacket {
val eventId = buffer.readInt()
val location = buffer.readBlockPos()
val data = buffer.readInt()
val disableRelativeVolume = buffer.readBoolean()
return ClientboundLevelEventPacket(eventId, location, data, disableRelativeVolume)
}
}
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ClientboundLinkEntitiesPacket(val attachedEntityId: Int, val holdingEntityId: Int) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundLinkEntitiesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundLinkEntitiesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundLinkEntitiesPacket {
val attachedEntityId = buffer.readInt()
val holdingEntityId = buffer.readInt()
return ClientboundLinkEntitiesPacket(attachedEntityId, holdingEntityId)
}
}
}
@@ -41,7 +41,7 @@ public data class ClientboundLoginPlayPacket(
val isOnlineMode: Boolean,
val enforceSecureChat: Boolean,
) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundLoginPlayPacket> {
internal companion object Codec : PacketCodec<ClientboundLoginPlayPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundLoginPlayPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundLoginPlayPacket {
val entityId = buffer.readInt()
@@ -57,7 +57,7 @@ public data class ClientboundLoginPlayPacket(
val dimensionType = buffer.readVarInt()
val dimensionName = buffer.readIdentifier()
val hashedSeed = buffer.readLong()
val gameMode = GameMode.fromID(buffer.readByte().toUByte())
val gameMode = GameMode.fromID(buffer.readUByte())
val previousGameMode = GameMode.fromID(buffer.readByte())
val isDebug = buffer.readBoolean()
val isFlat = buffer.readBoolean()
@@ -0,0 +1,19 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data object ClientboundLowDiskSpaceWarningPacket : MinecraftPacket,
PacketCodec<ClientboundLowDiskSpaceWarningPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundLowDiskSpaceWarningPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundLowDiskSpaceWarningPacket =
ClientboundLowDiskSpaceWarningPacket
}
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.entity.MinecartStep
import cn.rtast.libmc.protocol.protocol.game.entity.readMinecartStep
public data class ClientboundMoveMinecartAlongTrackPacket(val entityId: Int, val steps: List<MinecartStep>) :
MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundMoveMinecartAlongTrackPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundMoveMinecartAlongTrackPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundMoveMinecartAlongTrackPacket {
val entityId = buffer.readVarInt()
val stepCount = buffer.readVarInt()
val steps = ArrayList<MinecartStep>()
repeat(stepCount) { steps.add(buffer.readMinecartStep()) }
return ClientboundMoveMinecartAlongTrackPacket(entityId, steps)
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.protocol.game.math.Vec3d
import cn.rtast.libmc.protocol.protocol.game.math.readVec3d
public data class ClientboundMoveVehiclePacket(val position: Vec3d, val yaw: Float, val pitch: Float) :
MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundMoveVehiclePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundMoveVehiclePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundMoveVehiclePacket {
val position = buffer.readVec3d()!!
val yaw = buffer.readFloat()
val pitch = buffer.readFloat()
return ClientboundMoveVehiclePacket(position, yaw, pitch)
}
}
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.player.Hand
public data class ClientboundOpenBookPacket(val hand: Hand) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundOpenBookPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundOpenBookPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundOpenBookPacket {
return ClientboundOpenBookPacket(Hand.fromID(buffer.readVarInt()))
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundOpenHorseScreenPacket(
val windowId: Int,
val columnsCount: Int,
val entityId: Int,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundOpenHorseScreenPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundOpenHorseScreenPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundOpenHorseScreenPacket {
val windowId = buffer.readVarInt()
val columnsCount = buffer.readVarInt()
val entityId = buffer.readInt()
return ClientboundOpenHorseScreenPacket(windowId, columnsCount, entityId)
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundOpenScreenPacket(
val windowId: Int,
val windowType: Int,
val title: NBTCompound,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundOpenScreenPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundOpenScreenPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundOpenScreenPacket {
val windowId = buffer.readVarInt()
val windowType = buffer.readVarInt()
val title = buffer.readNetworkNBTCompound()
return ClientboundOpenScreenPacket(windowId, windowType, title)
}
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
public data class ClientboundOpenSignEditorPacket(val location: BlockPos, val isFrontText: Boolean) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundOpenSignEditorPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundOpenSignEditorPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundOpenSignEditorPacket {
val location = buffer.readBlockPos()
val isFrontText = buffer.readBoolean()
return ClientboundOpenSignEditorPacket(location, isFrontText)
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundPickupItemPacket(
val collectedEntityId: Int,
val collectorEntityId: Int,
/**
* Seems to be 1 for XP orbs, otherwise the number of items in the stack.
*/
val itemCount: Int,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPickupItemPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPickupItemPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPickupItemPacket {
val collectedEntityId = buffer.readVarInt()
val collectorEntityId = buffer.readVarInt()
val itemCount = buffer.readVarInt()
return ClientboundPickupItemPacket(collectedEntityId, collectorEntityId, itemCount)
}
}
}
@@ -11,7 +11,7 @@ import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
public data class ClientboundPingPacket(val id: Int) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundPingPacket> {
internal companion object Codec : PacketCodec<ClientboundPingPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPingPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPingPacket {
return ClientboundPingPacket(id = buffer.readInt())
@@ -9,4 +9,7 @@ package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.packet.MinecraftPacket
/**
* mark a packet that is used when join to the server
*/
public sealed interface ClientboundPlayPacket : MinecraftPacket
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.protocol.game.player.PlayerAbilities
public data class ClientboundPlayerAbilitiesPacket(
val flags: PlayerAbilities,
val flyingSpeed: Float,
val fovModifier: Float,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPlayerAbilitiesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerAbilitiesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerAbilitiesPacket {
val flag = PlayerAbilities.fromByte(buffer.readByte())
val flyingSpeed = buffer.readFloat()
val fovModifier = buffer.readFloat()
return ClientboundPlayerAbilitiesPacket(flag, flyingSpeed, fovModifier)
}
}
}
@@ -36,14 +36,14 @@ public data class ClientboundPlayerChatMessagePacket(
FULLY_FILTERED(1),
PARTIALLY_FILTERED(2);
public companion object {
public fun fromId(id: Int): ChatFilterType =
internal companion object {
fun fromID(id: Int): ChatFilterType =
entries.firstOrNull { it.id == id } ?: PASS_THROUGH
}
}
public data class PreviousMessageEntry(val messageId: Int, val signature: ByteArray?) {
public companion object Codec : PacketCodec<PreviousMessageEntry> {
internal companion object Codec : PacketCodec<PreviousMessageEntry> {
override fun encode(buffer: BytesBuffer, value: PreviousMessageEntry) {}
override fun decode(buffer: BytesBuffer): PreviousMessageEntry {
val messageId = buffer.readVarInt()
@@ -68,7 +68,7 @@ public data class ClientboundPlayerChatMessagePacket(
}
}
public companion object Codec : PacketCodec<ClientboundPlayerChatMessagePacket> {
internal companion object Codec : PacketCodec<ClientboundPlayerChatMessagePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerChatMessagePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerChatMessagePacket {
val globalIndex = buffer.readVarInt()
@@ -88,7 +88,7 @@ public data class ClientboundPlayerChatMessagePacket(
val unsignedContent = if (hasUnsignedContent) buffer.readNetworkNBTCompound() else null // ?
val filterTypeId = buffer.readVarInt()
val filterType = ChatFilterType.fromId(filterTypeId)
val filterType = ChatFilterType.fromID(filterTypeId)
val filterMaskBits = if (filterType == ChatFilterType.PARTIALLY_FILTERED) {
val bitSetLen = buffer.readVarInt()
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundPlayerCombatDeathPacket(val playerId: Int, val message: NBTCompound) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPlayerCombatDeathPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerCombatDeathPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerCombatDeathPacket {
val playerId = buffer.readVarInt()
val message = buffer.readNetworkNBTCompound()
return ClientboundPlayerCombatDeathPacket(playerId, message)
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.tick.ticks
import kotlin.time.Duration
public data class ClientboundPlayerEndCombatPacket(val duration: Duration) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPlayerEndCombatPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerEndCombatPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerEndCombatPacket {
return ClientboundPlayerEndCombatPacket(buffer.readVarInt().ticks) // convert int to minecraft ticks
}
}
}
@@ -0,0 +1,18 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data object ClientboundPlayerEnterCombatPacket : MinecraftPacket,
PacketCodec<ClientboundPlayerEnterCombatPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerEnterCombatPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerEnterCombatPacket = ClientboundPlayerEnterCombatPacket
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readPrefixed
import cn.rtast.libmc.common.readUuid
import kotlin.uuid.Uuid
public data class ClientboundPlayerInfoRemovePacket(val uuids: List<Uuid>) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPlayerInfoRemovePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerInfoRemovePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerInfoRemovePacket {
return ClientboundPlayerInfoRemovePacket(buffer.readPrefixed { readUuid() })
}
}
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.math.Vec3d
import cn.rtast.libmc.protocol.protocol.game.math.readVec3d
import cn.rtast.libmc.protocol.protocol.game.player.AnchorPoint
public data class ClientboundPlayerLookAtPacket(
val fromAnchor: AnchorPoint,
val targetPosition: Vec3d,
val entityTarget: EntityLookAtTarget?,
) : MinecraftPacket {
public data class EntityLookAtTarget(
val entityId: Int,
val entityAnchor: AnchorPoint,
)
internal companion object Codec : PacketCodec<ClientboundPlayerLookAtPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerLookAtPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerLookAtPacket {
val fromAnchor = AnchorPoint.fromID(buffer.readVarInt())
val targetPosition = buffer.readVec3d()!!
val isEntity = buffer.readBoolean()
val entityTarget = if (isEntity) {
val entityId = buffer.readVarInt()
val entityAnchor = AnchorPoint.fromID(buffer.readVarInt())
EntityLookAtTarget(entityId, entityAnchor)
} else null
return ClientboundPlayerLookAtPacket(
fromAnchor = fromAnchor,
targetPosition = targetPosition,
entityTarget = entityTarget
)
}
}
}
@@ -0,0 +1,30 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ClientboundPlayerRotationPacket(
val yaw: Float,
val relativeYaw: Boolean,
val pitch: Float,
val relativePitch: Boolean,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPlayerRotationPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundPlayerRotationPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundPlayerRotationPacket {
val yaw = buffer.readFloat()
val relativeYaw = buffer.readBoolean()
val pitch = buffer.readFloat()
val relativePitch = buffer.readBoolean()
return ClientboundPlayerRotationPacket(yaw, relativeYaw, pitch, relativePitch)
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundProjectilePowerPacket(val entityId: Int, val power: Double) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundProjectilePowerPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundProjectilePowerPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundProjectilePowerPacket {
val entityId = buffer.readVarInt()
val power = buffer.readDouble()
return ClientboundProjectilePowerPacket(entityId, power)
}
}
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readPrefixed
import cn.rtast.libmc.common.readVarInt
public data class ClientboundRemoveEntitiesPacket(val entityIds: List<Int>): MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundRemoveEntitiesPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundRemoveEntitiesPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundRemoveEntitiesPacket {
return ClientboundRemoveEntitiesPacket(buffer.readPrefixed { readVarInt() })
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundRemoveEntityEffectPacket(val entityId: Int, val effectId: Int) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundRemoveEntityEffectPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundRemoveEntityEffectPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundRemoveEntityEffectPacket {
val entityId = buffer.readVarInt()
val effectId = buffer.readVarInt()
return ClientboundRemoveEntityEffectPacket(entityId, effectId)
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.*
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ClientboundResetScorePacket(val entityName: String, val objectiveName: String?) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundResetScorePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundResetScorePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundResetScorePacket {
val entityName = buffer.readMcString()
val objectiveName = buffer.readPrefixed { readOptional { readMcString() } }.first() // ?
return ClientboundResetScorePacket(entityName, objectiveName)
}
}
}
@@ -0,0 +1,62 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readOptional
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.GameMode
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
import cn.rtast.libmc.protocol.protocol.game.world.RespawnDataToKeep
public data class ClientboundRespawnPacket(
val dimensionType: Int,
val dimensionName: Identifier,
val hashedSeed: Long,
val gameMode: GameMode,
val previousGameMode: GameMode,
val isDebug: Boolean,
val isFlat: Boolean,
val hasDeathLocation: Boolean,
val deathDimensionName: Identifier?,
val deathLocation: BlockPos?,
val portalCooldown: Int,
val seaLevel: Int,
val dataKept: RespawnDataToKeep,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundRespawnPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundRespawnPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundRespawnPacket {
val dimensionType = buffer.readVarInt()
val dimensionName = buffer.readIdentifier()
val hashedSeed = buffer.readLong()
val gameMode = GameMode.fromID(buffer.readUByte())
val previousGameMode = GameMode.fromID(buffer.readByte())
val isDebug = buffer.readBoolean()
val isFlat = buffer.readBoolean()
val hasDeathLocation = buffer.readBoolean()
val deathDimensionName = buffer.readOptional { readIdentifier() }
val deathLocation = buffer.readOptional { readBlockPos() }
val portalCooldown = buffer.readVarInt()
val seaLevel = buffer.readVarInt()
val dataKept = RespawnDataToKeep.fromByte(buffer.readByte())
return ClientboundRespawnPacket(
dimensionType, dimensionName, hashedSeed,
gameMode, previousGameMode, isDebug,
isFlat, hasDeathLocation,
deathDimensionName, deathLocation,
portalCooldown, seaLevel, dataKept
)
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readOptional
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
public data class ClientboundSelectAdvancementsTabPacket(val tabId: Identifier?) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSelectAdvancementsTabPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSelectAdvancementsTabPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSelectAdvancementsTabPacket {
return ClientboundSelectAdvancementsTabPacket(buffer.readOptional { readIdentifier() })
}
}
}
@@ -0,0 +1,42 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readOptional
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundServerDataPacket(val motd: NBTCompound, val icon: ByteArray?) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundServerDataPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundServerDataPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundServerDataPacket {
val motd = buffer.readNetworkNBTCompound()
val icon = buffer.readOptional { val length = readVarInt(); readBytes(length) }
return ClientboundServerDataPacket(motd, icon)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as ClientboundServerDataPacket
if (motd != other.motd) return false
if (!icon.contentEquals(other.icon)) return false
return true
}
override fun hashCode(): Int {
var result = motd.hashCode()
result = 31 * result + (icon?.contentHashCode() ?: 0)
return result
}
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
public data class ClientboundSetActionBarTextPacket(val text: NBTCompound) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetActionBarTextPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetActionBarTextPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetActionBarTextPacket {
return ClientboundSetActionBarTextPacket(buffer.readNetworkNBTCompound())
}
}
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ClientboundSetBorderCenterPacket(val x: Double, val z: Double) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetBorderCenterPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetBorderCenterPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetBorderCenterPacket {
val x = buffer.readDouble()
val z = buffer.readDouble()
return ClientboundSetBorderCenterPacket(x, z)
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarLong
public data class ClientboundSetBorderLeapSizePacket(
val oldDiameter: Double,
val newDiameter: Double,
val speed: Long,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetBorderLeapSizePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetBorderLeapSizePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetBorderLeapSizePacket {
val oldDiameter = buffer.readDouble()
val newDiameter = buffer.readDouble()
val speed = buffer.readVarLong()
return ClientboundSetBorderLeapSizePacket(oldDiameter, newDiameter, speed)
}
}
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ClientboundSetBorderSizePacket(
/**
* Length of a single side of the world border, in meters
*/
val diameter: Double,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetBorderSizePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetBorderSizePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetBorderSizePacket {
return ClientboundSetBorderSizePacket(buffer.readDouble())
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundSetBorderWarningDelayPacket(
/**
* In seconds as set by /worldborder warning time
*/
val warningTime: Int,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetBorderWarningDelayPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetBorderWarningDelayPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetBorderWarningDelayPacket {
return ClientboundSetBorderWarningDelayPacket(buffer.readVarInt())
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundSetBorderWarningDistancePacket(
/**
* In meters.
*/
val warningBlocks: Int,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetBorderWarningDistancePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetBorderWarningDistancePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetBorderWarningDistancePacket {
return ClientboundSetBorderWarningDistancePacket(buffer.readVarInt())
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundSetCameraPacket(val cameraId: Int) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetCameraPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetCameraPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetCameraPacket {
return ClientboundSetCameraPacket(buffer.readVarInt())
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
public data class ClientboundSetCarriedItemPacket(val slot: Int) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundSetCarriedItemPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundSetCarriedItemPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundSetCarriedItemPacket {
return ClientboundSetCarriedItemPacket(buffer.readVarInt())
}
}
}
Loaded 100 of 261 files, more files were not shown because too many files have changed in this diff. Show more