diff --git a/src/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php index e7b4a6d3fc..ea506e388c 100644 --- a/src/inventory/transaction/InventoryTransaction.php +++ b/src/inventory/transaction/InventoryTransaction.php @@ -142,8 +142,10 @@ class InventoryTransaction{ $needItems[] = $action->getTargetItem(); } - if(!$action->isValid($this->source)){ - throw new TransactionValidationException("Action " . get_class($action) . " is not valid in the current transaction"); + try{ + $action->validate($this->source); + }catch(TransactionValidationException $e){ + throw new TransactionValidationException(get_class($action) . ": " . $e->getMessage(), 0, $e); } if(!$action->getSourceItem()->isNull()){ diff --git a/src/inventory/transaction/action/CreateItemAction.php b/src/inventory/transaction/action/CreateItemAction.php index 18cd4a5368..dbe02798ee 100644 --- a/src/inventory/transaction/action/CreateItemAction.php +++ b/src/inventory/transaction/action/CreateItemAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\CreativeInventory; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -38,8 +39,13 @@ class CreateItemAction extends InventoryAction{ parent::__construct($sourceItem, ItemFactory::air()); } - public function isValid(Player $source) : bool{ - return !$source->hasFiniteResources() and CreativeInventory::getInstance()->contains($this->sourceItem); + public function validate(Player $source) : void{ + if($source->hasFiniteResources()){ + throw new TransactionValidationException("Player has finite resources, cannot create items"); + } + if(!CreativeInventory::getInstance()->contains($this->sourceItem)){ + throw new TransactionValidationException("Creative inventory does not contain requested item"); + } } public function execute(Player $source) : void{ diff --git a/src/inventory/transaction/action/DestroyItemAction.php b/src/inventory/transaction/action/DestroyItemAction.php index d59485c072..6edd30af2a 100644 --- a/src/inventory/transaction/action/DestroyItemAction.php +++ b/src/inventory/transaction/action/DestroyItemAction.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -37,8 +38,10 @@ class DestroyItemAction extends InventoryAction{ parent::__construct(ItemFactory::air(), $targetItem); } - public function isValid(Player $source) : bool{ - return !$source->hasFiniteResources(); + public function validate(Player $source) : void{ + if($source->hasFiniteResources()){ + throw new TransactionValidationException("Player has finite resources, cannot destroy items"); + } } public function execute(Player $source) : void{ diff --git a/src/inventory/transaction/action/DropItemAction.php b/src/inventory/transaction/action/DropItemAction.php index a15e3fdd05..2e20d5f93d 100644 --- a/src/inventory/transaction/action/DropItemAction.php +++ b/src/inventory/transaction/action/DropItemAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\event\player\PlayerDropItemEvent; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -37,8 +38,10 @@ class DropItemAction extends InventoryAction{ parent::__construct(ItemFactory::air(), $targetItem); } - public function isValid(Player $source) : bool{ - return !$this->targetItem->isNull(); + public function validate(Player $source) : void{ + if($this->targetItem->isNull()){ + throw new TransactionValidationException("Cannot drop an empty itemstack"); + } } public function onPreExecute(Player $source) : bool{ diff --git a/src/inventory/transaction/action/InventoryAction.php b/src/inventory/transaction/action/InventoryAction.php index 5b1e8db5db..4fa3ac15e5 100644 --- a/src/inventory/transaction/action/InventoryAction.php +++ b/src/inventory/transaction/action/InventoryAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\player\Player; @@ -57,8 +58,10 @@ abstract class InventoryAction{ /** * Returns whether this action is currently valid. This should perform any necessary sanity checks. + * + * @throws TransactionValidationException */ - abstract public function isValid(Player $source) : bool; + abstract public function validate(Player $source) : void; /** * Called when the action is added to the specified InventoryTransaction. diff --git a/src/inventory/transaction/action/SlotChangeAction.php b/src/inventory/transaction/action/SlotChangeAction.php index eda92b4579..1686c261bb 100644 --- a/src/inventory/transaction/action/SlotChangeAction.php +++ b/src/inventory/transaction/action/SlotChangeAction.php @@ -25,6 +25,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\player\Player; @@ -60,12 +61,16 @@ class SlotChangeAction extends InventoryAction{ /** * Checks if the item in the inventory at the specified slot is the same as this action's source item. + * + * @throws TransactionValidationException */ - public function isValid(Player $source) : bool{ - return ( - $this->inventory->slotExists($this->inventorySlot) and - $this->inventory->getItem($this->inventorySlot)->equalsExact($this->sourceItem) - ); + public function validate(Player $source) : void{ + if(!$this->inventory->slotExists($this->inventorySlot)){ + throw new TransactionValidationException("Slot does not exist"); + } + if(!$this->inventory->getItem($this->inventorySlot)->equalsExact($this->sourceItem)){ + throw new TransactionValidationException("Slot does not contain expected original item"); + } } /**