TypeConverter: use a less slow hack to restore meta values on items sent by the client

this isn't even really needed anymore, since we don't decode items from the client since 4.18.

However, this may still be useful for tools.
This commit is contained in:
Dylan K. Taylor 2023-04-18 15:00:34 +01:00
parent 40168a457e
commit 6102740ee3
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -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;