mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-15 18:29:46 +00:00
BaseInventory no longer uses viewers to send updates to players
we want viewers to be as close to decorative as possible, so that they provide useful information to plugins, but don't get in the way of other changes.
This commit is contained in:
parent
f98cebbd62
commit
473bbe64e0
@ -99,15 +99,10 @@ abstract class BaseInventory implements Inventory, SlotValidatedInventory{
|
||||
|
||||
$listeners = $this->listeners->toArray();
|
||||
$this->listeners->clear();
|
||||
$viewers = $this->viewers;
|
||||
$this->viewers = [];
|
||||
|
||||
$this->internalSetContents($items);
|
||||
|
||||
$this->listeners->add(...$listeners); //don't directly write, in case listeners were added while operation was in progress
|
||||
foreach($viewers as $id => $viewer){
|
||||
$this->viewers[$id] = $viewer;
|
||||
}
|
||||
|
||||
$this->onContentChange($oldContents);
|
||||
}
|
||||
@ -369,13 +364,6 @@ abstract class BaseInventory implements Inventory, SlotValidatedInventory{
|
||||
foreach($this->listeners as $listener){
|
||||
$listener->onSlotChange($this, $index, $before);
|
||||
}
|
||||
foreach($this->viewers as $viewer){
|
||||
$invManager = $viewer->getNetworkSession()->getInvManager();
|
||||
if($invManager === null){
|
||||
continue;
|
||||
}
|
||||
$invManager->onSlotChange($this, $index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -386,14 +374,6 @@ abstract class BaseInventory implements Inventory, SlotValidatedInventory{
|
||||
foreach($this->listeners as $listener){
|
||||
$listener->onContentChange($this, $itemsBefore);
|
||||
}
|
||||
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$invManager = $viewer->getNetworkSession()->getInvManager();
|
||||
if($invManager === null){
|
||||
continue;
|
||||
}
|
||||
$invManager->syncContents($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function slotExists(int $slot) : bool{
|
||||
|
@ -37,10 +37,12 @@ use pocketmine\block\inventory\StonecutterInventory;
|
||||
use pocketmine\crafting\FurnaceType;
|
||||
use pocketmine\data\bedrock\EnchantmentIdMap;
|
||||
use pocketmine\inventory\Inventory;
|
||||
use pocketmine\inventory\InventoryListener;
|
||||
use pocketmine\inventory\transaction\action\SlotChangeAction;
|
||||
use pocketmine\inventory\transaction\InventoryTransaction;
|
||||
use pocketmine\item\enchantment\EnchantingOption;
|
||||
use pocketmine\item\enchantment\EnchantmentInstance;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\mcpe\cache\CreativeInventoryCache;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
|
||||
@ -78,7 +80,7 @@ use function spl_object_id;
|
||||
/**
|
||||
* @phpstan-type ContainerOpenClosure \Closure(int $id, Inventory $inventory) : (list<ClientboundPacket>|null)
|
||||
*/
|
||||
class InventoryManager{
|
||||
class InventoryManager implements InventoryListener{
|
||||
/**
|
||||
* @var InventoryManagerEntry[] spl_object_id(Inventory) => InventoryManagerEntry
|
||||
* @phpstan-var array<int, InventoryManagerEntry>
|
||||
@ -149,6 +151,7 @@ class InventoryManager{
|
||||
throw new \InvalidArgumentException("Inventory " . get_class($inventory) . " is already tracked");
|
||||
}
|
||||
$this->inventories[spl_object_id($inventory)] = new InventoryManagerEntry($inventory);
|
||||
$inventory->getListeners()->add($this);
|
||||
$this->associateIdWithInventory($id, $inventory);
|
||||
}
|
||||
|
||||
@ -171,6 +174,7 @@ class InventoryManager{
|
||||
$inventory,
|
||||
$complexSlotMap
|
||||
);
|
||||
$inventory->getListeners()->add($this);
|
||||
foreach($complexSlotMap->getSlotMap() as $netSlot => $coreSlot){
|
||||
$this->complexSlotToInventoryMap[$netSlot] = $complexSlotMap;
|
||||
}
|
||||
@ -191,6 +195,7 @@ class InventoryManager{
|
||||
$inventory = $this->networkIdToInventoryMap[$id];
|
||||
unset($this->networkIdToInventoryMap[$id]);
|
||||
if($this->getWindowId($inventory) === null){
|
||||
$inventory->getListeners()->remove($this);
|
||||
unset($this->inventories[spl_object_id($inventory)]);
|
||||
foreach($this->complexSlotToInventoryMap as $netSlot => $entry){
|
||||
if($entry->getInventory() === $inventory){
|
||||
@ -468,7 +473,7 @@ class InventoryManager{
|
||||
$this->itemStackExtraDataEqual($left, $right);
|
||||
}
|
||||
|
||||
public function onSlotChange(Inventory $inventory, int $slot) : void{
|
||||
public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void{
|
||||
$inventoryEntry = $this->inventories[spl_object_id($inventory)] ?? null;
|
||||
if($inventoryEntry === null){
|
||||
//this can happen when an inventory changed during InventoryCloseEvent, or when a temporary inventory
|
||||
@ -570,6 +575,10 @@ class InventoryManager{
|
||||
unset($entry->predictions[$slot], $entry->pendingSyncs[$slot]);
|
||||
}
|
||||
|
||||
public function onContentChange(Inventory $inventory, array $oldContents) : void{
|
||||
$this->syncContents($inventory);
|
||||
}
|
||||
|
||||
public function syncContents(Inventory $inventory) : void{
|
||||
$entry = $this->inventories[spl_object_id($inventory)] ?? null;
|
||||
if($entry === null){
|
||||
|
Loading…
x
Reference in New Issue
Block a user