diff --git a/composer.lock b/composer.lock index b942bb6f5..8395d5e19 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "cb170cf827e265cfb492de2af684cba23574dfec" + "reference": "772f627884c92beb750cc1c50a8d25f155a9c006" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/cb170cf827e265cfb492de2af684cba23574dfec", - "reference": "cb170cf827e265cfb492de2af684cba23574dfec", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/772f627884c92beb750cc1c50a8d25f155a9c006", + "reference": "772f627884c92beb750cc1c50a8d25f155a9c006", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-03-16T12:12:20+00:00" + "time": "2019-03-18T14:38:07+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 11f320a4a..ea3cee7cc 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1826,10 +1826,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: old code had a TODO for SpawnForced }elseif($spawnReset){ - $namedtag->setTag(new ListTag("Pos", [ - new DoubleTag("", $spawn->x), - new DoubleTag("", $spawn->y), - new DoubleTag("", $spawn->z) + $namedtag->setTag("Pos", new ListTag([ + new DoubleTag($spawn->x), + new DoubleTag($spawn->y), + new DoubleTag($spawn->z) ])); } @@ -1882,9 +1882,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->achievements = []; $achievements = $nbt->getCompoundTag("Achievements"); if($achievements !== null){ - /** @var ByteTag $achievement */ - foreach($achievements as $achievement){ - $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + /** @var ByteTag $tag */ + foreach($achievements as $name => $tag){ + $this->achievements[$name] = $tag->getValue() !== 0; } } @@ -2897,19 +2897,19 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$this->isAlive()){ //hack for respawn after quit - $nbt->setTag(new ListTag("Pos", [ - new DoubleTag("", $this->spawnPosition->x), - new DoubleTag("", $this->spawnPosition->y), - new DoubleTag("", $this->spawnPosition->z) + $nbt->setTag("Pos", new ListTag([ + new DoubleTag($this->spawnPosition->x), + new DoubleTag($this->spawnPosition->y), + new DoubleTag($this->spawnPosition->z) ])); } } - $achievements = new CompoundTag("Achievements"); + $achievements = new CompoundTag(); foreach($this->achievements as $achievement => $status){ $achievements->setByte($achievement, $status ? 1 : 0); } - $nbt->setTag($achievements); + $nbt->setTag("Achievements", $achievements); $nbt->setInt("playerGameType", $this->gamemode); $nbt->setLong("firstPlayed", $this->firstPlayed); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d5ea787e1..b2978f9ca 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -61,6 +61,7 @@ use pocketmine\metadata\PlayerMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\CompressBatchTask; @@ -645,7 +646,7 @@ class Server{ if(file_exists($path . "$name.dat")){ try{ - return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat")); + return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat"))->getTag(); }catch(NbtDataException $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); @@ -667,7 +668,7 @@ class Server{ if(!$ev->isCancelled()){ $nbt = new BigEndianNbtSerializer(); try{ - file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())); + file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed(new TreeRoot($ev->getSaveData()))); }catch(\ErrorException $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); $this->logger->logException($e); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7e62b59fd..a191cf47e 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -715,7 +715,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(""); + $nbt = new CompoundTag(); if(!($this instanceof Player)){ $nbt->setString("id", EntityFactory::getSaveId(get_class($this))); @@ -725,21 +725,21 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } } - $nbt->setTag(new ListTag("Pos", [ - new DoubleTag("", $this->x), - new DoubleTag("", $this->y), - new DoubleTag("", $this->z) + $nbt->setTag("Pos", new ListTag([ + new DoubleTag($this->x), + new DoubleTag($this->y), + new DoubleTag($this->z) ])); - $nbt->setTag(new ListTag("Motion", [ - new DoubleTag("", $this->motion->x), - new DoubleTag("", $this->motion->y), - new DoubleTag("", $this->motion->z) + $nbt->setTag("Motion", new ListTag([ + new DoubleTag($this->motion->x), + new DoubleTag($this->motion->y), + new DoubleTag($this->motion->z) ])); - $nbt->setTag(new ListTag("Rotation", [ - new FloatTag("", $this->yaw), - new FloatTag("", $this->pitch) + $nbt->setTag("Rotation", new ListTag([ + new FloatTag($this->yaw), + new FloatTag($this->pitch) ])); $nbt->setFloat("FallDistance", $this->fallDistance); diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index 75bd41e19..2b3191374 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -246,21 +246,20 @@ final class EntityFactory{ * @return CompoundTag */ public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ - return new CompoundTag("", [ - new ListTag("Pos", [ - new DoubleTag("", $pos->x), - new DoubleTag("", $pos->y), - new DoubleTag("", $pos->z) - ]), - new ListTag("Motion", [ - new DoubleTag("", $motion ? $motion->x : 0.0), - new DoubleTag("", $motion ? $motion->y : 0.0), - new DoubleTag("", $motion ? $motion->z : 0.0) - ]), - new ListTag("Rotation", [ - new FloatTag("", $yaw), - new FloatTag("", $pitch) - ]) - ]); + return CompoundTag::create() + ->setTag("Pos", new ListTag([ + new DoubleTag($pos->x), + new DoubleTag($pos->y), + new DoubleTag($pos->z) + ])) + ->setTag("Motion", new ListTag([ + new DoubleTag($motion ? $motion->x : 0.0), + new DoubleTag($motion ? $motion->y : 0.0), + new DoubleTag($motion ? $motion->z : 0.0) + ])) + ->setTag("Rotation", new ListTag([ + new FloatTag($yaw), + new FloatTag($pitch) + ])); } } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 9c21083d8..9748fd0de 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -800,8 +800,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $nbt->setInt("XpTotal", $this->totalXp); $nbt->setInt("XpSeed", $this->xpSeed); - $inventoryTag = new ListTag("Inventory", [], NBT::TAG_Compound); - $nbt->setTag($inventoryTag); + $inventoryTag = new ListTag([], NBT::TAG_Compound); + $nbt->setTag("Inventory", $inventoryTag); if($this->inventory !== null){ //Normal inventory $slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize(); @@ -835,17 +835,17 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $nbt->setTag(new ListTag("EnderChestInventory", $items, NBT::TAG_Compound)); + $nbt->setTag("EnderChestInventory", new ListTag($items, NBT::TAG_Compound)); } if($this->skin !== null){ - $nbt->setTag(new CompoundTag("Skin", [ - new StringTag("Name", $this->skin->getSkinId()), - new ByteArrayTag("Data", $this->skin->getSkinData()), - new ByteArrayTag("CapeData", $this->skin->getCapeData()), - new StringTag("GeometryName", $this->skin->getGeometryName()), - new ByteArrayTag("GeometryData", $this->skin->getGeometryData()) - ])); + $nbt->setTag("Skin", CompoundTag::create() + ->setString("Name", $this->skin->getSkinId()) + ->setByteArray("Data", $this->skin->getSkinData()) + ->setByteArray("CapeData", $this->skin->getCapeData()) + ->setString("GeometryName", $this->skin->getGeometryName()) + ->setByteArray("GeometryData", $this->skin->getGeometryData()) + ); } return $nbt; diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 7b18eb7ae..0f41ed146 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -42,10 +42,8 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -178,16 +176,15 @@ abstract class Living extends Entity implements Damageable{ if(count($this->effects) > 0){ $effects = []; foreach($this->effects as $effect){ - $effects[] = new CompoundTag("", [ - new ByteTag("Id", $effect->getId()), - new ByteTag("Amplifier", Binary::signByte($effect->getAmplifier())), - new IntTag("Duration", $effect->getDuration()), - new ByteTag("Ambient", $effect->isAmbient() ? 1 : 0), - new ByteTag("ShowParticles", $effect->isVisible() ? 1 : 0) - ]); + $effects[] = CompoundTag::create() + ->setByte("Id", $effect->getId()) + ->setByte("Amplifier", Binary::signByte($effect->getAmplifier())) + ->setInt("Duration", $effect->getDuration()) + ->setByte("Ambient", $effect->isAmbient() ? 1 : 0) + ->setByte("ShowParticles", $effect->isVisible() ? 1 : 0); } - $nbt->setTag(new ListTag("ActiveEffects", $effects)); + $nbt->setTag("ActiveEffects", new ListTag($effects)); } return $nbt; diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 415b6a196..74baf8e48 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -134,7 +134,7 @@ class ItemEntity extends Entity{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setTag($this->item->nbtSerialize(-1, "Item")); + $nbt->setTag("Item", $this->item->nbtSerialize()); $nbt->setShort("Health", (int) $this->getHealth()); if($this->despawnDelay === self::NEVER_DESPAWN){ $age = -32768; diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 7db0be713..469e0f3b2 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -29,9 +29,7 @@ use pocketmine\block\BlockFactory; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\tile\Banner as TileBanner; class Banner extends Item{ @@ -81,15 +79,15 @@ class Banner extends Item{ * @param Deque|BannerPattern[] $patterns */ public function setPatterns(Deque $patterns) : void{ - $tag = new ListTag(self::TAG_PATTERNS); + $tag = new ListTag(); /** @var BannerPattern $pattern */ foreach($patterns as $pattern){ - $tag->push(new CompoundTag("", [ - new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), - new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ])); + $tag->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); } - $this->getNamedTag()->setTag($tag); + $this->getNamedTag()->setTag(self::TAG_PATTERNS, $tag); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 4b243e415..c4efba3ae 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -36,11 +36,11 @@ use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\Player; use pocketmine\utils\Binary; use function array_map; @@ -199,10 +199,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function setCustomBlockData(CompoundTag $compound) : Item{ - $tags = clone $compound; - $tags->setName(self::TAG_BLOCK_ENTITY_TAG); - $this->getNamedTag()->setTag($tags); - + $this->getNamedTag()->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $compound); return $this; } @@ -311,15 +308,15 @@ class Item implements ItemIds, \JsonSerializable{ $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if(!($ench instanceof ListTag)){ - $ench = new ListTag(self::TAG_ENCH, [], NBT::TAG_Compound); + $ench = new ListTag([], NBT::TAG_Compound); }else{ /** @var CompoundTag $entry */ foreach($ench as $k => $entry){ if($entry->getShort("id") === $enchantment->getId()){ - $ench->set($k, new CompoundTag("", [ - new ShortTag("id", $enchantment->getId()), - new ShortTag("lvl", $enchantment->getLevel()) - ])); + $ench->set($k, CompoundTag::create() + ->setShort("id", $enchantment->getId()) + ->setShort("lvl", $enchantment->getLevel()) + ); $found = true; break; } @@ -327,13 +324,13 @@ class Item implements ItemIds, \JsonSerializable{ } if(!$found){ - $ench->push(new CompoundTag("", [ - new ShortTag("id", $enchantment->getId()), - new ShortTag("lvl", $enchantment->getLevel()) - ])); + $ench->push(CompoundTag::create() + ->setShort("id", $enchantment->getId()) + ->setShort("lvl", $enchantment->getLevel()) + ); } - $this->getNamedTag()->setTag($ench); + $this->getNamedTag()->setTag(self::TAG_ENCH, $ench); return $this; } @@ -418,12 +415,12 @@ class Item implements ItemIds, \JsonSerializable{ /** @var CompoundTag $display */ $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if(!($display instanceof CompoundTag)){ - $display = new CompoundTag(self::TAG_DISPLAY); + if($display === null){ + $display = new CompoundTag(); } $display->setString(self::TAG_DISPLAY_NAME, $name); - $this->getNamedTag()->setTag($display); + $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); return $this; } @@ -439,7 +436,7 @@ class Item implements ItemIds, \JsonSerializable{ if($display->getCount() === 0){ $this->getNamedTag()->removeTag(self::TAG_DISPLAY); }else{ - $this->getNamedTag()->setTag($display); + $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); } } @@ -466,14 +463,14 @@ class Item implements ItemIds, \JsonSerializable{ public function setLore(array $lines) : Item{ $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if(!($display instanceof CompoundTag)){ - $display = new CompoundTag(self::TAG_DISPLAY, []); + $display = new CompoundTag(); } - $display->setTag(new ListTag(self::TAG_DISPLAY_LORE, array_map(function(string $str) : StringTag{ - return new StringTag("", $str); + $display->setTag(self::TAG_DISPLAY_LORE, new ListTag(array_map(function(string $str) : StringTag{ + return new StringTag($str); }, $lines), NBT::TAG_String)); - $this->getNamedTag()->setTag($display); + $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); return $this; } @@ -493,7 +490,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag */ public function getNamedTag() : CompoundTag{ - return $this->nbt ?? ($this->nbt = new CompoundTag("")); + return $this->nbt ?? ($this->nbt = new CompoundTag()); } /** @@ -790,7 +787,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode((new LittleEndianNbtSerializer())->write($this->nbt)) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->nbt))) : ""); } /** @@ -812,7 +809,7 @@ class Item implements ItemIds, \JsonSerializable{ } if($this->hasNamedTag()){ - $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write($this->getNamedTag())); + $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))); } return $data; @@ -839,29 +836,25 @@ class Item implements ItemIds, \JsonSerializable{ $nbt = base64_decode($data["nbt_b64"], true); } return ItemFactory::get( - (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt) : null + (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->getTag() : null ); } /** * Serializes the item to an NBT CompoundTag * - * @param int $slot optional, the inventory slot of the item - * @param string $tagName the name to assign to the CompoundTag object + * @param int $slot optional, the inventory slot of the item * * @return CompoundTag */ - public function nbtSerialize(int $slot = -1, string $tagName = "") : CompoundTag{ - $result = new CompoundTag($tagName, [ - new ShortTag("id", $this->id), - new ByteTag("Count", Binary::signByte($this->count)), - new ShortTag("Damage", $this->getMeta()) - ]); + public function nbtSerialize(int $slot = -1) : CompoundTag{ + $result = CompoundTag::create() + ->setShort("id", $this->id) + ->setByte("Count", Binary::signByte($this->count)) + ->setShort("Damage", $this->getMeta()); if($this->hasNamedTag()){ - $itemNBT = clone $this->getNamedTag(); - $itemNBT->setName("tag"); - $result->setTag($itemNBT); + $result->setTag("tag", clone $this->getNamedTag()); } if($slot !== -1){ @@ -902,11 +895,8 @@ class Item implements ItemIds, \JsonSerializable{ } $itemNBT = $tag->getCompoundTag("tag"); - if($itemNBT instanceof CompoundTag){ - /** @var CompoundTag $t */ - $t = clone $itemNBT; - $t->setName(""); - $item->setNamedTag($t); + if($itemNBT !== null){ + $item->setNamedTag(clone $itemNBT); } return $item; diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index 3040bb7bb..cc1a311cf 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -26,7 +26,6 @@ namespace pocketmine\item; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; class WritableBook extends Item{ @@ -91,7 +90,7 @@ class WritableBook extends Item{ $page = $pagesTag->get($pageId); $page->setString(self::TAG_PAGE_TEXT, $pageText); - $this->getNamedTag()->setTag($pagesTag); + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); return $created; } @@ -110,13 +109,13 @@ class WritableBook extends Item{ $pagesTag = $this->getPagesTag(); for($current = $pagesTag->count(); $current <= $pageId; $current++){ - $pagesTag->push(new CompoundTag("", [ - new StringTag(self::TAG_PAGE_TEXT, ""), - new StringTag(self::TAG_PAGE_PHOTONAME, "") - ])); + $pagesTag->push(CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, "") + ->setString(self::TAG_PAGE_PHOTONAME, "") + ); } - $this->getNamedTag()->setTag($pagesTag); + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); } /** @@ -144,12 +143,12 @@ class WritableBook extends Item{ public function insertPage(int $pageId, string $pageText = "") : bool{ $pagesTag = $this->getPagesTag(); - $pagesTag->insert($pageId, new CompoundTag("", [ - new StringTag(self::TAG_PAGE_TEXT, $pageText), - new StringTag(self::TAG_PAGE_PHOTONAME, "") - ])); + $pagesTag->insert($pageId, CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, $pageText) + ->setString(self::TAG_PAGE_PHOTONAME, "") + ); - $this->getNamedTag()->setTag($pagesTag); + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); return true; } @@ -194,7 +193,7 @@ class WritableBook extends Item{ } protected function getPagesTag() : ListTag{ - return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag(self::TAG_PAGES, [], NBT::TAG_Compound); + return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag([], NBT::TAG_Compound); } /** @@ -203,7 +202,7 @@ class WritableBook extends Item{ */ public function setPages(array $pages) : void{ $nbt = $this->getNamedTag(); - $nbt->setTag(new ListTag(self::TAG_PAGES, $pages, NBT::TAG_Compound)); + $nbt->setTag(self::TAG_PAGES, new ListTag($pages, NBT::TAG_Compound)); $this->setNamedTag($nbt); } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 468741093..150dd15dc 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1630,22 +1630,21 @@ class Level implements ChunkManager, Metadatable{ * @return ItemEntity|null */ public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10) : ?ItemEntity{ - $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); - $itemTag = $item->nbtSerialize(); - $itemTag->setName("Item"); - - if(!$item->isNull()){ - $nbt = EntityFactory::createBaseNBT($source, $motion, lcg_value() * 360, 0); - $nbt->setShort("Health", 5); - $nbt->setShort("PickupDelay", $delay); - $nbt->setTag($itemTag); - - /** @var ItemEntity $itemEntity */ - $itemEntity = EntityFactory::create(ItemEntity::class, $this, $nbt); - $itemEntity->spawnToAll(); - return $itemEntity; + if($item->isNull()){ + return null; } - return null; + + $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); + $nbt = EntityFactory::createBaseNBT($source, $motion, lcg_value() * 360, 0); + $nbt->setShort("Health", 5); + $nbt->setShort("PickupDelay", $delay); + $nbt->setTag("Item", $item->nbtSerialize()); + + /** @var ItemEntity $itemEntity */ + $itemEntity = EntityFactory::create(ItemEntity::class, $this, $nbt); + $itemEntity->spawnToAll(); + return $itemEntity; + } /** diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index d70b34309..7f793b939 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -29,12 +29,10 @@ use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\LittleEndianNbtSerializer; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; use pocketmine\utils\Utils; @@ -63,51 +61,50 @@ class BedrockLevelData extends BaseNbtLevelData{ //TODO: add support for limited worlds } - $levelData = new CompoundTag("", [ + $levelData = CompoundTag::create() //Vanilla fields - new IntTag("DayCycleStopTime", -1), - new IntTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("ForceGameType", 0), - new IntTag("GameType", 0), - new IntTag("Generator", $generatorType), - new LongTag("LastPlayed", time()), - new StringTag("LevelName", $name), - new IntTag("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL), - //new IntTag("Platform", 2), //TODO: find out what the possible values are for - new LongTag("RandomSeed", $seed), - new IntTag("SpawnX", 0), - new IntTag("SpawnY", 32767), - new IntTag("SpawnZ", 0), - new IntTag("StorageVersion", self::CURRENT_STORAGE_VERSION), - new LongTag("Time", 0), - new ByteTag("eduLevel", 0), - new ByteTag("falldamage", 1), - new ByteTag("firedamage", 1), - new ByteTag("hasBeenLoadedInCreative", 1), //badly named, this actually determines whether achievements can be earned in this world... - new ByteTag("immutableWorld", 0), - new FloatTag("lightningLevel", 0.0), - new IntTag("lightningTime", 0), - new ByteTag("pvp", 1), - new FloatTag("rainLevel", 0.0), - new IntTag("rainTime", 0), - new ByteTag("spawnMobs", 1), - new ByteTag("texturePacksRequired", 0), //TODO + ->setInt("DayCycleStopTime", -1) + ->setInt("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setByte("ForceGameType", 0) + ->setInt("GameType", 0) + ->setInt("Generator", $generatorType) + ->setLong("LastPlayed", time()) + ->setString("LevelName", $name) + ->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL) + //->setInt("Platform", 2) //TODO: find out what the possible values are for + ->setLong("RandomSeed", $seed) + ->setInt("SpawnX", 0) + ->setInt("SpawnY", 32767) + ->setInt("SpawnZ", 0) + ->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION) + ->setLong("Time", 0) + ->setByte("eduLevel", 0) + ->setByte("falldamage", 1) + ->setByte("firedamage", 1) + ->setByte("hasBeenLoadedInCreative", 1) //badly named, this actually determines whether achievements can be earned in this world... + ->setByte("immutableWorld", 0) + ->setFloat("lightningLevel", 0.0) + ->setInt("lightningTime", 0) + ->setByte("pvp", 1) + ->setFloat("rainLevel", 0.0) + ->setInt("rainTime", 0) + ->setByte("spawnMobs", 1) + ->setByte("texturePacksRequired", 0) //TODO //Additional PocketMine-MP fields - new CompoundTag("GameRules", []), - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? "") - ]); + ->setTag("GameRules", new CompoundTag()) + ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) + ->setString("generatorName", GeneratorManager::getGeneratorName($generator)) + ->setString("generatorOptions", $options["preset"] ?? ""); $nbt = new LittleEndianNbtSerializer(); - $buffer = $nbt->write($levelData); + $buffer = $nbt->write(new TreeRoot($levelData)); file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } protected function load() : ?CompoundTag{ $nbt = new LittleEndianNbtSerializer(); - $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8)); + $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); $version = $levelData->getInt("StorageVersion", INT32_MAX, true); if($version > self::CURRENT_STORAGE_VERSION){ @@ -152,7 +149,7 @@ class BedrockLevelData extends BaseNbtLevelData{ $this->compoundTag->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); $nbt = new LittleEndianNbtSerializer(); - $buffer = $nbt->write($this->compoundTag); + $buffer = $nbt->write(new TreeRoot($this->compoundTag)); file_put_contents($this->dataPath, Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index ac1aa39f2..c360b1dec 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -27,12 +27,10 @@ use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\utils\Utils; use function ceil; use function file_get_contents; @@ -44,36 +42,34 @@ class JavaLevelData extends BaseNbtLevelData{ public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ Utils::testValidInstance($generator, Generator::class); //TODO, add extra details - $levelData = new CompoundTag("Data", [ - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new ByteTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("initialized", 1), - new IntTag("GameType", 0), - new IntTag("generatorVersion", 1), //2 in MCPE - new IntTag("SpawnX", 256), - new IntTag("SpawnY", 70), - new IntTag("SpawnZ", 256), - new IntTag("version", $version), - new IntTag("DayTime", 0), - new LongTag("LastPlayed", (int) (microtime(true) * 1000)), - new LongTag("RandomSeed", $seed), - new LongTag("SizeOnDisk", 0), - new LongTag("Time", 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? ""), - new StringTag("LevelName", $name), - new CompoundTag("GameRules", []) - ]); + $levelData = CompoundTag::create() + ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) + ->setByte("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setByte("initialized", 1) + ->setInt("GameType", 0) + ->setInt("generatorVersion", 1) //2 in MCPE + ->setInt("SpawnX", 256) + ->setInt("SpawnY", 70) + ->setInt("SpawnZ", 256) + ->setInt("version", $version) + ->setInt("DayTime", 0) + ->setLong("LastPlayed", (int) (microtime(true) * 1000)) + ->setLong("RandomSeed", $seed) + ->setLong("SizeOnDisk", 0) + ->setLong("Time", 0) + ->setString("generatorName", GeneratorManager::getGeneratorName($generator)) + ->setString("generatorOptions", $options["preset"] ?? "") + ->setString("LevelName", $name) + ->setTag("GameRules", new CompoundTag()); + $nbt = new BigEndianNbtSerializer(); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $levelData - ])); + $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $levelData))); file_put_contents($path . "level.dat", $buffer); } protected function load() : ?CompoundTag{ $nbt = new BigEndianNbtSerializer(); - $levelData = $nbt->readCompressed(file_get_contents($this->dataPath)); + $levelData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); if($levelData->hasTag("Data", CompoundTag::class)){ return $levelData->getCompoundTag("Data"); } @@ -94,10 +90,7 @@ class JavaLevelData extends BaseNbtLevelData{ public function save() : void{ $nbt = new BigEndianNbtSerializer(); - $this->compoundTag->setName("Data"); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $this->compoundTag - ])); + $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $this->compoundTag))); file_put_contents($this->dataPath, $buffer); } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 195271cbd..ecf9ad567 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -40,14 +40,13 @@ use pocketmine\level\generator\Generator; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ShortTag; -use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; use function array_flip; +use function array_map; use function array_values; use function chr; use function count; @@ -159,7 +158,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $palette = []; for($i = 0, $paletteSize = $stream->getLInt(); $i < $paletteSize; ++$i){ $offset = $stream->getOffset(); - $tag = $nbt->read($stream->getBuffer(), $offset); + $tag = $nbt->read($stream->getBuffer(), $offset)->getTag(); $stream->setOffset($offset); $id = $stringToLegacyId[$tag->getString("name")] ?? BlockIds::INFO_UPDATE; @@ -303,7 +302,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and $entityData !== ""){ try{ - $entities = $nbt->readMultiple($entityData); + $entities = array_map(function(TreeRoot $root) : CompoundTag{ return $root->getTag(); }, $nbt->readMultiple($entityData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -313,7 +312,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ try{ - $tiles = $nbt->readMultiple($tileData); + $tiles = array_map(function(TreeRoot $root) : CompoundTag{ return $root->getTag(); }, $nbt->readMultiple($tileData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -379,11 +378,10 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $subStream->putLInt(count($palette)); $tags = []; foreach($palette as $p){ - $tags[] = new CompoundTag("", [ - new StringTag("name", $idMap[$p >> 4] ?? "minecraft:info_update"), - new IntTag("oldid", $p >> 4), //PM only (debugging), vanilla doesn't have this - new ShortTag("val", $p & 0xf) - ]); + $tags[] = new TreeRoot(CompoundTag::create() + ->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update") + ->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this + ->setShort("val", $p & 0xf)); } $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); @@ -415,7 +413,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{ if(!empty($targets)){ $nbt = new LittleEndianNbtSerializer(); - $write->put($index, $nbt->writeMultiple($targets)); + $write->put($index, $nbt->writeMultiple(array_map(function(CompoundTag $tag) : TreeRoot{ return new TreeRoot($tag); }, $targets))); }else{ $write->delete($index); } diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index a60c914e3..978c8a69a 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -59,7 +59,7 @@ trait LegacyAnvilChunkTrait{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data); + $chunk = $nbt->readCompressed($data)->getTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index c4a81aa14..56146df0a 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -56,7 +56,7 @@ class McRegion extends RegionLevelProvider{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data); + $chunk = $nbt->readCompressed($data)->getTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 54c918524..aceb3c60c 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -31,6 +31,8 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; @@ -96,13 +98,14 @@ class NetworkBinaryStream extends BinaryStream{ $cnt = $auxValue & 0xff; $nbtLen = $this->getLShort(); + /** @var CompoundTag|null $compound */ $compound = null; if($nbtLen === 0xffff){ $c = $this->getByte(); if($c !== 1){ throw new BadPacketException("Unexpected NBT count $c"); } - $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset); + $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset)->getTag(); }elseif($nbtLen !== 0){ throw new BadPacketException("Unexpected fake NBT length $nbtLen"); } @@ -143,7 +146,7 @@ class NetworkBinaryStream extends BinaryStream{ if($item->hasNamedTag()){ $this->putLShort(0xffff); $this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0 - $this->put((new NetworkNbtSerializer())->write($item->getNamedTag())); + $this->put((new NetworkNbtSerializer())->write(new TreeRoot($item->getNamedTag()))); }else{ $this->putLShort(0); } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index bb09244ad..c329737f6 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -398,7 +398,7 @@ class SimpleSessionHandler extends SessionHandler{ $block = $this->player->getLevel()->getBlock($pos); try{ - $nbt = (new NetworkNbtSerializer())->read($packet->namedtag); + $nbt = (new NetworkNbtSerializer())->read($packet->namedtag)->getTag(); }catch(NbtDataException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 839c6ca72..6da72e874 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -31,7 +31,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; /** * @deprecated @@ -72,26 +71,26 @@ class Banner extends Spawnable{ protected function writeSaveData(CompoundTag $nbt) : void{ $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); - $patterns = new ListTag(self::TAG_PATTERNS); + $patterns = new ListTag(); foreach($this->patterns as $pattern){ - $patterns->push(new CompoundTag("", [ - new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), - new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ])); + $patterns->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); } - $nbt->setTag($patterns); + $nbt->setTag(self::TAG_PATTERNS, $patterns); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); - $patterns = new ListTag(self::TAG_PATTERNS); + $patterns = new ListTag(); foreach($this->patterns as $pattern){ - $patterns->push(new CompoundTag("", [ - new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), - new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ])); + $patterns->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); } - $nbt->setTag($patterns); + $nbt->setTag(self::TAG_PATTERNS, $patterns); } /** diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/tile/ContainerTrait.php index b09bfb42c..efacc7bd2 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/tile/ContainerTrait.php @@ -69,7 +69,7 @@ trait ContainerTrait{ $items[] = $item->nbtSerialize($slot); } - $tag->setTag(new ListTag(Container::TAG_ITEMS, $items, NBT::TAG_Compound)); + $tag->setTag(Container::TAG_ITEMS, new ListTag($items, NBT::TAG_Compound)); if($this->lock !== null){ $tag->setString(Container::TAG_LOCK, $this->lock); diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 9d041e6e8..0841f540c 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -61,7 +61,7 @@ class ItemFrame extends Spawnable{ 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)); + $nbt->setTag(self::TAG_ITEM, $this->item->nbtSerialize()); } public function hasItem() : bool{ @@ -102,6 +102,6 @@ class ItemFrame extends Spawnable{ protected function addAdditionalSpawnData(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)); + $nbt->setTag(self::TAG_ITEM, $this->item->nbtSerialize()); } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 0d707bce2..0eaac5461 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\NetworkNbtSerializer; use function get_class; @@ -76,7 +75,7 @@ abstract class Spawnable extends Tile{ self::$nbtWriter = new NetworkNbtSerializer(); } - $this->spawnCompoundCache = self::$nbtWriter->write($this->getSpawnCompound()); + $this->spawnCompoundCache = self::$nbtWriter->write(new TreeRoot($this->getSpawnCompound())); } return $this->spawnCompoundCache; @@ -86,12 +85,11 @@ abstract class Spawnable extends Tile{ * @return CompoundTag */ final public function getSpawnCompound() : CompoundTag{ - $nbt = new CompoundTag("", [ - new StringTag(self::TAG_ID, TileFactory::getSaveId(get_class($this))), //TODO: disassociate network ID from save ID - new IntTag(self::TAG_X, $this->x), - new IntTag(self::TAG_Y, $this->y), - new IntTag(self::TAG_Z, $this->z) - ]); + $nbt = CompoundTag::create() + ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) //TODO: disassociate network ID from save ID + ->setInt(self::TAG_X, $this->x) + ->setInt(self::TAG_Y, $this->y) + ->setInt(self::TAG_Z, $this->z); $this->addAdditionalSpawnData($nbt); return $nbt; } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 4cadd2b51..c0caea151 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -72,18 +72,18 @@ abstract class Tile extends Position{ abstract protected function writeSaveData(CompoundTag $nbt) : void; public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(""); - $nbt->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))); - $nbt->setInt(self::TAG_X, $this->x); - $nbt->setInt(self::TAG_Y, $this->y); - $nbt->setInt(self::TAG_Z, $this->z); + $nbt = CompoundTag::create() + ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) + ->setInt(self::TAG_X, $this->x) + ->setInt(self::TAG_Y, $this->y) + ->setInt(self::TAG_Z, $this->z); $this->writeSaveData($nbt); return $nbt; } public function getCleanedNBT() : ?CompoundTag{ - $this->writeSaveData($tag = new CompoundTag("")); + $this->writeSaveData($tag = new CompoundTag()); return $tag->getCount() > 0 ? $tag : null; }