mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-16 08:25:29 +00:00
Do not assume the presence of a crafting transaction closing marker
fixes #3655, fixes #3241 instead of guessing where the end of the transaction is, we attempt validation after every piece of the transaction, with the assumption being that a crafting transaction will not validate until it's complete.
This commit is contained in:
parent
756840f11d
commit
5b620d964e
@ -149,6 +149,7 @@ use pocketmine\network\mcpe\protocol\types\CommandParameter;
|
|||||||
use pocketmine\network\mcpe\protocol\types\ContainerIds;
|
use pocketmine\network\mcpe\protocol\types\ContainerIds;
|
||||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||||
use pocketmine\network\mcpe\protocol\types\GameMode;
|
use pocketmine\network\mcpe\protocol\types\GameMode;
|
||||||
|
use pocketmine\network\mcpe\protocol\types\inventory\UIInventorySlotOffset;
|
||||||
use pocketmine\network\mcpe\protocol\types\NetworkInventoryAction;
|
use pocketmine\network\mcpe\protocol\types\NetworkInventoryAction;
|
||||||
use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor;
|
use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor;
|
||||||
use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece;
|
use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece;
|
||||||
@ -2392,18 +2393,20 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
/** @var InventoryAction[] $actions */
|
/** @var InventoryAction[] $actions */
|
||||||
$actions = [];
|
$actions = [];
|
||||||
$isCraftingPart = false;
|
$isCraftingPart = false;
|
||||||
$isFinalCraftingPart = false;
|
|
||||||
foreach($packet->actions as $networkInventoryAction){
|
foreach($packet->actions as $networkInventoryAction){
|
||||||
if(
|
if(
|
||||||
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_TODO and (
|
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_TODO and (
|
||||||
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT or
|
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT or
|
||||||
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT
|
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT
|
||||||
|
) or (
|
||||||
|
$this->craftingTransaction !== null &&
|
||||||
|
!$networkInventoryAction->oldItem->equalsExact($networkInventoryAction->newItem) &&
|
||||||
|
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER &&
|
||||||
|
$networkInventoryAction->windowId === ContainerIds::UI &&
|
||||||
|
$networkInventoryAction->inventorySlot === UIInventorySlotOffset::CREATED_ITEM_OUTPUT
|
||||||
)
|
)
|
||||||
){
|
){
|
||||||
$isCraftingPart = true;
|
$isCraftingPart = true;
|
||||||
if($networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT){
|
|
||||||
$isFinalCraftingPart = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try{
|
try{
|
||||||
$action = $networkInventoryAction->createInventoryAction($this);
|
$action = $networkInventoryAction->createInventoryAction($this);
|
||||||
@ -2426,9 +2429,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($isFinalCraftingPart){
|
try{
|
||||||
//we get the actions for this in several packets, so we need to wait until we have all the pieces before
|
$this->craftingTransaction->validate();
|
||||||
//trying to execute it
|
}catch(TransactionValidationException $e){
|
||||||
|
//transaction is incomplete - crafting transaction comes in lots of little bits, so we have to collect
|
||||||
|
//all of the parts before we can execute it
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$ret = true;
|
$ret = true;
|
||||||
try{
|
try{
|
||||||
@ -2440,9 +2447,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
|
|
||||||
$this->craftingTransaction = null;
|
$this->craftingTransaction = null;
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}elseif($this->craftingTransaction !== null){
|
}elseif($this->craftingTransaction !== null){
|
||||||
$this->server->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->getName() . ", refusing to execute crafting");
|
$this->server->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->getName() . ", refusing to execute crafting");
|
||||||
$this->craftingTransaction = null;
|
$this->craftingTransaction = null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user