Implemented clientbound packet player_info_update 0x46

This commit is contained in:
2026-09-07 21:07:11 +08:00
parent 991bf72073
commit 8dca918cfd
10 files changed
+268 -97

No files matched your search

+4 -4
View File
@@ -143,7 +143,7 @@ A lightweight minecraft client-side protocol library and related library, includ
- [x] `0x0D` Chunks Biomes (`ClientboundChunksBiomesPacket`) - [x] `0x0D` Chunks Biomes (`ClientboundChunksBiomesPacket`)
- [x] `0x0E` Clear Titles (`ClientboundClearTitlesPacket`) - [x] `0x0E` Clear Titles (`ClientboundClearTitlesPacket`)
- [x] `0x0F` Command Suggestions (`ClientboundCommandSuggestionsPacket`) - [x] `0x0F` Command Suggestions (`ClientboundCommandSuggestionsPacket`)
- [ ] `0x10` Commands (`ClientboundCommandsPacket`) - [x] `0x10` Commands (`ClientboundCommandsPacket`)
- [x] `0x11` Container Close (`ClientboundContainerClosePacket`) - [x] `0x11` Container Close (`ClientboundContainerClosePacket`)
- [ ] `0x12` Container Set Content (`ClientboundContainerSetContentPacket`) - [ ] `0x12` Container Set Content (`ClientboundContainerSetContentPacket`)
- [x] `0x13` Container Set Data (`ClientboundContainerSetDataPacket`) - [x] `0x13` Container Set Data (`ClientboundContainerSetDataPacket`)
@@ -178,7 +178,7 @@ A lightweight minecraft client-side protocol library and related library, includ
- [ ] `0x30` Light Update (`ClientboundLightUpdatePacket`) - [ ] `0x30` Light Update (`ClientboundLightUpdatePacket`)
- [x] `0x31` Login Play (`ClientboundLoginPlayPacket`) - [x] `0x31` Login Play (`ClientboundLoginPlayPacket`)
- [x] `0x32` Low Disk Space Warning (`ClientboundLowDiskSpaceWarningPacket`) - [x] `0x32` Low Disk Space Warning (`ClientboundLowDiskSpaceWarningPacket`)
- [ ] `0x33` Map Item Data (`ClientboundMapItemDataPacket`) - [x] `0x33` Map Item Data (`ClientboundMapItemDataPacket`)
- [ ] `0x34` Merchant Offers (`ClientboundMerchantOffersPacket`) - [ ] `0x34` Merchant Offers (`ClientboundMerchantOffersPacket`)
- [x] `0x35` Update Entity Position (`ClientboundUpdateEntityPositionPacket`) - [x] `0x35` Update Entity Position (`ClientboundUpdateEntityPositionPacket`)
- [x] `0x36` Update Entity Position and Rotation (`ClientboundUpdateEntityPositionAndRotationPacket`) - [x] `0x36` Update Entity Position and Rotation (`ClientboundUpdateEntityPositionAndRotationPacket`)
@@ -197,7 +197,7 @@ A lightweight minecraft client-side protocol library and related library, includ
- [x] `0x43` Player Enter Combat (`ClientboundPlayerEnterCombatPacket`) - [x] `0x43` Player Enter Combat (`ClientboundPlayerEnterCombatPacket`)
- [x] `0x44` Player Combat Death (`ClientboundPlayerCombatDeathPacket`) - [x] `0x44` Player Combat Death (`ClientboundPlayerCombatDeathPacket`)
- [x] `0x45` Player Info Remove (`ClientboundPlayerInfoRemovePacket`) - [x] `0x45` Player Info Remove (`ClientboundPlayerInfoRemovePacket`)
- [ ] `0x46` Player Info Update (`ClientboundPlayerInfoUpdatePacket`) - [x] `0x46` Player Info Update (`ClientboundPlayerInfoUpdatePacket`)
- [x] `0x47` Player Look At (`ClientboundPlayerLookAtPacket`) - [x] `0x47` Player Look At (`ClientboundPlayerLookAtPacket`)
- [x] `0x48` Synchronize Player Position (`ClientboundSynchronizePlayerPositionPacket`) - [x] `0x48` Synchronize Player Position (`ClientboundSynchronizePlayerPositionPacket`)
- [x] `0x49` Player Rotation (`ClientboundPlayerRotationPacket`) - [x] `0x49` Player Rotation (`ClientboundPlayerRotationPacket`)
@@ -265,7 +265,7 @@ A lightweight minecraft client-side protocol library and related library, includ
- [x] `0x87` Projectile Power (`ClientboundProjectilePowerPacket`) - [x] `0x87` Projectile Power (`ClientboundProjectilePowerPacket`)
- [x] `0x88` Custom Report Details (`ClientboundCustomReportDetailsPacket`) - [x] `0x88` Custom Report Details (`ClientboundCustomReportDetailsPacket`)
- [x] `0x89` Server Links (`ClientboundServerLinksPacket`) - [x] `0x89` Server Links (`ClientboundServerLinksPacket`)
- [ ] `0x8A` Waypoint (`ClientboundWaypointPacket`) - [x] `0x8A` Waypoint (`ClientboundWaypointPacket`)
- [x] `0x8B` Clear Dialog (`ClientboundClearDialogPacket`) - [x] `0x8B` Clear Dialog (`ClientboundClearDialogPacket`)
- [x] `0x8C` Show Dialog (`ClientboundShowDialogPacket`) - [x] `0x8C` Show Dialog (`ClientboundShowDialogPacket`)
@@ -0,0 +1,89 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/7
*/
package cn.rtast.libmc.protocol.packet.play.clientbound
import cn.rtast.libmc.packet.MinecraftPacket
import cn.rtast.libmc.packet.PacketCodec
import cn.rtast.libmc.primitives.*
import cn.rtast.libmc.protocol.protocol.game.chat.readTextComponent
import cn.rtast.libmc.protocol.protocol.game.player.action.PlayerInfoUpdateEntry
import cn.rtast.libmc.protocol.protocol.game.player.action.PlayerUpdateInfoAction
import cn.rtast.libmc.protocol.protocol.game.player.action.SinglePlayerAction
import cn.rtast.libmc.protocol.protocol.game.session.GameProfile
import cn.rtast.libmc.stream.BytesBuffer
public data class ClientboundPlayerInfoUpdatePacket(
val actions: Set<PlayerUpdateInfoAction>,
val entries: List<PlayerInfoUpdateEntry>,
) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundPlayerInfoUpdatePacket> {
override suspend fun encode(buffer: BytesBuffer, value: ClientboundPlayerInfoUpdatePacket) {}
override suspend fun decode(buffer: BytesBuffer): ClientboundPlayerInfoUpdatePacket {
val actionsMask = buffer.readUByte().toInt()
val actionsSet = PlayerUpdateInfoAction.parseActions(actionsMask)
val playerCount = buffer.readVarInt()
val entries = ArrayList<PlayerInfoUpdateEntry>(playerCount)
repeat(playerCount) {
val playerUuid = buffer.readUuid()
val playerActions = ArrayList<SinglePlayerAction>(actionsSet.size)
for (action in PlayerUpdateInfoAction.entries) {
if (action !in actionsSet) continue
val parsedAction = when (action) {
PlayerUpdateInfoAction.ADD_PLAYER -> {
val name = buffer.readMcString()
val properties = buffer.readPrefixed {
GameProfile.Property.decode(buffer)
}
SinglePlayerAction.AddPlayer(name, properties)
}
PlayerUpdateInfoAction.INITIALIZE_CHAT -> {
buffer.readOptional {
SinglePlayerAction.InitializeChat(
readUuid(), readLong(),
readBytes(512), readBytes(4096)
)
} ?: SinglePlayerAction.InitializeChat(null, null, null, null)
}
PlayerUpdateInfoAction.UPDATE_GAME_MODE -> {
SinglePlayerAction.UpdateGameMode(buffer.readVarInt())
}
PlayerUpdateInfoAction.UPDATE_LISTED -> {
SinglePlayerAction.UpdateListed(buffer.readBoolean())
}
PlayerUpdateInfoAction.UPDATE_LATENCY -> {
SinglePlayerAction.UpdateLatency(buffer.readVarInt())
}
PlayerUpdateInfoAction.UPDATE_DISPLAY_NAME -> {
val hasDisplayName = buffer.readBoolean()
val displayName = if (hasDisplayName) buffer.readTextComponent() else null
SinglePlayerAction.UpdateDisplayName(displayName)
}
PlayerUpdateInfoAction.UPDATE_LIST_PRIORITY -> {
SinglePlayerAction.UpdateListPriority(buffer.readVarInt())
}
PlayerUpdateInfoAction.UPDATE_HAT -> {
SinglePlayerAction.UpdateHat(buffer.readBoolean())
}
}
playerActions.add(parsedAction)
}
entries.add(PlayerInfoUpdateEntry(playerUuid, playerActions))
}
return ClientboundPlayerInfoUpdatePacket(actionsSet, entries)
}
}
}
@@ -11,7 +11,7 @@ import cn.rtast.libmc.stream.BytesBuffer
import cn.rtast.libmc.packet.PacketCodec import cn.rtast.libmc.packet.PacketCodec
import cn.rtast.libmc.packet.MinecraftPacket import cn.rtast.libmc.packet.MinecraftPacket
import cn.rtast.libmc.primitives.writeVarInt import cn.rtast.libmc.primitives.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.player.PlayerActionStatus import cn.rtast.libmc.protocol.protocol.game.player.action.PlayerActionStatus
public data class ServerboundClientCommandPacket(val action: PlayerActionStatus) : MinecraftPacket { public data class ServerboundClientCommandPacket(val action: PlayerActionStatus) : MinecraftPacket {
internal companion object Codec : PacketCodec<ServerboundClientCommandPacket> { internal companion object Codec : PacketCodec<ServerboundClientCommandPacket> {
@@ -14,7 +14,7 @@ import cn.rtast.libmc.primitives.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.block.BlockFace 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.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos
import cn.rtast.libmc.protocol.protocol.game.player.PlayerActionStatus import cn.rtast.libmc.protocol.protocol.game.player.action.PlayerActionStatus
/** /**
* ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Player_Action * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Player_Action
@@ -11,7 +11,7 @@ import cn.rtast.libmc.stream.BytesBuffer
import cn.rtast.libmc.packet.PacketCodec import cn.rtast.libmc.packet.PacketCodec
import cn.rtast.libmc.packet.MinecraftPacket import cn.rtast.libmc.packet.MinecraftPacket
import cn.rtast.libmc.primitives.writeVarInt import cn.rtast.libmc.primitives.writeVarInt
import cn.rtast.libmc.protocol.protocol.game.player.PlayerCommandAction import cn.rtast.libmc.protocol.protocol.game.player.action.PlayerCommandAction
public data class ServerboundPlayerCommandPacket( public data class ServerboundPlayerCommandPacket(
val entityId: Int, val entityId: Int,
@@ -48,12 +48,12 @@ internal object GamePacketsProtocolCodec {
register(0x07, ClientboundRegistryDataPacket) register(0x07, ClientboundRegistryDataPacket)
register(0x08, ClientboundRemoveResourcePackPacket) register(0x08, ClientboundRemoveResourcePackPacket)
register(0x09, ClientboundAddResourcePackPacket) register(0x09, ClientboundAddResourcePackPacket)
register(0x0a, ClientboundStoreCookiePacket) register(0x0A, ClientboundStoreCookiePacket)
register(0x0b, ClientboundTransferPacket) register(0x0B, ClientboundTransferPacket)
register(0x0c, ClientboundUpdateEnabledFeaturesPacket) register(0x0C, ClientboundUpdateEnabledFeaturesPacket)
register(0x0d, ClientboundUpdateTagsPacket) register(0x0D, ClientboundUpdateTagsPacket)
register(0x0e, ClientboundSelectKnownPacksPacket) register(0x0E, ClientboundSelectKnownPacksPacket)
register(0x0f, ClientboundCustomReportDetailsPacket) register(0x0F, ClientboundCustomReportDetailsPacket)
register(0x10, ClientboundServerLinksPacket) register(0x10, ClientboundServerLinksPacket)
register(0x11, ClientboundClearDialogPacket) register(0x11, ClientboundClearDialogPacket)
register(0x12, ClientboundConfigurationShowDialogPacket) register(0x12, ClientboundConfigurationShowDialogPacket)
@@ -70,12 +70,12 @@ internal object GamePacketsProtocolCodec {
register(0x07, ClientboundBlockEventPacket) register(0x07, ClientboundBlockEventPacket)
register(0x08, ClientboundBlockUpdatePacket) register(0x08, ClientboundBlockUpdatePacket)
register(0x09, ClientboundBossEventPacket) register(0x09, ClientboundBossEventPacket)
register(0x0a, ClientboundChangeDifficultyPacket) register(0x0A, ClientboundChangeDifficultyPacket)
register(0x0b, ClientboundChunkBatchFinishedPacket) register(0x0B, ClientboundChunkBatchFinishedPacket)
register(0x0c, ClientboundChunkBatchStartPacket) register(0x0C, ClientboundChunkBatchStartPacket)
register(0x0d, ClientboundChunksBiomesPacket) register(0x0D, ClientboundChunksBiomesPacket)
register(0x0e, ClientboundClearTitlesPacket) register(0x0E, ClientboundClearTitlesPacket)
register(0x0f, ClientboundCommandSuggestionsPacket) register(0x0F, ClientboundCommandSuggestionsPacket)
register(0x10, ClientboundCommandsPacket) register(0x10, ClientboundCommandsPacket)
register(0x11, ClientboundContainerClosePacket) register(0x11, ClientboundContainerClosePacket)
// register(0x12, ClientboundContainerSetContentPacket) // register(0x12, ClientboundContainerSetContentPacket)
@@ -86,12 +86,12 @@ internal object GamePacketsProtocolCodec {
register(0x17, ClientboundCustomChatCompletionsPacket) register(0x17, ClientboundCustomChatCompletionsPacket)
register(0x18, ClientboundCustomPayloadPacket) register(0x18, ClientboundCustomPayloadPacket)
register(0x19, ClientboundDamageEventPacket) register(0x19, ClientboundDamageEventPacket)
// register(0x1a, ClientboundDebugBlockValuePacket) // register(0x1A, ClientboundDebugBlockValuePacket)
// register(0x1b, ClientboundDebugChunkValuePacket) // register(0x1B, ClientboundDebugChunkValuePacket)
// register(0x1c, ClientboundDebugEntityValuePacket) // register(0x1C, ClientboundDebugEntityValuePacket)
// register(0x1d, ClientboundDebugEventPacket) // register(0x1D, ClientboundDebugEventPacket)
// register(0x1e, ClientboundDebugSamplePacket) // register(0x1E, ClientboundDebugSamplePacket)
register(0x1f, ClientboundDeleteChatPacket) register(0x1F, ClientboundDeleteChatPacket)
register(0x20, ClientboundDisconnectPlayPacket) register(0x20, ClientboundDisconnectPlayPacket)
register(0x21, ClientboundDisguisedChatMessagePacket) register(0x21, ClientboundDisguisedChatMessagePacket)
register(0x22, ClientboundEntityEventPacket) register(0x22, ClientboundEntityEventPacket)
@@ -102,12 +102,12 @@ internal object GamePacketsProtocolCodec {
register(0x27, ClientboundGameRuleValuesPacket) register(0x27, ClientboundGameRuleValuesPacket)
register(0x28, ClientboundTestHighlightPositionPacket) register(0x28, ClientboundTestHighlightPositionPacket)
register(0x29, ClientboundOpenHorseScreenPacket) register(0x29, ClientboundOpenHorseScreenPacket)
register(0x2a, ClientboundHurtAnimationPacket) register(0x2A, ClientboundHurtAnimationPacket)
register(0x2b, ClientboundInitializeWorldBorderPacket) register(0x2B, ClientboundInitializeWorldBorderPacket)
register(0x2c, ClientboundKeepAlivePlayPacket) register(0x2C, ClientboundKeepAlivePlayPacket)
// register(0x2d, ClientboundLevelChunkUpdateWithLightPacket) // register(0x2D, ClientboundLevelChunkUpdateWithLightPacket)
register(0x2e, ClientboundLevelEventPacket) register(0x2E, ClientboundLevelEventPacket)
// register(0x2f, ClientboundParticlePacket) // register(0x2F, ClientboundParticlePacket)
// register(0x30, ClientboundLightUpdatePacket) // register(0x30, ClientboundLightUpdatePacket)
register(0x31, ClientboundLoginPlayPacket) register(0x31, ClientboundLoginPlayPacket)
register(0x32, ClientboundLowDiskSpaceWarningPacket) register(0x32, ClientboundLowDiskSpaceWarningPacket)
@@ -118,28 +118,28 @@ internal object GamePacketsProtocolCodec {
register(0x37, ClientboundMoveMinecartAlongTrackPacket) register(0x37, ClientboundMoveMinecartAlongTrackPacket)
register(0x38, ClientboundUpdateEntityRotationPacket) register(0x38, ClientboundUpdateEntityRotationPacket)
register(0x39, ClientboundMoveVehiclePacket) register(0x39, ClientboundMoveVehiclePacket)
register(0x3a, ClientboundOpenBookPacket) register(0x3A, ClientboundOpenBookPacket)
register(0x3b, ClientboundOpenScreenPacket) register(0x3B, ClientboundOpenScreenPacket)
register(0x3c, ClientboundOpenSignEditorPacket) register(0x3C, ClientboundOpenSignEditorPacket)
register(0x3d, ClientboundPingPacket) register(0x3D, ClientboundPingPacket)
register(0x3e, ClientboundPongResponsePacket) register(0x3E, ClientboundPongResponsePacket)
// register(0x3f, ClientboundPlaceGhostRecipePacket) // register(0x3F, ClientboundPlaceGhostRecipePacket)
register(0x40, ClientboundPlayerAbilitiesPacket) register(0x40, ClientboundPlayerAbilitiesPacket)
register(0x41, ClientboundPlayerChatMessagePacket) register(0x41, ClientboundPlayerChatMessagePacket)
register(0x42, ClientboundPlayerEndCombatPacket) register(0x42, ClientboundPlayerEndCombatPacket)
register(0x43, ClientboundPlayerEnterCombatPacket) register(0x43, ClientboundPlayerEnterCombatPacket)
register(0x44, ClientboundPlayerCombatDeathPacket) register(0x44, ClientboundPlayerCombatDeathPacket)
register(0x45, ClientboundPlayerInfoRemovePacket) register(0x45, ClientboundPlayerInfoRemovePacket)
// register(0x46, ClientboundPlayerInfoUpdatePacket) register(0x46, ClientboundPlayerInfoUpdatePacket)
register(0x47, ClientboundPlayerLookAtPacket) register(0x47, ClientboundPlayerLookAtPacket)
register(0x48, ClientboundSynchronizePlayerPositionPacket) register(0x48, ClientboundSynchronizePlayerPositionPacket)
register(0x49, ClientboundPlayerRotationPacket) register(0x49, ClientboundPlayerRotationPacket)
// register(0x4a, ClientboundRecipeBookAddPacket) // register(0x4A, ClientboundRecipeBookAddPacket)
// register(0x4b, ClientboundRecipeBookRemovePacket) // register(0x4B, ClientboundRecipeBookRemovePacket)
// register(0x4c, ClientboundRecipeBookSettingsPacket) // register(0x4C, ClientboundRecipeBookSettingsPacket)
register(0x4d, ClientboundRemoveEntitiesPacket) register(0x4D, ClientboundRemoveEntitiesPacket)
register(0x4e, ClientboundRemoveEntityEffectPacket) register(0x4E, ClientboundRemoveEntityEffectPacket)
register(0x4f, ClientboundResetScorePacket) register(0x4F, ClientboundResetScorePacket)
register(0x50, ClientboundRemoveResourcePackPacket) register(0x50, ClientboundRemoveResourcePackPacket)
register(0x51, ClientboundAddResourcePackPacket) register(0x51, ClientboundAddResourcePackPacket)
register(0x52, ClientboundRespawnPacket) register(0x52, ClientboundRespawnPacket)
@@ -150,12 +150,12 @@ internal object GamePacketsProtocolCodec {
register(0x57, ClientboundSetActionBarTextPacket) register(0x57, ClientboundSetActionBarTextPacket)
register(0x58, ClientboundSetBorderCenterPacket) register(0x58, ClientboundSetBorderCenterPacket)
register(0x59, ClientboundSetBorderLeapSizePacket) register(0x59, ClientboundSetBorderLeapSizePacket)
register(0x5a, ClientboundSetBorderSizePacket) register(0x5A, ClientboundSetBorderSizePacket)
register(0x5b, ClientboundSetBorderWarningDelayPacket) register(0x5B, ClientboundSetBorderWarningDelayPacket)
register(0x5c, ClientboundSetBorderWarningDistancePacket) register(0x5C, ClientboundSetBorderWarningDistancePacket)
register(0x5d, ClientboundSetCameraPacket) register(0x5D, ClientboundSetCameraPacket)
register(0x5e, ClientboundSetCenterChunkPacket) register(0x5E, ClientboundSetCenterChunkPacket)
register(0x5f, ClientboundSetRenderDistancePacket) register(0x5F, ClientboundSetRenderDistancePacket)
// register(0x60, ClientboundSetCursorItemPacket) // register(0x60, ClientboundSetCursorItemPacket)
register(0x61, ClientboundSetDefaultSpawnPositionPacket) register(0x61, ClientboundSetDefaultSpawnPositionPacket)
register(0x62, ClientboundSetDisplayObjectivePacket) register(0x62, ClientboundSetDisplayObjectivePacket)
@@ -166,12 +166,12 @@ internal object GamePacketsProtocolCodec {
register(0x67, ClientboundSetExperiencePacket) register(0x67, ClientboundSetExperiencePacket)
register(0x68, ClientboundSetHealthPacket) register(0x68, ClientboundSetHealthPacket)
register(0x69, ClientboundSetCarriedItemPacket) register(0x69, ClientboundSetCarriedItemPacket)
register(0x6a, ClientboundUpdateObjectivePacket) register(0x6A, ClientboundUpdateObjectivePacket)
register(0x6b, ClientboundSetPassengersPacket) register(0x6B, ClientboundSetPassengersPacket)
// register(0x6c, ClientboundSetPlayerInventorySlotPacket) // register(0x6C, ClientboundSetPlayerInventorySlotPacket)
// register(0x6d, ClientboundSetPlayerTeamPacket) // register(0x6D, ClientboundSetPlayerTeamPacket)
register(0x6e, ClientboundUpdateScorePacket) register(0x6E, ClientboundUpdateScorePacket)
register(0x6f, ClientboundSetSimulationDistancePacket) register(0x6F, ClientboundSetSimulationDistancePacket)
register(0x70, ClientboundSetSubtitleTextPacket) register(0x70, ClientboundSetSubtitleTextPacket)
register(0x71, ClientboundSetTimePacket) register(0x71, ClientboundSetTimePacket)
register(0x72, ClientboundSetTitleTextPacket) register(0x72, ClientboundSetTitleTextPacket)
@@ -182,12 +182,12 @@ internal object GamePacketsProtocolCodec {
register(0x77, ClientboundStopSoundPacket) register(0x77, ClientboundStopSoundPacket)
register(0x78, ClientboundStoreCookiePacket) register(0x78, ClientboundStoreCookiePacket)
register(0x79, ClientboundSystemChatMessagePacket) register(0x79, ClientboundSystemChatMessagePacket)
register(0x7a, ClientboundSetTabListHeaderAndFooterPacket) register(0x7A, ClientboundSetTabListHeaderAndFooterPacket)
register(0x7b, ClientboundTagQueryResponsePacket) register(0x7B, ClientboundTagQueryResponsePacket)
register(0x7c, ClientboundPickupItemPacket) register(0x7C, ClientboundPickupItemPacket)
register(0x7d, ClientboundSynchronizeVehiclePositionPacket) register(0x7D, ClientboundSynchronizeVehiclePositionPacket)
register(0x7e, ClientboundTestInstanceBlockStatusPacket) register(0x7E, ClientboundTestInstanceBlockStatusPacket)
register(0x7f, ClientboundSetTickingStatePacket) register(0x7F, ClientboundSetTickingStatePacket)
register(0x80, ClientboundStepTickPacket) register(0x80, ClientboundStepTickPacket)
register(0x81, ClientboundTransferPacket) register(0x81, ClientboundTransferPacket)
// register(0x82, ClientboundUpdateAdvancementsPacket) // register(0x82, ClientboundUpdateAdvancementsPacket)
@@ -198,9 +198,9 @@ internal object GamePacketsProtocolCodec {
register(0x87, ClientboundProjectilePowerPacket) register(0x87, ClientboundProjectilePowerPacket)
register(0x88, ClientboundCustomReportDetailsPacket) register(0x88, ClientboundCustomReportDetailsPacket)
register(0x89, ClientboundServerLinksPacket) register(0x89, ClientboundServerLinksPacket)
register(0x8a, ClientboundWaypointPacket) register(0x8A, ClientboundWaypointPacket)
register(0x8b, ClientboundClearDialogPacket) register(0x8B, ClientboundClearDialogPacket)
register(0x8c, ClientboundShowDialogPacket) register(0x8C, ClientboundShowDialogPacket)
} }
} }
@@ -241,12 +241,12 @@ internal object GamePacketsProtocolCodec {
register(0x07, ServerboundChatCommandPacket) register(0x07, ServerboundChatCommandPacket)
register(0x08, ServerboundSignedChatCommandPacket) register(0x08, ServerboundSignedChatCommandPacket)
register(0x09, ServerboundChatMessagePacket) register(0x09, ServerboundChatMessagePacket)
register(0x0a, ServerboundUpdateChatSessionPacket) register(0x0A, ServerboundUpdateChatSessionPacket)
register(0x0b, ServerboundChunkBatchReceivedPacket) register(0x0B, ServerboundChunkBatchReceivedPacket)
register(0x0c, ServerboundClientCommandPacket) register(0x0C, ServerboundClientCommandPacket)
register(0x0d, ServerboundClientTickEndPacket) register(0x0D, ServerboundClientTickEndPacket)
register(0x0e, ServerboundClientInformationPacket) register(0x0E, ServerboundClientInformationPacket)
register(0x0f, ServerboundCommandSuggestionRequestPacket) register(0x0F, ServerboundCommandSuggestionRequestPacket)
register(0x10, ServerboundConfigurationAcknowledgedPacket) register(0x10, ServerboundConfigurationAcknowledgedPacket)
register(0x11, ServerboundContainerClickButtonPacket) register(0x11, ServerboundContainerClickButtonPacket)
// register(0x12, ServerboundContainerClickPacket) // register(0x12, ServerboundContainerClickPacket)
@@ -257,12 +257,12 @@ internal object GamePacketsProtocolCodec {
// register(0x17, ServerboundDebugSubscriptionRequestPacket) // register(0x17, ServerboundDebugSubscriptionRequestPacket)
register(0x18, ServerboundEditBookPacket) register(0x18, ServerboundEditBookPacket)
register(0x19, ServerboundQueryEntityTagPacket) register(0x19, ServerboundQueryEntityTagPacket)
register(0x1a, ServerboundInteractPacket) register(0x1A, ServerboundInteractPacket)
register(0x1b, ServerboundJigsawGeneratePacket) register(0x1B, ServerboundJigsawGeneratePacket)
register(0x1c, ServerboundKeepAlivePlayPacket) register(0x1C, ServerboundKeepAlivePlayPacket)
register(0x1d, ServerboundLockDifficultyPacket) register(0x1D, ServerboundLockDifficultyPacket)
register(0x1e, ServerboundSetPlayerPositionPacket) register(0x1E, ServerboundSetPlayerPositionPacket)
register(0x1f, ServerboundSetPlayerPositionAndRotationPacket) register(0x1F, ServerboundSetPlayerPositionAndRotationPacket)
register(0x20, ServerboundSetPlayerRotationPacket) register(0x20, ServerboundSetPlayerRotationPacket)
register(0x21, ServerboundSetPlayerMovementFlagPacket) register(0x21, ServerboundSetPlayerMovementFlagPacket)
register(0x22, ServerboundMoveVehiclePacket) register(0x22, ServerboundMoveVehiclePacket)
@@ -273,12 +273,12 @@ internal object GamePacketsProtocolCodec {
register(0x27, ServerboundPlaceRecipePacket) register(0x27, ServerboundPlaceRecipePacket)
register(0x28, ServerboundPlayerAbilitiesPacket) register(0x28, ServerboundPlayerAbilitiesPacket)
register(0x29, ServerboundPlayerActionPacket) register(0x29, ServerboundPlayerActionPacket)
register(0x2a, ServerboundPlayerCommandPacket) register(0x2A, ServerboundPlayerCommandPacket)
register(0x2b, ServerboundPlayerInputPacket) register(0x2B, ServerboundPlayerInputPacket)
register(0x2c, ServerboundPlayerLoadedPacket) register(0x2C, ServerboundPlayerLoadedPacket)
register(0x2d, ServerboundPongPlayPacket) register(0x2D, ServerboundPongPlayPacket)
register(0x2e, ServerboundRecipeBookChangeSettingsPacket) register(0x2E, ServerboundRecipeBookChangeSettingsPacket)
register(0x2f, ServerboundRecipeBookSeenRecipePacket) register(0x2F, ServerboundRecipeBookSeenRecipePacket)
register(0x30, ServerboundRenameItemPacket) register(0x30, ServerboundRenameItemPacket)
register(0x31, ServerboundResourcePackResponsePacket) register(0x31, ServerboundResourcePackResponsePacket)
register(0x32, ServerboundSeenAdvancementsPacket) register(0x32, ServerboundSeenAdvancementsPacket)
@@ -289,12 +289,12 @@ internal object GamePacketsProtocolCodec {
register(0x37, ServerboundSetCommandMinecartPacket) register(0x37, ServerboundSetCommandMinecartPacket)
// register(0x38, ServerboundSetCreativeModeSlotPacket) // register(0x38, ServerboundSetCreativeModeSlotPacket)
register(0x39, ServerboundSetGameRulePacket) register(0x39, ServerboundSetGameRulePacket)
register(0x3a, ServerboundSetJigsawBlockPacket) register(0x3A, ServerboundSetJigsawBlockPacket)
register(0x3b, ServerboundSetStructureBlockPacket) register(0x3B, ServerboundSetStructureBlockPacket)
register(0x3c, ServerboundSetTestBlockPacket) register(0x3C, ServerboundSetTestBlockPacket)
register(0x3d, ServerboundSignUpdatePacket) register(0x3D, ServerboundSignUpdatePacket)
register(0x3e, ServerboundSpectatorActionPacket) register(0x3E, ServerboundSpectatorActionPacket)
register(0x3f, ServerboundSwingPacket) register(0x3F, ServerboundSwingPacket)
register(0x40, ServerboundTeleportToEntityPacket) register(0x40, ServerboundTeleportToEntityPacket)
register(0x41, ServerboundTestInstanceBlockActionPacket) register(0x41, ServerboundTestInstanceBlockActionPacket)
register(0x42, ServerboundUseItemOnPacket) register(0x42, ServerboundUseItemOnPacket)
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.protocol.game.player package cn.rtast.libmc.protocol.protocol.game.player.action
public enum class PlayerActionStatus(public val id: Int) { public enum class PlayerActionStatus(public val id: Int) {
STARTED_DIGGING(0), STARTED_DIGGING(0),
@@ -5,7 +5,7 @@
*/ */
package cn.rtast.libmc.protocol.protocol.game.player package cn.rtast.libmc.protocol.protocol.game.player.action
public enum class PlayerCommandAction(public val id: Int) { public enum class PlayerCommandAction(public val id: Int) {
LEAVE_BED(0), LEAVE_BED(0),
@@ -0,0 +1,79 @@
/*
* Copyright © 2026 RTAkland
* Author: RTAkland
* Date: 2026/9/7
*/
package cn.rtast.libmc.protocol.protocol.game.player.action
import cn.rtast.libmc.protocol.protocol.game.chat.TextComponent
import cn.rtast.libmc.protocol.protocol.game.session.GameProfile
import kotlin.uuid.Uuid
public enum class PlayerUpdateInfoAction(public val mask: Int) {
ADD_PLAYER(0x01),
INITIALIZE_CHAT(0x02),
UPDATE_GAME_MODE(0x04),
UPDATE_LISTED(0x08),
UPDATE_LATENCY(0x10),
UPDATE_DISPLAY_NAME(0x20),
UPDATE_LIST_PRIORITY(0x40),
UPDATE_HAT(0x80);
public companion object {
public fun parseActions(mask: Int): Set<PlayerUpdateInfoAction> {
val set = HashSet<PlayerUpdateInfoAction>()
for (action in entries) if ((mask and action.mask) != 0) set.add(action)
return set
}
public fun toMask(actions: Set<PlayerUpdateInfoAction>): Int {
var mask = 0
for (action in actions) mask = mask or action.mask
return mask
}
}
}
public sealed class SinglePlayerAction {
public data class AddPlayer(val name: String, val properties: List<GameProfile.Property>) : SinglePlayerAction()
public data class InitializeChat(
val sessionId: Uuid?,
val keyExpiryTime: Long?,
val encodedPublicKey: ByteArray?,
val publicKeySignature: ByteArray?,
) : SinglePlayerAction() {
val hasSignatureData: Boolean get() = sessionId != null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as InitializeChat
if (keyExpiryTime != other.keyExpiryTime) return false
if (sessionId != other.sessionId) return false
if (!encodedPublicKey.contentEquals(other.encodedPublicKey)) return false
if (!publicKeySignature.contentEquals(other.publicKeySignature)) return false
if (hasSignatureData != other.hasSignatureData) return false
return true
}
override fun hashCode(): Int {
var result = keyExpiryTime.hashCode()
result = 31 * result + sessionId.hashCode()
result = 31 * result + (encodedPublicKey?.contentHashCode() ?: 0)
result = 31 * result + (publicKeySignature?.contentHashCode() ?: 0)
result = 31 * result + hasSignatureData.hashCode()
return result
}
}
public data class UpdateGameMode(val gameMode: Int) : SinglePlayerAction()
public data class UpdateListed(val listed: Boolean) : SinglePlayerAction()
public data class UpdateLatency(val ping: Int) : SinglePlayerAction()
public data class UpdateDisplayName(val displayName: TextComponent?) : SinglePlayerAction()
public data class UpdateListPriority(val priority: Int) : SinglePlayerAction()
public data class UpdateHat(val visible: Boolean) : SinglePlayerAction()
}
public data class PlayerInfoUpdateEntry(val uuid: Uuid, val actions: List<SinglePlayerAction>)
@@ -7,12 +7,11 @@
package test package test
import cn.rtast.libmc.packet.ClientboundUnknownPacket
import cn.rtast.libmc.protocol.client.createMinecraftClient import cn.rtast.libmc.protocol.client.createMinecraftClient
import cn.rtast.libmc.protocol.crypto.DefaultProtocolContext import cn.rtast.libmc.protocol.crypto.DefaultProtocolContext
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundCommandsPacket import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayerInfoUpdatePacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundDisconnectPlayPacket import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundWaypointPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundDisguisedChatMessagePacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundSystemChatMessagePacket
import cn.rtast.libmc.protocol.util.generateOfflineUuid import cn.rtast.libmc.protocol.util.generateOfflineUuid
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.junit.Test import org.junit.Test
@@ -81,8 +80,12 @@ class TestClientTestInJvm {
null, null,
crypto = DefaultProtocolContext crypto = DefaultProtocolContext
) )
cli.on { packet, direction -> println("$direction -> $packet") } // cli.on { packet, direction ->
// cli.onPacket<ClientboundSystemChatMessagePacket> { println(it.content.content) } // if (packet !is ClientboundWaypointPacket)
// println("$direction -> $packet")
// }
// cli.onPacket<ClientboundUnknownPacket> { println(it) }
cli.onPacket<ClientboundPlayerInfoUpdatePacket> { println(it) }
cli.launch { cli.connect() } cli.launch { cli.connect() }
while (true) { while (true) {
} }