diff --git a/src/block/tile/FlowerPot.php b/src/block/tile/FlowerPot.php index d6c2c58fb..3f1d4ff2e 100644 --- a/src/block/tile/FlowerPot.php +++ b/src/block/tile/FlowerPot.php @@ -52,7 +52,11 @@ class FlowerPot extends Spawnable{ $blockDataUpgrader = GlobalBlockStateHandlers::getUpgrader(); if(($itemIdTag = $nbt->getTag(self::TAG_ITEM)) instanceof ShortTag && ($itemMetaTag = $nbt->getTag(self::TAG_ITEM_DATA)) instanceof IntTag){ - $blockStateData = $blockDataUpgrader->upgradeIntIdMeta($itemIdTag->getValue(), $itemMetaTag->getValue()); + try{ + $blockStateData = $blockDataUpgrader->upgradeIntIdMeta($itemIdTag->getValue(), $itemMetaTag->getValue()); + }catch(BlockStateDeserializeException $e){ + throw new SavedDataLoadingException("Error loading legacy flower pot item data: " . $e->getMessage(), 0, $e); + } }elseif(($plantBlockTag = $nbt->getCompoundTag(self::TAG_PLANT_BLOCK)) !== null){ try{ $blockStateData = $blockDataUpgrader->upgradeBlockStateNbt($plantBlockTag); diff --git a/src/data/bedrock/item/upgrade/ItemDataUpgrader.php b/src/data/bedrock/item/upgrade/ItemDataUpgrader.php index 46fce81ce..249b257e2 100644 --- a/src/data/bedrock/item/upgrade/ItemDataUpgrader.php +++ b/src/data/bedrock/item/upgrade/ItemDataUpgrader.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\data\bedrock\item\upgrade; +use pocketmine\data\bedrock\block\BlockStateDeserializeException; use pocketmine\data\bedrock\block\upgrade\BlockDataUpgrader; use pocketmine\data\bedrock\item\SavedItemData; use pocketmine\data\bedrock\item\SavedItemStackData; @@ -57,7 +58,11 @@ final class ItemDataUpgrader{ */ public function upgradeItemTypeDataString(string $rawNameId, int $meta, int $count, ?CompoundTag $nbt) : SavedItemStackData{ if(($r12BlockId = $this->r12ItemIdToBlockIdMap->itemIdToBlockId($rawNameId)) !== null){ - $blockStateData = $this->blockDataUpgrader->upgradeStringIdMeta($r12BlockId, $meta); + try{ + $blockStateData = $this->blockDataUpgrader->upgradeStringIdMeta($r12BlockId, $meta); + }catch(BlockStateDeserializeException $e){ + throw new SavedDataLoadingException("Failed to deserialize blockstate for legacy blockitem: " . $e->getMessage(), 0, $e); + } }else{ //probably a standard item $blockStateData = null; @@ -124,12 +129,17 @@ final class ItemDataUpgrader{ $blockStateNbt = $tag->getCompoundTag(SavedItemData::TAG_BLOCK); if($blockStateNbt !== null){ - $blockStateData = $this->blockDataUpgrader->upgradeBlockStateNbt($blockStateNbt); + try{ + $blockStateData = $this->blockDataUpgrader->upgradeBlockStateNbt($blockStateNbt); + }catch(BlockStateDeserializeException $e){ + throw new SavedDataLoadingException("Failed to deserialize blockstate for blockitem: " . $e->getMessage(), 0, $e); + } }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"); + try{ + $blockStateData = $this->blockDataUpgrader->upgradeStringIdMeta($r12BlockId, $meta); + }catch(BlockStateDeserializeException $e){ + throw new SavedDataLoadingException("Failed to deserialize blockstate for legacy blockitem: " . $e->getMessage(), 0, $e); } }else{ //probably a standard item diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 0371ec950..8c2b1d5e6 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -75,7 +75,11 @@ class FallingBlock extends Entity{ //TODO: 1.8+ save format $blockDataUpgrader = GlobalBlockStateHandlers::getUpgrader(); if(($fallingBlockTag = $nbt->getCompoundTag(self::TAG_FALLING_BLOCK)) !== null){ - $blockStateData = $blockDataUpgrader->upgradeBlockStateNbt($fallingBlockTag); + try{ + $blockStateData = $blockDataUpgrader->upgradeBlockStateNbt($fallingBlockTag); + }catch(BlockStateDeserializeException $e){ + throw new SavedDataLoadingException("Invalid falling block blockstate: " . $e->getMessage(), 0, $e); + } }else{ if(($tileIdTag = $nbt->getTag(self::TAG_TILE_ID)) instanceof IntTag){ $blockId = $tileIdTag->getValue(); @@ -86,10 +90,11 @@ class FallingBlock extends Entity{ } $damage = $nbt->getByte(self::TAG_DATA, 0); - $blockStateData = $blockDataUpgrader->upgradeIntIdMeta($blockId, $damage); - } - if($blockStateData === null){ - throw new SavedDataLoadingException("Invalid legacy falling block"); + try{ + $blockStateData = $blockDataUpgrader->upgradeIntIdMeta($blockId, $damage); + }catch(BlockStateDeserializeException $e){ + throw new SavedDataLoadingException("Invalid legacy falling block data: " . $e->getMessage(), 0, $e); + } } try{ diff --git a/src/world/World.php b/src/world/World.php index f499ccb22..a9798fb8a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -37,6 +37,7 @@ use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\BiomeIds; use pocketmine\data\bedrock\block\BlockStateData; +use pocketmine\data\bedrock\block\BlockStateDeserializeException; use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; @@ -526,9 +527,10 @@ class World implements ChunkManager{ if($item !== null){ $block = $item->getBlock(); }elseif(preg_match("/^-?\d+$/", $name) === 1){ - //TODO: this may throw if the ID/meta was invalid - $blockStateData = GlobalBlockStateHandlers::getUpgrader()->upgradeIntIdMeta((int) $name, 0); - if($blockStateData === null){ + //TODO: this is a really sketchy hack - remove this as soon as possible + try{ + $blockStateData = GlobalBlockStateHandlers::getUpgrader()->upgradeIntIdMeta((int) $name, 0); + }catch(BlockStateDeserializeException){ continue; } $block = RuntimeBlockStateRegistry::getInstance()->fromStateId(GlobalBlockStateHandlers::getDeserializer()->deserialize($blockStateData)); diff --git a/src/world/format/io/BaseWorldProvider.php b/src/world/format/io/BaseWorldProvider.php index 7c881ef84..a4d8651a6 100644 --- a/src/world/format/io/BaseWorldProvider.php +++ b/src/world/format/io/BaseWorldProvider.php @@ -67,9 +67,10 @@ abstract class BaseWorldProvider implements WorldProvider{ $newPalette = []; foreach($palette as $k => $legacyIdMeta){ - $newStateData = $this->blockDataUpgrader->upgradeIntIdMeta($legacyIdMeta >> 4, $legacyIdMeta & 0xf); - if($newStateData === null){ - //TODO: remember data for unknown states so we can implement them later + //TODO: remember data for unknown states so we can implement them later + try{ + $newStateData = $this->blockDataUpgrader->upgradeIntIdMeta($legacyIdMeta >> 4, $legacyIdMeta & 0xf); + }catch(BlockStateDeserializeException $e){ $newStateData = GlobalBlockStateHandlers::getUnknownBlockStateData(); }