90 protected array $knownCommands = [];
92 public function __construct(
private Server $server){
93 $this->setDefaultCommands();
96 private function setDefaultCommands() :
void{
142 public function registerAll(
string $fallbackPrefix, array $commands) : void{
143 foreach($commands as $command){
144 $this->
register($fallbackPrefix, $command);
148 public function register(
string $fallbackPrefix,
Command $command, ?
string $label =
null) :
bool{
149 if(count($command->getPermissions()) === 0){
150 throw new \InvalidArgumentException(
"Commands must have a permission set");
154 $label = $command->getLabel();
156 $label = trim($label);
157 $fallbackPrefix = strtolower(trim($fallbackPrefix));
159 $registered = $this->registerAlias($command,
false, $fallbackPrefix, $label);
161 $aliases = $command->getAliases();
162 foreach($aliases as $index => $alias){
163 if(!$this->registerAlias($command,
true, $fallbackPrefix, $alias)){
164 unset($aliases[$index]);
167 $command->setAliases(array_values($aliases));
170 $command->setLabel($fallbackPrefix .
":" . $label);
173 $command->register($this);
178 public function unregister(Command $command) : bool{
179 foreach(Utils::promoteKeys($this->knownCommands) as $lbl => $cmd){
180 if($cmd === $command){
181 unset($this->knownCommands[$lbl]);
185 $command->unregister($this);
190 private function registerAlias(Command $command,
bool $isAlias,
string $fallbackPrefix,
string $label) : bool{
191 $this->knownCommands[$fallbackPrefix .
":" . $label] = $command;
192 if(($command instanceof VanillaCommand || $isAlias) && isset($this->knownCommands[$label])){
196 if(isset($this->knownCommands[$label]) && $this->knownCommands[$label]->getLabel() === $label){
201 $command->setLabel($label);
204 $this->knownCommands[$label] = $command;
209 public function dispatch(CommandSender $sender,
string $commandLine) : bool{
210 $args = CommandStringHelper::parseQuoteAware($commandLine);
212 $sentCommandLabel = array_shift($args);
213 if($sentCommandLabel !==
null && ($target = $this->getCommand($sentCommandLabel)) !==
null){
214 $timings = Timings::getCommandDispatchTimings($target->getLabel());
215 $timings->startTiming();
218 if($target->testPermission($sender)){
219 $target->execute($sender, $sentCommandLabel, $args);
221 }
catch(InvalidCommandSyntaxException $e){
222 $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
224 $timings->stopTiming();
229 $sender->sendMessage(KnownTranslationFactory::pocketmine_command_notFound($sentCommandLabel ??
"",
"/help")->prefix(TextFormat::RED));
233 public function clearCommands() : void{
234 foreach($this->knownCommands as $command){
235 $command->unregister($this);
237 $this->knownCommands = [];
238 $this->setDefaultCommands();
241 public function getCommand(
string $name) : ?Command{
242 return $this->knownCommands[$name] ?? null;
250 return $this->knownCommands;
253 public function registerServerAliases() : void{
254 $values = $this->
server->getCommandAliases();
256 foreach(Utils::stringifyKeys($values) as $alias => $commandStrings){
257 if(str_contains($alias,
":")){
258 $this->
server->getLogger()->warning($this->
server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_illegal($alias)));
266 foreach($commandStrings as $commandString){
267 $args = CommandStringHelper::parseQuoteAware($commandString);
268 $commandName = array_shift($args) ??
"";
269 $command = $this->getCommand($commandName);
271 if($command ===
null){
272 $bad[] = $commandString;
273 }elseif(strcasecmp($commandName, $alias) === 0){
274 $recursive[] = $commandString;
276 $targets[] = $commandString;
280 if(count($recursive) > 0){
281 $this->
server->getLogger()->warning($this->
server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_recursive($alias, implode(
", ", $recursive))));
286 $this->
server->getLogger()->warning($this->
server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_notFound($alias, implode(
", ", $bad))));
291 $lowerAlias = strtolower($alias);
292 if(count($targets) > 0){
293 $this->knownCommands[$lowerAlias] =
new FormattedCommandAlias($lowerAlias, $targets);
295 unset($this->knownCommands[$lowerAlias]);