From de482bcf84c7ea0bcf038cbffd7b5767066fc288 Mon Sep 17 00:00:00 2001 From: AkmalFairuz Date: Thu, 15 Aug 2024 09:34:27 +0700 Subject: [PATCH] 1.21.20 support --- src/CameraInstructionPacket.php | 15 ++- src/ChangeDimensionPacket.php | 9 +- src/ClientboundCloseFormPacket.php | 40 +++++++ src/CurrentStructureFeaturePacket.php | 44 ++++++++ src/DisconnectPacket.php | 16 ++- src/EditorNetworkPacket.php | 10 +- src/InventoryContentPacket.php | 10 +- src/InventorySlotPacket.php | 10 +- src/JigsawStructureDataPacket.php | 50 +++++++++ src/MobArmorEquipmentPacket.php | 10 +- src/PacketHandlerDefaultImplTrait.php | 20 ++++ src/PacketHandlerInterface.php | 10 ++ src/PlayerArmorDamagePacket.php | 13 ++- src/ProtocolInfo.php | 15 ++- src/ServerboundDiagnosticsPacket.php | 104 ++++++++++++++++++ src/ServerboundLoadingScreenPacket.php | 53 +++++++++ src/SetTitlePacket.php | 9 ++ src/StopSoundPacket.php | 10 +- src/serializer/PacketSerializer.php | 28 ++++- src/types/AbilitiesLayer.php | 1 + src/types/camera/CameraPreset.php | 18 +++ src/types/camera/CameraTargetInstruction.php | 44 ++++++++ src/types/entity/EntityLink.php | 3 +- .../ServerboundLoadingScreenPacketType.php | 25 +++++ src/types/inventory/ContainerUIIds.php | 4 + src/types/inventory/FullContainerName.php | 39 +++++++ src/types/inventory/PredictedResult.php | 24 ++++ src/types/inventory/TriggerType.php | 25 +++++ .../inventory/UseItemTransactionData.php | 25 +++++ .../CraftRecipeAutoStackRequestAction.php | 13 ++- .../CraftRecipeStackRequestAction.php | 14 ++- .../CreativeCreateStackRequestAction.php | 14 ++- .../GrindstoneStackRequestAction.php | 14 ++- .../ItemStackResponseContainerInfo.php | 2 + .../resourcepacks/BehaviorPackInfoEntry.php | 16 ++- .../resourcepacks/ResourcePackInfoEntry.php | 14 ++- 36 files changed, 744 insertions(+), 27 deletions(-) create mode 100644 src/ClientboundCloseFormPacket.php 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 create mode 100644 src/types/hud/ServerboundLoadingScreenPacketType.php create mode 100644 src/types/inventory/FullContainerName.php create mode 100644 src/types/inventory/PredictedResult.php create mode 100644 src/types/inventory/TriggerType.php diff --git a/src/CameraInstructionPacket.php b/src/CameraInstructionPacket.php index a5a5ad8d..8031ee09 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 = null, ?bool $removeTarget = null) : self{ $result = new self; $result->set = $set; $result->clear = $clear; $result->fade = $fade; + $result->target = $target; + $result->removeTarget = $removeTarget; return $result; } @@ -46,12 +51,20 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->set = $in->readOptional(fn() => CameraSetInstruction::read($in)); $this->clear = $in->readOptional(fn() => $in->getBool()); $this->fade = $in->readOptional(fn() => CameraFadeInstruction::read($in)); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $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, fn(bool $v) => $out->putBool($v)); $out->writeOptional($this->fade, fn(CameraFadeInstruction $v) => $v->write($out)); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $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..38de0d2d 100644 --- a/src/ChangeDimensionPacket.php +++ b/src/ChangeDimensionPacket.php @@ -23,11 +23,12 @@ 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 = null) : self{ $result = new self; $result->dimension = $dimension; $result->position = $position; @@ -39,12 +40,18 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->dimension = $in->getVarInt(); $this->position = $in->getVector3(); $this->respawn = $in->getBool(); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $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); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->writeOptional($this->loadingScreenId, $out->putLInt(...)); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/ClientboundCloseFormPacket.php b/src/ClientboundCloseFormPacket.php new file mode 100644 index 00000000..41aed5ea --- /dev/null +++ b/src/ClientboundCloseFormPacket.php @@ -0,0 +1,40 @@ + + * + * 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 ClientboundCloseFormPacket extends DataPacket implements ClientboundPacket{ + public const NETWORK_ID = ProtocolInfo::CLIENTBOUND_CLOSE_FORM_PACKET; + + /** + * @generate-create-func + */ + public static function create() : self{ + return new self; + } + + protected function decodePayload(PacketSerializer $in) : void{ + //No payload + } + + protected function encodePayload(PacketSerializer $out) : void{ + //No payload + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleClientboundCloseForm($this); + } +} \ No newline at end of file diff --git a/src/CurrentStructureFeaturePacket.php b/src/CurrentStructureFeaturePacket.php new file mode 100644 index 00000000..b574255f --- /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); + } +} \ No newline at end of file diff --git a/src/DisconnectPacket.php b/src/DisconnectPacket.php index 95812fc8..8293f753 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 = null) : self{ $result = new self; $result->reason = $reason; $result->message = $message; + $result->filteredMessage = $filteredMessage; return $result; } @@ -43,6 +45,9 @@ protected function decodePayload(PacketSerializer $in) : void{ $hideDisconnectionScreen = $in->getBool(); if(!$hideDisconnectionScreen){ $this->message = $in->getString(); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->filteredMessage = $in->getString(); + } } } @@ -50,9 +55,12 @@ protected function encodePayload(PacketSerializer $out) : void{ if($out->getProtocol() >= ProtocolInfo::PROTOCOL_622){ $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 ?? ""); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putString($this->filteredMessage ?? ""); + } } } diff --git a/src/EditorNetworkPacket.php b/src/EditorNetworkPacket.php index 5f4d8b36..664b2047 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 = false; /** @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; } @@ -40,10 +42,16 @@ public static function create(CacheableNbt $payload) : self{ public function getPayload() : CacheableNbt{ return $this->payload; } protected function decodePayload(PacketSerializer $in) : void{ + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->isRouteToManager = $in->getBool(); + } $this->payload = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(PacketSerializer $out) : void{ + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putBool($this->isRouteToManager); + } $out->put($this->payload->getEncodedNbt()); } diff --git a/src/InventoryContentPacket.php b/src/InventoryContentPacket.php index 82573375..7b6b5702 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,9 @@ protected function decodePayload(PacketSerializer $in) : void{ for($i = 0; $i < $count; ++$i){ $this->items[] = ItemStackWrapper::read($in); } + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->dynamicContainerId = $in->getUnsignedVarInt(); + } } protected function encodePayload(PacketSerializer $out) : void{ @@ -50,6 +55,9 @@ protected function encodePayload(PacketSerializer $out) : void{ foreach($this->items as $item){ $item->write($out); } + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putUnsignedVarInt($this->dynamicContainerId); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/InventorySlotPacket.php b/src/InventorySlotPacket.php index 00e49419..89ea7e31 100644 --- a/src/InventorySlotPacket.php +++ b/src/InventorySlotPacket.php @@ -23,15 +23,17 @@ 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; } @@ -39,12 +41,18 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getUnsignedVarInt(); $this->inventorySlot = $in->getUnsignedVarInt(); $this->item = ItemStackWrapper::read($in); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->dynamicContainerId = $in->getUnsignedVarInt(); + } } protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->windowId); $out->putUnsignedVarInt($this->inventorySlot); $this->item->write($out); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putUnsignedVarInt($this->dynamicContainerId); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/JigsawStructureDataPacket.php b/src/JigsawStructureDataPacket.php new file mode 100644 index 00000000..d266a2e2 --- /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); + } +} \ No newline at end of file diff --git a/src/MobArmorEquipmentPacket.php b/src/MobArmorEquipmentPacket.php index 6c4c77c2..d5262cef 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,9 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->chest = ItemStackWrapper::read($in); $this->legs = ItemStackWrapper::read($in); $this->feet = ItemStackWrapper::read($in); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->body = ItemStackWrapper::read($in); + } } protected function encodePayload(PacketSerializer $out) : void{ @@ -55,6 +60,9 @@ protected function encodePayload(PacketSerializer $out) : void{ $this->chest->write($out); $this->legs->write($out); $this->feet->write($out); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->body->write($out); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/PacketHandlerDefaultImplTrait.php b/src/PacketHandlerDefaultImplTrait.php index fb61c459..620a90f9 100644 --- a/src/PacketHandlerDefaultImplTrait.php +++ b/src/PacketHandlerDefaultImplTrait.php @@ -817,4 +817,24 @@ public function handleSetHud(SetHudPacket $packet) : bool{ public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ return false; } + + 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 98afe134..5cd27fcf 100644 --- a/src/PacketHandlerInterface.php +++ b/src/PacketHandlerInterface.php @@ -415,4 +415,14 @@ public function handleSetPlayerInventoryOptions(SetPlayerInventoryOptionsPacket public function handleCraftingEvent(CraftingEventPacket $packet) : bool; public function handleSetHud(SetHudPacket $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/PlayerArmorDamagePacket.php b/src/PlayerArmorDamagePacket.php index 96f0a673..cca36be0 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 = null) : 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,9 @@ 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); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->bodySlotDamage = $this->maybeReadDamage($flags, self::FLAG_BODY, $in); + } } private function composeFlag(?int $field, int $flag) : int{ @@ -87,6 +95,9 @@ protected function encodePayload(PacketSerializer $out) : void{ $this->maybeWriteDamage($this->chestSlotDamage, $out); $this->maybeWriteDamage($this->legsSlotDamage, $out); $this->maybeWriteDamage($this->feetSlotDamage, $out); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->maybeWriteDamage($this->bodySlotDamage, $out); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/ProtocolInfo.php b/src/ProtocolInfo.php index fd92a906..5e5d1ad5 100644 --- a/src/ProtocolInfo.php +++ b/src/ProtocolInfo.php @@ -32,14 +32,16 @@ private function __construct(){ */ /** Actual Minecraft: PE protocol version */ - public const CURRENT_PROTOCOL = 685; + 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.0'; + public const MINECRAFT_VERSION = 'v1.21.20'; /** Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.21.0'; + public const MINECRAFT_VERSION_NETWORK = '1.21.20'; public const BASE_VERSION = '1.18.0'; + public const PROTOCOL_712 = 712; // 1.21.20 + public const PROTOCOL_686 = 686; // 1.21.2 public const PROTOCOL_685 = 685; // 1.21.0 public const PROTOCOL_671 = 671; // 1.20.80 public const PROTOCOL_662 = 662; // 1.20.70 @@ -65,6 +67,8 @@ private function __construct(){ public const PROTOCOL_475 = 475; // v1.18.0 public const COMPATIBLE_PROTOCOL = [ + self::PROTOCOL_712, + self::PROTOCOL_686, self::PROTOCOL_685, self::PROTOCOL_671, self::PROTOCOL_662, @@ -296,4 +300,9 @@ private function __construct(){ public const SET_PLAYER_INVENTORY_OPTIONS_PACKET = 0x133; public const SET_HUD_PACKET = 0x134; + 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..eb955ad6 --- /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); + } +} \ No newline at end of file diff --git a/src/ServerboundLoadingScreenPacket.php b/src/ServerboundLoadingScreenPacket.php new file mode 100644 index 00000000..3d78a6f6 --- /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); + } +} \ No newline at end of file diff --git a/src/SetTitlePacket.php b/src/SetTitlePacket.php index 71e781f1..e4cc3875 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,9 @@ protected function decodePayload(PacketSerializer $in) : void{ $this->fadeOutTime = $in->getVarInt(); $this->xuid = $in->getString(); $this->platformOnlineId = $in->getString(); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->filteredTitleText = $in->getString(); + } } protected function encodePayload(PacketSerializer $out) : void{ @@ -78,6 +84,9 @@ protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->fadeOutTime); $out->putString($this->xuid); $out->putString($this->platformOnlineId); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putString($this->filteredTitleText); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/StopSoundPacket.php b/src/StopSoundPacket.php index 4794cb73..25c40a94 100644 --- a/src/StopSoundPacket.php +++ b/src/StopSoundPacket.php @@ -21,25 +21,33 @@ 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 = false) : 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(); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->stopLegacyMusic = $in->getBool(); + } } protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->soundName); $out->putBool($this->stopAll); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putBool($this->stopLegacyMusic); + } } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/serializer/PacketSerializer.php b/src/serializer/PacketSerializer.php index 86ed7091..a5ae4181 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\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; @@ -593,6 +594,25 @@ public function putSignedBlockPosition(BlockPosition $blockPosition) : void{ $this->putVarInt($blockPosition->getZ()); } + /** + * 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 Vector2 object + */ + public function putVector2(Vector2 $vector2) : void{ + $this->putLFloat($vector2->x); + $this->putLFloat($vector2->y); + } + /** * Reads a floating-point Vector3 object with coordinates rounded to 4 decimal places. * @@ -699,7 +719,10 @@ public function getEntityLink() : EntityLink{ $type = $this->getByte(); $immediate = $this->getBool(); $causedByRider = $this->getBool(); - return new EntityLink($fromActorUniqueId, $toActorUniqueId, $type, $immediate, $causedByRider); + if($this->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $vehicleAngularVelocity = $this->getLFloat(); + } + return new EntityLink($fromActorUniqueId, $toActorUniqueId, $type, $immediate, $causedByRider, $vehicleAngularVelocity ?? 0.0); } public function putEntityLink(EntityLink $link) : void{ @@ -708,6 +731,9 @@ public function putEntityLink(EntityLink $link) : void{ $this->putByte($link->type); $this->putBool($link->immediate); $this->putBool($link->causedByRider); + if($this->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->putLFloat($link->vehicleAngularVelocity); + } } /** diff --git a/src/types/AbilitiesLayer.php b/src/types/AbilitiesLayer.php index 39a02065..48b26390 100644 --- a/src/types/AbilitiesLayer.php +++ b/src/types/AbilitiesLayer.php @@ -25,6 +25,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/camera/CameraPreset.php b/src/types/camera/CameraPreset.php index b019d4e8..44769fca 100644 --- a/src/types/camera/CameraPreset.php +++ b/src/types/camera/CameraPreset.php @@ -14,6 +14,8 @@ namespace pocketmine\network\mcpe\protocol\types\camera; +use pocketmine\math\Vector2; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class CameraPreset{ @@ -28,6 +30,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 +50,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 +66,10 @@ public static function read(PacketSerializer $in) : self{ $zPosition = $in->readOptional(fn() => $in->getLFloat()); $pitch = $in->readOptional(fn() => $in->getLFloat()); $yaw = $in->readOptional(fn() => $in->getLFloat()); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $viewOffset = $in->readOptional(fn() => $in->getVector2()); + $radius = $in->readOptional(fn() => $in->getLFloat()); + } $audioListenerType = $in->readOptional(fn() => $in->getByte()); $playerEffects = $in->readOptional(fn() => $in->getBool()); @@ -69,6 +81,8 @@ public static function read(PacketSerializer $in) : self{ $zPosition, $pitch, $yaw, + $viewOffset ?? null, + $radius ?? null, $audioListenerType, $playerEffects ); @@ -82,6 +96,10 @@ public function write(PacketSerializer $out) : void{ $out->writeOptional($this->zPosition, fn(float $v) => $out->putLFloat($v)); $out->writeOptional($this->pitch, fn(float $v) => $out->putLFloat($v)); $out->writeOptional($this->yaw, fn(float $v) => $out->putLFloat($v)); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->writeOptional($this->viewOffset, fn(Vector2 $v) => $out->putVector2($v)); + $out->writeOptional($this->radius, fn(float $v) => $out->putLFloat($v)); + } $out->writeOptional($this->audioListenerType, fn(int $v) => $out->putByte($v)); $out->writeOptional($this->playerEffects, fn(bool $v) => $out->putBool($v)); } diff --git a/src/types/camera/CameraTargetInstruction.php b/src/types/camera/CameraTargetInstruction.php new file mode 100644 index 00000000..eb02eca3 --- /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); + } +} \ No newline at end of file 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/hud/ServerboundLoadingScreenPacketType.php b/src/types/hud/ServerboundLoadingScreenPacketType.php new file mode 100644 index 00000000..cb7a97aa --- /dev/null +++ b/src/types/hud/ServerboundLoadingScreenPacketType.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\hud; + +use pocketmine\network\mcpe\protocol\types\PacketIntEnumTrait; + +enum ServerboundLoadingScreenPacketType : int{ + use PacketIntEnumTrait; + + case UNKNOWN = 0; + case START_LOADING_SCREEN = 1; + case STOP_LOADING_SCREEN = 2; +} \ No newline at end of file diff --git a/src/types/inventory/ContainerUIIds.php b/src/types/inventory/ContainerUIIds.php index 13bc0381..79e94dc6 100644 --- a/src/types/inventory/ContainerUIIds.php +++ b/src/types/inventory/ContainerUIIds.php @@ -86,6 +86,7 @@ private function __construct(){ public const CREATED_OUTPUT = 60; public const SMITHING_TABLE_TEMPLATE = 61; public const CRAFTER = 62; + public const DYNAMIC = 63; public static function write(PacketSerializer $out, int $containerId) : void{ if($out->getProtocol() < ProtocolInfo::PROTOCOL_560){ @@ -100,6 +101,9 @@ public static function write(PacketSerializer $out, int $containerId) : void{ } public static function read(PacketSerializer $in) : ?int{ + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + return FullContainerName::read($in)->getContainerId(); + } $containerId = $in->getByte(); if($in->getProtocol() < ProtocolInfo::PROTOCOL_560 && $containerId >= self::RECIPE_BOOK){ diff --git a/src/types/inventory/FullContainerName.php b/src/types/inventory/FullContainerName.php new file mode 100644 index 00000000..4ebeee77 --- /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); + } +} \ No newline at end of file diff --git a/src/types/inventory/PredictedResult.php b/src/types/inventory/PredictedResult.php new file mode 100644 index 00000000..3cfa9c57 --- /dev/null +++ b/src/types/inventory/PredictedResult.php @@ -0,0 +1,24 @@ + + * + * 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 PredictedResult : int{ + use PacketIntEnumTrait; + + case FAILURE = 0; + case SUCCESS = 1; +} \ No newline at end of file diff --git a/src/types/inventory/TriggerType.php b/src/types/inventory/TriggerType.php new file mode 100644 index 00000000..d1c04292 --- /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; +} \ No newline at end of file diff --git a/src/types/inventory/UseItemTransactionData.php b/src/types/inventory/UseItemTransactionData.php index cbae5c45..78498302 100644 --- a/src/types/inventory/UseItemTransactionData.php +++ b/src/types/inventory/UseItemTransactionData.php @@ -16,6 +16,7 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\GetTypeIdFromConstTrait; @@ -30,6 +31,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 +39,16 @@ 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 +77,15 @@ public function getBlockRuntimeId() : int{ return $this->blockRuntimeId; } + public function getClientInteractPrediction(): PredictedResult{ + return $this->clientInteractPrediction; + } + protected function decodeData(PacketSerializer $stream) : void{ $this->actionType = $stream->getUnsignedVarInt(); + if($stream->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->triggerType = TriggerType::fromPacket($this->actionType); + } $this->blockPosition = $stream->getBlockPosition(); $this->face = $stream->getVarInt(); $this->hotbarSlot = $stream->getVarInt(); @@ -79,10 +93,18 @@ protected function decodeData(PacketSerializer $stream) : void{ $this->playerPosition = $stream->getVector3(); $this->clickPosition = $stream->getVector3(); $this->blockRuntimeId = $stream->getUnsignedVarInt(); + if($stream->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $this->clientInteractPrediction = PredictedResult::fromPacket($stream->getUnsignedVarInt()); + }else{ + $this->clientInteractPrediction = PredictedResult::SUCCESS; + } } protected function encodeData(PacketSerializer $stream) : void{ $stream->putUnsignedVarInt($this->actionType); + if($stream->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $stream->putUnsignedVarInt($this->triggerType->value); + } $stream->putBlockPosition($this->blockPosition); $stream->putVarInt($this->face); $stream->putVarInt($this->hotbarSlot); @@ -90,6 +112,9 @@ protected function encodeData(PacketSerializer $stream) : void{ $stream->putVector3($this->playerPosition); $stream->putVector3($this->clickPosition); $stream->putUnsignedVarInt($this->blockRuntimeId); + if($stream->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $stream->putUnsignedVarInt($this->clientInteractPrediction->value); + } } /** diff --git a/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php index 7d78f8f3..063dd497 100644 --- a/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php @@ -35,6 +35,7 @@ final class CraftRecipeAutoStackRequestAction extends ItemStackRequestAction{ */ final public function __construct( private int $recipeId, + private int $repetitions2, private int $repetitions, private array $ingredients ){} @@ -43,6 +44,10 @@ 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 @@ -51,6 +56,9 @@ public function getIngredients() : array{ return $this->ingredients; } public static function read(PacketSerializer $in) : self{ $recipeId = $in->readGenericTypeNetworkId(); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $repetitions2 = $in->getByte(); + } $repetitions = $in->getByte(); $ingredients = []; if($in->getProtocol() >= ProtocolInfo::PROTOCOL_557){ @@ -58,11 +66,14 @@ public static function read(PacketSerializer $in) : self{ $ingredients[] = $in->getRecipeIngredient(); } } - return new self($recipeId, $repetitions, $ingredients); + return new self($recipeId, $repetitions2 ?? 0, $repetitions, $ingredients); } public function write(PacketSerializer $out) : void{ $out->writeGenericTypeNetworkId($this->recipeId); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putByte($this->repetitions2); + } $out->putByte($this->repetitions); if($out->getProtocol() >= ProtocolInfo::PROTOCOL_557){ $out->putByte(count($this->ingredients)); diff --git a/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php index c497c074..7457ee86 100644 --- a/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\GetTypeIdFromConstTrait; @@ -26,17 +27,26 @@ 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->readGenericTypeNetworkId(); - return new self($recipeId); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $repetitions = $in->getByte(); + } + return new self($recipeId, $repetitions ?? 0); } public function write(PacketSerializer $out) : void{ $out->writeGenericTypeNetworkId($this->recipeId); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putByte($this->repetitions); + } } } diff --git a/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php b/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php index d14e7f84..069a8ac4 100644 --- a/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php +++ b/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\GetTypeIdFromConstTrait; @@ -26,17 +27,26 @@ 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->readGenericTypeNetworkId(); - return new self($creativeItemId); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $repetitions = $in->getByte(); + } + return new self($creativeItemId, $repetitions ?? 0); } public function write(PacketSerializer $out) : void{ $out->writeGenericTypeNetworkId($this->creativeItemId); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putByte($this->repetitions); + } } } diff --git a/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php b/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php index 5994a555..785ddbcc 100644 --- a/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php +++ b/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory\stackrequest; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\GetTypeIdFromConstTrait; @@ -27,7 +28,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 +37,23 @@ 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->readGenericTypeNetworkId(); $repairCost = $in->getVarInt(); //WHY!!!! + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $repetitions = $in->getByte(); + } - return new self($recipeId, $repairCost); + return new self($recipeId, $repairCost, $repetitions ?? 0); } public function write(PacketSerializer $out) : void{ $out->writeGenericTypeNetworkId($this->recipeId); $out->putVarInt($this->repairCost); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putByte($this->repetitions); + } } } diff --git a/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php b/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php index 06c415f3..d95dcf79 100644 --- a/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php +++ b/src/types/inventory/stackresponse/ItemStackResponseContainerInfo.php @@ -14,8 +14,10 @@ namespace pocketmine\network\mcpe\protocol\types\inventory\stackresponse; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds; +use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName; use function count; final class ItemStackResponseContainerInfo{ diff --git a/src/types/resourcepacks/BehaviorPackInfoEntry.php b/src/types/resourcepacks/BehaviorPackInfoEntry.php index 8831af76..7d049224 100644 --- a/src/types/resourcepacks/BehaviorPackInfoEntry.php +++ b/src/types/resourcepacks/BehaviorPackInfoEntry.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\types\resourcepacks; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class BehaviorPackInfoEntry{ @@ -24,7 +25,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 +57,10 @@ 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 +69,9 @@ public function write(PacketSerializer $out) : void{ $out->putString($this->subPackName); $out->putString($this->contentId); $out->putBool($this->hasScripts); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putBool($this->isAddonPack); + } } public static function read(PacketSerializer $in) : self{ @@ -73,6 +82,9 @@ 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); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $isAddonPack = $in->getBool(); + } + return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts, $isAddonPack ?? false); } } diff --git a/src/types/resourcepacks/ResourcePackInfoEntry.php b/src/types/resourcepacks/ResourcePackInfoEntry.php index 60a0e49e..db24f84d 100644 --- a/src/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/types/resourcepacks/ResourcePackInfoEntry.php @@ -14,6 +14,7 @@ namespace pocketmine\network\mcpe\protocol\types\resourcepacks; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ResourcePackInfoEntry{ @@ -25,6 +26,7 @@ public function __construct( private string $subPackName = "", private string $contentId = "", private bool $hasScripts = false, + private bool $isAddonPack = false, private bool $isRtxCapable = false ){} @@ -56,6 +58,10 @@ 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 +72,9 @@ public function write(PacketSerializer $out) : void{ $out->putString($this->subPackName); $out->putString($this->contentId); $out->putBool($this->hasScripts); + if($out->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $out->putBool($this->isAddonPack); + } $out->putBool($this->isRtxCapable); } @@ -77,7 +86,10 @@ public static function read(PacketSerializer $in) : self{ $subPackName = $in->getString(); $contentId = $in->getString(); $hasScripts = $in->getBool(); + if($in->getProtocol() >= ProtocolInfo::PROTOCOL_712){ + $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 ?? false, $rtxCapable); } }