Filter out recipes containing unknown items

This commit is contained in:
Dylan K. Taylor 2022-06-06 18:25:14 +01:00
parent f08f82edfd
commit 08fbf92d8d
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 62 additions and 15 deletions

View File

@ -23,7 +23,9 @@ declare(strict_types=1);
namespace pocketmine\crafting; namespace pocketmine\crafting;
use pocketmine\item\Durable;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
use function array_map; use function array_map;
@ -33,6 +35,24 @@ use function json_decode;
final class CraftingManagerFromDataHelper{ final class CraftingManagerFromDataHelper{
/**
* @param Item[] $items
*/
private static function containsUnknownItems(array $items) : bool{
$factory = ItemFactory::getInstance();
foreach($items as $item){
if(
//TODO: this check is imperfect and might cause problems if meta 0 isn't used for some reason
(($item instanceof Durable || $item->hasAnyDamageValue()) && !$factory->isRegistered($item->getId())) ||
!$factory->isRegistered($item->getId(), $item->getMeta())
){
return true;
}
}
return false;
}
public static function make(string $filePath) : CraftingManager{ public static function make(string $filePath) : CraftingManager{
$recipes = json_decode(Utils::assumeNotFalse(file_get_contents($filePath), "Missing required resource file"), true); $recipes = json_decode(Utils::assumeNotFalse(file_get_contents($filePath), "Missing required resource file"), true);
if(!is_array($recipes)){ if(!is_array($recipes)){
@ -52,9 +72,14 @@ final class CraftingManagerFromDataHelper{
if($recipeType === null){ if($recipeType === null){
continue; continue;
} }
$inputs = array_map($itemDeserializerFunc, $recipe["input"]);
$outputs = array_map($itemDeserializerFunc, $recipe["output"]);
if(self::containsUnknownItems($inputs) || self::containsUnknownItems($outputs)){
continue;
}
$result->registerShapelessRecipe(new ShapelessRecipe( $result->registerShapelessRecipe(new ShapelessRecipe(
array_map($itemDeserializerFunc, $recipe["input"]), $inputs,
array_map($itemDeserializerFunc, $recipe["output"]), $outputs,
$recipeType $recipeType
)); ));
} }
@ -62,10 +87,15 @@ final class CraftingManagerFromDataHelper{
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
continue; continue;
} }
$inputs = array_map($itemDeserializerFunc, $recipe["input"]);
$outputs = array_map($itemDeserializerFunc, $recipe["output"]);
if(self::containsUnknownItems($inputs) || self::containsUnknownItems($outputs)){
continue;
}
$result->registerShapedRecipe(new ShapedRecipe( $result->registerShapedRecipe(new ShapedRecipe(
$recipe["shape"], $recipe["shape"],
array_map($itemDeserializerFunc, $recipe["input"]), $inputs,
array_map($itemDeserializerFunc, $recipe["output"]) $outputs
)); ));
} }
foreach($recipes["smelting"] as $recipe){ foreach($recipes["smelting"] as $recipe){
@ -79,23 +109,42 @@ final class CraftingManagerFromDataHelper{
if($furnaceType === null){ if($furnaceType === null){
continue; continue;
} }
$output = Item::jsonDeserialize($recipe["output"]);
$input = Item::jsonDeserialize($recipe["input"]);
if(self::containsUnknownItems([$output, $input])){
continue;
}
$result->getFurnaceRecipeManager($furnaceType)->register(new FurnaceRecipe( $result->getFurnaceRecipeManager($furnaceType)->register(new FurnaceRecipe(
Item::jsonDeserialize($recipe["output"]), $output,
Item::jsonDeserialize($recipe["input"])) $input
); ));
} }
foreach($recipes["potion_type"] as $recipe){ foreach($recipes["potion_type"] as $recipe){
$input = Item::jsonDeserialize($recipe["input"]);
$ingredient = Item::jsonDeserialize($recipe["ingredient"]);
$output = Item::jsonDeserialize($recipe["output"]);
if(self::containsUnknownItems([$input, $ingredient, $output])){
continue;
}
$result->registerPotionTypeRecipe(new PotionTypeRecipe( $result->registerPotionTypeRecipe(new PotionTypeRecipe(
Item::jsonDeserialize($recipe["input"]), $input,
Item::jsonDeserialize($recipe["ingredient"]), $ingredient,
Item::jsonDeserialize($recipe["output"]) $output
)); ));
} }
foreach($recipes["potion_container_change"] as $recipe){ foreach($recipes["potion_container_change"] as $recipe){
$input = ItemFactory::getInstance()->get($recipe["input_item_id"], -1);
$ingredient = Item::jsonDeserialize($recipe["ingredient"]);
$output = ItemFactory::getInstance()->get($recipe["output_item_id"], -1);
if(self::containsUnknownItems([$input, $ingredient, $output])){
continue;
}
$result->registerPotionContainerChangeRecipe(new PotionContainerChangeRecipe( $result->registerPotionContainerChangeRecipe(new PotionContainerChangeRecipe(
$recipe["input_item_id"], $input->getId(),
Item::jsonDeserialize($recipe["ingredient"]), $ingredient,
$recipe["output_item_id"] $output->getId()
)); ));
} }

View File

@ -28,7 +28,6 @@ use pocketmine\data\bedrock\item\ItemSerializer;
use pocketmine\data\bedrock\item\ItemTypeSerializeException; use pocketmine\data\bedrock\item\ItemTypeSerializeException;
use pocketmine\data\bedrock\item\SavedItemData; use pocketmine\data\bedrock\item\SavedItemData;
use pocketmine\item\ItemFactory; use pocketmine\item\ItemFactory;
use pocketmine\item\ItemIds;
use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\SingletonTrait; use pocketmine\utils\SingletonTrait;
@ -87,7 +86,6 @@ final class ItemTranslator{
*/ */
public function toNetworkId(int $internalId, int $internalMeta) : array{ public function toNetworkId(int $internalId, int $internalMeta) : array{
return $this->toNetworkIdQuiet($internalId, $internalMeta) ?? return $this->toNetworkIdQuiet($internalId, $internalMeta) ??
$this->toNetworkIdQuiet(ItemIds::INFO_UPDATE, 0) ?? //TODO: bad duct tape
throw new \InvalidArgumentException("Unmapped ID/metadata combination $internalId:$internalMeta"); throw new \InvalidArgumentException("Unmapped ID/metadata combination $internalId:$internalMeta");
} }