From 7c19f14cf5d0e55a2d38ec60ae489f8c867969f5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Apr 2023 13:25:08 +0100 Subject: [PATCH] Fixed up offhand handling for ItemStackRequest, fixes #5723 --- .../mcpe/handler/InGamePacketHandler.php | 4 ++-- .../handler/ItemStackContainerIdTranslator.php | 18 ++++++++++++------ .../mcpe/handler/ItemStackRequestExecutor.php | 7 +------ .../mcpe/handler/ItemStackResponseBuilder.php | 6 +----- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 732c8817d..329bcd6ef 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -356,8 +356,8 @@ class InGamePacketHandler extends PacketHandler{ //rejects the transaction. The most common example of this is equipping armor by right-click, which doesn't send //a legacy prediction action for the destination armor slot. foreach($packet->requestChangedSlots as $containerInfo){ - $windowId = ItemStackContainerIdTranslator::translate($containerInfo->getContainerId(), $this->inventoryManager->getCurrentWindowId()); - foreach($containerInfo->getChangedSlotIndexes() as $slot){ + foreach($containerInfo->getChangedSlotIndexes() as $netSlot){ + [$windowId, $slot] = ItemStackContainerIdTranslator::translate($containerInfo->getContainerId(), $this->inventoryManager->getCurrentWindowId(), $netSlot); $inventoryAndSlot = $this->inventoryManager->locateWindowAndSlot($windowId, $slot); if($inventoryAndSlot !== null){ //trigger the normal slot sync logic $this->inventoryManager->onSlotChange($inventoryAndSlot[0], $inventoryAndSlot[1]); diff --git a/src/network/mcpe/handler/ItemStackContainerIdTranslator.php b/src/network/mcpe/handler/ItemStackContainerIdTranslator.php index a0ad3b26c..f9ea9ef5f 100644 --- a/src/network/mcpe/handler/ItemStackContainerIdTranslator.php +++ b/src/network/mcpe/handler/ItemStackContainerIdTranslator.php @@ -33,15 +33,21 @@ final class ItemStackContainerIdTranslator{ //NOOP } - public static function translate(int $containerInterfaceId, int $currentWindowId) : int{ + /** + * @return int[] + * @phpstan-return array{int, int} + * @throws PacketHandlingException + */ + public static function translate(int $containerInterfaceId, int $currentWindowId, int $slotId) : array{ return match($containerInterfaceId){ - ContainerUIIds::ARMOR => ContainerIds::ARMOR, + ContainerUIIds::ARMOR => [ContainerIds::ARMOR, $slotId], ContainerUIIds::HOTBAR, ContainerUIIds::INVENTORY, - ContainerUIIds::COMBINED_HOTBAR_AND_INVENTORY => ContainerIds::INVENTORY, + ContainerUIIds::COMBINED_HOTBAR_AND_INVENTORY => [ContainerIds::INVENTORY, $slotId], - ContainerUIIds::OFFHAND => ContainerIds::OFFHAND, + //TODO: HACK! The client sends an incorrect slot ID for the offhand as of 1.19.70 (though this doesn't really matter since the offhand has only 1 slot anyway) + ContainerUIIds::OFFHAND => [ContainerIds::OFFHAND, 0], ContainerUIIds::ANVIL_INPUT, ContainerUIIds::ANVIL_MATERIAL, @@ -68,7 +74,7 @@ final class ItemStackContainerIdTranslator{ ContainerUIIds::TRADE2_INGREDIENT1, ContainerUIIds::TRADE2_INGREDIENT2, ContainerUIIds::TRADE_INGREDIENT1, - ContainerUIIds::TRADE_INGREDIENT2 => ContainerIds::UI, + ContainerUIIds::TRADE_INGREDIENT2 => [ContainerIds::UI, $slotId], ContainerUIIds::BARREL, ContainerUIIds::BLAST_FURNACE_INGREDIENT, @@ -80,7 +86,7 @@ final class ItemStackContainerIdTranslator{ ContainerUIIds::FURNACE_RESULT, ContainerUIIds::LEVEL_ENTITY, //chest ContainerUIIds::SHULKER_BOX, - ContainerUIIds::SMOKER_INGREDIENT => $currentWindowId, + ContainerUIIds::SMOKER_INGREDIENT => [$currentWindowId, $slotId], //all preview slots are ignored, since the client shouldn't be modifying those directly diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index b7f9b1604..f9532291c 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -111,12 +111,7 @@ class ItemStackRequestExecutor{ * @throws ItemStackRequestProcessException */ protected function getBuilderInventoryAndSlot(ItemStackRequestSlotInfo $info) : array{ - $windowId = ItemStackContainerIdTranslator::translate($info->getContainerId(), $this->inventoryManager->getCurrentWindowId()); - $slotId = $info->getSlotId(); - if($info->getContainerId() === ContainerUIIds::OFFHAND && $slotId === 1){ - //TODO: HACK! The client sends an incorrect slot ID for the offhand as of 1.19.70 - $slotId = 0; - } + [$windowId, $slotId] = ItemStackContainerIdTranslator::translate($info->getContainerId(), $this->inventoryManager->getCurrentWindowId(), $info->getSlotId()); $windowAndSlot = $this->inventoryManager->locateWindowAndSlot($windowId, $slotId); if($windowAndSlot === null){ throw new ItemStackRequestProcessException("No open inventory matches container UI ID: " . $info->getContainerId() . ", slot ID: " . $info->getSlotId()); diff --git a/src/network/mcpe/handler/ItemStackResponseBuilder.php b/src/network/mcpe/handler/ItemStackResponseBuilder.php index 2a55c2d95..09af69f2a 100644 --- a/src/network/mcpe/handler/ItemStackResponseBuilder.php +++ b/src/network/mcpe/handler/ItemStackResponseBuilder.php @@ -53,11 +53,7 @@ final class ItemStackResponseBuilder{ * @phpstan-return array{Inventory, int} */ private function getInventoryAndSlot(int $containerInterfaceId, int $slotId) : ?array{ - if($containerInterfaceId === ContainerUIIds::OFFHAND && $slotId === 1){ - //TODO: HACK! The client sends an incorrect slot ID for the offhand as of 1.19.70 - $slotId = 0; - } - $windowId = ItemStackContainerIdTranslator::translate($containerInterfaceId, $this->inventoryManager->getCurrentWindowId()); + [$windowId, $slotId] = ItemStackContainerIdTranslator::translate($containerInterfaceId, $this->inventoryManager->getCurrentWindowId(), $slotId); $windowAndSlot = $this->inventoryManager->locateWindowAndSlot($windowId, $slotId); if($windowAndSlot === null){ return null;