mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-12 16:59:44 +00:00
NetworkInventoryAction: move type translation to TypeConverter
This commit is contained in:
parent
33f899f2fc
commit
ebcfab4b61
@ -22,14 +22,24 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace pocketmine\network\mcpe\convert;
|
namespace pocketmine\network\mcpe\convert;
|
||||||
|
|
||||||
|
use pocketmine\crafting\CraftingGrid;
|
||||||
|
use pocketmine\inventory\transaction\action\CreateItemAction;
|
||||||
|
use pocketmine\inventory\transaction\action\DestroyItemAction;
|
||||||
|
use pocketmine\inventory\transaction\action\DropItemAction;
|
||||||
|
use pocketmine\inventory\transaction\action\InventoryAction;
|
||||||
|
use pocketmine\inventory\transaction\action\SlotChangeAction;
|
||||||
use pocketmine\item\Durable;
|
use pocketmine\item\Durable;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\item\ItemFactory;
|
use pocketmine\item\ItemFactory;
|
||||||
use pocketmine\item\ItemIds;
|
use pocketmine\item\ItemIds;
|
||||||
use pocketmine\nbt\tag\CompoundTag;
|
use pocketmine\nbt\tag\CompoundTag;
|
||||||
use pocketmine\nbt\tag\IntTag;
|
use pocketmine\nbt\tag\IntTag;
|
||||||
|
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
|
||||||
|
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
|
||||||
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
|
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
|
||||||
|
use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction;
|
||||||
use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient;
|
use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient;
|
||||||
|
use pocketmine\player\Player;
|
||||||
|
|
||||||
class TypeConverter{
|
class TypeConverter{
|
||||||
private const DAMAGE_TAG = "Damage"; //TAG_Int
|
private const DAMAGE_TAG = "Damage"; //TAG_Int
|
||||||
@ -121,4 +131,75 @@ class TypeConverter{
|
|||||||
$compound
|
$compound
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
*/
|
||||||
|
public function createInventoryAction(NetworkInventoryAction $action, Player $player) : ?InventoryAction{
|
||||||
|
$old = TypeConverter::getInstance()->netItemStackToCore($action->oldItem);
|
||||||
|
$new = TypeConverter::getInstance()->netItemStackToCore($action->newItem);
|
||||||
|
if($old->equalsExact($new)){
|
||||||
|
//filter out useless noise in 1.13
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch($action->sourceType){
|
||||||
|
case NetworkInventoryAction::SOURCE_CONTAINER:
|
||||||
|
if($action->windowId === ContainerIds::UI and $action->inventorySlot > 0){
|
||||||
|
if($action->inventorySlot === 50){
|
||||||
|
return null; //useless noise
|
||||||
|
}
|
||||||
|
if($action->inventorySlot >= 28 and $action->inventorySlot <= 31){
|
||||||
|
$window = $player->getCraftingGrid();
|
||||||
|
if($window->getGridWidth() !== CraftingGrid::SIZE_SMALL){
|
||||||
|
throw new \UnexpectedValueException("Expected small crafting grid");
|
||||||
|
}
|
||||||
|
$slot = $action->inventorySlot - 28;
|
||||||
|
}elseif($action->inventorySlot >= 32 and $action->inventorySlot <= 40){
|
||||||
|
$window = $player->getCraftingGrid();
|
||||||
|
if($window->getGridWidth() !== CraftingGrid::SIZE_BIG){
|
||||||
|
throw new \UnexpectedValueException("Expected big crafting grid");
|
||||||
|
}
|
||||||
|
$slot = $action->inventorySlot - 32;
|
||||||
|
}else{
|
||||||
|
throw new \UnexpectedValueException("Unhandled magic UI slot offset $action->inventorySlot");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$window = $player->getNetworkSession()->getInvManager()->getWindow($action->windowId);
|
||||||
|
$slot = $action->inventorySlot;
|
||||||
|
}
|
||||||
|
if($window !== null){
|
||||||
|
return new SlotChangeAction($window, $slot, $old, $new);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \UnexpectedValueException("No open container with window ID $action->windowId");
|
||||||
|
case NetworkInventoryAction::SOURCE_WORLD:
|
||||||
|
if($action->inventorySlot !== NetworkInventoryAction::ACTION_MAGIC_SLOT_DROP_ITEM){
|
||||||
|
throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DropItemAction($new);
|
||||||
|
case NetworkInventoryAction::SOURCE_CREATIVE:
|
||||||
|
switch($action->inventorySlot){
|
||||||
|
case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM:
|
||||||
|
return new DestroyItemAction($new);
|
||||||
|
case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM:
|
||||||
|
return new CreateItemAction($new);
|
||||||
|
default:
|
||||||
|
throw new \UnexpectedValueException("Unexpected creative action type $action->inventorySlot");
|
||||||
|
|
||||||
|
}
|
||||||
|
case NetworkInventoryAction::SOURCE_TODO:
|
||||||
|
//These types need special handling.
|
||||||
|
switch($action->windowId){
|
||||||
|
case NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT:
|
||||||
|
case NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: more stuff
|
||||||
|
throw new \UnexpectedValueException("No open container with window ID $action->windowId");
|
||||||
|
default:
|
||||||
|
throw new \UnexpectedValueException("Unknown inventory source type $action->sourceType");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -205,9 +205,10 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
|
|
||||||
$isCrafting = false;
|
$isCrafting = false;
|
||||||
$isFinalCraftingPart = false;
|
$isFinalCraftingPart = false;
|
||||||
|
$converter = TypeConverter::getInstance();
|
||||||
foreach($data->getActions() as $networkInventoryAction){
|
foreach($data->getActions() as $networkInventoryAction){
|
||||||
$old = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->oldItem);
|
$old = $converter->netItemStackToCore($networkInventoryAction->oldItem);
|
||||||
$new = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->newItem);
|
$new = $converter->netItemStackToCore($networkInventoryAction->newItem);
|
||||||
if(
|
if(
|
||||||
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER and
|
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER and
|
||||||
$networkInventoryAction->windowId === ContainerIds::UI and
|
$networkInventoryAction->windowId === ContainerIds::UI and
|
||||||
@ -228,7 +229,7 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
$action = $networkInventoryAction->createInventoryAction($this->player);
|
$action = $converter->createInventoryAction($networkInventoryAction, $this->player);
|
||||||
if($action !== null){
|
if($action !== null){
|
||||||
$actions[] = $action;
|
$actions[] = $action;
|
||||||
}
|
}
|
||||||
|
@ -23,16 +23,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace pocketmine\network\mcpe\protocol\types\inventory;
|
namespace pocketmine\network\mcpe\protocol\types\inventory;
|
||||||
|
|
||||||
use pocketmine\crafting\CraftingGrid;
|
|
||||||
use pocketmine\inventory\transaction\action\CreateItemAction;
|
|
||||||
use pocketmine\inventory\transaction\action\DestroyItemAction;
|
|
||||||
use pocketmine\inventory\transaction\action\DropItemAction;
|
|
||||||
use pocketmine\inventory\transaction\action\InventoryAction;
|
|
||||||
use pocketmine\inventory\transaction\action\SlotChangeAction;
|
|
||||||
use pocketmine\network\BadPacketException;
|
use pocketmine\network\BadPacketException;
|
||||||
use pocketmine\network\mcpe\convert\TypeConverter;
|
|
||||||
use pocketmine\network\mcpe\serializer\NetworkBinaryStream;
|
use pocketmine\network\mcpe\serializer\NetworkBinaryStream;
|
||||||
use pocketmine\player\Player;
|
|
||||||
use pocketmine\utils\BinaryDataException;
|
use pocketmine\utils\BinaryDataException;
|
||||||
|
|
||||||
class NetworkInventoryAction{
|
class NetworkInventoryAction{
|
||||||
@ -143,75 +135,4 @@ class NetworkInventoryAction{
|
|||||||
$packet->putSlot($this->oldItem);
|
$packet->putSlot($this->oldItem);
|
||||||
$packet->putSlot($this->newItem);
|
$packet->putSlot($this->newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \UnexpectedValueException
|
|
||||||
*/
|
|
||||||
public function createInventoryAction(Player $player) : ?InventoryAction{
|
|
||||||
$old = TypeConverter::getInstance()->netItemStackToCore($this->oldItem);
|
|
||||||
$new = TypeConverter::getInstance()->netItemStackToCore($this->newItem);
|
|
||||||
if($old->equalsExact($new)){
|
|
||||||
//filter out useless noise in 1.13
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
switch($this->sourceType){
|
|
||||||
case self::SOURCE_CONTAINER:
|
|
||||||
if($this->windowId === ContainerIds::UI and $this->inventorySlot > 0){
|
|
||||||
if($this->inventorySlot === 50){
|
|
||||||
return null; //useless noise
|
|
||||||
}
|
|
||||||
if($this->inventorySlot >= 28 and $this->inventorySlot <= 31){
|
|
||||||
$window = $player->getCraftingGrid();
|
|
||||||
if($window->getGridWidth() !== CraftingGrid::SIZE_SMALL){
|
|
||||||
throw new \UnexpectedValueException("Expected small crafting grid");
|
|
||||||
}
|
|
||||||
$slot = $this->inventorySlot - 28;
|
|
||||||
}elseif($this->inventorySlot >= 32 and $this->inventorySlot <= 40){
|
|
||||||
$window = $player->getCraftingGrid();
|
|
||||||
if($window->getGridWidth() !== CraftingGrid::SIZE_BIG){
|
|
||||||
throw new \UnexpectedValueException("Expected big crafting grid");
|
|
||||||
}
|
|
||||||
$slot = $this->inventorySlot - 32;
|
|
||||||
}else{
|
|
||||||
throw new \UnexpectedValueException("Unhandled magic UI slot offset $this->inventorySlot");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
$window = $player->getNetworkSession()->getInvManager()->getWindow($this->windowId);
|
|
||||||
$slot = $this->inventorySlot;
|
|
||||||
}
|
|
||||||
if($window !== null){
|
|
||||||
return new SlotChangeAction($window, $slot, $old, $new);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \UnexpectedValueException("No open container with window ID $this->windowId");
|
|
||||||
case self::SOURCE_WORLD:
|
|
||||||
if($this->inventorySlot !== self::ACTION_MAGIC_SLOT_DROP_ITEM){
|
|
||||||
throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DropItemAction($new);
|
|
||||||
case self::SOURCE_CREATIVE:
|
|
||||||
switch($this->inventorySlot){
|
|
||||||
case self::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM:
|
|
||||||
return new DestroyItemAction($new);
|
|
||||||
case self::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM:
|
|
||||||
return new CreateItemAction($new);
|
|
||||||
default:
|
|
||||||
throw new \UnexpectedValueException("Unexpected creative action type $this->inventorySlot");
|
|
||||||
|
|
||||||
}
|
|
||||||
case self::SOURCE_TODO:
|
|
||||||
//These types need special handling.
|
|
||||||
switch($this->windowId){
|
|
||||||
case self::SOURCE_TYPE_CRAFTING_RESULT:
|
|
||||||
case self::SOURCE_TYPE_CRAFTING_USE_INGREDIENT:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: more stuff
|
|
||||||
throw new \UnexpectedValueException("No open container with window ID $this->windowId");
|
|
||||||
default:
|
|
||||||
throw new \UnexpectedValueException("Unknown inventory source type $this->sourceType");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user