Merge branch 'stable'

# Conflicts:
#	resources/vanilla
#	src/pocketmine/VersionInfo.php
This commit is contained in:
Dylan K. Taylor 2019-06-10 18:20:01 +01:00
commit 3175a319a2
2 changed files with 50 additions and 1 deletions

View File

@ -32,6 +32,21 @@ use function array_pop;
use function count; use function count;
use function intdiv; use function intdiv;
/**
* This transaction type is specialized for crafting validation. It shares most of the same semantics of the base
* inventory transaction type, but the requirement for validity is slightly different.
*
* It is expected that the actions in this transaction type will produce an **unbalanced result**, i.e. some inputs won't
* have corresponding outputs, and vice versa. The reason why is because the unmatched inputs are recipe inputs, and
* the unmatched outputs are recipe results.
*
* Therefore, the validity requirement is that the imbalance of the transaction should match the expected inputs and
* outputs of a registered crafting recipe.
*
* This transaction allows multiple repetitions of the same recipe to be crafted in a single batch. In the case of batch
* crafting, the number of unmatched inputs and outputs must be exactly divisible by the expected recipe ingredients and
* results, with no remainder. Any leftovers are expected to be emitted back to the crafting grid.
*/
class CraftingTransaction extends InventoryTransaction{ class CraftingTransaction extends InventoryTransaction{
/** @var CraftingRecipe|null */ /** @var CraftingRecipe|null */
protected $recipe; protected $recipe;

View File

@ -29,15 +29,29 @@ use pocketmine\inventory\transaction\action\InventoryAction;
use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\action\SlotChangeAction;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\Player; use pocketmine\Player;
use function array_keys;
use function assert; use function assert;
use function count; use function count;
use function get_class; use function get_class;
use function min; use function min;
use function shuffle;
use function spl_object_hash; use function spl_object_hash;
use function spl_object_id; use function spl_object_id;
/** /**
* This InventoryTransaction only allows doing Transaction between one / two inventories * This is the basic type for an inventory transaction. This is used for moving items between inventories, dropping
* items and more. It allows transactions with multiple inputs and outputs.
*
* Validation **does not** depend on ordering. This means that the actions can appear in any order and still be valid.
* The only validity requirement for this transaction type is that the balance of items must add up to zero. This means:
* - No new outputs without matching input amounts
* - No inputs without matching output amounts
* - No userdata changes (item state, NBT, etc)
*
* A transaction is composed of "actions", which are pairs of inputs and outputs which target a specific itemstack in
* a specific location. There are multiple types of inventory actions which might be involved in a transaction.
*
* @see InventoryAction
*/ */
class InventoryTransaction{ class InventoryTransaction{
protected $hasExecuted = false; protected $hasExecuted = false;
@ -76,6 +90,11 @@ class InventoryTransaction{
} }
/** /**
* Returns an **unordered** set of actions involved in this transaction.
*
* WARNING: This system is **explicitly designed NOT to care about ordering**. Any order seen in this set has NO
* significance and should not be relied on.
*
* @return InventoryAction[] * @return InventoryAction[]
*/ */
public function getActions() : array{ public function getActions() : array{
@ -94,6 +113,19 @@ class InventoryTransaction{
} }
} }
/**
* Shuffles actions in the transaction to prevent external things relying on any implicit ordering.
*/
private function shuffleActions() : void{
$keys = array_keys($this->actions);
shuffle($keys);
$actions = [];
foreach($keys as $key){
$actions[$key] = $this->actions[$key];
}
$this->actions = $actions;
}
/** /**
* @internal This method should not be used by plugins, it's used to add tracked inventories for InventoryActions * @internal This method should not be used by plugins, it's used to add tracked inventories for InventoryActions
* involving inventories. * involving inventories.
@ -272,6 +304,8 @@ class InventoryTransaction{
return false; return false;
} }
$this->shuffleActions();
$this->validate(); $this->validate();
if(!$this->callExecuteEvent()){ if(!$this->callExecuteEvent()){