From 4f25ab10e99308fbd9b7f977405f4d52b2695a5e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Feb 2022 16:45:21 +0000 Subject: [PATCH] InventoryManager: Do not sync slots the client correctly predicted during using items closes #4825 --- src/network/mcpe/InventoryManager.php | 13 +++++++++++++ src/network/mcpe/handler/InGamePacketHandler.php | 3 +++ 2 files changed, 16 insertions(+) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index e7e53b4d3..2c2ecc8c8 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -50,6 +50,7 @@ use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; +use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; @@ -145,6 +146,18 @@ class InventoryManager{ } } + /** + * @param NetworkInventoryAction[] $networkInventoryActions + */ + public function addPredictedSlotChanges(array $networkInventoryActions) : void{ + foreach($networkInventoryActions as $action){ + if($action->sourceType === NetworkInventoryAction::SOURCE_CONTAINER && isset($this->windowMap[$action->windowId])){ + //this won't cover stuff like crafting grid due to too much magic + $this->initiatedSlotChanges[$action->windowId][$action->inventorySlot] = TypeConverter::getInstance()->netItemStackToCore($action->newItem->getItemStack()); + } + } + } + public function onCurrentWindowChange(Inventory $inventory) : void{ $this->onCurrentWindowRemove(); $this->add($this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % self::RESERVED_WINDOW_ID_RANGE_START), $inventory); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index dc2a5e468..f2e0eafb4 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -411,6 +411,7 @@ class InGamePacketHandler extends PacketHandler{ private function handleUseItemTransaction(UseItemTransactionData $data) : bool{ $this->player->selectHotbarSlot($data->getHotbarSlot()); + $this->inventoryManager->addPredictedSlotChanges($data->getActions()); switch($data->getActionType()){ case UseItemTransactionData::ACTION_CLICK_BLOCK: @@ -500,6 +501,7 @@ class InGamePacketHandler extends PacketHandler{ } $this->player->selectHotbarSlot($data->getHotbarSlot()); + $this->inventoryManager->addPredictedSlotChanges($data->getActions()); //TODO: use transactiondata for rollbacks here switch($data->getActionType()){ @@ -520,6 +522,7 @@ class InGamePacketHandler extends PacketHandler{ private function handleReleaseItemTransaction(ReleaseItemTransactionData $data) : bool{ $this->player->selectHotbarSlot($data->getHotbarSlot()); + $this->inventoryManager->addPredictedSlotChanges($data->getActions()); //TODO: use transactiondata for rollbacks here (resending entire inventory is very wasteful) switch($data->getActionType()){