From ae13dc9a0964681cfe70b1454b3f552f0063aab1 Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Sun, 17 Dec 2023 11:56:55 +0100 Subject: [PATCH 01/22] add basic smithing table requirements --- .../inventory/SmithingTableInventory.php | 40 ++++++- src/crafting/CraftingManager.php | 31 ++++++ .../CraftingManagerFromDataHelper.php | 23 +++- src/crafting/SmithingRecipe.php | 37 +++++++ src/crafting/SmithingTransformRecipe.php | 58 ++++++++++ src/crafting/SmithingTrimRecipe.php | 61 +++++++++++ .../transaction/SmithingTransaction.php | 48 +++++++++ src/item/Armor.php | 37 +++++++ src/item/ArmorTrim.php | 21 ++++ src/item/ArmorTrimMaterial.php | 69 ++++++++++++ src/item/ArmorTrimPattern.php | 47 ++++++++ src/network/mcpe/cache/CraftingDataCache.php | 30 ++++++ src/network/mcpe/cache/TrimDataHelper.php | 100 ++++++++++++++++++ .../mcpe/handler/ItemStackRequestExecutor.php | 7 +- .../mcpe/handler/PreSpawnPacketHandler.php | 13 +++ src/utils/TextFormat.php | 20 ++++ 16 files changed, 638 insertions(+), 4 deletions(-) create mode 100644 src/crafting/SmithingRecipe.php create mode 100644 src/crafting/SmithingTransformRecipe.php create mode 100644 src/crafting/SmithingTrimRecipe.php create mode 100644 src/inventory/transaction/SmithingTransaction.php create mode 100644 src/item/ArmorTrim.php create mode 100644 src/item/ArmorTrimMaterial.php create mode 100644 src/item/ArmorTrimPattern.php create mode 100644 src/network/mcpe/cache/TrimDataHelper.php diff --git a/src/block/inventory/SmithingTableInventory.php b/src/block/inventory/SmithingTableInventory.php index 2f67ac9d2dd..ed24c1a116e 100644 --- a/src/block/inventory/SmithingTableInventory.php +++ b/src/block/inventory/SmithingTableInventory.php @@ -23,15 +23,53 @@ namespace pocketmine\block\inventory; +use InvalidArgumentException; +use pocketmine\crafting\SmithingRecipe; +use pocketmine\crafting\SmithingTransformRecipe; +use pocketmine\crafting\SmithingTrimRecipe; use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\TemporaryInventory; +use pocketmine\item\Armor; +use pocketmine\item\ArmorTrim; +use pocketmine\item\ArmorTrimMaterial; +use pocketmine\item\ArmorTrimPattern; +use pocketmine\item\Item; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\cache\TrimDataHelper; +use pocketmine\network\mcpe\convert\TypeConverter; +use pocketmine\Server; use pocketmine\world\Position; +use function var_dump; final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ use BlockInventoryTrait; + public const SLOT_INPUT = 0; + + public const SLOT_ADDITION = 1; + + public const SLOT_TEMPLATE = 2; + public function __construct(Position $holder){ $this->holder = $holder; - parent::__construct(3); + parent::__construct(4); + } + + public function getInput() : Item{ + return $this->getItem(self::SLOT_INPUT); + } + + public function getAddition() : Item{ + return $this->getItem(self::SLOT_ADDITION); + } + + public function getTemplate() : Item{ + return $this->getItem(self::SLOT_TEMPLATE); + } + + public function getOutput() : ?Item{ + $craftingManager = Server::getInstance()->getCraftingManager(); + $recipe = $craftingManager->matchSmithingRecipe($this->getInput(), $this->getAddition(), $this->getTemplate()); + return $recipe?->constructOutput($this->getInput(), $this->getAddition(), $this->getTemplate()); } } diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index c7c0b10c645..fe7397a135d 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -64,6 +64,12 @@ class CraftingManager{ */ protected array $potionTypeRecipes = []; + /** + * @var SmithingRecipe[] + * @phpstan-var list + */ + protected array $smithingRecipes = []; + /** * @var PotionContainerChangeRecipe[] * @phpstan-var list @@ -197,6 +203,14 @@ public function getPotionContainerChangeRecipes() : array{ return $this->potionContainerChangeRecipes; } + /** + * @return SmithingRecipe[] + * @phpstan-return list + */ + public function getSmithingRecipes() : array{ + return $this->smithingRecipes; + } + public function registerShapedRecipe(ShapedRecipe $recipe) : void{ $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; $this->craftingRecipeIndex[] = $recipe; @@ -231,6 +245,14 @@ public function registerPotionContainerChangeRecipe(PotionContainerChangeRecipe } } + public function registerSmithingRecipe(SmithingRecipe $recipe) : void{ + $this->smithingRecipes[] = $recipe; + + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } + } + /** * @param Item[] $outputs */ @@ -304,4 +326,13 @@ public function matchBrewingRecipe(Item $input, Item $ingredient) : ?BrewingReci return null; } + + public function matchSmithingRecipe(Item $input, Item $addition, Item $template) : ?SmithingRecipe{ + foreach($this->smithingRecipes as $recipe){ + if($recipe->getInput()->accepts($input) && $recipe->getAddition()->accepts($addition) && $recipe->getTemplate()->accepts($template)){ + return $recipe; + } + } + return null; + } } diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 8315f2b3b33..e0746da5ee6 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -30,6 +30,8 @@ use pocketmine\crafting\json\RecipeIngredientData; use pocketmine\crafting\json\ShapedRecipeData; use pocketmine\crafting\json\ShapelessRecipeData; +use pocketmine\crafting\json\SmithingTransformRecipeData; +use pocketmine\crafting\json\SmithingTrimRecipeData; use pocketmine\data\bedrock\block\BlockStateData; use pocketmine\data\bedrock\item\BlockItemIdMap; use pocketmine\data\bedrock\item\ItemTypeDeserializeException; @@ -292,7 +294,6 @@ public static function make(string $directoryPath) : CraftingManager{ $input )); } - foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'potion_type.json'), PotionTypeRecipeData::class) as $recipe){ $input = self::deserializeIngredient($recipe->input); $ingredient = self::deserializeIngredient($recipe->ingredient); @@ -329,9 +330,27 @@ public static function make(string $directoryPath) : CraftingManager{ $outputId )); } + foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'smithing.json'), SmithingTransformRecipeData::class) as $recipe){ + $input = self::deserializeIngredient($recipe->input); + $addition = self::deserializeIngredient($recipe->addition); + $template = self::deserializeIngredient($recipe->template); + $output = self::deserializeItemStack($recipe->output); - //TODO: smithing + if($input === null || $template === null || $addition === null || $output === null){ + continue; + } + $result->registerSmithingRecipe(new SmithingTransformRecipe($input, $addition, $template, $output)); + } + foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'smithing_trim.json'), SmithingTrimRecipeData::class) as $recipe){ + $input = self::deserializeIngredient($recipe->input); + $addition = self::deserializeIngredient($recipe->addition); + $template = self::deserializeIngredient($recipe->template); + if($input === null || $template === null || $addition === null){ + continue; + } + $result->registerSmithingRecipe(new SmithingTrimRecipe($input, $addition, $template,)); + } return $result; } } diff --git a/src/crafting/SmithingRecipe.php b/src/crafting/SmithingRecipe.php new file mode 100644 index 00000000000..72d28da47e5 --- /dev/null +++ b/src/crafting/SmithingRecipe.php @@ -0,0 +1,37 @@ +result = clone $this->result; + } + + public function getInput() : RecipeIngredient{ + return $this->input; + } + + public function getAddition() : RecipeIngredient{ + return $this->addition; + } + + public function getTemplate() : RecipeIngredient{ + return $this->template; + } + + public function getResult() : Item{ + return clone $this->result; + } + + public function constructOutput(Item $input, Item $addition, Item $template) : ?Item{ + return $this->getResult()->setNamedTag($input->getNamedTag()); + } +} diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php new file mode 100644 index 00000000000..6df996f86c2 --- /dev/null +++ b/src/crafting/SmithingTrimRecipe.php @@ -0,0 +1,61 @@ +input; + } + + public function getAddition() : RecipeIngredient{ + return $this->addition; + } + + public function getTemplate() : RecipeIngredient{ + return $this->template; + } + + public function constructOutput(Item $input, Item $addition, Item $template) : ?Item{ + if(!$input instanceof Armor){ + return null; + } + if (($material = ArmorTrimMaterial::fromItem($addition)) === null || ($pattern = ArmorTrimPattern::fromItem($template)) === null){ + return null; + } + return $input->setTrim(new ArmorTrim($material, $pattern)); + } +} diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php new file mode 100644 index 00000000000..3bf031a75ce --- /dev/null +++ b/src/inventory/transaction/SmithingTransaction.php @@ -0,0 +1,48 @@ +actions) < 1){ + throw new TransactionValidationException("Transaction must have at least one action to be executable"); + } + + /** @var Item[] $inputs */ + $inputs = []; + /** @var Item[] $outputs */ + $outputs = []; + $this->matchItems($outputs, $inputs); + + var_dump(array_map("strval", $inputs)); + + if(($inputCount = count($inputs)) !== 3){ + throw new TransactionValidationException("Expected 3 input items, got $inputCount"); + } + if(($outputCount = count($outputs)) !== 1){ + throw new TransactionValidationException("Expected 1 output item, but received $outputCount"); + } + + [$input, $template, $addition] = $inputs; + + $craftingManager = Server::getInstance()->getCraftingManager(); + $recipe = $craftingManager->matchSmithingRecipe($input, $addition, $template); + var_dump($recipe); + + if(($output = $recipe?->constructOutput($input, $addition, $template)) === null){ + throw new TransactionValidationException("Could find a matching output item for the given inputs"); + } + if(!$output->equalsExact($outputs[0])){ + throw new TransactionValidationException("Invalid output item"); + } + } +} \ No newline at end of file diff --git a/src/item/Armor.php b/src/item/Armor.php index e9667a8a89a..621561d89d3 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -31,17 +31,27 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\nbt\tag\StringTag; use pocketmine\player\Player; use pocketmine\utils\Binary; use function lcg_value; use function mt_rand; +use function strtolower; class Armor extends Durable{ public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int + public const TAG_TRIM = "Trim"; //TAG_String + + public const TAG_TRIM_MATERIAL = "Material"; //TAG_String + + public const TAG_TRIM_PATTERN = "Pattern"; //TAG_String + private ArmorTypeInfo $armorInfo; + private ?ArmorTrim $armorTrim = null; + protected ?Color $customColor = null; /** @@ -106,6 +116,20 @@ public function clearCustomColor() : self{ return $this; } + public function getTrim() : ?ArmorTrim{ + return $this->armorTrim; + } + + public function setTrim(ArmorTrim $trim) : self{ + $this->armorTrim = $trim; + return $this; + } + + public function removeTrim() : self{ + $this->armorTrim = null; + return $this; + } + /** * Returns the total enchantment protection factor this armour piece offers from all applicable protection * enchantments on the item. @@ -160,6 +184,14 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ }else{ $this->customColor = null; } + $trimTag = $tag->getTag(self::TAG_TRIM); + if($trimTag instanceof CompoundTag){ + $material = ArmorTrimMaterial::tryFrom($trimTag->getString(self::TAG_TRIM_MATERIAL, "")); + $pattern = ArmorTrimPattern::tryFrom($trimTag->getString(self::TAG_TRIM_PATTERN, "")); + if($material instanceof ArmorTrimMaterial && $pattern instanceof ArmorTrimPattern){ + $this->armorTrim = new ArmorTrim($material, $pattern); + } + } } protected function serializeCompoundTag(CompoundTag $tag) : void{ @@ -167,5 +199,10 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ $this->customColor !== null ? $tag->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($this->customColor->toARGB())) : $tag->removeTag(self::TAG_CUSTOM_COLOR); + $this->armorTrim !== null ? + $tag->setTag(self::TAG_TRIM, CompoundTag::create() + ->setString(self::TAG_TRIM_MATERIAL, $this->armorTrim->getMaterial()->value) + ->setString(self::TAG_TRIM_PATTERN, $this->armorTrim->getPattern()->value)) : + $tag->removeTag(self::TAG_TRIM); } } diff --git a/src/item/ArmorTrim.php b/src/item/ArmorTrim.php new file mode 100644 index 00000000000..29806876a4a --- /dev/null +++ b/src/item/ArmorTrim.php @@ -0,0 +1,21 @@ +material; + } + + public function getPattern() : ArmorTrimPattern{ + return $this->pattern; + } +} \ No newline at end of file diff --git a/src/item/ArmorTrimMaterial.php b/src/item/ArmorTrimMaterial.php new file mode 100644 index 00000000000..c5e8f9c98a0 --- /dev/null +++ b/src/item/ArmorTrimMaterial.php @@ -0,0 +1,69 @@ +getTypeId()){ + ItemTypeIds::AMETHYST_SHARD => self::AMETHYST, + ItemTypeIds::COPPER_INGOT => self::COPPER, + ItemTypeIds::DIAMOND => self::DIAMOND, + ItemTypeIds::EMERALD => self::EMERALD, + ItemTypeIds::GOLD_INGOT => self::GOLD, + ItemTypeIds::IRON_INGOT => self::IRON, + ItemTypeIds::LAPIS_LAZULI => self::LAPIS, + ItemTypeIds::NETHERITE_INGOT => self::NETHERITE, + ItemTypeIds::NETHER_QUARTZ => self::QUARTZ, + ItemTypeIds::REDSTONE_DUST => self::REDSTONE, + default => throw new InvalidArgumentException("Item " . $item . " is no valid armor trim material") + }; + } + + public function getItemId() : string{ + return match($this){ + self::AMETHYST => ItemTypeNames::AMETHYST_SHARD, + self::COPPER => ItemTypeNames::COPPER_INGOT, + self::DIAMOND => ItemTypeNames::DIAMOND, + self::EMERALD => ItemTypeNames::EMERALD, + self::GOLD => ItemTypeNames::GOLD_INGOT, + self::IRON => ItemTypeNames::IRON_INGOT, + self::LAPIS => ItemTypeNames::LAPIS_LAZULI, + self::NETHERITE => ItemTypeNames::NETHERITE_INGOT, + self::QUARTZ => ItemTypeNames::QUARTZ, + self::REDSTONE => ItemTypeNames::REDSTONE + }; + } + + public function getColor() : string{ + return match($this){ + self::AMETHYST => TextFormat::MATERIAL_AMETHYST, + self::COPPER => TextFormat::MATERIAL_COPPER, + self::DIAMOND => TextFormat::MATERIAL_DIAMOND, + self::EMERALD => TextFormat::MATERIAL_EMERALD, + self::GOLD => TextFormat::MATERIAL_GOLD, + self::IRON => TextFormat::MATERIAL_IRON, + self::LAPIS => TextFormat::MATERIAL_LAPIS, + self::NETHERITE => TextFormat::MATERIAL_NETHERITE, + self::QUARTZ => TextFormat::MATERIAL_QUARTZ, + self::REDSTONE => TextFormat::MATERIAL_REDSTONE + }; + } +} \ No newline at end of file diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php new file mode 100644 index 00000000000..84a512b9e76 --- /dev/null +++ b/src/item/ArmorTrimPattern.php @@ -0,0 +1,47 @@ +lookupAliases($item) as $alias){ + if (!str_ends_with($alias, self::TEMPLATE_SUFFIX)){ + continue; + } + return self::tryFrom(substr($alias, 0, strlen($alias) - strlen(self::TEMPLATE_SUFFIX))); + } + return null; + } + + public function getItemId() : string{ + return "minecraft:" . $this->value . self::TEMPLATE_SUFFIX; + } +} \ No newline at end of file diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 1aa64c5970d..038f44632f1 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -28,6 +28,8 @@ use pocketmine\crafting\ShapedRecipe; use pocketmine\crafting\ShapelessRecipe; use pocketmine\crafting\ShapelessRecipeType; +use pocketmine\crafting\SmithingTransformRecipe; +use pocketmine\crafting\SmithingTrimRecipe; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\network\mcpe\protocol\types\recipe\CraftingRecipeBlockName; @@ -38,6 +40,8 @@ use pocketmine\network\mcpe\protocol\types\recipe\PotionTypeRecipe as ProtocolPotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\SmithingTransformRecipe as ProtocolSmithingTransformRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\SmithingTrimRecipe as ProtocolSmithingTrimRecipe; use pocketmine\timings\Timings; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Binary; @@ -79,6 +83,7 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData $converter = TypeConverter::getInstance(); $recipesWithTypeIds = []; + $index = 0; foreach($manager->getCraftingRecipeIndex() as $index => $recipe){ if($recipe instanceof ShapelessRecipe){ $typeTag = match($recipe->getType()){ @@ -140,6 +145,31 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData ); } } + foreach($manager->getSmithingRecipes() as $recipe){ + $index++; + if($recipe instanceof SmithingTransformRecipe){ + $recipesWithTypeIds[] = new ProtocolSmithingTransformRecipe( + CraftingDataPacket::ENTRY_SMITHING_TRANSFORM, + Binary::writeInt($index), + $converter->coreRecipeIngredientToNet($recipe->getTemplate()), + $converter->coreRecipeIngredientToNet($recipe->getInput()), + $converter->coreRecipeIngredientToNet($recipe->getAddition()), + $converter->coreItemStackToNet($recipe->getResult()), + CraftingRecipeBlockName::SMITHING_TABLE, + $index + ); + }elseif($recipe instanceof SmithingTrimRecipe){ + $recipesWithTypeIds[] = new ProtocolSmithingTrimRecipe( + CraftingDataPacket::ENTRY_SMITHING_TRIM, + Binary::writeInt($index), + $converter->coreRecipeIngredientToNet($recipe->getTemplate()), + $converter->coreRecipeIngredientToNet($recipe->getInput()), + $converter->coreRecipeIngredientToNet($recipe->getAddition()), + CraftingRecipeBlockName::SMITHING_TABLE, + $index + ); + } + } $potionTypeRecipes = []; foreach($manager->getPotionTypeRecipes() as $recipe){ diff --git a/src/network/mcpe/cache/TrimDataHelper.php b/src/network/mcpe/cache/TrimDataHelper.php new file mode 100644 index 00000000000..6a18a4d0af1 --- /dev/null +++ b/src/network/mcpe/cache/TrimDataHelper.php @@ -0,0 +1,100 @@ + "amethyst", + ItemTypeIds::COPPER_INGOT => "copper", + ItemTypeIds::DIAMOND => "diamond", + ItemTypeIds::EMERALD => "emerald", + ItemTypeIds::GOLD_INGOT => "gold", + ItemTypeIds::IRON_INGOT => "iron", + ItemTypeIds::LAPIS_LAZULI => "lapis", + ItemTypeIds::NETHERITE_INGOT => "netherite", + ItemTypeIds::NETHER_QUARTZ => "quartz", + ItemTypeIds::REDSTONE_DUST => "redstone" + ]; + + /** + * @param string[] $itemIdToPatternMappings + * @phpstan-param array $itemIdToPatternMappings + */ + public function __construct(private TrimDataPacket $packet, private array $itemIdToPatternMappings){} + + private static function make() : TrimDataHelper{ + $itemIdToPatternIdMappings = []; + return new TrimDataHelper(TrimDataPacket::create(TrimDataHelper::loadPatterns($itemIdToPatternIdMappings), TrimDataHelper::loadMaterials()), $itemIdToPatternIdMappings); + } + + public function getPacket() : TrimDataPacket{ + return $this->packet; + } + + public function itemIdToPatternId(int $itemId) : string{ + var_dump($this->itemIdToPatternMappings); + return $this->itemIdToPatternMappings[$itemId]; + } + + /** + * @param + * + * @return TrimPattern[] + * @phpstan-return list + */ + private static function loadPatterns(array &$itemIdToPatternIdMappings) : array{ + $patterns = []; + foreach(ItemTagToIdMap::getInstance()->getIdsForTag(self::TAG_PATTERNS) as $stringId){ + $patterns[] = $pattern = new TrimPattern($stringId, self::getPatternName($stringId)); + $itemIdToPatternIdMappings[StringToItemParser::getInstance()->parse($stringId)->getTypeId()] = $pattern->getPatternId(); + } + return $patterns; + } + + public static function getPatternName(string $stringId) : string{ + if (!str_ends_with($stringId, "_armor_trim_smithing_template")){ + throw new \InvalidArgumentException("Pattern names can only be constructed from trim item ids"); //todo + } + $prefixLength = strlen("minecraft:"); + return substr($stringId, $prefixLength, (strpos($stringId, "_") - $prefixLength)); + } + + /** + * @return TrimMaterial[] + * @phpstan-return list + */ + private static function loadMaterials() : array{ + $materials = []; + $materials[] = new TrimMaterial("amethyst", "§u", ItemTypeNames::AMETHYST_SHARD); + $materials[] = new TrimMaterial("copper", "§n", ItemTypeNames::COPPER_INGOT); + $materials[] = new TrimMaterial("diamond", "§s", ItemTypeNames::DIAMOND); + $materials[] = new TrimMaterial("emerald", "§q", ItemTypeNames::EMERALD); + $materials[] = new TrimMaterial("gold", "§p", ItemTypeNames::GOLD_INGOT); + $materials[] = new TrimMaterial("iron", "§i", ItemTypeNames::IRON_INGOT); + $materials[] = new TrimMaterial("lapis", "§t", ItemTypeNames::LAPIS_LAZULI); + $materials[] = new TrimMaterial("netherite", "§j", ItemTypeNames::NETHERITE_INGOT); + $materials[] = new TrimMaterial("quartz", "§h", ItemTypeNames::QUARTZ); + $materials[] = new TrimMaterial("redstone", "§m", ItemTypeNames::REDSTONE); + return $materials; + } +} \ No newline at end of file diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index a36ae9f4051..ba95b4d5538 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -24,6 +24,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\block\inventory\EnchantInventory; +use pocketmine\block\inventory\SmithingTableInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; @@ -31,6 +32,7 @@ use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\inventory\transaction\EnchantingTransaction; use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\SmithingTransaction; use pocketmine\inventory\transaction\TransactionBuilder; use pocketmine\inventory\transaction\TransactionBuilderInventory; use pocketmine\item\Item; @@ -289,7 +291,7 @@ protected function takeCreatedItem(int $count) : Item{ * @throws ItemStackRequestProcessException */ private function assertDoingCrafting() : void{ - if(!$this->specialTransaction instanceof CraftingTransaction && !$this->specialTransaction instanceof EnchantingTransaction){ + if(!$this->specialTransaction instanceof CraftingTransaction && !$this->specialTransaction instanceof EnchantingTransaction && !$this->specialTransaction instanceof SmithingTransaction){ if($this->specialTransaction === null){ throw new ItemStackRequestProcessException("Expected CraftRecipe or CraftRecipeAuto action to precede this action"); }else{ @@ -342,6 +344,9 @@ protected function processItemStackRequestAction(ItemStackRequestAction $action) $this->specialTransaction = new EnchantingTransaction($this->player, $option, $optionId + 1); $this->setNextCreatedItem($window->getOutput($optionId)); } + }elseif($window instanceof SmithingTableInventory){ + $this->specialTransaction = new SmithingTransaction($this->player); + $this->setNextCreatedItem($window->getOutput()); }else{ $this->beginCrafting($action->getRecipeId(), 1); } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index f80bacfc181..c6de24d2697 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -23,14 +23,18 @@ namespace pocketmine\network\mcpe\handler; +use pocketmine\item\ArmorTrimMaterial; +use pocketmine\item\ArmorTrimPattern; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\cache\CraftingDataCache; use pocketmine\network\mcpe\cache\StaticPacketCache; +use pocketmine\network\mcpe\cache\TrimDataHelper; use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PlayerAuthInputPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; +use pocketmine\network\mcpe\protocol\TrimDataPacket; use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\CacheableNbt; @@ -41,11 +45,14 @@ use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings; use pocketmine\network\mcpe\protocol\types\PlayerMovementType; use pocketmine\network\mcpe\protocol\types\SpawnSettings; +use pocketmine\network\mcpe\protocol\types\TrimMaterial; +use pocketmine\network\mcpe\protocol\types\TrimPattern; use pocketmine\player\Player; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\VersionInfo; use Ramsey\Uuid\Uuid; +use function array_map; use function sprintf; /** @@ -144,6 +151,12 @@ public function setUp() : void{ $this->session->getLogger()->debug("Sending creative inventory data"); $this->inventoryManager->syncCreative(); + $this->session->getLogger()->debug("Sending armor trim data"); + $this->session->sendDataPacket(TrimDataPacket::create( + array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($pattern->getItemId(), $pattern->value), ArmorTrimPattern::cases()), + array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->value, $material->getColor(), $material->getItemId()), ArmorTrimMaterial::cases()) + )); + $this->session->getLogger()->debug("Sending crafting data"); $this->session->sendDataPacket(CraftingDataCache::getInstance()->getCache($this->server->getCraftingManager())); diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index dfd6a359aef..9ccdb52a2ca 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -63,6 +63,16 @@ abstract class TextFormat{ public const YELLOW = TextFormat::ESCAPE . "e"; public const WHITE = TextFormat::ESCAPE . "f"; public const MINECOIN_GOLD = TextFormat::ESCAPE . "g"; + public const MATERIAL_QUARTZ = TextFormat::ESCAPE . "h"; + public const MATERIAL_IRON = TextFormat::ESCAPE . "i"; + public const MATERIAL_NETHERITE = TextFormat::ESCAPE . "j"; + public const MATERIAL_REDSTONE = TextFormat::ESCAPE . "m"; + public const MATERIAL_COPPER = TextFormat::ESCAPE . "n"; + public const MATERIAL_GOLD = TextFormat::ESCAPE . "p"; + public const MATERIAL_EMERALD = TextFormat::ESCAPE . "q"; + public const MATERIAL_DIAMOND = TextFormat::ESCAPE . "s"; + public const MATERIAL_LAPIS = TextFormat::ESCAPE . "t"; + public const MATERIAL_AMETHYST = TextFormat::ESCAPE . "u"; public const COLORS = [ self::BLACK => self::BLACK, @@ -82,6 +92,16 @@ abstract class TextFormat{ self::YELLOW => self::YELLOW, self::WHITE => self::WHITE, self::MINECOIN_GOLD => self::MINECOIN_GOLD, + self::MATERIAL_QUARTZ => self::MATERIAL_QUARTZ, + self::MATERIAL_IRON => self::MATERIAL_IRON, + self::MATERIAL_NETHERITE => self::MATERIAL_NETHERITE, + self::MATERIAL_REDSTONE => self::MATERIAL_REDSTONE, + self::MATERIAL_COPPER => self::MATERIAL_COPPER, + self::MATERIAL_GOLD => self::MATERIAL_GOLD, + self::MATERIAL_EMERALD => self::MATERIAL_EMERALD, + self::MATERIAL_DIAMOND => self::MATERIAL_DIAMOND, + self::MATERIAL_LAPIS => self::MATERIAL_LAPIS, + self::MATERIAL_AMETHYST => self::MATERIAL_AMETHYST ]; public const OBFUSCATED = TextFormat::ESCAPE . "k"; From fc5e5eb11596b66a5f208474bf5e76264411efd7 Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Mon, 18 Dec 2023 13:36:23 +0100 Subject: [PATCH 02/22] fixed remaining problems --- .../inventory/SmithingTableInventory.php | 12 --- .../CraftingManagerFromDataHelper.php | 4 +- src/crafting/SmithingTrimRecipe.php | 2 +- .../transaction/SmithingTransaction.php | 27 ++++- src/item/Armor.php | 6 +- src/item/ArmorTrimPattern.php | 2 - src/network/mcpe/cache/TrimDataHelper.php | 100 ------------------ .../mcpe/handler/PreSpawnPacketHandler.php | 8 +- 8 files changed, 31 insertions(+), 130 deletions(-) delete mode 100644 src/network/mcpe/cache/TrimDataHelper.php diff --git a/src/block/inventory/SmithingTableInventory.php b/src/block/inventory/SmithingTableInventory.php index ed24c1a116e..84ec6e8ffa8 100644 --- a/src/block/inventory/SmithingTableInventory.php +++ b/src/block/inventory/SmithingTableInventory.php @@ -23,23 +23,11 @@ namespace pocketmine\block\inventory; -use InvalidArgumentException; -use pocketmine\crafting\SmithingRecipe; -use pocketmine\crafting\SmithingTransformRecipe; -use pocketmine\crafting\SmithingTrimRecipe; use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\TemporaryInventory; -use pocketmine\item\Armor; -use pocketmine\item\ArmorTrim; -use pocketmine\item\ArmorTrimMaterial; -use pocketmine\item\ArmorTrimPattern; use pocketmine\item\Item; -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\cache\TrimDataHelper; -use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\Server; use pocketmine\world\Position; -use function var_dump; final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ use BlockInventoryTrait; diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index e0746da5ee6..310207d36b0 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -332,8 +332,8 @@ public static function make(string $directoryPath) : CraftingManager{ } foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'smithing.json'), SmithingTransformRecipeData::class) as $recipe){ $input = self::deserializeIngredient($recipe->input); - $addition = self::deserializeIngredient($recipe->addition); $template = self::deserializeIngredient($recipe->template); + $addition = self::deserializeIngredient($recipe->addition); $output = self::deserializeItemStack($recipe->output); if($input === null || $template === null || $addition === null || $output === null){ @@ -349,7 +349,7 @@ public static function make(string $directoryPath) : CraftingManager{ if($input === null || $template === null || $addition === null){ continue; } - $result->registerSmithingRecipe(new SmithingTrimRecipe($input, $addition, $template,)); + $result->registerSmithingRecipe(new SmithingTrimRecipe($input, $addition, $template)); } return $result; } diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php index 6df996f86c2..96a4ce0081b 100644 --- a/src/crafting/SmithingTrimRecipe.php +++ b/src/crafting/SmithingTrimRecipe.php @@ -53,7 +53,7 @@ public function constructOutput(Item $input, Item $addition, Item $template) : ? if(!$input instanceof Armor){ return null; } - if (($material = ArmorTrimMaterial::fromItem($addition)) === null || ($pattern = ArmorTrimPattern::fromItem($template)) === null){ + if(($material = ArmorTrimMaterial::fromItem($addition)) === null || ($pattern = ArmorTrimPattern::fromItem($template)) === null){ return null; } return $input->setTrim(new ArmorTrim($material, $pattern)); diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php index 3bf031a75ce..017afd451b3 100644 --- a/src/inventory/transaction/SmithingTransaction.php +++ b/src/inventory/transaction/SmithingTransaction.php @@ -4,9 +4,11 @@ namespace pocketmine\inventory\transaction; +use pocketmine\item\Armor; use pocketmine\item\Item; +use pocketmine\item\ItemTypeIds; +use pocketmine\item\TieredTool; use pocketmine\Server; -use function array_map; use function count; use function var_dump; @@ -23,8 +25,6 @@ public function validate() : void{ $outputs = []; $this->matchItems($outputs, $inputs); - var_dump(array_map("strval", $inputs)); - if(($inputCount = count($inputs)) !== 3){ throw new TransactionValidationException("Expected 3 input items, got $inputCount"); } @@ -32,15 +32,32 @@ public function validate() : void{ throw new TransactionValidationException("Expected 1 output item, but received $outputCount"); } - [$input, $template, $addition] = $inputs; + $input = $addition = $template = null; + foreach($inputs as $item){ + switch(true){ + case $item instanceof Armor || $item instanceof TieredTool: + $input = $item; + break; + case $item->getTypeId() >= ItemTypeIds::NETHERITE_UPGRADE_SMITHING_TEMPLATE && $item->getTypeId() <= ItemTypeIds::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE: + $template = $item; + break; + default: + $addition = $item; + break; + } + } + + if($input === null || $addition === null || $template === null){ + throw new TransactionValidationException("The given inputs are no valid smithing ingredients"); + } $craftingManager = Server::getInstance()->getCraftingManager(); $recipe = $craftingManager->matchSmithingRecipe($input, $addition, $template); - var_dump($recipe); if(($output = $recipe?->constructOutput($input, $addition, $template)) === null){ throw new TransactionValidationException("Could find a matching output item for the given inputs"); } + if(!$output->equalsExact($outputs[0])){ throw new TransactionValidationException("Invalid output item"); } diff --git a/src/item/Armor.php b/src/item/Armor.php index 621561d89d3..0ae1c40e855 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -31,12 +31,10 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\player\Player; use pocketmine\utils\Binary; use function lcg_value; use function mt_rand; -use function strtolower; class Armor extends Durable{ @@ -120,12 +118,14 @@ public function getTrim() : ?ArmorTrim{ return $this->armorTrim; } + /** @return $this */ public function setTrim(ArmorTrim $trim) : self{ $this->armorTrim = $trim; return $this; } - public function removeTrim() : self{ + /** @return $this */ + public function clearTrim() : self{ $this->armorTrim = null; return $this; } diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index 84a512b9e76..85e11dd85dc 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -4,11 +4,9 @@ namespace pocketmine\item; -use pocketmine\data\bedrock\item\ItemTypeNames; use function str_ends_with; use function strlen; use function substr; -use function var_dump; enum ArmorTrimPattern : string{ diff --git a/src/network/mcpe/cache/TrimDataHelper.php b/src/network/mcpe/cache/TrimDataHelper.php deleted file mode 100644 index 6a18a4d0af1..00000000000 --- a/src/network/mcpe/cache/TrimDataHelper.php +++ /dev/null @@ -1,100 +0,0 @@ - "amethyst", - ItemTypeIds::COPPER_INGOT => "copper", - ItemTypeIds::DIAMOND => "diamond", - ItemTypeIds::EMERALD => "emerald", - ItemTypeIds::GOLD_INGOT => "gold", - ItemTypeIds::IRON_INGOT => "iron", - ItemTypeIds::LAPIS_LAZULI => "lapis", - ItemTypeIds::NETHERITE_INGOT => "netherite", - ItemTypeIds::NETHER_QUARTZ => "quartz", - ItemTypeIds::REDSTONE_DUST => "redstone" - ]; - - /** - * @param string[] $itemIdToPatternMappings - * @phpstan-param array $itemIdToPatternMappings - */ - public function __construct(private TrimDataPacket $packet, private array $itemIdToPatternMappings){} - - private static function make() : TrimDataHelper{ - $itemIdToPatternIdMappings = []; - return new TrimDataHelper(TrimDataPacket::create(TrimDataHelper::loadPatterns($itemIdToPatternIdMappings), TrimDataHelper::loadMaterials()), $itemIdToPatternIdMappings); - } - - public function getPacket() : TrimDataPacket{ - return $this->packet; - } - - public function itemIdToPatternId(int $itemId) : string{ - var_dump($this->itemIdToPatternMappings); - return $this->itemIdToPatternMappings[$itemId]; - } - - /** - * @param - * - * @return TrimPattern[] - * @phpstan-return list - */ - private static function loadPatterns(array &$itemIdToPatternIdMappings) : array{ - $patterns = []; - foreach(ItemTagToIdMap::getInstance()->getIdsForTag(self::TAG_PATTERNS) as $stringId){ - $patterns[] = $pattern = new TrimPattern($stringId, self::getPatternName($stringId)); - $itemIdToPatternIdMappings[StringToItemParser::getInstance()->parse($stringId)->getTypeId()] = $pattern->getPatternId(); - } - return $patterns; - } - - public static function getPatternName(string $stringId) : string{ - if (!str_ends_with($stringId, "_armor_trim_smithing_template")){ - throw new \InvalidArgumentException("Pattern names can only be constructed from trim item ids"); //todo - } - $prefixLength = strlen("minecraft:"); - return substr($stringId, $prefixLength, (strpos($stringId, "_") - $prefixLength)); - } - - /** - * @return TrimMaterial[] - * @phpstan-return list - */ - private static function loadMaterials() : array{ - $materials = []; - $materials[] = new TrimMaterial("amethyst", "§u", ItemTypeNames::AMETHYST_SHARD); - $materials[] = new TrimMaterial("copper", "§n", ItemTypeNames::COPPER_INGOT); - $materials[] = new TrimMaterial("diamond", "§s", ItemTypeNames::DIAMOND); - $materials[] = new TrimMaterial("emerald", "§q", ItemTypeNames::EMERALD); - $materials[] = new TrimMaterial("gold", "§p", ItemTypeNames::GOLD_INGOT); - $materials[] = new TrimMaterial("iron", "§i", ItemTypeNames::IRON_INGOT); - $materials[] = new TrimMaterial("lapis", "§t", ItemTypeNames::LAPIS_LAZULI); - $materials[] = new TrimMaterial("netherite", "§j", ItemTypeNames::NETHERITE_INGOT); - $materials[] = new TrimMaterial("quartz", "§h", ItemTypeNames::QUARTZ); - $materials[] = new TrimMaterial("redstone", "§m", ItemTypeNames::REDSTONE); - return $materials; - } -} \ No newline at end of file diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index c6de24d2697..391a47f48c4 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -28,7 +28,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\cache\CraftingDataCache; use pocketmine\network\mcpe\cache\StaticPacketCache; -use pocketmine\network\mcpe\cache\TrimDataHelper; use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PlayerAuthInputPacket; @@ -152,10 +151,9 @@ public function setUp() : void{ $this->inventoryManager->syncCreative(); $this->session->getLogger()->debug("Sending armor trim data"); - $this->session->sendDataPacket(TrimDataPacket::create( - array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($pattern->getItemId(), $pattern->value), ArmorTrimPattern::cases()), - array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->value, $material->getColor(), $material->getItemId()), ArmorTrimMaterial::cases()) - )); + $patterns = array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($pattern->getItemId(), $pattern->value), ArmorTrimPattern::cases()); + $materials = array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->value, $material->getColor(), $material->getItemId()), ArmorTrimMaterial::cases()); + $this->session->sendDataPacket(TrimDataPacket::create($patterns, $materials)); $this->session->getLogger()->debug("Sending crafting data"); $this->session->sendDataPacket(CraftingDataCache::getInstance()->getCache($this->server->getCraftingManager())); From c3ea0babfe75c2423ed4fff0afdd77949559f017 Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Mon, 18 Dec 2023 14:20:33 +0100 Subject: [PATCH 03/22] phpstan stop crying --- src/inventory/transaction/SmithingTransaction.php | 3 +-- src/item/ArmorTrim.php | 2 +- src/item/ArmorTrimMaterial.php | 2 +- src/item/ArmorTrimPattern.php | 2 +- src/network/mcpe/cache/CraftingDataCache.php | 3 ++- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php index 017afd451b3..b6ed22aba5f 100644 --- a/src/inventory/transaction/SmithingTransaction.php +++ b/src/inventory/transaction/SmithingTransaction.php @@ -10,7 +10,6 @@ use pocketmine\item\TieredTool; use pocketmine\Server; use function count; -use function var_dump; class SmithingTransaction extends InventoryTransaction{ @@ -62,4 +61,4 @@ public function validate() : void{ throw new TransactionValidationException("Invalid output item"); } } -} \ No newline at end of file +} diff --git a/src/item/ArmorTrim.php b/src/item/ArmorTrim.php index 29806876a4a..c8ce8946bdf 100644 --- a/src/item/ArmorTrim.php +++ b/src/item/ArmorTrim.php @@ -18,4 +18,4 @@ public function getMaterial() : ArmorTrimMaterial{ public function getPattern() : ArmorTrimPattern{ return $this->pattern; } -} \ No newline at end of file +} diff --git a/src/item/ArmorTrimMaterial.php b/src/item/ArmorTrimMaterial.php index c5e8f9c98a0..866651dda1f 100644 --- a/src/item/ArmorTrimMaterial.php +++ b/src/item/ArmorTrimMaterial.php @@ -66,4 +66,4 @@ public function getColor() : string{ self::REDSTONE => TextFormat::MATERIAL_REDSTONE }; } -} \ No newline at end of file +} diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index 85e11dd85dc..8f8677c12e8 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -42,4 +42,4 @@ public static function fromItem(Item $item) : ?ArmorTrimPattern{ public function getItemId() : string{ return "minecraft:" . $this->value . self::TEMPLATE_SUFFIX; } -} \ No newline at end of file +} diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 038f44632f1..eda96d407a6 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -83,7 +83,6 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData $converter = TypeConverter::getInstance(); $recipesWithTypeIds = []; - $index = 0; foreach($manager->getCraftingRecipeIndex() as $index => $recipe){ if($recipe instanceof ShapelessRecipe){ $typeTag = match($recipe->getType()){ @@ -145,6 +144,8 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData ); } } + + $index ??= 0; foreach($manager->getSmithingRecipes() as $recipe){ $index++; if($recipe instanceof SmithingTransformRecipe){ From 2a56e41ac11f59eb3b8a5da68bfc12a91ba67713 Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Mon, 18 Dec 2023 14:30:29 +0100 Subject: [PATCH 04/22] why are headers missing? --- .../transaction/SmithingTransaction.php | 19 +++++++++++++++++++ src/item/ArmorTrim.php | 19 +++++++++++++++++++ src/item/ArmorTrimMaterial.php | 19 +++++++++++++++++++ src/item/ArmorTrimPattern.php | 19 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php index b6ed22aba5f..1e5afe82b94 100644 --- a/src/inventory/transaction/SmithingTransaction.php +++ b/src/inventory/transaction/SmithingTransaction.php @@ -1,5 +1,24 @@ Date: Sun, 21 Jan 2024 19:39:11 +0100 Subject: [PATCH 05/22] updated version with all fixes except for save ids - they must be fixed --- src/block/SmithingTable.php | 5 +- .../inventory/SmithingTableInventory.php | 9 +-- src/crafting/CraftingManager.php | 19 +++--- src/crafting/SmithingRecipe.php | 14 ++-- src/crafting/SmithingTransformRecipe.php | 25 +++++-- src/crafting/SmithingTrimRecipe.php | 28 ++++++-- src/data/bedrock/TrimMaterialTypeIdMap.php | 46 +++++++++++++ src/data/bedrock/TrimMaterialTypeIds.php | 38 +++++++++++ src/data/bedrock/TrimPatternTypeIdMap.php | 52 +++++++++++++++ src/data/bedrock/TrimPatternTypeIds.php | 44 +++++++++++++ .../transaction/SmithingTransaction.php | 40 ++++------- src/item/Armor.php | 16 +++-- src/item/ArmorTrim.php | 2 +- src/item/ArmorTrimPattern.php | 6 +- src/item/SmithingTemplate.php | 28 ++++++++ src/item/VanillaItems.php | 66 +++++++++---------- .../mcpe/handler/ItemStackRequestExecutor.php | 9 ++- .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- 18 files changed, 334 insertions(+), 115 deletions(-) create mode 100644 src/data/bedrock/TrimMaterialTypeIdMap.php create mode 100644 src/data/bedrock/TrimMaterialTypeIds.php create mode 100644 src/data/bedrock/TrimPatternTypeIdMap.php create mode 100644 src/data/bedrock/TrimPatternTypeIds.php create mode 100644 src/item/SmithingTemplate.php diff --git a/src/block/SmithingTable.php b/src/block/SmithingTable.php index 741e9c02fdc..72eab244045 100644 --- a/src/block/SmithingTable.php +++ b/src/block/SmithingTable.php @@ -31,10 +31,7 @@ final class SmithingTable extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ - if($player !== null){ - $player->setCurrentWindow(new SmithingTableInventory($this->position)); - } - + $player?->setCurrentWindow(new SmithingTableInventory($this->position)); return true; } diff --git a/src/block/inventory/SmithingTableInventory.php b/src/block/inventory/SmithingTableInventory.php index 84ec6e8ffa8..e9bb7f03b39 100644 --- a/src/block/inventory/SmithingTableInventory.php +++ b/src/block/inventory/SmithingTableInventory.php @@ -26,7 +26,6 @@ use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\TemporaryInventory; use pocketmine\item\Item; -use pocketmine\Server; use pocketmine\world\Position; final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ @@ -40,7 +39,7 @@ final class SmithingTableInventory extends SimpleInventory implements BlockInven public function __construct(Position $holder){ $this->holder = $holder; - parent::__construct(4); + parent::__construct(3); } public function getInput() : Item{ @@ -54,10 +53,4 @@ public function getAddition() : Item{ public function getTemplate() : Item{ return $this->getItem(self::SLOT_TEMPLATE); } - - public function getOutput() : ?Item{ - $craftingManager = Server::getInstance()->getCraftingManager(); - $recipe = $craftingManager->matchSmithingRecipe($this->getInput(), $this->getAddition(), $this->getTemplate()); - return $recipe?->constructOutput($this->getInput(), $this->getAddition(), $this->getTemplate()); - } } diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index fe7397a135d..3d936b59756 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -29,6 +29,7 @@ use pocketmine\utils\BinaryStream; use pocketmine\utils\DestructorCallbackTrait; use pocketmine\utils\ObjectSet; +use function count; use function spl_object_id; use function usort; @@ -211,6 +212,15 @@ public function getSmithingRecipes() : array{ return $this->smithingRecipes; } + public function getSmithingRecipeFromIndex(int $index) : ?SmithingRecipe{ + $craftingOffset = count($this->craftingRecipeIndex) - 1; + + if($index < $craftingOffset || $index > ($craftingOffset + count($this->smithingRecipes))){ + return null; + } + return $this->smithingRecipes[$index - $craftingOffset - 1]; + } + public function registerShapedRecipe(ShapedRecipe $recipe) : void{ $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; $this->craftingRecipeIndex[] = $recipe; @@ -326,13 +336,4 @@ public function matchBrewingRecipe(Item $input, Item $ingredient) : ?BrewingReci return null; } - - public function matchSmithingRecipe(Item $input, Item $addition, Item $template) : ?SmithingRecipe{ - foreach($this->smithingRecipes as $recipe){ - if($recipe->getInput()->accepts($input) && $recipe->getAddition()->accepts($addition) && $recipe->getTemplate()->accepts($template)){ - return $recipe; - } - } - return null; - } } diff --git a/src/crafting/SmithingRecipe.php b/src/crafting/SmithingRecipe.php index 72d28da47e5..53b82548a24 100644 --- a/src/crafting/SmithingRecipe.php +++ b/src/crafting/SmithingRecipe.php @@ -25,13 +25,17 @@ use pocketmine\item\Item; -abstract class SmithingRecipe{ +interface SmithingRecipe{ - abstract public function getInput() : RecipeIngredient; + public function getInput() : RecipeIngredient; - abstract public function getAddition() : RecipeIngredient; + public function getAddition() : RecipeIngredient; - abstract public function getTemplate() : RecipeIngredient; + public function getTemplate() : RecipeIngredient; - abstract public function constructOutput(Item $input, Item $addition, Item $template) : ?Item; + /** + * @param Item[] $inputs + * @phpstan-param list $inputs + */ + public function getResultFor(array $inputs) : ?Item; } diff --git a/src/crafting/SmithingTransformRecipe.php b/src/crafting/SmithingTransformRecipe.php index d9e1ea6abba..dfe81c87847 100644 --- a/src/crafting/SmithingTransformRecipe.php +++ b/src/crafting/SmithingTransformRecipe.php @@ -23,14 +23,16 @@ namespace pocketmine\crafting; +use pocketmine\item\Armor; use pocketmine\item\Item; +use pocketmine\item\TieredTool; -class SmithingTransformRecipe extends SmithingRecipe{ +class SmithingTransformRecipe implements SmithingRecipe{ public function __construct( - private RecipeIngredient $input, - private RecipeIngredient $addition, - private RecipeIngredient $template, + private readonly RecipeIngredient $input, + private readonly RecipeIngredient $addition, + private readonly RecipeIngredient $template, private Item $result ){ $this->result = clone $this->result; @@ -52,7 +54,20 @@ public function getResult() : Item{ return clone $this->result; } - public function constructOutput(Item $input, Item $addition, Item $template) : ?Item{ + /** + * @param Item[] $inputs + * @phpstan-param list $inputs + */ + public function getResultFor(array $inputs) : ?Item{ + $input = null; + foreach($inputs as $item){ + if ($item instanceof Armor || $item instanceof TieredTool){ + $input = $item; + } + } + if($input === null){ + return null; + } return $this->getResult()->setNamedTag($input->getNamedTag()); } } diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php index 96a4ce0081b..67f5f3f465f 100644 --- a/src/crafting/SmithingTrimRecipe.php +++ b/src/crafting/SmithingTrimRecipe.php @@ -28,13 +28,14 @@ use pocketmine\item\ArmorTrimMaterial; use pocketmine\item\ArmorTrimPattern; use pocketmine\item\Item; +use pocketmine\item\SmithingTemplate; -class SmithingTrimRecipe extends SmithingRecipe{ +class SmithingTrimRecipe implements SmithingRecipe{ public function __construct( - private RecipeIngredient $input, - private RecipeIngredient $addition, - private RecipeIngredient $template){ + private readonly RecipeIngredient $input, + private readonly RecipeIngredient $addition, + private readonly RecipeIngredient $template){ } public function getInput() : RecipeIngredient{ @@ -49,8 +50,23 @@ public function getTemplate() : RecipeIngredient{ return $this->template; } - public function constructOutput(Item $input, Item $addition, Item $template) : ?Item{ - if(!$input instanceof Armor){ + /** + * @param Item[] $inputs + * @phpstan-param list $inputs + */ + public function getResultFor(array $inputs) : ?Item{ + $input = $template = $addition = null; + foreach($inputs as $item){ + if($item instanceof Armor){ + $input = $item; + }elseif($item instanceof SmithingTemplate){ + $template = $item; + }else{ + $addition = $item; + } + } + + if($input === null || $addition === null || $template === null){ return null; } if(($material = ArmorTrimMaterial::fromItem($addition)) === null || ($pattern = ArmorTrimPattern::fromItem($template)) === null){ diff --git a/src/data/bedrock/TrimMaterialTypeIdMap.php b/src/data/bedrock/TrimMaterialTypeIdMap.php new file mode 100644 index 00000000000..dbf4574ee85 --- /dev/null +++ b/src/data/bedrock/TrimMaterialTypeIdMap.php @@ -0,0 +1,46 @@ + */ + use IntSaveIdMapTrait; + + private function __construct(){ + $this->register(TrimMaterialTypeIds::AMETHYST, ArmorTrimMaterial::AMETHYST); + $this->register(TrimMaterialTypeIds::COPPER, ArmorTrimMaterial::COPPER); + $this->register(TrimMaterialTypeIds::DIAMOND, ArmorTrimMaterial::DIAMOND); + $this->register(TrimMaterialTypeIds::EMERALD, ArmorTrimMaterial::EMERALD); + $this->register(TrimMaterialTypeIds::GOLD, ArmorTrimMaterial::GOLD); + $this->register(TrimMaterialTypeIds::IRON, ArmorTrimMaterial::IRON); + $this->register(TrimMaterialTypeIds::LAPIS, ArmorTrimMaterial::LAPIS); + $this->register(TrimMaterialTypeIds::NETHERITE, ArmorTrimMaterial::NETHERITE); + $this->register(TrimMaterialTypeIds::QUARTZ, ArmorTrimMaterial::QUARTZ); + $this->register(TrimMaterialTypeIds::REDSTONE, ArmorTrimMaterial::REDSTONE); + } +} diff --git a/src/data/bedrock/TrimMaterialTypeIds.php b/src/data/bedrock/TrimMaterialTypeIds.php new file mode 100644 index 00000000000..5e5e555878f --- /dev/null +++ b/src/data/bedrock/TrimMaterialTypeIds.php @@ -0,0 +1,38 @@ + */ + use IntSaveIdMapTrait; + + private function __construct(){ + $this->register(TrimPatternTypeIds::COAST, ArmorTrimPattern::COAST); + $this->register(TrimPatternTypeIds::DUNE, ArmorTrimPattern::DUNE); + $this->register(TrimPatternTypeIds::EYE, ArmorTrimPattern::EYE); + $this->register(TrimPatternTypeIds::HOST, ArmorTrimPattern::HOST); + $this->register(TrimPatternTypeIds::RAISER, ArmorTrimPattern::RAISER); + $this->register(TrimPatternTypeIds::RIB, ArmorTrimPattern::RIB); + $this->register(TrimPatternTypeIds::SENTRY, ArmorTrimPattern::SENTRY); + $this->register(TrimPatternTypeIds::SHAPER, ArmorTrimPattern::SHAPER); + $this->register(TrimPatternTypeIds::SILENCE, ArmorTrimPattern::SILENCE); + $this->register(TrimPatternTypeIds::SNOUT, ArmorTrimPattern::SNOUT); + $this->register(TrimPatternTypeIds::SPIRE, ArmorTrimPattern::SPIRE); + $this->register(TrimPatternTypeIds::TIDE, ArmorTrimPattern::TIDE); + $this->register(TrimPatternTypeIds::VEX, ArmorTrimPattern::VEX); + $this->register(TrimPatternTypeIds::WARD, ArmorTrimPattern::WARD); + $this->register(TrimPatternTypeIds::WAYFINDER, ArmorTrimPattern::WAYFINDER); + $this->register(TrimPatternTypeIds::WILD, ArmorTrimPattern::WILD); + } +} diff --git a/src/data/bedrock/TrimPatternTypeIds.php b/src/data/bedrock/TrimPatternTypeIds.php new file mode 100644 index 00000000000..57b4598d6e3 --- /dev/null +++ b/src/data/bedrock/TrimPatternTypeIds.php @@ -0,0 +1,44 @@ +actions) < 1){ throw new TransactionValidationException("Transaction must have at least one action to be executable"); @@ -49,33 +55,9 @@ public function validate() : void{ if(($outputCount = count($outputs)) !== 1){ throw new TransactionValidationException("Expected 1 output item, but received $outputCount"); } - - $input = $addition = $template = null; - foreach($inputs as $item){ - switch(true){ - case $item instanceof Armor || $item instanceof TieredTool: - $input = $item; - break; - case $item->getTypeId() >= ItemTypeIds::NETHERITE_UPGRADE_SMITHING_TEMPLATE && $item->getTypeId() <= ItemTypeIds::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE: - $template = $item; - break; - default: - $addition = $item; - break; - } - } - - if($input === null || $addition === null || $template === null){ - throw new TransactionValidationException("The given inputs are no valid smithing ingredients"); - } - - $craftingManager = Server::getInstance()->getCraftingManager(); - $recipe = $craftingManager->matchSmithingRecipe($input, $addition, $template); - - if(($output = $recipe?->constructOutput($input, $addition, $template)) === null){ + if(($output = $this->recipe->getResultFor($inputs)) === null){ throw new TransactionValidationException("Could find a matching output item for the given inputs"); } - if(!$output->equalsExact($outputs[0])){ throw new TransactionValidationException("Invalid output item"); } diff --git a/src/item/Armor.php b/src/item/Armor.php index 0ae1c40e855..818426a7279 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -24,6 +24,8 @@ namespace pocketmine\item; use pocketmine\color\Color; +use pocketmine\data\bedrock\TrimMaterialTypeIdMap; +use pocketmine\data\bedrock\TrimPatternTypeIdMap; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\inventory\ArmorInventory; use pocketmine\item\enchantment\ProtectionEnchantment; @@ -40,11 +42,11 @@ class Armor extends Durable{ public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int - public const TAG_TRIM = "Trim"; //TAG_String + public const TAG_TRIM = "Trim"; - public const TAG_TRIM_MATERIAL = "Material"; //TAG_String + public const TAG_TRIM_MATERIAL = "Material"; //TAG_Int - public const TAG_TRIM_PATTERN = "Pattern"; //TAG_String + public const TAG_TRIM_PATTERN = "Pattern"; //TAG_Int private ArmorTypeInfo $armorInfo; @@ -186,8 +188,8 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ } $trimTag = $tag->getTag(self::TAG_TRIM); if($trimTag instanceof CompoundTag){ - $material = ArmorTrimMaterial::tryFrom($trimTag->getString(self::TAG_TRIM_MATERIAL, "")); - $pattern = ArmorTrimPattern::tryFrom($trimTag->getString(self::TAG_TRIM_PATTERN, "")); + $material = TrimMaterialTypeIdMap::getInstance()->fromId($trimTag->getInt(self::TAG_TRIM_MATERIAL, -1)); + $pattern = TrimPatternTypeIdMap::getInstance()->fromId($trimTag->getInt(self::TAG_TRIM_PATTERN, -1)); if($material instanceof ArmorTrimMaterial && $pattern instanceof ArmorTrimPattern){ $this->armorTrim = new ArmorTrim($material, $pattern); } @@ -201,8 +203,8 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ $tag->removeTag(self::TAG_CUSTOM_COLOR); $this->armorTrim !== null ? $tag->setTag(self::TAG_TRIM, CompoundTag::create() - ->setString(self::TAG_TRIM_MATERIAL, $this->armorTrim->getMaterial()->value) - ->setString(self::TAG_TRIM_PATTERN, $this->armorTrim->getPattern()->value)) : + ->setInt(self::TAG_TRIM_MATERIAL, TrimMaterialTypeIdMap::getInstance()->toId($this->armorTrim->getMaterial())) + ->setInt(self::TAG_TRIM_PATTERN, TrimPatternTypeIdMap::getInstance()->toId($this->armorTrim->getPattern()))) : $tag->removeTag(self::TAG_TRIM); } } diff --git a/src/item/ArmorTrim.php b/src/item/ArmorTrim.php index dd6124ad013..caadfd935b7 100644 --- a/src/item/ArmorTrim.php +++ b/src/item/ArmorTrim.php @@ -28,7 +28,7 @@ class ArmorTrim{ public function __construct( private readonly ArmorTrimMaterial $material, private readonly ArmorTrimPattern $pattern - ){ } + ){} public function getMaterial() : ArmorTrimMaterial{ return $this->material; diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index 5eb6a21a969..b1c135e8141 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -46,7 +46,7 @@ enum ArmorTrimPattern : string{ case WAYFINDER = "wayfinder"; case WILD = "wild"; - private const TEMPLATE_SUFFIX = "_armor_trim_smithing_template"; + public const TEMPLATE_SUFFIX = "_armor_trim_smithing_template"; public static function fromItem(Item $item) : ?ArmorTrimPattern{ foreach(StringToItemParser::getInstance()->lookupAliases($item) as $alias){ @@ -57,8 +57,4 @@ public static function fromItem(Item $item) : ?ArmorTrimPattern{ } return null; } - - public function getItemId() : string{ - return "minecraft:" . $this->value . self::TEMPLATE_SUFFIX; - } } diff --git a/src/item/SmithingTemplate.php b/src/item/SmithingTemplate.php new file mode 100644 index 00000000000..2c589d6b8e3 --- /dev/null +++ b/src/item/SmithingTemplate.php @@ -0,0 +1,28 @@ +setNextCreatedItem($window->getOutput($optionId)); } }elseif($window instanceof SmithingTableInventory){ - $this->specialTransaction = new SmithingTransaction($this->player); - $this->setNextCreatedItem($window->getOutput()); + $craftingManager = Server::getInstance()->getCraftingManager(); + $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId()); + if ($recipe !== null){ + $this->specialTransaction = new SmithingTransaction($this->player, $recipe); + $this->setNextCreatedItem($recipe->getResultFor($window->getContents())); + } }else{ $this->beginCrafting($action->getRecipeId(), 1); } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 391a47f48c4..165b0c5ccdf 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -151,7 +151,7 @@ public function setUp() : void{ $this->inventoryManager->syncCreative(); $this->session->getLogger()->debug("Sending armor trim data"); - $patterns = array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($pattern->getItemId(), $pattern->value), ArmorTrimPattern::cases()); + $patterns = array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern("minecraft:" . $pattern->value . ArmorTrimPattern::TEMPLATE_SUFFIX, $pattern->value), ArmorTrimPattern::cases()); $materials = array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->value, $material->getColor(), $material->getItemId()), ArmorTrimMaterial::cases()); $this->session->sendDataPacket(TrimDataPacket::create($patterns, $materials)); From 6dce15d5a53143d5f588fe9d5a014d0379e26054 Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Sun, 21 Jan 2024 19:52:16 +0100 Subject: [PATCH 06/22] oops (save ids still not working) --- src/item/VanillaItems.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index 4685efabe2c..989a29e87f9 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -121,7 +121,7 @@ * @method static Clock CLOCK() * @method static Clownfish CLOWNFISH() * @method static Coal COAL() - * @method static Item COAST_ARMOR_TRIM_SMITHING_TEMPLATE() + * @method static SmithingTemplate COAST_ARMOR_TRIM_SMITHING_TEMPLATE() * @method static CocoaBeans COCOA_BEANS() * @method static Compass COMPASS() * @method static CookedChicken COOKED_CHICKEN() From b82de6549bd2ce97b10e507ada782e5e5916002b Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Mon, 22 Jan 2024 22:55:07 +0100 Subject: [PATCH 07/22] oops --- src/network/mcpe/handler/ItemStackRequestExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index 1f956465282..df3b277ec7c 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -348,7 +348,7 @@ protected function processItemStackRequestAction(ItemStackRequestAction $action) }elseif($window instanceof SmithingTableInventory){ $craftingManager = Server::getInstance()->getCraftingManager(); $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId()); - if ($recipe !== null){ + if($recipe !== null){ $this->specialTransaction = new SmithingTransaction($this->player, $recipe); $this->setNextCreatedItem($recipe->getResultFor($window->getContents())); } From 93db5ef4f6b89d6495d12236416302d37350158f Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Fri, 22 Mar 2024 14:29:00 +0100 Subject: [PATCH 08/22] fixes all big remaining issues --- src/block/SmithingTable.php | 4 +- src/crafting/CraftingManager.php | 8 +-- .../CraftingManagerFromDataHelper.php | 1 + src/data/bedrock/TrimMaterialTypeIdMap.php | 46 ---------------- src/data/bedrock/TrimMaterialTypeIds.php | 38 -------------- src/data/bedrock/TrimPatternTypeIdMap.php | 52 ------------------- src/data/bedrock/TrimPatternTypeIds.php | 44 ---------------- src/item/Armor.php | 16 +++--- src/item/ArmorTrimPattern.php | 28 +++++++--- src/network/mcpe/cache/CraftingDataCache.php | 4 +- .../mcpe/handler/ItemStackRequestExecutor.php | 2 +- 11 files changed, 38 insertions(+), 205 deletions(-) delete mode 100644 src/data/bedrock/TrimMaterialTypeIdMap.php delete mode 100644 src/data/bedrock/TrimMaterialTypeIds.php delete mode 100644 src/data/bedrock/TrimPatternTypeIdMap.php delete mode 100644 src/data/bedrock/TrimPatternTypeIds.php diff --git a/src/block/SmithingTable.php b/src/block/SmithingTable.php index 72eab244045..e2bf9648d9d 100644 --- a/src/block/SmithingTable.php +++ b/src/block/SmithingTable.php @@ -31,7 +31,9 @@ final class SmithingTable extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ - $player?->setCurrentWindow(new SmithingTableInventory($this->position)); + if($player !== null){ + $player->setCurrentWindow(new SmithingTableInventory($this->position)); + } return true; } diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 3d936b59756..5c0568e6bb4 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -36,6 +36,8 @@ class CraftingManager{ use DestructorCallbackTrait; + public const SMITHING_RECIPES_OFFSET = 200000; + /** * @var ShapedRecipe[][] * @phpstan-var array> @@ -213,12 +215,10 @@ public function getSmithingRecipes() : array{ } public function getSmithingRecipeFromIndex(int $index) : ?SmithingRecipe{ - $craftingOffset = count($this->craftingRecipeIndex) - 1; - - if($index < $craftingOffset || $index > ($craftingOffset + count($this->smithingRecipes))){ + if($index < self::SMITHING_RECIPES_OFFSET || $index > (self::SMITHING_RECIPES_OFFSET + count($this->smithingRecipes))){ return null; } - return $this->smithingRecipes[$index - $craftingOffset - 1]; + return $this->smithingRecipes[$index - self::SMITHING_RECIPES_OFFSET]; } public function registerShapedRecipe(ShapedRecipe $recipe) : void{ diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 310207d36b0..f72a146a388 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -294,6 +294,7 @@ public static function make(string $directoryPath) : CraftingManager{ $input )); } + foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'potion_type.json'), PotionTypeRecipeData::class) as $recipe){ $input = self::deserializeIngredient($recipe->input); $ingredient = self::deserializeIngredient($recipe->ingredient); diff --git a/src/data/bedrock/TrimMaterialTypeIdMap.php b/src/data/bedrock/TrimMaterialTypeIdMap.php deleted file mode 100644 index dbf4574ee85..00000000000 --- a/src/data/bedrock/TrimMaterialTypeIdMap.php +++ /dev/null @@ -1,46 +0,0 @@ - */ - use IntSaveIdMapTrait; - - private function __construct(){ - $this->register(TrimMaterialTypeIds::AMETHYST, ArmorTrimMaterial::AMETHYST); - $this->register(TrimMaterialTypeIds::COPPER, ArmorTrimMaterial::COPPER); - $this->register(TrimMaterialTypeIds::DIAMOND, ArmorTrimMaterial::DIAMOND); - $this->register(TrimMaterialTypeIds::EMERALD, ArmorTrimMaterial::EMERALD); - $this->register(TrimMaterialTypeIds::GOLD, ArmorTrimMaterial::GOLD); - $this->register(TrimMaterialTypeIds::IRON, ArmorTrimMaterial::IRON); - $this->register(TrimMaterialTypeIds::LAPIS, ArmorTrimMaterial::LAPIS); - $this->register(TrimMaterialTypeIds::NETHERITE, ArmorTrimMaterial::NETHERITE); - $this->register(TrimMaterialTypeIds::QUARTZ, ArmorTrimMaterial::QUARTZ); - $this->register(TrimMaterialTypeIds::REDSTONE, ArmorTrimMaterial::REDSTONE); - } -} diff --git a/src/data/bedrock/TrimMaterialTypeIds.php b/src/data/bedrock/TrimMaterialTypeIds.php deleted file mode 100644 index 5e5e555878f..00000000000 --- a/src/data/bedrock/TrimMaterialTypeIds.php +++ /dev/null @@ -1,38 +0,0 @@ - */ - use IntSaveIdMapTrait; - - private function __construct(){ - $this->register(TrimPatternTypeIds::COAST, ArmorTrimPattern::COAST); - $this->register(TrimPatternTypeIds::DUNE, ArmorTrimPattern::DUNE); - $this->register(TrimPatternTypeIds::EYE, ArmorTrimPattern::EYE); - $this->register(TrimPatternTypeIds::HOST, ArmorTrimPattern::HOST); - $this->register(TrimPatternTypeIds::RAISER, ArmorTrimPattern::RAISER); - $this->register(TrimPatternTypeIds::RIB, ArmorTrimPattern::RIB); - $this->register(TrimPatternTypeIds::SENTRY, ArmorTrimPattern::SENTRY); - $this->register(TrimPatternTypeIds::SHAPER, ArmorTrimPattern::SHAPER); - $this->register(TrimPatternTypeIds::SILENCE, ArmorTrimPattern::SILENCE); - $this->register(TrimPatternTypeIds::SNOUT, ArmorTrimPattern::SNOUT); - $this->register(TrimPatternTypeIds::SPIRE, ArmorTrimPattern::SPIRE); - $this->register(TrimPatternTypeIds::TIDE, ArmorTrimPattern::TIDE); - $this->register(TrimPatternTypeIds::VEX, ArmorTrimPattern::VEX); - $this->register(TrimPatternTypeIds::WARD, ArmorTrimPattern::WARD); - $this->register(TrimPatternTypeIds::WAYFINDER, ArmorTrimPattern::WAYFINDER); - $this->register(TrimPatternTypeIds::WILD, ArmorTrimPattern::WILD); - } -} diff --git a/src/data/bedrock/TrimPatternTypeIds.php b/src/data/bedrock/TrimPatternTypeIds.php deleted file mode 100644 index 57b4598d6e3..00000000000 --- a/src/data/bedrock/TrimPatternTypeIds.php +++ /dev/null @@ -1,44 +0,0 @@ -getTag(self::TAG_TRIM); if($trimTag instanceof CompoundTag){ - $material = TrimMaterialTypeIdMap::getInstance()->fromId($trimTag->getInt(self::TAG_TRIM_MATERIAL, -1)); - $pattern = TrimPatternTypeIdMap::getInstance()->fromId($trimTag->getInt(self::TAG_TRIM_PATTERN, -1)); + $material = ArmorTrimMaterial::tryFrom($trimTag->getString(self::TAG_TRIM_MATERIAL)); + $pattern = ArmorTrimPattern::tryFrom($trimTag->getString(self::TAG_TRIM_PATTERN)); if($material instanceof ArmorTrimMaterial && $pattern instanceof ArmorTrimPattern){ $this->armorTrim = new ArmorTrim($material, $pattern); } @@ -203,8 +201,8 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ $tag->removeTag(self::TAG_CUSTOM_COLOR); $this->armorTrim !== null ? $tag->setTag(self::TAG_TRIM, CompoundTag::create() - ->setInt(self::TAG_TRIM_MATERIAL, TrimMaterialTypeIdMap::getInstance()->toId($this->armorTrim->getMaterial())) - ->setInt(self::TAG_TRIM_PATTERN, TrimPatternTypeIdMap::getInstance()->toId($this->armorTrim->getPattern()))) : + ->setString(self::TAG_TRIM_MATERIAL, $this->armorTrim->getMaterial()->value) + ->setString(self::TAG_TRIM_PATTERN, $this->armorTrim->getPattern()->value)) : $tag->removeTag(self::TAG_TRIM); } } diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index b1c135e8141..26cb99afbcd 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -38,7 +38,7 @@ enum ArmorTrimPattern : string{ case SENTRY = "sentry"; case SHAPER = "shaper"; case SILENCE = "silence"; - case SNOUT = "snouth"; + case SNOUT = "snout"; case SPIRE = "spire"; case TIDE = "tide"; case VEX = "vex"; @@ -49,12 +49,24 @@ enum ArmorTrimPattern : string{ public const TEMPLATE_SUFFIX = "_armor_trim_smithing_template"; public static function fromItem(Item $item) : ?ArmorTrimPattern{ - foreach(StringToItemParser::getInstance()->lookupAliases($item) as $alias){ - if (!str_ends_with($alias, self::TEMPLATE_SUFFIX)){ - continue; - } - return self::tryFrom(substr($alias, 0, strlen($alias) - strlen(self::TEMPLATE_SUFFIX))); - } - return null; + return match($item->getTypeId()){ + ItemTypeIds::COAST_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::COAST, + ItemTypeIds::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::DUNE, + ItemTypeIds::EYE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::EYE, + ItemTypeIds::HOST_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::HOST, + ItemTypeIds::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::RAISER, + ItemTypeIds::RIB_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::RIB, + ItemTypeIds::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SENTRY, + ItemTypeIds::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SHAPER, + ItemTypeIds::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SILENCE, + ItemTypeIds::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SNOUT, + ItemTypeIds::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SPIRE, + ItemTypeIds::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::TIDE, + ItemTypeIds::VEX_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::VEX, + ItemTypeIds::WARD_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::WARD, + ItemTypeIds::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::WAYFINDER, + ItemTypeIds::WILD_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::WILD, + default => null + }; } } diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index eda96d407a6..08119ef98eb 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -145,9 +145,8 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData } } - $index ??= 0; + $index = CraftingManager::SMITHING_RECIPES_OFFSET; foreach($manager->getSmithingRecipes() as $recipe){ - $index++; if($recipe instanceof SmithingTransformRecipe){ $recipesWithTypeIds[] = new ProtocolSmithingTransformRecipe( CraftingDataPacket::ENTRY_SMITHING_TRANSFORM, @@ -170,6 +169,7 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData $index ); } + $index++; } $potionTypeRecipes = []; diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index df3b277ec7c..ab3e1d92c0a 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -346,7 +346,7 @@ protected function processItemStackRequestAction(ItemStackRequestAction $action) $this->setNextCreatedItem($window->getOutput($optionId)); } }elseif($window instanceof SmithingTableInventory){ - $craftingManager = Server::getInstance()->getCraftingManager(); + $craftingManager = $this->player->getServer()->getCraftingManager(); $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId()); if($recipe !== null){ $this->specialTransaction = new SmithingTransaction($this->player, $recipe); From 5360b77f06484cfa75839d83a763d8176c6da758 Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:09:00 +0100 Subject: [PATCH 09/22] cs style fixes --- src/item/ArmorTrimPattern.php | 4 ---- src/network/mcpe/handler/ItemStackRequestExecutor.php | 1 - 2 files changed, 5 deletions(-) diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index 26cb99afbcd..57a623594a5 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -23,10 +23,6 @@ namespace pocketmine\item; -use function str_ends_with; -use function strlen; -use function substr; - enum ArmorTrimPattern : string{ case COAST = "coast"; diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index ab3e1d92c0a..9a6c3013d8e 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -55,7 +55,6 @@ use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse; use pocketmine\network\mcpe\protocol\types\inventory\UIInventorySlotOffset; use pocketmine\player\Player; -use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; use function array_key_first; use function count; From 7433655b6abfd1dff43c78c5e9322e269df60f0e Mon Sep 17 00:00:00 2001 From: HimmelKreis4865 <51092444+HimmelKreis4865@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:21:56 +0100 Subject: [PATCH 10/22] resolved some more problems --- src/block/SmithingTable.php | 1 + src/crafting/SmithingTrimRecipe.php | 3 +- src/item/Armor.php | 8 +--- src/item/ArmorTrim.php | 4 +- src/item/SmithingTemplate.php | 28 ------------ src/item/VanillaItems.php | 68 ++++++++++++++--------------- 6 files changed, 39 insertions(+), 73 deletions(-) delete mode 100644 src/item/SmithingTemplate.php diff --git a/src/block/SmithingTable.php b/src/block/SmithingTable.php index e2bf9648d9d..741e9c02fdc 100644 --- a/src/block/SmithingTable.php +++ b/src/block/SmithingTable.php @@ -34,6 +34,7 @@ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player if($player !== null){ $player->setCurrentWindow(new SmithingTableInventory($this->position)); } + return true; } diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php index 67f5f3f465f..4e2c7362bdd 100644 --- a/src/crafting/SmithingTrimRecipe.php +++ b/src/crafting/SmithingTrimRecipe.php @@ -28,7 +28,6 @@ use pocketmine\item\ArmorTrimMaterial; use pocketmine\item\ArmorTrimPattern; use pocketmine\item\Item; -use pocketmine\item\SmithingTemplate; class SmithingTrimRecipe implements SmithingRecipe{ @@ -59,7 +58,7 @@ public function getResultFor(array $inputs) : ?Item{ foreach($inputs as $item){ if($item instanceof Armor){ $input = $item; - }elseif($item instanceof SmithingTemplate){ + }elseif(ArmorTrimPattern::fromItem($item) !== null){ $template = $item; }else{ $addition = $item; diff --git a/src/item/Armor.php b/src/item/Armor.php index d6de941906a..85c635c1333 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -119,17 +119,11 @@ public function getTrim() : ?ArmorTrim{ } /** @return $this */ - public function setTrim(ArmorTrim $trim) : self{ + public function setTrim(?ArmorTrim $trim) : self{ $this->armorTrim = $trim; return $this; } - /** @return $this */ - public function clearTrim() : self{ - $this->armorTrim = null; - return $this; - } - /** * Returns the total enchantment protection factor this armour piece offers from all applicable protection * enchantments on the item. diff --git a/src/item/ArmorTrim.php b/src/item/ArmorTrim.php index caadfd935b7..9c68326e67c 100644 --- a/src/item/ArmorTrim.php +++ b/src/item/ArmorTrim.php @@ -26,8 +26,8 @@ class ArmorTrim{ public function __construct( - private readonly ArmorTrimMaterial $material, - private readonly ArmorTrimPattern $pattern + private ArmorTrimMaterial $material, + private ArmorTrimPattern $pattern ){} public function getMaterial() : ArmorTrimMaterial{ diff --git a/src/item/SmithingTemplate.php b/src/item/SmithingTemplate.php deleted file mode 100644 index 2c589d6b8e3..00000000000 --- a/src/item/SmithingTemplate.php +++ /dev/null @@ -1,28 +0,0 @@ - Date: Sun, 24 Mar 2024 16:17:58 +0100 Subject: [PATCH 11/22] made materials & patterns customizable --- src/crafting/SmithingTrimRecipe.php | 9 +- src/item/Armor.php | 8 +- src/item/ArmorTrimMaterial.php | 85 ++++------- src/item/ArmorTrimPattern.php | 70 ++++----- src/item/ArmorTrimRegistry.php | 142 ++++++++++++++++++ .../mcpe/handler/PreSpawnPacketHandler.php | 5 +- 6 files changed, 215 insertions(+), 104 deletions(-) create mode 100644 src/item/ArmorTrimRegistry.php diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php index 4e2c7362bdd..476602e8dbd 100644 --- a/src/crafting/SmithingTrimRecipe.php +++ b/src/crafting/SmithingTrimRecipe.php @@ -25,8 +25,7 @@ use pocketmine\item\Armor; use pocketmine\item\ArmorTrim; -use pocketmine\item\ArmorTrimMaterial; -use pocketmine\item\ArmorTrimPattern; +use pocketmine\item\ArmorTrimRegistry; use pocketmine\item\Item; class SmithingTrimRecipe implements SmithingRecipe{ @@ -58,7 +57,7 @@ public function getResultFor(array $inputs) : ?Item{ foreach($inputs as $item){ if($item instanceof Armor){ $input = $item; - }elseif(ArmorTrimPattern::fromItem($item) !== null){ + }elseif(ArmorTrimRegistry::getInstance()->getPatternFromItem($item) !== null){ $template = $item; }else{ $addition = $item; @@ -68,7 +67,9 @@ public function getResultFor(array $inputs) : ?Item{ if($input === null || $addition === null || $template === null){ return null; } - if(($material = ArmorTrimMaterial::fromItem($addition)) === null || ($pattern = ArmorTrimPattern::fromItem($template)) === null){ + $material = ArmorTrimRegistry::getInstance()->getMaterialFromItem($addition); + $pattern = ArmorTrimRegistry::getInstance()->getPatternFromItem($template); + if($material === null || $pattern === null){ return null; } return $input->setTrim(new ArmorTrim($material, $pattern)); diff --git a/src/item/Armor.php b/src/item/Armor.php index 85c635c1333..2cce390efac 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -180,8 +180,8 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ } $trimTag = $tag->getTag(self::TAG_TRIM); if($trimTag instanceof CompoundTag){ - $material = ArmorTrimMaterial::tryFrom($trimTag->getString(self::TAG_TRIM_MATERIAL)); - $pattern = ArmorTrimPattern::tryFrom($trimTag->getString(self::TAG_TRIM_PATTERN)); + $material = ArmorTrimRegistry::getInstance()->getMaterial($trimTag->getString(self::TAG_TRIM_MATERIAL)); + $pattern = ArmorTrimRegistry::getInstance()->getPattern($trimTag->getString(self::TAG_TRIM_PATTERN)); if($material instanceof ArmorTrimMaterial && $pattern instanceof ArmorTrimPattern){ $this->armorTrim = new ArmorTrim($material, $pattern); } @@ -195,8 +195,8 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ $tag->removeTag(self::TAG_CUSTOM_COLOR); $this->armorTrim !== null ? $tag->setTag(self::TAG_TRIM, CompoundTag::create() - ->setString(self::TAG_TRIM_MATERIAL, $this->armorTrim->getMaterial()->value) - ->setString(self::TAG_TRIM_PATTERN, $this->armorTrim->getPattern()->value)) : + ->setString(self::TAG_TRIM_MATERIAL, $this->armorTrim->getMaterial()->getIdentifier()) + ->setString(self::TAG_TRIM_PATTERN, $this->armorTrim->getPattern()->getIdentifier())) : $tag->removeTag(self::TAG_TRIM); } } diff --git a/src/item/ArmorTrimMaterial.php b/src/item/ArmorTrimMaterial.php index 653201627a3..e80111a775c 100644 --- a/src/item/ArmorTrimMaterial.php +++ b/src/item/ArmorTrimMaterial.php @@ -23,66 +23,39 @@ namespace pocketmine\item; -use InvalidArgumentException; -use pocketmine\data\bedrock\item\ItemTypeNames; -use pocketmine\utils\TextFormat; - -enum ArmorTrimMaterial : string{ - - case AMETHYST = "amethyst"; - case COPPER = "copper"; - case DIAMOND = "diamond"; - case EMERALD = "emerald"; - case GOLD = "gold"; - case IRON = "iron"; - case LAPIS = "lapis"; - case NETHERITE = "netherite"; - case QUARTZ = "quartz"; - case REDSTONE = "redstone"; +class ArmorTrimMaterial{ + + public const AMETHYST = "amethyst"; + public const COPPER = "copper"; + public const DIAMOND = "diamond"; + public const EMERALD = "emerald"; + public const GOLD = "gold"; + public const IRON = "iron"; + public const LAPIS = "lapis"; + public const NETHERITE = "netherite"; + public const QUARTZ = "quartz"; + public const REDSTONE = "redstone"; + + public function __construct( + private string $identifier, + private string $color, + private string $itemName, + private int $typeId + ){} + + public function getIdentifier() : string{ + return $this->identifier; + } - public static function fromItem(Item $item) : ?self{ - return match($item->getTypeId()){ - ItemTypeIds::AMETHYST_SHARD => self::AMETHYST, - ItemTypeIds::COPPER_INGOT => self::COPPER, - ItemTypeIds::DIAMOND => self::DIAMOND, - ItemTypeIds::EMERALD => self::EMERALD, - ItemTypeIds::GOLD_INGOT => self::GOLD, - ItemTypeIds::IRON_INGOT => self::IRON, - ItemTypeIds::LAPIS_LAZULI => self::LAPIS, - ItemTypeIds::NETHERITE_INGOT => self::NETHERITE, - ItemTypeIds::NETHER_QUARTZ => self::QUARTZ, - ItemTypeIds::REDSTONE_DUST => self::REDSTONE, - default => throw new InvalidArgumentException("Item " . $item . " is no valid armor trim material") - }; + public function getColor() : string{ + return $this->color; } - public function getItemId() : string{ - return match($this){ - self::AMETHYST => ItemTypeNames::AMETHYST_SHARD, - self::COPPER => ItemTypeNames::COPPER_INGOT, - self::DIAMOND => ItemTypeNames::DIAMOND, - self::EMERALD => ItemTypeNames::EMERALD, - self::GOLD => ItemTypeNames::GOLD_INGOT, - self::IRON => ItemTypeNames::IRON_INGOT, - self::LAPIS => ItemTypeNames::LAPIS_LAZULI, - self::NETHERITE => ItemTypeNames::NETHERITE_INGOT, - self::QUARTZ => ItemTypeNames::QUARTZ, - self::REDSTONE => ItemTypeNames::REDSTONE - }; + public function getItemName() : string{ + return $this->itemName; } - public function getColor() : string{ - return match($this){ - self::AMETHYST => TextFormat::MATERIAL_AMETHYST, - self::COPPER => TextFormat::MATERIAL_COPPER, - self::DIAMOND => TextFormat::MATERIAL_DIAMOND, - self::EMERALD => TextFormat::MATERIAL_EMERALD, - self::GOLD => TextFormat::MATERIAL_GOLD, - self::IRON => TextFormat::MATERIAL_IRON, - self::LAPIS => TextFormat::MATERIAL_LAPIS, - self::NETHERITE => TextFormat::MATERIAL_NETHERITE, - self::QUARTZ => TextFormat::MATERIAL_QUARTZ, - self::REDSTONE => TextFormat::MATERIAL_REDSTONE - }; + public function getTypeId() : int{ + return $this->typeId; } } diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index 57a623594a5..8a04afcf669 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -23,46 +23,40 @@ namespace pocketmine\item; -enum ArmorTrimPattern : string{ +class ArmorTrimPattern{ - case COAST = "coast"; - case DUNE = "dune"; - case EYE = "eye"; - case HOST = "host"; - case RAISER = "raiser"; - case RIB = "rib"; - case SENTRY = "sentry"; - case SHAPER = "shaper"; - case SILENCE = "silence"; - case SNOUT = "snout"; - case SPIRE = "spire"; - case TIDE = "tide"; - case VEX = "vex"; - case WARD = "ward"; - case WAYFINDER = "wayfinder"; - case WILD = "wild"; + public const COAST = "coast"; + public const DUNE = "dune"; + public const EYE = "eye"; + public const HOST = "host"; + public const RAISER = "raiser"; + public const RIB = "rib"; + public const SENTRY = "sentry"; + public const SHAPER = "shaper"; + public const SILENCE = "silence"; + public const SNOUT = "snout"; + public const SPIRE = "spire"; + public const TIDE = "tide"; + public const VEX = "vex"; + public const WARD = "ward"; + public const WAYFINDER = "wayfinder"; + public const WILD = "wild"; - public const TEMPLATE_SUFFIX = "_armor_trim_smithing_template"; + public function __construct( + private string $identifier, + private string $itemName, + private int $typeId + ){} - public static function fromItem(Item $item) : ?ArmorTrimPattern{ - return match($item->getTypeId()){ - ItemTypeIds::COAST_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::COAST, - ItemTypeIds::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::DUNE, - ItemTypeIds::EYE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::EYE, - ItemTypeIds::HOST_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::HOST, - ItemTypeIds::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::RAISER, - ItemTypeIds::RIB_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::RIB, - ItemTypeIds::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SENTRY, - ItemTypeIds::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SHAPER, - ItemTypeIds::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SILENCE, - ItemTypeIds::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SNOUT, - ItemTypeIds::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::SPIRE, - ItemTypeIds::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::TIDE, - ItemTypeIds::VEX_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::VEX, - ItemTypeIds::WARD_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::WARD, - ItemTypeIds::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::WAYFINDER, - ItemTypeIds::WILD_ARMOR_TRIM_SMITHING_TEMPLATE => ArmorTrimPattern::WILD, - default => null - }; + public function getIdentifier() : string{ + return $this->identifier; + } + + public function getItemName() : string{ + return $this->itemName; + } + + public function getTypeId() : int{ + return $this->typeId; } } diff --git a/src/item/ArmorTrimRegistry.php b/src/item/ArmorTrimRegistry.php new file mode 100644 index 00000000000..624d57dbe36 --- /dev/null +++ b/src/item/ArmorTrimRegistry.php @@ -0,0 +1,142 @@ + + */ + private array $materials = []; + + /** + * @var ArmorTrimMaterial[] $patterns, + * @phpstan-var array + */ + private array $idToMaterialMap = []; + + /** + * @var ArmorTrimPattern[] $patterns + * @phpstan-var array + */ + private array $patterns = []; + + /** + * @var ArmorTrimPattern[] $patterns, + * @phpstan-var array + */ + private array $idToPatternMap = []; + + public function __construct(){ + $this->registerDefaultMaterials(); + $this->registerDefaultPatterns(); + } + + private function registerDefaultMaterials() : void{ + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::AMETHYST, TextFormat::MATERIAL_AMETHYST, Names::AMETHYST_SHARD, Ids::AMETHYST_SHARD)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::COPPER, TextFormat::MATERIAL_COPPER, Names::COPPER_INGOT, Ids::COPPER_INGOT)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::DIAMOND, TextFormat::MATERIAL_DIAMOND, Names::DIAMOND, Ids::DIAMOND)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::EMERALD, TextFormat::MATERIAL_EMERALD, Names::EMERALD, Ids::EMERALD)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::GOLD, TextFormat::MATERIAL_GOLD, Names::GOLD_INGOT, Ids::GOLD_INGOT)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::IRON, TextFormat::MATERIAL_IRON, Names::IRON_INGOT, Ids::IRON_INGOT)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::LAPIS, TextFormat::MATERIAL_LAPIS, Names::LAPIS_LAZULI, Ids::LAPIS_LAZULI)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::NETHERITE, TextFormat::MATERIAL_NETHERITE, Names::NETHERITE_INGOT, Ids::NETHERITE_INGOT)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::QUARTZ, TextFormat::MATERIAL_QUARTZ, Names::QUARTZ, Ids::NETHER_QUARTZ)); + $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::REDSTONE, TextFormat::MATERIAL_REDSTONE, Names::REDSTONE, Ids::REDSTONE_DUST)); + } + + private function registerDefaultPatterns() : void{ + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::COAST, Names::COAST_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::COAST_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::DUNE, Names::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::EYE, Names::EYE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::EYE_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::HOST, Names::HOST_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::HOST_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::RAISER, Names::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::RIB, Names::RIB_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::RIB_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SENTRY, Names::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SHAPER, Names::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SILENCE, Names::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SNOUT,Names::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SPIRE,Names::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::TIDE,Names::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::VEX,Names::VEX_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::VEX_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::WARD,Names::WARD_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::WARD_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::WAYFINDER,Names::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE)); + $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::WILD,Names::WILD_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::WILD_ARMOR_TRIM_SMITHING_TEMPLATE)); + } + + public function registerMaterial(ArmorTrimMaterial $material, bool $overwrite = false) : bool{ + if((isset($this->materials[$material->getIdentifier()]) || isset($this->idToMaterialMap[$material->getTypeId()])) && !$overwrite){ + return false; + } + $this->materials[$material->getIdentifier()] = $material; + $this->idToMaterialMap[$material->getTypeId()] = $material; + return true; + } + + public function registerPattern(ArmorTrimPattern $pattern, bool $overwrite = false) : bool{ + if((isset($this->patterns[$pattern->getIdentifier()]) || isset($this->idToPatternMap[$pattern->getTypeId()])) && !$overwrite){ + return false; + } + $this->patterns[$pattern->getIdentifier()] = $pattern; + $this->idToPatternMap[$pattern->getTypeId()] = $pattern; + return true; + } + + public function getMaterial(string $identifier) : ?ArmorTrimMaterial{ + return $this->materials[$identifier] ?? null; + } + + public function getMaterialFromItem(Item $item) : ?ArmorTrimMaterial{ + return $this->idToMaterialMap[$item->getTypeId()] ?? null; + } + + public function getPattern(string $identifier) : ?ArmorTrimPattern{ + return $this->patterns[$identifier] ?? null; + } + + public function getPatternFromItem(Item $item) : ?ArmorTrimPattern{ + return $this->idToPatternMap[$item->getTypeId()] ?? null; + } + + /** + * @return ArmorTrimMaterial[] + */ + public function getMaterials() : array{ + return $this->materials; + } + + /** + * @return ArmorTrimPattern[] + */ + public function getPatterns() : array{ + return $this->patterns; + } +} diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 165b0c5ccdf..0914435addd 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -25,6 +25,7 @@ use pocketmine\item\ArmorTrimMaterial; use pocketmine\item\ArmorTrimPattern; +use pocketmine\item\ArmorTrimRegistry; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\cache\CraftingDataCache; use pocketmine\network\mcpe\cache\StaticPacketCache; @@ -151,8 +152,8 @@ public function setUp() : void{ $this->inventoryManager->syncCreative(); $this->session->getLogger()->debug("Sending armor trim data"); - $patterns = array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern("minecraft:" . $pattern->value . ArmorTrimPattern::TEMPLATE_SUFFIX, $pattern->value), ArmorTrimPattern::cases()); - $materials = array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->value, $material->getColor(), $material->getItemId()), ArmorTrimMaterial::cases()); + $patterns = array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($pattern->getItemName(), $pattern->getIdentifier()), ArmorTrimRegistry::getInstance()->getPatterns()); + $materials = array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->getIdentifier(), $material->getColor(), $material->getItemName()), ArmorTrimRegistry::getInstance()->getMaterials()); $this->session->sendDataPacket(TrimDataPacket::create($patterns, $materials)); $this->session->getLogger()->debug("Sending crafting data"); From 849f9b1537087a43769b876a5554eb8a511580e4 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:20:02 +0300 Subject: [PATCH 12/22] Code overhaul --- src/crafting/SmithingTransformRecipe.php | 12 +- src/crafting/SmithingTrimRecipe.php | 36 ++--- .../bedrock/ArmorTrimMaterialTypeIdMap.php | 101 +++++++++++++ src/data/bedrock/ArmorTrimMaterialTypeIds.php | 37 +++++ .../bedrock/ArmorTrimPatternTypeIdMap.php | 107 +++++++++++++ src/data/bedrock/ArmorTrimPatternTypeIds.php | 43 ++++++ .../transaction/SmithingTransaction.php | 2 +- src/item/Armor.php | 15 +- src/item/ArmorTrimMaterial.php | 41 ++--- src/item/ArmorTrimPattern.php | 35 +---- src/item/ArmorTrimRegistry.php | 142 ------------------ src/item/VanillaArmorTrimMaterials.php | 80 ++++++++++ src/item/VanillaArmorTrimPatterns.php | 91 +++++++++++ .../mcpe/handler/PreSpawnPacketHandler.php | 16 +- 14 files changed, 523 insertions(+), 235 deletions(-) create mode 100644 src/data/bedrock/ArmorTrimMaterialTypeIdMap.php create mode 100644 src/data/bedrock/ArmorTrimMaterialTypeIds.php create mode 100644 src/data/bedrock/ArmorTrimPatternTypeIdMap.php create mode 100644 src/data/bedrock/ArmorTrimPatternTypeIds.php delete mode 100644 src/item/ArmorTrimRegistry.php create mode 100644 src/item/VanillaArmorTrimMaterials.php create mode 100644 src/item/VanillaArmorTrimPatterns.php diff --git a/src/crafting/SmithingTransformRecipe.php b/src/crafting/SmithingTransformRecipe.php index dfe81c87847..de4c5e9e08b 100644 --- a/src/crafting/SmithingTransformRecipe.php +++ b/src/crafting/SmithingTransformRecipe.php @@ -23,9 +23,7 @@ namespace pocketmine\crafting; -use pocketmine\item\Armor; use pocketmine\item\Item; -use pocketmine\item\TieredTool; class SmithingTransformRecipe implements SmithingRecipe{ @@ -59,15 +57,11 @@ public function getResult() : Item{ * @phpstan-param list $inputs */ public function getResultFor(array $inputs) : ?Item{ - $input = null; foreach($inputs as $item){ - if ($item instanceof Armor || $item instanceof TieredTool){ - $input = $item; + if($this->input->accepts($item)){ + return $this->getResult()->setNamedTag($item->getNamedTag()); } } - if($input === null){ - return null; - } - return $this->getResult()->setNamedTag($input->getNamedTag()); + return null; } } diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php index 476602e8dbd..5f7555c9fb7 100644 --- a/src/crafting/SmithingTrimRecipe.php +++ b/src/crafting/SmithingTrimRecipe.php @@ -23,18 +23,19 @@ namespace pocketmine\crafting; +use pocketmine\data\bedrock\ArmorTrimMaterialTypeIdMap; +use pocketmine\data\bedrock\ArmorTrimPatternTypeIdMap; use pocketmine\item\Armor; use pocketmine\item\ArmorTrim; -use pocketmine\item\ArmorTrimRegistry; use pocketmine\item\Item; class SmithingTrimRecipe implements SmithingRecipe{ public function __construct( - private readonly RecipeIngredient $input, - private readonly RecipeIngredient $addition, - private readonly RecipeIngredient $template){ - } + private RecipeIngredient $input, + private RecipeIngredient $addition, + private RecipeIngredient $template + ){} public function getInput() : RecipeIngredient{ return $this->input; @@ -55,23 +56,22 @@ public function getTemplate() : RecipeIngredient{ public function getResultFor(array $inputs) : ?Item{ $input = $template = $addition = null; foreach($inputs as $item){ - if($item instanceof Armor){ + if($this->input->accepts($item) && $item instanceof Armor){ $input = $item; - }elseif(ArmorTrimRegistry::getInstance()->getPatternFromItem($item) !== null){ - $template = $item; - }else{ + }elseif($this->addition->accepts($item)){ $addition = $item; + }elseif($this->template->accepts($item)){ + $template = $item; } } - - if($input === null || $addition === null || $template === null){ - return null; - } - $material = ArmorTrimRegistry::getInstance()->getMaterialFromItem($addition); - $pattern = ArmorTrimRegistry::getInstance()->getPatternFromItem($template); - if($material === null || $pattern === null){ - return null; + if($input !== null && $addition !== null && $template !== null){ + $material = ArmorTrimMaterialTypeIdMap::getInstance()->fromItem($addition); + $pattern = ArmorTrimPatternTypeIdMap::getInstance()->fromItem($template); + if($material !== null && $pattern !== null){ + return (clone $input)->setTrim(new ArmorTrim($material, $pattern)); + } } - return $input->setTrim(new ArmorTrim($material, $pattern)); + + return null; } } diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php new file mode 100644 index 00000000000..026ca7829bd --- /dev/null +++ b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php @@ -0,0 +1,101 @@ + + */ + private array $idToMaterial = []; + /** + * @var ArmorTrimMaterial[] + * @phpstan-var array + */ + private array $itemToMaterial = []; + /** + * @var string[] + * @phpstan-var array + */ + private array $materialToId = []; + + public function __construct(){ + foreach(Materials::getAll() as $case){ + $this->register(match($case) { + Materials::AMETHYST() => Ids::AMETHYST, + Materials::COPPER() => Ids::COPPER, + Materials::DIAMOND() => Ids::DIAMOND, + Materials::EMERALD() => Ids::EMERALD, + Materials::GOLD() => Ids::GOLD, + Materials::IRON() => Ids::IRON, + Materials::LAPIS() => Ids::LAPIS, + Materials::NETHERITE() => Ids::NETHERITE, + Materials::QUARTZ() => Ids::QUARTZ, + Materials::REDSTONE() => Ids::REDSTONE, + default => throw new AssumptionFailedError("Unhandled armor trim material type") + }, $case); + } + } + + public function register(string $stringId, ArmorTrimMaterial $material) : void{ + $this->idToMaterial[$stringId] = $material; + $this->itemToMaterial[$material->getItem()->getStateId()] = $material; + $this->materialToId[spl_object_id($material)] = $stringId; + } + + public function fromId(string $id) : ?ArmorTrimMaterial{ + return $this->idToMaterial[$id] ?? null; + } + + public function fromItem(Item $item) : ?ArmorTrimMaterial{ + return $this->itemToMaterial[$item->getStateId()] ?? null; + } + + public function toId(ArmorTrimMaterial $material) : string{ + $k = spl_object_id($material); + if(!array_key_exists($k, $this->materialToId)){ + throw new \InvalidArgumentException("Missing mapping for armor trim material with item" . $material->getItem()->getName() . " and color " . $material->getColor()); + } + return $this->materialToId[$k]; + } + + /** + * @return ArmorTrimMaterial[] + */ + public function getAllMaterials() : array{ + return array_values($this->idToMaterial); + } +} diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIds.php b/src/data/bedrock/ArmorTrimMaterialTypeIds.php new file mode 100644 index 00000000000..6c6ada1dcb4 --- /dev/null +++ b/src/data/bedrock/ArmorTrimMaterialTypeIds.php @@ -0,0 +1,37 @@ + + */ + private array $idToPattern = []; + /** + * @var ArmorTrimPattern[] + * @phpstan-var array + */ + private array $itemToPattern = []; + /** + * @var string[] + * @phpstan-var array + */ + private array $patternToId = []; + + public function __construct(){ + foreach(Patterns::getAll() as $case){ + $this->register(match($case){ + Patterns::COAST() => Ids::COAST, + Patterns::DUNE() => Ids::DUNE, + Patterns::EYE() => Ids::EYE, + Patterns::HOST() => Ids::HOST, + Patterns::RAISER() => Ids::RAISER, + Patterns::RIB() => Ids::RIB, + Patterns::SENTRY() => Ids::SENTRY, + Patterns::SHAPER() => Ids::SHAPER, + Patterns::SILENCE() => Ids::SILENCE, + Patterns::SNOUT() => Ids::SNOUT, + Patterns::SPIRE() => Ids::SPIRE, + Patterns::TIDE() => Ids::TIDE, + Patterns::VEX() => Ids::VEX, + Patterns::WARD() => Ids::WARD, + Patterns::WAYFINDER() => Ids::WAYFINDER, + Patterns::WILD() => Ids::WILD, + default => throw new AssumptionFailedError("Unhandled armor trim pattern type") + }, $case); + } + } + + public function register(string $stringId, ArmorTrimPattern $pattern) : void{ + $this->idToPattern[$stringId] = $pattern; + $this->itemToPattern[$pattern->getItem()->getStateId()] = $pattern; + $this->patternToId[spl_object_id($pattern)] = $stringId; + } + + public function fromId(string $id) : ?ArmorTrimPattern{ + return $this->idToPattern[$id] ?? null; + } + + public function fromItem(Item $item) : ?ArmorTrimPattern{ + return $this->itemToPattern[$item->getStateId()] ?? null; + } + + public function toId(ArmorTrimPattern $pattern) : string{ + $k = spl_object_id($pattern); + if(!array_key_exists($k, $this->patternToId)){ + throw new \InvalidArgumentException("Missing mapping for armor trim pattern with item" . $pattern->getItem()->getName()); + } + return $this->patternToId[$k]; + } + + /** + * @return ArmorTrimPattern[] + */ + public function getAllPatterns() : array{ + return array_values($this->idToPattern); + } +} diff --git a/src/data/bedrock/ArmorTrimPatternTypeIds.php b/src/data/bedrock/ArmorTrimPatternTypeIds.php new file mode 100644 index 00000000000..877c9c536cb --- /dev/null +++ b/src/data/bedrock/ArmorTrimPatternTypeIds.php @@ -0,0 +1,43 @@ +customColor = null; } + $trimTag = $tag->getTag(self::TAG_TRIM); if($trimTag instanceof CompoundTag){ - $material = ArmorTrimRegistry::getInstance()->getMaterial($trimTag->getString(self::TAG_TRIM_MATERIAL)); - $pattern = ArmorTrimRegistry::getInstance()->getPattern($trimTag->getString(self::TAG_TRIM_PATTERN)); - if($material instanceof ArmorTrimMaterial && $pattern instanceof ArmorTrimPattern){ + $material = ArmorTrimMaterialTypeIdMap::getInstance()->fromId($trimTag->getString(self::TAG_TRIM_MATERIAL)); + $pattern = ArmorTrimPatternTypeIdMap::getInstance()->fromId($trimTag->getString(self::TAG_TRIM_PATTERN)); + + if($material !== null && $pattern !== null){ $this->armorTrim = new ArmorTrim($material, $pattern); } } @@ -197,10 +201,11 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ $this->customColor !== null ? $tag->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($this->customColor->toARGB())) : $tag->removeTag(self::TAG_CUSTOM_COLOR); + $this->armorTrim !== null ? $tag->setTag(self::TAG_TRIM, CompoundTag::create() - ->setString(self::TAG_TRIM_MATERIAL, $this->armorTrim->getMaterial()->getIdentifier()) - ->setString(self::TAG_TRIM_PATTERN, $this->armorTrim->getPattern()->getIdentifier())) : + ->setString(self::TAG_TRIM_MATERIAL, ArmorTrimMaterialTypeIdMap::getInstance()->toId($this->armorTrim->getMaterial())) + ->setString(self::TAG_TRIM_PATTERN, ArmorTrimPatternTypeIdMap::getInstance()->toId($this->armorTrim->getPattern()))) : $tag->removeTag(self::TAG_TRIM); } } diff --git a/src/item/ArmorTrimMaterial.php b/src/item/ArmorTrimMaterial.php index e80111a775c..fe4abefe79b 100644 --- a/src/item/ArmorTrimMaterial.php +++ b/src/item/ArmorTrimMaterial.php @@ -25,37 +25,26 @@ class ArmorTrimMaterial{ - public const AMETHYST = "amethyst"; - public const COPPER = "copper"; - public const DIAMOND = "diamond"; - public const EMERALD = "emerald"; - public const GOLD = "gold"; - public const IRON = "iron"; - public const LAPIS = "lapis"; - public const NETHERITE = "netherite"; - public const QUARTZ = "quartz"; - public const REDSTONE = "redstone"; + private Item $item; + /** + * @param string $color Minecraft color code. + */ public function __construct( - private string $identifier, - private string $color, - private string $itemName, - private int $typeId - ){} - - public function getIdentifier() : string{ - return $this->identifier; + Item $item, + private string $color + ){ + $this->item = clone $item; } - public function getColor() : string{ - return $this->color; - } - - public function getItemName() : string{ - return $this->itemName; + public function getItem() : Item{ + return clone $this->item; } - public function getTypeId() : int{ - return $this->typeId; + /** + * Returns the Minecraft color code. + */ + public function getColor() : string{ + return $this->color; } } diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index 8a04afcf669..a08aa68b0ea 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -25,38 +25,13 @@ class ArmorTrimPattern{ - public const COAST = "coast"; - public const DUNE = "dune"; - public const EYE = "eye"; - public const HOST = "host"; - public const RAISER = "raiser"; - public const RIB = "rib"; - public const SENTRY = "sentry"; - public const SHAPER = "shaper"; - public const SILENCE = "silence"; - public const SNOUT = "snout"; - public const SPIRE = "spire"; - public const TIDE = "tide"; - public const VEX = "vex"; - public const WARD = "ward"; - public const WAYFINDER = "wayfinder"; - public const WILD = "wild"; + private Item $item; - public function __construct( - private string $identifier, - private string $itemName, - private int $typeId - ){} - - public function getIdentifier() : string{ - return $this->identifier; - } - - public function getItemName() : string{ - return $this->itemName; + public function __construct(Item $item){ + $this->item = clone $item; } - public function getTypeId() : int{ - return $this->typeId; + public function getItem() : Item{ + return clone $this->item; } } diff --git a/src/item/ArmorTrimRegistry.php b/src/item/ArmorTrimRegistry.php deleted file mode 100644 index 624d57dbe36..00000000000 --- a/src/item/ArmorTrimRegistry.php +++ /dev/null @@ -1,142 +0,0 @@ - - */ - private array $materials = []; - - /** - * @var ArmorTrimMaterial[] $patterns, - * @phpstan-var array - */ - private array $idToMaterialMap = []; - - /** - * @var ArmorTrimPattern[] $patterns - * @phpstan-var array - */ - private array $patterns = []; - - /** - * @var ArmorTrimPattern[] $patterns, - * @phpstan-var array - */ - private array $idToPatternMap = []; - - public function __construct(){ - $this->registerDefaultMaterials(); - $this->registerDefaultPatterns(); - } - - private function registerDefaultMaterials() : void{ - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::AMETHYST, TextFormat::MATERIAL_AMETHYST, Names::AMETHYST_SHARD, Ids::AMETHYST_SHARD)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::COPPER, TextFormat::MATERIAL_COPPER, Names::COPPER_INGOT, Ids::COPPER_INGOT)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::DIAMOND, TextFormat::MATERIAL_DIAMOND, Names::DIAMOND, Ids::DIAMOND)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::EMERALD, TextFormat::MATERIAL_EMERALD, Names::EMERALD, Ids::EMERALD)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::GOLD, TextFormat::MATERIAL_GOLD, Names::GOLD_INGOT, Ids::GOLD_INGOT)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::IRON, TextFormat::MATERIAL_IRON, Names::IRON_INGOT, Ids::IRON_INGOT)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::LAPIS, TextFormat::MATERIAL_LAPIS, Names::LAPIS_LAZULI, Ids::LAPIS_LAZULI)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::NETHERITE, TextFormat::MATERIAL_NETHERITE, Names::NETHERITE_INGOT, Ids::NETHERITE_INGOT)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::QUARTZ, TextFormat::MATERIAL_QUARTZ, Names::QUARTZ, Ids::NETHER_QUARTZ)); - $this->registerMaterial(new ArmorTrimMaterial(ArmorTrimMaterial::REDSTONE, TextFormat::MATERIAL_REDSTONE, Names::REDSTONE, Ids::REDSTONE_DUST)); - } - - private function registerDefaultPatterns() : void{ - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::COAST, Names::COAST_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::COAST_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::DUNE, Names::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::EYE, Names::EYE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::EYE_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::HOST, Names::HOST_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::HOST_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::RAISER, Names::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::RIB, Names::RIB_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::RIB_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SENTRY, Names::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SHAPER, Names::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SILENCE, Names::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SNOUT,Names::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::SPIRE,Names::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::TIDE,Names::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::VEX,Names::VEX_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::VEX_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::WARD,Names::WARD_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::WARD_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::WAYFINDER,Names::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE)); - $this->registerPattern(new ArmorTrimPattern(ArmorTrimPattern::WILD,Names::WILD_ARMOR_TRIM_SMITHING_TEMPLATE, Ids::WILD_ARMOR_TRIM_SMITHING_TEMPLATE)); - } - - public function registerMaterial(ArmorTrimMaterial $material, bool $overwrite = false) : bool{ - if((isset($this->materials[$material->getIdentifier()]) || isset($this->idToMaterialMap[$material->getTypeId()])) && !$overwrite){ - return false; - } - $this->materials[$material->getIdentifier()] = $material; - $this->idToMaterialMap[$material->getTypeId()] = $material; - return true; - } - - public function registerPattern(ArmorTrimPattern $pattern, bool $overwrite = false) : bool{ - if((isset($this->patterns[$pattern->getIdentifier()]) || isset($this->idToPatternMap[$pattern->getTypeId()])) && !$overwrite){ - return false; - } - $this->patterns[$pattern->getIdentifier()] = $pattern; - $this->idToPatternMap[$pattern->getTypeId()] = $pattern; - return true; - } - - public function getMaterial(string $identifier) : ?ArmorTrimMaterial{ - return $this->materials[$identifier] ?? null; - } - - public function getMaterialFromItem(Item $item) : ?ArmorTrimMaterial{ - return $this->idToMaterialMap[$item->getTypeId()] ?? null; - } - - public function getPattern(string $identifier) : ?ArmorTrimPattern{ - return $this->patterns[$identifier] ?? null; - } - - public function getPatternFromItem(Item $item) : ?ArmorTrimPattern{ - return $this->idToPatternMap[$item->getTypeId()] ?? null; - } - - /** - * @return ArmorTrimMaterial[] - */ - public function getMaterials() : array{ - return $this->materials; - } - - /** - * @return ArmorTrimPattern[] - */ - public function getPatterns() : array{ - return $this->patterns; - } -} diff --git a/src/item/VanillaArmorTrimMaterials.php b/src/item/VanillaArmorTrimMaterials.php new file mode 100644 index 00000000000..edba1572ba1 --- /dev/null +++ b/src/item/VanillaArmorTrimMaterials.php @@ -0,0 +1,80 @@ + + */ + public static function getAll() : array{ + // phpstan doesn't support generic traits yet :( + /** @var ArmorTrimMaterial[] $result */ + $result = self::_registryGetAll(); + return $result; + } + + protected static function setup() : void{ + self::register("amethyst", new ArmorTrimMaterial(VanillaItems::AMETHYST_SHARD(), TextFormat::MATERIAL_AMETHYST)); + self::register("copper", new ArmorTrimMaterial(VanillaItems::COPPER_INGOT(), TextFormat::MATERIAL_COPPER)); + self::register("diamond", new ArmorTrimMaterial(VanillaItems::DIAMOND(), TextFormat::MATERIAL_DIAMOND)); + self::register("emerald", new ArmorTrimMaterial(VanillaItems::EMERALD(), TextFormat::MATERIAL_EMERALD)); + self::register("gold", new ArmorTrimMaterial(VanillaItems::GOLD_INGOT(), TextFormat::MATERIAL_GOLD)); + self::register("iron", new ArmorTrimMaterial(VanillaItems::IRON_INGOT(), TextFormat::MATERIAL_IRON)); + self::register("lapis", new ArmorTrimMaterial(VanillaItems::LAPIS_LAZULI(), TextFormat::MATERIAL_LAPIS)); + self::register("netherite", new ArmorTrimMaterial(VanillaItems::NETHERITE_INGOT(), TextFormat::MATERIAL_NETHERITE)); + self::register("quartz", new ArmorTrimMaterial(VanillaItems::NETHER_QUARTZ(), TextFormat::MATERIAL_QUARTZ)); + self::register("redstone", new ArmorTrimMaterial(VanillaItems::REDSTONE_DUST(), TextFormat::MATERIAL_REDSTONE)); + } +} diff --git a/src/item/VanillaArmorTrimPatterns.php b/src/item/VanillaArmorTrimPatterns.php new file mode 100644 index 00000000000..3045ce84126 --- /dev/null +++ b/src/item/VanillaArmorTrimPatterns.php @@ -0,0 +1,91 @@ + + */ + public static function getAll() : array{ + // phpstan doesn't support generic traits yet :( + /** @var ArmorTrimPattern[] $result */ + $result = self::_registryGetAll(); + return $result; + } + + protected static function setup() : void{ + self::register("coast", new ArmorTrimPattern(VanillaItems::COAST_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("dune", new ArmorTrimPattern(VanillaItems::DUNE_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("eye", new ArmorTrimPattern(VanillaItems::EYE_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("host", new ArmorTrimPattern(VanillaItems::HOST_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("raiser", new ArmorTrimPattern(VanillaItems::RAISER_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("rib", new ArmorTrimPattern(VanillaItems::RIB_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("sentry", new ArmorTrimPattern(VanillaItems::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("shaper", new ArmorTrimPattern(VanillaItems::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("silence", new ArmorTrimPattern(VanillaItems::SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("snout", new ArmorTrimPattern(VanillaItems::SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("spire", new ArmorTrimPattern(VanillaItems::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("tide", new ArmorTrimPattern(VanillaItems::TIDE_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("vex", new ArmorTrimPattern(VanillaItems::VEX_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("ward", new ArmorTrimPattern(VanillaItems::WARD_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("wayfinder", new ArmorTrimPattern(VanillaItems::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE())); + self::register("wild", new ArmorTrimPattern(VanillaItems::WILD_ARMOR_TRIM_SMITHING_TEMPLATE())); + } +} diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 2bc3deb7e49..aaadc7d9877 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -23,9 +23,10 @@ namespace pocketmine\network\mcpe\handler; +use pocketmine\data\bedrock\ArmorTrimMaterialTypeIdMap; +use pocketmine\data\bedrock\ArmorTrimPatternTypeIdMap; use pocketmine\item\ArmorTrimMaterial; use pocketmine\item\ArmorTrimPattern; -use pocketmine\item\ArmorTrimRegistry; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\cache\CraftingDataCache; use pocketmine\network\mcpe\cache\StaticPacketCache; @@ -51,6 +52,7 @@ use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\VersionInfo; +use pocketmine\world\format\io\GlobalItemDataHandlers; use Ramsey\Uuid\Uuid; use function array_map; use function sprintf; @@ -152,9 +154,15 @@ public function setUp() : void{ $this->inventoryManager->syncCreative(); $this->session->getLogger()->debug("Sending armor trim data"); - $patterns = array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($pattern->getItemName(), $pattern->getIdentifier()), ArmorTrimRegistry::getInstance()->getPatterns()); - $materials = array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($material->getIdentifier(), $material->getColor(), $material->getItemName()), ArmorTrimRegistry::getInstance()->getMaterials()); - $this->session->sendDataPacket(TrimDataPacket::create($patterns, $materials)); + + $serializer = GlobalItemDataHandlers::getSerializer(); + $patternMap = ArmorTrimPatternTypeIdMap::getInstance(); + $materialMap = ArmorTrimMaterialTypeIdMap::getInstance(); + + $this->session->sendDataPacket(TrimDataPacket::create( + array_map(fn(ArmorTrimPattern $pattern) => new TrimPattern($serializer->serializeType($pattern->getItem())->getName(), $patternMap->toId($pattern)), $patternMap->getAllPatterns()), + array_map(fn(ArmorTrimMaterial $material) => new TrimMaterial($materialMap->toId($material), $material->getColor(), $serializer->serializeType($material->getItem())->getName()), $materialMap->getAllMaterials())) + ); $this->session->getLogger()->debug("Sending crafting data"); $this->session->sendDataPacket(CraftingDataCache::getInstance()->getCache($this->server->getCraftingManager())); From 348a211c9133f536086caf41c6f88be22dc06d51 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:23:01 +0300 Subject: [PATCH 13/22] Update src/inventory/transaction/SmithingTransaction.php Co-authored-by: Dylan T. --- src/inventory/transaction/SmithingTransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php index 169f49fc0ac..75e49a6d788 100644 --- a/src/inventory/transaction/SmithingTransaction.php +++ b/src/inventory/transaction/SmithingTransaction.php @@ -56,7 +56,7 @@ public function validate() : void{ throw new TransactionValidationException("Expected 1 output item, but received $outputCount"); } if(($output = $this->recipe->getResultFor($inputs)) === null){ - throw new TransactionValidationException("Could find a matching output item for the given inputs"); + throw new TransactionValidationException("Couldn't find a matching output item for the given inputs"); } if(!$output->equalsExact($outputs[0])){ throw new TransactionValidationException("Invalid output item"); From 2294a6f85288d9943e289f95bb6f56be83320b23 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:46:41 +0300 Subject: [PATCH 14/22] CS --- src/block/inventory/SmithingTableInventory.php | 2 -- src/data/bedrock/ArmorTrimMaterialTypeIdMap.php | 6 +++--- src/data/bedrock/ArmorTrimPatternTypeIdMap.php | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/block/inventory/SmithingTableInventory.php b/src/block/inventory/SmithingTableInventory.php index e9bb7f03b39..30201d02d57 100644 --- a/src/block/inventory/SmithingTableInventory.php +++ b/src/block/inventory/SmithingTableInventory.php @@ -32,9 +32,7 @@ final class SmithingTableInventory extends SimpleInventory implements BlockInven use BlockInventoryTrait; public const SLOT_INPUT = 0; - public const SLOT_ADDITION = 1; - public const SLOT_TEMPLATE = 2; public function __construct(Position $holder){ diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php index 026ca7829bd..1ca7f50ceb9 100644 --- a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php @@ -53,8 +53,8 @@ final class ArmorTrimMaterialTypeIdMap{ private array $materialToId = []; public function __construct(){ - foreach(Materials::getAll() as $case){ - $this->register(match($case) { + foreach(Materials::getAll() as $material){ + $this->register(match($material){ Materials::AMETHYST() => Ids::AMETHYST, Materials::COPPER() => Ids::COPPER, Materials::DIAMOND() => Ids::DIAMOND, @@ -66,7 +66,7 @@ public function __construct(){ Materials::QUARTZ() => Ids::QUARTZ, Materials::REDSTONE() => Ids::REDSTONE, default => throw new AssumptionFailedError("Unhandled armor trim material type") - }, $case); + }, $material); } } diff --git a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php index 467657f123d..ab389903619 100644 --- a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php @@ -53,8 +53,8 @@ final class ArmorTrimPatternTypeIdMap{ private array $patternToId = []; public function __construct(){ - foreach(Patterns::getAll() as $case){ - $this->register(match($case){ + foreach(Patterns::getAll() as $pattern){ + $this->register(match($pattern){ Patterns::COAST() => Ids::COAST, Patterns::DUNE() => Ids::DUNE, Patterns::EYE() => Ids::EYE, @@ -72,7 +72,7 @@ public function __construct(){ Patterns::WAYFINDER() => Ids::WAYFINDER, Patterns::WILD() => Ids::WILD, default => throw new AssumptionFailedError("Unhandled armor trim pattern type") - }, $case); + }, $pattern); } } From e19d0d7d8638a358390183bed98acf3cb0985d37 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:47:36 +0300 Subject: [PATCH 15/22] Make trim constants private --- src/item/Armor.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/item/Armor.php b/src/item/Armor.php index 5bf04d00d00..2e6117758c9 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -42,11 +42,9 @@ class Armor extends Durable{ public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int - public const TAG_TRIM = "Trim"; // TAG_Compound - - public const TAG_TRIM_MATERIAL = "Material"; //TAG_String - - public const TAG_TRIM_PATTERN = "Pattern"; //TAG_String + private const TAG_TRIM = "Trim"; // TAG_Compound + private const TAG_TRIM_MATERIAL = "Material"; //TAG_String + private const TAG_TRIM_PATTERN = "Pattern"; //TAG_String private ArmorTypeInfo $armorInfo; From 30a4edbd094a5921b1cccbd6e71b606182217d92 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 12:03:10 +0300 Subject: [PATCH 16/22] Don't use match --- .../bedrock/ArmorTrimMaterialTypeIdMap.php | 25 +++++-------- .../bedrock/ArmorTrimPatternTypeIdMap.php | 37 ++++++++----------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php index 1ca7f50ceb9..f29c2094263 100644 --- a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php @@ -53,21 +53,16 @@ final class ArmorTrimMaterialTypeIdMap{ private array $materialToId = []; public function __construct(){ - foreach(Materials::getAll() as $material){ - $this->register(match($material){ - Materials::AMETHYST() => Ids::AMETHYST, - Materials::COPPER() => Ids::COPPER, - Materials::DIAMOND() => Ids::DIAMOND, - Materials::EMERALD() => Ids::EMERALD, - Materials::GOLD() => Ids::GOLD, - Materials::IRON() => Ids::IRON, - Materials::LAPIS() => Ids::LAPIS, - Materials::NETHERITE() => Ids::NETHERITE, - Materials::QUARTZ() => Ids::QUARTZ, - Materials::REDSTONE() => Ids::REDSTONE, - default => throw new AssumptionFailedError("Unhandled armor trim material type") - }, $material); - } + $this->register(Ids::AMETHYST, Materials::AMETHYST()); + $this->register(Ids::COPPER, Materials::COPPER()); + $this->register(Ids::DIAMOND, Materials::DIAMOND()); + $this->register(Ids::EMERALD, Materials::EMERALD()); + $this->register(Ids::GOLD, Materials::GOLD()); + $this->register(Ids::IRON, Materials::IRON()); + $this->register(Ids::LAPIS, Materials::LAPIS()); + $this->register(Ids::NETHERITE, Materials::NETHERITE()); + $this->register(Ids::QUARTZ, Materials::QUARTZ()); + $this->register(Ids::REDSTONE, Materials::REDSTONE()); } public function register(string $stringId, ArmorTrimMaterial $material) : void{ diff --git a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php index ab389903619..5a284c2e744 100644 --- a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php @@ -53,27 +53,22 @@ final class ArmorTrimPatternTypeIdMap{ private array $patternToId = []; public function __construct(){ - foreach(Patterns::getAll() as $pattern){ - $this->register(match($pattern){ - Patterns::COAST() => Ids::COAST, - Patterns::DUNE() => Ids::DUNE, - Patterns::EYE() => Ids::EYE, - Patterns::HOST() => Ids::HOST, - Patterns::RAISER() => Ids::RAISER, - Patterns::RIB() => Ids::RIB, - Patterns::SENTRY() => Ids::SENTRY, - Patterns::SHAPER() => Ids::SHAPER, - Patterns::SILENCE() => Ids::SILENCE, - Patterns::SNOUT() => Ids::SNOUT, - Patterns::SPIRE() => Ids::SPIRE, - Patterns::TIDE() => Ids::TIDE, - Patterns::VEX() => Ids::VEX, - Patterns::WARD() => Ids::WARD, - Patterns::WAYFINDER() => Ids::WAYFINDER, - Patterns::WILD() => Ids::WILD, - default => throw new AssumptionFailedError("Unhandled armor trim pattern type") - }, $pattern); - } + $this->register(Ids::COAST, Patterns::COAST()); + $this->register(Ids::DUNE, Patterns::DUNE()); + $this->register(Ids::EYE, Patterns::EYE()); + $this->register(Ids::HOST, Patterns::HOST()); + $this->register(Ids::RAISER, Patterns::RAISER()); + $this->register(Ids::RIB, Patterns::RIB()); + $this->register(Ids::SENTRY, Patterns::SENTRY()); + $this->register(Ids::SHAPER, Patterns::SHAPER()); + $this->register(Ids::SILENCE, Patterns::SILENCE()); + $this->register(Ids::SNOUT, Patterns::SNOUT()); + $this->register(Ids::SPIRE, Patterns::SPIRE()); + $this->register(Ids::TIDE, Patterns::TIDE()); + $this->register(Ids::VEX, Patterns::VEX()); + $this->register(Ids::WARD, Patterns::WARD()); + $this->register(Ids::WAYFINDER, Patterns::WAYFINDER()); + $this->register(Ids::WILD, Patterns::WILD()); } public function register(string $stringId, ArmorTrimPattern $pattern) : void{ From d88960ec55b5498e76aa6bbf819de918bd663833 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 12:07:45 +0300 Subject: [PATCH 17/22] Use readonly where possible --- src/crafting/SmithingTrimRecipe.php | 6 +++--- src/inventory/transaction/SmithingTransaction.php | 2 +- src/item/ArmorTrim.php | 4 ++-- src/item/ArmorTrimMaterial.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/crafting/SmithingTrimRecipe.php b/src/crafting/SmithingTrimRecipe.php index 5f7555c9fb7..e3a450e987e 100644 --- a/src/crafting/SmithingTrimRecipe.php +++ b/src/crafting/SmithingTrimRecipe.php @@ -32,9 +32,9 @@ class SmithingTrimRecipe implements SmithingRecipe{ public function __construct( - private RecipeIngredient $input, - private RecipeIngredient $addition, - private RecipeIngredient $template + private readonly RecipeIngredient $input, + private readonly RecipeIngredient $addition, + private readonly RecipeIngredient $template ){} public function getInput() : RecipeIngredient{ diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php index 75e49a6d788..b43c9b54cb8 100644 --- a/src/inventory/transaction/SmithingTransaction.php +++ b/src/inventory/transaction/SmithingTransaction.php @@ -32,7 +32,7 @@ class SmithingTransaction extends InventoryTransaction{ public function __construct( Player $source, - private SmithingRecipe $recipe, + private readonly SmithingRecipe $recipe, array $actions = [] ){ parent::__construct($source, $actions); diff --git a/src/item/ArmorTrim.php b/src/item/ArmorTrim.php index 9c68326e67c..caadfd935b7 100644 --- a/src/item/ArmorTrim.php +++ b/src/item/ArmorTrim.php @@ -26,8 +26,8 @@ class ArmorTrim{ public function __construct( - private ArmorTrimMaterial $material, - private ArmorTrimPattern $pattern + private readonly ArmorTrimMaterial $material, + private readonly ArmorTrimPattern $pattern ){} public function getMaterial() : ArmorTrimMaterial{ diff --git a/src/item/ArmorTrimMaterial.php b/src/item/ArmorTrimMaterial.php index fe4abefe79b..c2bca807abe 100644 --- a/src/item/ArmorTrimMaterial.php +++ b/src/item/ArmorTrimMaterial.php @@ -32,7 +32,7 @@ class ArmorTrimMaterial{ */ public function __construct( Item $item, - private string $color + private readonly string $color ){ $this->item = clone $item; } From f479d66c98effa8c24b1f424168bf797a64a6803 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 12:15:57 +0300 Subject: [PATCH 18/22] Fix CS --- src/data/bedrock/ArmorTrimMaterialTypeIdMap.php | 1 - src/data/bedrock/ArmorTrimPatternTypeIdMap.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php index f29c2094263..a011e9be93b 100644 --- a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php @@ -27,7 +27,6 @@ use pocketmine\item\ArmorTrimMaterial; use pocketmine\item\Item; use pocketmine\item\VanillaArmorTrimMaterials as Materials; -use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; use function array_key_exists; use function array_values; diff --git a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php index 5a284c2e744..afe16f7f1e3 100644 --- a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php @@ -27,7 +27,6 @@ use pocketmine\item\ArmorTrimPattern; use pocketmine\item\Item; use pocketmine\item\VanillaArmorTrimPatterns as Patterns; -use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; use function array_key_exists; use function array_values; From 1deacda65cfe4481d77e748fb56438d0f167c088 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:33:08 +0300 Subject: [PATCH 19/22] Revert "Don't use match" This reverts commit 30a4edbd094a5921b1cccbd6e71b606182217d92. --- .../bedrock/ArmorTrimMaterialTypeIdMap.php | 25 ++++++++----- .../bedrock/ArmorTrimPatternTypeIdMap.php | 37 +++++++++++-------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php index a011e9be93b..9a17d113729 100644 --- a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php @@ -52,16 +52,21 @@ final class ArmorTrimMaterialTypeIdMap{ private array $materialToId = []; public function __construct(){ - $this->register(Ids::AMETHYST, Materials::AMETHYST()); - $this->register(Ids::COPPER, Materials::COPPER()); - $this->register(Ids::DIAMOND, Materials::DIAMOND()); - $this->register(Ids::EMERALD, Materials::EMERALD()); - $this->register(Ids::GOLD, Materials::GOLD()); - $this->register(Ids::IRON, Materials::IRON()); - $this->register(Ids::LAPIS, Materials::LAPIS()); - $this->register(Ids::NETHERITE, Materials::NETHERITE()); - $this->register(Ids::QUARTZ, Materials::QUARTZ()); - $this->register(Ids::REDSTONE, Materials::REDSTONE()); + foreach(Materials::getAll() as $material){ + $this->register(match($material){ + Materials::AMETHYST() => Ids::AMETHYST, + Materials::COPPER() => Ids::COPPER, + Materials::DIAMOND() => Ids::DIAMOND, + Materials::EMERALD() => Ids::EMERALD, + Materials::GOLD() => Ids::GOLD, + Materials::IRON() => Ids::IRON, + Materials::LAPIS() => Ids::LAPIS, + Materials::NETHERITE() => Ids::NETHERITE, + Materials::QUARTZ() => Ids::QUARTZ, + Materials::REDSTONE() => Ids::REDSTONE, + default => throw new AssumptionFailedError("Unhandled armor trim material type") + }, $material); + } } public function register(string $stringId, ArmorTrimMaterial $material) : void{ diff --git a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php index afe16f7f1e3..c527914987d 100644 --- a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php @@ -52,22 +52,27 @@ final class ArmorTrimPatternTypeIdMap{ private array $patternToId = []; public function __construct(){ - $this->register(Ids::COAST, Patterns::COAST()); - $this->register(Ids::DUNE, Patterns::DUNE()); - $this->register(Ids::EYE, Patterns::EYE()); - $this->register(Ids::HOST, Patterns::HOST()); - $this->register(Ids::RAISER, Patterns::RAISER()); - $this->register(Ids::RIB, Patterns::RIB()); - $this->register(Ids::SENTRY, Patterns::SENTRY()); - $this->register(Ids::SHAPER, Patterns::SHAPER()); - $this->register(Ids::SILENCE, Patterns::SILENCE()); - $this->register(Ids::SNOUT, Patterns::SNOUT()); - $this->register(Ids::SPIRE, Patterns::SPIRE()); - $this->register(Ids::TIDE, Patterns::TIDE()); - $this->register(Ids::VEX, Patterns::VEX()); - $this->register(Ids::WARD, Patterns::WARD()); - $this->register(Ids::WAYFINDER, Patterns::WAYFINDER()); - $this->register(Ids::WILD, Patterns::WILD()); + foreach(Patterns::getAll() as $pattern){ + $this->register(match($pattern){ + Patterns::COAST() => Ids::COAST, + Patterns::DUNE() => Ids::DUNE, + Patterns::EYE() => Ids::EYE, + Patterns::HOST() => Ids::HOST, + Patterns::RAISER() => Ids::RAISER, + Patterns::RIB() => Ids::RIB, + Patterns::SENTRY() => Ids::SENTRY, + Patterns::SHAPER() => Ids::SHAPER, + Patterns::SILENCE() => Ids::SILENCE, + Patterns::SNOUT() => Ids::SNOUT, + Patterns::SPIRE() => Ids::SPIRE, + Patterns::TIDE() => Ids::TIDE, + Patterns::VEX() => Ids::VEX, + Patterns::WARD() => Ids::WARD, + Patterns::WAYFINDER() => Ids::WAYFINDER, + Patterns::WILD() => Ids::WILD, + default => throw new AssumptionFailedError("Unhandled armor trim pattern type") + }, $pattern); + } } public function register(string $stringId, ArmorTrimPattern $pattern) : void{ From b8da3237fde290e17d5e2fe537b2db2c301db6cd Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:34:05 +0300 Subject: [PATCH 20/22] Fix tests --- src/data/bedrock/ArmorTrimMaterialTypeIdMap.php | 1 + src/data/bedrock/ArmorTrimPatternTypeIdMap.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php index 9a17d113729..1ca7f50ceb9 100644 --- a/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimMaterialTypeIdMap.php @@ -27,6 +27,7 @@ use pocketmine\item\ArmorTrimMaterial; use pocketmine\item\Item; use pocketmine\item\VanillaArmorTrimMaterials as Materials; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; use function array_key_exists; use function array_values; diff --git a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php index c527914987d..ab389903619 100644 --- a/src/data/bedrock/ArmorTrimPatternTypeIdMap.php +++ b/src/data/bedrock/ArmorTrimPatternTypeIdMap.php @@ -27,6 +27,7 @@ use pocketmine\item\ArmorTrimPattern; use pocketmine\item\Item; use pocketmine\item\VanillaArmorTrimPatterns as Patterns; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; use function array_key_exists; use function array_values; From c41cf1551776b2512f74c9864facfa6e78ed829b Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:01:05 +0300 Subject: [PATCH 21/22] Changes for review --- src/block/inventory/SmithingTableInventory.php | 13 ------------- src/crafting/CraftingManager.php | 7 +------ src/inventory/transaction/SmithingTransaction.php | 3 --- src/item/ArmorTrimMaterial.php | 5 +++++ src/item/ArmorTrimPattern.php | 5 +++++ src/network/mcpe/cache/CraftingDataCache.php | 2 +- src/network/mcpe/convert/TypeConverter.php | 4 ++++ .../mcpe/handler/ItemStackRequestExecutor.php | 3 ++- 8 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/block/inventory/SmithingTableInventory.php b/src/block/inventory/SmithingTableInventory.php index 30201d02d57..3408435694c 100644 --- a/src/block/inventory/SmithingTableInventory.php +++ b/src/block/inventory/SmithingTableInventory.php @@ -25,7 +25,6 @@ use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\TemporaryInventory; -use pocketmine\item\Item; use pocketmine\world\Position; final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ @@ -39,16 +38,4 @@ public function __construct(Position $holder){ $this->holder = $holder; parent::__construct(3); } - - public function getInput() : Item{ - return $this->getItem(self::SLOT_INPUT); - } - - public function getAddition() : Item{ - return $this->getItem(self::SLOT_ADDITION); - } - - public function getTemplate() : Item{ - return $this->getItem(self::SLOT_TEMPLATE); - } } diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index d4811212c12..bda1f35d40b 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -36,8 +36,6 @@ class CraftingManager{ use DestructorCallbackTrait; - public const SMITHING_RECIPES_OFFSET = 200000; - /** * @var ShapedRecipe[][] * @phpstan-var array> @@ -217,10 +215,7 @@ public function getSmithingRecipes() : array{ } public function getSmithingRecipeFromIndex(int $index) : ?SmithingRecipe{ - if($index < self::SMITHING_RECIPES_OFFSET || $index > (self::SMITHING_RECIPES_OFFSET + count($this->smithingRecipes))){ - return null; - } - return $this->smithingRecipes[$index - self::SMITHING_RECIPES_OFFSET]; + return $this->smithingRecipes[$index] ?? null; } public function registerShapedRecipe(ShapedRecipe $recipe) : void{ diff --git a/src/inventory/transaction/SmithingTransaction.php b/src/inventory/transaction/SmithingTransaction.php index b43c9b54cb8..77f029563ca 100644 --- a/src/inventory/transaction/SmithingTransaction.php +++ b/src/inventory/transaction/SmithingTransaction.php @@ -24,7 +24,6 @@ namespace pocketmine\inventory\transaction; use pocketmine\crafting\SmithingRecipe; -use pocketmine\item\Item; use pocketmine\player\Player; use function count; @@ -43,9 +42,7 @@ public function validate() : void{ throw new TransactionValidationException("Transaction must have at least one action to be executable"); } - /** @var Item[] $inputs */ $inputs = []; - /** @var Item[] $outputs */ $outputs = []; $this->matchItems($outputs, $inputs); diff --git a/src/item/ArmorTrimMaterial.php b/src/item/ArmorTrimMaterial.php index c2bca807abe..777f76417d4 100644 --- a/src/item/ArmorTrimMaterial.php +++ b/src/item/ArmorTrimMaterial.php @@ -23,7 +23,12 @@ namespace pocketmine\item; +use pocketmine\utils\NotCloneable; +use pocketmine\utils\NotSerializable; + class ArmorTrimMaterial{ + use NotCloneable; + use NotSerializable; private Item $item; diff --git a/src/item/ArmorTrimPattern.php b/src/item/ArmorTrimPattern.php index a08aa68b0ea..53bbc0b2712 100644 --- a/src/item/ArmorTrimPattern.php +++ b/src/item/ArmorTrimPattern.php @@ -23,7 +23,12 @@ namespace pocketmine\item; +use pocketmine\utils\NotCloneable; +use pocketmine\utils\NotSerializable; + class ArmorTrimPattern{ + use NotCloneable; + use NotSerializable; private Item $item; diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index b745debc37b..3116938c803 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -152,7 +152,7 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData } } - $index = CraftingManager::SMITHING_RECIPES_OFFSET; + $index = TypeConverter::SMITHING_RECIPES_NETWORK_OFFSET; foreach($manager->getSmithingRecipes() as $recipe){ if($recipe instanceof SmithingTransformRecipe){ $recipesWithTypeIds[] = new ProtocolSmithingTransformRecipe( diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index e886b2b8be0..4f554515824 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -56,6 +56,10 @@ class TypeConverter{ use SingletonTrait; + //TODO: Hack! In Bedrock smithing recipe indexes go together with regular recipes, + //so we make an offset to prevent conflicts. + public const SMITHING_RECIPES_NETWORK_OFFSET = 200000; + private const PM_ID_TAG = "___Id___"; private const RECIPE_INPUT_WILDCARD_META = 0x7fff; diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index e51216ec41a..7e434fbb690 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -36,6 +36,7 @@ use pocketmine\inventory\transaction\TransactionBuilder; use pocketmine\inventory\transaction\TransactionBuilderInventory; use pocketmine\item\Item; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds; use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\CraftingConsumeInputStackRequestAction; @@ -347,7 +348,7 @@ protected function processItemStackRequestAction(ItemStackRequestAction $action) } }elseif($window instanceof SmithingTableInventory){ $craftingManager = $this->player->getServer()->getCraftingManager(); - $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId()); + $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId() - TypeConverter::SMITHING_RECIPES_NETWORK_OFFSET); if($recipe !== null){ $this->specialTransaction = new SmithingTransaction($this->player, $recipe); $this->setNextCreatedItem($recipe->getResultFor($window->getContents())); From 780b37311da6406019a68eb2f4d6430be7c8fdde Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:30:14 +0300 Subject: [PATCH 22/22] Declare all offset constants together --- src/network/mcpe/InventoryManager.php | 8 +++++++- src/network/mcpe/cache/CraftingDataCache.php | 3 ++- src/network/mcpe/convert/TypeConverter.php | 4 ---- src/network/mcpe/handler/ItemStackRequestExecutor.php | 3 +-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 7df8c734be6..930ebc4a8e5 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -79,6 +79,12 @@ * @phpstan-type ContainerOpenClosure \Closure(int $id, Inventory $inventory) : (list|null) */ class InventoryManager{ + + //TODO: Hack! In Bedrock these indexes go together with regular crafting recipes, + //so we make an offsets to prevent conflicts. + public const ENCHANTING_OPTION_NETWORK_OFFSET = 100000; + public const SMITHING_RECIPE_NETWORK_OFFSET = 200000; + /** * @var InventoryManagerEntry[] spl_object_id(Inventory) => InventoryManagerEntry * @phpstan-var array @@ -117,7 +123,7 @@ class InventoryManager{ private array $enchantingTableOptions = []; //TODO: this should be based on the total number of crafting recipes - if there are ever 100k recipes, this will //conflict with regular recipes - private int $nextEnchantingTableOptionId = 100000; + private int $nextEnchantingTableOptionId = self::ENCHANTING_OPTION_NETWORK_OFFSET; public function __construct( private Player $player, diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 3116938c803..b155d957431 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -31,6 +31,7 @@ use pocketmine\crafting\SmithingTransformRecipe; use pocketmine\crafting\SmithingTrimRecipe; use pocketmine\network\mcpe\convert\TypeConverter; +use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\network\mcpe\protocol\types\recipe\CraftingRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; @@ -152,7 +153,7 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData } } - $index = TypeConverter::SMITHING_RECIPES_NETWORK_OFFSET; + $index = InventoryManager::SMITHING_RECIPE_NETWORK_OFFSET; foreach($manager->getSmithingRecipes() as $recipe){ if($recipe instanceof SmithingTransformRecipe){ $recipesWithTypeIds[] = new ProtocolSmithingTransformRecipe( diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 4f554515824..e886b2b8be0 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -56,10 +56,6 @@ class TypeConverter{ use SingletonTrait; - //TODO: Hack! In Bedrock smithing recipe indexes go together with regular recipes, - //so we make an offset to prevent conflicts. - public const SMITHING_RECIPES_NETWORK_OFFSET = 200000; - private const PM_ID_TAG = "___Id___"; private const RECIPE_INPUT_WILDCARD_META = 0x7fff; diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index 7e434fbb690..3289445fe1c 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -36,7 +36,6 @@ use pocketmine\inventory\transaction\TransactionBuilder; use pocketmine\inventory\transaction\TransactionBuilderInventory; use pocketmine\item\Item; -use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds; use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\CraftingConsumeInputStackRequestAction; @@ -348,7 +347,7 @@ protected function processItemStackRequestAction(ItemStackRequestAction $action) } }elseif($window instanceof SmithingTableInventory){ $craftingManager = $this->player->getServer()->getCraftingManager(); - $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId() - TypeConverter::SMITHING_RECIPES_NETWORK_OFFSET); + $recipe = $craftingManager->getSmithingRecipeFromIndex($action->getRecipeId() - InventoryManager::SMITHING_RECIPE_NETWORK_OFFSET); if($recipe !== null){ $this->specialTransaction = new SmithingTransaction($this->player, $recipe); $this->setNextCreatedItem($recipe->getResultFor($window->getContents()));