mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +00:00
Throw proper exceptions for serialize/deserialize failures
this allows them to be caught and properly reported in tests.
This commit is contained in:
parent
901a51a9dd
commit
5ce5e1d2b0
@ -188,6 +188,8 @@ final class BlockObjectToBlockStateSerializer implements BlockStateSerializer{
|
||||
/**
|
||||
* @phpstan-template TBlockType of Block
|
||||
* @phpstan-param TBlockType $blockState
|
||||
*
|
||||
* @throws BlockStateSerializeException
|
||||
*/
|
||||
public function serializeBlock(Block $blockState) : BlockStateData{
|
||||
$typeId = $blockState->getTypeId();
|
||||
|
@ -35,7 +35,6 @@ use pocketmine\data\bedrock\EntityLegacyIds;
|
||||
use pocketmine\data\bedrock\item\ItemTypeIds as Ids;
|
||||
use pocketmine\data\bedrock\item\SavedItemData as Data;
|
||||
use pocketmine\data\bedrock\PotionTypeIdMap;
|
||||
use pocketmine\data\SavedDataLoadingException;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\VanillaItems as Items;
|
||||
@ -64,13 +63,16 @@ final class ItemDeserializer{
|
||||
$this->deserializers[$id] = $deserializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ItemTypeDeserializeException
|
||||
*/
|
||||
public function deserialize(Data $data) : Item{
|
||||
if(($blockData = $data->getBlock()) !== null){
|
||||
//TODO: this is rough duct tape; we need a better way to deal with this
|
||||
try{
|
||||
$block = GlobalBlockStateHandlers::getDeserializer()->deserialize($blockData);
|
||||
}catch(BlockStateDeserializeException $e){
|
||||
throw new SavedDataLoadingException("Failed to deserialize item data: " . $e->getMessage(), 0, $e);
|
||||
throw new ItemTypeDeserializeException("Failed to deserialize item data: " . $e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
//TODO: worth caching this or not?
|
||||
@ -78,7 +80,7 @@ final class ItemDeserializer{
|
||||
}
|
||||
$id = $data->getName();
|
||||
if(!isset($this->deserializers[$id])){
|
||||
throw new SavedDataLoadingException("No deserializer found for ID $id");
|
||||
throw new ItemTypeDeserializeException("No deserializer found for ID $id");
|
||||
}
|
||||
|
||||
return ($this->deserializers[$id])($data);
|
||||
@ -97,7 +99,7 @@ final class ItemDeserializer{
|
||||
if($data->getMeta() === 0){
|
||||
return Items::ARROW();
|
||||
}
|
||||
throw new SavedDataLoadingException("Tipped arrows are not implemented yet");
|
||||
throw new ItemTypeDeserializeException("Tipped arrows are not implemented yet");
|
||||
});
|
||||
//TODO: minecraft:axolotl_bucket
|
||||
//TODO: minecraft:axolotl_spawn_egg
|
||||
@ -107,7 +109,7 @@ final class ItemDeserializer{
|
||||
$meta = $data->getMeta();
|
||||
$color = DyeColorIdMap::getInstance()->fromInvertedId($meta);
|
||||
if($color === null){
|
||||
throw new SavedDataLoadingException("Unknown banner meta $meta");
|
||||
throw new ItemTypeDeserializeException("Unknown banner meta $meta");
|
||||
}
|
||||
return Items::BANNER()->setColor($color);
|
||||
});
|
||||
@ -117,7 +119,7 @@ final class ItemDeserializer{
|
||||
$meta = $data->getMeta();
|
||||
$color = DyeColorIdMap::getInstance()->fromId($meta);
|
||||
if($color === null){
|
||||
throw new SavedDataLoadingException("Unknown bed meta $meta");
|
||||
throw new ItemTypeDeserializeException("Unknown bed meta $meta");
|
||||
}
|
||||
return Blocks::BED()->setColor($color)->asItem();
|
||||
});
|
||||
@ -139,7 +141,7 @@ final class ItemDeserializer{
|
||||
try{
|
||||
$treeType = TreeType::fromMagicNumber($data->getMeta());
|
||||
}catch(\InvalidArgumentException $e){
|
||||
throw new SavedDataLoadingException($e->getMessage(), 0, $e);
|
||||
throw new ItemTypeDeserializeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
return match($treeType->id()){
|
||||
TreeType::OAK()->id() => Items::OAK_BOAT(),
|
||||
@ -229,7 +231,7 @@ final class ItemDeserializer{
|
||||
CompoundTypeIds::HYDROGEN_PEROXIDE => Items::CHEMICAL_HYDROGEN_PEROXIDE(),
|
||||
CompoundTypeIds::AMMONIA => Items::CHEMICAL_AMMONIA(),
|
||||
CompoundTypeIds::SODIUM_HYPOCHLORITE => Items::CHEMICAL_SODIUM_HYPOCHLORITE(),
|
||||
default => throw new SavedDataLoadingException("Unknown chemical meta " . $data->getMeta())
|
||||
default => throw new ItemTypeDeserializeException("Unknown chemical meta " . $data->getMeta())
|
||||
});
|
||||
$this->map(Ids::COOKED_BEEF, fn() => Items::STEAK());
|
||||
$this->map(Ids::COOKED_CHICKEN, fn() => Items::COOKED_CHICKEN());
|
||||
@ -284,7 +286,7 @@ final class ItemDeserializer{
|
||||
}
|
||||
$dyeColor = DyeColorIdMap::getInstance()->fromInvertedId($meta);
|
||||
if($dyeColor === null){
|
||||
throw new SavedDataLoadingException("Unknown dye meta $meta");
|
||||
throw new ItemTypeDeserializeException("Unknown dye meta $meta");
|
||||
}
|
||||
return match($dyeColor->id()){
|
||||
DyeColor::CYAN()->id() => Items::CYAN_DYE(),
|
||||
@ -475,7 +477,7 @@ final class ItemDeserializer{
|
||||
$meta = $data->getMeta();
|
||||
$potionType = PotionTypeIdMap::getInstance()->fromId($meta);
|
||||
if($potionType === null){
|
||||
throw new SavedDataLoadingException("Unknown potion type ID $meta");
|
||||
throw new ItemTypeDeserializeException("Unknown potion type ID $meta");
|
||||
}
|
||||
return match($potionType->id()){
|
||||
PotionType::WATER()->id() => Items::WATER_POTION(),
|
||||
@ -520,7 +522,7 @@ final class ItemDeserializer{
|
||||
PotionType::STRONG_TURTLE_MASTER()->id() => Items::STRONG_TURTLE_MASTER_POTION(),
|
||||
PotionType::SLOW_FALLING()->id() => Items::SLOW_FALLING_POTION(),
|
||||
PotionType::LONG_SLOW_FALLING()->id() => Items::LONG_SLOW_FALLING_POTION(),
|
||||
default => throw new SavedDataLoadingException("Unhandled potion type " . $potionType->getDisplayName())
|
||||
default => throw new ItemTypeDeserializeException("Unhandled potion type " . $potionType->getDisplayName())
|
||||
};
|
||||
});
|
||||
//TODO: minecraft:powder_snow_bucket
|
||||
@ -565,7 +567,7 @@ final class ItemDeserializer{
|
||||
try{
|
||||
$skullType = SkullType::fromMagicNumber($meta);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
throw new SavedDataLoadingException($e->getMessage(), 0, $e);
|
||||
throw new ItemTypeDeserializeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
return match($skullType->id()) {
|
||||
SkullType::SKELETON()->id() => Items::SKELETON_SKULL(),
|
||||
@ -574,7 +576,7 @@ final class ItemDeserializer{
|
||||
SkullType::CREEPER()->id() => Items::CREEPER_HEAD(),
|
||||
SkullType::PLAYER()->id() => Items::PLAYER_HEAD(),
|
||||
SkullType::DRAGON()->id() => Items::DRAGON_HEAD(),
|
||||
default => throw new SavedDataLoadingException("Unexpected skull type " . $skullType->getDisplayName())
|
||||
default => throw new ItemTypeDeserializeException("Unexpected skull type " . $skullType->getDisplayName())
|
||||
};
|
||||
});
|
||||
//TODO: minecraft:skull_banner_pattern
|
||||
@ -587,7 +589,7 @@ final class ItemDeserializer{
|
||||
EntityLegacyIds::ZOMBIE => Items::ZOMBIE_SPAWN_EGG(),
|
||||
EntityLegacyIds::SQUID => Items::SQUID_SPAWN_EGG(),
|
||||
EntityLegacyIds::VILLAGER => Items::VILLAGER_SPAWN_EGG(),
|
||||
default => throw new SavedDataLoadingException("Unhandled spawn egg meta " . $data->getMeta())
|
||||
default => throw new ItemTypeDeserializeException("Unhandled spawn egg meta " . $data->getMeta())
|
||||
});
|
||||
$this->map(Ids::SPIDER_EYE, fn() => Items::SPIDER_EYE());
|
||||
//TODO: minecraft:spider_spawn_egg
|
||||
@ -595,7 +597,7 @@ final class ItemDeserializer{
|
||||
$meta = $data->getMeta();
|
||||
$potionType = PotionTypeIdMap::getInstance()->fromId($meta);
|
||||
if($potionType === null){
|
||||
throw new SavedDataLoadingException("Unknown potion type ID $meta");
|
||||
throw new ItemTypeDeserializeException("Unknown potion type ID $meta");
|
||||
}
|
||||
return match($potionType->id()){
|
||||
PotionType::WATER()->id() => Items::WATER_SPLASH_POTION(),
|
||||
@ -640,7 +642,7 @@ final class ItemDeserializer{
|
||||
PotionType::STRONG_TURTLE_MASTER()->id() => Items::STRONG_TURTLE_MASTER_SPLASH_POTION(),
|
||||
PotionType::SLOW_FALLING()->id() => Items::SLOW_FALLING_SPLASH_POTION(),
|
||||
PotionType::LONG_SLOW_FALLING()->id() => Items::LONG_SLOW_FALLING_SPLASH_POTION(),
|
||||
default => throw new SavedDataLoadingException("Unhandled potion type " . $potionType->getDisplayName())
|
||||
default => throw new ItemTypeDeserializeException("Unhandled potion type " . $potionType->getDisplayName())
|
||||
};
|
||||
});
|
||||
$this->map(Ids::SPRUCE_BOAT, fn() => Items::SPRUCE_BOAT());
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SkullType;
|
||||
use pocketmine\data\bedrock\BlockItemIdMap;
|
||||
use pocketmine\data\bedrock\blockstate\BlockStateSerializeException;
|
||||
use pocketmine\data\bedrock\CompoundTypeIds;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\data\bedrock\item\ItemTypeIds as Ids;
|
||||
@ -78,6 +79,8 @@ final class ItemSerializer{
|
||||
/**
|
||||
* @phpstan-template TItemType of Item
|
||||
* @phpstan-param TItemType $item
|
||||
*
|
||||
* @throws ItemTypeSerializeException
|
||||
*/
|
||||
public function serialize(Item $item) : Data{
|
||||
if($item->isNull()){
|
||||
@ -102,8 +105,7 @@ final class ItemSerializer{
|
||||
}
|
||||
|
||||
if($locatedSerializer === null){
|
||||
//TODO: proper exceptions
|
||||
throw new \LogicException("No serializer registered for " . get_class($item) . " " . $item->getName());
|
||||
throw new ItemTypeSerializeException("No serializer registered for " . get_class($item) . " " . $item->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,15 +121,22 @@ final class ItemSerializer{
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ItemTypeSerializeException
|
||||
*/
|
||||
private static function standardBlock(Block $block) : Data{
|
||||
$blockStateData = GlobalBlockStateHandlers::getSerializer()->serialize($block->getFullId());
|
||||
try{
|
||||
$blockStateData = GlobalBlockStateHandlers::getSerializer()->serialize($block->getFullId());
|
||||
}catch(BlockStateSerializeException $e){
|
||||
throw new ItemTypeSerializeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
$itemNameId = BlockItemIdMap::getInstance()->lookupItemId($blockStateData->getName());
|
||||
if($itemNameId === null){
|
||||
//TODO: this might end up being a hassle for custom blocks, since it'll force providing an item
|
||||
//serializer for every custom block
|
||||
//it would probably be better if we allow adding custom item <-> block ID mappings for this
|
||||
throw new \LogicException("No blockitem serializer or blockitem ID mapping registered for block " . $blockStateData->getName());
|
||||
throw new ItemTypeSerializeException("No blockitem serializer or blockitem ID mapping registered for block " . $blockStateData->getName());
|
||||
}
|
||||
|
||||
return new Data($itemNameId, 0, $blockStateData);
|
||||
|
28
src/data/bedrock/item/ItemTypeDeserializeException.php
Normal file
28
src/data/bedrock/item/ItemTypeDeserializeException.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\item;
|
||||
|
||||
final class ItemTypeDeserializeException extends \RuntimeException{
|
||||
|
||||
}
|
28
src/data/bedrock/item/ItemTypeSerializeException.php
Normal file
28
src/data/bedrock/item/ItemTypeSerializeException.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\item;
|
||||
|
||||
final class ItemTypeSerializeException extends \LogicException{
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user