mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 09:56:06 +00:00
Merge branch 'minor-next' into major-next
This commit is contained in:
@ -325,6 +325,9 @@ class InGamePacketHandler extends PacketHandler{
|
||||
if(count($packet->trData->getActions()) > 50){
|
||||
throw new PacketHandlingException("Too many actions in inventory transaction");
|
||||
}
|
||||
if(count($packet->requestChangedSlots) > 10){
|
||||
throw new PacketHandlingException("Too many slot sync requests in inventory transaction");
|
||||
}
|
||||
|
||||
$this->inventoryManager->setCurrentItemStackRequestId($packet->requestId);
|
||||
$this->inventoryManager->addRawPredictedSlotChanges($packet->trData->getActions());
|
||||
@ -344,6 +347,21 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
$this->inventoryManager->syncMismatchedPredictedSlotChanges();
|
||||
|
||||
//requestChangedSlots asks the server to always send out the contents of the specified slots, even if they
|
||||
//haven't changed. Handling these is necessary to ensure the client inventory stays in sync if the server
|
||||
//rejects the transaction. The most common example of this is equipping armor by right-click, which doesn't send
|
||||
//a legacy prediction action for the destination armor slot.
|
||||
foreach($packet->requestChangedSlots as $containerInfo){
|
||||
$windowId = ItemStackContainerIdTranslator::translate($containerInfo->getContainerId(), $this->inventoryManager->getCurrentWindowId());
|
||||
foreach($containerInfo->getChangedSlotIndexes() as $slot){
|
||||
$inventoryAndSlot = $this->inventoryManager->locateWindowAndSlot($windowId, $slot);
|
||||
if($inventoryAndSlot !== null){ //trigger the normal slot sync logic
|
||||
$this->inventoryManager->onSlotChange($inventoryAndSlot[0], $inventoryAndSlot[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->inventoryManager->setCurrentItemStackRequestId(null);
|
||||
return $result;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\handler;
|
||||
|
||||
use pocketmine\crafting\CraftingGrid;
|
||||
use pocketmine\inventory\CreativeInventory;
|
||||
use pocketmine\inventory\Inventory;
|
||||
use pocketmine\inventory\transaction\action\CreateItemAction;
|
||||
@ -246,13 +245,11 @@ class ItemStackRequestExecutor{
|
||||
|
||||
$this->specialTransaction = new CraftingTransaction($this->player, $craftingManager, [], $recipe, $repetitions);
|
||||
|
||||
$currentWindow = $this->player->getCurrentWindow();
|
||||
if($currentWindow !== null && !($currentWindow instanceof CraftingGrid)){
|
||||
throw new ItemStackRequestProcessException("Player's current window is not a crafting grid");
|
||||
}
|
||||
$craftingGrid = $currentWindow ?? $this->player->getCraftingGrid();
|
||||
|
||||
$craftingResults = $recipe->getResultsFor($craftingGrid);
|
||||
//TODO: Since the system assumes that crafting can only be done in the crafting grid, we have to give it a
|
||||
//crafting grid to make the API happy. No implementation of getResultsFor() actually uses the crafting grid
|
||||
//right now, so this will work, but this will become a problem in the future for things like shulker boxes and
|
||||
//custom crafting recipes.
|
||||
$craftingResults = $recipe->getResultsFor($this->player->getCraftingGrid());
|
||||
foreach($craftingResults as $k => $craftingResult){
|
||||
$craftingResult->setCount($craftingResult->getCount() * $repetitions);
|
||||
$this->craftingResults[$k] = $craftingResult;
|
||||
|
Reference in New Issue
Block a user