mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-10 13:35:29 +00:00
Player: track hardcoded window state, fixes crashes opening inventory on high-latency connections
This commit is contained in:
parent
a6c1b7bf9c
commit
8480ee82ea
@ -176,6 +176,7 @@ use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\UUID;
|
||||
use function abs;
|
||||
use function array_key_exists;
|
||||
use function array_merge;
|
||||
use function array_values;
|
||||
use function assert;
|
||||
@ -315,6 +316,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
/** @var CraftingTransaction|null */
|
||||
protected $craftingTransaction = null;
|
||||
|
||||
/**
|
||||
* TODO: HACK! This tracks GUIs for inventories that the server considers "always open" so that the client can't
|
||||
* open them twice. (1.16 hack)
|
||||
* @var true[]
|
||||
* @phpstan-var array<int, true>
|
||||
* @internal
|
||||
*/
|
||||
public $openHardcodedWindows = [];
|
||||
|
||||
/** @var int */
|
||||
protected $messageCounter = 2;
|
||||
/** @var bool */
|
||||
@ -2795,12 +2805,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
case InteractPacket::ACTION_MOUSEOVER:
|
||||
break; //TODO: handle these
|
||||
case InteractPacket::ACTION_OPEN_INVENTORY:
|
||||
if($target === $this){
|
||||
if($target === $this && !array_key_exists($windowId = self::HARDCODED_INVENTORY_WINDOW_ID, $this->openHardcodedWindows)){
|
||||
//TODO: HACK! this restores 1.14ish behaviour, but this should be able to be listened to and
|
||||
//controlled by plugins. However, the player is always a subscriber to their own inventory so it
|
||||
//doesn't integrate well with the regular container system right now.
|
||||
$this->openHardcodedWindows[$windowId] = true;
|
||||
$pk = new ContainerOpenPacket();
|
||||
$pk->windowId = self::HARDCODED_INVENTORY_WINDOW_ID;
|
||||
$pk->windowId = $windowId;
|
||||
$pk->type = WindowTypes::INVENTORY;
|
||||
$pk->x = $pk->y = $pk->z = 0;
|
||||
$pk->entityUniqueId = $this->getId();
|
||||
@ -3027,7 +3038,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$this->doCloseInventory();
|
||||
|
||||
if($packet->windowId >= self::RESERVED_WINDOW_ID_RANGE_START and $packet->windowId <= self::RESERVED_WINDOW_ID_RANGE_END){
|
||||
if(array_key_exists($packet->windowId, $this->openHardcodedWindows)){
|
||||
unset($this->openHardcodedWindows[$packet->windowId]);
|
||||
$pk = new ContainerClosePacket();
|
||||
$pk->windowId = $packet->windowId;
|
||||
$this->sendDataPacket($pk);
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\WindowTypes;
|
||||
use pocketmine\Player;
|
||||
use function array_key_exists;
|
||||
|
||||
class CraftingTable extends Solid{
|
||||
|
||||
@ -53,15 +54,18 @@ class CraftingTable extends Solid{
|
||||
if($player instanceof Player){
|
||||
$player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG));
|
||||
|
||||
//TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack allows
|
||||
//it to carry on working approximately the same way as it did in 1.14
|
||||
$pk = new ContainerOpenPacket();
|
||||
$pk->windowId = Player::HARDCODED_CRAFTING_GRID_WINDOW_ID;
|
||||
$pk->type = WindowTypes::WORKBENCH;
|
||||
$pk->x = $this->getFloorX();
|
||||
$pk->y = $this->getFloorY();
|
||||
$pk->z = $this->getFloorZ();
|
||||
$player->sendDataPacket($pk);
|
||||
if(!array_key_exists($windowId = Player::HARDCODED_CRAFTING_GRID_WINDOW_ID, $player->openHardcodedWindows)){
|
||||
//TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack allows
|
||||
//it to carry on working approximately the same way as it did in 1.14
|
||||
$pk = new ContainerOpenPacket();
|
||||
$pk->windowId = $windowId;
|
||||
$pk->type = WindowTypes::WORKBENCH;
|
||||
$pk->x = $this->getFloorX();
|
||||
$pk->y = $this->getFloorY();
|
||||
$pk->z = $this->getFloorZ();
|
||||
$player->sendDataPacket($pk);
|
||||
$player->openHardcodedWindows[$windowId] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user