From 69640124644e54a661f77cb1f1d73a8407557958 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Jun 2022 19:34:08 +0100 Subject: [PATCH] fix a bunch of bugs --- src/block/tile/ContainerTrait.php | 9 ++++++- .../block/upgrade/BlockDataUpgrader.php | 2 ++ .../bedrock/item/upgrade/ItemDataUpgrader.php | 14 +++++++++- .../item/upgrade/ItemIdMetaUpgradeSchema.php | 4 +-- .../item/upgrade/R12ItemIdToBlockIdMap.php | 26 ++++++++++++++----- src/item/Item.php | 8 ++++-- 6 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 1274614d0..cbbc98843 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\tile; +use pocketmine\data\SavedDataLoadingException; use pocketmine\inventory\Inventory; use pocketmine\item\Item; use pocketmine\nbt\NBT; @@ -49,7 +50,13 @@ trait ContainerTrait{ $newContents = []; /** @var CompoundTag $itemNBT */ foreach($inventoryTag as $itemNBT){ - $newContents[$itemNBT->getByte("Slot")] = Item::nbtDeserialize($itemNBT); + try{ + $newContents[$itemNBT->getByte("Slot")] = Item::nbtDeserialize($itemNBT); + }catch(SavedDataLoadingException $e){ + //TODO: not the best solution + \GlobalLogger::get()->logException($e); + continue; + } } $inventory->setContents($newContents); diff --git a/src/data/bedrock/block/upgrade/BlockDataUpgrader.php b/src/data/bedrock/block/upgrade/BlockDataUpgrader.php index 63faa3532..a10c30d7e 100644 --- a/src/data/bedrock/block/upgrade/BlockDataUpgrader.php +++ b/src/data/bedrock/block/upgrade/BlockDataUpgrader.php @@ -60,4 +60,6 @@ final class BlockDataUpgrader{ return $this->blockStateUpgrader->upgrade($blockStateData); } + + public function getBlockStateUpgrader() : BlockStateUpgrader{ return $this->blockStateUpgrader; } } diff --git a/src/data/bedrock/item/upgrade/ItemDataUpgrader.php b/src/data/bedrock/item/upgrade/ItemDataUpgrader.php index e55513c9a..ba42e4039 100644 --- a/src/data/bedrock/item/upgrade/ItemDataUpgrader.php +++ b/src/data/bedrock/item/upgrade/ItemDataUpgrader.php @@ -70,6 +70,9 @@ final class ItemDataUpgrader{ ksort($this->idMetaUpgradeSchemas, SORT_NUMERIC); } + /** + * @throws SavedDataLoadingException + */ private function upgradeItemTypeNbt(CompoundTag $tag) : SavedItemData{ if(($nameIdTag = $tag->getTag(SavedItemData::TAG_NAME)) instanceof StringTag){ //Bedrock 1.6+ @@ -98,6 +101,11 @@ final class ItemDataUpgrader{ }elseif(($r12BlockId = $this->r12ItemIdToBlockIdMap->itemIdToBlockId($rawNameId)) !== null){ //this is a legacy blockitem represented by ID + meta $blockStateData = $this->blockDataUpgrader->upgradeStringIdMeta($r12BlockId, $meta); + if($blockStateData === null){ + throw new SavedDataLoadingException("Expected a blockstate to be associated with this block"); + } + //the block data upgrader returns states from 1.18.10, which need to be updated to the current version the usual way + $blockStateData = $this->blockDataUpgrader->getBlockStateUpgrader()->upgrade($blockStateData); }else{ //probably a standard item $blockStateData = null; @@ -112,6 +120,7 @@ final class ItemDataUpgrader{ /** * @return string[] + * @throws SavedDataLoadingException */ private static function deserializeListOfStrings(?ListTag $list, string $tagName) : array{ if($list === null){ @@ -129,6 +138,9 @@ final class ItemDataUpgrader{ return $result; } + /** + * @throws SavedDataLoadingException + */ public function upgradeItemStackNbt(CompoundTag $tag) : SavedItemStackData{ $savedItemData = $this->upgradeItemTypeNbt($tag); try{ @@ -169,6 +181,6 @@ final class ItemDataUpgrader{ } } - return [$id, $meta]; + return [$newId, $newMeta]; } } diff --git a/src/data/bedrock/item/upgrade/ItemIdMetaUpgradeSchema.php b/src/data/bedrock/item/upgrade/ItemIdMetaUpgradeSchema.php index f0b398acb..74175c560 100644 --- a/src/data/bedrock/item/upgrade/ItemIdMetaUpgradeSchema.php +++ b/src/data/bedrock/item/upgrade/ItemIdMetaUpgradeSchema.php @@ -40,10 +40,10 @@ final class ItemIdMetaUpgradeSchema{ public function getPriority() : int{ return $this->priority; } public function renameId(string $id) : ?string{ - return $this->renamedIds[$id] ?? null; + return $this->renamedIds[mb_strtolower($id, 'US-ASCII')] ?? null; } public function remapMeta(string $id, int $meta) : ?string{ - return $this->remappedMetas[$id][$meta] ?? null; + return $this->remappedMetas[mb_strtolower($id, 'US-ASCII')][$meta] ?? null; } } diff --git a/src/data/bedrock/item/upgrade/R12ItemIdToBlockIdMap.php b/src/data/bedrock/item/upgrade/R12ItemIdToBlockIdMap.php index 723e8d993..bd4866f97 100644 --- a/src/data/bedrock/item/upgrade/R12ItemIdToBlockIdMap.php +++ b/src/data/bedrock/item/upgrade/R12ItemIdToBlockIdMap.php @@ -68,20 +68,34 @@ final class R12ItemIdToBlockIdMap{ return new self($builtMap); } + /** + * @var string[] + * @phpstan-var array + */ + private array $itemToBlock = []; + /** + * @var string[] + * @phpstan-var array + */ + private array $blockToItem = []; + /** * @param string[] $itemToBlock * @phpstan-param array $itemToBlock */ - public function __construct(private array $itemToBlock){} + public function __construct(array $itemToBlock){ + foreach($itemToBlock as $itemId => $blockId){ + $this->itemToBlock[mb_strtolower($itemId, 'US-ASCII')] = $blockId; + $this->blockToItem[mb_strtolower($blockId, 'US-ASCII')] = $itemId; + } + } public function itemIdToBlockId(string $itemId) : ?string{ - return $this->itemToBlock[$itemId] ?? null; + return $this->itemToBlock[mb_strtolower($itemId, 'US-ASCII')] ?? null; } public function blockIdToItemId(string $blockId) : ?string{ - //we don't need this for any functionality, so we're not concerned about performance here - //however, it might be nice to have for debugging - $itemId = array_search($blockId, $this->itemToBlock, true); - return $itemId !== false ? $itemId : null; + //we don't need this for any functionality, but it might be nice to have for debugging + return $this->blockToItem[mb_strtolower($blockId, 'US-ASCII')] ?? null; } } diff --git a/src/item/Item.php b/src/item/Item.php index dd5e088fb..6aabbf313 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -31,6 +31,7 @@ use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockToolType; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\EnchantmentIdMap; +use pocketmine\data\bedrock\item\ItemTypeDeserializeException; use pocketmine\data\bedrock\item\SavedItemStackData; use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\Entity; @@ -661,13 +662,16 @@ class Item implements \JsonSerializable{ /** * Deserializes an Item from an NBT CompoundTag - * @throws NbtException * @throws SavedDataLoadingException */ public static function nbtDeserialize(CompoundTag $tag) : Item{ $itemData = GlobalItemDataHandlers::getUpgrader()->upgradeItemStackNbt($tag); - $item = GlobalItemDataHandlers::getDeserializer()->deserialize($itemData->getTypeData()); + try{ + $item = GlobalItemDataHandlers::getDeserializer()->deserialize($itemData->getTypeData()); + }catch(ItemTypeDeserializeException $e){ + throw new SavedDataLoadingException($e->getMessage(), 0, $e); + } $item->setCount($itemData->getCount()); if(($tagTag = $itemData->getTypeData()->getTag()) !== null){