From 86afecec890f93998b9876e593f713c43f023588 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Mon, 3 Nov 2014 11:48:10 +0100 Subject: [PATCH] Improved inventory sending, send single slots instead of full inventory as much as possible --- src/pocketmine/inventory/BaseInventory.php | 6 +- src/pocketmine/inventory/PlayerInventory.php | 84 ++++++++++++++++---- 2 files changed, 71 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 855244cc9..79ed94e8f 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -133,8 +133,7 @@ abstract class BaseInventory implements Inventory{ if($holder instanceof Entity){ Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $this->getItem($index), $item, $index)); if($ev->isCancelled()){ - $this->sendContents($this->getViewers()); - + $this->sendSlot($index, $this->getViewers()); return false; } $item = $ev->getNewItem(); @@ -300,8 +299,7 @@ abstract class BaseInventory implements Inventory{ if($holder instanceof Entity){ Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $old, $item, $index)); if($ev->isCancelled()){ - $this->sendContents($this->getViewers()); - + $this->sendSlot($index, $this->getViewers()); return false; } $item = $ev->getNewItem(); diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 5db5c6651..6f0d0805d 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -150,7 +150,8 @@ class PlayerInventory extends BaseInventory{ parent::onSlotChange($index, $before, $source); if($index >= $this->getSize()){ - $this->sendArmorContents($this->getHolder()->getViewers()); + $this->sendArmorSlot($index, $this->getViewers($source)); + $this->sendArmorSlot($index, $this->getHolder()->getViewers()); } } @@ -208,18 +209,22 @@ class PlayerInventory extends BaseInventory{ if($index >= $this->getSize()){ //Armor change Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $this->getItem($index), $item, $index)); if($ev->isCancelled() and $this->getHolder() instanceof Player){ - $this->sendArmorContents($this->getViewers()); - $this->sendContents($this->getViewers()); - + if($index >= $this->size){ + $this->sendArmorSlot($index, $this->getViewers()); + }else{ + $this->sendSlot($index, $this->getViewers()); + } return false; } $item = $ev->getNewItem(); }else{ Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $this->getItem($index), $item, $index)); if($ev->isCancelled()){ - $this->sendArmorContents($this->getViewers()); - $this->sendContents($this->getViewers()); - + if($index >= $this->size){ + $this->sendArmorSlot($index, $this->getViewers()); + }else{ + $this->sendSlot($index, $this->getViewers()); + } return false; } $item = $ev->getNewItem(); @@ -240,18 +245,22 @@ class PlayerInventory extends BaseInventory{ if($index >= $this->getSize() and $index < $this->size){ //Armor change Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $old, $item, $index)); if($ev->isCancelled()){ - $this->sendArmorContents($this->getViewers()); - $this->sendContents($this->getViewers()); - + if($index >= $this->size){ + $this->sendArmorSlot($index, $this->getViewers()); + }else{ + $this->sendSlot($index, $this->getViewers()); + } return false; } $item = $ev->getNewItem(); }else{ Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $old, $item, $index)); if($ev->isCancelled()){ - $this->sendArmorContents($this->getViewers()); - $this->sendContents($this->getViewers()); - + if($index >= $this->size){ + $this->sendArmorSlot($index, $this->getViewers()); + }else{ + $this->sendSlot($index, $this->getViewers()); + } return false; } $item = $ev->getNewItem(); @@ -345,6 +354,51 @@ class PlayerInventory extends BaseInventory{ } } + + + /** + * @param int $index + * @param Player|Player[] $target + */ + public function sendArmorSlot($index, $target){ + if($target instanceof Player){ + $target = [$target]; + } + + $armor = $this->getArmorContents(); + $slots = []; + + foreach($armor as $i => $slot){ + if($slot->getID() === Item::AIR){ + $slots[$i] = 255; + }else{ + $slots[$i] = $slot->getID(); + } + } + + $pk = new PlayerArmorEquipmentPacket(); + $pk->eid = $this->getHolder()->getID(); + $pk->slots = $slots; + $pk->encode(); + $pk->isEncoded = true; + + foreach($target as $player){ + if($player === $this->getHolder()){ + /** @var Player $player */ + //$pk2 = clone $pk; + //$pk2->eid = 0; + + $pk2 = new ContainerSetSlotPacket(); + $pk2->windowid = 0x78; //Armor window id constant + $pk2->slot = $index; + $pk2->item = $this->getItem($index); + $player->dataPacket($pk2); + }else{ + $player->dataPacket($pk); + } + } + } + /** * @param Player|Player[] $target */ @@ -392,8 +446,8 @@ class PlayerInventory extends BaseInventory{ foreach($target as $player){ if($player === $this->getHolder()){ /** @var Player $player */ - //TODO: Check if Mojang has implemented this (for the player inventory) on Minecraft: PE 0.9.0 - $this->sendContents($player); + $pk->windowid = 0; + $player->dataPacket(clone $pk); }else{ if(($id = $player->getWindowId($this)) === -1){ $this->close($player);