PocketMine-MP 5.35.1 git-e32e836dad793a3a3c8ddd8927c00e112b1e576a
Loading...
Searching...
No Matches
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
17use pmmp\encoding\ByteBufferReader;
18use pmmp\encoding\ByteBufferWriter;
19use pmmp\encoding\VarInt;
32use function count;
33
35 public const NETWORK_ID = ProtocolInfo::CRAFTING_DATA_PACKET;
36
37 public const ENTRY_SHAPELESS = 0;
38 public const ENTRY_SHAPED = 1;
39 public const ENTRY_FURNACE = 2;
40 public const ENTRY_FURNACE_DATA = 3;
41 public const ENTRY_MULTI = 4;
42 public const ENTRY_USER_DATA_SHAPELESS = 5;
43 public const ENTRY_SHAPELESS_CHEMISTRY = 6;
44 public const ENTRY_SHAPED_CHEMISTRY = 7;
45 public const ENTRY_SMITHING_TRANSFORM = 8;
46 public const ENTRY_SMITHING_TRIM = 9;
47
49 public array $recipesWithTypeIds = [];
51 public array $potionTypeRecipes = [];
53 public array $potionContainerRecipes = [];
55 public array $materialReducerRecipes = [];
56 public bool $cleanRecipes = false;
57
65 public static function create(array $recipesWithTypeIds, array $potionTypeRecipes, array $potionContainerRecipes, array $materialReducerRecipes, bool $cleanRecipes) : self{
66 $result = new self;
67 $result->recipesWithTypeIds = $recipesWithTypeIds;
68 $result->potionTypeRecipes = $potionTypeRecipes;
69 $result->potionContainerRecipes = $potionContainerRecipes;
70 $result->materialReducerRecipes = $materialReducerRecipes;
71 $result->cleanRecipes = $cleanRecipes;
72 return $result;
73 }
74
75 protected function decodePayload(ByteBufferReader $in) : void{
76 $recipeCount = VarInt::readUnsignedInt($in);
77 $previousType = "none";
78 for($i = 0; $i < $recipeCount; ++$i){
79 $recipeType = VarInt::readSignedInt($in);
80
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)"),
89 };
90 $previousType = $recipeType;
91 }
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);
100 }
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);
106 }
107 for($i = 0, $count = VarInt::readUnsignedInt($in); $i < $count; ++$i){
108 $inputIdAndData = VarInt::readSignedInt($in);
109 [$inputId, $inputMeta] = [$inputIdAndData >> 16, $inputIdAndData & 0x7fff];
110 $outputs = [];
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);
115 }
116 $this->materialReducerRecipes[] = new MaterialReducerRecipe($inputId, $inputMeta, $outputs);
117 }
118 $this->cleanRecipes = CommonTypes::getBool($in);
119 }
120
121 protected function encodePayload(ByteBufferWriter $out) : void{
122 VarInt::writeUnsignedInt($out, count($this->recipesWithTypeIds));
123 foreach($this->recipesWithTypeIds as $d){
124 VarInt::writeSignedInt($out, $d->getTypeId());
125 $d->encode($out);
126 }
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());
135 }
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());
141 }
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());
149 }
150 }
151 CommonTypes::putBool($out, $this->cleanRecipes);
152 }
153
154 public function handle(PacketHandlerInterface $handler) : bool{
155 return $handler->handleCraftingData($this);
156 }
157}
static create(array $recipesWithTypeIds, array $potionTypeRecipes, array $potionContainerRecipes, array $materialReducerRecipes, bool $cleanRecipes)