mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-16 02:38:54 +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();
|
$listeners = $this->listeners->toArray();
|
||||||
$this->listeners->clear();
|
$this->listeners->clear();
|
||||||
$viewers = $this->viewers;
|
|
||||||
$this->viewers = [];
|
|
||||||
|
|
||||||
$this->internalSetContents($items);
|
$this->internalSetContents($items);
|
||||||
|
|
||||||
$this->listeners->add(...$listeners); //don't directly write, in case listeners were added while operation was in progress
|
$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);
|
$this->onContentChange($oldContents);
|
||||||
}
|
}
|
||||||
@ -369,13 +364,6 @@ abstract class BaseInventory implements Inventory, SlotValidatedInventory{
|
|||||||
foreach($this->listeners as $listener){
|
foreach($this->listeners as $listener){
|
||||||
$listener->onSlotChange($this, $index, $before);
|
$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){
|
foreach($this->listeners as $listener){
|
||||||
$listener->onContentChange($this, $itemsBefore);
|
$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{
|
public function slotExists(int $slot) : bool{
|
||||||
|
@ -37,10 +37,12 @@ use pocketmine\block\inventory\StonecutterInventory;
|
|||||||
use pocketmine\crafting\FurnaceType;
|
use pocketmine\crafting\FurnaceType;
|
||||||
use pocketmine\data\bedrock\EnchantmentIdMap;
|
use pocketmine\data\bedrock\EnchantmentIdMap;
|
||||||
use pocketmine\inventory\Inventory;
|
use pocketmine\inventory\Inventory;
|
||||||
|
use pocketmine\inventory\InventoryListener;
|
||||||
use pocketmine\inventory\transaction\action\SlotChangeAction;
|
use pocketmine\inventory\transaction\action\SlotChangeAction;
|
||||||
use pocketmine\inventory\transaction\InventoryTransaction;
|
use pocketmine\inventory\transaction\InventoryTransaction;
|
||||||
use pocketmine\item\enchantment\EnchantingOption;
|
use pocketmine\item\enchantment\EnchantingOption;
|
||||||
use pocketmine\item\enchantment\EnchantmentInstance;
|
use pocketmine\item\enchantment\EnchantmentInstance;
|
||||||
|
use pocketmine\item\Item;
|
||||||
use pocketmine\network\mcpe\cache\CreativeInventoryCache;
|
use pocketmine\network\mcpe\cache\CreativeInventoryCache;
|
||||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||||
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
|
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)
|
* @phpstan-type ContainerOpenClosure \Closure(int $id, Inventory $inventory) : (list<ClientboundPacket>|null)
|
||||||
*/
|
*/
|
||||||
class InventoryManager{
|
class InventoryManager implements InventoryListener{
|
||||||
/**
|
/**
|
||||||
* @var InventoryManagerEntry[] spl_object_id(Inventory) => InventoryManagerEntry
|
* @var InventoryManagerEntry[] spl_object_id(Inventory) => InventoryManagerEntry
|
||||||
* @phpstan-var array<int, InventoryManagerEntry>
|
* @phpstan-var array<int, InventoryManagerEntry>
|
||||||
@ -149,6 +151,7 @@ class InventoryManager{
|
|||||||
throw new \InvalidArgumentException("Inventory " . get_class($inventory) . " is already tracked");
|
throw new \InvalidArgumentException("Inventory " . get_class($inventory) . " is already tracked");
|
||||||
}
|
}
|
||||||
$this->inventories[spl_object_id($inventory)] = new InventoryManagerEntry($inventory);
|
$this->inventories[spl_object_id($inventory)] = new InventoryManagerEntry($inventory);
|
||||||
|
$inventory->getListeners()->add($this);
|
||||||
$this->associateIdWithInventory($id, $inventory);
|
$this->associateIdWithInventory($id, $inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +174,7 @@ class InventoryManager{
|
|||||||
$inventory,
|
$inventory,
|
||||||
$complexSlotMap
|
$complexSlotMap
|
||||||
);
|
);
|
||||||
|
$inventory->getListeners()->add($this);
|
||||||
foreach($complexSlotMap->getSlotMap() as $netSlot => $coreSlot){
|
foreach($complexSlotMap->getSlotMap() as $netSlot => $coreSlot){
|
||||||
$this->complexSlotToInventoryMap[$netSlot] = $complexSlotMap;
|
$this->complexSlotToInventoryMap[$netSlot] = $complexSlotMap;
|
||||||
}
|
}
|
||||||
@ -191,6 +195,7 @@ class InventoryManager{
|
|||||||
$inventory = $this->networkIdToInventoryMap[$id];
|
$inventory = $this->networkIdToInventoryMap[$id];
|
||||||
unset($this->networkIdToInventoryMap[$id]);
|
unset($this->networkIdToInventoryMap[$id]);
|
||||||
if($this->getWindowId($inventory) === null){
|
if($this->getWindowId($inventory) === null){
|
||||||
|
$inventory->getListeners()->remove($this);
|
||||||
unset($this->inventories[spl_object_id($inventory)]);
|
unset($this->inventories[spl_object_id($inventory)]);
|
||||||
foreach($this->complexSlotToInventoryMap as $netSlot => $entry){
|
foreach($this->complexSlotToInventoryMap as $netSlot => $entry){
|
||||||
if($entry->getInventory() === $inventory){
|
if($entry->getInventory() === $inventory){
|
||||||
@ -468,7 +473,7 @@ class InventoryManager{
|
|||||||
$this->itemStackExtraDataEqual($left, $right);
|
$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;
|
$inventoryEntry = $this->inventories[spl_object_id($inventory)] ?? null;
|
||||||
if($inventoryEntry === null){
|
if($inventoryEntry === null){
|
||||||
//this can happen when an inventory changed during InventoryCloseEvent, or when a temporary inventory
|
//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]);
|
unset($entry->predictions[$slot], $entry->pendingSyncs[$slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onContentChange(Inventory $inventory, array $oldContents) : void{
|
||||||
|
$this->syncContents($inventory);
|
||||||
|
}
|
||||||
|
|
||||||
public function syncContents(Inventory $inventory) : void{
|
public function syncContents(Inventory $inventory) : void{
|
||||||
$entry = $this->inventories[spl_object_id($inventory)] ?? null;
|
$entry = $this->inventories[spl_object_id($inventory)] ?? null;
|
||||||
if($entry === null){
|
if($entry === null){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user