Player: Obliterate InventoryTransactionPacket handler, add some new methods

This commit is contained in:
Dylan K. Taylor
2018-08-04 20:01:32 +01:00
parent 905c0c825c
commit 25660843c5
2 changed files with 401 additions and 372 deletions

View File

@ -23,6 +23,10 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\handler;
use pocketmine\inventory\transaction\action\InventoryAction;
use pocketmine\inventory\transaction\CraftingTransaction;
use pocketmine\inventory\transaction\InventoryTransaction;
use pocketmine\inventory\transaction\TransactionValidationException;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket;
@ -70,6 +74,9 @@ class SimpleSessionHandler extends SessionHandler{
/** @var Player */
private $player;
/** @var CraftingTransaction|null */
protected $craftingTransaction = null;
public function __construct(Player $player){
$this->player = $player;
}
@ -95,7 +102,131 @@ class SimpleSessionHandler extends SessionHandler{
}
public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{
return $this->player->handleInventoryTransaction($packet);
if($this->player->isSpectator()){
$this->player->sendAllInventories();
return true;
}
/** @var InventoryAction[] $actions */
$actions = [];
foreach($packet->actions as $networkInventoryAction){
try{
$action = $networkInventoryAction->createInventoryAction($this->player);
if($action !== null){
$actions[] = $action;
}
}catch(\Exception $e){
$this->player->getServer()->getLogger()->debug("Unhandled inventory action from " . $this->player->getName() . ": " . $e->getMessage());
$this->player->sendAllInventories();
return false;
}
}
if($packet->isCraftingPart){
if($this->craftingTransaction === null){
$this->craftingTransaction = new CraftingTransaction($this->player, $actions);
}else{
foreach($actions as $action){
$this->craftingTransaction->addAction($action);
}
}
if($packet->isFinalCraftingPart){
//we get the actions for this in several packets, so we need to wait until we have all the pieces before
//trying to execute it
$ret = true;
try{
$this->craftingTransaction->execute();
}catch(TransactionValidationException $e){
$this->player->getServer()->getLogger()->debug("Failed to execute crafting transaction for " . $this->player->getName() . ": " . $e->getMessage());
$ret = false;
}
$this->craftingTransaction = null;
return $ret;
}
return true;
}
if($this->craftingTransaction !== null){
$this->player->getServer()->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->player->getName() . ", refusing to execute crafting");
$this->craftingTransaction = null;
}
switch($packet->transactionType){
case InventoryTransactionPacket::TYPE_NORMAL:
$transaction = new InventoryTransaction($this->player, $actions);
try{
$transaction->execute();
}catch(TransactionValidationException $e){
$this->player->getServer()->getLogger()->debug("Failed to execute inventory transaction from " . $this->player->getName() . ": " . $e->getMessage());
$this->player->getServer()->getLogger()->debug("Actions: " . json_encode($packet->actions));
return false;
}
//TODO: fix achievement for getting iron from furnace
return true;
case InventoryTransactionPacket::TYPE_MISMATCH:
if(count($packet->actions) > 0){
$this->player->getServer()->getLogger()->debug("Expected 0 actions for mismatch, got " . count($packet->actions) . ", " . json_encode($packet->actions));
}
$this->player->sendAllInventories();
return true;
case InventoryTransactionPacket::TYPE_USE_ITEM:
$blockVector = new Vector3($packet->trData->x, $packet->trData->y, $packet->trData->z);
$face = $packet->trData->face;
$type = $packet->trData->actionType;
switch($type){
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_BLOCK:
$this->player->interactBlock($blockVector, $face, $packet->trData->clickPos);
return true;
case InventoryTransactionPacket::USE_ITEM_ACTION_BREAK_BLOCK:
$this->player->breakBlock($blockVector);
return true;
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR:
$this->player->useHeldItem();
return true;
}
break;
case InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY:
$target = $this->player->getLevel()->getEntity($packet->trData->entityRuntimeId);
if($target === null){
return false;
}
switch($packet->trData->actionType){
case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_INTERACT:
$this->player->interactEntity($target, $packet->trData->clickPos);
return true;
case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_ATTACK:
$this->player->attackEntity($target);
return true;
}
break;
case InventoryTransactionPacket::TYPE_RELEASE_ITEM:
switch($packet->trData->actionType){
case InventoryTransactionPacket::RELEASE_ITEM_ACTION_RELEASE:
$this->player->releaseHeldItem();
return true;
case InventoryTransactionPacket::RELEASE_ITEM_ACTION_CONSUME:
$this->player->consumeHeldItem();
return true;
}
break;
default:
break;
}
$this->player->sendAllInventories();
return false;
}
public function handleMobEquipment(MobEquipmentPacket $packet) : bool{