From 55720d9f0a65f2378191adf48c0926aef4dd714b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Sep 2017 12:19:42 +0100 Subject: [PATCH] Added InventoryAction->onPreExecute(), fixed PlayerDropItemEvent deleting items --- src/pocketmine/Player.php | 6 ------ .../transaction/SimpleInventoryTransaction.php | 16 +++++++++++++++- .../transaction/action/DropItemAction.php | 10 ++++++++++ .../transaction/action/InventoryAction.php | 12 ++++++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 41fce7aae..ffdafb805 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -49,7 +49,6 @@ use pocketmine\event\player\PlayerBedLeaveEvent; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; -use pocketmine\event\player\PlayerDropItemEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; @@ -2723,11 +2722,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - $this->server->getPluginManager()->callEvent($ev = new PlayerDropItemEvent($this, $item)); - if($ev->isCancelled()){ - return false; - } - $motion = $this->getDirectionVector()->multiply(0.4); $this->level->dropItem($this->add(0, 1.3, 0), $item, $motion, 40); diff --git a/src/pocketmine/inventory/transaction/SimpleInventoryTransaction.php b/src/pocketmine/inventory/transaction/SimpleInventoryTransaction.php index 6c861c7e8..cd185e546 100644 --- a/src/pocketmine/inventory/transaction/SimpleInventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/SimpleInventoryTransaction.php @@ -222,6 +222,12 @@ class SimpleInventoryTransaction implements InventoryTransaction{ return $this->matchItems($needItems, $haveItems) and count($this->actions) > 0 and count($haveItems) === 0 and count($needItems) === 0; } + protected function handleFailed(){ + foreach($this->actions as $action){ + $action->onExecuteFail($this->source); + } + } + /** * @return bool */ @@ -232,7 +238,15 @@ class SimpleInventoryTransaction implements InventoryTransaction{ Server::getInstance()->getPluginManager()->callEvent($ev = new InventoryTransactionEvent($this)); if($ev->isCancelled()){ - return false; + $this->handleFailed(); + return true; + } + + foreach($this->actions as $action){ + if(!$action->onPreExecute($this->source)){ + $this->handleFailed(); + return true; + } } foreach($this->actions as $action){ diff --git a/src/pocketmine/inventory/transaction/action/DropItemAction.php b/src/pocketmine/inventory/transaction/action/DropItemAction.php index 5cde91b2c..4c9955851 100644 --- a/src/pocketmine/inventory/transaction/action/DropItemAction.php +++ b/src/pocketmine/inventory/transaction/action/DropItemAction.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; +use pocketmine\event\player\PlayerDropItemEvent; use pocketmine\Player; /** @@ -41,6 +42,15 @@ class DropItemAction extends InventoryAction{ return $this->sourceItem->isNull(); } + public function onPreExecute(Player $source) : bool{ + $source->getServer()->getPluginManager()->callEvent($ev = new PlayerDropItemEvent($source, $this->targetItem)); + if($ev->isCancelled()){ + return false; + } + + return true; + } + /** * Drops the target item in front of the player. * diff --git a/src/pocketmine/inventory/transaction/action/InventoryAction.php b/src/pocketmine/inventory/transaction/action/InventoryAction.php index e2496862a..8f901ae12 100644 --- a/src/pocketmine/inventory/transaction/action/InventoryAction.php +++ b/src/pocketmine/inventory/transaction/action/InventoryAction.php @@ -74,6 +74,18 @@ abstract class InventoryAction{ */ abstract public function isValid(Player $source) : bool; + /** + * Called by inventory transactions before any actions are processed. If this returns false, the transaction will + * be cancelled. + * + * @param Player $source + * + * @return bool + */ + public function onPreExecute(Player $source) : bool{ + return true; + } + /** * Performs actions needed to complete the inventory-action server-side. Returns if it was successful. Will return * false if plugins cancelled events. This will only be called if the transaction which it is part of is considered