diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index a63f58a43..53dd2af77 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -456,8 +456,8 @@ class LevelDB extends BaseLevelProvider{ $tiles = []; foreach($chunk->getTiles() as $tile){ if(!$tile->isClosed()){ - $tile->saveNBT(); - $tiles[] = $tile->namedtag; + $tile->saveNBT($tileTag = new CompoundTag()); + $tiles[] = $tileTag; } } $this->writeTags($tiles, $index . self::TAG_BLOCK_ENTITY); diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index 7f9bc3208..5a7a63c1d 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -75,8 +75,8 @@ class Anvil extends McRegion{ $tiles = []; foreach($chunk->getTiles() as $tile){ - $tile->saveNBT(); - $tiles[] = $tile->namedtag; + $tile->saveNBT($tileTag = new CompoundTag()); + $tiles[] = $tileTag; } $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index b83124ede..6c98dc67d 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -94,8 +94,8 @@ class McRegion extends BaseLevelProvider{ $tiles = []; foreach($chunk->getTiles() as $tile){ - $tile->saveNBT(); - $tiles[] = $tile->namedtag; + $tile->saveNBT($tileTag = new CompoundTag()); + $tiles[] = $tileTag; } $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 0bf7fdb50..9cdf3a30c 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\item\Item; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -107,19 +106,16 @@ class Banner extends Spawnable implements Nameable{ */ private $patterns; - public function __construct(Level $level, CompoundTag $nbt){ + protected function readSaveData(CompoundTag $nbt) : void{ $this->baseColor = $nbt->getInt(self::TAG_BASE, self::COLOR_BLACK, true); $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? new ListTag(self::TAG_PATTERNS); - $nbt->removeTag(self::TAG_BASE, self::TAG_PATTERNS); $this->loadName($nbt); - parent::__construct($level, $nbt); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setInt(self::TAG_BASE, $this->baseColor); - $this->namedtag->setTag($this->patterns); - $this->saveName($this->namedtag); + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setInt(self::TAG_BASE, $this->baseColor); + $nbt->setTag($this->patterns); + $this->saveName($nbt); } public function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index ad7694b02..322e42d62 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -25,7 +25,6 @@ namespace pocketmine\tile; use pocketmine\item\Item; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; @@ -35,13 +34,6 @@ class Bed extends Spawnable{ /** @var int */ private $color = 14; //default to old red - public function __construct(Level $level, CompoundTag $nbt){ - $this->color = $nbt->getByte(self::TAG_COLOR, 14, true); - $nbt->removeTag(self::TAG_COLOR); - - parent::__construct($level, $nbt); - } - public function getColor() : int{ return $this->color; } @@ -51,13 +43,16 @@ class Bed extends Spawnable{ $this->onChanged(); } - public function addAdditionalSpawnData(CompoundTag $nbt) : void{ + protected function readSaveData(CompoundTag $nbt) : void{ + $this->color = $nbt->getByte(self::TAG_COLOR, 14, true); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ $nbt->setByte(self::TAG_COLOR, $this->color); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setByte(self::TAG_COLOR, $this->color); + public function addAdditionalSpawnData(CompoundTag $nbt) : void{ + $nbt->setByte(self::TAG_COLOR, $this->color); } protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index 9d14dbf4c..74c51f900 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -26,7 +26,6 @@ namespace pocketmine\tile; use pocketmine\inventory\ChestInventory; use pocketmine\inventory\DoubleChestInventory; use pocketmine\inventory\InventoryHolder; -use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -50,19 +49,26 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var int|null */ private $pairZ; - public function __construct(Level $level, CompoundTag $nbt){ + protected function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_PAIRX, IntTag::class) and $nbt->hasTag(self::TAG_PAIRZ, IntTag::class)){ $this->pairX = $nbt->getInt(self::TAG_PAIRX); $this->pairZ = $nbt->getInt(self::TAG_PAIRZ); } - $nbt->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); $this->loadName($nbt); - parent::__construct($level, $nbt); - $this->inventory = new ChestInventory($this); - $this->loadItems($this->namedtag); + $this->loadItems($nbt); + } + protected function writeSaveData(CompoundTag $nbt) : void{ + if($this->isPaired()){ + $nbt->setInt(self::TAG_PAIRX, $this->pairX); + $nbt->setInt(self::TAG_PAIRZ, $this->pairZ); + }else{ + $nbt->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); + } + $this->saveName($nbt); + $this->saveItems($nbt); } public function close() : void{ @@ -81,18 +87,6 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } } - public function saveNBT() : void{ - parent::saveNBT(); - if($this->isPaired()){ - $this->namedtag->setInt(self::TAG_PAIRX, $this->pairX); - $this->namedtag->setInt(self::TAG_PAIRZ, $this->pairZ); - }else{ - $this->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); - } - $this->saveItems($this->namedtag); - $this->saveName($this->namedtag); - } - /** * @return ChestInventory|DoubleChestInventory */ diff --git a/src/pocketmine/tile/EnchantTable.php b/src/pocketmine/tile/EnchantTable.php index d31491ce2..e2618a8ff 100644 --- a/src/pocketmine/tile/EnchantTable.php +++ b/src/pocketmine/tile/EnchantTable.php @@ -23,20 +23,10 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\level\Level; -use pocketmine\nbt\tag\CompoundTag; - class EnchantTable extends Spawnable implements Nameable{ - use NameableTrait; - - public function __construct(Level $level, CompoundTag $nbt){ - $this->loadName($nbt); - parent::__construct($level, $nbt); - } - - public function saveNBT() : void{ - parent::saveNBT(); - $this->saveName($this->namedtag); + use NameableTrait{ + loadName as readSaveData; + saveName as writeSaveData; } /** diff --git a/src/pocketmine/tile/EnderChest.php b/src/pocketmine/tile/EnderChest.php index 1895c1c10..822c4c01a 100644 --- a/src/pocketmine/tile/EnderChest.php +++ b/src/pocketmine/tile/EnderChest.php @@ -27,6 +27,14 @@ use pocketmine\nbt\tag\CompoundTag; class EnderChest extends Spawnable{ + protected function readSaveData(CompoundTag $nbt) : void{ + + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + + } + public function addAdditionalSpawnData(CompoundTag $nbt) : void{ } diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index e4c7eb734..84de9f06c 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -25,7 +25,6 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; class FlowerPot extends Spawnable{ @@ -35,17 +34,13 @@ class FlowerPot extends Spawnable{ /** @var Item */ private $item; - public function __construct(Level $level, CompoundTag $nbt){ - //TODO: check PC format + protected function readSaveData(CompoundTag $nbt) : void{ $this->item = ItemFactory::get($nbt->getShort(self::TAG_ITEM, 0, true), $nbt->getInt(self::TAG_ITEM_DATA, 0, true), 1); - $nbt->removeTag(self::TAG_ITEM, self::TAG_ITEM_DATA); - - parent::__construct($level, $nbt); } - public function saveNBT() : void{ - $this->namedtag->setShort(self::TAG_ITEM, $this->item->getId()); - $this->namedtag->setInt(self::TAG_ITEM_DATA, $this->item->getDamage()); + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setShort(self::TAG_ITEM, $this->item->getId()); + $nbt->setInt(self::TAG_ITEM_DATA, $this->item->getDamage()); } public function canAddItem(Item $item) : bool{ diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index cd70d3aac..a952d0daf 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -56,6 +56,13 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ private $maxTime; public function __construct(Level $level, CompoundTag $nbt){ + parent::__construct($level, $nbt); + if($this->burnTime > 0){ + $this->scheduleUpdate(); + } + } + + protected function readSaveData(CompoundTag $nbt) : void{ $this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, 0, true)); $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, 0, true); @@ -70,14 +77,16 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $this->loadName($nbt); - parent::__construct($level, $nbt); $this->inventory = new FurnaceInventory($this); - $this->loadItems($this->namedtag); + $this->loadItems($nbt); + } - - if($this->burnTime > 0){ - $this->scheduleUpdate(); - } + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setShort(self::TAG_BURN_TIME, $this->burnTime); + $nbt->setShort(self::TAG_COOK_TIME, $this->cookTime); + $nbt->setShort(self::TAG_MAX_TIME, $this->maxTime); + $this->saveName($nbt); + $this->saveItems($nbt); } /** @@ -96,16 +105,6 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ } } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setShort(self::TAG_BURN_TIME, $this->burnTime); - $this->namedtag->setShort(self::TAG_COOK_TIME, $this->cookTime); - $this->namedtag->setShort(self::TAG_MAX_TIME, $this->maxTime); - - $this->saveItems($this->namedtag); - $this->saveName($this->namedtag); - } - /** * @return FurnaceInventory */ diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 39f715121..56ab6b7f2 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -25,7 +25,6 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; class ItemFrame extends Spawnable{ @@ -40,7 +39,7 @@ class ItemFrame extends Spawnable{ /** @var float */ private $itemDropChance; - public function __construct(Level $level, CompoundTag $nbt){ + protected function readSaveData(CompoundTag $nbt) : void{ if(($itemTag = $nbt->getCompoundTag(self::TAG_ITEM)) !== null){ $this->item = Item::nbtDeserialize($itemTag); }else{ @@ -48,16 +47,12 @@ class ItemFrame extends Spawnable{ } $this->itemRotation = $nbt->getByte(self::TAG_ITEM_ROTATION, 0, true); $this->itemDropChance = $nbt->getFloat(self::TAG_ITEM_DROP_CHANCE, 1.0, true); - $nbt->removeTag(self::TAG_ITEM, self::TAG_ITEM_ROTATION, self::TAG_ITEM_DROP_CHANCE); - - parent::__construct($level, $nbt); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); - $this->namedtag->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); - $this->namedtag->setTag($this->item->nbtSerialize(-1, self::TAG_ITEM)); + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); + $nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); + $nbt->setTag($this->item->nbtSerialize(-1, self::TAG_ITEM)); } public function hasItem() : bool{ diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 72974affb..1be69c42f 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\event\block\SignChangeEvent; -use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; use pocketmine\Player; @@ -37,7 +36,7 @@ class Sign extends Spawnable{ /** @var string[] */ protected $text = ["", "", "", ""]; - public function __construct(Level $level, CompoundTag $nbt){ + protected function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ //MCPE 1.2 save format $this->text = array_pad(explode("\n", $nbt->getString(self::TAG_TEXT_BLOB)), 4, ""); assert(count($this->text) === 4, "Too many lines!"); @@ -51,17 +50,14 @@ class Sign extends Spawnable{ } } } - - parent::__construct($level, $nbt); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text)); + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text)); for($i = 1; $i <= 4; ++$i){ //Backwards-compatibility $textKey = sprintf(self::TAG_TEXT_LINE, $i); - $this->namedtag->setString($textKey, $this->getLine($i - 1)); + $nbt->setString($textKey, $this->getLine($i - 1)); } } diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 1b24eb534..828c67d1a 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\item\Item; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; @@ -47,17 +46,14 @@ class Skull extends Spawnable{ /** @var int */ private $skullRotation; - public function __construct(Level $level, CompoundTag $nbt){ + protected function readSaveData(CompoundTag $nbt) : void{ $this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, self::TYPE_SKELETON, true); $this->skullRotation = $nbt->getByte(self::TAG_ROT, 0, true); - $nbt->removeTag(self::TAG_SKULL_TYPE, self::TAG_ROT); - parent::__construct($level, $nbt); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setByte(self::TAG_SKULL_TYPE, $this->skullType); - $this->namedtag->setByte(self::TAG_ROT, $this->skullRotation); + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType); + $nbt->setByte(self::TAG_ROT, $this->skullRotation); } public function setType(int $type){ diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 876b186d7..e87979c68 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -74,8 +74,6 @@ abstract class Tile extends Position{ public $id; /** @var bool */ public $closed = false; - /** @var CompoundTag */ - public $namedtag; /** @var Server */ protected $server; /** @var TimingsHandler */ @@ -155,12 +153,12 @@ abstract class Tile extends Position{ public function __construct(Level $level, CompoundTag $nbt){ $this->timings = Timings::getTileEntityTimings($this); - $this->namedtag = $nbt; $this->server = $level->getServer(); $this->name = ""; $this->id = Tile::$tileCount++; - parent::__construct($this->namedtag->getInt(self::TAG_X), $this->namedtag->getInt(self::TAG_Y), $this->namedtag->getInt(self::TAG_Z), $level); + parent::__construct($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z), $level); + $this->readSaveData($nbt); $this->getLevel()->addTile($this); } @@ -169,26 +167,31 @@ abstract class Tile extends Position{ return $this->id; } - public function saveNBT() : void{ - $this->namedtag->setString(self::TAG_ID, static::getSaveId()); - $this->namedtag->setInt(self::TAG_X, $this->x); - $this->namedtag->setInt(self::TAG_Y, $this->y); - $this->namedtag->setInt(self::TAG_Z, $this->z); - } + /** + * Reads additional data from the CompoundTag on tile creation. + * + * @param CompoundTag $nbt + */ + abstract protected function readSaveData(CompoundTag $nbt) : void; - public function getNBT() : CompoundTag{ - return $this->namedtag; + /** + * Writes additional save data to a CompoundTag, not including generic things like ID and coordinates. + * + * @param CompoundTag $nbt + */ + abstract protected function writeSaveData(CompoundTag $nbt) : void; + + public function saveNBT(CompoundTag $nbt) : void{ + $nbt->setString(self::TAG_ID, static::getSaveId()); + $nbt->setInt(self::TAG_X, $this->x); + $nbt->setInt(self::TAG_Y, $this->y); + $nbt->setInt(self::TAG_Z, $this->z); + $this->writeSaveData($nbt); } public function getCleanedNBT() : ?CompoundTag{ - $this->saveNBT(); - $tag = clone $this->namedtag; - $tag->removeTag(self::TAG_X, self::TAG_Y, self::TAG_Z, self::TAG_ID); - if($tag->getCount() > 0){ - return $tag; - }else{ - return null; - } + $this->writeSaveData($tag = new CompoundTag()); + return $tag->getCount() > 0 ? $tag : null; } /** @@ -270,8 +273,6 @@ abstract class Tile extends Position{ $this->level->removeTile($this); $this->setLevel(null); } - - $this->namedtag = null; } }