Merge branch 'item-stack-request' into item-stack-request-pm5

This commit is contained in:
Dylan K. Taylor 2023-03-14 22:56:47 +00:00
commit 6c29c3d2dd
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -46,7 +46,6 @@ use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
use pocketmine\network\mcpe\convert\TypeConversionException;
use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\InventoryManager;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
@ -388,25 +387,23 @@ class InGamePacketHandler extends PacketHandler{
//prediction rollback anyway. //prediction rollback anyway.
//it's technically possible to see this more than once, but a normal client should never do that. //it's technically possible to see this more than once, but a normal client should never do that.
$inventory = $this->player->getInventory(); $inventory = $this->player->getInventory();
$heldItem = $inventory->getItemInHand();
try{ $heldItemStack = $this->inventoryManager->getItemStackInfo($inventory, $inventory->getHeldItemIndex())?->getItemStack();
$droppedItem = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->newItem->getItemStack()); if($heldItemStack === null){
}catch(TypeConversionException $e){ throw new AssumptionFailedError("Missing itemstack info for held item");
throw PacketHandlingException::wrap($e);
} }
$droppedItemStack = $networkInventoryAction->newItem->getItemStack();
//TODO: if we can avoid decoding incoming item NBT, it will be faster to compare network ItemStacks //because the client doesn't tell us the expected itemstack ID, we have to deep-compare our known
//rather than converting to internal itemstacks and using canStackWith() here. //itemstack info with the one the client sent. This is costly, but we don't have any other option :(
if(!$heldItem->canStackWith($droppedItem) || $heldItem->getCount() < $droppedItem->getCount()){ if(!$heldItemStack->equalsWithoutCount($droppedItemStack) || $heldItemStack->getCount() < $droppedItemStack->getCount()){
return false; return false;
} }
//purposely overwritten here - this allows any immutable internal references to be shared $newHeldItem = $inventory->getItemInHand();
$droppedItem = $heldItem->pop($droppedItem->getCount()); $droppedItem = $newHeldItem->pop($droppedItemStack->getCount());
$builder = new TransactionBuilder(); $builder = new TransactionBuilder();
$builder->getInventory($inventory)->setItem($inventory->getHeldItemIndex(), $heldItem); $builder->getInventory($inventory)->setItem($inventory->getHeldItemIndex(), $newHeldItem);
$builder->addAction(new DropItemAction($droppedItem)); $builder->addAction(new DropItemAction($droppedItem));
$transaction = new InventoryTransaction($this->player, $builder->generateActions()); $transaction = new InventoryTransaction($this->player, $builder->generateActions());