From 7e92da126d3d080f1c58ea1bde8fd7dc2b86ef21 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Apr 2023 15:42:33 +0100 Subject: [PATCH] DelegateInventory: fixed slots being synced twice and breaking ItemStackRequests the second time the slot is synced, there is no prediction, so the slot update isn't associated with a request anymore. This causes subsequent requests in the same packet to fail, since the dependency request ID isn't associated with the slot anymore. This change fixes the problem by only allowing the backing inventory to trigger a call to DelegateInventory->on*Change(). While we could have removed and re-added the listener instead, this way is safer since it doesn't assume that the backing inventory won't modify the given item in setItem(). closes #5692 --- src/inventory/DelegateInventory.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/inventory/DelegateInventory.php b/src/inventory/DelegateInventory.php index 391b9599c..ba9e5a983 100644 --- a/src/inventory/DelegateInventory.php +++ b/src/inventory/DelegateInventory.php @@ -30,6 +30,7 @@ use pocketmine\item\Item; */ class DelegateInventory extends BaseInventory{ private InventoryListener $inventoryListener; + private bool $backingInventoryChanging = false; public function __construct( private Inventory $backingInventory @@ -39,12 +40,22 @@ class DelegateInventory extends BaseInventory{ $this->backingInventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener( static function(Inventory $unused, int $slot, Item $oldItem) use ($weakThis) : void{ if(($strongThis = $weakThis->get()) !== null){ - $strongThis->onSlotChange($slot, $oldItem); + $strongThis->backingInventoryChanging = true; + try{ + $strongThis->onSlotChange($slot, $oldItem); + }finally{ + $strongThis->backingInventoryChanging = false; + } } }, static function(Inventory $unused, array $oldContents) use ($weakThis) : void{ if(($strongThis = $weakThis->get()) !== null){ - $strongThis->onContentChange($oldContents); + $strongThis->backingInventoryChanging = true; + try{ + $strongThis->onContentChange($oldContents); + }finally{ + $strongThis->backingInventoryChanging = false; + } } } )); @@ -73,4 +84,16 @@ class DelegateInventory extends BaseInventory{ protected function internalSetContents(array $items) : void{ $this->backingInventory->setContents($items); } + + protected function onSlotChange(int $index, Item $before) : void{ + if($this->backingInventoryChanging){ + parent::onSlotChange($index, $before); + } + } + + protected function onContentChange(array $itemsBefore) : void{ + if($this->backingInventoryChanging){ + parent::onContentChange($itemsBefore); + } + } }