diff --git a/src/block/tile/FlowerPot.php b/src/block/tile/FlowerPot.php index 3544cd5fb..e778d0774 100644 --- a/src/block/tile/FlowerPot.php +++ b/src/block/tile/FlowerPot.php @@ -31,6 +31,7 @@ use pocketmine\data\SavedDataLoadingException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\world\format\io\GlobalBlockStateHandlers; /** @@ -88,7 +89,7 @@ class FlowerPot extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ if($this->plant !== null){ - $nbt->setTag(self::TAG_PLANT_BLOCK, GlobalBlockStateHandlers::getSerializer()->serialize($this->plant->getStateId())->toNbt()); + $nbt->setTag(self::TAG_PLANT_BLOCK, RuntimeBlockMapping::getInstance()->toStateData($this->plant->getStateId())->toNbt()); } } } diff --git a/src/block/tile/ItemFrame.php b/src/block/tile/ItemFrame.php index 92db02d5f..7482fa089 100644 --- a/src/block/tile/ItemFrame.php +++ b/src/block/tile/ItemFrame.php @@ -27,6 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\convert\ItemTranslator; use pocketmine\world\World; /** @@ -99,7 +100,7 @@ class ItemFrame extends Spawnable{ $nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); $nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); if(!$this->item->isNull()){ - $nbt->setTag(self::TAG_ITEM, $this->item->nbtSerialize()); + $nbt->setTag(self::TAG_ITEM, ItemTranslator::getInstance()->toNetworkNbt($this->item)); } } } diff --git a/src/block/tile/Jukebox.php b/src/block/tile/Jukebox.php index 3154c6a07..12dd3c302 100644 --- a/src/block/tile/Jukebox.php +++ b/src/block/tile/Jukebox.php @@ -26,6 +26,7 @@ namespace pocketmine\block\tile; use pocketmine\item\Item; use pocketmine\item\Record; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\convert\ItemTranslator; class Jukebox extends Spawnable{ private const TAG_RECORD = "RecordItem"; //Item CompoundTag @@ -58,7 +59,7 @@ class Jukebox extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ //this is needed for the note particles to show on the client side if($this->record !== null){ - $nbt->setTag(self::TAG_RECORD, $this->record->nbtSerialize()); + $nbt->setTag(self::TAG_RECORD, ItemTranslator::getInstance()->toNetworkNbt($this->record)); } } } diff --git a/src/block/tile/Lectern.php b/src/block/tile/Lectern.php index 28be8904e..f094d2316 100644 --- a/src/block/tile/Lectern.php +++ b/src/block/tile/Lectern.php @@ -26,6 +26,7 @@ namespace pocketmine\block\tile; use pocketmine\item\Item; use pocketmine\item\WritableBookBase; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\convert\ItemTranslator; use function count; /** @@ -80,7 +81,7 @@ class Lectern extends Spawnable{ $nbt->setByte(self::TAG_HAS_BOOK, $this->book !== null ? 1 : 0); $nbt->setInt(self::TAG_PAGE, $this->viewedPage); if($this->book !== null){ - $nbt->setTag(self::TAG_BOOK, $this->book->nbtSerialize()); + $nbt->setTag(self::TAG_BOOK, ItemTranslator::getInstance()->toNetworkNbt($this->book)); $nbt->setInt(self::TAG_TOTAL_PAGES, count($this->book->getPages())); } } diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index eb36ecdd2..b5a90c8a4 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -28,6 +28,7 @@ use pocketmine\data\bedrock\item\ItemSerializer; use pocketmine\data\bedrock\item\ItemTypeDeserializeException; use pocketmine\data\bedrock\item\ItemTypeSerializeException; use pocketmine\data\bedrock\item\SavedItemData; +use pocketmine\data\bedrock\item\SavedItemStackData; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\utils\AssumptionFailedError; @@ -96,6 +97,16 @@ final class ItemTranslator{ return [$numericId, $itemData->getMeta(), $blockRuntimeId]; } + /** + * @throws ItemTypeSerializeException + */ + public function toNetworkNbt(Item $item) : SavedItemStackData{ + //TODO: this relies on the assumption that network item NBT is the same as disk item NBT, which may not always + //be true - if we stick on an older world version while updating network version, this could be a problem (and + //may be a problem for multi version implementations) + return $this->itemSerializer->serializeStack($item); + } + /** * @throws TypeConversionException */ diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index c5945e28d..20cea50cb 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -94,6 +94,18 @@ final class RuntimeBlockMapping{ return $this->networkIdCache[$internalStateId] = $networkId; } + /** + * Looks up the network state data associated with the given internal state ID. + */ + public function toStateData(int $internalStateId) : BlockStateData{ + //we don't directly use the blockstate serializer here - we can't assume that the network blockstate NBT is the + //same as the disk blockstate NBT, in case we decide to have different world version than network version (or in + //case someone wants to implement multi version). + $networkRuntimeId = $this->toRuntimeId($internalStateId); + + return $this->blockStateDictionary->getDataFromStateId($networkRuntimeId) ?? throw new AssumptionFailedError("We just looked up this state ID, so it must exist"); + } + public function getBlockStateDictionary() : BlockStateDictionary{ return $this->blockStateDictionary; } public function getFallbackStateData() : BlockStateData{ return $this->fallbackStateData; }