PocketMine-MP 5.36.1 git-eaa7c4834c8fe2f379d24e7f0ee6cc63cfb18ccc
Loading...
Searching...
No Matches
AvailableCommandsPacketAssembler.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\serializer;
16
30use function array_push;
31use function count;
32use function spl_object_id;
33
38
43 private array $enumIndexes = [];
48 private array $enumValueIndexes = [];
53 private array $softEnumIndexes = [];
58 private array $postfixIndexes = [];
63 private array $chainedSubCommandDataIndexes = [];
68 private array $chainedSubCommandValueIndexes = [];
69
74 private array $enumValues = [];
79 private array $chainedSubCommandValues = [];
84 private array $postfixes = [];
89 private array $enums = [];
94 private array $chainedSubCommandData = [];
99 private array $commandData = [];
104 private array $softEnums = [];
109 private array $enumConstraints = [];
110
120 public static function assemble(
121 array $commandData,
122 array $hardcodedEnums,
123 array $hardcodedSoftEnums
125 $builder = new self();
126 foreach($commandData as $data){
127 $builder->addCommandData($data);
128 }
129 foreach($hardcodedEnums as $enum){
130 $builder->addHardEnum($enum);
131 }
132 foreach($hardcodedSoftEnums as $enum){
133 $builder->addSoftEnum($enum);
134 }
135
137 enumValues: $builder->enumValues,
138 chainedSubCommandValues: $builder->chainedSubCommandValues,
139 postfixes: $builder->postfixes,
140 enums: $builder->enums,
141 chainedSubCommandData: $builder->chainedSubCommandData,
142 commandData: $builder->commandData,
143 softEnums: $builder->softEnums,
144 enumConstraints: $builder->enumConstraints
145 );
146 }
147
148 private function addEnumValue(string $str) : int{
149 if(!isset($this->enumValueIndexes[$str])){
150 $this->enumValueIndexes[$str] = count($this->enumValues);
151 $this->enumValues[] = $str;
152 }
153 return $this->enumValueIndexes[$str];
154 }
155
156 private function addHardEnum(CommandHardEnum $enum) : int{
157 $key = spl_object_id($enum);
158 if(!isset($this->enumIndexes[$key])){
159 $valueIndexes = [];
160
161 $enumIndex = $this->enumIndexes[$key] = count($this->enums);
162
163 $constraints = [];
164 foreach($enum->getValues() as $value){
165 if($value instanceof ConstrainedEnumValue){
166 $valueIndex = $this->addEnumValue($value->getValue());
167 $constraints[] = new CommandEnumConstraintRawData($valueIndex, $enumIndex, $value->getConstraints());
168 }else{
169 $valueIndex = $this->addEnumValue($value);
170 }
171 $valueIndexes[] = $valueIndex;
172 }
173 if(count($this->enums) !== $enumIndex){
174 throw new \LogicException("Didn't expect enum list to be modified while compiling values");
175 }
176 $this->enums[] = new CommandEnumRawData($enum->getName(), $valueIndexes);
177 array_push($this->enumConstraints, ...$constraints);
178 }
179
180 return $this->enumIndexes[$key];
181 }
182
183 private function addSoftEnum(CommandSoftEnum $enum) : int{
184 $key = spl_object_id($enum);
185
186 if(!isset($this->softEnumIndexes[$key])){
187 $this->softEnumIndexes[$key] = count($this->softEnums);
188 $this->softEnums[] = $enum;
189 }
190
191 return $this->softEnumIndexes[$key];
192 }
193
194 private function addPostfix(string $postfix) : int{
195 if(!isset($this->postfixIndexes[$postfix])){
196 $this->postfixIndexes[$postfix] = count($this->postfixes);
197 $this->postfixes[] = $postfix;
198 }
199 return $this->postfixIndexes[$postfix];
200 }
201
202 private function addChainedSubCommandValueName(string $valueName) : int{
203 if(!isset($this->chainedSubCommandValueIndexes[$valueName])){
204 $this->chainedSubCommandValueIndexes[$valueName] = count($this->chainedSubCommandValues);
205 $this->chainedSubCommandValues[] = $valueName;
206 }
207 return $this->chainedSubCommandValueIndexes[$valueName];
208 }
209
210 private function addChainedSubCommandData(ChainedSubCommandData $data) : int{
211 $key = spl_object_id($data);
212
213 if(!isset($this->chainedSubCommandDataIndexes[$key])){
214 $rawValueData = [];
215 foreach($data->getValues() as $value){
216 $valueNameIndex = $this->addChainedSubCommandValueName($value->getName());
217 $rawValueData[] = new ChainedSubCommandValueRawData($valueNameIndex, $value->getType());
218 }
219
220 $this->chainedSubCommandDataIndexes[$key] = count($this->chainedSubCommandData);
221 $this->chainedSubCommandData[] = new ChainedSubCommandRawData($data->getName(), $rawValueData);
222 }
223
224 return $this->chainedSubCommandDataIndexes[$key];
225 }
226
227 private function addCommandData(CommandData $commandData) : void{
228 $aliasesIndex = $commandData->aliases !== null ? $this->addHardEnum($commandData->aliases) : -1;
229
230 $chainedSubCommandDataIndexes = [];
231 foreach($commandData->getChainedSubCommandData() as $chainedSubCommandData){
232 $chainedSubCommandDataIndexes[] = $this->addChainedSubCommandData($chainedSubCommandData);
233 }
234
235 $rawOverloadData = [];
236 foreach($commandData->getOverloads() as $overload){
237 $rawParameterData = [];
238
239 foreach($overload->getParameters() as $parameter){
240 if($parameter->enum !== null){
241 if($parameter->enum instanceof CommandSoftEnum){
242 $enumIndex = $this->addSoftEnum($parameter->enum);
243 $typeInfo = AvailableCommandsPacket::ARG_FLAG_SOFT_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID | $enumIndex;
244 }else{
245 $enumIndex = $this->addHardEnum($parameter->enum);
246 $typeInfo = AvailableCommandsPacket::ARG_FLAG_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID | $enumIndex;
247 }
248 }elseif($parameter->postfix !== null){
249 $postfixIndex = $this->addPostfix($parameter->postfix);
250 $typeInfo = AvailableCommandsPacket::ARG_FLAG_POSTFIX | $postfixIndex;
251 }else{
252 //mask this to prevent unwanted flags sneaking in
253 $typeInfo = AvailableCommandsPacket::ARG_FLAG_VALID | ($parameter->paramType & AvailableCommandsPacket::ARG_FLAG_VALID - 1);
254 }
255
256 $rawParameterData[] = new CommandParameterRawData($parameter->paramName, $typeInfo, $parameter->isOptional, $parameter->flags);
257 }
258
259 $rawOverloadData[] = new CommandOverloadRawData($overload->isChaining(), $rawParameterData);
260 }
261
262 $this->commandData[] = new CommandRawData(
263 name: $commandData->getName(),
264 description: $commandData->getDescription(),
265 flags: $commandData->getFlags(),
266 permission: $commandData->getPermission(),
267 aliasEnumIndex: $aliasesIndex,
268 chainedSubCommandDataIndexes: $chainedSubCommandDataIndexes,
269 overloads: $rawOverloadData
270 );
271 }
272}
static create(array $enumValues, array $chainedSubCommandValues, array $postfixes, array $enums, array $chainedSubCommandData, array $commandData, array $softEnums, array $enumConstraints,)
static assemble(array $commandData, array $hardcodedEnums, array $hardcodedSoftEnums)