PocketMine-MP 5.23.3 git-976fc63567edab7a6fb6aeae739f43cf9fe57de4
Loading...
Searching...
No Matches
SimpleCommandMap.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\command;
25
75use function array_shift;
76use function array_values;
77use function count;
78use function implode;
79use function str_contains;
80use function strcasecmp;
81use function strtolower;
82use function trim;
83
85
90 protected array $knownCommands = [];
91
92 public function __construct(private Server $server){
93 $this->setDefaultCommands();
94 }
95
96 private function setDefaultCommands() : void{
97 $this->registerAll("pocketmine", [
98 new BanCommand(),
99 new BanIpCommand(),
100 new BanListCommand(),
101 new ClearCommand(),
103 new DeopCommand(),
104 new DifficultyCommand(),
105 new DumpMemoryCommand(),
106 new EffectCommand(),
107 new EnchantCommand(),
108 new GamemodeCommand(),
110 new GiveCommand(),
111 new HelpCommand(),
112 new KickCommand(),
113 new KillCommand(),
114 new ListCommand(),
115 new MeCommand(),
116 new OpCommand(),
117 new PardonCommand(),
118 new PardonIpCommand(),
119 new ParticleCommand(),
120 new PluginsCommand(),
121 new SaveCommand(),
122 new SaveOffCommand(),
123 new SaveOnCommand(),
124 new SayCommand(),
125 new SeedCommand(),
127 new SpawnpointCommand(),
128 new StatusCommand(),
129 new StopCommand(),
130 new TeleportCommand(),
131 new TellCommand(),
132 new TimeCommand(),
133 new TimingsCommand(),
134 new TitleCommand(),
136 new VersionCommand(),
137 new WhitelistCommand(),
138 new XpCommand(),
139 ]);
140 }
141
142 public function registerAll(string $fallbackPrefix, array $commands) : void{
143 foreach($commands as $command){
144 $this->register($fallbackPrefix, $command);
145 }
146 }
147
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");
151 }
152
153 if($label === null){
154 $label = $command->getLabel();
155 }
156 $label = trim($label);
157 $fallbackPrefix = strtolower(trim($fallbackPrefix));
158
159 $registered = $this->registerAlias($command, false, $fallbackPrefix, $label);
160
161 $aliases = $command->getAliases();
162 foreach($aliases as $index => $alias){
163 if(!$this->registerAlias($command, true, $fallbackPrefix, $alias)){
164 unset($aliases[$index]);
165 }
166 }
167 $command->setAliases(array_values($aliases));
168
169 if(!$registered){
170 $command->setLabel($fallbackPrefix . ":" . $label);
171 }
172
173 $command->register($this);
174
175 return $registered;
176 }
177
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]);
182 }
183 }
184
185 $command->unregister($this);
186
187 return true;
188 }
189
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])){
193 return false;
194 }
195
196 if(isset($this->knownCommands[$label]) && $this->knownCommands[$label]->getLabel() === $label){
197 return false;
198 }
199
200 if(!$isAlias){
201 $command->setLabel($label);
202 }
203
204 $this->knownCommands[$label] = $command;
205
206 return true;
207 }
208
209 public function dispatch(CommandSender $sender, string $commandLine) : bool{
210 $args = CommandStringHelper::parseQuoteAware($commandLine);
211
212 $sentCommandLabel = array_shift($args);
213 if($sentCommandLabel !== null && ($target = $this->getCommand($sentCommandLabel)) !== null){
214 $timings = Timings::getCommandDispatchTimings($target->getLabel());
215 $timings->startTiming();
216
217 try{
218 if($target->testPermission($sender)){
219 $target->execute($sender, $sentCommandLabel, $args);
220 }
221 }catch(InvalidCommandSyntaxException $e){
222 $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
223 }finally{
224 $timings->stopTiming();
225 }
226 return true;
227 }
228
229 $sender->sendMessage(KnownTranslationFactory::pocketmine_command_notFound($sentCommandLabel ?? "", "/help")->prefix(TextFormat::RED));
230 return false;
231 }
232
233 public function clearCommands() : void{
234 foreach($this->knownCommands as $command){
235 $command->unregister($this);
236 }
237 $this->knownCommands = [];
238 $this->setDefaultCommands();
239 }
240
241 public function getCommand(string $name) : ?Command{
242 return $this->knownCommands[$name] ?? null;
243 }
244
249 public function getCommands() : array{
250 return $this->knownCommands;
251 }
252
253 public function registerServerAliases() : void{
254 $values = $this->server->getCommandAliases();
255
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)));
259 continue;
260 }
261
262 $targets = [];
263 $bad = [];
264 $recursive = [];
265
266 foreach($commandStrings as $commandString){
267 $args = CommandStringHelper::parseQuoteAware($commandString);
268 $commandName = array_shift($args) ?? "";
269 $command = $this->getCommand($commandName);
270
271 if($command === null){
272 $bad[] = $commandString;
273 }elseif(strcasecmp($commandName, $alias) === 0){
274 $recursive[] = $commandString;
275 }else{
276 $targets[] = $commandString;
277 }
278 }
279
280 if(count($recursive) > 0){
281 $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_recursive($alias, implode(", ", $recursive))));
282 continue;
283 }
284
285 if(count($bad) > 0){
286 $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_notFound($alias, implode(", ", $bad))));
287 continue;
288 }
289
290 //These registered commands have absolute priority
291 $lowerAlias = strtolower($alias);
292 if(count($targets) > 0){
293 $this->knownCommands[$lowerAlias] = new FormattedCommandAlias($lowerAlias, $targets);
294 }else{
295 unset($this->knownCommands[$lowerAlias]);
296 }
297
298 }
299 }
300}
registerAll(string $fallbackPrefix, array $commands)