diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 3fe679196..09d5d4a2e 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\item\Durable; use pocketmine\item\Item; @@ -142,8 +143,6 @@ class TypeConverter{ $nbt = clone $nbt; } - $isBlockItem = $itemStack->getId() < 256; - $idMeta = ItemTranslator::getInstance()->toNetworkIdQuiet($itemStack->getId(), $itemStack->getMeta()); if($idMeta === null){ //Display unmapped items as INFO_UPDATE, but stick something in their NBT to make sure they don't stack with @@ -168,23 +167,15 @@ class TypeConverter{ } $nbt->setInt(self::DAMAGE_TAG, $itemStack->getDamage()); $meta = 0; - }elseif($isBlockItem && $itemStack->getMeta() !== 0){ - //TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the - //client sends it back to us, because as of 1.16.220, blockitems quietly discard their metadata - //client-side. Aside from being very annoying, this also breaks various server-side behaviours. - if($nbt === null){ - $nbt = new CompoundTag(); - } - $nbt->setInt(self::PM_META_TAG, $itemStack->getMeta()); - $meta = 0; } } $blockRuntimeId = 0; - if($isBlockItem){ + if($itemStack->getId() < 256){ $block = $itemStack->getBlock(); if($block->getId() !== BlockLegacyIds::AIR){ $blockRuntimeId = RuntimeBlockMapping::getInstance()->toRuntimeId($block->getFullId()); + $meta = 0; } } @@ -210,6 +201,11 @@ class TypeConverter{ $compound = $itemStack->getNbt(); [$id, $meta] = ItemTranslator::getInstance()->fromNetworkId($itemStack->getId(), $itemStack->getMeta()); + if($itemStack->getBlockRuntimeId() !== 0){ + //blockitem meta is zeroed out by the client, so we have to infer it from the block runtime ID + $blockFullId = RuntimeBlockMapping::getInstance()->fromRuntimeId($itemStack->getBlockRuntimeId()); + $meta = $blockFullId & Block::INTERNAL_METADATA_MASK; + } if($compound !== null){ $compound = clone $compound; @@ -224,12 +220,6 @@ class TypeConverter{ $compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION); $compound->setTag(self::DAMAGE_TAG, $conflicted); } - }elseif(($metaTag = $compound->getTag(self::PM_META_TAG)) instanceof IntTag){ - //TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the - //client sends it back to us, because as of 1.16.220, blockitems quietly discard their metadata - //client-side. Aside from being very annoying, this also breaks various server-side behaviours. - $meta = $metaTag->getValue(); - $compound->removeTag(self::PM_META_TAG); } if($compound->count() === 0){ $compound = null;