Improve performance of loading player inventories

This commit is contained in:
Dylan K. Taylor 2022-01-01 15:26:42 +00:00
parent 3c6146b5e0
commit eedea38669
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -217,6 +217,19 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$this->uuid = Uuid::uuid3(Uuid::NIL, ((string) $this->getId()) . $this->skin->getSkinData() . $this->getNameTag()); $this->uuid = Uuid::uuid3(Uuid::NIL, ((string) $this->getId()) . $this->skin->getSkinData() . $this->getNameTag());
} }
/**
* @param Item[] $items
* @phpstan-param array<int, Item> $items
*/
private static function populateInventoryFromListTag(Inventory $inventory, array $items) : void{
$listeners = $inventory->getListeners()->toArray();
$inventory->getListeners()->clear();
$inventory->setContents($items);
$inventory->getListeners()->add(...$listeners);
}
protected function initEntity(CompoundTag $nbt) : void{ protected function initEntity(CompoundTag $nbt) : void{
parent::initEntity($nbt); parent::initEntity($nbt);
@ -247,10 +260,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$inventoryTag = $nbt->getListTag("Inventory"); $inventoryTag = $nbt->getListTag("Inventory");
if($inventoryTag !== null){ if($inventoryTag !== null){
$armorListeners = $this->armorInventory->getListeners()->toArray(); $inventoryItems = [];
$this->armorInventory->getListeners()->clear(); $armorInventoryItems = [];
$inventoryListeners = $this->inventory->getListeners()->toArray();
$this->inventory->getListeners()->clear();
/** @var CompoundTag $item */ /** @var CompoundTag $item */
foreach($inventoryTag as $i => $item){ foreach($inventoryTag as $i => $item){
@ -258,14 +269,14 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
if($slot >= 0 and $slot < 9){ //Hotbar if($slot >= 0 and $slot < 9){ //Hotbar
//Old hotbar saving stuff, ignore it //Old hotbar saving stuff, ignore it
}elseif($slot >= 100 and $slot < 104){ //Armor }elseif($slot >= 100 and $slot < 104){ //Armor
$this->armorInventory->setItem($slot - 100, Item::nbtDeserialize($item)); $armorInventoryItems[$slot - 100] = Item::nbtDeserialize($item);
}elseif($slot >= 9 and $slot < $this->inventory->getSize() + 9){ }elseif($slot >= 9 and $slot < $this->inventory->getSize() + 9){
$this->inventory->setItem($slot - 9, Item::nbtDeserialize($item)); $inventoryItems[$slot - 9] = Item::nbtDeserialize($item);
} }
} }
$this->armorInventory->getListeners()->add(...$armorListeners); self::populateInventoryFromListTag($this->inventory, $inventoryItems);
$this->inventory->getListeners()->add(...$inventoryListeners); self::populateInventoryFromListTag($this->armorInventory, $armorInventoryItems);
} }
$offHand = $nbt->getCompoundTag("OffHandItem"); $offHand = $nbt->getCompoundTag("OffHandItem");
if($offHand !== null){ if($offHand !== null){
@ -279,10 +290,13 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory");
if($enderChestInventoryTag !== null){ if($enderChestInventoryTag !== null){
$enderChestInventoryItems = [];
/** @var CompoundTag $item */ /** @var CompoundTag $item */
foreach($enderChestInventoryTag as $i => $item){ foreach($enderChestInventoryTag as $i => $item){
$this->enderInventory->setItem($item->getByte("Slot"), Item::nbtDeserialize($item)); $enderChestInventoryItems[$item->getByte("Slot")] = Item::nbtDeserialize($item);
} }
self::populateInventoryFromListTag($this->enderInventory, $enderChestInventoryItems);
} }
$this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0)); $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0));