PocketMine-MP 5.15.1 git-08c6e63aac45a450fe3b437616ee8aa2500e04e2
CraftingDataPacket.php
1<?php
2
3/*
4 * This file is part of BedrockProtocol.
5 * Copyright (C) 2014-2022 PocketMine Team <https://github.com/pmmp/BedrockProtocol>
6 *
7 * BedrockProtocol is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
13declare(strict_types=1);
14
15namespace pocketmine\network\mcpe\protocol;
16
29use function count;
30
32 public const NETWORK_ID = ProtocolInfo::CRAFTING_DATA_PACKET;
33
34 public const ENTRY_SHAPELESS = 0;
35 public const ENTRY_SHAPED = 1;
36 public const ENTRY_FURNACE = 2;
37 public const ENTRY_FURNACE_DATA = 3;
38 public const ENTRY_MULTI = 4;
39 public const ENTRY_SHULKER_BOX = 5;
40 public const ENTRY_SHAPELESS_CHEMISTRY = 6;
41 public const ENTRY_SHAPED_CHEMISTRY = 7;
42 public const ENTRY_SMITHING_TRANSFORM = 8;
43 public const ENTRY_SMITHING_TRIM = 9;
44
46 public array $recipesWithTypeIds = [];
48 public array $potionTypeRecipes = [];
50 public array $potionContainerRecipes = [];
52 public array $materialReducerRecipes = [];
53 public bool $cleanRecipes = false;
54
62 public static function create(array $recipesWithTypeIds, array $potionTypeRecipes, array $potionContainerRecipes, array $materialReducerRecipes, bool $cleanRecipes) : self{
63 $result = new self;
64 $result->recipesWithTypeIds = $recipesWithTypeIds;
65 $result->potionTypeRecipes = $potionTypeRecipes;
66 $result->potionContainerRecipes = $potionContainerRecipes;
67 $result->materialReducerRecipes = $materialReducerRecipes;
68 $result->cleanRecipes = $cleanRecipes;
69 return $result;
70 }
71
72 protected function decodePayload(PacketSerializer $in) : void{
73 $recipeCount = $in->getUnsignedVarInt();
74 for($i = 0; $i < $recipeCount; ++$i){
75 $recipeType = $in->getVarInt();
76
77 $this->recipesWithTypeIds[] = match($recipeType){
78 self::ENTRY_SHAPELESS, self::ENTRY_SHULKER_BOX, self::ENTRY_SHAPELESS_CHEMISTRY => ShapelessRecipe::decode($recipeType, $in),
79 self::ENTRY_SHAPED, self::ENTRY_SHAPED_CHEMISTRY => ShapedRecipe::decode($recipeType, $in),
80 self::ENTRY_FURNACE, self::ENTRY_FURNACE_DATA => FurnaceRecipe::decode($recipeType, $in),
81 self::ENTRY_MULTI => MultiRecipe::decode($recipeType, $in),
82 self::ENTRY_SMITHING_TRANSFORM => SmithingTransformRecipe::decode($recipeType, $in),
83 self::ENTRY_SMITHING_TRIM => SmithingTrimRecipe::decode($recipeType, $in),
84 default => throw new PacketDecodeException("Unhandled recipe type $recipeType!"),
85 };
86 }
87 for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){
88 $inputId = $in->getVarInt();
89 $inputMeta = $in->getVarInt();
90 $ingredientId = $in->getVarInt();
91 $ingredientMeta = $in->getVarInt();
92 $outputId = $in->getVarInt();
93 $outputMeta = $in->getVarInt();
94 $this->potionTypeRecipes[] = new PotionTypeRecipe($inputId, $inputMeta, $ingredientId, $ingredientMeta, $outputId, $outputMeta);
95 }
96 for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){
97 $input = $in->getVarInt();
98 $ingredient = $in->getVarInt();
99 $output = $in->getVarInt();
100 $this->potionContainerRecipes[] = new PotionContainerChangeRecipe($input, $ingredient, $output);
101 }
102 for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){
103 $inputIdAndData = $in->getVarInt();
104 [$inputId, $inputMeta] = [$inputIdAndData >> 16, $inputIdAndData & 0x7fff];
105 $outputs = [];
106 for($j = 0, $outputCount = $in->getUnsignedVarInt(); $j < $outputCount; ++$j){
107 $outputItemId = $in->getVarInt();
108 $outputItemCount = $in->getVarInt();
109 $outputs[] = new MaterialReducerRecipeOutput($outputItemId, $outputItemCount);
110 }
111 $this->materialReducerRecipes[] = new MaterialReducerRecipe($inputId, $inputMeta, $outputs);
112 }
113 $this->cleanRecipes = $in->getBool();
114 }
115
116 protected function encodePayload(PacketSerializer $out) : void{
117 $out->putUnsignedVarInt(count($this->recipesWithTypeIds));
118 foreach($this->recipesWithTypeIds as $d){
119 $out->putVarInt($d->getTypeId());
120 $d->encode($out);
121 }
122 $out->putUnsignedVarInt(count($this->potionTypeRecipes));
123 foreach($this->potionTypeRecipes as $recipe){
124 $out->putVarInt($recipe->getInputItemId());
125 $out->putVarInt($recipe->getInputItemMeta());
126 $out->putVarInt($recipe->getIngredientItemId());
127 $out->putVarInt($recipe->getIngredientItemMeta());
128 $out->putVarInt($recipe->getOutputItemId());
129 $out->putVarInt($recipe->getOutputItemMeta());
130 }
131 $out->putUnsignedVarInt(count($this->potionContainerRecipes));
132 foreach($this->potionContainerRecipes as $recipe){
133 $out->putVarInt($recipe->getInputItemId());
134 $out->putVarInt($recipe->getIngredientItemId());
135 $out->putVarInt($recipe->getOutputItemId());
136 }
137 $out->putUnsignedVarInt(count($this->materialReducerRecipes));
138 foreach($this->materialReducerRecipes as $recipe){
139 $out->putVarInt(($recipe->getInputItemId() << 16) | $recipe->getInputItemMeta());
140 $out->putUnsignedVarInt(count($recipe->getOutputs()));
141 foreach($recipe->getOutputs() as $output){
142 $out->putVarInt($output->getItemId());
143 $out->putVarInt($output->getCount());
144 }
145 }
146 $out->putBool($this->cleanRecipes);
147 }
148
149 public function handle(PacketHandlerInterface $handler) : bool{
150 return $handler->handleCraftingData($this);
151 }
152}
static create(array $recipesWithTypeIds, array $potionTypeRecipes, array $potionContainerRecipes, array $materialReducerRecipes, bool $cleanRecipes)