From 52917e9425fd3bcc58dc0898c312c31d6b73ae4d Mon Sep 17 00:00:00 2001 From: RTAkland Date: Sun, 6 Sep 2026 01:18:32 +0800 Subject: [PATCH] Complete all serverbound packets at PLAY state --- build.gradle.kts | 10 +- gradle.properties | 3 +- .../kotlin/cn/rtast/libmc/common/buffer.kt | 43 +++++++++ .../cn/rtast/libmc/common/mc_primitives.kt | 28 ++++++ .../kotlin/cn/rtast/libmc/nbt/NBTReader.kt | 5 +- .../kotlin/cn/rtast/libmc/nbt/NBTWriter.kt | 7 ++ .../libmc/protocol/block/EnchantmentButton.kt | 19 ++++ .../libmc/protocol/block/LecternButton.kt | 21 ++++ .../client/InternalPacketDispatcher.kt | 45 ++++++++- .../libmc/protocol/client/MinecraftClient.kt | 5 +- .../ClientboundConfigurationPacket.kt | 2 +- .../ClientboundCookieRequestPacket.kt | 2 +- .../ClientboundCustomPayloadPacket.kt | 2 +- ...lientboundDisconnectConfigurationPacket.kt | 2 +- .../ClientboundFinishConfigurationPacket.kt | 2 +- ...ClientboundKeepAliveConfigurationPacket.kt | 2 +- .../ClientboundPingConfigurationPacket.kt | 2 +- .../ClientboundSelectKnownPacksPacket.kt | 3 +- ...ServerboundAckFinishConfigurationPacket.kt | 2 +- .../ServerboundCookieResponsePacket.kt | 19 +--- ...ServerboundKeepAliveConfigurationPacket.kt | 2 +- .../ServerboundPongConfigurationPacket.kt | 2 +- .../ServerboundSelectKnownPacksPacket.kt | 3 +- .../ClientboundDisconnectLoginPacket.kt | 2 +- .../ClientboundLoginPacket.kt | 2 +- .../ClientboundLoginSuccessPacket.kt | 4 +- .../ClientboundSetCompressionPacket.kt | 2 +- .../ServerboundLoginAcknowledgedPacket.kt | 2 +- .../ServerboundLoginStartPacket.kt | 2 +- .../play/ServerboundChatMessagePacket.kt | 34 ------- ...ClientboundAcknowledgeBlockChangePacket.kt | 24 +++++ .../ClientboundAwardStatisticsPacket.kt | 27 ++++++ .../ClientboundBlockDestructionPacket.kt | 34 +++++++ .../ClientboundBlockEntityDataPacket.kt | 29 ++++++ .../ClientboundDelimiterPacket.kt | 2 +- .../ClientboundDisconnectPlayPacket.kt | 2 +- .../ClientboundEntityAnimationPacket.kt | 4 +- .../ClientboundKeepAlivePlayPacket.kt | 2 +- .../ClientboundLoginPlayPacket.kt | 4 +- .../ClientboundPingPlayPacket.kt | 2 +- .../ClientboundPlayPacket.kt | 2 +- .../ClientboundPlayerChatMessagePacket.kt | 2 +- .../ClientboundSpawnEntityPacket.kt | 10 +- .../ClientboundStartConfigurationPacket.kt | 2 +- .../ClientboundSystemChatMessagePacket.kt | 2 +- .../ServerboundAcceptTeleportationPacket.kt | 24 +++++ ...ServerboundAcknowledgeChatMessagePacket.kt | 24 +++++ .../ServerboundAttackActionPacket.kt | 24 +++++ .../ServerboundBundleItemSelectedPacket.kt | 25 +++++ ...rverboundChangeContainerSlotStatePacket.kt | 27 ++++++ .../ServerboundChangeDifficultyPacket.kt | 24 +++++ .../ServerboundChangeGameModePacket.kt | 26 +++++ .../ServerboundChatCommandPacket.kt | 24 +++++ .../ServerboundChatMessagePacket.kt | 69 +++++++++++++ .../ServerboundChunkBatchReceivedPacket.kt | 23 +++++ .../ServerboundClientActionPacket.kt | 25 +++++ .../ServerboundClientCommandPacket.kt | 25 +++++ .../ServerboundClientInformationPacket.kt | 67 +++++++++++++ .../ServerboundClientTickEndPacket.kt | 17 ++++ ...rverboundCommandSuggestionRequestPacket.kt | 35 +++++++ ...verboundConfigurationAcknowledgedPacket.kt | 2 +- .../ServerboundContainerClickButtonPacket.kt | 30 ++++++ .../ServerboundContainerClickPacket.kt | 73 ++++++++++++++ .../ServerboundContainerClosePacket.kt | 24 +++++ .../ServerboundCustomClickActionPacket.kt | 37 +++++++ .../ServerboundCustomPayloadPacket.kt | 44 +++++++++ ...rverboundDebugSubscriptionRequestPacket.kt | 26 +++++ .../serverbound/ServerboundEditBookPacket.kt | 27 ++++++ .../serverbound/ServerboundInteractPacket.kt | 35 +++++++ .../ServerboundJigsawGeneratePacket.kt | 35 +++++++ .../ServerboundKeepAlivePlayPacket.kt | 2 +- .../ServerboundLockDifficultyPacket.kt | 28 ++++++ .../ServerboundMoveVehiclePacket.kt | 37 +++++++ .../ServerboundPaddleBoatPacket.kt | 36 +++++++ .../ServerboundPickItemFromBlockPacket.kt | 33 +++++++ .../ServerboundPickItemFromEntityPacket.kt | 31 ++++++ .../ServerboundPlaceRecipePacket.kt | 30 ++++++ .../ServerboundPlayerAbilitiesPacket.kt | 24 +++++ .../ServerboundPlayerActionPacket.kt | 43 +++++++++ .../ServerboundPlayerCommandPacket.kt | 35 +++++++ .../ServerboundPlayerInputPacket.kt | 47 +++++++++ .../ServerboundPlayerLoadedPacket.kt | 17 ++++ .../ServerboundPongPlayPacket.kt | 7 +- .../ServerboundQueryBlockEntityTagPacket.kt | 29 ++++++ .../ServerboundQueryEntityTagPacket.kt | 31 ++++++ ...rverboundRecipeBookChangeSettingsPacket.kt | 31 ++++++ .../ServerboundRecipeBookSeenRecipePacket.kt | 24 +++++ .../ServerboundRenameItemPacket.kt | 25 +++++ .../ServerboundResourcePackResponsePacket.kt | 31 ++++++ .../ServerboundSeenAdvancementsPacket.kt | 32 +++++++ .../ServerboundSelectTradePacket.kt | 24 +++++ .../serverbound/ServerboundSetBeaconPacket.kt | 30 ++++++ .../ServerboundSetCarriedItemPacket.kt | 26 +++++ .../ServerboundSetCommandBlockPacket.kt | 46 +++++++++ .../ServerboundSetCommandMinecartPacket.kt | 34 +++++++ .../ServerboundSetCreativeModeSlotPacket.kt | 26 +++++ .../ServerboundSetGameRulePacket.kt | 29 ++++++ .../ServerboundSetJigsawBlockPacket.kt | 45 +++++++++ .../ServerboundSetPlayerMovementFlagPacket.kt | 24 +++++ ...boundSetPlayerPositionAndRotationPacket.kt | 45 +++++++++ .../ServerboundSetPlayerPositionPacket.kt | 32 +++++++ .../ServerboundSetPlayerRotationPacket.kt | 30 ++++++ .../ServerboundSetStructureBlockPacket.kt | 94 ++++++++++++++++++ .../ServerboundSetTestBlockPacket.kt | 35 +++++++ .../ServerboundSignUpdatePacket.kt | 47 +++++++++ .../ServerboundSignedChatCommandPacket.kt | 69 +++++++++++++ .../ServerboundSpectatorActionPacket.kt | 30 ++++++ .../serverbound/ServerboundSwingPacket.kt | 25 +++++ .../ServerboundTeleportToEntityPacket.kt | 25 +++++ ...erverboundTestInstanceBlockActionPacket.kt | 51 ++++++++++ .../ServerboundUpdateChatSessionPacket.kt | 67 +++++++++++++ .../serverbound/ServerboundUseItemOnPacket.kt | 52 ++++++++++ .../serverbound/ServerboundUseItemPacket.kt | 36 +++++++ .../serverbound/ServerboundPingRequest.kt | 23 +++++ .../libmc/protocol/protocol/GameProtocols.kt | 93 ++++++++++++++++-- .../{types => protocol/game}/Animations.kt | 2 +- .../libmc/protocol/protocol/game/ChatMode.kt | 18 ++++ .../protocol/protocol/game/StatisticsEntry.kt | 35 +++++++ .../game/advancement/AdvancementAction.kt | 17 ++++ .../protocol/game/block/BlockDestroyStage.kt | 17 ++++ .../protocol/protocol/game/block/BlockFace.kt | 21 ++++ .../protocol/game/{ => block}/BlockPos.kt | 2 +- .../protocol/game/block/CommandBlockMode.kt | 18 ++++ .../protocol/game/block/StructureBlock.kt | 51 ++++++++++ .../protocol/protocol/game/block/TestBlock.kt | 54 +++++++++++ .../game/container/ContainerButton.kt | 47 +++++++++ .../game/debug/DebugSubscriptionType.kt | 26 +++++ .../protocol/game/gamerule/GameRuleEntry.kt | 13 +++ .../protocol/game/inventory/ChangedSlot.kt | 30 ++++++ .../protocol/game/inventory/HashedSlot.kt | 68 +++++++++++++ .../game/inventory/InventoryClickType.kt | 23 +++++ .../protocol/protocol/game/inventory/Slot.kt | 96 +++++++++++++++++++ .../protocol/game/item/RecipeBookType.kt | 19 ++++ .../{types => protocol/game/math}/Angle.kt | 2 +- .../{types => protocol/game/math}/LpVec3.kt | 2 +- .../protocol/protocol/game/player/Hand.kt | 17 ++++ .../protocol/game/player/InteractType.kt | 16 ++++ .../protocol/protocol/game/player/MainHand.kt | 17 ++++ .../protocol/game/player/PlayerAbilities.kt | 16 ++++ .../game/player/PlayerActionStatus.kt | 23 +++++ .../game/player/PlayerCommandAction.kt | 22 +++++ .../game/player/PlayerPositionFlag.kt | 17 ++++ .../game/player/skin/ParticleStatus.kt | 18 ++++ .../game/player/skin/SkinPartFlags.kt | 21 ++++ .../game/resources/ResourcePackResult.kt | 23 +++++ .../protocol/signature/ArgumentSignature.kt | 50 ++++++++++ .../protocol/signature/ChecksumCalculate.kt | 36 +++++++ .../rtast/libmc/protocol/protocol/util/nbt.kt | 10 +- .../libmc/protocol/registry/ClientAction.kt | 29 ++++++ .../libmc/protocol/registry/GameDifficulty.kt | 20 ++++ .../{profile => session}/GameProfile.kt | 2 +- .../protocol/session/TransactionIdManager.kt | 24 +++++ .../src/commonTest/kotlin/test/TestClient.kt | 15 +-- 153 files changed, 3636 insertions(+), 131 deletions(-) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/EnchantmentButton.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/LecternButton.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundConfigurationPacket.kt (75%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundCookieRequestPacket.kt (92%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundCustomPayloadPacket.kt (95%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundDisconnectConfigurationPacket.kt (92%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundFinishConfigurationPacket.kt (89%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundKeepAliveConfigurationPacket.kt (91%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundPingConfigurationPacket.kt (90%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => clientbound}/ClientboundSelectKnownPacksPacket.kt (88%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => serverbound}/ServerboundAckFinishConfigurationPacket.kt (89%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => serverbound}/ServerboundCookieResponsePacket.kt (71%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => serverbound}/ServerboundKeepAliveConfigurationPacket.kt (91%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => serverbound}/ServerboundPongConfigurationPacket.kt (91%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/{ => serverbound}/ServerboundSelectKnownPacksPacket.kt (88%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/{ => clientbound}/ClientboundDisconnectLoginPacket.kt (92%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/{ => clientbound}/ClientboundLoginPacket.kt (77%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/{ => clientbound}/ClientboundLoginSuccessPacket.kt (88%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/{ => clientbound}/ClientboundSetCompressionPacket.kt (92%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/{ => serverbound}/ServerboundLoginAcknowledgedPacket.kt (90%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/{ => serverbound}/ServerboundLoginStartPacket.kt (93%) delete mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundChatMessagePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAcknowledgeBlockChangePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAwardStatisticsPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockDestructionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockEntityDataPacket.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundDelimiterPacket.kt (89%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundDisconnectPlayPacket.kt (92%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundEntityAnimationPacket.kt (88%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundKeepAlivePlayPacket.kt (91%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundLoginPlayPacket.kt (94%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundPingPlayPacket.kt (91%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundPlayPacket.kt (77%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundPlayerChatMessagePacket.kt (99%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundSpawnEntityPacket.kt (84%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundStartConfigurationPacket.kt (90%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => clientbound}/ClientboundSystemChatMessagePacket.kt (93%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcceptTeleportationPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcknowledgeChatMessagePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAttackActionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundBundleItemSelectedPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeContainerSlotStatePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeDifficultyPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeGameModePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatCommandPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatMessagePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChunkBatchReceivedPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientActionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientCommandPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientInformationPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientTickEndPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCommandSuggestionRequestPacket.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => serverbound}/ServerboundConfigurationAcknowledgedPacket.kt (91%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickButtonPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClosePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomClickActionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomPayloadPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundDebugSubscriptionRequestPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundEditBookPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundInteractPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundJigsawGeneratePacket.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => serverbound}/ServerboundKeepAlivePlayPacket.kt (92%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundLockDifficultyPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundMoveVehiclePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPaddleBoatPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromBlockPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromEntityPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlaceRecipePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerAbilitiesPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerActionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerCommandPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerInputPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerLoadedPacket.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/{ => serverbound}/ServerboundPongPlayPacket.kt (80%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryBlockEntityTagPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryEntityTagPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookChangeSettingsPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookSeenRecipePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRenameItemPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundResourcePackResponsePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSeenAdvancementsPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSelectTradePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetBeaconPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCarriedItemPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandBlockPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandMinecartPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCreativeModeSlotPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetGameRulePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetJigsawBlockPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerMovementFlagPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionAndRotationPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerRotationPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetStructureBlockPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetTestBlockPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignUpdatePacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignedChatCommandPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSpectatorActionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSwingPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTeleportToEntityPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTestInstanceBlockActionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUpdateChatSessionPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemOnPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemPacket.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/status/serverbound/ServerboundPingRequest.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/{types => protocol/game}/Animations.kt (92%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/ChatMode.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/StatisticsEntry.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/advancement/AdvancementAction.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockDestroyStage.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockFace.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/{ => block}/BlockPos.kt (96%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/CommandBlockMode.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/StructureBlock.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/TestBlock.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/container/ContainerButton.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/debug/DebugSubscriptionType.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/gamerule/GameRuleEntry.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/ChangedSlot.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/HashedSlot.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/InventoryClickType.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/Slot.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/item/RecipeBookType.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/{types => protocol/game/math}/Angle.kt (93%) rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/{types => protocol/game/math}/LpVec3.kt (98%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/Hand.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/InteractType.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/MainHand.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerAbilities.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerActionStatus.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerCommandAction.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerPositionFlag.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/ParticleStatus.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/SkinPartFlags.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/resources/ResourcePackResult.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ArgumentSignature.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ChecksumCalculate.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/ClientAction.kt create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/GameDifficulty.kt rename libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/{profile => session}/GameProfile.kt (98%) create mode 100644 libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/TransactionIdManager.kt diff --git a/build.gradle.kts b/build.gradle.kts index 8f3c965..b0f38c3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,11 @@ plugins { allprojects { group = "cn.rtast.libmc" - version = providers.gradleProperty("libVersion").get() + val libVersion = getProperty("libVersion") + version = when (name) { + "protocol" -> "${getProperty("protocolVersion")}-$libVersion" + else -> libVersion + } repositories { mavenCentral() @@ -29,4 +33,6 @@ subprojects { } } } -} \ No newline at end of file +} + +fun getProperty(name: String): String = providers.gradleProperty(name).get() \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 03ecb79..b518a9d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,4 +4,5 @@ kotlin.native.enableKlibsCrossCompilation=true kotlin.daemon.jvmargs=-Xmx2048M org.gradle.jvmargs=-Xmx3g -Dfile.encoding=UTF-8 -libVersion=0.1.0 \ No newline at end of file +libVersion=0.1.0 +protocolVersion=26.2 \ No newline at end of file diff --git a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt index c429459..8acf66e 100644 --- a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt +++ b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/buffer.kt @@ -56,9 +56,52 @@ public fun BytesBuffer.readUuid(): Uuid { public fun BytesBuffer.writeVarInt(value: Int): Unit = VarIntCodec.encode(this, value) public fun BytesBuffer.readVarInt(): Int = VarIntCodec.decode(this) +public fun BytesBuffer.writeVarLong(value: Long): Unit = VarLongCodec.encode(this, value) +public fun BytesBuffer.readVarLong(): Long = VarLongCodec.decode(this) + public fun BytesBuffer.writeMcString(value: String): Unit = McStringCodec.encode(this, value) public fun BytesBuffer.readMcString(): String = McStringCodec.decode(this) +public fun BytesBuffer.readPrefixedByteArray(): ByteArray { + val length = this.readVarInt() + val data = this.readBytes(length) + return data +} + +public fun BytesBuffer.writePrefixedByteArray(data: ByteArray) { + this.writeVarInt(data.size) + this.writeBytes(data) +} + +public fun BytesBuffer.readPrefixedVarIntArray(): List { + val length = readVarInt() + val list = ArrayList(length) + repeat(length) { list.add(readVarInt()) } + return list +} + +public fun BytesBuffer.writePrefixedVarIntArray(value: List) { + writeVarInt(value.size) + for (item in value) writeVarInt(item) +} + +public fun BytesBuffer.readPrefixedStringArray(): List { + val length = readVarInt() + val list = ArrayList(length) + repeat(length) { list.add(readMcString()) } + return list +} + +public fun BytesBuffer.writePrefixedStringArray(value: List) { + writeVarInt(value.size) + for (item in value) writeMcString(item) +} + +public inline fun BytesBuffer.writePrefixedArray(value: List, writeItem: BytesBuffer.(T) -> Unit) { + writeVarInt(value.size) + for (item in value) writeItem(item) +} + public fun ReadChannel.readPacketFrame(): BytesBuffer { val length = this.readVarInt() return this.readBytes(length).wrap() diff --git a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/mc_primitives.kt b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/mc_primitives.kt index 9a27168..8b80092 100644 --- a/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/mc_primitives.kt +++ b/libmc-common/src/commonMain/kotlin/cn/rtast/libmc/common/mc_primitives.kt @@ -34,6 +34,34 @@ public object VarIntCodec : PacketCodec { } } +public object VarLongCodec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: Long) { + var v = value + while (true) { + if ((v and 0x7FL.inv()) == 0L) { + buffer.writeByte(v.toByte()) + return + } + buffer.writeByte(((v and 0x7F) or 0x80).toByte()) + v = v ushr 7 + } + } + + override fun decode(buffer: BytesBuffer): Long { + var numRead = 0 + var result = 0L + var read: Byte + do { + read = buffer.readByte() + val value = (read.toLong() and 0x7F) + result = result or (value shl (7 * numRead)) + numRead++ + if (numRead > 10) throw IllegalArgumentException("VarLong is too big") + } while ((read.toInt() and 0x80) != 0) + return result + } +} + public object McStringCodec : PacketCodec { override fun encode(buffer: BytesBuffer, value: String) { val bytes = value.encodeToByteArray() diff --git a/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt b/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt index 847398b..a1e081a 100644 --- a/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt +++ b/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTReader.kt @@ -79,10 +79,7 @@ public fun NBTInput.readRootCompound(): NBTCompound { public fun NBTInput.readNetworkCompound(): NBTCompound { return when (val type = NBTType.fromId(readByte().toInt() and 0xFF)) { NBTType.Compound -> NBTCompound("", readCompoundTag()) - NBTType.String -> NBTCompound( - "", NBTTag.CompoundTag(linkedMapOf("text" to NBTTag.StringTag(readStringTag()))) - ) - + NBTType.String -> NBTCompound("", NBTTag.CompoundTag(linkedMapOf("text" to NBTTag.StringTag(readStringTag())))) else -> throw UnsupportedOperationException("Unsupported network nbt tag 0x${type.id.toString(16).uppercase()}") } } \ No newline at end of file diff --git a/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTWriter.kt b/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTWriter.kt index 3ab50a9..2cc0dfb 100644 --- a/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTWriter.kt +++ b/libmc-nbt/src/commonMain/kotlin/cn/rtast/libmc/nbt/NBTWriter.kt @@ -62,3 +62,10 @@ public fun NBTOutput.writeRootNBTCompound(name: String = ""): ByteArray { writeTagPayload(root) return toByteArray() } + +public fun NBTOutput.writeNetworkCompound(compound: NBTCompound) { + val compoundTag = compound.element as? NBTTag.CompoundTag + ?: throw IllegalArgumentException("NBTCompound element must be an NBTTag.CompoundTag") + writeByte(NBTType.Compound.id) + writeTagPayload(compoundTag) +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/EnchantmentButton.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/EnchantmentButton.kt new file mode 100644 index 0000000..2de1f0c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/EnchantmentButton.kt @@ -0,0 +1,19 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.block + +public enum class EnchantmentButton(public val id: Int) { + TOPMOST(0), + MIDDLE(1), + BOTTOM(2); + + public companion object { + public fun fromID(id: Int): EnchantmentButton = + requireNotNull(entries.firstOrNull { it.id == id }) { "Unknown enchantment button id $id" } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/LecternButton.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/LecternButton.kt new file mode 100644 index 0000000..6380b7b --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/block/LecternButton.kt @@ -0,0 +1,21 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.block + +public enum class LecternButton(public val id: Int) { + PREVIOUS_PAGE(1), + NEXT_PAGE(2), + TAKE_BOOK(3); + + public companion object { + public fun fromID(id: Int): LecternButton = + requireNotNull(entries.firstOrNull { it.id == id }) { "Unknown lectern button id $id" } + + public fun specificPage(page: Int): Int = 100 + page + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/InternalPacketDispatcher.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/InternalPacketDispatcher.kt index ce94cde..05676e5 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/InternalPacketDispatcher.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/InternalPacketDispatcher.kt @@ -8,9 +8,41 @@ package cn.rtast.libmc.protocol.client import cn.rtast.libmc.common.packet.MinecraftPacket -import cn.rtast.libmc.protocol.packet.configuration.* -import cn.rtast.libmc.protocol.packet.login.* -import cn.rtast.libmc.protocol.packet.play.* +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundCookieRequestPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundCustomPayloadPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundDisconnectConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundFinishConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundKeepAliveConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundPingConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.clientbound.ClientboundSelectKnownPacksPacket +import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundAckFinishConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundKeepAliveConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundPongConfigurationPacket +import cn.rtast.libmc.protocol.packet.configuration.serverbound.ServerboundSelectKnownPacksPacket +import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundDisconnectLoginPacket +import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundLoginPacket +import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundLoginSuccessPacket +import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundSetCompressionPacket +import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginAcknowledgedPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAwardStatisticsPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundBlockDestructionPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundBlockEntityDataPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundDelimiterPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundDisconnectPlayPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundEntityAnimationPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundKeepAlivePlayPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundLoginPlayPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPingPlayPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayerChatMessagePacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundSpawnEntityPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundStartConfigurationPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundSystemChatMessagePacket +import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundConfigurationAcknowledgedPacket +import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundKeepAlivePlayPacket +import cn.rtast.libmc.protocol.packet.play.serverbound.ServerboundPongPlayPacket import cn.rtast.libmc.protocol.protocol.state.ProtocolState internal class InternalPacketDispatcher(private val client: MinecraftClient) { @@ -90,6 +122,13 @@ internal class InternalPacketDispatcher(private val client: MinecraftClient) { } is ClientboundSystemChatMessagePacket -> {} + is ClientboundAcknowledgeBlockChangePacket -> {} + is ClientboundAwardStatisticsPacket -> {} + is ClientboundBlockDestructionPacket -> {} + is ClientboundBlockEntityDataPacket -> {} + ClientboundDelimiterPacket -> {} + is ClientboundEntityAnimationPacket -> {} + is ClientboundSpawnEntityPacket -> {} } } } \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt index 337a033..4625383 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/client/MinecraftClient.kt @@ -10,9 +10,10 @@ import cn.rtast.libmc.common.LibMCContext import cn.rtast.libmc.protocol.event.PacketEventDispatcher import cn.rtast.libmc.protocol.network.NetworkChannel import cn.rtast.libmc.protocol.packet.handshake.ServerboundHandshakePacket -import cn.rtast.libmc.protocol.packet.login.ServerboundLoginStartPacket +import cn.rtast.libmc.protocol.packet.login.serverbound.ServerboundLoginStartPacket import cn.rtast.libmc.protocol.protocol.state.HandshakeIntent import cn.rtast.libmc.protocol.protocol.state.ProtocolState +import cn.rtast.libmc.protocol.session.TransactionIdManager import cn.rtast.libmc.protocol.util.generateOfflineUuid import kotlinx.coroutines.* import kotlin.coroutines.CoroutineContext @@ -35,6 +36,8 @@ public class MinecraftClient internal constructor( private val clientJob = SupervisorJob(parentJob) private var listenJob: Job? = null + public val transactionManager: TransactionIdManager = TransactionIdManager() + override val coroutineContext: CoroutineContext get() = clientJob + ioDispatcher + CoroutineName("LibMC-MinecraftClient-$username") diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundConfigurationPacket.kt similarity index 75% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundConfigurationPacket.kt index c28b039..9e4eec4 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.packet.MinecraftPacket diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundCookieRequestPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundCookieRequestPacket.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundCookieRequestPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundCookieRequestPacket.kt index d2c1382..ab71ce5 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundCookieRequestPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundCookieRequestPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundCustomPayloadPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundCustomPayloadPacket.kt similarity index 95% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundCustomPayloadPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundCustomPayloadPacket.kt index 5acc573..9a49844 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundCustomPayloadPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundCustomPayloadPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundDisconnectConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundDisconnectConfigurationPacket.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundDisconnectConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundDisconnectConfigurationPacket.kt index 3b46bbf..3d4e5b4 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundDisconnectConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundDisconnectConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundFinishConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundFinishConfigurationPacket.kt similarity index 89% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundFinishConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundFinishConfigurationPacket.kt index f7c9152..3a6ded5 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundFinishConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundFinishConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundKeepAliveConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundKeepAliveConfigurationPacket.kt similarity index 91% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundKeepAliveConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundKeepAliveConfigurationPacket.kt index ff29237..1a7a85b 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundKeepAliveConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundKeepAliveConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundPingConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundPingConfigurationPacket.kt similarity index 90% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundPingConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundPingConfigurationPacket.kt index 37d18d9..7d075e6 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundPingConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundPingConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundSelectKnownPacksPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacksPacket.kt similarity index 88% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundSelectKnownPacksPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacksPacket.kt index e613ab1..6f8caef 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ClientboundSelectKnownPacksPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacksPacket.kt @@ -5,12 +5,13 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.packet.configuration.KnownPacks public data class ClientboundSelectKnownPacksPacket(val knownPacks: List) : ClientboundConfigurationPacket { public companion object Codec : PacketCodec { diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundAckFinishConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundAckFinishConfigurationPacket.kt similarity index 89% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundAckFinishConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundAckFinishConfigurationPacket.kt index adf2e1b..b7494f9 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundAckFinishConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundAckFinishConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundCookieResponsePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundCookieResponsePacket.kt similarity index 71% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundCookieResponsePacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundCookieResponsePacket.kt index e9da34b..09b3df0 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundCookieResponsePacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundCookieResponsePacket.kt @@ -5,15 +5,13 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.packet.MinecraftPacket -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 public data class ServerboundCookieResponsePacket(val key: Identifier, val payload: ByteArray?) : MinecraftPacket { @@ -24,20 +22,11 @@ public data class ServerboundCookieResponsePacket(val key: Identifier, val paylo buffer.writeBoolean(true) buffer.writeVarInt(value.payload.size) buffer.writeBytes(value.payload) - } else { - buffer.writeBoolean(false) - } + } else buffer.writeBoolean(false) } - override fun decode(buffer: BytesBuffer): ServerboundCookieResponsePacket { - val key = buffer.readIdentifier() - val hasPayload = buffer.readBoolean() - val payload = if (hasPayload) { - val length = buffer.readVarInt() - buffer.readBytes(length) - } else null - return ServerboundCookieResponsePacket(key, payload) - } + override fun decode(buffer: BytesBuffer): ServerboundCookieResponsePacket = + throw UnsupportedOperationException() } override fun equals(other: Any?): Boolean { diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundKeepAliveConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundKeepAliveConfigurationPacket.kt similarity index 91% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundKeepAliveConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundKeepAliveConfigurationPacket.kt index e940090..5c9ed68 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundKeepAliveConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundKeepAliveConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundPongConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundPongConfigurationPacket.kt similarity index 91% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundPongConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundPongConfigurationPacket.kt index 797c7e6..b925521 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundPongConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundPongConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundSelectKnownPacksPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundSelectKnownPacksPacket.kt similarity index 88% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundSelectKnownPacksPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundSelectKnownPacksPacket.kt index 884cbfa..172cd11 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/ServerboundSelectKnownPacksPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/configuration/serverbound/ServerboundSelectKnownPacksPacket.kt @@ -5,13 +5,14 @@ */ -package cn.rtast.libmc.protocol.packet.configuration +package cn.rtast.libmc.protocol.packet.configuration.serverbound import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.packet.MinecraftPacket import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.packet.configuration.KnownPacks public data class ServerboundSelectKnownPacksPacket(val knownPacks: List) : MinecraftPacket { public companion object Codec : PacketCodec { diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundDisconnectLoginPacket.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundDisconnectLoginPacket.kt index 0591b87..57dcac7 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundDisconnectLoginPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundDisconnectLoginPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.login +package cn.rtast.libmc.protocol.packet.login.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundLoginPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundLoginPacket.kt similarity index 77% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundLoginPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundLoginPacket.kt index cee9f5c..4718d6b 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundLoginPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundLoginPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.login +package cn.rtast.libmc.protocol.packet.login.clientbound import cn.rtast.libmc.common.packet.MinecraftPacket diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundLoginSuccessPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundLoginSuccessPacket.kt similarity index 88% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundLoginSuccessPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundLoginSuccessPacket.kt index 6dba6b8..d23e599 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundLoginSuccessPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundLoginSuccessPacket.kt @@ -5,12 +5,12 @@ */ -package cn.rtast.libmc.protocol.packet.login +package cn.rtast.libmc.protocol.packet.login.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.readUuid -import cn.rtast.libmc.protocol.profile.GameProfile +import cn.rtast.libmc.protocol.session.GameProfile import kotlin.uuid.Uuid public data class ClientboundLoginSuccessPacket(val gameProfile: GameProfile, val sessionId: Uuid) : diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundSetCompressionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundSetCompressionPacket.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundSetCompressionPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundSetCompressionPacket.kt index 0b06af5..528b4fa 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ClientboundSetCompressionPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/clientbound/ClientboundSetCompressionPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.login +package cn.rtast.libmc.protocol.packet.login.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ServerboundLoginAcknowledgedPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/serverbound/ServerboundLoginAcknowledgedPacket.kt similarity index 90% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ServerboundLoginAcknowledgedPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/serverbound/ServerboundLoginAcknowledgedPacket.kt index 783a2f1..1f988e2 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ServerboundLoginAcknowledgedPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/serverbound/ServerboundLoginAcknowledgedPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.login +package cn.rtast.libmc.protocol.packet.login.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ServerboundLoginStartPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/serverbound/ServerboundLoginStartPacket.kt similarity index 93% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ServerboundLoginStartPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/serverbound/ServerboundLoginStartPacket.kt index e930146..f16b8a6 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/ServerboundLoginStartPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/login/serverbound/ServerboundLoginStartPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.login +package cn.rtast.libmc.protocol.packet.login.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundChatMessagePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundChatMessagePacket.kt deleted file mode 100644 index 811e38d..0000000 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundChatMessagePacket.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright © 2026 RTAkland - * Author: RTAkland - * Date: 2026/9/4 - */ - - -package cn.rtast.libmc.protocol.packet.play - -import cn.rtast.libmc.common.BytesBuffer -import cn.rtast.libmc.common.PacketCodec -import cn.rtast.libmc.common.packet.MinecraftPacket -import cn.rtast.libmc.common.writeMcString -import cn.rtast.libmc.common.writeVarInt -import kotlin.time.Clock - -public data class ServerboundChatMessagePacket( - val message: String, - val timestamp: Long = Clock.System.now().toEpochMilliseconds(), - val salt: Long = 0L, -) : MinecraftPacket { - public companion object Codec : PacketCodec { - override fun encode(buffer: BytesBuffer, value: ServerboundChatMessagePacket) { - buffer.writeMcString(value.message) - buffer.writeLong(value.timestamp) - buffer.writeLong(value.salt) - buffer.writeBoolean(false) // has signature - buffer.writeVarInt(0) // message count - buffer.writeBytes(byteArrayOf(0, 0, 0)) - } - - override fun decode(buffer: BytesBuffer): ServerboundChatMessagePacket = throw UnsupportedOperationException() - } -} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAcknowledgeBlockChangePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAcknowledgeBlockChangePacket.kt new file mode 100644 index 0000000..10ae3a6 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAcknowledgeBlockChangePacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.clientbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.readVarInt + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Acknowledge_Block_Change + */ +public data class ClientboundAcknowledgeBlockChangePacket(val sequenceId: Int) : ClientboundPlayPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ClientboundAcknowledgeBlockChangePacket) {} + override fun decode(buffer: BytesBuffer): ClientboundAcknowledgeBlockChangePacket { + return ClientboundAcknowledgeBlockChangePacket(buffer.readVarInt()) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAwardStatisticsPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAwardStatisticsPacket.kt new file mode 100644 index 0000000..ebcfc7b --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundAwardStatisticsPacket.kt @@ -0,0 +1,27 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.clientbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.readVarInt +import cn.rtast.libmc.protocol.protocol.game.StatisticsEntry + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Award_Statistics + */ +public data class ClientboundAwardStatisticsPacket(val stats: List) : ClientboundPlayPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ClientboundAwardStatisticsPacket) {} + override fun decode(buffer: BytesBuffer): ClientboundAwardStatisticsPacket { + val count = buffer.readVarInt() + val stats = List(count) { StatisticsEntry.decode(buffer) } + return ClientboundAwardStatisticsPacket(stats) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockDestructionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockDestructionPacket.kt new file mode 100644 index 0000000..4225ab3 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockDestructionPacket.kt @@ -0,0 +1,34 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.clientbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.readVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockDestroyStage +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Set_Block_Destroy_Stage + */ +public data class ClientboundBlockDestructionPacket( + val entityId: Int, + val location: BlockPos, + val stage: BlockDestroyStage, +) : ClientboundPlayPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ClientboundBlockDestructionPacket) {} + override fun decode(buffer: BytesBuffer): ClientboundBlockDestructionPacket { + val entityId = buffer.readVarInt() + val location = buffer.readBlockPos() + val stage = buffer.readByte() + return ClientboundBlockDestructionPacket(entityId, location, BlockDestroyStage(stage)) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockEntityDataPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockEntityDataPacket.kt new file mode 100644 index 0000000..3989d5c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundBlockEntityDataPacket.kt @@ -0,0 +1,29 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.clientbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.readVarInt +import cn.rtast.libmc.nbt.NBTCompound +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos +import cn.rtast.libmc.protocol.protocol.util.readNetworkNBTCompound + +public data class ClientboundBlockEntityDataPacket(val location: BlockPos, val type: Int, val data: NBTCompound) : + ClientboundPlayPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ClientboundBlockEntityDataPacket) {} + override fun decode(buffer: BytesBuffer): ClientboundBlockEntityDataPacket { + val location = buffer.readBlockPos() + val type = buffer.readVarInt() + val data = buffer.readNetworkNBTCompound() + return ClientboundBlockEntityDataPacket(location, type, data) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundDelimiterPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundDelimiterPacket.kt similarity index 89% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundDelimiterPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundDelimiterPacket.kt index 9007171..83b088a 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundDelimiterPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundDelimiterPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundDisconnectPlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundDisconnectPlayPacket.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundDisconnectPlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundDisconnectPlayPacket.kt index 0c3cc2b..fe59f32 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundDisconnectPlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundDisconnectPlayPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundEntityAnimationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundEntityAnimationPacket.kt similarity index 88% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundEntityAnimationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundEntityAnimationPacket.kt index db33c49..ce18765 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundEntityAnimationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundEntityAnimationPacket.kt @@ -5,12 +5,12 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.readVarInt -import cn.rtast.libmc.protocol.types.Animations +import cn.rtast.libmc.protocol.protocol.game.Animations /** * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Entity_Animation diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundKeepAlivePlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundKeepAlivePlayPacket.kt similarity index 91% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundKeepAlivePlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundKeepAlivePlayPacket.kt index a1718bc..41472b6 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundKeepAlivePlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundKeepAlivePlayPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundLoginPlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundLoginPlayPacket.kt similarity index 94% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundLoginPlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundLoginPlayPacket.kt index e905469..444f3e6 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundLoginPlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundLoginPlayPacket.kt @@ -5,12 +5,14 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.readVarInt import cn.rtast.libmc.protocol.protocol.game.* +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos public data class ClientboundLoginPlayPacket( val entityId: Int, diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPingPlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPingPlayPacket.kt similarity index 91% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPingPlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPingPlayPacket.kt index 22ed854..a37d112 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPingPlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPingPlayPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPlayPacket.kt similarity index 77% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPlayPacket.kt index bd9d77f..9f2fb1b 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPlayPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.packet.MinecraftPacket diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPlayerChatMessagePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPlayerChatMessagePacket.kt similarity index 99% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPlayerChatMessagePacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPlayerChatMessagePacket.kt index 200e8bb..3281278 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundPlayerChatMessagePacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundPlayerChatMessagePacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.* import cn.rtast.libmc.nbt.NBTCompound diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundSpawnEntityPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundSpawnEntityPacket.kt similarity index 84% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundSpawnEntityPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundSpawnEntityPacket.kt index aa034c4..d5fd47b 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundSpawnEntityPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundSpawnEntityPacket.kt @@ -5,16 +5,16 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.readUuid import cn.rtast.libmc.common.readVarInt -import cn.rtast.libmc.protocol.types.Angle -import cn.rtast.libmc.protocol.types.LpVec3 -import cn.rtast.libmc.protocol.types.readAngle -import cn.rtast.libmc.protocol.types.readLpVec3 +import cn.rtast.libmc.protocol.protocol.game.math.Angle +import cn.rtast.libmc.protocol.protocol.game.math.LpVec3 +import cn.rtast.libmc.protocol.protocol.game.math.readAngle +import cn.rtast.libmc.protocol.protocol.game.math.readLpVec3 import kotlin.uuid.Uuid /** diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundStartConfigurationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundStartConfigurationPacket.kt similarity index 90% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundStartConfigurationPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundStartConfigurationPacket.kt index 4f181b8..846ff4c 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundStartConfigurationPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundStartConfigurationPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundSystemChatMessagePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundSystemChatMessagePacket.kt similarity index 93% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundSystemChatMessagePacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundSystemChatMessagePacket.kt index 9d01475..6bca92c 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ClientboundSystemChatMessagePacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/clientbound/ClientboundSystemChatMessagePacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.clientbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcceptTeleportationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcceptTeleportationPacket.kt new file mode 100644 index 0000000..dd3f065 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcceptTeleportationPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundAcceptTeleportationPacket(val teleportId: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundAcceptTeleportationPacket) { + buffer.writeVarInt(value.teleportId) + } + + override fun decode(buffer: BytesBuffer): ServerboundAcceptTeleportationPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcknowledgeChatMessagePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcknowledgeChatMessagePacket.kt new file mode 100644 index 0000000..b2e1eb6 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAcknowledgeChatMessagePacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundAcknowledgeChatMessagePacket(val messageCount: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundAcknowledgeChatMessagePacket) { + buffer.writeVarInt(value.messageCount) + } + + override fun decode(buffer: BytesBuffer): ServerboundAcknowledgeChatMessagePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAttackActionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAttackActionPacket.kt new file mode 100644 index 0000000..333f3f4 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundAttackActionPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundAttackActionPacket(val entityId: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundAttackActionPacket) { + buffer.writeVarInt(value.entityId) + } + + override fun decode(buffer: BytesBuffer): ServerboundAttackActionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundBundleItemSelectedPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundBundleItemSelectedPacket.kt new file mode 100644 index 0000000..54d9a4e --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundBundleItemSelectedPacket.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundBundleItemSelectedPacket(val slotOfBundle: Int, val slotInBundle: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundBundleItemSelectedPacket) { + buffer.writeVarInt(value.slotOfBundle) + buffer.writeVarInt(value.slotInBundle) + } + + override fun decode(buffer: BytesBuffer): ServerboundBundleItemSelectedPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeContainerSlotStatePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeContainerSlotStatePacket.kt new file mode 100644 index 0000000..5cf8f3f --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeContainerSlotStatePacket.kt @@ -0,0 +1,27 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundChangeContainerSlotStatePacket(val slotId: Int, val windowId: Int, val state: Boolean) : + MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundChangeContainerSlotStatePacket) { + buffer.writeVarInt(value.slotId) + buffer.writeVarInt(value.windowId) + buffer.writeBoolean(value.state) + } + + override fun decode(buffer: BytesBuffer): ServerboundChangeContainerSlotStatePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeDifficultyPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeDifficultyPacket.kt new file mode 100644 index 0000000..82e4c01 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeDifficultyPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.registry.GameDifficulty + +public data class ServerboundChangeDifficultyPacket(val newDifficulty: GameDifficulty) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundChangeDifficultyPacket) { + buffer.writeByte(value.newDifficulty.id) + } + + override fun decode(buffer: BytesBuffer): ServerboundChangeDifficultyPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeGameModePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeGameModePacket.kt new file mode 100644 index 0000000..da1b0eb --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChangeGameModePacket.kt @@ -0,0 +1,26 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.GameMode + +public data class ServerboundChangeGameModePacket(val gameMode: GameMode) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundChangeGameModePacket) { + require(value.gameMode != GameMode.Unknown && value.gameMode != GameMode.Undefined) + buffer.writeVarInt(value.gameMode.id.toInt()) + } + + override fun decode(buffer: BytesBuffer): ServerboundChangeGameModePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatCommandPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatCommandPacket.kt new file mode 100644 index 0000000..cf2d07c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatCommandPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString + +public data class ServerboundChatCommandPacket(val command: String) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundChatCommandPacket) { + buffer.writeMcString(value.command.removePrefix("/")) + } + + override fun decode(buffer: BytesBuffer): ServerboundChatCommandPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatMessagePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatMessagePacket.kt new file mode 100644 index 0000000..268831f --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChatMessagePacket.kt @@ -0,0 +1,69 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/4 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundChatMessagePacket( + val message: String, + val timestamp: Long, + val salt: Long, + val signature: ByteArray?, + val messageCount: Int, + val acknowledged: ByteArray, + val checksum: Byte, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundChatMessagePacket) { + buffer.writeMcString(value.message) + buffer.writeLong(value.timestamp) + buffer.writeLong(value.salt) + val hasSignature = value.signature != null + buffer.writeBoolean(hasSignature) + if (hasSignature) buffer.writeBytes(value.signature) + buffer.writeVarInt(value.messageCount) + buffer.writeBytes(value.acknowledged) + buffer.writeByte(value.checksum) + } + + override fun decode(buffer: BytesBuffer): ServerboundChatMessagePacket = + throw UnsupportedOperationException() + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ServerboundChatMessagePacket + + if (timestamp != other.timestamp) return false + if (salt != other.salt) return false + if (messageCount != other.messageCount) return false + if (checksum != other.checksum) return false + if (message != other.message) return false + if (!signature.contentEquals(other.signature)) return false + if (!acknowledged.contentEquals(other.acknowledged)) return false + + return true + } + + override fun hashCode(): Int { + var result = timestamp.hashCode() + result = 31 * result + salt.hashCode() + result = 31 * result + messageCount + result = 31 * result + checksum + result = 31 * result + message.hashCode() + result = 31 * result + (signature?.contentHashCode() ?: 0) + result = 31 * result + acknowledged.contentHashCode() + return result + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChunkBatchReceivedPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChunkBatchReceivedPacket.kt new file mode 100644 index 0000000..9aadb8e --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundChunkBatchReceivedPacket.kt @@ -0,0 +1,23 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +public data class ServerboundChunkBatchReceivedPacket(val chunksPerTick: Float) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundChunkBatchReceivedPacket) { + buffer.writeFloat(value.chunksPerTick) + } + + override fun decode(buffer: BytesBuffer): ServerboundChunkBatchReceivedPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientActionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientActionPacket.kt new file mode 100644 index 0000000..e15c21a --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientActionPacket.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.registry.ClientAction + +public data class ServerboundClientActionPacket(val action: ClientAction) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundClientActionPacket) { + buffer.writeVarInt(value.action.actionID) + } + + override fun decode(buffer: BytesBuffer): ServerboundClientActionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientCommandPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientCommandPacket.kt new file mode 100644 index 0000000..a37f5d8 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientCommandPacket.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.player.PlayerActionStatus + +public data class ServerboundClientCommandPacket(val action: PlayerActionStatus) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundClientCommandPacket) { + buffer.writeVarInt(value.action.id) + } + + override fun decode(buffer: BytesBuffer): ServerboundClientCommandPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientInformationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientInformationPacket.kt new file mode 100644 index 0000000..2df4f8b --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientInformationPacket.kt @@ -0,0 +1,67 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.ChatMode +import cn.rtast.libmc.protocol.protocol.game.player.MainHand +import cn.rtast.libmc.protocol.protocol.game.player.skin.ParticleStatus +import cn.rtast.libmc.protocol.protocol.game.player.skin.SkinPartFlag +import cn.rtast.libmc.protocol.protocol.game.player.skin.SkinPartFlags + +public data class ServerboundClientInformationPacket( + val locale: String, + /** + * real type is [Byte] + */ + val viewDistance: Int, + val chatMode: ChatMode, + /** + * “Colors” multiplayer setting. The vanilla server stores this value but does nothing with it (see MC-64867). + * Some third-party servers disable all coloring in chat and system messages when it is false. + */ + val chatColors: Boolean, + /** + * see [SkinPartFlags] + */ + val displayedSkinParts: SkinPartFlag, + val mainHand: MainHand, + /** + * Enables filtering of text on signs and written book titles. + * The vanilla client sets this according to the profanityFilterPreferences.profanityFilterOn + * account attribute indicated by the Mojang API endpoint for player attributes. + * In offline mode, it is always false. + */ + val enableTextFiltering: Boolean, + /** + * Servers usually list online players; this option should let you not show up in that list. + */ + val allowServerListings: Boolean, + val particleStatus: ParticleStatus, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundClientInformationPacket) { + buffer.writeMcString(value.locale) + buffer.writeByte(value.viewDistance.toByte()) + buffer.writeVarInt(value.chatMode.id) + buffer.writeBoolean(value.chatColors) + buffer.writeByte(value.displayedSkinParts.toByte()) + buffer.writeVarInt(value.mainHand.id) + buffer.writeBoolean(value.enableTextFiltering) + buffer.writeBoolean(value.allowServerListings) + buffer.writeVarInt(value.particleStatus.id) + } + + override fun decode(buffer: BytesBuffer): ServerboundClientInformationPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientTickEndPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientTickEndPacket.kt new file mode 100644 index 0000000..b89a7de --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundClientTickEndPacket.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +public data object ServerboundClientTickEndPacket : MinecraftPacket, PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundClientTickEndPacket) {} + override fun decode(buffer: BytesBuffer): ServerboundClientTickEndPacket = throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCommandSuggestionRequestPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCommandSuggestionRequestPacket.kt new file mode 100644 index 0000000..d0fea07 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCommandSuggestionRequestPacket.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundCommandSuggestionRequestPacket( + /** + * to get transaction id, use `MinecraftClient.transactionManager.nextCommandSuggestionId` + */ + val transactionId: Int, + /** + * All the text behind the cursor including the / (e.g. to the left of the cursor in left-to-right languages like English). + */ + val text: String, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundCommandSuggestionRequestPacket) { + buffer.writeVarInt(value.transactionId) + buffer.writeMcString(value.text) + } + + override fun decode(buffer: BytesBuffer): ServerboundCommandSuggestionRequestPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundConfigurationAcknowledgedPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundConfigurationAcknowledgedPacket.kt similarity index 91% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundConfigurationAcknowledgedPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundConfigurationAcknowledgedPacket.kt index 394c79f..f0c0429 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundConfigurationAcknowledgedPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundConfigurationAcknowledgedPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickButtonPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickButtonPacket.kt new file mode 100644 index 0000000..8dbe79a --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickButtonPacket.kt @@ -0,0 +1,30 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.block.EnchantmentButton +import cn.rtast.libmc.protocol.block.LecternButton + +public data class ServerboundContainerClickButtonPacket(val windowId: Int, val buttonId: Int) : MinecraftPacket { + public constructor(windowId: Int, button: EnchantmentButton) : this(windowId, button.id) + public constructor(windowId: Int, button: LecternButton) : this(windowId, button.id) + + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundContainerClickButtonPacket) { + buffer.writeVarInt(value.windowId) + buffer.writeVarInt(value.buttonId) + } + + override fun decode(buffer: BytesBuffer): ServerboundContainerClickButtonPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickPacket.kt new file mode 100644 index 0000000..8609ab1 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClickPacket.kt @@ -0,0 +1,73 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.container.ContainerButton +import cn.rtast.libmc.protocol.protocol.game.inventory.ChangedSlot +import cn.rtast.libmc.protocol.protocol.game.inventory.HashedSlot +import cn.rtast.libmc.protocol.protocol.game.inventory.InventoryClickType + +public data class ServerboundContainerClickPacket( + val windowId: Int, + val stateId: Int, + val slot: Short, + val button: Byte, + val mode: Int, + val changedSlots: List, + val carriedItem: HashedSlot, +) : MinecraftPacket { + public constructor( + windowId: Int, + stateId: Int, + slot: Short, + mouseButton: ContainerButton.Mouse, + changedSlots: List, + carriedItem: HashedSlot, + ) : this( + windowId = windowId, + stateId = stateId, + slot = slot, + button = mouseButton.id, + mode = InventoryClickType.PICKUP.id, + changedSlots = changedSlots, + carriedItem = carriedItem + ) + + public constructor( + windowId: Int, + stateId: Int, + slot: Short, + swapButton: ContainerButton.Swap, + changedSlots: List, + carriedItem: HashedSlot, + ) : this( + windowId = windowId, + stateId = stateId, + slot = slot, + button = swapButton.id, + mode = InventoryClickType.SWAP.id, + changedSlots = changedSlots, + carriedItem = carriedItem + ) + + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundContainerClickPacket) { + buffer.writeVarInt(value.windowId) + buffer.writeVarInt(value.stateId) + buffer.writeShort(value.slot) + buffer.writeByte(value.button) + } + + override fun decode(buffer: BytesBuffer): ServerboundContainerClickPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClosePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClosePacket.kt new file mode 100644 index 0000000..9cb4167 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundContainerClosePacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundContainerClosePacket(val windowId: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundContainerClosePacket) { + buffer.writeVarInt(value.windowId) + } + + override fun decode(buffer: BytesBuffer): ServerboundContainerClosePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomClickActionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomClickActionPacket.kt new file mode 100644 index 0000000..5dc8d1f --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomClickActionPacket.kt @@ -0,0 +1,37 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.nbt.NBTCompound +import cn.rtast.libmc.protocol.protocol.game.Identifier +import cn.rtast.libmc.protocol.protocol.game.writeIdentifier +import cn.rtast.libmc.protocol.protocol.util.writeNetworkNBTCompound + +public data class ServerboundCustomClickActionPacket( + val id: Identifier, + /** + * payload size, bytes + */ + val size: Int, + val payload: NBTCompound, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundCustomClickActionPacket) { + buffer.writeIdentifier(value.id) + buffer.writeVarInt(value.size) + buffer.writeNetworkNBTCompound(value.payload) + } + + override fun decode(buffer: BytesBuffer): ServerboundCustomClickActionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomPayloadPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomPayloadPacket.kt new file mode 100644 index 0000000..cdf5f7c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundCustomPayloadPacket.kt @@ -0,0 +1,44 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.Identifier +import cn.rtast.libmc.protocol.protocol.game.writeIdentifier + +public data class ServerboundCustomPayloadPacket(val channel: Identifier, val data: ByteArray) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundCustomPayloadPacket) { + buffer.writeIdentifier(value.channel) + buffer.writeBytes(value.data) // ? + } + + override fun decode(buffer: BytesBuffer): ServerboundCustomPayloadPacket = + throw UnsupportedOperationException() + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ServerboundCustomPayloadPacket + + if (channel != other.channel) return false + if (!data.contentEquals(other.data)) return false + + return true + } + + override fun hashCode(): Int { + var result = channel.hashCode() + result = 31 * result + data.contentHashCode() + return result + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundDebugSubscriptionRequestPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundDebugSubscriptionRequestPacket.kt new file mode 100644 index 0000000..d366875 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundDebugSubscriptionRequestPacket.kt @@ -0,0 +1,26 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writePrefixedVarIntArray +import cn.rtast.libmc.protocol.protocol.game.debug.DebugSubscriptionType + +public data class ServerboundDebugSubscriptionRequestPacket(val subscriptions: List) : + MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundDebugSubscriptionRequestPacket) { + buffer.writePrefixedVarIntArray(value.subscriptions.map { it.id }) + } + + override fun decode(buffer: BytesBuffer): ServerboundDebugSubscriptionRequestPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundEditBookPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundEditBookPacket.kt new file mode 100644 index 0000000..f815867 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundEditBookPacket.kt @@ -0,0 +1,27 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.* +import cn.rtast.libmc.common.packet.MinecraftPacket + +public data class ServerboundEditBookPacket(val slot: Int, val entries: List, val title: String?) : + MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundEditBookPacket) { + buffer.writeVarInt(value.slot) + buffer.writePrefixedStringArray(value.entries) + val hasTitle = value.title != null + buffer.writeBoolean(hasTitle) + if (hasTitle) buffer.writeMcString(value.title) + } + + override fun decode(buffer: BytesBuffer): ServerboundEditBookPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundInteractPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundInteractPacket.kt new file mode 100644 index 0000000..f160d1a --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundInteractPacket.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.math.LpVec3 +import cn.rtast.libmc.protocol.protocol.game.math.writeLpVec3 +import cn.rtast.libmc.protocol.protocol.game.player.Hand + +public data class ServerboundInteractPacket( + val entityId: Int, + val hand: Hand, + val targetOffset: LpVec3, + val isSneaking: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundInteractPacket) { + buffer.writeVarInt(value.entityId) + buffer.writeVarInt(value.hand.id) + buffer.writeLpVec3(value.targetOffset) + buffer.writeBoolean(value.isSneaking) + } + + override fun decode(buffer: BytesBuffer): ServerboundInteractPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundJigsawGeneratePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundJigsawGeneratePacket.kt new file mode 100644 index 0000000..3259555 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundJigsawGeneratePacket.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos + +public data class ServerboundJigsawGeneratePacket( + val location: BlockPos, + /** + * Value of the levels slider/max depth to generate. + */ + val levels: Int, + val keepJigsaw: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundJigsawGeneratePacket) { + buffer.writeBlockPos(value.location) + buffer.writeVarInt(value.levels) + buffer.writeBoolean(value.keepJigsaw) + } + + override fun decode(buffer: BytesBuffer): ServerboundJigsawGeneratePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundKeepAlivePlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundKeepAlivePlayPacket.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundKeepAlivePlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundKeepAlivePlayPacket.kt index 80afe6d..41ab3de 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundKeepAlivePlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundKeepAlivePlayPacket.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundLockDifficultyPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundLockDifficultyPacket.kt new file mode 100644 index 0000000..82e9e52 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundLockDifficultyPacket.kt @@ -0,0 +1,28 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +/** + * Must have at least op level 2 to use. + * Appears to only be used on singleplayer; the difficulty buttons are still disabled in multiplayer. + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Lock_Difficulty + */ +public data class ServerboundLockDifficultyPacket(val locked: Boolean) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundLockDifficultyPacket) { + buffer.writeBoolean(value.locked) + } + + override fun decode(buffer: BytesBuffer): ServerboundLockDifficultyPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundMoveVehiclePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundMoveVehiclePacket.kt new file mode 100644 index 0000000..9d21cad --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundMoveVehiclePacket.kt @@ -0,0 +1,37 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Move_Vehicle_(serverbound) + * onGround does not seem to exist + */ +public data class ServerboundMoveVehiclePacket( + val x: Double, + val y: Double, + val z: Double, + val yaw: Float, + val pitch: Float, +// val onGround: Boolean +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundMoveVehiclePacket) { + buffer.writeDouble(value.x) + buffer.writeDouble(value.y) + buffer.writeDouble(value.z) + buffer.writeFloat(value.yaw) + buffer.writeFloat(value.pitch) + } + + override fun decode(buffer: BytesBuffer): ServerboundMoveVehiclePacket = throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPaddleBoatPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPaddleBoatPacket.kt new file mode 100644 index 0000000..aa95345 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPaddleBoatPacket.kt @@ -0,0 +1,36 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +/** + * Used to visually update whether boat paddles are turning. + * The server will update the Boat entity metadata to match the values here. + * + * Right paddle turning is set to true when the left button or forward button is held, + * left paddle turning is set to true when the right button or forward button is held. + * + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Paddle_Boat + */ +public data class ServerboundPaddleBoatPacket( + val leftPaddleTurning: Boolean, + val rightPaddleTurning: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPaddleBoatPacket) { + buffer.writeBoolean(value.leftPaddleTurning) + buffer.writeBoolean(value.rightPaddleTurning) + } + + override fun decode(buffer: BytesBuffer): ServerboundPaddleBoatPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromBlockPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromBlockPacket.kt new file mode 100644 index 0000000..990251d --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromBlockPacket.kt @@ -0,0 +1,33 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos + +public data class ServerboundPickItemFromBlockPacket( + val location: BlockPos, + /** + * Used to tell the server to include block data in the new stack, + * works only if in creative mode. + */ + val includeData: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPickItemFromBlockPacket) { + buffer.writeBlockPos(value.location) + buffer.writeBoolean(value.includeData) + } + + override fun decode(buffer: BytesBuffer): ServerboundPickItemFromBlockPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromEntityPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromEntityPacket.kt new file mode 100644 index 0000000..14106fc --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPickItemFromEntityPacket.kt @@ -0,0 +1,31 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundPickItemFromEntityPacket( + val entityId: Int, + /** + * Unused by the vanilla server. + */ + val includeData: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPickItemFromEntityPacket) { + buffer.writeVarInt(value.entityId) + buffer.writeBoolean(value.includeData) + } + + override fun decode(buffer: BytesBuffer): ServerboundPickItemFromEntityPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlaceRecipePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlaceRecipePacket.kt new file mode 100644 index 0000000..9328d4b --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlaceRecipePacket.kt @@ -0,0 +1,30 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundPlaceRecipePacket( + val windowId: Int, + val recipeId: Int, + val makeAll: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPlaceRecipePacket) { + buffer.writeVarInt(value.windowId) + buffer.writeVarInt(value.recipeId) + buffer.writeBoolean(value.makeAll) + } + + override fun decode(buffer: BytesBuffer): ServerboundPlaceRecipePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerAbilitiesPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerAbilitiesPacket.kt new file mode 100644 index 0000000..dea4742 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerAbilitiesPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.player.PlayerAbilities + +public data class ServerboundPlayerAbilitiesPacket(val flags: PlayerAbilities) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPlayerAbilitiesPacket) { + buffer.writeByte(value.flags.flag) + } + + override fun decode(buffer: BytesBuffer): ServerboundPlayerAbilitiesPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerActionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerActionPacket.kt new file mode 100644 index 0000000..fdb1839 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerActionPacket.kt @@ -0,0 +1,43 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockFace +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos +import cn.rtast.libmc.protocol.protocol.game.player.PlayerActionStatus + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Player_Action + */ +public data class ServerboundPlayerActionPacket( + val status: PlayerActionStatus, + val location: BlockPos, + val blockFace: BlockFace, + /** + * Block change sequence number + * see [cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket] + */ + val sequence: Int, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPlayerActionPacket) { + buffer.writeVarInt(value.status.id) + buffer.writeBlockPos(value.location) + buffer.writeByte(value.blockFace.id) + buffer.writeVarInt(value.sequence) + } + + override fun decode(buffer: BytesBuffer): ServerboundPlayerActionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerCommandPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerCommandPacket.kt new file mode 100644 index 0000000..1a4ebac --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerCommandPacket.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.player.PlayerCommandAction + +public data class ServerboundPlayerCommandPacket( + val entityId: Int, + val action: PlayerCommandAction, + /** + * Only used by the “start jump with horse” action, + * in which case it ranges from 0 to 100. In all other cases it is 0 + */ + val jumpBoost: Int, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPlayerCommandPacket) { + buffer.writeVarInt(value.entityId) + buffer.writeVarInt(value.action.id) + buffer.writeVarInt(value.jumpBoost) + } + + override fun decode(buffer: BytesBuffer): ServerboundPlayerCommandPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerInputPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerInputPacket.kt new file mode 100644 index 0000000..009a1fe --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerInputPacket.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +public data class ServerboundPlayerInputPacket( + val forward: Boolean, + val backward: Boolean, + val left: Boolean, + val right: Boolean, + val jump: Boolean, + val sneak: Boolean, + val sprint: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + private const val FLAG_FORWARD = 0x01 + private const val FLAG_BACKWARD = 0x02 + private const val FLAG_LEFT = 0x04 + private const val FLAG_RIGHT = 0x08 + private const val FLAG_JUMP = 0x10 + private const val FLAG_SNEAK = 0x20 + private const val FLAG_SPRINT = 0x40 + + override fun encode(buffer: BytesBuffer, value: ServerboundPlayerInputPacket) { + var flags = 0 + if (value.forward) flags = flags or FLAG_FORWARD + if (value.backward) flags = flags or FLAG_BACKWARD + if (value.left) flags = flags or FLAG_LEFT + if (value.right) flags = flags or FLAG_RIGHT + if (value.jump) flags = flags or FLAG_JUMP + if (value.sneak) flags = flags or FLAG_SNEAK + if (value.sprint) flags = flags or FLAG_SPRINT + buffer.writeByte(flags.toByte()) + } + + override fun decode(buffer: BytesBuffer): ServerboundPlayerInputPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerLoadedPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerLoadedPacket.kt new file mode 100644 index 0000000..b297100 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPlayerLoadedPacket.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +public data object ServerboundPlayerLoadedPacket : MinecraftPacket, PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPlayerLoadedPacket) {} + override fun decode(buffer: BytesBuffer): ServerboundPlayerLoadedPacket = throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundPongPlayPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPongPlayPacket.kt similarity index 80% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundPongPlayPacket.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPongPlayPacket.kt index 5e706d8..66116d0 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/ServerboundPongPlayPacket.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundPongPlayPacket.kt @@ -4,7 +4,7 @@ * Date: 2026/9/5 */ -package cn.rtast.libmc.protocol.packet.play +package cn.rtast.libmc.protocol.packet.play.serverbound import cn.rtast.libmc.common.BytesBuffer import cn.rtast.libmc.common.PacketCodec @@ -16,8 +16,7 @@ public data class ServerboundPongPlayPacket(val id: Int) : MinecraftPacket { buffer.writeInt(value.id) } - override fun decode(buffer: BytesBuffer): ServerboundPongPlayPacket { - return ServerboundPongPlayPacket(id = buffer.readInt()) - } + override fun decode(buffer: BytesBuffer): ServerboundPongPlayPacket = + throw UnsupportedOperationException() } } \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryBlockEntityTagPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryBlockEntityTagPacket.kt new file mode 100644 index 0000000..8d53cde --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryBlockEntityTagPacket.kt @@ -0,0 +1,29 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos + +/** + * to get a transaction id, use `MinecraftClient.transactionManager.nextQueryId` + */ +public data class ServerboundQueryBlockEntityTagPacket(val transactionId: Int, val location: BlockPos) : + MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundQueryBlockEntityTagPacket) { + buffer.writeVarInt(value.transactionId) + } + + override fun decode(buffer: BytesBuffer): ServerboundQueryBlockEntityTagPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryEntityTagPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryEntityTagPacket.kt new file mode 100644 index 0000000..239a28c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundQueryEntityTagPacket.kt @@ -0,0 +1,31 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundQueryEntityTagPacket( + /** + * to get a transaction id, use `MinecraftClient.transactionManager.nextQueryEntitytagId` + */ + val transactionId: Int, + val entityId: Int, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundQueryEntityTagPacket) { + buffer.writeVarInt(value.transactionId) + buffer.writeVarInt(value.entityId) + } + + override fun decode(buffer: BytesBuffer): ServerboundQueryEntityTagPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookChangeSettingsPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookChangeSettingsPacket.kt new file mode 100644 index 0000000..8aa6e3c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookChangeSettingsPacket.kt @@ -0,0 +1,31 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.item.RecipeBookType + +public data class ServerboundRecipeBookChangeSettingsPacket( + val bookId: RecipeBookType, + val bookOpen: Boolean, + val filterActive: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundRecipeBookChangeSettingsPacket) { + buffer.writeVarInt(value.bookId.id) + buffer.writeBoolean(value.bookOpen) + buffer.writeBoolean(value.filterActive) + } + + override fun decode(buffer: BytesBuffer): ServerboundRecipeBookChangeSettingsPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookSeenRecipePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookSeenRecipePacket.kt new file mode 100644 index 0000000..5698df7 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRecipeBookSeenRecipePacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundRecipeBookSeenRecipePacket(val recipeId: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundRecipeBookSeenRecipePacket) { + buffer.writeVarInt(value.recipeId) + } + + override fun decode(buffer: BytesBuffer): ServerboundRecipeBookSeenRecipePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRenameItemPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRenameItemPacket.kt new file mode 100644 index 0000000..995a449 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundRenameItemPacket.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString + +public data class ServerboundRenameItemPacket(val itemName: String) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundRenameItemPacket) { + require(value.itemName.length < 50) + buffer.writeMcString(value.itemName) + } + + override fun decode(buffer: BytesBuffer): ServerboundRenameItemPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundResourcePackResponsePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundResourcePackResponsePacket.kt new file mode 100644 index 0000000..cc8bb5e --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundResourcePackResponsePacket.kt @@ -0,0 +1,31 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeUuid +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.resources.ResourcePackResult +import kotlin.uuid.Uuid + +public data class ServerboundResourcePackResponsePacket( + val uuid: Uuid, + val result: ResourcePackResult, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundResourcePackResponsePacket) { + buffer.writeUuid(value.uuid) + buffer.writeVarInt(value.result.id) + } + + override fun decode(buffer: BytesBuffer): ServerboundResourcePackResponsePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSeenAdvancementsPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSeenAdvancementsPacket.kt new file mode 100644 index 0000000..cab03be --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSeenAdvancementsPacket.kt @@ -0,0 +1,32 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.Identifier +import cn.rtast.libmc.protocol.protocol.game.advancement.AdvancementAction +import cn.rtast.libmc.protocol.protocol.game.writeIdentifier + +public data class ServerboundSeenAdvancementsPacket(val action: AdvancementAction, val tabId: Identifier?) : + MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSeenAdvancementsPacket) { + buffer.writeVarInt(value.action.id) + if (value.action == AdvancementAction.OPENED_TAB) { + requireNotNull(value.tabId) { "tabId must not be null when action is OPENED_TAB" } + buffer.writeIdentifier(value.tabId) + } else require(value.tabId == null) { "tabId must be null when action is CLOSED_SCREEN" } + } + + override fun decode(buffer: BytesBuffer): ServerboundSeenAdvancementsPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSelectTradePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSelectTradePacket.kt new file mode 100644 index 0000000..121c4ee --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSelectTradePacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundSelectTradePacket(val selectedSlot: Int) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSelectTradePacket) { + buffer.writeVarInt(value.selectedSlot) + } + + override fun decode(buffer: BytesBuffer): ServerboundSelectTradePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetBeaconPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetBeaconPacket.kt new file mode 100644 index 0000000..bb4ed8f --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetBeaconPacket.kt @@ -0,0 +1,30 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Set_Beacon_Effect + */ +public data class ServerboundSetBeaconPacket(val primaryEffect: Int?, val secondaryEffect: Int?) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetBeaconPacket) { + buffer.writeBoolean(value.primaryEffect != null) + if (value.primaryEffect != null) buffer.writeVarInt(value.primaryEffect) + buffer.writeBoolean(value.secondaryEffect != null) + if (value.secondaryEffect != null) buffer.writeVarInt(value.secondaryEffect) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetBeaconPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCarriedItemPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCarriedItemPacket.kt new file mode 100644 index 0000000..d7581cd --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCarriedItemPacket.kt @@ -0,0 +1,26 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket + +public data class ServerboundSetCarriedItemPacket(val slot: Short) : MinecraftPacket { + public companion object Codec : PacketCodec { + private const val MIN_SLOT: Short = 0 + private const val MAX_SLOT: Short = 8 + override fun encode(buffer: BytesBuffer, value: ServerboundSetCarriedItemPacket) { + require(value.slot in MIN_SLOT..MAX_SLOT) { "Carried item slot ${value.slot} must be between $MIN_SLOT and $MAX_SLOT" } + buffer.writeShort(value.slot) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetCarriedItemPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandBlockPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandBlockPacket.kt new file mode 100644 index 0000000..532e022 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandBlockPacket.kt @@ -0,0 +1,46 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.CommandBlockMode +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos + +public data class ServerboundSetCommandBlockPacket( + val location: BlockPos, + val command: String, + val mode: CommandBlockMode, + val trackOutput: Boolean, + val conditional: Boolean, + val automatic: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + private const val FLAG_TRACK_OUTPUT = 0x01 + private const val FLAG_CONDITIONAL = 0x02 + private const val FLAG_AUTOMATIC = 0x04 + + override fun encode(buffer: BytesBuffer, value: ServerboundSetCommandBlockPacket) { + var flags = 0 + if (value.trackOutput) flags = flags or FLAG_TRACK_OUTPUT + if (value.conditional) flags = flags or FLAG_CONDITIONAL + if (value.automatic) flags = flags or FLAG_AUTOMATIC + buffer.writeBlockPos(value.location) + buffer.writeMcString(value.command) + buffer.writeVarInt(value.mode.id) + buffer.writeByte(flags.toByte()) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetCommandBlockPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandMinecartPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandMinecartPacket.kt new file mode 100644 index 0000000..b86b3cf --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCommandMinecartPacket.kt @@ -0,0 +1,34 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundSetCommandMinecartPacket( + val entityId: Int, + val command: String, + /** + * If false, the output of the previous command will not be stored within the command block. + */ + val trackOutput: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetCommandMinecartPacket) { + buffer.writeVarInt(value.entityId) + buffer.writeMcString(value.command) + buffer.writeBoolean(value.trackOutput) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetCommandMinecartPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCreativeModeSlotPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCreativeModeSlotPacket.kt new file mode 100644 index 0000000..7c4f5a6 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetCreativeModeSlotPacket.kt @@ -0,0 +1,26 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.inventory.Slot +import cn.rtast.libmc.protocol.protocol.game.inventory.writeSlot + +public data class ServerboundSetCreativeModeSlotPacket(val slot: Short, val clickedItem: Slot) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetCreativeModeSlotPacket) { + buffer.writeShort(value.slot) + buffer.writeSlot(value.clickedItem) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetCreativeModeSlotPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetGameRulePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetGameRulePacket.kt new file mode 100644 index 0000000..c1a4317 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetGameRulePacket.kt @@ -0,0 +1,29 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writePrefixedArray +import cn.rtast.libmc.protocol.protocol.game.gamerule.GameRuleEntry + +public data class ServerboundSetGameRulePacket(val rules: List) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetGameRulePacket) { + buffer.writePrefixedArray(value.rules) { rule -> + writeMcString(rule.name) + writeMcString(rule.value) + } + } + + override fun decode(buffer: BytesBuffer): ServerboundSetGameRulePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetJigsawBlockPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetJigsawBlockPacket.kt new file mode 100644 index 0000000..81cae69 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetJigsawBlockPacket.kt @@ -0,0 +1,45 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.Identifier +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos +import cn.rtast.libmc.protocol.protocol.game.writeIdentifier + +public data class ServerboundSetJigsawBlockPacket( + val location: BlockPos, + val name: Identifier, + val target: Identifier, + val pool: Identifier, + val finalState: String, + val jointType: String, + val selectionPriority: Int, + val placementPriority: Int, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetJigsawBlockPacket) { + buffer.writeBlockPos(value.location) + buffer.writeIdentifier(value.name) + buffer.writeIdentifier(value.target) + buffer.writeIdentifier(value.pool) + buffer.writeMcString(value.finalState) + buffer.writeMcString(value.jointType) + buffer.writeVarInt(value.selectionPriority) + buffer.writeVarInt(value.placementPriority) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetJigsawBlockPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerMovementFlagPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerMovementFlagPacket.kt new file mode 100644 index 0000000..b91a061 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerMovementFlagPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.player.PlayerPositionFlag + +public data class ServerboundSetPlayerMovementFlagPacket(val flags: PlayerPositionFlag) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetPlayerMovementFlagPacket) { + buffer.writeByte(value.flags.flag) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetPlayerMovementFlagPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionAndRotationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionAndRotationPacket.kt new file mode 100644 index 0000000..2f87912 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionAndRotationPacket.kt @@ -0,0 +1,45 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.player.PlayerPositionFlag + +public data class ServerboundSetPlayerPositionAndRotationPacket( + val x: Double, + /** + * Absolute feet position, normally Head Y - 1.62. + */ + val feetY: Double, + val z: Double, + /** + * Absolute rotation on the X Axis, in degrees. + */ + val yaw: Float, + /** + * Absolute rotation on the Y Axis, in degrees. + */ + val pitch: Float, + val flags: PlayerPositionFlag, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetPlayerPositionAndRotationPacket) { + buffer.writeDouble(value.x) + buffer.writeDouble(value.feetY) + buffer.writeDouble(value.z) + buffer.writeFloat(value.yaw) + buffer.writeFloat(value.pitch) + buffer.writeByte(value.flags.flag) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetPlayerPositionAndRotationPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionPacket.kt new file mode 100644 index 0000000..ac60932 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerPositionPacket.kt @@ -0,0 +1,32 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.player.PlayerPositionFlag + +public data class ServerboundSetPlayerPositionPacket( + val x: Double, + val feetY: Double, + val z: Double, + val flags: PlayerPositionFlag, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetPlayerPositionPacket) { + buffer.writeDouble(value.x) + buffer.writeDouble(value.feetY) + buffer.writeDouble(value.z) + buffer.writeByte(value.flags.flag) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetPlayerPositionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerRotationPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerRotationPacket.kt new file mode 100644 index 0000000..40e7c72 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetPlayerRotationPacket.kt @@ -0,0 +1,30 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.player.PlayerPositionFlag + +public data class ServerboundSetPlayerRotationPacket( + val yaw: Float, + val pitch: Float, + val flags: PlayerPositionFlag, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetPlayerRotationPacket) { + buffer.writeFloat(value.yaw) + buffer.writeFloat(value.pitch) + buffer.writeByte(value.flags.flag) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetPlayerRotationPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetStructureBlockPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetStructureBlockPacket.kt new file mode 100644 index 0000000..4ee530b --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetStructureBlockPacket.kt @@ -0,0 +1,94 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.* +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.protocol.protocol.game.block.* + +public data class ServerboundSetStructureBlockPacket( + val location: BlockPos, + val action: StructureBlockAction, + val mode: StructureBlockMode, + val name: String, + /** + * Between -48 and 48. + */ + val offsetX: Byte, + /** + * Between -48 and 48. + */ + val offsetY: Byte, + /** + * Between -48 and 48. + */ + val offsetZ: Byte, + /** + * Between 0 and 48. + */ + val sizeX: Byte, + /** + * Between 0 and 48. + */ + val sizeY: Byte, + /** + * Between 0 and 48. + */ + val sizeZ: Byte, + val mirror: StructureMirror, + val rotation: StructureRotation, + val metadata: String, + val integrity: Float, + val seed: Long, + val ignoreEntities: Boolean, + val showAir: Boolean, + val showBoundingBox: Boolean, + val strictPlacement: Boolean, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + private const val FLAG_IGNORE_ENTITIES = 0x01 + private const val FLAG_SHOW_AIR = 0x02 + private const val FLAG_SHOW_BOUNDING_BOX = 0x04 + private const val FLAG_STRICT_PLACEMENT = 0x08 + + override fun encode(buffer: BytesBuffer, value: ServerboundSetStructureBlockPacket) { + require(value.offsetX in -48..48) { "offsetX must be between -48 and 48" } + require(value.offsetY in -48..48) { "offsetY must be between -48 and 48" } + require(value.offsetZ in -48..48) { "offsetZ must be between -48 and 48" } + require(value.sizeX in 0..48) { "sizeX must be between 0 and 48" } + require(value.sizeY in 0..48) { "sizeY must be between 0 and 48" } + require(value.sizeZ in 0..48) { "sizeZ must be between 0 and 48" } + require(value.integrity in 0.0f..1.0f) { "integrity must be between 0.0 and 1.0" } + require(value.metadata.length <= 128) { "metadata length must not exceed 128" } + var flags = 0 + if (value.ignoreEntities) flags = flags or FLAG_IGNORE_ENTITIES + if (value.showAir) flags = flags or FLAG_SHOW_AIR + if (value.showBoundingBox) flags = flags or FLAG_SHOW_BOUNDING_BOX + if (value.strictPlacement) flags = flags or FLAG_STRICT_PLACEMENT + buffer.writeBlockPos(value.location) + buffer.writeVarInt(value.action.id) + buffer.writeVarInt(value.mode.id) + buffer.writeMcString(value.name) + buffer.writeByte(value.offsetX) + buffer.writeByte(value.offsetY) + buffer.writeByte(value.offsetZ) + buffer.writeByte(value.sizeX) + buffer.writeByte(value.sizeY) + buffer.writeByte(value.sizeZ) + buffer.writeVarInt(value.mirror.id) + buffer.writeVarInt(value.rotation.id) + buffer.writeMcString(value.metadata) + buffer.writeFloat(value.integrity) + buffer.writeVarLong(value.seed) + buffer.writeByte(flags.toByte()) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetStructureBlockPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetTestBlockPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetTestBlockPacket.kt new file mode 100644 index 0000000..ebbe405 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSetTestBlockPacket.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.TestBlockMode +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos + +public data class ServerboundSetTestBlockPacket( + val position: BlockPos, + val mode: TestBlockMode, + val message: String, +) : MinecraftPacket { + + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSetTestBlockPacket) { + buffer.writeBlockPos(value.position) + buffer.writeVarInt(value.mode.id) + buffer.writeMcString(value.message) + } + + override fun decode(buffer: BytesBuffer): ServerboundSetTestBlockPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignUpdatePacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignUpdatePacket.kt new file mode 100644 index 0000000..05a9f45 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignUpdatePacket.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos + +public data class ServerboundSignUpdatePacket( + val location: BlockPos, + /** + * Whether the updated text is in front or on the back of the sign + */ + val isFrontText: Boolean, + val line1: String, + val line2: String, + val line3: String, + val line4: String, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + private const val MAX_LINE_LENGTH = 384 + + override fun encode(buffer: BytesBuffer, value: ServerboundSignUpdatePacket) { + require(value.line1.length <= MAX_LINE_LENGTH) { "Line 1 exceeds maximum length of $MAX_LINE_LENGTH" } + require(value.line2.length <= MAX_LINE_LENGTH) { "Line 2 exceeds maximum length of $MAX_LINE_LENGTH" } + require(value.line3.length <= MAX_LINE_LENGTH) { "Line 3 exceeds maximum length of $MAX_LINE_LENGTH" } + require(value.line4.length <= MAX_LINE_LENGTH) { "Line 4 exceeds maximum length of $MAX_LINE_LENGTH" } + buffer.writeBlockPos(value.location) + buffer.writeBoolean(value.isFrontText) + buffer.writeMcString(value.line1) + buffer.writeMcString(value.line2) + buffer.writeMcString(value.line3) + buffer.writeMcString(value.line4) + } + + override fun decode(buffer: BytesBuffer): ServerboundSignUpdatePacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignedChatCommandPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignedChatCommandPacket.kt new file mode 100644 index 0000000..40c8c50 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSignedChatCommandPacket.kt @@ -0,0 +1,69 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeMcString +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.signature.ArgumentSignature + +public data class ServerboundSignedChatCommandPacket( + val command: String, + val timestamp: Long, + val salt: Long, + val argumentSignatures: List, + val messageCount: Int, + val acknowledged: ByteArray, + val checksum: Byte, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSignedChatCommandPacket) { + buffer.writeMcString(value.command) + buffer.writeLong(value.timestamp) + buffer.writeLong(value.salt) + buffer.writeVarInt(value.argumentSignatures.size) + value.argumentSignatures.forEach { ArgumentSignature.encode(buffer, it) } + buffer.writeVarInt(value.messageCount) + buffer.writeBytes(value.acknowledged) + buffer.writeByte(value.checksum) + } + + override fun decode(buffer: BytesBuffer): ServerboundSignedChatCommandPacket = + throw UnsupportedOperationException() + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ServerboundSignedChatCommandPacket + + if (timestamp != other.timestamp) return false + if (salt != other.salt) return false + if (messageCount != other.messageCount) return false + if (checksum != other.checksum) return false + if (command != other.command) return false + if (argumentSignatures != other.argumentSignatures) return false + if (!acknowledged.contentEquals(other.acknowledged)) return false + + return true + } + + override fun hashCode(): Int { + var result = timestamp.hashCode() + result = 31 * result + salt.hashCode() + result = 31 * result + messageCount + result = 31 * result + checksum + result = 31 * result + command.hashCode() + result = 31 * result + argumentSignatures.hashCode() + result = 31 * result + acknowledged.contentHashCode() + return result + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSpectatorActionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSpectatorActionPacket.kt new file mode 100644 index 0000000..15bf3d5 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSpectatorActionPacket.kt @@ -0,0 +1,30 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt + +public data class ServerboundSpectatorActionPacket( + /** + * If 0, the player was not targeting an entity. + * Otherwise, the ID of the targeted entity plus 1. + */ + val entityId: Int +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSpectatorActionPacket) { + buffer.writeVarInt(value.entityId) + } + + override fun decode(buffer: BytesBuffer): ServerboundSpectatorActionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSwingPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSwingPacket.kt new file mode 100644 index 0000000..dcbe93d --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundSwingPacket.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.player.Hand + +public data class ServerboundSwingPacket(val hand: Hand) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundSwingPacket) { + buffer.writeVarInt(value.hand.id) + } + + override fun decode(buffer: BytesBuffer): ServerboundSwingPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTeleportToEntityPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTeleportToEntityPacket.kt new file mode 100644 index 0000000..71b6475 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTeleportToEntityPacket.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeUuid +import kotlin.uuid.Uuid + +public data class ServerboundTeleportToEntityPacket(val targetPlayer: Uuid) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundTeleportToEntityPacket) { + buffer.writeUuid(value.targetPlayer) + } + + override fun decode(buffer: BytesBuffer): ServerboundTeleportToEntityPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTestInstanceBlockActionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTestInstanceBlockActionPacket.kt new file mode 100644 index 0000000..dda7c6a --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundTestInstanceBlockActionPacket.kt @@ -0,0 +1,51 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.nbt.NBTCompound +import cn.rtast.libmc.protocol.protocol.game.Identifier +import cn.rtast.libmc.protocol.protocol.game.block.* +import cn.rtast.libmc.protocol.protocol.game.writeIdentifier +import cn.rtast.libmc.protocol.protocol.util.writeNetworkNBTCompound + +public data class ServerboundTestInstanceBlockActionPacket( + val position: BlockPos, + val action: TestInstanceBlockAction, + val test: Identifier?, + val sizeX: Int, + val sizeY: Int, + val sizeZ: Int, + val rotation: TestInstanceRotation, + val ignoreEntities: Boolean, + val status: TestInstanceStatus, + val errorMessage: NBTCompound?, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundTestInstanceBlockActionPacket) { + buffer.writeBlockPos(value.position) + buffer.writeVarInt(value.action.id) + buffer.writeBoolean(value.test != null) + if (value.test != null) buffer.writeIdentifier(value.test) + buffer.writeVarInt(value.sizeX) + buffer.writeVarInt(value.sizeY) + buffer.writeVarInt(value.sizeZ) + buffer.writeVarInt(value.rotation.id) + buffer.writeBoolean(value.ignoreEntities) + buffer.writeVarInt(value.status.id) + buffer.writeBoolean(value.errorMessage != null) + if (value.errorMessage != null) buffer.writeNetworkNBTCompound(value.errorMessage) // TODO to fix + } + + override fun decode(buffer: BytesBuffer): ServerboundTestInstanceBlockActionPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUpdateChatSessionPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUpdateChatSessionPacket.kt new file mode 100644 index 0000000..df4b378 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUpdateChatSessionPacket.kt @@ -0,0 +1,67 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writePrefixedByteArray +import cn.rtast.libmc.common.writeUuid +import kotlin.uuid.Uuid + +public data class ServerboundUpdateChatSessionPacket( + val sessionId: Uuid, + /** + * The time the play session key expires in epoch milliseconds. + */ + val expiresAt: Long, + /** + * A byte array of an X.509-encoded public key. Get this from Mojang API + * ref: https://minecraft.wiki/w/Mojang_API#Get_keypair_for_signature + */ + val publicKey: ByteArray, + /** + * The signature consists of the player UUID, the key expiration timestamp, + * and the public key data. These values are hashed using SHA-1 and signed using Mojang's private RSA key. + */ + val keySignature: ByteArray, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundUpdateChatSessionPacket) { + buffer.writeUuid(value.sessionId) + buffer.writeLong(value.expiresAt) + buffer.writePrefixedByteArray(value.publicKey) + buffer.writePrefixedByteArray(value.keySignature) + } + + override fun decode(buffer: BytesBuffer): ServerboundUpdateChatSessionPacket = + throw UnsupportedOperationException() + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ServerboundUpdateChatSessionPacket + + if (expiresAt != other.expiresAt) return false + if (sessionId != other.sessionId) return false + if (!publicKey.contentEquals(other.publicKey)) return false + if (!keySignature.contentEquals(other.keySignature)) return false + + return true + } + + override fun hashCode(): Int { + var result = expiresAt.hashCode() + result = 31 * result + sessionId.hashCode() + result = 31 * result + publicKey.contentHashCode() + result = 31 * result + keySignature.contentHashCode() + return result + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemOnPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemOnPacket.kt new file mode 100644 index 0000000..bc34bc9 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemOnPacket.kt @@ -0,0 +1,52 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.block.BlockFace +import cn.rtast.libmc.protocol.protocol.game.block.BlockPos +import cn.rtast.libmc.protocol.protocol.game.block.writeBlockPos +import cn.rtast.libmc.protocol.protocol.game.player.Hand + +public data class ServerboundUseItemOnPacket( + val hand: Hand, + val location: BlockPos, + val face: BlockFace, + val cursorPositionX: Float, + val cursorPositionY: Float, + val cursorPositionZ: Float, + val insideBlock: Boolean, + val worldBorderHit: Boolean, + /** + * see [cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket] + */ + val sequence: Int +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundUseItemOnPacket) { + require(value.cursorPositionX in 0.0f..1.0f) { "cursorPositionX must be between 0.0 and 1.0" } + require(value.cursorPositionY in 0.0f..1.0f) { "cursorPositionY must be between 0.0 and 1.0" } + require(value.cursorPositionZ in 0.0f..1.0f) { "cursorPositionZ must be between 0.0 and 1.0" } + buffer.writeVarInt(value.hand.id) + buffer.writeBlockPos(value.location) + buffer.writeVarInt(value.face.id.toInt()) + buffer.writeFloat(value.cursorPositionX) + buffer.writeFloat(value.cursorPositionY) + buffer.writeFloat(value.cursorPositionZ) + buffer.writeBoolean(value.insideBlock) + buffer.writeBoolean(value.worldBorderHit) + buffer.writeVarInt(value.sequence) + } + + override fun decode(buffer: BytesBuffer): ServerboundUseItemOnPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemPacket.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemPacket.kt new file mode 100644 index 0000000..12e36c1 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/play/serverbound/ServerboundUseItemPacket.kt @@ -0,0 +1,36 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.packet.play.serverbound + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.packet.MinecraftPacket +import cn.rtast.libmc.common.writeVarInt +import cn.rtast.libmc.protocol.protocol.game.player.Hand + +public data class ServerboundUseItemPacket( + val hand: Hand, + /** + * see [cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAcknowledgeBlockChangePacket] + */ + val sequence: Int, + val yaw: Float, + val pitch: Float, +) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundUseItemPacket) { + buffer.writeVarInt(value.hand.id) + buffer.writeVarInt(value.sequence) + buffer.writeFloat(value.yaw) + buffer.writeFloat(value.pitch) + } + + override fun decode(buffer: BytesBuffer): ServerboundUseItemPacket = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/status/serverbound/ServerboundPingRequest.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/status/serverbound/ServerboundPingRequest.kt new file mode 100644 index 0000000..440ddc3 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/packet/status/serverbound/ServerboundPingRequest.kt @@ -0,0 +1,23 @@ +/* + * 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 class ServerboundPingRequest(val timestamp: Long) : MinecraftPacket { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ServerboundPingRequest) { + buffer.writeLong(value.timestamp) + } + + override fun decode(buffer: BytesBuffer): ServerboundPingRequest = + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/GameProtocols.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/GameProtocols.kt index f1d6dcd..c83f161 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/GameProtocols.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/GameProtocols.kt @@ -6,10 +6,17 @@ package cn.rtast.libmc.protocol.protocol -import cn.rtast.libmc.protocol.packet.configuration.* +import cn.rtast.libmc.protocol.packet.configuration.clientbound.* +import cn.rtast.libmc.protocol.packet.configuration.serverbound.* import cn.rtast.libmc.protocol.packet.handshake.ServerboundHandshakePacket -import cn.rtast.libmc.protocol.packet.login.* -import cn.rtast.libmc.protocol.packet.play.* +import cn.rtast.libmc.protocol.packet.login.clientbound.ClientboundDisconnectLoginPacket +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.ServerboundLoginStartPacket +import cn.rtast.libmc.protocol.packet.play.clientbound.* +import cn.rtast.libmc.protocol.packet.play.serverbound.* +import cn.rtast.libmc.protocol.packet.status.serverbound.ServerboundPingRequest import cn.rtast.libmc.protocol.protocol.state.ProtocolState import cn.rtast.libmc.protocol.protocol.state.ProtocolStateRegistry @@ -30,6 +37,14 @@ internal object GameProtocols { register(0x03, ClientboundSetCompressionPacket) } register(ProtocolState.PLAY) { + register(0x00, ClientboundDelimiterPacket) + register(0x01, ClientboundSpawnEntityPacket) + register(0x02, ClientboundEntityAnimationPacket) + register(0x03, ClientboundAwardStatisticsPacket) + register(0x04, ClientboundAcknowledgeBlockChangePacket) + register(0x05, ClientboundBlockDestructionPacket) + register(0x06, ClientboundBlockEntityDataPacket) + register(0x20, ClientboundDisconnectPlayPacket) register(0x2c, ClientboundKeepAlivePlayPacket) register(0x31, ClientboundLoginPlayPacket) @@ -45,6 +60,8 @@ internal object GameProtocols { register(0x00, ServerboundHandshakePacket) } register(ProtocolState.CONFIGURATION) { + register(0x00, ServerboundCookieResponsePacket) + register(0x02, ServerboundCustomPayloadPacket) register(0x03, ServerboundAckFinishConfigurationPacket) register(0x04, ServerboundKeepAliveConfigurationPacket) register(0x05, ServerboundPongConfigurationPacket) @@ -55,13 +72,75 @@ internal object GameProtocols { register(0x03, ServerboundLoginAcknowledgedPacket) } register(ProtocolState.PLAY) { - register(0x00, ClientboundDelimiterPacket) - register(0x01, ClientboundSpawnEntityPacket) - register(0x02, ClientboundEntityAnimationPacket) + register(0x00, ServerboundAcceptTeleportationPacket) + register(0x01, ServerboundAttackActionPacket) + register(0x02, ServerboundQueryBlockEntityTagPacket) + register(0x03, ServerboundBundleItemSelectedPacket) + register(0x04, ServerboundChangeDifficultyPacket) + register(0x05, ServerboundChangeGameModePacket) + register(0x06, ServerboundAcknowledgeChatMessagePacket) + register(0x07, ServerboundChatCommandPacket) + register(0x08, ServerboundSignedChatCommandPacket) register(0x09, ServerboundChatMessagePacket) - register(0x2d, ServerboundPongPlayPacket) + register(0x0a, ServerboundUpdateChatSessionPacket) + register(0x0b, ServerboundChunkBatchReceivedPacket) + register(0x0c, ServerboundClientCommandPacket) + register(0x0d, ServerboundClientTickEndPacket) + register(0x0e, ServerboundClientInformationPacket) + register(0x0f, ServerboundCommandSuggestionRequestPacket) register(0x10, ServerboundConfigurationAcknowledgedPacket) + register(0x11, ServerboundContainerClickButtonPacket) + register(0x12, ServerboundContainerClickPacket) + register(0x13, ServerboundContainerClosePacket) + register(0x14, ServerboundChangeContainerSlotStatePacket) + register(0x15, ServerboundCookieResponsePacket) + register(0x16, ServerboundCustomPayloadPacket) + register(0x17, ServerboundDebugSubscriptionRequestPacket) + register(0x18, ServerboundEditBookPacket) + register(0x19, ServerboundQueryEntityTagPacket) + register(0x1a, ServerboundInteractPacket) + register(0x1b, ServerboundJigsawGeneratePacket) register(0x1c, ServerboundKeepAlivePlayPacket) + register(0x1d, ServerboundLockDifficultyPacket) + register(0x1e, ServerboundSetPlayerPositionPacket) + register(0x1f, ServerboundSetPlayerPositionAndRotationPacket) + register(0x20, ServerboundSetPlayerRotationPacket) + register(0x21, ServerboundSetPlayerMovementFlagPacket) + register(0x22, ServerboundMoveVehiclePacket) + register(0x23, ServerboundPaddleBoatPacket) + register(0x24, ServerboundPickItemFromBlockPacket) + register(0x25, ServerboundPickItemFromEntityPacket) + register(0x26, ServerboundPingRequest) + register(0x27, ServerboundPlaceRecipePacket) + register(0x28, ServerboundPlayerAbilitiesPacket) + register(0x29, ServerboundPlayerActionPacket) + register(0x2a, ServerboundPlayerCommandPacket) + register(0x2b, ServerboundPlayerInputPacket) + register(0x2c, ServerboundPlayerLoadedPacket) + register(0x2d, ServerboundPongPlayPacket) + register(0x2e, ServerboundRecipeBookChangeSettingsPacket) + register(0x2f, ServerboundRecipeBookSeenRecipePacket) + register(0x30, ServerboundRenameItemPacket) + register(0x31, ServerboundResourcePackResponsePacket) + register(0x32, ServerboundSeenAdvancementsPacket) + register(0x33, ServerboundSelectTradePacket) + register(0x34, ServerboundSetBeaconPacket) + register(0x35, ServerboundSetCarriedItemPacket) + register(0x36, ServerboundSetCommandBlockPacket) + register(0x37, ServerboundSetCommandMinecartPacket) + register(0x38, ServerboundSetCreativeModeSlotPacket) + register(0x39, ServerboundSetGameRulePacket) + register(0x3a, ServerboundSetJigsawBlockPacket) + register(0x3b, ServerboundSetStructureBlockPacket) + register(0x3c, ServerboundSetTestBlockPacket) + register(0x3d, ServerboundSignUpdatePacket) + register(0x3e, ServerboundSpectatorActionPacket) + register(0x3f, ServerboundSwingPacket) + register(0x40, ServerboundTeleportToEntityPacket) + register(0x41, ServerboundTestInstanceBlockActionPacket) + register(0x42, ServerboundUseItemOnPacket) + register(0x43, ServerboundUseItemPacket) + register(0x44, ServerboundCustomClickActionPacket) } } } \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/Animations.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/Animations.kt similarity index 92% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/Animations.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/Animations.kt index 2912db5..ca59cdb 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/Animations.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/Animations.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.types +package cn.rtast.libmc.protocol.protocol.game /** * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Entity_Animation diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/ChatMode.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/ChatMode.kt new file mode 100644 index 0000000..6a37781 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/ChatMode.kt @@ -0,0 +1,18 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game + +public enum class ChatMode(public val id: Int) { + ENABLED(0), + COMMANDS_ONLY(1), + HIDDEN(2); + + public companion object { + public fun fromID(id: Int): ChatMode = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/StatisticsEntry.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/StatisticsEntry.kt new file mode 100644 index 0000000..4563d5e --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/StatisticsEntry.kt @@ -0,0 +1,35 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game + +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 kotlinx.serialization.Serializable + +/** + * ref: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Award_Statistics + */ +@Serializable +public data class StatisticsEntry(val categoryId: Int, val statisticId: Int, val value: Int) { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: StatisticsEntry) { + buffer.writeVarInt(value.categoryId) + buffer.writeVarInt(value.statisticId) + buffer.writeVarInt(value.value) + } + + override fun decode(buffer: BytesBuffer): StatisticsEntry { + val categoryId = buffer.readVarInt() + val statisticId = buffer.readVarInt() + val value = buffer.readVarInt() + return StatisticsEntry(categoryId, statisticId, value) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/advancement/AdvancementAction.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/advancement/AdvancementAction.kt new file mode 100644 index 0000000..927bf04 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/advancement/AdvancementAction.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.advancement + +public enum class AdvancementAction(public val id: Int) { + OPENED_TAB(0), + CLOSED_SCREEN(1); + + public companion object { + public fun fromID(id: Int): AdvancementAction = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockDestroyStage.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockDestroyStage.kt new file mode 100644 index 0000000..44ca405 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockDestroyStage.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.block + +import kotlinx.serialization.Serializable +import kotlin.jvm.JvmInline + +@JvmInline +@Serializable +public value class BlockDestroyStage internal constructor(public val stage: Byte) { + public val isBroken: Boolean get() = stage !in 0..9 +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockFace.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockFace.kt new file mode 100644 index 0000000..453e68a --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockFace.kt @@ -0,0 +1,21 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.block + +public enum class BlockFace(public val id: Byte) { + DOWN(0), // -Y (Bottom) + UP(1), // +Y (Top) + NORTH(2), // -Z + SOUTH(3), // +Z + WEST(4), // -X + EAST(5); // +X + + public companion object { + public fun fromID(id: Byte): BlockFace = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/BlockPos.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockPos.kt similarity index 96% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/BlockPos.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockPos.kt index 5a909fe..7aa807b 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/BlockPos.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/BlockPos.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.protocol.game +package cn.rtast.libmc.protocol.protocol.game.block import cn.rtast.libmc.common.PacketCodec import cn.rtast.libmc.common.BytesBuffer diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/CommandBlockMode.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/CommandBlockMode.kt new file mode 100644 index 0000000..d8ae839 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/CommandBlockMode.kt @@ -0,0 +1,18 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.block + +public enum class CommandBlockMode(public val id: Int) { + SEQUENCE(0), // Chain + AUTO(1), // Repeating + REDSTONE(2); // Impulse + + public companion object { + public fun fromID(id: Int): CommandBlockMode = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/StructureBlock.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/StructureBlock.kt new file mode 100644 index 0000000..4eb91f1 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/StructureBlock.kt @@ -0,0 +1,51 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.block + +public enum class StructureBlockAction(public val id: Int) { + UPDATE_DATA(0), + SAVE(1), + LOAD(2), + DETECT_SIZE(3); + + public companion object { + public fun fromID(id: Int): StructureBlockAction = entries.first { it.id == id } + } +} + +public enum class StructureBlockMode(public val id: Int) { + SAVE(0), + LOAD(1), + CORNER(2), + DATA(3); + + public companion object { + public fun fromID(id: Int): StructureBlockMode = entries.first { it.id == id } + } +} + +public enum class StructureMirror(public val id: Int) { + NONE(0), + LEFT_RIGHT(1), + FRONT_BACK(2); + + public companion object { + public fun fromID(id: Int): StructureMirror = entries.first { it.id == id } + } +} + +public enum class StructureRotation(public val id: Int) { + NONE(0), + CLOCKWISE_90(1), + CLOCKWISE_180(2), + COUNTERCLOCKWISE_90(3); + + public companion object { + public fun fromID(id: Int): StructureRotation = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/TestBlock.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/TestBlock.kt new file mode 100644 index 0000000..d6e238b --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/block/TestBlock.kt @@ -0,0 +1,54 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.block + +public enum class TestInstanceBlockAction(public val id: Int) { + INIT(0), + QUERY(1), + SET(2), + RESET(3), + SAVE(4), + EXPORT(5), + RUN(6); + + public companion object { + public fun fromID(id: Int): TestInstanceBlockAction = entries.first { it.id == id } + } +} + +public enum class TestBlockMode(public val id: Int) { + START(0), + LOG(1), + FAIL(2), + ACCEPT(3); + + public companion object { + public fun fromID(id: Int): TestBlockMode = entries.first { it.id == id } + } +} + +public enum class TestInstanceRotation(public val id: Int) { + NONE(0), + CLOCKWISE_90(1), + CLOCKWISE_180(2), + COUNTERCLOCKWISE_90(3); + + public companion object { + public fun fromID(id: Int): TestInstanceRotation = entries.first { it.id == id } + } +} + +public enum class TestInstanceStatus(public val id: Int) { + CLEARED(0), + RUNNING(1), + FINISHED(2); + + public companion object { + public fun fromID(id: Int): TestInstanceStatus = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/container/ContainerButton.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/container/ContainerButton.kt new file mode 100644 index 0000000..6520a98 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/container/ContainerButton.kt @@ -0,0 +1,47 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.container + +public object ContainerButton { + public enum class Mouse(public val id: Byte) { + LEFT(0), + RIGHT(1) + } + + public enum class Swap(public val id: Byte) { + HOTBAR_1(0), + HOTBAR_2(1), + HOTBAR_3(2), + HOTBAR_4(3), + HOTBAR_5(4), + HOTBAR_6(5), + HOTBAR_7(6), + HOTBAR_8(7), + HOTBAR_9(8), + OFFHAND(40) + } + + public enum class Drop(public val id: Byte) { + SINGLE_ITEM(0), + FULL_STACK(1) + } + + public enum class Drag(public val id: Byte) { + START_LEFT(0), + ADD_SLOT_LEFT(1), + END_LEFT(2), + + START_RIGHT(4), + ADD_SLOT_RIGHT(5), + END_RIGHT(6), + + START_MIDDLE(8), + ADD_SLOT_MIDDLE(9), + END_MIDDLE(10) + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/debug/DebugSubscriptionType.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/debug/DebugSubscriptionType.kt new file mode 100644 index 0000000..f9682a8 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/debug/DebugSubscriptionType.kt @@ -0,0 +1,26 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.debug + +public enum class DebugSubscriptionType(public val id: Int) { + BEES(0), + BRAIN(1), + GAME_TEST(2), + GAME_TEST_MARKER(3), + GOAL_SELECTOR(4), + NEIGHBOR_UPDATES(5), + PATH_FINDING(6), + RAIDS(7), + STRUCTURES(8), + WORLD_GEN(9); + + public companion object { + public fun fromID(id: Int): DebugSubscriptionType = + requireNotNull(entries.firstOrNull { it.id == id }) { "Unknown debug subscription id $id" } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/gamerule/GameRuleEntry.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/gamerule/GameRuleEntry.kt new file mode 100644 index 0000000..9102192 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/gamerule/GameRuleEntry.kt @@ -0,0 +1,13 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.gamerule + +import kotlinx.serialization.Serializable + +@Serializable +public data class GameRuleEntry(val name: String, val value: String) \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/ChangedSlot.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/ChangedSlot.kt new file mode 100644 index 0000000..f8f6fe7 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/ChangedSlot.kt @@ -0,0 +1,30 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.inventory + +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 kotlinx.serialization.Serializable + +@Serializable +public data class ChangedSlot(val slotNumber: Int, val item: HashedSlot) { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ChangedSlot) { + buffer.writeVarInt(value.slotNumber) + HashedSlot.encode(buffer, value.item) + } + + override fun decode(buffer: BytesBuffer): ChangedSlot { + val slotNumber = buffer.readVarInt() + val item = HashedSlot.decode(buffer) + return ChangedSlot(slotNumber, item) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/HashedSlot.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/HashedSlot.kt new file mode 100644 index 0000000..d61e6ba --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/HashedSlot.kt @@ -0,0 +1,68 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.inventory + +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 kotlinx.serialization.Serializable + +@Serializable +public data class HashedSlot( + val hasItem: Boolean, + val itemId: Int?, + val itemCount: Int?, + val componentsToAdd: List?, + val componentsToRemove: List?, +) { + @Serializable + public data class ComponentAddEntry(val typeId: Int, val dataHash: Int) { + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ComponentAddEntry) { + buffer.writeVarInt(value.typeId) + buffer.writeVarInt(value.dataHash) + } + + override fun decode(buffer: BytesBuffer): ComponentAddEntry { + val typeId = buffer.readVarInt() + val dataHash = buffer.readVarInt() + return ComponentAddEntry(typeId, dataHash) + } + } + } + + public companion object Codec : PacketCodec { + public val EMPTY: HashedSlot = HashedSlot(false, null, null, null, null) + + override fun encode(buffer: BytesBuffer, value: HashedSlot) { + buffer.writeBoolean(value.hasItem) + if (!value.hasItem) return + buffer.writeVarInt(requireNotNull(value.itemId) { "itemId must not be null when hasItem is true" }) + buffer.writeVarInt(requireNotNull(value.itemCount) { "itemCount must not be null when hasItem is true" }) + val addList = value.componentsToAdd ?: emptyList() + buffer.writeVarInt(addList.size) + addList.forEach { ComponentAddEntry.encode(buffer, it) } + val removeList = value.componentsToRemove ?: emptyList() + buffer.writeVarInt(removeList.size) + removeList.forEach { buffer.writeVarInt(it) } + } + + override fun decode(buffer: BytesBuffer): HashedSlot { + val hasItem = buffer.readBoolean() + if (!hasItem) return EMPTY + val itemId = buffer.readVarInt() + val itemCount = buffer.readVarInt() + val addCount = buffer.readVarInt() + val componentsToAdd = List(addCount) { ComponentAddEntry.decode(buffer) } + val removeCount = buffer.readVarInt() + val componentsToRemove = List(removeCount) { buffer.readVarInt() } + return HashedSlot(hasItem, itemId, itemCount, componentsToAdd, componentsToRemove) + } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/InventoryClickType.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/InventoryClickType.kt new file mode 100644 index 0000000..8189ea5 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/InventoryClickType.kt @@ -0,0 +1,23 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.inventory + +public enum class InventoryClickType(public val id: Int) { + PICKUP(0), + QUICK_MOVE(1), + SWAP(2), + CLONE(3), + THROW(4), + QUICK_CRAFT(5), + PICKUP_ALL(6); + + public companion object { + public fun fromID(id: Int): InventoryClickType = + requireNotNull(entries.firstOrNull { it.id == id }) { "Unknown inventory click type id $id" } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/Slot.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/Slot.kt new file mode 100644 index 0000000..81eb037 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/inventory/Slot.kt @@ -0,0 +1,96 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.inventory + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.readPrefixedByteArray +import cn.rtast.libmc.common.readVarInt +import cn.rtast.libmc.common.writeVarInt +import kotlinx.serialization.Serializable + +@Serializable +public data class Slot( + val count: Int, + val itemId: Int?, + val componentsToAdd: List, + val componentsToRemove: List, +) { + @Serializable + public data class DataComponentToAdd(val typeId: Int, val data: ByteArray) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as DataComponentToAdd + + if (typeId != other.typeId) return false + if (!data.contentEquals(other.data)) return false + + return true + } + + override fun hashCode(): Int { + var result = typeId + result = 31 * result + data.contentHashCode() + return result + } + } + + public val isEmpty: Boolean get() = count <= 0 + + public companion object { + /** + * air + */ + public val EMPTY: Slot = Slot( + count = 0, + itemId = null, + componentsToAdd = emptyList(), + componentsToRemove = emptyList() + ) + } +} + +internal fun BytesBuffer.writeSlot(value: Slot) { + if (value.isEmpty) { + writeVarInt(0) + return + } + val itemId = requireNotNull(value.itemId) { "itemId must not be null when slot is not empty" } + writeVarInt(value.count) + writeVarInt(itemId) + writeVarInt(value.componentsToAdd.size) + writeVarInt(value.componentsToRemove.size) + for ((typeId, data) in value.componentsToAdd) { + writeVarInt(typeId) + writeBytes(data) + } + for (typeId in value.componentsToRemove) writeVarInt(typeId) +} + +internal fun BytesBuffer.readSlot(): Slot { + val count = readVarInt() + if (count <= 0) return Slot.EMPTY + val itemId = readVarInt() + val componentsToAddCount = readVarInt() + val componentsToRemoveCount = readVarInt() + val componentsToAdd = ArrayList(componentsToAddCount) + repeat(componentsToAddCount) { + val typeId = readVarInt() + val data = readPrefixedByteArray() + componentsToAdd.add(Slot.DataComponentToAdd(typeId, data)) + } + val componentsToRemove = ArrayList(componentsToRemoveCount) + repeat(componentsToRemoveCount) { componentsToRemove.add(readVarInt()) } + return Slot( + count = count, + itemId = itemId, + componentsToAdd = componentsToAdd, + componentsToRemove = componentsToRemove + ) +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/item/RecipeBookType.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/item/RecipeBookType.kt new file mode 100644 index 0000000..0ee09ad --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/item/RecipeBookType.kt @@ -0,0 +1,19 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.item + +public enum class RecipeBookType(public val id: Int) { + CRAFTING(0), + FURNACE(1), + BLAST_FURNACE(2), + SMOKER(3); + + public companion object { + public fun fromID(id: Int): RecipeBookType = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/Angle.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/math/Angle.kt similarity index 93% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/Angle.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/math/Angle.kt index f9ff414..389c34a 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/Angle.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/math/Angle.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.types +package cn.rtast.libmc.protocol.protocol.game.math import cn.rtast.libmc.common.BytesBuffer import kotlin.jvm.JvmInline diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/LpVec3.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/math/LpVec3.kt similarity index 98% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/LpVec3.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/math/LpVec3.kt index 4b2f551..a01e8a9 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/types/LpVec3.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/math/LpVec3.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.types +package cn.rtast.libmc.protocol.protocol.game.math import cn.rtast.libmc.common.ByteOrder import cn.rtast.libmc.common.BytesBuffer diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/Hand.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/Hand.kt new file mode 100644 index 0000000..c89c329 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/Hand.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +public enum class Hand(public val id: Int) { + MAIN_HAND(0), + OFF_HAND(1); + + public companion object { + public fun fromID(id: Int): Hand = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/InteractType.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/InteractType.kt new file mode 100644 index 0000000..375b145 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/InteractType.kt @@ -0,0 +1,16 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +import cn.rtast.libmc.protocol.protocol.game.math.LpVec3 + +public sealed class InteractType(public val id: Int) { + public data class Interact(val hand: Hand) : InteractType(0) + public data object Attack : InteractType(1) + public data class InteractAt(val targetOffset: LpVec3, val hand: Hand) : InteractType(2) +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/MainHand.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/MainHand.kt new file mode 100644 index 0000000..18147c2 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/MainHand.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +public enum class MainHand(public val id: Int) { + Left(0), + Right(1); + + public companion object { + public fun fromID(id: Int): MainHand = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerAbilities.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerAbilities.kt new file mode 100644 index 0000000..ccab772 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerAbilities.kt @@ -0,0 +1,16 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +public enum class PlayerAbilities(public val flag: Byte) { + FLYING(0x02); + + public companion object { + public fun fromFlag(flag: Byte): PlayerAbilities = entries.first { it.flag == flag } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerActionStatus.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerActionStatus.kt new file mode 100644 index 0000000..da9e2f0 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerActionStatus.kt @@ -0,0 +1,23 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +public enum class PlayerActionStatus(public val id: Int) { + STARTED_DIGGING(0), + CANCELLED_DIGGING(1), + FINISHED_DIGGING(2), + DROP_ITEM_STACK(3), + DROP_ITEM(4), + SHOOT_ARROW_OR_FINISH_EATING(5), + SWAP_ITEM_IN_HAND(6), + STAB(7); + + public companion object { + public fun fromID(id: Int): PlayerActionStatus = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerCommandAction.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerCommandAction.kt new file mode 100644 index 0000000..5dcb5c1 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerCommandAction.kt @@ -0,0 +1,22 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +public enum class PlayerCommandAction(public val id: Int) { + LEAVE_BED(0), + START_SPRINTING(1), + STOP_SPRINTING(2), + START_JUMP_WITH_HORSE(3), + STOP_JUMP_WITH_HORSE(4), + OPEN_VEHICLE_INVENTORY(5), + START_FLYING_WITH_ELYTRA(6); + + public companion object { + public fun fromID(id: Int): PlayerCommandAction = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerPositionFlag.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerPositionFlag.kt new file mode 100644 index 0000000..9a98af0 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/PlayerPositionFlag.kt @@ -0,0 +1,17 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player + +public enum class PlayerPositionFlag(public val flag: Byte) { + ON_GROUND(0x01), + PUSHING_AGAINST_WALL(0x02); + + public companion object { + public fun fromFlag(flag: Byte): PlayerPositionFlag = entries.first { it.flag == flag } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/ParticleStatus.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/ParticleStatus.kt new file mode 100644 index 0000000..ed736c2 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/ParticleStatus.kt @@ -0,0 +1,18 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player.skin + +public enum class ParticleStatus(public val id: Int) { + All(0), + Decreased(1), + Minimal(2); + + public companion object { + public fun fromID(id: Int): ParticleStatus = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/SkinPartFlags.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/SkinPartFlags.kt new file mode 100644 index 0000000..1cb41af --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/player/skin/SkinPartFlags.kt @@ -0,0 +1,21 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.player.skin + +public typealias SkinPartFlag = UByte + +public object SkinPartFlags { + public const val CAPE: SkinPartFlag = 0x01u + public const val JACKET: SkinPartFlag = 0x02u + public const val LEFT_SLEEVE: SkinPartFlag = 0x04u + public const val RIGHT_SLEEVE: SkinPartFlag = 0x08u + public const val RIGHT_PANTS_LEG: SkinPartFlag = 0x10u + public const val LEFT_PANTS_LEG: SkinPartFlag = 0x20u + public const val HAT: SkinPartFlag = 0x40u + public const val ALL: SkinPartFlag = 0x7Fu +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/resources/ResourcePackResult.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/resources/ResourcePackResult.kt new file mode 100644 index 0000000..5c4db1c --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/game/resources/ResourcePackResult.kt @@ -0,0 +1,23 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/6 + */ + + +package cn.rtast.libmc.protocol.protocol.game.resources + +public enum class ResourcePackResult(public val id: Int) { + SuccessfullyDownloaded(0), + Declined(1), + FailedToDownload(2), + Accepted(3), + Downloaded(4), + InvalidURL(5), + FailedToReload(6), + Discarded(7); + + public companion object { + public fun fromID(id: Int): ResourcePackResult = entries.first { it.id == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ArgumentSignature.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ArgumentSignature.kt new file mode 100644 index 0000000..ebdc9bc --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ArgumentSignature.kt @@ -0,0 +1,50 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.signature + +import cn.rtast.libmc.common.BytesBuffer +import cn.rtast.libmc.common.PacketCodec +import cn.rtast.libmc.common.readMcString +import cn.rtast.libmc.common.writeMcString + +public data class ArgumentSignature(val name: String, val signature: ByteArray) { + init { + require(signature.size == 256) + } + + public companion object Codec : PacketCodec { + override fun encode(buffer: BytesBuffer, value: ArgumentSignature) { + buffer.writeMcString(value.name) + buffer.writeBytes(value.signature) + } + + override fun decode(buffer: BytesBuffer): ArgumentSignature { + val name = buffer.readMcString() + val signature = buffer.readBytes(256) + return ArgumentSignature(name, signature) + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ArgumentSignature + + if (name != other.name) return false + if (!signature.contentEquals(other.signature)) return false + + return true + } + + override fun hashCode(): Int { + var result = name.hashCode() + result = 31 * result + signature.contentHashCode() + return result + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ChecksumCalculate.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ChecksumCalculate.kt new file mode 100644 index 0000000..d760d53 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/signature/ChecksumCalculate.kt @@ -0,0 +1,36 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.protocol.signature + +public fun javaArraysHashCode(bytes: ByteArray): Int { + var result = 1 + for (b in bytes) { + result = 31 * result + b.toInt() + } + return result +} + +public fun calculateChatChecksum(signaturesLastSeen: List): Byte { + if (signaturesLastSeen.isEmpty()) return 1 + val hashCodes = IntArray(signaturesLastSeen.size) + for (i in signaturesLastSeen.indices) { + hashCodes[i] = javaArraysHashCode(signaturesLastSeen[i]) + } + val combinedBytes = ByteArray(hashCodes.size * 4) + for (i in hashCodes.indices) { + val h = hashCodes[i] + val offset = i * 4 + combinedBytes[offset] = (h ushr 24).toByte() + combinedBytes[offset + 1] = (h ushr 16).toByte() + combinedBytes[offset + 2] = (h ushr 8).toByte() + combinedBytes[offset + 3] = h.toByte() + } + val finalIntHash = javaArraysHashCode(combinedBytes) + val finalByte = finalIntHash.toByte() + return if (finalByte == 0.toByte()) 1 else finalByte +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/util/nbt.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/util/nbt.kt index c74435f..1706739 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/util/nbt.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/protocol/util/nbt.kt @@ -8,13 +8,13 @@ package cn.rtast.libmc.protocol.protocol.util import cn.rtast.libmc.common.BytesBuffer -import cn.rtast.libmc.nbt.NBTCompound -import cn.rtast.libmc.nbt.readNetworkCompound -import cn.rtast.libmc.nbt.readRootCompound -import cn.rtast.libmc.nbt.toNBTInput +import cn.rtast.libmc.nbt.* internal fun BytesBuffer.readNBTCompound(): NBTCompound = this.toNBTInput().readRootCompound() internal fun BytesBuffer.readNetworkNBTCompound(): NBTCompound = - this.toNBTInput().readNetworkCompound() \ No newline at end of file + this.toNBTInput().readNetworkCompound() + +internal fun BytesBuffer.writeNetworkNBTCompound(value: NBTCompound) = + this.toNBTOutput(NBTTag.CompoundTag(mutableMapOf("" to NBTTag.StringTag("")))).writeNetworkCompound(value) \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/ClientAction.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/ClientAction.kt new file mode 100644 index 0000000..e72d6c8 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/ClientAction.kt @@ -0,0 +1,29 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.registry + +public enum class ClientAction(public val actionID: Int) { + /** + * Sent when the client is ready to respawn after death. + */ + PerformRespawn(0), + + /** + * Sent when the client opens the Statistics menu. + */ + RequestStatus(1), + + /** + * Sent when the client opens the Edit Game Rules menu. + */ + RequestGameRuleValues(2); + + public companion object { + public fun fromID(id: Int): ClientAction = entries.first { it.actionID == id } + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/GameDifficulty.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/GameDifficulty.kt new file mode 100644 index 0000000..5dff327 --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/registry/GameDifficulty.kt @@ -0,0 +1,20 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.registry + +public enum class GameDifficulty(public val id: Byte) { + Peaceful(0), + Easy(1), + Normal(2), + Hard(3); + + public companion object { + public fun fromID(id: Byte): GameDifficulty = entries.first { it.id == id } + public fun fromID(id: Int): GameDifficulty = fromID(id.toByte()) + } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/profile/GameProfile.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/GameProfile.kt similarity index 98% rename from libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/profile/GameProfile.kt rename to libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/GameProfile.kt index 18ca9d7..dca7816 100644 --- a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/profile/GameProfile.kt +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/GameProfile.kt @@ -5,7 +5,7 @@ */ -package cn.rtast.libmc.protocol.profile +package cn.rtast.libmc.protocol.session import cn.rtast.libmc.common.* import kotlinx.serialization.Serializable diff --git a/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/TransactionIdManager.kt b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/TransactionIdManager.kt new file mode 100644 index 0000000..802e5cd --- /dev/null +++ b/libmc-protocol/src/commonMain/kotlin/cn/rtast/libmc/protocol/session/TransactionIdManager.kt @@ -0,0 +1,24 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/9/5 + */ + + +package cn.rtast.libmc.protocol.session + +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock + +public class TransactionIdManager internal constructor() { + private var queryTransactionCounter: Int = 1 + private var commandSuggestionTransactionCounter: Int = 1 + private var queryEntityTagCounter: Int = 1 + private val mutex = Mutex() + + public suspend fun nextQueryId(): Int = mutex.withLock { queryTransactionCounter++ } + public suspend fun nextCommandSuggestionId(): Int = + mutex.withLock { commandSuggestionTransactionCounter++ } + + public suspend fun nextQueryEntityTagId(): Int = mutex.withLock { queryEntityTagCounter++ } +} \ No newline at end of file diff --git a/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt b/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt index 1e33c18..6d91183 100644 --- a/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt +++ b/libmc-protocol/src/commonTest/kotlin/test/TestClient.kt @@ -8,9 +8,7 @@ package test import cn.rtast.libmc.protocol.client.createMinecraftClient -import cn.rtast.libmc.protocol.packet.play.ClientboundDisconnectPlayPacket -import cn.rtast.libmc.protocol.packet.play.ClientboundLoginPlayPacket -import cn.rtast.libmc.protocol.packet.play.ClientboundSystemChatMessagePacket +import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundAwardStatisticsPacket import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import kotlin.test.Test @@ -21,16 +19,7 @@ class TestClient { fun `test client`() = runTest { val cli = createMinecraftClient("127.0.0.1", 25565, "123") cli.launch { cli.connect() } - - cli.on { - println(it) - } - cli.on { - println(it) - } - cli.on { - println(it) - } + cli.on { println(it) } while (true) { } }