65    public static function create(array $recipesWithTypeIds, array $potionTypeRecipes, array $potionContainerRecipes, array $materialReducerRecipes, 
bool $cleanRecipes) : self{
 
   67        $result->recipesWithTypeIds = $recipesWithTypeIds;
 
   68        $result->potionTypeRecipes = $potionTypeRecipes;
 
   69        $result->potionContainerRecipes = $potionContainerRecipes;
 
   70        $result->materialReducerRecipes = $materialReducerRecipes;
 
   71        $result->cleanRecipes = $cleanRecipes;
 
 
   76        $recipeCount = VarInt::readUnsignedInt($in);
 
   77        $previousType = 
"none";
 
   78        for($i = 0; $i < $recipeCount; ++$i){
 
   79            $recipeType = VarInt::readSignedInt($in);
 
   81            $this->recipesWithTypeIds[] = match($recipeType){
 
   82                self::ENTRY_SHAPELESS, self::ENTRY_USER_DATA_SHAPELESS, self::ENTRY_SHAPELESS_CHEMISTRY => ShapelessRecipe::decode($recipeType, $in),
 
   83                self::ENTRY_SHAPED, self::ENTRY_SHAPED_CHEMISTRY => ShapedRecipe::decode($recipeType, $in),
 
   84                self::ENTRY_FURNACE, self::ENTRY_FURNACE_DATA => FurnaceRecipe::decode($recipeType, $in),
 
   85                self::ENTRY_MULTI => MultiRecipe::decode($recipeType, $in),
 
   86                self::ENTRY_SMITHING_TRANSFORM => SmithingTransformRecipe::decode($recipeType, $in),
 
   87                self::ENTRY_SMITHING_TRIM => SmithingTrimRecipe::decode($recipeType, $in),
 
   88                default => 
throw new PacketDecodeException(
"Unhandled recipe type $recipeType (previous was $previousType)"),
 
   90            $previousType = $recipeType;
 
   92        for($i = 0, $count = VarInt::readUnsignedInt($in); $i < $count; ++$i){
 
   93            $inputId = VarInt::readSignedInt($in);
 
   94            $inputMeta = VarInt::readSignedInt($in);
 
   95            $ingredientId = VarInt::readSignedInt($in);
 
   96            $ingredientMeta = VarInt::readSignedInt($in);
 
   97            $outputId = VarInt::readSignedInt($in);
 
   98            $outputMeta = VarInt::readSignedInt($in);
 
   99            $this->potionTypeRecipes[] = 
new PotionTypeRecipe($inputId, $inputMeta, $ingredientId, $ingredientMeta, $outputId, $outputMeta);
 
  101        for($i = 0, $count = VarInt::readUnsignedInt($in); $i < $count; ++$i){
 
  102            $input = VarInt::readSignedInt($in);
 
  103            $ingredient = VarInt::readSignedInt($in);
 
  104            $output = VarInt::readSignedInt($in);
 
  105            $this->potionContainerRecipes[] = 
new PotionContainerChangeRecipe($input, $ingredient, $output);
 
  107        for($i = 0, $count = VarInt::readUnsignedInt($in); $i < $count; ++$i){
 
  108            $inputIdAndData = VarInt::readSignedInt($in);
 
  109            [$inputId, $inputMeta] = [$inputIdAndData >> 16, $inputIdAndData & 0x7fff];
 
  111            for($j = 0, $outputCount = VarInt::readUnsignedInt($in); $j < $outputCount; ++$j){
 
  112                $outputItemId = VarInt::readSignedInt($in);
 
  113                $outputItemCount = VarInt::readSignedInt($in);
 
  114                $outputs[] = 
new MaterialReducerRecipeOutput($outputItemId, $outputItemCount);
 
  116            $this->materialReducerRecipes[] = 
new MaterialReducerRecipe($inputId, $inputMeta, $outputs);
 
  118        $this->cleanRecipes = CommonTypes::getBool($in);
 
 
  122        VarInt::writeUnsignedInt($out, count($this->recipesWithTypeIds));
 
  123        foreach($this->recipesWithTypeIds as $d){
 
  124            VarInt::writeSignedInt($out, $d->getTypeId());
 
  127        VarInt::writeUnsignedInt($out, count($this->potionTypeRecipes));
 
  128        foreach($this->potionTypeRecipes as $recipe){
 
  129            VarInt::writeSignedInt($out, $recipe->getInputItemId());
 
  130            VarInt::writeSignedInt($out, $recipe->getInputItemMeta());
 
  131            VarInt::writeSignedInt($out, $recipe->getIngredientItemId());
 
  132            VarInt::writeSignedInt($out, $recipe->getIngredientItemMeta());
 
  133            VarInt::writeSignedInt($out, $recipe->getOutputItemId());
 
  134            VarInt::writeSignedInt($out, $recipe->getOutputItemMeta());
 
  136        VarInt::writeUnsignedInt($out, count($this->potionContainerRecipes));
 
  137        foreach($this->potionContainerRecipes as $recipe){
 
  138            VarInt::writeSignedInt($out, $recipe->getInputItemId());
 
  139            VarInt::writeSignedInt($out, $recipe->getIngredientItemId());
 
  140            VarInt::writeSignedInt($out, $recipe->getOutputItemId());
 
  142        VarInt::writeUnsignedInt($out, count($this->materialReducerRecipes));
 
  143        foreach($this->materialReducerRecipes as $recipe){
 
  144            VarInt::writeSignedInt($out, ($recipe->getInputItemId() << 16) | $recipe->getInputItemMeta());
 
  145            VarInt::writeUnsignedInt($out, count($recipe->getOutputs()));
 
  146            foreach($recipe->getOutputs() as $output){
 
  147                VarInt::writeSignedInt($out, $output->getItemId());
 
  148                VarInt::writeSignedInt($out, $output->getCount());
 
  151        CommonTypes::putBool($out, $this->cleanRecipes);