Complete all serverbound packets at PLAY state

This commit is contained in:
2026-09-06 01:18:32 +08:00
parent 94cca61df1
commit 52917e9425
153 files changed
+3636 -131

No files matched your search

+7 -1
View File
@@ -5,7 +5,11 @@ plugins {
allprojects { allprojects {
group = "cn.rtast.libmc" group = "cn.rtast.libmc"
version = providers.gradleProperty("libVersion").get() val libVersion = getProperty("libVersion")
version = when (name) {
"protocol" -> "${getProperty("protocolVersion")}-$libVersion"
else -> libVersion
}
repositories { repositories {
mavenCentral() mavenCentral()
@@ -30,3 +34,5 @@ subprojects {
} }
} }
} }
fun getProperty(name: String): String = providers.gradleProperty(name).get()
+1
View File
@@ -5,3 +5,4 @@ kotlin.daemon.jvmargs=-Xmx2048M
org.gradle.jvmargs=-Xmx3g -Dfile.encoding=UTF-8 org.gradle.jvmargs=-Xmx3g -Dfile.encoding=UTF-8
libVersion=0.1.0 libVersion=0.1.0
protocolVersion=26.2
@@ -56,9 +56,52 @@ public fun BytesBuffer.readUuid(): Uuid {
public fun BytesBuffer.writeVarInt(value: Int): Unit = VarIntCodec.encode(this, value) public fun BytesBuffer.writeVarInt(value: Int): Unit = VarIntCodec.encode(this, value)
public fun BytesBuffer.readVarInt(): Int = VarIntCodec.decode(this) public fun BytesBuffer.readVarInt(): Int = VarIntCodec.decode(this)
public fun BytesBuffer.writeVarLong(value: Long): Unit = VarLongCodec.encode(this, value)
public fun BytesBuffer.readVarLong(): Long = VarLongCodec.decode(this)
public fun BytesBuffer.writeMcString(value: String): Unit = McStringCodec.encode(this, value) public fun BytesBuffer.writeMcString(value: String): Unit = McStringCodec.encode(this, value)
public fun BytesBuffer.readMcString(): String = McStringCodec.decode(this) public fun BytesBuffer.readMcString(): String = McStringCodec.decode(this)
public fun BytesBuffer.readPrefixedByteArray(): ByteArray {
val length = this.readVarInt()
val data = this.readBytes(length)
return data
}
public fun BytesBuffer.writePrefixedByteArray(data: ByteArray) {
this.writeVarInt(data.size)
this.writeBytes(data)
}
public fun BytesBuffer.readPrefixedVarIntArray(): List<Int> {
val length = readVarInt()
val list = ArrayList<Int>(length)
repeat(length) { list.add(readVarInt()) }
return list
}
public fun BytesBuffer.writePrefixedVarIntArray(value: List<Int>) {
writeVarInt(value.size)
for (item in value) writeVarInt(item)
}
public fun BytesBuffer.readPrefixedStringArray(): List<String> {
val length = readVarInt()
val list = ArrayList<String>(length)
repeat(length) { list.add(readMcString()) }
return list
}
public fun BytesBuffer.writePrefixedStringArray(value: List<String>) {
writeVarInt(value.size)
for (item in value) writeMcString(item)
}
public inline fun <T> BytesBuffer.writePrefixedArray(value: List<T>, writeItem: BytesBuffer.(T) -> Unit) {
writeVarInt(value.size)
for (item in value) writeItem(item)
}
public fun ReadChannel.readPacketFrame(): BytesBuffer { public fun ReadChannel.readPacketFrame(): BytesBuffer {
val length = this.readVarInt() val length = this.readVarInt()
return this.readBytes(length).wrap() return this.readBytes(length).wrap()
@@ -34,6 +34,34 @@ public object VarIntCodec : PacketCodec<Int> {
} }
} }
public object VarLongCodec : PacketCodec<Long> {
override fun encode(buffer: BytesBuffer, value: Long) {
var v = value
while (true) {
if ((v and 0x7FL.inv()) == 0L) {
buffer.writeByte(v.toByte())
return
}
buffer.writeByte(((v and 0x7F) or 0x80).toByte())
v = v ushr 7
}
}
override fun decode(buffer: BytesBuffer): Long {
var numRead = 0
var result = 0L
var read: Byte
do {
read = buffer.readByte()
val value = (read.toLong() and 0x7F)
result = result or (value shl (7 * numRead))
numRead++
if (numRead > 10) throw IllegalArgumentException("VarLong is too big")
} while ((read.toInt() and 0x80) != 0)
return result
}
}
public object McStringCodec : PacketCodec<String> { public object McStringCodec : PacketCodec<String> {
override fun encode(buffer: BytesBuffer, value: String) { override fun encode(buffer: BytesBuffer, value: String) {
val bytes = value.encodeToByteArray() val bytes = value.encodeToByteArray()
@@ -79,10 +79,7 @@ public fun NBTInput.readRootCompound(): NBTCompound {
public fun NBTInput.readNetworkCompound(): NBTCompound { public fun NBTInput.readNetworkCompound(): NBTCompound {
return when (val type = NBTType.fromId(readByte().toInt() and 0xFF)) { return when (val type = NBTType.fromId(readByte().toInt() and 0xFF)) {
NBTType.Compound -> NBTCompound("", readCompoundTag()) NBTType.Compound -> NBTCompound("", readCompoundTag())
NBTType.String -> NBTCompound( NBTType.String -> NBTCompound("", NBTTag.CompoundTag(linkedMapOf("text" to NBTTag.StringTag(readStringTag()))))
"", NBTTag.CompoundTag(linkedMapOf("text" to NBTTag.StringTag(readStringTag())))
)
else -> throw UnsupportedOperationException("Unsupported network nbt tag 0x${type.id.toString(16).uppercase()}") else -> throw UnsupportedOperationException("Unsupported network nbt tag 0x${type.id.toString(16).uppercase()}")
} }
} }
@@ -62,3 +62,10 @@ public fun NBTOutput.writeRootNBTCompound(name: String = ""): ByteArray {
writeTagPayload(root) writeTagPayload(root)
return toByteArray() return toByteArray()
} }
public fun NBTOutput.writeNetworkCompound(compound: NBTCompound) {
val compoundTag = compound.element as? NBTTag.CompoundTag
?: throw IllegalArgumentException("NBTCompound element must be an NBTTag.CompoundTag")
writeByte(NBTType.Compound.id)
writeTagPayload(compoundTag)
}
@@ -0,0 +1,19 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.block
public enum class EnchantmentButton(public val id: Int) {
TOPMOST(0),
MIDDLE(1),
BOTTOM(2);
public companion object {
public fun fromID(id: Int): EnchantmentButton =
requireNotNull(entries.firstOrNull { it.id == id }) { "Unknown enchantment button id $id" }
}
}
@@ -0,0 +1,21 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.block
public enum class LecternButton(public val id: Int) {
PREVIOUS_PAGE(1),
NEXT_PAGE(2),
TAKE_BOOK(3);
public companion object {
public fun fromID(id: Int): LecternButton =
requireNotNull(entries.firstOrNull { it.id == id }) { "Unknown lectern button id $id" }
public fun specificPage(page: Int): Int = 100 + page
}
}
@@ -8,9 +8,41 @@
package cn.rtast.libmc.protocol.client package cn.rtast.libmc.protocol.client
import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.packet.configuration.* import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundConfigurationPacket
import cn.rtast.libmc.protocol.packet.login.* import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundCookieRequestPacket
import cn.rtast.libmc.protocol.packet.play.* import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundCustomPayloadPacket
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundDisconnectConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundFinishConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundKeepAliveConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundPingConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundSelectKnownPacksPacket
import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundAckFinishConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundKeepAliveConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundPongConfigurationPacket
import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundSelectKnownPacksPacket
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundDisconnectLoginPacket
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundLoginPacket
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundLoginSuccessPacket
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundSetCompressionPacket
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginAcknowledgedPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAwardStatisticsPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundBlockDestructionPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundBlockEntityDataPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundDelimiterPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundDisconnectPlayPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundEntityAnimationPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundKeepAlivePlayPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundLoginPlayPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPingPlayPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayerChatMessagePacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundSpawnEntityPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundStartConfigurationPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundSystemChatMessagePacket
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundConfigurationAcknowledgedPacket
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundKeepAlivePlayPacket
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundPongPlayPacket
import cn.rtast.libmc.protocol.protocol.state.ProtocolState import cn.rtast.libmc.protocol.protocol.state.ProtocolState
internal class InternalPacketDispatcher(private val client: MinecraftClient) { internal class InternalPacketDispatcher(private val client: MinecraftClient) {
@@ -90,6 +122,13 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) {
} }
is ClientboundSystemChatMessagePacket -> {} is ClientboundSystemChatMessagePacket -> {}
is ClientboundAcknowledgeBlockChangePacket -> {}
is ClientboundAwardStatisticsPacket -> {}
is ClientboundBlockDestructionPacket -> {}
is ClientboundBlockEntityDataPacket -> {}
ClientboundDelimiterPacket -> {}
is ClientboundEntityAnimationPacket -> {}
is ClientboundSpawnEntityPacket -> {}
} }
} }
} }
@@ -10,9 +10,10 @@ import cn.rtast.libmc.common.LibMCContext
import cn.rtast.libmc.protocol.event.PacketEventDispatcher import cn.rtast.libmc.protocol.event.PacketEventDispatcher
import cn.rtast.libmc.protocol.network.NetworkChannel import cn.rtast.libmc.protocol.network.NetworkChannel
import cn.rtast.libmc.protocol.packet.handshake.ServerboundHandshakePacket import cn.rtast.libmc.protocol.packet.handshake.ServerboundHandshakePacket
import cn.rtast.libmc.protocol.packet.login.ServerboundLoginStartPacket import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginStartPacket
import cn.rtast.libmc.protocol.protocol.state.HandshakeIntent import cn.rtast.libmc.protocol.protocol.state.HandshakeIntent
import cn.rtast.libmc.protocol.protocol.state.ProtocolState import cn.rtast.libmc.protocol.protocol.state.ProtocolState
import cn.rtast.libmc.protocol.session.TransactionIdManager
import cn.rtast.libmc.protocol.util.generateOfflineUuid import cn.rtast.libmc.protocol.util.generateOfflineUuid
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@@ -35,6 +36,8 @@ public class MinecraftClient internal constructor(
private val clientJob = SupervisorJob(parentJob) private val clientJob = SupervisorJob(parentJob)
private var listenJob: Job? = null private var listenJob: Job? = null
public val transactionManager: TransactionIdManager = TransactionIdManager()
override val coroutineContext: CoroutineContext override val coroutineContext: CoroutineContext
get() = clientJob + ioDispatcher + CoroutineName("LibMC-MinecraftClient-$username") get() = clientJob + ioDispatcher + CoroutineName("LibMC-MinecraftClient-$username")
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.packet.MinecraftPacket
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,12 +5,13 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.common.writeVarInt import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.packet.configuration.KnownPacks
public data class ClientboundSelectKnownPacksPacket(val knownPacks: List<KnownPacks>) : ClientboundConfigurationPacket { public data class ClientboundSelectKnownPacksPacket(val knownPacks: List<KnownPacks>) : ClientboundConfigurationPacket {
public companion object Codec : PacketCodec<ClientboundSelectKnownPacksPacket> { public companion object Codec : PacketCodec<ClientboundSelectKnownPacksPacket> {
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,15 +5,13 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.common.writeVarInt import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.Identifier 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 cn.rtast.libmc.protocol.protocol.game.writeIdentifier
public data class ServerboundCookieResponsePacket(val key: Identifier, val payload: ByteArray?) : MinecraftPacket { public data class ServerboundCookieResponsePacket(val key: Identifier, val payload: ByteArray?) : MinecraftPacket {
@@ -24,20 +22,11 @@ public data class ServerboundCookieResponsePacket(val key: Identifier, val paylo
buffer.writeBoolean(true) buffer.writeBoolean(true)
buffer.writeVarInt(value.payload.size) buffer.writeVarInt(value.payload.size)
buffer.writeBytes(value.payload) buffer.writeBytes(value.payload)
} else { } else buffer.writeBoolean(false)
buffer.writeBoolean(false)
}
} }
override fun decode(buffer: BytesBuffer): ServerboundCookieResponsePacket { override fun decode(buffer: BytesBuffer): ServerboundCookieResponsePacket =
val key = buffer.readIdentifier() throw UnsupportedOperationException()
val hasPayload = buffer.readBoolean()
val payload = if (hasPayload) {
val length = buffer.readVarInt()
buffer.readBytes(length)
} else null
return ServerboundCookieResponsePacket(key, payload)
}
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,13 +5,14 @@
*/ */
package cn.rtast.libmc.protocol.packet.configuration package cn.rtast.libmc.protocol.packet.configuration.serverbound
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.common.writeVarInt import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.packet.configuration.KnownPacks
public data class ServerboundSelectKnownPacksPacket(val knownPacks: List<KnownPacks>) : MinecraftPacket { public data class ServerboundSelectKnownPacksPacket(val knownPacks: List<KnownPacks>) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSelectKnownPacksPacket> { public companion object Codec : PacketCodec<ServerboundSelectKnownPacksPacket> {
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.login package cn.rtast.libmc.protocol.packet.login.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.login package cn.rtast.libmc.protocol.packet.login.clientbound
import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.packet.MinecraftPacket
@@ -5,12 +5,12 @@
*/ */
package cn.rtast.libmc.protocol.packet.login package cn.rtast.libmc.protocol.packet.login.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readUuid import cn.rtast.libmc.common.readUuid
import cn.rtast.libmc.protocol.profile.GameProfile import cn.rtast.libmc.protocol.session.GameProfile
import kotlin.uuid.Uuid import kotlin.uuid.Uuid
public data class ClientboundLoginSuccessPacket(val gameProfile: GameProfile, val sessionId: Uuid) : public data class ClientboundLoginSuccessPacket(val gameProfile: GameProfile, val sessionId: Uuid) :
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.login package cn.rtast.libmc.protocol.packet.login.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.login package cn.rtast.libmc.protocol.packet.login.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.login package cn.rtast.libmc.protocol.packet.login.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -1,34 +0,0 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.protocol.packet.play
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
import kotlin.time.Clock
public data class ServerboundChatMessagePacket(
val message: String,
val timestamp: Long = Clock.System.now().toEpochMilliseconds(),
val salt: Long = 0L,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChatMessagePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChatMessagePacket) {
buffer.writeMcString(value.message)
buffer.writeLong(value.timestamp)
buffer.writeLong(value.salt)
buffer.writeBoolean(false) // has signature
buffer.writeVarInt(0) // message count
buffer.writeBytes(byteArrayOf(0, 0, 0))
}
override fun decode(buffer: BytesBuffer): ServerboundChatMessagePacket = throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
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#Acknowledge_Block_Change
*/
public data class ClientboundAcknowledgeBlockChangePacket(val sequenceId: Int) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundAcknowledgeBlockChangePacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundAcknowledgeBlockChangePacket) {}
override fun decode(buffer: BytesBuffer): ClientboundAcknowledgeBlockChangePacket {
return ClientboundAcknowledgeBlockChangePacket(buffer.readVarInt())
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
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.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> {
override fun encode(buffer: BytesBuffer, value: ClientboundAwardStatisticsPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundAwardStatisticsPacket {
val count = buffer.readVarInt()
val stats = List(count) { StatisticsEntry.decode(buffer) }
return ClientboundAwardStatisticsPacket(stats)
}
}
}
@@ -0,0 +1,34 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
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.BlockDestroyStage
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Set_Block_Destroy_Stage
*/
public data class ClientboundBlockDestructionPacket(
val entityId: Int,
val location: BlockPos,
val stage: BlockDestroyStage,
) : ClientboundPlayPacket {
public companion object Codec : PacketCodec<ClientboundBlockDestructionPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundBlockDestructionPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBlockDestructionPacket {
val entityId = buffer.readVarInt()
val location = buffer.readBlockPos()
val stage = buffer.readByte()
return ClientboundBlockDestructionPacket(entityId, location, BlockDestroyStage(stage))
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
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.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
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> {
override fun encode(buffer: BytesBuffer, value: ClientboundBlockEntityDataPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundBlockEntityDataPacket {
val location = buffer.readBlockPos()
val type = buffer.readVarInt()
val data = buffer.readNetworkNBTCompound()
return ClientboundBlockEntityDataPacket(location, type, data)
}
}
}
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,12 +5,12 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.types.Animations import cn.rtast.libmc.protocol.protocol.game.Animations
/** /**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Entity_Animation * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Entity_Animation
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,12 +5,14 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.protocol.game.* import cn.rtast.libmc.protocol.protocol.game.*
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
public data class ClientboundLoginPlayPacket( public data class ClientboundLoginPlayPacket(
val entityId: Int, val entityId: Int,
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.packet.MinecraftPacket
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.* import cn.rtast.libmc.common.*
import cn.rtast.libmc.nbt.NBTCompound import cn.rtast.libmc.nbt.NBTCompound
@@ -5,16 +5,16 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.readUuid import cn.rtast.libmc.common.readUuid
import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.readVarInt
import cn.rtast.libmc.protocol.types.Angle import cn.rtast.libmc.protocol.protocol.game.math.Angle
import cn.rtast.libmc.protocol.types.LpVec3 import cn.rtast.libmc.protocol.protocol.game.math.LpVec3
import cn.rtast.libmc.protocol.types.readAngle import cn.rtast.libmc.protocol.protocol.game.math.readAngle
import cn.rtast.libmc.protocol.types.readLpVec3 import cn.rtast.libmc.protocol.protocol.game.math.readLpVec3
import kotlin.uuid.Uuid import kotlin.uuid.Uuid
/** /**
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundAcceptTeleportationPacket(val teleportId: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundAcceptTeleportationPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundAcceptTeleportationPacket) {
buffer.writeVarInt(value.teleportId)
}
override fun decode(buffer: BytesBuffer): ServerboundAcceptTeleportationPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundAcknowledgeChatMessagePacket(val messageCount: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundAcknowledgeChatMessagePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundAcknowledgeChatMessagePacket) {
buffer.writeVarInt(value.messageCount)
}
override fun decode(buffer: BytesBuffer): ServerboundAcknowledgeChatMessagePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundAttackActionPacket(val entityId: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundAttackActionPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundAttackActionPacket) {
buffer.writeVarInt(value.entityId)
}
override fun decode(buffer: BytesBuffer): ServerboundAttackActionPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundBundleItemSelectedPacket(val slotOfBundle: Int, val slotInBundle: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundBundleItemSelectedPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundBundleItemSelectedPacket) {
buffer.writeVarInt(value.slotOfBundle)
buffer.writeVarInt(value.slotInBundle)
}
override fun decode(buffer: BytesBuffer): ServerboundBundleItemSelectedPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundChangeContainerSlotStatePacket(val slotId: Int, val windowId: Int, val state: Boolean) :
MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChangeContainerSlotStatePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChangeContainerSlotStatePacket) {
buffer.writeVarInt(value.slotId)
buffer.writeVarInt(value.windowId)
buffer.writeBoolean(value.state)
}
override fun decode(buffer: BytesBuffer): ServerboundChangeContainerSlotStatePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.protocol.registry.GameDifficulty
public data class ServerboundChangeDifficultyPacket(val newDifficulty: GameDifficulty) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChangeDifficultyPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChangeDifficultyPacket) {
buffer.writeByte(value.newDifficulty.id)
}
override fun decode(buffer: BytesBuffer): ServerboundChangeDifficultyPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.GameMode
public data class ServerboundChangeGameModePacket(val gameMode: GameMode) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChangeGameModePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChangeGameModePacket) {
require(value.gameMode != GameMode.Unknown && value.gameMode != GameMode.Undefined)
buffer.writeVarInt(value.gameMode.id.toInt())
}
override fun decode(buffer: BytesBuffer): ServerboundChangeGameModePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
public data class ServerboundChatCommandPacket(val command: String) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChatCommandPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChatCommandPacket) {
buffer.writeMcString(value.command.removePrefix("/"))
}
override fun decode(buffer: BytesBuffer): ServerboundChatCommandPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,69 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/4
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundChatMessagePacket(
val message: String,
val timestamp: Long,
val salt: Long,
val signature: ByteArray?,
val messageCount: Int,
val acknowledged: ByteArray,
val checksum: Byte,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChatMessagePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChatMessagePacket) {
buffer.writeMcString(value.message)
buffer.writeLong(value.timestamp)
buffer.writeLong(value.salt)
val hasSignature = value.signature != null
buffer.writeBoolean(hasSignature)
if (hasSignature) buffer.writeBytes(value.signature)
buffer.writeVarInt(value.messageCount)
buffer.writeBytes(value.acknowledged)
buffer.writeByte(value.checksum)
}
override fun decode(buffer: BytesBuffer): ServerboundChatMessagePacket =
throw UnsupportedOperationException()
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as ServerboundChatMessagePacket
if (timestamp != other.timestamp) return false
if (salt != other.salt) return false
if (messageCount != other.messageCount) return false
if (checksum != other.checksum) return false
if (message != other.message) return false
if (!signature.contentEquals(other.signature)) return false
if (!acknowledged.contentEquals(other.acknowledged)) return false
return true
}
override fun hashCode(): Int {
var result = timestamp.hashCode()
result = 31 * result + salt.hashCode()
result = 31 * result + messageCount
result = 31 * result + checksum
result = 31 * result + message.hashCode()
result = 31 * result + (signature?.contentHashCode() ?: 0)
result = 31 * result + acknowledged.contentHashCode()
return result
}
}
@@ -0,0 +1,23 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ServerboundChunkBatchReceivedPacket(val chunksPerTick: Float) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundChunkBatchReceivedPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundChunkBatchReceivedPacket) {
buffer.writeFloat(value.chunksPerTick)
}
override fun decode(buffer: BytesBuffer): ServerboundChunkBatchReceivedPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.registry.ClientAction
public data class ServerboundClientActionPacket(val action: ClientAction) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundClientActionPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundClientActionPacket) {
buffer.writeVarInt(value.action.actionID)
}
override fun decode(buffer: BytesBuffer): ServerboundClientActionPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.player.PlayerActionStatus
public data class ServerboundClientCommandPacket(val action: PlayerActionStatus) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundClientCommandPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundClientCommandPacket) {
buffer.writeVarInt(value.action.id)
}
override fun decode(buffer: BytesBuffer): ServerboundClientCommandPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,67 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.ChatMode
import cn.rtast.libmc.protocol.protocol.game.player.MainHand
import cn.rtast.libmc.protocol.protocol.game.player.skin.ParticleStatus
import cn.rtast.libmc.protocol.protocol.game.player.skin.SkinPartFlag
import cn.rtast.libmc.protocol.protocol.game.player.skin.SkinPartFlags
public data class ServerboundClientInformationPacket(
val locale: String,
/**
* real type is [Byte]
*/
val viewDistance: Int,
val chatMode: ChatMode,
/**
* Colors multiplayer setting. The vanilla server stores this value but does nothing with it (see MC-64867).
* Some third-party servers disable all coloring in chat and system messages when it is false.
*/
val chatColors: Boolean,
/**
* see [SkinPartFlags]
*/
val displayedSkinParts: SkinPartFlag,
val mainHand: MainHand,
/**
* Enables filtering of text on signs and written book titles.
* The vanilla client sets this according to the profanityFilterPreferences.profanityFilterOn
* account attribute indicated by the Mojang API endpoint for player attributes.
* In offline mode, it is always false.
*/
val enableTextFiltering: Boolean,
/**
* Servers usually list online players; this option should let you not show up in that list.
*/
val allowServerListings: Boolean,
val particleStatus: ParticleStatus,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundClientInformationPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundClientInformationPacket) {
buffer.writeMcString(value.locale)
buffer.writeByte(value.viewDistance.toByte())
buffer.writeVarInt(value.chatMode.id)
buffer.writeBoolean(value.chatColors)
buffer.writeByte(value.displayedSkinParts.toByte())
buffer.writeVarInt(value.mainHand.id)
buffer.writeBoolean(value.enableTextFiltering)
buffer.writeBoolean(value.allowServerListings)
buffer.writeVarInt(value.particleStatus.id)
}
override fun decode(buffer: BytesBuffer): ServerboundClientInformationPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,17 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data object ServerboundClientTickEndPacket : MinecraftPacket, PacketCodec<ServerboundClientTickEndPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundClientTickEndPacket) {}
override fun decode(buffer: BytesBuffer): ServerboundClientTickEndPacket = throw UnsupportedOperationException()
}
@@ -0,0 +1,35 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundCommandSuggestionRequestPacket(
/**
* to get transaction id, use `MinecraftClient.transactionManager.nextCommandSuggestionId`
*/
val transactionId: Int,
/**
* All the text behind the cursor including the / (e.g. to the left of the cursor in left-to-right languages like English).
*/
val text: String,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundCommandSuggestionRequestPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundCommandSuggestionRequestPacket) {
buffer.writeVarInt(value.transactionId)
buffer.writeMcString(value.text)
}
override fun decode(buffer: BytesBuffer): ServerboundCommandSuggestionRequestPacket =
throw UnsupportedOperationException()
}
}
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -0,0 +1,30 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.block.EnchantmentButton
import cn.rtast.libmc.protocol.block.LecternButton
public data class ServerboundContainerClickButtonPacket(val windowId: Int, val buttonId: Int) : MinecraftPacket {
public constructor(windowId: Int, button: EnchantmentButton) : this(windowId, button.id)
public constructor(windowId: Int, button: LecternButton) : this(windowId, button.id)
public companion object Codec : PacketCodec<ServerboundContainerClickButtonPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundContainerClickButtonPacket) {
buffer.writeVarInt(value.windowId)
buffer.writeVarInt(value.buttonId)
}
override fun decode(buffer: BytesBuffer): ServerboundContainerClickButtonPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,73 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.container.ContainerButton
import cn.rtast.libmc.protocol.protocol.game.inventory.ChangedSlot
import cn.rtast.libmc.protocol.protocol.game.inventory.HashedSlot
import cn.rtast.libmc.protocol.protocol.game.inventory.InventoryClickType
public data class ServerboundContainerClickPacket(
val windowId: Int,
val stateId: Int,
val slot: Short,
val button: Byte,
val mode: Int,
val changedSlots: List<ChangedSlot>,
val carriedItem: HashedSlot,
) : MinecraftPacket {
public constructor(
windowId: Int,
stateId: Int,
slot: Short,
mouseButton: ContainerButton.Mouse,
changedSlots: List<ChangedSlot>,
carriedItem: HashedSlot,
) : this(
windowId = windowId,
stateId = stateId,
slot = slot,
button = mouseButton.id,
mode = InventoryClickType.PICKUP.id,
changedSlots = changedSlots,
carriedItem = carriedItem
)
public constructor(
windowId: Int,
stateId: Int,
slot: Short,
swapButton: ContainerButton.Swap,
changedSlots: List<ChangedSlot>,
carriedItem: HashedSlot,
) : this(
windowId = windowId,
stateId = stateId,
slot = slot,
button = swapButton.id,
mode = InventoryClickType.SWAP.id,
changedSlots = changedSlots,
carriedItem = carriedItem
)
public companion object Codec : PacketCodec<ServerboundContainerClickPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundContainerClickPacket) {
buffer.writeVarInt(value.windowId)
buffer.writeVarInt(value.stateId)
buffer.writeShort(value.slot)
buffer.writeByte(value.button)
}
override fun decode(buffer: BytesBuffer): ServerboundContainerClickPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundContainerClosePacket(val windowId: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundContainerClosePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundContainerClosePacket) {
buffer.writeVarInt(value.windowId)
}
override fun decode(buffer: BytesBuffer): ServerboundContainerClosePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,37 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.nbt.NBTCompound
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
import cn.rtast.libmc.protocol.protocol.util.writeNetworkNBTCompound
public data class ServerboundCustomClickActionPacket(
val id: Identifier,
/**
* payload size, bytes
*/
val size: Int,
val payload: NBTCompound,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundCustomClickActionPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundCustomClickActionPacket) {
buffer.writeIdentifier(value.id)
buffer.writeVarInt(value.size)
buffer.writeNetworkNBTCompound(value.payload)
}
override fun decode(buffer: BytesBuffer): ServerboundCustomClickActionPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,44 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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.writeIdentifier
public data class ServerboundCustomPayloadPacket(val channel: Identifier, val data: ByteArray) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundCustomPayloadPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundCustomPayloadPacket) {
buffer.writeIdentifier(value.channel)
buffer.writeBytes(value.data) // ?
}
override fun decode(buffer: BytesBuffer): ServerboundCustomPayloadPacket =
throw UnsupportedOperationException()
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as ServerboundCustomPayloadPacket
if (channel != other.channel) return false
if (!data.contentEquals(other.data)) return false
return true
}
override fun hashCode(): Int {
var result = channel.hashCode()
result = 31 * result + data.contentHashCode()
return result
}
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writePrefixedVarIntArray
import cn.rtast.libmc.protocol.protocol.game.debug.DebugSubscriptionType
public data class ServerboundDebugSubscriptionRequestPacket(val subscriptions: List<DebugSubscriptionType>) :
MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundDebugSubscriptionRequestPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundDebugSubscriptionRequestPacket) {
buffer.writePrefixedVarIntArray(value.subscriptions.map { it.id })
}
override fun decode(buffer: BytesBuffer): ServerboundDebugSubscriptionRequestPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,27 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.*
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ServerboundEditBookPacket(val slot: Int, val entries: List<String>, val title: String?) :
MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundEditBookPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundEditBookPacket) {
buffer.writeVarInt(value.slot)
buffer.writePrefixedStringArray(value.entries)
val hasTitle = value.title != null
buffer.writeBoolean(hasTitle)
if (hasTitle) buffer.writeMcString(value.title)
}
override fun decode(buffer: BytesBuffer): ServerboundEditBookPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,35 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.math.LpVec3
import cn.rtast.libmc.protocol.protocol.game.math.writeLpVec3
import cn.rtast.libmc.protocol.protocol.game.player.Hand
public data class ServerboundInteractPacket(
val entityId: Int,
val hand: Hand,
val targetOffset: LpVec3,
val isSneaking: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundInteractPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundInteractPacket) {
buffer.writeVarInt(value.entityId)
buffer.writeVarInt(value.hand.id)
buffer.writeLpVec3(value.targetOffset)
buffer.writeBoolean(value.isSneaking)
}
override fun decode(buffer: BytesBuffer): ServerboundInteractPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,35 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos
public data class ServerboundJigsawGeneratePacket(
val location: BlockPos,
/**
* Value of the levels slider/max depth to generate.
*/
val levels: Int,
val keepJigsaw: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundJigsawGeneratePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundJigsawGeneratePacket) {
buffer.writeBlockPos(value.location)
buffer.writeVarInt(value.levels)
buffer.writeBoolean(value.keepJigsaw)
}
override fun decode(buffer: BytesBuffer): ServerboundJigsawGeneratePacket =
throw UnsupportedOperationException()
}
}
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -0,0 +1,28 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
/**
* Must have at least op level 2 to use.
* Appears to only be used on singleplayer; the difficulty buttons are still disabled in multiplayer.
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Lock_Difficulty
*/
public data class ServerboundLockDifficultyPacket(val locked: Boolean) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundLockDifficultyPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundLockDifficultyPacket) {
buffer.writeBoolean(value.locked)
}
override fun decode(buffer: BytesBuffer): ServerboundLockDifficultyPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,37 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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#Move_Vehicle_(serverbound)
* onGround does not seem to exist
*/
public data class ServerboundMoveVehiclePacket(
val x: Double,
val y: Double,
val z: Double,
val yaw: Float,
val pitch: Float,
// val onGround: Boolean
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundMoveVehiclePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundMoveVehiclePacket) {
buffer.writeDouble(value.x)
buffer.writeDouble(value.y)
buffer.writeDouble(value.z)
buffer.writeFloat(value.yaw)
buffer.writeFloat(value.pitch)
}
override fun decode(buffer: BytesBuffer): ServerboundMoveVehiclePacket = throw UnsupportedOperationException()
}
}
@@ -0,0 +1,36 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
/**
* Used to visually update whether boat paddles are turning.
* The server will update the Boat entity metadata to match the values here.
*
* Right paddle turning is set to true when the left button or forward button is held,
* left paddle turning is set to true when the right button or forward button is held.
*
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Paddle_Boat
*/
public data class ServerboundPaddleBoatPacket(
val leftPaddleTurning: Boolean,
val rightPaddleTurning: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPaddleBoatPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPaddleBoatPacket) {
buffer.writeBoolean(value.leftPaddleTurning)
buffer.writeBoolean(value.rightPaddleTurning)
}
override fun decode(buffer: BytesBuffer): ServerboundPaddleBoatPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,33 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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.writeBlockPos
public data class ServerboundPickItemFromBlockPacket(
val location: BlockPos,
/**
* Used to tell the server to include block data in the new stack,
* works only if in creative mode.
*/
val includeData: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPickItemFromBlockPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPickItemFromBlockPacket) {
buffer.writeBlockPos(value.location)
buffer.writeBoolean(value.includeData)
}
override fun decode(buffer: BytesBuffer): ServerboundPickItemFromBlockPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundPickItemFromEntityPacket(
val entityId: Int,
/**
* Unused by the vanilla server.
*/
val includeData: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPickItemFromEntityPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPickItemFromEntityPacket) {
buffer.writeVarInt(value.entityId)
buffer.writeBoolean(value.includeData)
}
override fun decode(buffer: BytesBuffer): ServerboundPickItemFromEntityPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,30 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundPlaceRecipePacket(
val windowId: Int,
val recipeId: Int,
val makeAll: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPlaceRecipePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPlaceRecipePacket) {
buffer.writeVarInt(value.windowId)
buffer.writeVarInt(value.recipeId)
buffer.writeBoolean(value.makeAll)
}
override fun decode(buffer: BytesBuffer): ServerboundPlaceRecipePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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 ServerboundPlayerAbilitiesPacket(val flags: PlayerAbilities) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPlayerAbilitiesPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPlayerAbilitiesPacket) {
buffer.writeByte(value.flags.flag)
}
override fun decode(buffer: BytesBuffer): ServerboundPlayerAbilitiesPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,43 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockFace
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos
import cn.rtast.libmc.protocol.protocol.game.player.PlayerActionStatus
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Player_Action
*/
public data class ServerboundPlayerActionPacket(
val status: PlayerActionStatus,
val location: BlockPos,
val blockFace: BlockFace,
/**
* Block change sequence number
* see [cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket]
*/
val sequence: Int,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPlayerActionPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPlayerActionPacket) {
buffer.writeVarInt(value.status.id)
buffer.writeBlockPos(value.location)
buffer.writeByte(value.blockFace.id)
buffer.writeVarInt(value.sequence)
}
override fun decode(buffer: BytesBuffer): ServerboundPlayerActionPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,35 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.player.PlayerCommandAction
public data class ServerboundPlayerCommandPacket(
val entityId: Int,
val action: PlayerCommandAction,
/**
* Only used by the start jump with horse action,
* in which case it ranges from 0 to 100. In all other cases it is 0
*/
val jumpBoost: Int,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPlayerCommandPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPlayerCommandPacket) {
buffer.writeVarInt(value.entityId)
buffer.writeVarInt(value.action.id)
buffer.writeVarInt(value.jumpBoost)
}
override fun decode(buffer: BytesBuffer): ServerboundPlayerCommandPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,47 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ServerboundPlayerInputPacket(
val forward: Boolean,
val backward: Boolean,
val left: Boolean,
val right: Boolean,
val jump: Boolean,
val sneak: Boolean,
val sprint: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundPlayerInputPacket> {
private const val FLAG_FORWARD = 0x01
private const val FLAG_BACKWARD = 0x02
private const val FLAG_LEFT = 0x04
private const val FLAG_RIGHT = 0x08
private const val FLAG_JUMP = 0x10
private const val FLAG_SNEAK = 0x20
private const val FLAG_SPRINT = 0x40
override fun encode(buffer: BytesBuffer, value: ServerboundPlayerInputPacket) {
var flags = 0
if (value.forward) flags = flags or FLAG_FORWARD
if (value.backward) flags = flags or FLAG_BACKWARD
if (value.left) flags = flags or FLAG_LEFT
if (value.right) flags = flags or FLAG_RIGHT
if (value.jump) flags = flags or FLAG_JUMP
if (value.sneak) flags = flags or FLAG_SNEAK
if (value.sprint) flags = flags or FLAG_SPRINT
buffer.writeByte(flags.toByte())
}
override fun decode(buffer: BytesBuffer): ServerboundPlayerInputPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,17 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data object ServerboundPlayerLoadedPacket : MinecraftPacket, PacketCodec<ServerboundPlayerLoadedPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundPlayerLoadedPacket) {}
override fun decode(buffer: BytesBuffer): ServerboundPlayerLoadedPacket = throw UnsupportedOperationException()
}
@@ -4,7 +4,7 @@
* Date: 2026/9/5 * Date: 2026/9/5
*/ */
package cn.rtast.libmc.protocol.packet.play package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.PacketCodec
@@ -16,8 +16,7 @@ public data class ServerboundPongPlayPacket(val id: Int) : MinecraftPacket {
buffer.writeInt(value.id) buffer.writeInt(value.id)
} }
override fun decode(buffer: BytesBuffer): ServerboundPongPlayPacket { override fun decode(buffer: BytesBuffer): ServerboundPongPlayPacket =
return ServerboundPongPlayPacket(id = buffer.readInt()) throw UnsupportedOperationException()
}
} }
} }
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
/**
* to get a transaction id, use `MinecraftClient.transactionManager.nextQueryId`
*/
public data class ServerboundQueryBlockEntityTagPacket(val transactionId: Int, val location: BlockPos) :
MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundQueryBlockEntityTagPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundQueryBlockEntityTagPacket) {
buffer.writeVarInt(value.transactionId)
}
override fun decode(buffer: BytesBuffer): ServerboundQueryBlockEntityTagPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundQueryEntityTagPacket(
/**
* to get a transaction id, use `MinecraftClient.transactionManager.nextQueryEntitytagId`
*/
val transactionId: Int,
val entityId: Int,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundQueryEntityTagPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundQueryEntityTagPacket) {
buffer.writeVarInt(value.transactionId)
buffer.writeVarInt(value.entityId)
}
override fun decode(buffer: BytesBuffer): ServerboundQueryEntityTagPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.item.RecipeBookType
public data class ServerboundRecipeBookChangeSettingsPacket(
val bookId: RecipeBookType,
val bookOpen: Boolean,
val filterActive: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundRecipeBookChangeSettingsPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundRecipeBookChangeSettingsPacket) {
buffer.writeVarInt(value.bookId.id)
buffer.writeBoolean(value.bookOpen)
buffer.writeBoolean(value.filterActive)
}
override fun decode(buffer: BytesBuffer): ServerboundRecipeBookChangeSettingsPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundRecipeBookSeenRecipePacket(val recipeId: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundRecipeBookSeenRecipePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundRecipeBookSeenRecipePacket) {
buffer.writeVarInt(value.recipeId)
}
override fun decode(buffer: BytesBuffer): ServerboundRecipeBookSeenRecipePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,25 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
public data class ServerboundRenameItemPacket(val itemName: String) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundRenameItemPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundRenameItemPacket) {
require(value.itemName.length < 50)
buffer.writeMcString(value.itemName)
}
override fun decode(buffer: BytesBuffer): ServerboundRenameItemPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeUuid
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.resources.ResourcePackResult
import kotlin.uuid.Uuid
public data class ServerboundResourcePackResponsePacket(
val uuid: Uuid,
val result: ResourcePackResult,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundResourcePackResponsePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundResourcePackResponsePacket) {
buffer.writeUuid(value.uuid)
buffer.writeVarInt(value.result.id)
}
override fun decode(buffer: BytesBuffer): ServerboundResourcePackResponsePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,32 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.Identifier
import cn.rtast.libmc.protocol.protocol.game.advancement.AdvancementAction
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
public data class ServerboundSeenAdvancementsPacket(val action: AdvancementAction, val tabId: Identifier?) :
MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSeenAdvancementsPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSeenAdvancementsPacket) {
buffer.writeVarInt(value.action.id)
if (value.action == AdvancementAction.OPENED_TAB) {
requireNotNull(value.tabId) { "tabId must not be null when action is OPENED_TAB" }
buffer.writeIdentifier(value.tabId)
} else require(value.tabId == null) { "tabId must be null when action is CLOSED_SCREEN" }
}
override fun decode(buffer: BytesBuffer): ServerboundSeenAdvancementsPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundSelectTradePacket(val selectedSlot: Int) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSelectTradePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSelectTradePacket) {
buffer.writeVarInt(value.selectedSlot)
}
override fun decode(buffer: BytesBuffer): ServerboundSelectTradePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,30 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeVarInt
/**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Set_Beacon_Effect
*/
public data class ServerboundSetBeaconPacket(val primaryEffect: Int?, val secondaryEffect: Int?) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetBeaconPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetBeaconPacket) {
buffer.writeBoolean(value.primaryEffect != null)
if (value.primaryEffect != null) buffer.writeVarInt(value.primaryEffect)
buffer.writeBoolean(value.secondaryEffect != null)
if (value.secondaryEffect != null) buffer.writeVarInt(value.secondaryEffect)
}
override fun decode(buffer: BytesBuffer): ServerboundSetBeaconPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
public data class ServerboundSetCarriedItemPacket(val slot: Short) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetCarriedItemPacket> {
private const val MIN_SLOT: Short = 0
private const val MAX_SLOT: Short = 8
override fun encode(buffer: BytesBuffer, value: ServerboundSetCarriedItemPacket) {
require(value.slot in MIN_SLOT..MAX_SLOT) { "Carried item slot ${value.slot} must be between $MIN_SLOT and $MAX_SLOT" }
buffer.writeShort(value.slot)
}
override fun decode(buffer: BytesBuffer): ServerboundSetCarriedItemPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.CommandBlockMode
import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos
public data class ServerboundSetCommandBlockPacket(
val location: BlockPos,
val command: String,
val mode: CommandBlockMode,
val trackOutput: Boolean,
val conditional: Boolean,
val automatic: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetCommandBlockPacket> {
private const val FLAG_TRACK_OUTPUT = 0x01
private const val FLAG_CONDITIONAL = 0x02
private const val FLAG_AUTOMATIC = 0x04
override fun encode(buffer: BytesBuffer, value: ServerboundSetCommandBlockPacket) {
var flags = 0
if (value.trackOutput) flags = flags or FLAG_TRACK_OUTPUT
if (value.conditional) flags = flags or FLAG_CONDITIONAL
if (value.automatic) flags = flags or FLAG_AUTOMATIC
buffer.writeBlockPos(value.location)
buffer.writeMcString(value.command)
buffer.writeVarInt(value.mode.id)
buffer.writeByte(flags.toByte())
}
override fun decode(buffer: BytesBuffer): ServerboundSetCommandBlockPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,34 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
public data class ServerboundSetCommandMinecartPacket(
val entityId: Int,
val command: String,
/**
* If false, the output of the previous command will not be stored within the command block.
*/
val trackOutput: Boolean,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetCommandMinecartPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetCommandMinecartPacket) {
buffer.writeVarInt(value.entityId)
buffer.writeMcString(value.command)
buffer.writeBoolean(value.trackOutput)
}
override fun decode(buffer: BytesBuffer): ServerboundSetCommandMinecartPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,26 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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.inventory.Slot
import cn.rtast.libmc.protocol.protocol.game.inventory.writeSlot
public data class ServerboundSetCreativeModeSlotPacket(val slot: Short, val clickedItem: Slot) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetCreativeModeSlotPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetCreativeModeSlotPacket) {
buffer.writeShort(value.slot)
buffer.writeSlot(value.clickedItem)
}
override fun decode(buffer: BytesBuffer): ServerboundSetCreativeModeSlotPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,29 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writePrefixedArray
import cn.rtast.libmc.protocol.protocol.game.gamerule.GameRuleEntry
public data class ServerboundSetGameRulePacket(val rules: List<GameRuleEntry>) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetGameRulePacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetGameRulePacket) {
buffer.writePrefixedArray(value.rules) { rule ->
writeMcString(rule.name)
writeMcString(rule.value)
}
}
override fun decode(buffer: BytesBuffer): ServerboundSetGameRulePacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,45 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/6
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.common.BytesBuffer
import cn.rtast.libmc.common.PacketCodec
import cn.rtast.libmc.common.packet.MinecraftPacket
import cn.rtast.libmc.common.writeMcString
import cn.rtast.libmc.common.writeVarInt
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.writeBlockPos
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
public data class ServerboundSetJigsawBlockPacket(
val location: BlockPos,
val name: Identifier,
val target: Identifier,
val pool: Identifier,
val finalState: String,
val jointType: String,
val selectionPriority: Int,
val placementPriority: Int,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetJigsawBlockPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetJigsawBlockPacket) {
buffer.writeBlockPos(value.location)
buffer.writeIdentifier(value.name)
buffer.writeIdentifier(value.target)
buffer.writeIdentifier(value.pool)
buffer.writeMcString(value.finalState)
buffer.writeMcString(value.jointType)
buffer.writeVarInt(value.selectionPriority)
buffer.writeVarInt(value.placementPriority)
}
override fun decode(buffer: BytesBuffer): ServerboundSetJigsawBlockPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,24 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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.PlayerPositionFlag
public data class ServerboundSetPlayerMovementFlagPacket(val flags: PlayerPositionFlag) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetPlayerMovementFlagPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetPlayerMovementFlagPacket) {
buffer.writeByte(value.flags.flag)
}
override fun decode(buffer: BytesBuffer): ServerboundSetPlayerMovementFlagPacket =
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,45 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/5
*/
package cn.rtast.libmc.protocol.packet.play.serverbound
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.PlayerPositionFlag
public data class ServerboundSetPlayerPositionAndRotationPacket(
val x: Double,
/**
* Absolute feet position, normally Head Y - 1.62.
*/
val feetY: Double,
val z: Double,
/**
* Absolute rotation on the X Axis, in degrees.
*/
val yaw: Float,
/**
* Absolute rotation on the Y Axis, in degrees.
*/
val pitch: Float,
val flags: PlayerPositionFlag,
) : MinecraftPacket {
public companion object Codec : PacketCodec<ServerboundSetPlayerPositionAndRotationPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetPlayerPositionAndRotationPacket) {
buffer.writeDouble(value.x)
buffer.writeDouble(value.feetY)
buffer.writeDouble(value.z)
buffer.writeFloat(value.yaw)
buffer.writeFloat(value.pitch)
buffer.writeByte(value.flags.flag)
}
override fun decode(buffer: BytesBuffer): ServerboundSetPlayerPositionAndRotationPacket =
throw UnsupportedOperationException()
}
}
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff. Show more