Complete all serverbound packets
This commit is contained in:
43 files changed
+1002
-100
No files matched your search
@@ -73,6 +73,22 @@ public fun BytesBuffer.writePrefixedByteArray(data: ByteArray) {
|
|||||||
this.writeBytes(data)
|
this.writeBytes(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun BytesBuffer.readOptionalPrefixedByteArray(): ByteArray? {
|
||||||
|
val isPresent = this.readBoolean()
|
||||||
|
return if (isPresent) {
|
||||||
|
val length = this.readVarInt()
|
||||||
|
this.readBytes(length)
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun BytesBuffer.writeOptionalPrefixedByteArray(data: ByteArray?) {
|
||||||
|
if (data != null) {
|
||||||
|
this.writeBoolean(true)
|
||||||
|
this.writeVarInt(data.size)
|
||||||
|
this.writeBytes(data)
|
||||||
|
} else this.writeBoolean(false)
|
||||||
|
}
|
||||||
|
|
||||||
public fun BytesBuffer.readPrefixedVarIntArray(): List<Int> {
|
public fun BytesBuffer.readPrefixedVarIntArray(): List<Int> {
|
||||||
val length = readVarInt()
|
val length = readVarInt()
|
||||||
val list = ArrayList<Int>(length)
|
val list = ArrayList<Int>(length)
|
||||||
|
|||||||
@@ -75,3 +75,24 @@ public object McStringCodec : PacketCodec<String> {
|
|||||||
return bytes.decodeToString()
|
return bytes.decodeToString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed interface IdOrX<out T> {
|
||||||
|
public data class Inline<T>(val value: T) : IdOrX<T>
|
||||||
|
public data class Reference(val registryId: Int) : IdOrX<Nothing>
|
||||||
|
}
|
||||||
|
|
||||||
|
public inline fun <T> BytesBuffer.writeIdOrX(value: IdOrX<T>, writeX: BytesBuffer.(T) -> Unit) {
|
||||||
|
when (value) {
|
||||||
|
is IdOrX.Inline -> {
|
||||||
|
this.writeVarInt(0)
|
||||||
|
this.writeX(value.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
is IdOrX.Reference -> this.writeVarInt(value.registryId + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public inline fun <T> BytesBuffer.readIdOrX(readX: BytesBuffer.() -> T): IdOrX<T> {
|
||||||
|
val id = this.readVarInt()
|
||||||
|
return if (id == 0) IdOrX.Inline(this.readX()) else IdOrX.Reference(id - 1)
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
package cn.rtast.libmc.protocol.client
|
package cn.rtast.libmc.protocol.client
|
||||||
|
|
||||||
import cn.rtast.libmc.common.LibMCContext
|
import cn.rtast.libmc.common.LibMCContext
|
||||||
|
import cn.rtast.libmc.protocol.event.InternalPacketDispatcher
|
||||||
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
|
||||||
|
|||||||
+24
-29
@@ -5,41 +5,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package cn.rtast.libmc.protocol.client
|
package cn.rtast.libmc.protocol.event
|
||||||
|
|
||||||
import cn.rtast.libmc.common.packet.MinecraftPacket
|
import cn.rtast.libmc.common.packet.MinecraftPacket
|
||||||
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundConfigurationPacket
|
import cn.rtast.libmc.protocol.client.MinecraftClient
|
||||||
import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundCookieRequestPacket
|
import cn.rtast.libmc.protocol.packet.configuration.clientbound.*
|
||||||
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.ServerboundAckFinishConfigurationPacket
|
||||||
import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundKeepAliveConfigurationPacket
|
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.ServerboundPongConfigurationPacket
|
||||||
import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundSelectKnownPacksPacket
|
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.*
|
||||||
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.login.serverbound.ServerboundLoginAcknowledgedPacket
|
||||||
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket
|
import cn.rtast.libmc.protocol.packet.play.clientbound.*
|
||||||
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.ServerboundConfigurationAcknowledgedPacket
|
||||||
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundKeepAlivePlayPacket
|
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundKeepAlivePlayPacket
|
||||||
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundPongPlayPacket
|
import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundPongPlayPacket
|
||||||
@@ -69,6 +46,9 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) {
|
|||||||
client.networkChannel.sendPacket(ServerboundLoginAcknowledgedPacket)
|
client.networkChannel.sendPacket(ServerboundLoginAcknowledgedPacket)
|
||||||
client.stateMachine.transitionTo(ProtocolState.CONFIGURATION)
|
client.stateMachine.transitionTo(ProtocolState.CONFIGURATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is ClientboundCustomQueryPacket -> {}
|
||||||
|
is ClientboundHelloPacket -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +82,20 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) {
|
|||||||
is ClientboundSelectKnownPacksPacket -> {
|
is ClientboundSelectKnownPacksPacket -> {
|
||||||
client.networkChannel.sendPacket(ServerboundSelectKnownPacksPacket(emptyList())) // TODO empty resource packs list
|
client.networkChannel.sendPacket(ServerboundSelectKnownPacksPacket(emptyList())) // TODO empty resource packs list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is ClientboundAddResourcePackPacket -> {}
|
||||||
|
ClientboundClearDialogPacket -> {}
|
||||||
|
is ClientboundCodeOfConductPacket -> {}
|
||||||
|
is ClientboundConfigurationShowDialogPacket -> {}
|
||||||
|
is ClientboundCustomReportDetailsPacket -> {}
|
||||||
|
is ClientboundRegistryDataPacket -> {}
|
||||||
|
is ClientboundRemoveResourcePackPacket -> {}
|
||||||
|
ClientboundResetChatPacket -> {}
|
||||||
|
is ClientboundServerLinksPacket -> {}
|
||||||
|
is ClientboundStoreCookiePacket -> {}
|
||||||
|
is ClientboundTransferPacket -> {}
|
||||||
|
is ClientboundUpdateEnabledFeaturesPacket -> {}
|
||||||
|
is ClientboundUpdateTagsPacket -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +104,7 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) {
|
|||||||
is ClientboundDisconnectPlayPacket -> client.close()
|
is ClientboundDisconnectPlayPacket -> client.close()
|
||||||
is ClientboundKeepAlivePlayPacket -> client.networkChannel.sendPacket(ServerboundKeepAlivePlayPacket(id = packet.id))
|
is ClientboundKeepAlivePlayPacket -> client.networkChannel.sendPacket(ServerboundKeepAlivePlayPacket(id = packet.id))
|
||||||
is ClientboundLoginPlayPacket -> println("Successfully joined world Entity ID: ${packet.entityId}")
|
is ClientboundLoginPlayPacket -> println("Successfully joined world Entity ID: ${packet.entityId}")
|
||||||
is ClientboundPingPlayPacket -> client.networkChannel.sendPacket(ServerboundPongPlayPacket(packet.id))
|
is ClientboundPingPacket -> client.networkChannel.sendPacket(ServerboundPongPlayPacket(packet.id))
|
||||||
is ClientboundPlayerChatMessagePacket -> {
|
is ClientboundPlayerChatMessagePacket -> {
|
||||||
println("Received player chat message $packet")
|
println("Received player chat message $packet")
|
||||||
// TODO
|
// TODO
|
||||||
@@ -129,6 +123,7 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) {
|
|||||||
ClientboundDelimiterPacket -> {}
|
ClientboundDelimiterPacket -> {}
|
||||||
is ClientboundEntityAnimationPacket -> {}
|
is ClientboundEntityAnimationPacket -> {}
|
||||||
is ClientboundSpawnEntityPacket -> {}
|
is ClientboundSpawnEntityPacket -> {}
|
||||||
|
is ClientboundShowDialogPacket -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.configuration.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.*
|
||||||
|
import cn.rtast.libmc.nbt.NBTCompound
|
||||||
|
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
|
||||||
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
|
public data class ClientboundAddResourcePackPacket(
|
||||||
|
val uuid: Uuid,
|
||||||
|
val url: String,
|
||||||
|
val hash: String,
|
||||||
|
val forced: Boolean,
|
||||||
|
val prompt: NBTCompound,
|
||||||
|
) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundAddResourcePackPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundAddResourcePackPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundAddResourcePackPacket {
|
||||||
|
val uuid = buffer.readUuid()
|
||||||
|
val url = buffer.readMcString()
|
||||||
|
val hash = buffer.readMcString()
|
||||||
|
val forced = buffer.readBoolean()
|
||||||
|
buffer.readVarInt() // ?
|
||||||
|
val prompt = buffer.readNetworkNBTCompound() // ?
|
||||||
|
return ClientboundAddResourcePackPacket(uuid, url, hash, forced, prompt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.configuration.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
|
||||||
|
public data object ClientboundClearDialogPacket : ClientboundConfigurationPacket,
|
||||||
|
PacketCodec<ClientboundClearDialogPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundClearDialogPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundClearDialogPacket = ClientboundClearDialogPacket
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readMcString
|
||||||
|
|
||||||
|
public data class ClientboundCodeOfConductPacket(val codeOfConduct: String) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundCodeOfConductPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundCodeOfConductPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundCodeOfConductPacket {
|
||||||
|
return ClientboundCodeOfConductPacket(buffer.readMcString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.configuration.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
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> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundConfigurationShowDialogPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundConfigurationShowDialogPacket {
|
||||||
|
return ClientboundConfigurationShowDialogPacket(buffer.readNetworkNBTCompound())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-5
@@ -11,14 +11,10 @@ import cn.rtast.libmc.common.BytesBuffer
|
|||||||
import cn.rtast.libmc.common.PacketCodec
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
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.readIdentifier
|
||||||
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
|
|
||||||
|
|
||||||
public data class ClientboundCookieRequestPacket(val key: Identifier) : ClientboundConfigurationPacket {
|
public data class ClientboundCookieRequestPacket(val key: Identifier) : ClientboundConfigurationPacket {
|
||||||
public companion object Codec : PacketCodec<ClientboundCookieRequestPacket> {
|
public companion object Codec : PacketCodec<ClientboundCookieRequestPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ClientboundCookieRequestPacket) {
|
override fun encode(buffer: BytesBuffer, value: ClientboundCookieRequestPacket) {}
|
||||||
buffer.writeIdentifier(value.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ClientboundCookieRequestPacket {
|
override fun decode(buffer: BytesBuffer): ClientboundCookieRequestPacket {
|
||||||
return ClientboundCookieRequestPacket(key = buffer.readIdentifier())
|
return ClientboundCookieRequestPacket(key = buffer.readIdentifier())
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-10
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2026 RTAkland
|
* Copyright © 2026 RTAkland
|
||||||
* Author: RTAkland
|
* Author: RTAkland
|
||||||
* Date: 2026/9/5
|
* Date: 2026/9/6
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -11,19 +11,16 @@ import cn.rtast.libmc.common.BytesBuffer
|
|||||||
import cn.rtast.libmc.common.PacketCodec
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
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.readIdentifier
|
||||||
import cn.rtast.libmc.protocol.protocol.game.writeIdentifier
|
|
||||||
|
|
||||||
public data class ClientboundCustomPayloadPacket(val channel: Identifier, val data: ByteArray) :
|
public data class ClientboundCustomPayloadPacket(
|
||||||
ClientboundConfigurationPacket {
|
val channel: Identifier,
|
||||||
|
val data: ByteArray,
|
||||||
|
) : ClientboundConfigurationPacket {
|
||||||
public companion object Codec : PacketCodec<ClientboundCustomPayloadPacket> {
|
public companion object Codec : PacketCodec<ClientboundCustomPayloadPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ClientboundCustomPayloadPacket) {
|
override fun encode(buffer: BytesBuffer, value: ClientboundCustomPayloadPacket) {}
|
||||||
buffer.writeIdentifier(value.channel)
|
|
||||||
buffer.writeBytes(value.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ClientboundCustomPayloadPacket {
|
override fun decode(buffer: BytesBuffer): ClientboundCustomPayloadPacket {
|
||||||
val channel = buffer.readIdentifier()
|
val channel = buffer.readIdentifier()
|
||||||
val data = buffer.readBytes(buffer.remaining.toInt())
|
val data = buffer.readRemainingBytes()
|
||||||
return ClientboundCustomPayloadPacket(channel, data)
|
return ClientboundCustomPayloadPacket(channel, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ReportDetail) {
|
||||||
|
buffer.writeMcString(value.title)
|
||||||
|
buffer.writeMcString(value.description)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): ReportDetail {
|
||||||
|
val title = buffer.readMcString()
|
||||||
|
val description = buffer.readMcString()
|
||||||
|
return ReportDetail(title, description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public companion object Codec : PacketCodec<ClientboundCustomReportDetailsPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundCustomReportDetailsPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundCustomReportDetailsPacket {
|
||||||
|
val detailCount = buffer.readVarInt()
|
||||||
|
val details = ArrayList<ReportDetail>(detailCount)
|
||||||
|
repeat(detailCount) { details.add(ReportDetail.decode(buffer)) }
|
||||||
|
return ClientboundCustomReportDetailsPacket(details)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-4
@@ -12,10 +12,7 @@ import cn.rtast.libmc.common.PacketCodec
|
|||||||
|
|
||||||
public data class ClientboundKeepAliveConfigurationPacket(val id: Long) : ClientboundConfigurationPacket {
|
public data class ClientboundKeepAliveConfigurationPacket(val id: Long) : ClientboundConfigurationPacket {
|
||||||
public companion object Codec : PacketCodec<ClientboundKeepAliveConfigurationPacket> {
|
public companion object Codec : PacketCodec<ClientboundKeepAliveConfigurationPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ClientboundKeepAliveConfigurationPacket) {
|
override fun encode(buffer: BytesBuffer, value: ClientboundKeepAliveConfigurationPacket) {}
|
||||||
buffer.writeLong(value.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ClientboundKeepAliveConfigurationPacket {
|
override fun decode(buffer: BytesBuffer): ClientboundKeepAliveConfigurationPacket {
|
||||||
return ClientboundKeepAliveConfigurationPacket(buffer.readLong())
|
return ClientboundKeepAliveConfigurationPacket(buffer.readLong())
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-6
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2026 RTAkland
|
* Copyright © 2026 RTAkland
|
||||||
* Author: RTAkland
|
* Author: RTAkland
|
||||||
* Date: 2026/9/4
|
* Date: 2026/9/6
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -12,10 +12,9 @@ import cn.rtast.libmc.common.PacketCodec
|
|||||||
|
|
||||||
public data class ClientboundPingConfigurationPacket(val id: Int) : ClientboundConfigurationPacket {
|
public data class ClientboundPingConfigurationPacket(val id: Int) : ClientboundConfigurationPacket {
|
||||||
public companion object Codec : PacketCodec<ClientboundPingConfigurationPacket> {
|
public companion object Codec : PacketCodec<ClientboundPingConfigurationPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ClientboundPingConfigurationPacket) {
|
override fun encode(buffer: BytesBuffer, value: ClientboundPingConfigurationPacket) {}
|
||||||
buffer.writeInt(value.id)
|
override fun decode(buffer: BytesBuffer): ClientboundPingConfigurationPacket {
|
||||||
}
|
return ClientboundPingConfigurationPacket(id = buffer.readInt())
|
||||||
|
}
|
||||||
override fun decode(buffer: BytesBuffer): ClientboundPingConfigurationPacket = ClientboundPingConfigurationPacket(buffer.readInt())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readVarInt
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.Identifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.registry.RegistryEntry
|
||||||
|
|
||||||
|
public data class ClientboundRegistryDataPacket(
|
||||||
|
/**
|
||||||
|
* Name of the registry, such as minecraft:dimension_type.
|
||||||
|
*/
|
||||||
|
val registryId: Identifier,
|
||||||
|
val entries: List<RegistryEntry>,
|
||||||
|
) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundRegistryDataPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundRegistryDataPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundRegistryDataPacket {
|
||||||
|
val id = buffer.readIdentifier()
|
||||||
|
val entryCount = buffer.readVarInt()
|
||||||
|
val entries = ArrayList<RegistryEntry>(entryCount)
|
||||||
|
(0 until entryCount).forEach { _ -> entries.add(RegistryEntry.decode(buffer)) }
|
||||||
|
return ClientboundRegistryDataPacket(id, entries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.configuration.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.*
|
||||||
|
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
|
||||||
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
|
public data class ClientboundRemoveResourcePackPacket(val uuid: Uuid) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundRemoveResourcePackPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundRemoveResourcePackPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundRemoveResourcePackPacket {
|
||||||
|
val uuid = buffer.readUuid()
|
||||||
|
return ClientboundRemoveResourcePackPacket(uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.configuration.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
|
||||||
|
public data object ClientboundResetChatPacket : ClientboundConfigurationPacket,
|
||||||
|
PacketCodec<ClientboundResetChatPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundResetChatPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundResetChatPacket = ClientboundResetChatPacket
|
||||||
|
}
|
||||||
+1
-6
@@ -10,16 +10,11 @@ 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.protocol.packet.configuration.KnownPacks
|
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> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ClientboundSelectKnownPacksPacket) {
|
override fun encode(buffer: BytesBuffer, value: ClientboundSelectKnownPacksPacket) {}
|
||||||
buffer.writeVarInt(value.knownPacks.size)
|
|
||||||
value.knownPacks.forEach { KnownPacks.encode(buffer, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ClientboundSelectKnownPacksPacket {
|
override fun decode(buffer: BytesBuffer): ClientboundSelectKnownPacksPacket {
|
||||||
val packsCount = buffer.readVarInt()
|
val packsCount = buffer.readVarInt()
|
||||||
val packs = List(packsCount) { KnownPacks.decode(buffer) }
|
val packs = List(packsCount) { KnownPacks.decode(buffer) }
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readVarInt
|
||||||
|
import cn.rtast.libmc.protocol.registry.report.ServerLink
|
||||||
|
|
||||||
|
public data class ClientboundServerLinksPacket(val links: List<ServerLink>) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundServerLinksPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundServerLinksPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundServerLinksPacket {
|
||||||
|
val count = buffer.readVarInt()
|
||||||
|
val links = ArrayList<ServerLink>(count)
|
||||||
|
repeat(count) { links.add(ServerLink.decode(buffer)) }
|
||||||
|
return ClientboundServerLinksPacket(links)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readPrefixedByteArray
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.Identifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
|
||||||
|
|
||||||
|
public data class ClientboundStoreCookiePacket(
|
||||||
|
val key: Identifier,
|
||||||
|
/**
|
||||||
|
* cookie
|
||||||
|
*/
|
||||||
|
val payload: ByteArray,
|
||||||
|
) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundStoreCookiePacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundStoreCookiePacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundStoreCookiePacket {
|
||||||
|
val key = buffer.readIdentifier()
|
||||||
|
val payload = buffer.readPrefixedByteArray()
|
||||||
|
return ClientboundStoreCookiePacket(key, payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || this::class != other::class) return false
|
||||||
|
|
||||||
|
other as ClientboundStoreCookiePacket
|
||||||
|
|
||||||
|
if (key != other.key) return false
|
||||||
|
if (!payload.contentEquals(other.payload)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = key.hashCode()
|
||||||
|
result = 31 * result + payload.contentHashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readMcString
|
||||||
|
import cn.rtast.libmc.common.readVarInt
|
||||||
|
|
||||||
|
public data class ClientboundTransferPacket(val host: String, val port: Int) : ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundTransferPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundTransferPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundTransferPacket {
|
||||||
|
val host = buffer.readMcString()
|
||||||
|
val port = buffer.readVarInt()
|
||||||
|
return ClientboundTransferPacket(host, port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readVarInt
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.Identifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
|
||||||
|
|
||||||
|
public data class ClientboundUpdateEnabledFeaturesPacket(val features: List<Identifier>) :
|
||||||
|
ClientboundConfigurationPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundUpdateEnabledFeaturesPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundUpdateEnabledFeaturesPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundUpdateEnabledFeaturesPacket {
|
||||||
|
val featureCount = buffer.readVarInt()
|
||||||
|
val features = ArrayList<Identifier>(featureCount)
|
||||||
|
repeat(featureCount) { features.add(buffer.readIdentifier()) }
|
||||||
|
return ClientboundUpdateEnabledFeaturesPacket(features)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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.readVarInt
|
||||||
|
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> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: TaggedRegistry) {
|
||||||
|
buffer.writeIdentifier(value.registryId)
|
||||||
|
buffer.writeVarInt(value.tags.size)
|
||||||
|
value.tags.forEach { Tag.encode(buffer, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): TaggedRegistry {
|
||||||
|
val id = buffer.readIdentifier()
|
||||||
|
val tagCount = buffer.readVarInt()
|
||||||
|
val tags = ArrayList<Tag>(tagCount)
|
||||||
|
repeat(tagCount) { tags.add(Tag.decode(buffer)) }
|
||||||
|
return TaggedRegistry(id, tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public data class Tag(val name: Identifier, val entries: IntArray) {
|
||||||
|
public companion object Codec : PacketCodec<Tag> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: Tag) {
|
||||||
|
buffer.writeIdentifier(value.name)
|
||||||
|
buffer.writeVarInt(value.entries.size)
|
||||||
|
value.entries.forEach { buffer.writeVarInt(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): Tag {
|
||||||
|
val name = buffer.readIdentifier()
|
||||||
|
val entrySize = buffer.readVarInt()
|
||||||
|
val entries = ArrayList<Int>(entrySize)
|
||||||
|
repeat(entrySize) { entries.add(buffer.readVarInt()) }
|
||||||
|
return Tag(name, entries.toIntArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || this::class != other::class) return false
|
||||||
|
other as Tag
|
||||||
|
if (name != other.name) return false
|
||||||
|
if (!entries.contentEquals(other.entries)) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = name.hashCode()
|
||||||
|
result = 31 * result + entries.contentHashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public companion object Codec : PacketCodec<ClientboundUpdateTagsPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundUpdateTagsPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundUpdateTagsPacket {
|
||||||
|
val registryCount = buffer.readVarInt()
|
||||||
|
val registries = ArrayList<TaggedRegistry>(registryCount)
|
||||||
|
repeat(registryCount) { registries.add(TaggedRegistry.decode(buffer)) }
|
||||||
|
return ClientboundUpdateTagsPacket(registries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.configuration.serverbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
import cn.rtast.libmc.common.packet.MinecraftPacket
|
||||||
|
|
||||||
|
public data object ServerboundAcceptCodeOfConductPacket : MinecraftPacket,
|
||||||
|
PacketCodec<ServerboundAcceptCodeOfConductPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ServerboundAcceptCodeOfConductPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ServerboundAcceptCodeOfConductPacket =
|
||||||
|
ServerboundAcceptCodeOfConductPacket
|
||||||
|
}
|
||||||
+1
-2
@@ -14,7 +14,6 @@ import cn.rtast.libmc.common.packet.MinecraftPacket
|
|||||||
public data object ServerboundAckFinishConfigurationPacket : MinecraftPacket,
|
public data object ServerboundAckFinishConfigurationPacket : MinecraftPacket,
|
||||||
PacketCodec<ServerboundAckFinishConfigurationPacket> {
|
PacketCodec<ServerboundAckFinishConfigurationPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ServerboundAckFinishConfigurationPacket) {}
|
override fun encode(buffer: BytesBuffer, value: ServerboundAckFinishConfigurationPacket) {}
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ServerboundAckFinishConfigurationPacket =
|
override fun decode(buffer: BytesBuffer): ServerboundAckFinishConfigurationPacket =
|
||||||
ServerboundAckFinishConfigurationPacket
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
+2
-3
@@ -17,8 +17,7 @@ public data class ServerboundKeepAliveConfigurationPacket(val id: Long) : Minecr
|
|||||||
buffer.writeLong(value.id)
|
buffer.writeLong(value.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ServerboundKeepAliveConfigurationPacket {
|
override fun decode(buffer: BytesBuffer): ServerboundKeepAliveConfigurationPacket =
|
||||||
return ServerboundKeepAliveConfigurationPacket(buffer.readLong())
|
throw UnsupportedOperationException()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -17,6 +17,7 @@ public data class ServerboundPongConfigurationPacket(val id: Int) : MinecraftPac
|
|||||||
buffer.writeInt(value.id)
|
buffer.writeInt(value.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ServerboundPongConfigurationPacket = ServerboundPongConfigurationPacket(buffer.readInt())
|
override fun decode(buffer: BytesBuffer): ServerboundPongConfigurationPacket =
|
||||||
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-7
@@ -7,10 +7,9 @@
|
|||||||
|
|
||||||
package cn.rtast.libmc.protocol.packet.configuration.serverbound
|
package cn.rtast.libmc.protocol.packet.configuration.serverbound
|
||||||
|
|
||||||
import cn.rtast.libmc.common.PacketCodec
|
|
||||||
import cn.rtast.libmc.common.BytesBuffer
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
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.packet.configuration.KnownPacks
|
import cn.rtast.libmc.protocol.packet.configuration.KnownPacks
|
||||||
|
|
||||||
@@ -21,10 +20,7 @@ public data class ServerboundSelectKnownPacksPacket(val knownPacks: List<KnownPa
|
|||||||
value.knownPacks.forEach { KnownPacks.encode(buffer, it) }
|
value.knownPacks.forEach { KnownPacks.encode(buffer, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ServerboundSelectKnownPacksPacket {
|
override fun decode(buffer: BytesBuffer): ServerboundSelectKnownPacksPacket =
|
||||||
val packsCount = buffer.readVarInt()
|
throw UnsupportedOperationException()
|
||||||
val packs = List(packsCount) { KnownPacks.decode(buffer) }
|
|
||||||
return ServerboundSelectKnownPacksPacket(packs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/5
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.login.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.Identifier
|
||||||
|
import cn.rtast.libmc.protocol.protocol.game.readIdentifier
|
||||||
|
|
||||||
|
public data class ClientboundCustomQueryPacket(
|
||||||
|
val messageId: Int,
|
||||||
|
val channel: Identifier,
|
||||||
|
val data: ByteArray,
|
||||||
|
) : ClientboundLoginPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundCustomQueryPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundCustomQueryPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundCustomQueryPacket {
|
||||||
|
val messageId = buffer.readVarInt()
|
||||||
|
val channel = buffer.readIdentifier()
|
||||||
|
val data = buffer.readBytes(buffer.remaining.toInt())
|
||||||
|
return ClientboundCustomQueryPacket(messageId, channel, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || this::class != other::class) return false
|
||||||
|
|
||||||
|
other as ClientboundCustomQueryPacket
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.login.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
import cn.rtast.libmc.common.readMcString
|
||||||
|
import cn.rtast.libmc.common.readPrefixedByteArray
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Encryption_Request
|
||||||
|
*/
|
||||||
|
public data class ClientboundHelloPacket(
|
||||||
|
val serverId: String,
|
||||||
|
val publicKey: ByteArray,
|
||||||
|
val verifyToken: ByteArray,
|
||||||
|
/**
|
||||||
|
* Whether the client should attempt to authenticate through mojang servers.
|
||||||
|
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Encryption#Authentication
|
||||||
|
*/
|
||||||
|
val shouldAuthenticate: Boolean,
|
||||||
|
) : ClientboundLoginPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundHelloPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundHelloPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundHelloPacket {
|
||||||
|
val serverId = buffer.readMcString()
|
||||||
|
val publicKey = buffer.readPrefixedByteArray()
|
||||||
|
val verifyToken = buffer.readPrefixedByteArray()
|
||||||
|
val shouldAuthenticate = buffer.readBoolean()
|
||||||
|
return ClientboundHelloPacket(serverId, publicKey, verifyToken, shouldAuthenticate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || this::class != other::class) return false
|
||||||
|
|
||||||
|
other as ClientboundHelloPacket
|
||||||
|
|
||||||
|
if (shouldAuthenticate != other.shouldAuthenticate) return false
|
||||||
|
if (serverId != other.serverId) return false
|
||||||
|
if (!publicKey.contentEquals(other.publicKey)) return false
|
||||||
|
if (!verifyToken.contentEquals(other.verifyToken)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = shouldAuthenticate.hashCode()
|
||||||
|
result = 31 * result + serverId.hashCode()
|
||||||
|
result = 31 * result + publicKey.contentHashCode()
|
||||||
|
result = 31 * result + verifyToken.contentHashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.login.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.writeOptionalPrefixedByteArray
|
||||||
|
import cn.rtast.libmc.common.writeVarInt
|
||||||
|
|
||||||
|
public data class ServerboundCustomQueryAnswerPacket(val messageId: Int, val data: ByteArray?) : MinecraftPacket {
|
||||||
|
public companion object Codec : PacketCodec<ServerboundCustomQueryAnswerPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ServerboundCustomQueryAnswerPacket) {
|
||||||
|
buffer.writeVarInt(value.messageId)
|
||||||
|
buffer.writeOptionalPrefixedByteArray(value.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): ServerboundCustomQueryAnswerPacket =
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || this::class != other::class) return false
|
||||||
|
|
||||||
|
other as ServerboundCustomQueryAnswerPacket
|
||||||
|
|
||||||
|
if (messageId != other.messageId) return false
|
||||||
|
if (!data.contentEquals(other.data)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = messageId
|
||||||
|
result = 31 * result + (data?.contentHashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.login.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.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> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ServerboundKeyPacket) {
|
||||||
|
buffer.writePrefixedByteArray(value.sharedSecret)
|
||||||
|
buffer.writePrefixedByteArray(value.verifyToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): ServerboundKeyPacket =
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other == null || this::class != other::class) return false
|
||||||
|
|
||||||
|
other as ServerboundKeyPacket
|
||||||
|
|
||||||
|
if (!sharedSecret.contentEquals(other.sharedSecret)) return false
|
||||||
|
if (!verifyToken.contentEquals(other.verifyToken)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = sharedSecret.contentHashCode()
|
||||||
|
result = 31 * result + verifyToken.contentHashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-8
@@ -10,14 +10,11 @@ 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
|
||||||
|
|
||||||
public data class ClientboundPingPlayPacket(val id: Int) : ClientboundPlayPacket {
|
public data class ClientboundPingPacket(val id: Int) : ClientboundPlayPacket {
|
||||||
public companion object Codec : PacketCodec<ClientboundPingPlayPacket> {
|
public companion object Codec : PacketCodec<ClientboundPingPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ClientboundPingPlayPacket) {
|
override fun encode(buffer: BytesBuffer, value: ClientboundPingPacket) {}
|
||||||
buffer.writeInt(value.id)
|
override fun decode(buffer: BytesBuffer): ClientboundPingPacket {
|
||||||
}
|
return ClientboundPingPacket(id = buffer.readInt())
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ClientboundPingPlayPacket {
|
|
||||||
return ClientboundPingPlayPacket(id = buffer.readInt())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+24
@@ -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.IdOrX
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
import cn.rtast.libmc.common.readIdOrX
|
||||||
|
import cn.rtast.libmc.nbt.NBTCompound
|
||||||
|
import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound
|
||||||
|
|
||||||
|
public data class ClientboundShowDialogPacket(val dialog: IdOrX<NBTCompound>) : ClientboundPlayPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundShowDialogPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundShowDialogPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundShowDialogPacket {
|
||||||
|
return ClientboundShowDialogPacket(buffer.readIdOrX { this.readNetworkNBTCompound() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.status.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
|
||||||
|
public data class ClientboundPongResponsePacket(val timestamp: Long) : ClientboundStatusPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundPongResponsePacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundPongResponsePacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundPongResponsePacket {
|
||||||
|
return ClientboundPongResponsePacket(buffer.readLong())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.status.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.packet.MinecraftPacket
|
||||||
|
|
||||||
|
public sealed interface ClientboundStatusPacket : MinecraftPacket
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.status.clientbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
import cn.rtast.libmc.common.readMcString
|
||||||
|
|
||||||
|
public data class ClientboundStatusResponsePacket(val jsonResponse: String) : ClientboundStatusPacket {
|
||||||
|
public companion object Codec : PacketCodec<ClientboundStatusResponsePacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ClientboundStatusResponsePacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ClientboundStatusResponsePacket =
|
||||||
|
ClientboundStatusResponsePacket(buffer.readMcString())
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -11,13 +11,13 @@ 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
|
||||||
|
|
||||||
public data class ServerboundPingRequest(val timestamp: Long) : MinecraftPacket {
|
public data class ServerboundPingRequestPacket(val timestamp: Long) : MinecraftPacket {
|
||||||
public companion object Codec : PacketCodec<ServerboundPingRequest> {
|
public companion object Codec : PacketCodec<ServerboundPingRequestPacket> {
|
||||||
override fun encode(buffer: BytesBuffer, value: ServerboundPingRequest) {
|
override fun encode(buffer: BytesBuffer, value: ServerboundPingRequestPacket) {
|
||||||
buffer.writeLong(value.timestamp)
|
buffer.writeLong(value.timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decode(buffer: BytesBuffer): ServerboundPingRequest =
|
override fun decode(buffer: BytesBuffer): ServerboundPingRequestPacket =
|
||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.packet.status.serverbound
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
import cn.rtast.libmc.common.packet.MinecraftPacket
|
||||||
|
|
||||||
|
public data object ServerboundStatusRequestPacket : MinecraftPacket, PacketCodec<ServerboundStatusRequestPacket> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ServerboundStatusRequestPacket) {}
|
||||||
|
override fun decode(buffer: BytesBuffer): ServerboundStatusRequestPacket =
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
+64
-15
@@ -9,19 +9,34 @@ package cn.rtast.libmc.protocol.protocol
|
|||||||
import cn.rtast.libmc.protocol.packet.configuration.clientbound.*
|
import cn.rtast.libmc.protocol.packet.configuration.clientbound.*
|
||||||
import cn.rtast.libmc.protocol.packet.configuration.serverbound.*
|
import cn.rtast.libmc.protocol.packet.configuration.serverbound.*
|
||||||
import cn.rtast.libmc.protocol.packet.handshake.ServerboundHandshakePacket
|
import cn.rtast.libmc.protocol.packet.handshake.ServerboundHandshakePacket
|
||||||
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundDisconnectLoginPacket
|
import cn.rtast.libmc.protocol.packet.login.clientbound.*
|
||||||
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundLoginSuccessPacket
|
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket
|
||||||
import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundSetCompressionPacket
|
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundKeyPacket
|
||||||
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginAcknowledgedPacket
|
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginAcknowledgedPacket
|
||||||
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginStartPacket
|
import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginStartPacket
|
||||||
import cn.rtast.libmc.protocol.packet.play.clientbound.*
|
import cn.rtast.libmc.protocol.packet.play.clientbound.*
|
||||||
import cn.rtast.libmc.protocol.packet.play.serverbound.*
|
import cn.rtast.libmc.protocol.packet.play.serverbound.*
|
||||||
import cn.rtast.libmc.protocol.packet.status.serverbound.ServerboundPingRequest
|
import cn.rtast.libmc.protocol.packet.status.clientbound.ClientboundPongResponsePacket
|
||||||
|
import cn.rtast.libmc.protocol.packet.status.clientbound.ClientboundStatusResponsePacket
|
||||||
|
import cn.rtast.libmc.protocol.packet.status.serverbound.ServerboundPingRequestPacket
|
||||||
|
import cn.rtast.libmc.protocol.packet.status.serverbound.ServerboundStatusRequestPacket
|
||||||
import cn.rtast.libmc.protocol.protocol.state.ProtocolState
|
import cn.rtast.libmc.protocol.protocol.state.ProtocolState
|
||||||
import cn.rtast.libmc.protocol.protocol.state.ProtocolStateRegistry
|
import cn.rtast.libmc.protocol.protocol.state.ProtocolStateRegistry
|
||||||
|
|
||||||
internal object GameProtocols {
|
internal object GameProtocols {
|
||||||
val clientboundGameProtocols = ProtocolStateRegistry().apply {
|
val clientboundGameProtocols = ProtocolStateRegistry().apply {
|
||||||
|
register(ProtocolState.STATUS) {
|
||||||
|
register(0x00, ClientboundStatusResponsePacket)
|
||||||
|
register(0x01, ClientboundPongResponsePacket)
|
||||||
|
}
|
||||||
|
register(ProtocolState.LOGIN) {
|
||||||
|
register(0x00, ClientboundDisconnectLoginPacket)
|
||||||
|
register(0x01, ClientboundHelloPacket)
|
||||||
|
register(0x02, ClientboundLoginSuccessPacket)
|
||||||
|
register(0x03, ClientboundSetCompressionPacket)
|
||||||
|
register(0x04, ClientboundCustomQueryPacket)
|
||||||
|
register(0x05, ClientboundCookieRequestPacket)
|
||||||
|
}
|
||||||
register(ProtocolState.CONFIGURATION) {
|
register(ProtocolState.CONFIGURATION) {
|
||||||
register(0x00, ClientboundCookieRequestPacket)
|
register(0x00, ClientboundCookieRequestPacket)
|
||||||
register(0x01, ClientboundCustomPayloadPacket)
|
register(0x01, ClientboundCustomPayloadPacket)
|
||||||
@@ -29,12 +44,20 @@ internal object GameProtocols {
|
|||||||
register(0x03, ClientboundFinishConfigurationPacket)
|
register(0x03, ClientboundFinishConfigurationPacket)
|
||||||
register(0x04, ClientboundKeepAliveConfigurationPacket)
|
register(0x04, ClientboundKeepAliveConfigurationPacket)
|
||||||
register(0x05, ClientboundPingConfigurationPacket)
|
register(0x05, ClientboundPingConfigurationPacket)
|
||||||
|
register(0x06, ClientboundResetChatPacket)
|
||||||
|
register(0x07, ClientboundRegistryDataPacket)
|
||||||
|
register(0x08, ClientboundRemoveResourcePackPacket)
|
||||||
|
register(0x09, ClientboundAddResourcePackPacket)
|
||||||
|
register(0x0a, ClientboundStoreCookiePacket)
|
||||||
|
register(0x0b, ClientboundTransferPacket)
|
||||||
|
register(0x0c, ClientboundUpdateEnabledFeaturesPacket)
|
||||||
|
register(0x0d, ClientboundUpdateTagsPacket)
|
||||||
register(0x0e, ClientboundSelectKnownPacksPacket)
|
register(0x0e, ClientboundSelectKnownPacksPacket)
|
||||||
}
|
register(0x0f, ClientboundCustomReportDetailsPacket)
|
||||||
register(ProtocolState.LOGIN) {
|
register(0x10, ClientboundServerLinksPacket)
|
||||||
register(0x00, ClientboundDisconnectLoginPacket)
|
register(0x11, ClientboundClearDialogPacket)
|
||||||
register(0x02, ClientboundLoginSuccessPacket)
|
register(0x12, ClientboundConfigurationShowDialogPacket)
|
||||||
register(0x03, ClientboundSetCompressionPacket)
|
register(0x13, ClientboundCodeOfConductPacket)
|
||||||
}
|
}
|
||||||
register(ProtocolState.PLAY) {
|
register(ProtocolState.PLAY) {
|
||||||
register(0x00, ClientboundDelimiterPacket)
|
register(0x00, ClientboundDelimiterPacket)
|
||||||
@@ -45,13 +68,29 @@ internal object GameProtocols {
|
|||||||
register(0x05, ClientboundBlockDestructionPacket)
|
register(0x05, ClientboundBlockDestructionPacket)
|
||||||
register(0x06, ClientboundBlockEntityDataPacket)
|
register(0x06, ClientboundBlockEntityDataPacket)
|
||||||
|
|
||||||
|
register(0x15, ClientboundCookieRequestPacket)
|
||||||
|
|
||||||
register(0x20, ClientboundDisconnectPlayPacket)
|
register(0x20, ClientboundDisconnectPlayPacket)
|
||||||
|
register(0x24, ClientboundCustomPayloadPacket)
|
||||||
register(0x2c, ClientboundKeepAlivePlayPacket)
|
register(0x2c, ClientboundKeepAlivePlayPacket)
|
||||||
register(0x31, ClientboundLoginPlayPacket)
|
register(0x31, ClientboundLoginPlayPacket)
|
||||||
register(0x3d, ClientboundPingPlayPacket)
|
register(0x3d, ClientboundPingPacket)
|
||||||
register(0x41, ClientboundPlayerChatMessagePacket)
|
register(0x41, ClientboundPlayerChatMessagePacket)
|
||||||
|
register(0x50, ClientboundRemoveResourcePackPacket)
|
||||||
|
register(0x51, ClientboundAddResourcePackPacket)
|
||||||
register(0x76, ClientboundStartConfigurationPacket)
|
register(0x76, ClientboundStartConfigurationPacket)
|
||||||
|
register(0x78, ClientboundStoreCookiePacket)
|
||||||
register(0x79, ClientboundSystemChatMessagePacket)
|
register(0x79, ClientboundSystemChatMessagePacket)
|
||||||
|
|
||||||
|
register(0x81, ClientboundTransferPacket)
|
||||||
|
|
||||||
|
register(0x86, ClientboundUpdateTagsPacket)
|
||||||
|
|
||||||
|
register(0x88, ClientboundCustomReportDetailsPacket)
|
||||||
|
register(0x89, ClientboundServerLinksPacket)
|
||||||
|
|
||||||
|
register(0x8b, ClientboundClearDialogPacket)
|
||||||
|
register(0x8c, ClientboundShowDialogPacket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,17 +98,27 @@ internal object GameProtocols {
|
|||||||
register(ProtocolState.HANDSHAKE) {
|
register(ProtocolState.HANDSHAKE) {
|
||||||
register(0x00, ServerboundHandshakePacket)
|
register(0x00, ServerboundHandshakePacket)
|
||||||
}
|
}
|
||||||
|
register(ProtocolState.STATUS) {
|
||||||
|
register(0x00, ServerboundStatusRequestPacket)
|
||||||
|
register(0x01, ServerboundPingRequestPacket)
|
||||||
|
}
|
||||||
|
register(ProtocolState.LOGIN) {
|
||||||
|
register(0x00, ServerboundLoginStartPacket)
|
||||||
|
register(0x01, ServerboundKeyPacket)
|
||||||
|
register(0x02, ServerboundCustomQueryAnswerPacket)
|
||||||
|
register(0x03, ServerboundLoginAcknowledgedPacket)
|
||||||
|
register(0x04, ServerboundCookieResponsePacket)
|
||||||
|
}
|
||||||
register(ProtocolState.CONFIGURATION) {
|
register(ProtocolState.CONFIGURATION) {
|
||||||
register(0x00, ServerboundCookieResponsePacket)
|
register(0x00, ServerboundCookieResponsePacket)
|
||||||
|
register(0x01, ServerboundCookieResponsePacket)
|
||||||
register(0x02, ServerboundCustomPayloadPacket)
|
register(0x02, ServerboundCustomPayloadPacket)
|
||||||
register(0x03, ServerboundAckFinishConfigurationPacket)
|
register(0x03, ServerboundAckFinishConfigurationPacket)
|
||||||
register(0x04, ServerboundKeepAliveConfigurationPacket)
|
register(0x04, ServerboundKeepAliveConfigurationPacket)
|
||||||
register(0x05, ServerboundPongConfigurationPacket)
|
register(0x05, ServerboundPongConfigurationPacket)
|
||||||
register(0x07, ServerboundSelectKnownPacksPacket)
|
register(0x07, ServerboundSelectKnownPacksPacket)
|
||||||
}
|
register(0x08, ServerboundCustomClickActionPacket)
|
||||||
register(ProtocolState.LOGIN) {
|
register(0x09, ServerboundAcceptCodeOfConductPacket)
|
||||||
register(0x00, ServerboundLoginStartPacket)
|
|
||||||
register(0x03, ServerboundLoginAcknowledgedPacket)
|
|
||||||
}
|
}
|
||||||
register(ProtocolState.PLAY) {
|
register(ProtocolState.PLAY) {
|
||||||
register(0x00, ServerboundAcceptTeleportationPacket)
|
register(0x00, ServerboundAcceptTeleportationPacket)
|
||||||
@@ -110,7 +159,7 @@ internal object GameProtocols {
|
|||||||
register(0x23, ServerboundPaddleBoatPacket)
|
register(0x23, ServerboundPaddleBoatPacket)
|
||||||
register(0x24, ServerboundPickItemFromBlockPacket)
|
register(0x24, ServerboundPickItemFromBlockPacket)
|
||||||
register(0x25, ServerboundPickItemFromEntityPacket)
|
register(0x25, ServerboundPickItemFromEntityPacket)
|
||||||
register(0x26, ServerboundPingRequest)
|
register(0x26, ServerboundPingRequestPacket)
|
||||||
register(0x27, ServerboundPlaceRecipePacket)
|
register(0x27, ServerboundPlaceRecipePacket)
|
||||||
register(0x28, ServerboundPlayerAbilitiesPacket)
|
register(0x28, ServerboundPlayerAbilitiesPacket)
|
||||||
register(0x29, ServerboundPlayerActionPacket)
|
register(0x29, ServerboundPlayerActionPacket)
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.protocol.game.registry
|
||||||
|
|
||||||
|
import cn.rtast.libmc.common.BytesBuffer
|
||||||
|
import cn.rtast.libmc.common.PacketCodec
|
||||||
|
import cn.rtast.libmc.nbt.NBTCompound
|
||||||
|
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.util.readNetworkNBTCompound
|
||||||
|
import cn.rtast.libmc.protocol.protocol.util.writeNetworkNBTCompound
|
||||||
|
|
||||||
|
public data class RegistryEntry(
|
||||||
|
/**
|
||||||
|
* Name of the entry, such as minecraft:overworld.
|
||||||
|
*/
|
||||||
|
val id: Identifier,
|
||||||
|
/**
|
||||||
|
* Entry data. If omitted, sourced from the selected known packs.
|
||||||
|
*/
|
||||||
|
val data: NBTCompound?,
|
||||||
|
) {
|
||||||
|
public companion object Codec : PacketCodec<RegistryEntry> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: RegistryEntry) {
|
||||||
|
buffer.writeIdentifier(value.id)
|
||||||
|
buffer.writeBoolean(value.data != null)
|
||||||
|
if (value.data != null) buffer.writeNetworkNBTCompound(value.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): RegistryEntry {
|
||||||
|
val id = buffer.readIdentifier()
|
||||||
|
val hasData = buffer.readBoolean()
|
||||||
|
val data = if (hasData) buffer.readNetworkNBTCompound() else null
|
||||||
|
return RegistryEntry(id, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-1
@@ -12,5 +12,10 @@ public enum class ProtocolState {
|
|||||||
LOGIN,
|
LOGIN,
|
||||||
CONFIGURATION,
|
CONFIGURATION,
|
||||||
PLAY,
|
PLAY,
|
||||||
DISCONNECTED
|
STATUS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reserved
|
||||||
|
*/
|
||||||
|
DISCONNECTED,
|
||||||
}
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.registry.report
|
||||||
|
|
||||||
|
public enum class BuiltinServerLinkType(public val id: Int) {
|
||||||
|
BUG_REPORT(0),
|
||||||
|
COMMUNITY_GUIDELINES(1),
|
||||||
|
SUPPORT(2),
|
||||||
|
STATUS(3),
|
||||||
|
FEEDBACK(4),
|
||||||
|
COMMUNITY(5),
|
||||||
|
WEBSITE(6),
|
||||||
|
FORUMS(7),
|
||||||
|
NEWS(8),
|
||||||
|
ANNOUNCEMENTS(9);
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public fun fromID(id: Int): BuiltinServerLinkType = entries.first { it.id == id }
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2026 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2026/9/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package cn.rtast.libmc.protocol.registry.report
|
||||||
|
|
||||||
|
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 ServerLink(val label: ServerLinkLabel, val url: String) {
|
||||||
|
public companion object Codec : PacketCodec<ServerLink> {
|
||||||
|
override fun encode(buffer: BytesBuffer, value: ServerLink) {
|
||||||
|
when (value.label) {
|
||||||
|
is ServerLinkLabel.Builtin -> {
|
||||||
|
buffer.writeBoolean(true)
|
||||||
|
buffer.writeVarInt(value.label.type.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ServerLinkLabel.Custom -> {
|
||||||
|
buffer.writeBoolean(false)
|
||||||
|
buffer.writeNetworkNBTCompound(value.label.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.writeMcString(value.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buffer: BytesBuffer): ServerLink {
|
||||||
|
val isBuiltin = buffer.readBoolean()
|
||||||
|
val label = if (isBuiltin) ServerLinkLabel.Builtin(BuiltinServerLinkType.fromID(buffer.readVarInt()))
|
||||||
|
else ServerLinkLabel.Custom(buffer.readNetworkNBTCompound())
|
||||||
|
val url = buffer.readMcString()
|
||||||
|
return ServerLink(label, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed interface ServerLinkLabel {
|
||||||
|
public data class Builtin(val type: BuiltinServerLinkType) : ServerLinkLabel
|
||||||
|
public data class Custom(val text: NBTCompound) : ServerLinkLabel
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user