From a2f231bf99cef0d30f10533cb65fac5aa0b6bcb4 Mon Sep 17 00:00:00 2001 From: Dries C Date: Wed, 14 Aug 2024 23:45:01 +0200 Subject: [PATCH] Protocol changes for 1.21.20 --- src/CameraInstructionPacket.php | 13 ++- src/ChangeDimensionPacket.php | 6 +- src/ClientboundCloseFormPacket.php | 2 +- src/CurrentStructureFeaturePacket.php | 44 ++++++++ src/DisconnectPacket.php | 16 ++- src/EditorNetworkPacket.php | 8 +- src/InventoryContentPacket.php | 6 +- src/InventorySlotPacket.php | 6 +- src/JigsawStructureDataPacket.php | 50 +++++++++ src/MobArmorEquipmentPacket.php | 6 +- src/PacketHandlerDefaultImplTrait.php | 18 ++- src/PacketHandlerInterface.php | 10 +- src/PacketPool.php | 4 + src/PlayerArmorDamagePacket.php | 12 +- src/ProtocolInfo.php | 10 +- src/ServerboundDiagnosticsPacket.php | 104 ++++++++++++++++++ src/ServerboundLoadingScreenPacket.php | 53 +++++++++ src/SetTitlePacket.php | 5 + src/StopSoundPacket.php | 6 +- src/StructureTemplateDataRequestPacket.php | 1 - src/StructureTemplateDataResponsePacket.php | 1 - src/serializer/PacketSerializer.php | 24 +++- src/types/AbilitiesLayer.php | 1 + src/types/ActorEvent.php | 2 +- src/types/LevelSoundEvent.php | 5 +- src/types/camera/CameraPreset.php | 13 +++ src/types/camera/CameraTargetInstruction.php | 44 ++++++++ src/types/entity/EntityLink.php | 3 +- .../ServerboundLoadingScreenPacketType.php} | 16 ++- src/types/inventory/ContainerUIIds.php | 1 + src/types/inventory/FullContainerName.php | 39 +++++++ ...kRequestAction.php => PredictedResult.php} | 15 +-- src/types/inventory/TriggerType.php | 25 +++++ .../inventory/UseItemTransactionData.php | 14 ++- .../CraftRecipeAutoStackRequestAction.php | 7 +- .../CraftRecipeStackRequestAction.php | 9 +- .../CreativeCreateStackRequestAction.php | 9 +- .../GrindstoneStackRequestAction.php | 9 +- .../stackrequest/ItemStackRequest.php | 2 - .../ItemStackRequestActionType.php | 2 - .../stackrequest/ItemStackRequestSlotInfo.php | 11 +- .../ItemStackResponseContainerInfo.php | 11 +- .../resourcepacks/BehaviorPackInfoEntry.php | 9 +- .../resourcepacks/ResourcePackInfoEntry.php | 7 +- 44 files changed, 588 insertions(+), 71 deletions(-) create mode 100644 src/CurrentStructureFeaturePacket.php create mode 100644 src/JigsawStructureDataPacket.php create mode 100644 src/ServerboundDiagnosticsPacket.php create mode 100644 src/ServerboundLoadingScreenPacket.php create mode 100644 src/types/camera/CameraTargetInstruction.php rename src/types/{inventory/stackrequest/TakeFromBundleStackRequestAction.php => hud/ServerboundLoadingScreenPacketType.php} (52%) create mode 100644 src/types/inventory/FullContainerName.php rename src/types/inventory/{stackrequest/PlaceIntoBundleStackRequestAction.php => PredictedResult.php} (52%) create mode 100644 src/types/inventory/TriggerType.php diff --git a/src/CameraInstructionPacket.php b/src/CameraInstructionPacket.php index 0ca063c2..1f1f3db7 100644 --- a/src/CameraInstructionPacket.php +++ b/src/CameraInstructionPacket.php @@ -17,6 +17,7 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\camera\CameraFadeInstruction; use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstruction; +use pocketmine\network\mcpe\protocol\types\camera\CameraTargetInstruction; class CameraInstructionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_INSTRUCTION_PACKET; @@ -24,15 +25,19 @@ class CameraInstructionPacket extends DataPacket implements ClientboundPacket{ private ?CameraSetInstruction $set; private ?bool $clear; private ?CameraFadeInstruction $fade; + private ?CameraTargetInstruction $target; + private ?bool $removeTarget; /** * @generate-create-func */ - public static function create(?CameraSetInstruction $set, ?bool $clear, ?CameraFadeInstruction $fade) : self{ + public static function create(?CameraSetInstruction $set, ?bool $clear, ?CameraFadeInstruction $fade, ?CameraTargetInstruction $target, ?bool $removeTarget) : self{ $result = new self; $result->set = $set; $result->clear = $clear; $result->fade = $fade; + $result->target = $target; + $result->removeTarget = $removeTarget; return $result; } @@ -42,16 +47,22 @@ public function getClear() : ?bool{ return $this->clear; } public function getFade() : ?CameraFadeInstruction{ return $this->fade; } + public function getTarget() : ?CameraTargetInstruction{ return $this->target; } + protected function decodePayload(PacketSerializer $in) : void{ $this->set = $in->readOptional(fn() => CameraSetInstruction::read($in)); $this->clear = $in->readOptional($in->getBool(...)); $this->fade = $in->readOptional(fn() => CameraFadeInstruction::read($in)); + $this->target = $in->readOptional(fn() => CameraTargetInstruction::read($in)); + $this->removeTarget = $in->readOptional($in->getBool(...)); } protected function encodePayload(PacketSerializer $out) : void{ $out->writeOptional($this->set, fn(CameraSetInstruction $v) => $v->write($out)); $out->writeOptional($this->clear, $out->putBool(...)); $out->writeOptional($this->fade, fn(CameraFadeInstruction $v) => $v->write($out)); + $out->writeOptional($this->target, fn(CameraTargetInstruction $v) => $v->write($out)); + $out->writeOptional($this->removeTarget, $out->putBool(...)); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/ChangeDimensionPacket.php b/src/ChangeDimensionPacket.php index 381d9ff4..6e2cdd34 100644 --- a/src/ChangeDimensionPacket.php +++ b/src/ChangeDimensionPacket.php @@ -23,15 +23,17 @@ class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public int $dimension; public Vector3 $position; public bool $respawn = false; + private ?int $loadingScreenId = null; /** * @generate-create-func */ - public static function create(int $dimension, Vector3 $position, bool $respawn) : self{ + public static function create(int $dimension, Vector3 $position, bool $respawn, ?int $loadingScreenId) : self{ $result = new self; $result->dimension = $dimension; $result->position = $position; $result->respawn = $respawn; + $result->loadingScreenId = $loadingScreenId; return $result; } @@ -39,12 +41,14 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->dimension = $in->getVarInt(); $this->position = $in->getVector3(); $this->respawn = $in->getBool(); + $this->loadingScreenId = $in->readOptional(fn() => $in->getLInt()); } protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->dimension); $out->putVector3($this->position); $out->putBool($this->respawn); + $out->writeOptional($this->loadingScreenId, $out->putLInt(...)); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/ClientboundCloseFormPacket.php b/src/ClientboundCloseFormPacket.php index c6eb8e34..b8bf5b70 100644 --- a/src/ClientboundCloseFormPacket.php +++ b/src/ClientboundCloseFormPacket.php @@ -35,6 +35,6 @@ protected function encodePayload(PacketSerializer $out) : void{ } public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCloseForm($this); + return $handler->handleClientboundCloseForm($this); } } diff --git a/src/CurrentStructureFeaturePacket.php b/src/CurrentStructureFeaturePacket.php new file mode 100644 index 00000000..8558408d --- /dev/null +++ b/src/CurrentStructureFeaturePacket.php @@ -0,0 +1,44 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol; + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +class CurrentStructureFeaturePacket extends DataPacket implements ClientboundPacket{ + public const NETWORK_ID = ProtocolInfo::CURRENT_STRUCTURE_FEATURE_PACKET; + + public string $currentStructureFeature; + + /** + * @generate-create-func + */ + public static function create(string $currentStructureFeature) : self{ + $result = new self; + $result->currentStructureFeature = $currentStructureFeature; + return $result; + } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->currentStructureFeature = $in->getString(); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->putString($this->currentStructureFeature); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleCurrentStructureFeature($this); + } +} diff --git a/src/DisconnectPacket.php b/src/DisconnectPacket.php index 61b854e0..c8724fc2 100644 --- a/src/DisconnectPacket.php +++ b/src/DisconnectPacket.php @@ -21,14 +21,16 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo public int $reason; //TODO: add constants / enum public ?string $message; + public ?string $filteredMessage; /** * @generate-create-func */ - public static function create(int $reason, ?string $message) : self{ + public static function create(int $reason, ?string $message, ?string $filteredMessage) : self{ $result = new self; $result->reason = $reason; $result->message = $message; + $result->filteredMessage = $filteredMessage; return $result; } @@ -38,15 +40,17 @@ public function canBeSentBeforeLogin() : bool{ protected function decodePayload(PacketSerializer $in) : void{ $this->reason = $in->getVarInt(); - $hideDisconnectionScreen = $in->getBool(); - $this->message = $hideDisconnectionScreen ? null : $in->getString(); + $skipMessage = $in->getBool(); + $this->message = $skipMessage ? null : $in->getString(); + $this->filteredMessage = $skipMessage ? null : $in->getString(); } protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->reason); - $out->putBool($this->message === null); - if($this->message !== null){ - $out->putString($this->message); + $out->putBool($skipMessage = $this->message === null && $this->filteredMessage === null); + if(!$skipMessage){ + $out->putString($this->message ?? ""); + $out->putString($this->filteredMessage ?? ""); } } diff --git a/src/EditorNetworkPacket.php b/src/EditorNetworkPacket.php index 5f4d8b36..17bd81d6 100644 --- a/src/EditorNetworkPacket.php +++ b/src/EditorNetworkPacket.php @@ -23,6 +23,7 @@ class EditorNetworkPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::EDITOR_NETWORK_PACKET; + private bool $isRouteToManager; /** @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ private CacheableNbt $payload; @@ -30,8 +31,9 @@ class EditorNetworkPacket extends DataPacket implements ClientboundPacket, Serve * @generate-create-func * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $payload */ - public static function create(CacheableNbt $payload) : self{ + public static function create(bool $isRouteToManager, CacheableNbt $payload) : self{ $result = new self; + $result->isRouteToManager = $isRouteToManager; $result->payload = $payload; return $result; } @@ -39,11 +41,15 @@ public static function create(CacheableNbt $payload) : self{ /** @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ public function getPayload() : CacheableNbt{ return $this->payload; } + public function isRouteToManager() : bool{ return $this->isRouteToManager; } + protected function decodePayload(PacketSerializer $in) : void{ + $this->isRouteToManager = $in->getBool(); $this->payload = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(PacketSerializer $out) : void{ + $out->putBool($this->isRouteToManager); $out->put($this->payload->getEncodedNbt()); } diff --git a/src/InventoryContentPacket.php b/src/InventoryContentPacket.php index 5d15994e..c3cb7702 100644 --- a/src/InventoryContentPacket.php +++ b/src/InventoryContentPacket.php @@ -24,15 +24,17 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ public int $windowId; /** @var ItemStackWrapper[] */ public array $items = []; + public int $dynamicContainerId; /** * @generate-create-func * @param ItemStackWrapper[] $items */ - public static function create(int $windowId, array $items) : self{ + public static function create(int $windowId, array $items, int $dynamicContainerId) : self{ $result = new self; $result->windowId = $windowId; $result->items = $items; + $result->dynamicContainerId = $dynamicContainerId; return $result; } @@ -42,6 +44,7 @@ protected function decodePayload(PacketSerializer $in) : void{ for($i = 0; $i < $count; ++$i){ $this->items[] = $in->getItemStackWrapper(); } + $this->dynamicContainerId = $in->getUnsignedVarInt(); } protected function encodePayload(PacketSerializer $out) : void{ @@ -50,6 +53,7 @@ protected function encodePayload(PacketSerializer $out) : void{ foreach($this->items as $item){ $out->putItemStackWrapper($item); } + $out->putUnsignedVarInt($this->dynamicContainerId); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/InventorySlotPacket.php b/src/InventorySlotPacket.php index 6c214d21..cb860ecc 100644 --- a/src/InventorySlotPacket.php +++ b/src/InventorySlotPacket.php @@ -23,27 +23,31 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ public int $windowId; public int $inventorySlot; public ItemStackWrapper $item; + public int $dynamicContainerId; /** * @generate-create-func */ - public static function create(int $windowId, int $inventorySlot, ItemStackWrapper $item) : self{ + public static function create(int $windowId, int $inventorySlot, ItemStackWrapper $item, int $dynamicContainerId) : self{ $result = new self; $result->windowId = $windowId; $result->inventorySlot = $inventorySlot; $result->item = $item; + $result->dynamicContainerId = $dynamicContainerId; return $result; } protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getUnsignedVarInt(); $this->inventorySlot = $in->getUnsignedVarInt(); + $this->dynamicContainerId = $in->getUnsignedVarInt(); $this->item = $in->getItemStackWrapper(); } protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->windowId); $out->putUnsignedVarInt($this->inventorySlot); + $out->putUnsignedVarInt($this->dynamicContainerId); $out->putItemStackWrapper($this->item); } diff --git a/src/JigsawStructureDataPacket.php b/src/JigsawStructureDataPacket.php new file mode 100644 index 00000000..c6841565 --- /dev/null +++ b/src/JigsawStructureDataPacket.php @@ -0,0 +1,50 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol; + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; + +class JigsawStructureDataPacket extends DataPacket implements ClientboundPacket{ + public const NETWORK_ID = ProtocolInfo::JIGSAW_STRUCTURE_DATA_PACKET; + + /** @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ + private CacheableNbt $nbt; + + /** + * @generate-create-func + * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt + */ + public static function create(CacheableNbt $nbt) : self{ + $result = new self; + $result->nbt = $nbt; + return $result; + } + + /** @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ + public function getNbt() : CacheableNbt{ return $this->nbt; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->nbt = new CacheableNbt($in->getNbtCompoundRoot()); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->put($this->nbt->getEncodedNbt()); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleJigsawStructureData($this); + } +} diff --git a/src/MobArmorEquipmentPacket.php b/src/MobArmorEquipmentPacket.php index e9f56677..947173a0 100644 --- a/src/MobArmorEquipmentPacket.php +++ b/src/MobArmorEquipmentPacket.php @@ -27,17 +27,19 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S public ItemStackWrapper $chest; public ItemStackWrapper $legs; public ItemStackWrapper $feet; + public ItemStackWrapper $body; /** * @generate-create-func */ - public static function create(int $actorRuntimeId, ItemStackWrapper $head, ItemStackWrapper $chest, ItemStackWrapper $legs, ItemStackWrapper $feet) : self{ + public static function create(int $actorRuntimeId, ItemStackWrapper $head, ItemStackWrapper $chest, ItemStackWrapper $legs, ItemStackWrapper $feet, ItemStackWrapper $body) : self{ $result = new self; $result->actorRuntimeId = $actorRuntimeId; $result->head = $head; $result->chest = $chest; $result->legs = $legs; $result->feet = $feet; + $result->body = $body; return $result; } @@ -47,6 +49,7 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->chest = $in->getItemStackWrapper(); $this->legs = $in->getItemStackWrapper(); $this->feet = $in->getItemStackWrapper(); + $this->body = $in->getItemStackWrapper(); } protected function encodePayload(PacketSerializer $out) : void{ @@ -55,6 +58,7 @@ protected function encodePayload(PacketSerializer $out) : void{ $out->putItemStackWrapper($this->chest); $out->putItemStackWrapper($this->legs); $out->putItemStackWrapper($this->feet); + $out->putItemStackWrapper($this->body); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/PacketHandlerDefaultImplTrait.php b/src/PacketHandlerDefaultImplTrait.php index 9cedf25a..3b68ea2d 100644 --- a/src/PacketHandlerDefaultImplTrait.php +++ b/src/PacketHandlerDefaultImplTrait.php @@ -802,7 +802,23 @@ public function handleAwardAchievement(AwardAchievementPacket $packet) : bool{ return false; } - public function handleCloseForm(ClientboundCloseFormPacket $packet) : bool{ + public function handleClientboundCloseForm(ClientboundCloseFormPacket $packet) : bool{ + return false; + } + + public function handleServerboundLoadingScreen(ServerboundLoadingScreenPacket $packet) : bool{ + return false; + } + + public function handleJigsawStructureData(JigsawStructureDataPacket $packet) : bool{ + return false; + } + + public function handleCurrentStructureFeature(CurrentStructureFeaturePacket $packet) : bool{ + return false; + } + + public function handleServerboundDiagnostics(ServerboundDiagnosticsPacket $packet) : bool{ return false; } } diff --git a/src/PacketHandlerInterface.php b/src/PacketHandlerInterface.php index 107c6b2f..c79632fa 100644 --- a/src/PacketHandlerInterface.php +++ b/src/PacketHandlerInterface.php @@ -408,5 +408,13 @@ public function handleSetHud(SetHudPacket $packet) : bool; public function handleAwardAchievement(AwardAchievementPacket $packet) : bool; - public function handleCloseForm(ClientboundCloseFormPacket $packet) : bool; + public function handleClientboundCloseForm(ClientboundCloseFormPacket $packet) : bool; + + public function handleServerboundLoadingScreen(ServerboundLoadingScreenPacket $packet) : bool; + + public function handleJigsawStructureData(JigsawStructureDataPacket $packet) : bool; + + public function handleCurrentStructureFeature(CurrentStructureFeaturePacket $packet) : bool; + + public function handleServerboundDiagnostics(ServerboundDiagnosticsPacket $packet) : bool; } diff --git a/src/PacketPool.php b/src/PacketPool.php index b48bd757..d19df2d7 100644 --- a/src/PacketPool.php +++ b/src/PacketPool.php @@ -229,6 +229,10 @@ public function __construct(){ $this->registerPacket(new SetHudPacket()); $this->registerPacket(new AwardAchievementPacket()); $this->registerPacket(new ClientboundCloseFormPacket()); + $this->registerPacket(new ServerboundLoadingScreenPacket()); + $this->registerPacket(new JigsawStructureDataPacket()); + $this->registerPacket(new CurrentStructureFeaturePacket()); + $this->registerPacket(new ServerboundDiagnosticsPacket()); } public function registerPacket(Packet $packet) : void{ diff --git a/src/PlayerArmorDamagePacket.php b/src/PlayerArmorDamagePacket.php index 96f0a673..b5a10e4b 100644 --- a/src/PlayerArmorDamagePacket.php +++ b/src/PlayerArmorDamagePacket.php @@ -23,21 +23,24 @@ class PlayerArmorDamagePacket extends DataPacket implements ClientboundPacket{ private const FLAG_CHEST = 1; private const FLAG_LEGS = 2; private const FLAG_FEET = 3; + private const FLAG_BODY = 4; private ?int $headSlotDamage; private ?int $chestSlotDamage; private ?int $legsSlotDamage; private ?int $feetSlotDamage; + private ?int $bodySlotDamage; /** * @generate-create-func */ - public static function create(?int $headSlotDamage, ?int $chestSlotDamage, ?int $legsSlotDamage, ?int $feetSlotDamage) : self{ + public static function create(?int $headSlotDamage, ?int $chestSlotDamage, ?int $legsSlotDamage, ?int $feetSlotDamage, ?int $bodySlotDamage) : self{ $result = new self; $result->headSlotDamage = $headSlotDamage; $result->chestSlotDamage = $chestSlotDamage; $result->legsSlotDamage = $legsSlotDamage; $result->feetSlotDamage = $feetSlotDamage; + $result->bodySlotDamage = $bodySlotDamage; return $result; } @@ -49,6 +52,8 @@ public function getLegsSlotDamage() : ?int{ return $this->legsSlotDamage; } public function getFeetSlotDamage() : ?int{ return $this->feetSlotDamage; } + public function getBodySlotDamage() : ?int{ return $this->bodySlotDamage; } + private function maybeReadDamage(int $flags, int $flag, PacketSerializer $in) : ?int{ if(($flags & (1 << $flag)) !== 0){ return $in->getVarInt(); @@ -63,6 +68,7 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->chestSlotDamage = $this->maybeReadDamage($flags, self::FLAG_CHEST, $in); $this->legsSlotDamage = $this->maybeReadDamage($flags, self::FLAG_LEGS, $in); $this->feetSlotDamage = $this->maybeReadDamage($flags, self::FLAG_FEET, $in); + $this->bodySlotDamage = $this->maybeReadDamage($flags, self::FLAG_BODY, $in); } private function composeFlag(?int $field, int $flag) : int{ @@ -80,13 +86,15 @@ protected function encodePayload(PacketSerializer $out) : void{ $this->composeFlag($this->headSlotDamage, self::FLAG_HEAD) | $this->composeFlag($this->chestSlotDamage, self::FLAG_CHEST) | $this->composeFlag($this->legsSlotDamage, self::FLAG_LEGS) | - $this->composeFlag($this->feetSlotDamage, self::FLAG_FEET) + $this->composeFlag($this->feetSlotDamage, self::FLAG_FEET) | + $this->composeFlag($this->bodySlotDamage, self::FLAG_BODY) ); $this->maybeWriteDamage($this->headSlotDamage, $out); $this->maybeWriteDamage($this->chestSlotDamage, $out); $this->maybeWriteDamage($this->legsSlotDamage, $out); $this->maybeWriteDamage($this->feetSlotDamage, $out); + $this->maybeWriteDamage($this->bodySlotDamage, $out); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/ProtocolInfo.php b/src/ProtocolInfo.php index 4df23820..c73ec6de 100644 --- a/src/ProtocolInfo.php +++ b/src/ProtocolInfo.php @@ -32,11 +32,11 @@ private function __construct(){ */ /** Actual Minecraft: PE protocol version */ - public const CURRENT_PROTOCOL = 686; + public const CURRENT_PROTOCOL = 712; /** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - public const MINECRAFT_VERSION = 'v1.21.2'; + public const MINECRAFT_VERSION = 'v1.21.20'; /** Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.21.2'; + public const MINECRAFT_VERSION_NETWORK = '1.21.20'; public const LOGIN_PACKET = 0x01; public const PLAY_STATUS_PACKET = 0x02; @@ -247,4 +247,8 @@ private function __construct(){ public const AWARD_ACHIEVEMENT_PACKET = 0x135; public const CLIENTBOUND_CLOSE_FORM_PACKET = 0x136; + public const SERVERBOUND_LOADING_SCREEN_PACKET = 0x138; + public const JIGSAW_STRUCTURE_DATA_PACKET = 0x139; + public const CURRENT_STRUCTURE_FEATURE_PACKET = 0x13a; + public const SERVERBOUND_DIAGNOSTICS_PACKET = 0x13b; } diff --git a/src/ServerboundDiagnosticsPacket.php b/src/ServerboundDiagnosticsPacket.php new file mode 100644 index 00000000..d2681839 --- /dev/null +++ b/src/ServerboundDiagnosticsPacket.php @@ -0,0 +1,104 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol; + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +class ServerboundDiagnosticsPacket extends DataPacket implements ServerboundPacket{ + public const NETWORK_ID = ProtocolInfo::SERVERBOUND_DIAGNOSTICS_PACKET; + + private float $avgFps; + private float $avgServerSimTickTimeMS; + private float $avgClientSimTickTimeMS; + private float $avgBeginFrameTimeMS; + private float $avgInputTimeMS; + private float $avgRenderTimeMS; + private float $avgEndFrameTimeMS; + private float $avgRemainderTimePercent; + private float $avgUnaccountedTimePercent; + + /** + * @generate-create-func + */ + public static function create( + float $avgFps, + float $avgServerSimTickTimeMS, + float $avgClientSimTickTimeMS, + float $avgBeginFrameTimeMS, + float $avgInputTimeMS, + float $avgRenderTimeMS, + float $avgEndFrameTimeMS, + float $avgRemainderTimePercent, + float $avgUnaccountedTimePercent, + ) : self{ + $result = new self; + $result->avgFps = $avgFps; + $result->avgServerSimTickTimeMS = $avgServerSimTickTimeMS; + $result->avgClientSimTickTimeMS = $avgClientSimTickTimeMS; + $result->avgBeginFrameTimeMS = $avgBeginFrameTimeMS; + $result->avgInputTimeMS = $avgInputTimeMS; + $result->avgRenderTimeMS = $avgRenderTimeMS; + $result->avgEndFrameTimeMS = $avgEndFrameTimeMS; + $result->avgRemainderTimePercent = $avgRemainderTimePercent; + $result->avgUnaccountedTimePercent = $avgUnaccountedTimePercent; + return $result; + } + + public function getAvgFps() : float{ return $this->avgFps; } + + public function getAvgServerSimTickTimeMS() : float{ return $this->avgServerSimTickTimeMS; } + + public function getAvgClientSimTickTimeMS() : float{ return $this->avgClientSimTickTimeMS; } + + public function getAvgBeginFrameTimeMS() : float{ return $this->avgBeginFrameTimeMS; } + + public function getAvgInputTimeMS() : float{ return $this->avgInputTimeMS; } + + public function getAvgRenderTimeMS() : float{ return $this->avgRenderTimeMS; } + + public function getAvgEndFrameTimeMS() : float{ return $this->avgEndFrameTimeMS; } + + public function getAvgRemainderTimePercent() : float{ return $this->avgRemainderTimePercent; } + + public function getAvgUnaccountedTimePercent() : float{ return $this->avgUnaccountedTimePercent; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->avgFps = $in->getLFloat(); + $this->avgServerSimTickTimeMS = $in->getLFloat(); + $this->avgClientSimTickTimeMS = $in->getLFloat(); + $this->avgBeginFrameTimeMS = $in->getLFloat(); + $this->avgInputTimeMS = $in->getLFloat(); + $this->avgRenderTimeMS = $in->getLFloat(); + $this->avgEndFrameTimeMS = $in->getLFloat(); + $this->avgRemainderTimePercent = $in->getLFloat(); + $this->avgUnaccountedTimePercent = $in->getLFloat(); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->putLFloat($this->avgFps); + $out->putLFloat($this->avgServerSimTickTimeMS); + $out->putLFloat($this->avgClientSimTickTimeMS); + $out->putLFloat($this->avgBeginFrameTimeMS); + $out->putLFloat($this->avgInputTimeMS); + $out->putLFloat($this->avgRenderTimeMS); + $out->putLFloat($this->avgEndFrameTimeMS); + $out->putLFloat($this->avgRemainderTimePercent); + $out->putLFloat($this->avgUnaccountedTimePercent); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleServerboundDiagnostics($this); + } +} diff --git a/src/ServerboundLoadingScreenPacket.php b/src/ServerboundLoadingScreenPacket.php new file mode 100644 index 00000000..41cddf86 --- /dev/null +++ b/src/ServerboundLoadingScreenPacket.php @@ -0,0 +1,53 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol; + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\types\hud\ServerboundLoadingScreenPacketType; + +class ServerboundLoadingScreenPacket extends DataPacket implements ServerboundPacket{ + public const NETWORK_ID = ProtocolInfo::SERVERBOUND_LOADING_SCREEN_PACKET; + + private ServerboundLoadingScreenPacketType $loadingScreenType; + private ?int $loadingScreenId = null; + + /** + * @generate-create-func + */ + public static function create(ServerboundLoadingScreenPacketType $loadingScreenType, ?int $loadingScreenId) : self{ + $result = new self; + $result->loadingScreenType = $loadingScreenType; + $result->loadingScreenId = $loadingScreenId; + return $result; + } + + public function getLoadingScreenType() : ServerboundLoadingScreenPacketType{ return $this->loadingScreenType; } + + public function getLoadingScreenId() : ?int{ return $this->loadingScreenId; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->loadingScreenType = ServerboundLoadingScreenPacketType::fromPacket($in->getVarInt()); + $this->loadingScreenId = $in->readOptional(fn() => $in->getLInt()); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->putVarInt($this->loadingScreenType->value); + $out->writeOptional($this->loadingScreenId, $out->putLInt(...)); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleServerboundLoadingScreen($this); + } +} diff --git a/src/SetTitlePacket.php b/src/SetTitlePacket.php index 71e781f1..e8be6ccb 100644 --- a/src/SetTitlePacket.php +++ b/src/SetTitlePacket.php @@ -36,6 +36,7 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ public int $fadeOutTime = 0; public string $xuid = ""; public string $platformOnlineId = ""; + public string $filteredTitleText = ""; /** * @generate-create-func @@ -48,6 +49,7 @@ public static function create( int $fadeOutTime, string $xuid, string $platformOnlineId, + string $filteredTitleText, ) : self{ $result = new self; $result->type = $type; @@ -57,6 +59,7 @@ public static function create( $result->fadeOutTime = $fadeOutTime; $result->xuid = $xuid; $result->platformOnlineId = $platformOnlineId; + $result->filteredTitleText = $filteredTitleText; return $result; } @@ -68,6 +71,7 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->fadeOutTime = $in->getVarInt(); $this->xuid = $in->getString(); $this->platformOnlineId = $in->getString(); + $this->filteredTitleText = $in->getString(); } protected function encodePayload(PacketSerializer $out) : void{ @@ -78,6 +82,7 @@ protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->fadeOutTime); $out->putString($this->xuid); $out->putString($this->platformOnlineId); + $out->putString($this->filteredTitleText); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/StopSoundPacket.php b/src/StopSoundPacket.php index 4794cb73..6ee20d3c 100644 --- a/src/StopSoundPacket.php +++ b/src/StopSoundPacket.php @@ -21,25 +21,29 @@ class StopSoundPacket extends DataPacket implements ClientboundPacket{ public string $soundName; public bool $stopAll; + public bool $stopLegacyMusic; /** * @generate-create-func */ - public static function create(string $soundName, bool $stopAll) : self{ + public static function create(string $soundName, bool $stopAll, bool $stopLegacyMusic) : self{ $result = new self; $result->soundName = $soundName; $result->stopAll = $stopAll; + $result->stopLegacyMusic = $stopLegacyMusic; return $result; } protected function decodePayload(PacketSerializer $in) : void{ $this->soundName = $in->getString(); $this->stopAll = $in->getBool(); + $this->stopLegacyMusic = $in->getBool(); } protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->soundName); $out->putBool($this->stopAll); + $out->putBool($this->stopLegacyMusic); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/StructureTemplateDataRequestPacket.php b/src/StructureTemplateDataRequestPacket.php index 4dd5b1bd..a6f40dcf 100644 --- a/src/StructureTemplateDataRequestPacket.php +++ b/src/StructureTemplateDataRequestPacket.php @@ -24,7 +24,6 @@ class StructureTemplateDataRequestPacket extends DataPacket implements Serverbou public const TYPE_EXPORT_FROM_SAVE_MODE = 1; public const TYPE_EXPORT_FROM_LOAD_MODE = 2; public const TYPE_QUERY_SAVED_STRUCTURE = 3; - public const TYPE_IMPORT = 4; public string $structureTemplateName; public BlockPosition $structureBlockPosition; diff --git a/src/StructureTemplateDataResponsePacket.php b/src/StructureTemplateDataResponsePacket.php index 26bac79a..5704f1ac 100644 --- a/src/StructureTemplateDataResponsePacket.php +++ b/src/StructureTemplateDataResponsePacket.php @@ -23,7 +23,6 @@ class StructureTemplateDataResponsePacket extends DataPacket implements Clientbo public const TYPE_FAILURE = 0; public const TYPE_EXPORT = 1; public const TYPE_QUERY = 2; - public const TYPE_IMPORT = 3; public string $structureTemplateName; /** @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ diff --git a/src/serializer/PacketSerializer.php b/src/serializer/PacketSerializer.php index 40e7542f..e893362d 100644 --- a/src/serializer/PacketSerializer.php +++ b/src/serializer/PacketSerializer.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\serializer; +use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -530,6 +531,17 @@ public function getVector3() : Vector3{ return new Vector3($x, $y, $z); } + /** + * Reads a floating-point Vector2 object with coordinates rounded to 4 decimal places. + * + * @throws BinaryDataException + */ + public function getVector2() : Vector2{ + $x = $this->getLFloat(); + $y = $this->getLFloat(); + return new Vector2($x, $y); + } + /** * Writes a floating-point Vector3 object, or 3x zero if null is given. * @@ -557,6 +569,14 @@ public function putVector3(Vector3 $vector) : void{ $this->putLFloat($vector->z); } + /** + * Writes a floating-point Vector2 object + */ + public function putVector2(Vector2 $vector2) : void{ + $this->putLFloat($vector2->x); + $this->putLFloat($vector2->y); + } + /** * @throws BinaryDataException */ @@ -624,7 +644,8 @@ public function getEntityLink() : EntityLink{ $type = $this->getByte(); $immediate = $this->getBool(); $causedByRider = $this->getBool(); - return new EntityLink($fromActorUniqueId, $toActorUniqueId, $type, $immediate, $causedByRider); + $vehicleAngularVelocity = $this->getLFloat(); + return new EntityLink($fromActorUniqueId, $toActorUniqueId, $type, $immediate, $causedByRider, $vehicleAngularVelocity); } public function putEntityLink(EntityLink $link) : void{ @@ -633,6 +654,7 @@ public function putEntityLink(EntityLink $link) : void{ $this->putByte($link->type); $this->putBool($link->immediate); $this->putBool($link->causedByRider); + $this->putLFloat($link->vehicleAngularVelocity); } /** diff --git a/src/types/AbilitiesLayer.php b/src/types/AbilitiesLayer.php index a95815b4..e9b72efa 100644 --- a/src/types/AbilitiesLayer.php +++ b/src/types/AbilitiesLayer.php @@ -24,6 +24,7 @@ final class AbilitiesLayer{ public const LAYER_SPECTATOR = 2; public const LAYER_COMMANDS = 3; public const LAYER_EDITOR = 4; + public const LAYER_LOADING_SCREEN = 5; public const ABILITY_BUILD = 0; public const ABILITY_MINE = 1; diff --git a/src/types/ActorEvent.php b/src/types/ActorEvent.php index 751c503f..fa1097e8 100644 --- a/src/types/ActorEvent.php +++ b/src/types/ActorEvent.php @@ -67,7 +67,7 @@ private function __construct(){ public const REMOVE_LEASH = 63; //data 1 = cut leash public const CARAVAN_UPDATED = 64; public const CONSUME_TOTEM = 65; - public const PLAYER_CHECK_TREASURE_HUNTER_ACHIEVEMENT = 66; //mojang... + public const DEPRECATED_UPDATE_STRUCTURE_FEATURE = 66; //mojang... public const ENTITY_SPAWN = 67; //used for MinecraftEventing stuff, not needed public const DRAGON_PUKE = 68; //they call this puke particles public const ITEM_ENTITY_MERGE = 69; diff --git a/src/types/LevelSoundEvent.php b/src/types/LevelSoundEvent.php index dbfecaaa..13a836d4 100644 --- a/src/types/LevelSoundEvent.php +++ b/src/types/LevelSoundEvent.php @@ -178,7 +178,7 @@ private function __construct(){ public const IMITATE_EVOCATION_ILLAGER = 152; public const IMITATE_GHAST = 153; public const IMITATE_HUSK = 154; - public const IMITATE_ILLUSION_ILLAGER = 155; + public const IMITATE_MAGMA_CUBE = 156; public const IMITATE_POLAR_BEAR = 157; public const IMITATE_SHULKER = 158; @@ -499,7 +499,7 @@ private function __construct(){ public const VAULT_DEACTIVATE = 507; public const HURT_REDUCED = 508; public const WIND_CHARGE_BURST = 509; - + public const IMITATE_BOGGED = 510; public const ARMOR_CRACK_WOLF = 511; public const ARMOR_BREAK_WOLF = 512; public const ARMOR_REPAIR_WOLF = 513; @@ -519,6 +519,7 @@ private function __construct(){ public const RECORD_CREATOR = 527; public const RECORD_CREATOR_MUSIC_BOX = 528; public const RECORD_PRECIPICE = 529; + public const VAULT_REJECT_REWARDED_PLAYER = 530; //The following aliases are kept for backwards compatibility only public const SCULK_SENSOR_POWER_ON = self::POWER_ON_SCULK_SENSOR; diff --git a/src/types/camera/CameraPreset.php b/src/types/camera/CameraPreset.php index df7b7521..4b3ee8df 100644 --- a/src/types/camera/CameraPreset.php +++ b/src/types/camera/CameraPreset.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\types\camera; +use pocketmine\math\Vector2; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class CameraPreset{ @@ -28,6 +29,8 @@ public function __construct( private ?float $zPosition, private ?float $pitch, private ?float $yaw, + private ?Vector2 $viewOffset, + private ?float $radius, private ?int $audioListenerType, private ?bool $playerEffects ){} @@ -46,6 +49,10 @@ public function getPitch() : ?float{ return $this->pitch; } public function getYaw() : ?float{ return $this->yaw; } + public function getViewOffset() : ?Vector2{ return $this->viewOffset; } + + public function getRadius() : ?float{ return $this->radius; } + public function getAudioListenerType() : ?int{ return $this->audioListenerType; } public function getPlayerEffects() : ?bool{ return $this->playerEffects; } @@ -58,6 +65,8 @@ public static function read(PacketSerializer $in) : self{ $zPosition = $in->readOptional($in->getLFloat(...)); $pitch = $in->readOptional($in->getLFloat(...)); $yaw = $in->readOptional($in->getLFloat(...)); + $viewOffset = $in->readOptional($in->getVector2(...)); + $radius = $in->readOptional($in->getLFloat(...)); $audioListenerType = $in->readOptional($in->getByte(...)); $playerEffects = $in->readOptional($in->getBool(...)); @@ -69,6 +78,8 @@ public static function read(PacketSerializer $in) : self{ $zPosition, $pitch, $yaw, + $viewOffset, + $radius, $audioListenerType, $playerEffects ); @@ -82,6 +93,8 @@ public function write(PacketSerializer $out) : void{ $out->writeOptional($this->zPosition, $out->putLFloat(...)); $out->writeOptional($this->pitch, $out->putLFloat(...)); $out->writeOptional($this->yaw, $out->putLFloat(...)); + $out->writeOptional($this->viewOffset, $out->putVector2(...)); + $out->writeOptional($this->radius, $out->putLFloat(...)); $out->writeOptional($this->audioListenerType, $out->putByte(...)); $out->writeOptional($this->playerEffects, $out->putBool(...)); } diff --git a/src/types/camera/CameraTargetInstruction.php b/src/types/camera/CameraTargetInstruction.php new file mode 100644 index 00000000..90deda16 --- /dev/null +++ b/src/types/camera/CameraTargetInstruction.php @@ -0,0 +1,44 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol\types\camera; + +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +final class CameraTargetInstruction{ + + public function __construct( + private ?Vector3 $targetCenterOffset, + private int $actorUniqueId + ){} + + public function getTargetCenterOffset() : ?Vector3{ return $this->targetCenterOffset; } + + public function getActorUniqueId() : int{ return $this->actorUniqueId; } + + public static function read(PacketSerializer $in) : self{ + $targetCenterOffset = $in->readOptional(fn() => $in->getVector3()); + $actorUniqueId = $in->getActorUniqueId(); + return new self( + $targetCenterOffset, + $actorUniqueId + ); + } + + public function write(PacketSerializer $out) : void{ + $out->writeOptional($this->targetCenterOffset, fn(Vector3 $v) => $out->putVector3($v)); + $out->putActorUniqueId($this->actorUniqueId); + } +} diff --git a/src/types/entity/EntityLink.php b/src/types/entity/EntityLink.php index 1051edee..3397f5fe 100644 --- a/src/types/entity/EntityLink.php +++ b/src/types/entity/EntityLink.php @@ -25,6 +25,7 @@ public function __construct( public int $toActorUniqueId, public int $type, public bool $immediate, - public bool $causedByRider + public bool $causedByRider, + public float $vehicleAngularVelocity ){} } diff --git a/src/types/inventory/stackrequest/TakeFromBundleStackRequestAction.php b/src/types/hud/ServerboundLoadingScreenPacketType.php similarity index 52% rename from src/types/inventory/stackrequest/TakeFromBundleStackRequestAction.php rename to src/types/hud/ServerboundLoadingScreenPacketType.php index cd096eae..6143cde5 100644 --- a/src/types/inventory/stackrequest/TakeFromBundleStackRequestAction.php +++ b/src/types/hud/ServerboundLoadingScreenPacketType.php @@ -12,16 +12,14 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest; +namespace pocketmine\network\mcpe\protocol\types\hud; -use pocketmine\network\mcpe\protocol\types\GetTypeIdFromConstTrait; +use pocketmine\network\mcpe\protocol\types\PacketIntEnumTrait; -/** - * Take an item out of a bundle. - */ -final class TakeFromBundleStackRequestAction extends ItemStackRequestAction{ - use GetTypeIdFromConstTrait; - use TakeOrPlaceStackRequestActionTrait; +enum ServerboundLoadingScreenPacketType : int{ + use PacketIntEnumTrait; - public const ID = ItemStackRequestActionType::TAKE_FROM_BUNDLE; + case UNKNOWN = 0; + case START_LOADING_SCREEN = 1; + case STOP_LOADING_SCREEN = 2; } diff --git a/src/types/inventory/ContainerUIIds.php b/src/types/inventory/ContainerUIIds.php index baef072e..be48b607 100644 --- a/src/types/inventory/ContainerUIIds.php +++ b/src/types/inventory/ContainerUIIds.php @@ -83,4 +83,5 @@ private function __construct(){ public const CREATED_OUTPUT = 60; public const SMITHING_TABLE_TEMPLATE = 61; public const CRAFTER = 62; + public const DYNAMIC = 63; } diff --git a/src/types/inventory/FullContainerName.php b/src/types/inventory/FullContainerName.php new file mode 100644 index 00000000..49b90884 --- /dev/null +++ b/src/types/inventory/FullContainerName.php @@ -0,0 +1,39 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol\types\inventory; + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +final class FullContainerName{ + public function __construct( + private int $containerId, + private int $dynamicId = 0 + ){} + + public function getContainerId() : int{ return $this->containerId; } + + public function getDynamicId() : int{ return $this->dynamicId; } + + public static function read(PacketSerializer $in) : self{ + $containerId = $in->getByte(); + $dynamicId = $in->getLInt(); + return new self($containerId, $dynamicId); + } + + public function write(PacketSerializer $out) : void{ + $out->putByte($this->containerId); + $out->putLInt($this->dynamicId); + } +} diff --git a/src/types/inventory/stackrequest/PlaceIntoBundleStackRequestAction.php b/src/types/inventory/PredictedResult.php similarity index 52% rename from src/types/inventory/stackrequest/PlaceIntoBundleStackRequestAction.php rename to src/types/inventory/PredictedResult.php index 846b4f3c..d21306d8 100644 --- a/src/types/inventory/stackrequest/PlaceIntoBundleStackRequestAction.php +++ b/src/types/inventory/PredictedResult.php @@ -12,16 +12,13 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest; +namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\network\mcpe\protocol\types\GetTypeIdFromConstTrait; +use pocketmine\network\mcpe\protocol\types\PacketIntEnumTrait; -/** - * Insert an item into a bundle. - */ -final class PlaceIntoBundleStackRequestAction extends ItemStackRequestAction{ - use GetTypeIdFromConstTrait; - use TakeOrPlaceStackRequestActionTrait; +enum PredictedResult : int{ + use PacketIntEnumTrait; - public const ID = ItemStackRequestActionType::PLACE_INTO_BUNDLE; + case FAILURE = 0; + case SUCCESS = 1; } diff --git a/src/types/inventory/TriggerType.php b/src/types/inventory/TriggerType.php new file mode 100644 index 00000000..31a7baef --- /dev/null +++ b/src/types/inventory/TriggerType.php @@ -0,0 +1,25 @@ + + * + * BedrockProtocol is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +declare(strict_types=1); + +namespace pocketmine\network\mcpe\protocol\types\inventory; + +use pocketmine\network\mcpe\protocol\types\PacketIntEnumTrait; + +enum TriggerType : int{ + use PacketIntEnumTrait; + + case UNKNOWN = 0; + case PLAYER_INPUT = 1; + case SIMULATION_TICK = 2; +} diff --git a/src/types/inventory/UseItemTransactionData.php b/src/types/inventory/UseItemTransactionData.php index df2568c7..1fd97646 100644 --- a/src/types/inventory/UseItemTransactionData.php +++ b/src/types/inventory/UseItemTransactionData.php @@ -30,6 +30,7 @@ class UseItemTransactionData extends TransactionData{ public const ACTION_BREAK_BLOCK = 2; private int $actionType; + private TriggerType $triggerType; private BlockPosition $blockPosition; private int $face; private int $hotbarSlot; @@ -37,11 +38,14 @@ class UseItemTransactionData extends TransactionData{ private Vector3 $playerPosition; private Vector3 $clickPosition; private int $blockRuntimeId; + private PredictedResult $clientInteractPrediction; public function getActionType() : int{ return $this->actionType; } + public function getTriggerType() : TriggerType{ return $this->triggerType; } + public function getBlockPosition() : BlockPosition{ return $this->blockPosition; } @@ -70,8 +74,11 @@ public function getBlockRuntimeId() : int{ return $this->blockRuntimeId; } + public function getClientInteractPrediction() : PredictedResult{ return $this->clientInteractPrediction; } + protected function decodeData(PacketSerializer $stream) : void{ $this->actionType = $stream->getUnsignedVarInt(); + $this->triggerType = TriggerType::fromPacket($stream->getUnsignedVarInt()); $this->blockPosition = $stream->getBlockPosition(); $this->face = $stream->getVarInt(); $this->hotbarSlot = $stream->getVarInt(); @@ -79,10 +86,12 @@ protected function decodeData(PacketSerializer $stream) : void{ $this->playerPosition = $stream->getVector3(); $this->clickPosition = $stream->getVector3(); $this->blockRuntimeId = $stream->getUnsignedVarInt(); + $this->clientInteractPrediction = PredictedResult::fromPacket($stream->getUnsignedVarInt()); } protected function encodeData(PacketSerializer $stream) : void{ $stream->putUnsignedVarInt($this->actionType); + $stream->putUnsignedVarInt($this->triggerType->value); $stream->putBlockPosition($this->blockPosition); $stream->putVarInt($this->face); $stream->putVarInt($this->hotbarSlot); @@ -90,15 +99,17 @@ protected function encodeData(PacketSerializer $stream) : void{ $stream->putVector3($this->playerPosition); $stream->putVector3($this->clickPosition); $stream->putUnsignedVarInt($this->blockRuntimeId); + $stream->putUnsignedVarInt($this->clientInteractPrediction->value); } /** * @param NetworkInventoryAction[] $actions */ - public static function new(array $actions, int $actionType, BlockPosition $blockPosition, int $face, int $hotbarSlot, ItemStackWrapper $itemInHand, Vector3 $playerPosition, Vector3 $clickPosition, int $blockRuntimeId) : self{ + public static function new(array $actions, int $actionType, TriggerType $triggerType, BlockPosition $blockPosition, int $face, int $hotbarSlot, ItemStackWrapper $itemInHand, Vector3 $playerPosition, Vector3 $clickPosition, int $blockRuntimeId, PredictedResult $clientInteractPrediction) : self{ $result = new self; $result->actions = $actions; $result->actionType = $actionType; + $result->triggerType = $triggerType; $result->blockPosition = $blockPosition; $result->face = $face; $result->hotbarSlot = $hotbarSlot; @@ -106,6 +117,7 @@ public static function new(array $actions, int $actionType, BlockPosition $block $result->playerPosition = $playerPosition; $result->clickPosition = $clickPosition; $result->blockRuntimeId = $blockRuntimeId; + $result->clientInteractPrediction = $clientInteractPrediction; return $result; } } diff --git a/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php index 25831c17..189e8569 100644 --- a/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php @@ -34,6 +34,7 @@ final class CraftRecipeAutoStackRequestAction extends ItemStackRequestAction{ */ final public function __construct( private int $recipeId, + private int $repetitions2, private int $repetitions, private array $ingredients ){} @@ -42,6 +43,8 @@ public function getRecipeId() : int{ return $this->recipeId; } public function getRepetitions() : int{ return $this->repetitions; } + public function getRepetitions2() : int{ return $this->repetitions2; } + /** * @return RecipeIngredient[] * @phpstan-return list @@ -50,16 +53,18 @@ public function getIngredients() : array{ return $this->ingredients; } public static function read(PacketSerializer $in) : self{ $recipeId = $in->readRecipeNetId(); + $repetitions2 = $in->getByte(); $repetitions = $in->getByte(); $ingredients = []; for($i = 0, $count = $in->getByte(); $i < $count; ++$i){ $ingredients[] = $in->getRecipeIngredient(); } - return new self($recipeId, $repetitions, $ingredients); + return new self($recipeId, $repetitions2, $repetitions, $ingredients); } public function write(PacketSerializer $out) : void{ $out->writeRecipeNetId($this->recipeId); + $out->putByte($this->repetitions2); $out->putByte($this->repetitions); $out->putByte(count($this->ingredients)); foreach($this->ingredients as $ingredient){ diff --git a/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php index 272c9873..87ebd06c 100644 --- a/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php @@ -26,17 +26,22 @@ final class CraftRecipeStackRequestAction extends ItemStackRequestAction{ public const ID = ItemStackRequestActionType::CRAFTING_RECIPE; final public function __construct( - private int $recipeId + private int $recipeId, + private int $repetitions ){} public function getRecipeId() : int{ return $this->recipeId; } + public function getRepetitions() : int{ return $this->repetitions; } + public static function read(PacketSerializer $in) : self{ $recipeId = $in->readRecipeNetId(); - return new self($recipeId); + $repetitions = $in->getByte(); + return new self($recipeId, $repetitions); } public function write(PacketSerializer $out) : void{ $out->writeRecipeNetId($this->recipeId); + $out->putByte($this->repetitions); } } diff --git a/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php b/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php index 2304991d..74d09ad8 100644 --- a/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php +++ b/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php @@ -26,17 +26,22 @@ final class CreativeCreateStackRequestAction extends ItemStackRequestAction{ public const ID = ItemStackRequestActionType::CREATIVE_CREATE; public function __construct( - private int $creativeItemId + private int $creativeItemId, + private int $repetitions ){} public function getCreativeItemId() : int{ return $this->creativeItemId; } + public function getRepetitions() : int{ return $this->repetitions; } + public static function read(PacketSerializer $in) : self{ $creativeItemId = $in->readCreativeItemNetId(); - return new self($creativeItemId); + $repetitions = $in->getByte(); + return new self($creativeItemId, $repetitions); } public function write(PacketSerializer $out) : void{ $out->writeCreativeItemNetId($this->creativeItemId); + $out->putByte($this->repetitions); } } diff --git a/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php b/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php index 39016ec1..e161d8f6 100644 --- a/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php +++ b/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php @@ -27,7 +27,8 @@ final class GrindstoneStackRequestAction extends ItemStackRequestAction{ public function __construct( private int $recipeId, - private int $repairCost + private int $repairCost, + private int $repetitions ){} public function getRecipeId() : int{ return $this->recipeId; } @@ -35,15 +36,19 @@ public function getRecipeId() : int{ return $this->recipeId; } /** WARNING: This may be negative */ public function getRepairCost() : int{ return $this->repairCost; } + public function getRepetitions() : int{ return $this->repetitions; } + public static function read(PacketSerializer $in) : self{ $recipeId = $in->readRecipeNetId(); $repairCost = $in->getVarInt(); //WHY!!!! + $repetitions = $in->getByte(); - return new self($recipeId, $repairCost); + return new self($recipeId, $repairCost, $repetitions); } public function write(PacketSerializer $out) : void{ $out->writeRecipeNetId($this->recipeId); $out->putVarInt($this->repairCost); + $out->putByte($this->repetitions); } } diff --git a/src/types/inventory/stackrequest/ItemStackRequest.php b/src/types/inventory/stackrequest/ItemStackRequest.php index 9e8c698e..dd82de79 100644 --- a/src/types/inventory/stackrequest/ItemStackRequest.php +++ b/src/types/inventory/stackrequest/ItemStackRequest.php @@ -58,8 +58,6 @@ private static function readAction(PacketSerializer $in, int $typeId) : ItemStac DestroyStackRequestAction::ID => DestroyStackRequestAction::read($in), CraftingConsumeInputStackRequestAction::ID => CraftingConsumeInputStackRequestAction::read($in), CraftingCreateSpecificResultStackRequestAction::ID => CraftingCreateSpecificResultStackRequestAction::read($in), - PlaceIntoBundleStackRequestAction::ID => PlaceIntoBundleStackRequestAction::read($in), - TakeFromBundleStackRequestAction::ID => TakeFromBundleStackRequestAction::read($in), LabTableCombineStackRequestAction::ID => LabTableCombineStackRequestAction::read($in), BeaconPaymentStackRequestAction::ID => BeaconPaymentStackRequestAction::read($in), MineBlockStackRequestAction::ID => MineBlockStackRequestAction::read($in), diff --git a/src/types/inventory/stackrequest/ItemStackRequestActionType.php b/src/types/inventory/stackrequest/ItemStackRequestActionType.php index e93d26d8..59ddd8f1 100644 --- a/src/types/inventory/stackrequest/ItemStackRequestActionType.php +++ b/src/types/inventory/stackrequest/ItemStackRequestActionType.php @@ -27,8 +27,6 @@ private function __construct(){ public const DESTROY = 4; public const CRAFTING_CONSUME_INPUT = 5; public const CRAFTING_CREATE_SPECIFIC_RESULT = 6; - public const PLACE_INTO_BUNDLE = 7; - public const TAKE_FROM_BUNDLE = 8; public const LAB_TABLE_COMBINE = 9; public const BEACON_PAYMENT = 10; public const MINE_BLOCK = 11; diff --git a/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php b/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php index 64c9a879..09688f51 100644 --- a/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php +++ b/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php @@ -15,29 +15,30 @@ namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName; final class ItemStackRequestSlotInfo{ public function __construct( - private int $containerId, + private FullContainerName $containerName, private int $slotId, private int $stackId ){} - public function getContainerId() : int{ return $this->containerId; } + public function getContainerName() : FullContainerName{ return $this->containerName; } public function getSlotId() : int{ return $this->slotId; } public function getStackId() : int{ return $this->stackId; } public static function read(PacketSerializer $in) : self{ - $containerId = $in->getByte(); + $containerName = FullContainerName::read($in); $slotId = $in->getByte(); $stackId = $in->readItemStackNetIdVariant(); - return new self($containerId, $slotId, $stackId); + return new self($containerName, $slotId, $stackId); } public function write(PacketSerializer $out) : void{ - $out->putByte($this->containerId); + $this->containerName->write($out); $out->putByte($this->slotId); $out->writeItemStackNetIdVariant($this->stackId); } diff --git a/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php b/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php index 4687a8f6..6cd03642 100644 --- a/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php +++ b/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php @@ -15,6 +15,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory\stackresponse; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName; use function count; final class ItemStackResponseContainerInfo{ @@ -22,26 +23,26 @@ final class ItemStackResponseContainerInfo{ * @param ItemStackResponseSlotInfo[] $slots */ public function __construct( - private int $containerId, + private FullContainerName $containerName, private array $slots ){} - public function getContainerId() : int{ return $this->containerId; } + public function getContainerName() : FullContainerName{ return $this->containerName; } /** @return ItemStackResponseSlotInfo[] */ public function getSlots() : array{ return $this->slots; } public static function read(PacketSerializer $in) : self{ - $containerId = $in->getByte(); + $containerName = FullContainerName::read($in); $slots = []; for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ $slots[] = ItemStackResponseSlotInfo::read($in); } - return new self($containerId, $slots); + return new self($containerName, $slots); } public function write(PacketSerializer $out) : void{ - $out->putByte($this->containerId); + $this->containerName->write($out); $out->putUnsignedVarInt(count($this->slots)); foreach($this->slots as $slot){ $slot->write($out); diff --git a/src/types/resourcepacks/BehaviorPackInfoEntry.php b/src/types/resourcepacks/BehaviorPackInfoEntry.php index 8831af76..230f73f6 100644 --- a/src/types/resourcepacks/BehaviorPackInfoEntry.php +++ b/src/types/resourcepacks/BehaviorPackInfoEntry.php @@ -24,7 +24,8 @@ public function __construct( private string $encryptionKey = "", private string $subPackName = "", private string $contentId = "", - private bool $hasScripts = false + private bool $hasScripts = false, + private bool $isAddonPack = false ){} public function getPackId() : string{ @@ -55,6 +56,8 @@ public function hasScripts() : bool{ return $this->hasScripts; } + public function isAddonPack() : bool{ return $this->isAddonPack; } + public function write(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putString($this->version); @@ -63,6 +66,7 @@ public function write(PacketSerializer $out) : void{ $out->putString($this->subPackName); $out->putString($this->contentId); $out->putBool($this->hasScripts); + $out->putBool($this->isAddonPack); } public static function read(PacketSerializer $in) : self{ @@ -73,6 +77,7 @@ public static function read(PacketSerializer $in) : self{ $subPackName = $in->getString(); $contentId = $in->getString(); $hasScripts = $in->getBool(); - return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts); + $isAddonPack = $in->getBool(); + return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts, $isAddonPack); } } diff --git a/src/types/resourcepacks/ResourcePackInfoEntry.php b/src/types/resourcepacks/ResourcePackInfoEntry.php index 60a0e49e..d673e031 100644 --- a/src/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/types/resourcepacks/ResourcePackInfoEntry.php @@ -25,6 +25,7 @@ public function __construct( private string $subPackName = "", private string $contentId = "", private bool $hasScripts = false, + private bool $isAddonPack = false, private bool $isRtxCapable = false ){} @@ -56,6 +57,8 @@ public function hasScripts() : bool{ return $this->hasScripts; } + public function isAddonPack() : bool{ return $this->isAddonPack; } + public function isRtxCapable() : bool{ return $this->isRtxCapable; } public function write(PacketSerializer $out) : void{ @@ -66,6 +69,7 @@ public function write(PacketSerializer $out) : void{ $out->putString($this->subPackName); $out->putString($this->contentId); $out->putBool($this->hasScripts); + $out->putBool($this->isAddonPack); $out->putBool($this->isRtxCapable); } @@ -77,7 +81,8 @@ public static function read(PacketSerializer $in) : self{ $subPackName = $in->getString(); $contentId = $in->getString(); $hasScripts = $in->getBool(); + $isAddonPack = $in->getBool(); $rtxCapable = $in->getBool(); - return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts, $rtxCapable); + return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts, $isAddonPack, $rtxCapable); } }