From c368ebb5e74632bc622534b37cd1447b97281e20 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 16:45:20 +0000 Subject: [PATCH 1/3] InventoryTransaction: beware of conflicting slot change actions with the same origin/target these types of chains would never normally occur, but they've been seen in the wild. Attempting to resolve such chains has exponentially increasing complexity. --- .../transaction/InventoryTransaction.php | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/pocketmine/inventory/transaction/InventoryTransaction.php index b85395785..053a15712 100644 --- a/src/pocketmine/inventory/transaction/InventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/InventoryTransaction.php @@ -230,21 +230,34 @@ class InventoryTransaction{ protected function findResultItem(Item $needOrigin, array $possibleActions) : ?Item{ assert(count($possibleActions) > 0); + $candidate = null; + $newList = $possibleActions; foreach($possibleActions as $i => $action){ if($action->getSourceItem()->equalsExact($needOrigin)){ - $newList = $possibleActions; + if($candidate !== null){ + /* + * we found multiple possible actions that match the origin action + * this means that there are multiple ways that this chain could play out + * if we cared so much about this, we could build all the possible chains in parallel and see which + * variation managed to complete the chain, but this has an extremely high complexity which is not + * worth the trouble for this scenario (we don't usually expect to see chains longer than a couple + * of actions in here anyway), and might still result in multiple possible results. + */ + return null; + } + $candidate = $action; unset($newList[$i]); - if(count($newList) === 0){ - return $action->getTargetItem(); - } - $result = $this->findResultItem($action->getTargetItem(), $newList); - if($result !== null){ - return $result; - } } } + if($candidate === null){ + //chaining is not possible with this origin, none of the actions are valid + return null; + } - return null; + if(count($newList) === 0){ + return $candidate->getTargetItem(); + } + return $this->findResultItem($candidate->getTargetItem(), $newList); } /** From e8b6b56330c8918b911ccc48e88a88b1e2cd201c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 16:48:18 +0000 Subject: [PATCH 2/3] Release 3.15.4 --- changelogs/3.15.md | 3 +++ src/pocketmine/VersionInfo.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelogs/3.15.md b/changelogs/3.15.md index 364fd298d..a9ed9cb2c 100644 --- a/changelogs/3.15.md +++ b/changelogs/3.15.md @@ -49,3 +49,6 @@ Plugin developers should **only** update their required API to this version if y - `Maximum memory (system)` is no longer reported in `/status` due to having a misleading output (it was the same as the current memory usage). - The `Player Chunk Send` timer on timings reports now actually reports measurements of chunk sending, not chunk loading. - A new parent timer `World Load` has been added to timings reports, which aggregates timings from `syncChunkLoad` and subtimings from all worlds. + +# 3.15.4 +- Fixed a bug in the inventory transaction system that caused the server to freeze under some circumstances. diff --git a/src/pocketmine/VersionInfo.php b/src/pocketmine/VersionInfo.php index f0e73f017..ea250f4f8 100644 --- a/src/pocketmine/VersionInfo.php +++ b/src/pocketmine/VersionInfo.php @@ -34,5 +34,5 @@ const _VERSION_INFO_INCLUDED = true; const NAME = "PocketMine-MP"; const BASE_VERSION = "3.15.4"; -const IS_DEVELOPMENT_BUILD = true; +const IS_DEVELOPMENT_BUILD = false; const BUILD_NUMBER = 0; From 574b7f6343886def824522e286dc497d905c5b3f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 16:48:18 +0000 Subject: [PATCH 3/3] 3.15.5 is next --- src/pocketmine/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/VersionInfo.php b/src/pocketmine/VersionInfo.php index ea250f4f8..7626b0092 100644 --- a/src/pocketmine/VersionInfo.php +++ b/src/pocketmine/VersionInfo.php @@ -33,6 +33,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ const _VERSION_INFO_INCLUDED = true; const NAME = "PocketMine-MP"; -const BASE_VERSION = "3.15.4"; -const IS_DEVELOPMENT_BUILD = false; +const BASE_VERSION = "3.15.5"; +const IS_DEVELOPMENT_BUILD = true; const BUILD_NUMBER = 0;