TypeConverter: account for items without properly mapped IDs

fixes #4459
This commit is contained in:
Dylan K. Taylor 2021-10-11 15:05:08 +01:00
parent 19a66a8d03
commit 8ac16345a3
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 50 additions and 19 deletions

View File

@ -142,10 +142,10 @@ final class ItemTranslator{
} }
/** /**
* @return int[] * @return int[]|null
* @phpstan-return array{int, int} * @phpstan-return array{int, int}|null
*/ */
public function toNetworkId(int $internalId, int $internalMeta) : array{ public function toNetworkIdQuiet(int $internalId, int $internalMeta) : ?array{
if($internalMeta === -1){ if($internalMeta === -1){
$internalMeta = 0x7fff; $internalMeta = 0x7fff;
} }
@ -156,6 +156,15 @@ final class ItemTranslator{
return [$this->simpleCoreToNetMapping[$internalId], $internalMeta]; return [$this->simpleCoreToNetMapping[$internalId], $internalMeta];
} }
return null;
}
/**
* @return int[]
* @phpstan-return array{int, int}
*/
public function toNetworkId(int $internalId, int $internalMeta) : array{
return $this->toNetworkIdQuiet($internalId, $internalMeta) ??
throw new \InvalidArgumentException("Unmapped ID/metadata combination $internalId:$internalMeta"); throw new \InvalidArgumentException("Unmapped ID/metadata combination $internalId:$internalMeta");
} }

View File

@ -58,6 +58,7 @@ class TypeConverter{
private const DAMAGE_TAG = "Damage"; //TAG_Int private const DAMAGE_TAG = "Damage"; //TAG_Int
private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___"; private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___";
private const PM_ID_TAG = "___Id___";
private const PM_META_TAG = "___Meta___"; private const PM_META_TAG = "___Meta___";
/** @var int */ /** @var int */
@ -143,6 +144,20 @@ class TypeConverter{
} }
$isBlockItem = $itemStack->getId() < 256; $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
//other unmapped items.
[$id, $meta] = ItemTranslator::getInstance()->toNetworkId(ItemIds::INFO_UPDATE, 0);
if($nbt === null){
$nbt = new CompoundTag();
}
$nbt->setInt(self::PM_ID_TAG, $itemStack->getId());
$nbt->setInt(self::PM_META_TAG, $itemStack->getMeta());
}else{
[$id, $meta] = $idMeta;
if($itemStack instanceof Durable and $itemStack->getDamage() > 0){ if($itemStack instanceof Durable and $itemStack->getDamage() > 0){
if($nbt !== null){ if($nbt !== null){
if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){ if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){
@ -162,7 +177,7 @@ class TypeConverter{
} }
$nbt->setInt(self::PM_META_TAG, $itemStack->getMeta()); $nbt->setInt(self::PM_META_TAG, $itemStack->getMeta());
} }
[$id, $meta] = ItemTranslator::getInstance()->toNetworkId($itemStack->getId(), $itemStack->getMeta()); }
$blockRuntimeId = 0; $blockRuntimeId = 0;
if($isBlockItem){ if($isBlockItem){
@ -197,6 +212,13 @@ class TypeConverter{
if($compound !== null){ if($compound !== null){
$compound = clone $compound; $compound = clone $compound;
if(($idTag = $compound->getTag(self::PM_ID_TAG)) instanceof IntTag){
$id = $idTag->getValue();
$compound->removeTag(self::PM_ID_TAG);
if($compound->count() === 0){
$compound = null;
}
}
if(($damageTag = $compound->getTag(self::DAMAGE_TAG)) instanceof IntTag){ if(($damageTag = $compound->getTag(self::DAMAGE_TAG)) instanceof IntTag){
$meta = $damageTag->getValue(); $meta = $damageTag->getValue();
$compound->removeTag(self::DAMAGE_TAG); $compound->removeTag(self::DAMAGE_TAG);