Improved inventory sending, send single slots instead of full inventory as much as possible

This commit is contained in:
Shoghi Cervantes 2014-11-03 11:48:10 +01:00
parent 29d1fd1fc8
commit 86afecec89
2 changed files with 71 additions and 19 deletions

View File

@ -133,8 +133,7 @@ abstract class BaseInventory implements Inventory{
if($holder instanceof Entity){ if($holder instanceof Entity){
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $this->getItem($index), $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $this->getItem($index), $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendContents($this->getViewers()); $this->sendSlot($index, $this->getViewers());
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
@ -300,8 +299,7 @@ abstract class BaseInventory implements Inventory{
if($holder instanceof Entity){ if($holder instanceof Entity){
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $old, $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $old, $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendContents($this->getViewers()); $this->sendSlot($index, $this->getViewers());
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();

View File

@ -150,7 +150,8 @@ class PlayerInventory extends BaseInventory{
parent::onSlotChange($index, $before, $source); parent::onSlotChange($index, $before, $source);
if($index >= $this->getSize()){ 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 if($index >= $this->getSize()){ //Armor change
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $this->getItem($index), $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $this->getItem($index), $item, $index));
if($ev->isCancelled() and $this->getHolder() instanceof Player){ if($ev->isCancelled() and $this->getHolder() instanceof Player){
$this->sendArmorContents($this->getViewers()); if($index >= $this->size){
$this->sendContents($this->getViewers()); $this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
}else{ }else{
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $this->getItem($index), $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $this->getItem($index), $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendArmorContents($this->getViewers()); if($index >= $this->size){
$this->sendContents($this->getViewers()); $this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
@ -240,18 +245,22 @@ class PlayerInventory extends BaseInventory{
if($index >= $this->getSize() and $index < $this->size){ //Armor change if($index >= $this->getSize() and $index < $this->size){ //Armor change
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $old, $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $old, $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendArmorContents($this->getViewers()); if($index >= $this->size){
$this->sendContents($this->getViewers()); $this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false; return false;
} }
$item = $ev->getNewItem(); $item = $ev->getNewItem();
}else{ }else{
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $old, $item, $index)); Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->getHolder(), $old, $item, $index));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendArmorContents($this->getViewers()); if($index >= $this->size){
$this->sendContents($this->getViewers()); $this->sendArmorSlot($index, $this->getViewers());
}else{
$this->sendSlot($index, $this->getViewers());
}
return false; return false;
} }
$item = $ev->getNewItem(); $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 * @param Player|Player[] $target
*/ */
@ -392,8 +446,8 @@ class PlayerInventory extends BaseInventory{
foreach($target as $player){ foreach($target as $player){
if($player === $this->getHolder()){ if($player === $this->getHolder()){
/** @var Player $player */ /** @var Player $player */
//TODO: Check if Mojang has implemented this (for the player inventory) on Minecraft: PE 0.9.0 $pk->windowid = 0;
$this->sendContents($player); $player->dataPacket(clone $pk);
}else{ }else{
if(($id = $player->getWindowId($this)) === -1){ if(($id = $player->getWindowId($this)) === -1){
$this->close($player); $this->close($player);