diff --git a/src/CortexPE/Commando/BaseCommand.php b/src/CortexPE/Commando/BaseCommand.php index ad32a35..331735c 100644 --- a/src/CortexPE/Commando/BaseCommand.php +++ b/src/CortexPE/Commando/BaseCommand.php @@ -192,4 +192,4 @@ public function registerSubCommand(BaseSubCommand $subCommand): void { public function getSubCommands(): array { return $this->subCommands; } -} +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/BaseArgument.php b/src/CortexPE/Commando/args/BaseArgument.php index b5015e6..eb068d2 100644 --- a/src/CortexPE/Commando/args/BaseArgument.php +++ b/src/CortexPE/Commando/args/BaseArgument.php @@ -56,8 +56,8 @@ public function __construct(string $name, bool $optional = false) { abstract public function getNetworkType(): int; /** - * @param string $testString - * @param CommandSender $sender + * @param string $testString + * @param CommandSender $sender * * @return bool */ @@ -97,7 +97,7 @@ public function getSpanLength(): int { abstract public function getTypeName(): string; - public function getNetworkParameterData():CommandParameter { + public function getNetworkParameterData(): CommandParameter { return $this->parameterData; } } diff --git a/src/CortexPE/Commando/args/IntegerArgument.php b/src/CortexPE/Commando/args/IntegerArgument.php index 1d5085a..2a60d0c 100644 --- a/src/CortexPE/Commando/args/IntegerArgument.php +++ b/src/CortexPE/Commando/args/IntegerArgument.php @@ -44,7 +44,7 @@ public function getTypeName(): string { } public function canParse(string $testString, CommandSender $sender): bool { - return (bool)preg_match("/^-?(?:\d+)$/", $testString); + return (bool)preg_match("/^-?\d+$/", $testString); } public function parse(string $argument, CommandSender $sender) { diff --git a/src/CortexPE/Commando/args/StringEnumArgument.php b/src/CortexPE/Commando/args/StringEnumArgument.php index a7cc11d..b88dfd8 100644 --- a/src/CortexPE/Commando/args/StringEnumArgument.php +++ b/src/CortexPE/Commando/args/StringEnumArgument.php @@ -73,4 +73,4 @@ public function getEnumName(): string { public function getEnumValues(): array { return array_keys(static::VALUES); } -} +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/TargetArgument.php b/src/CortexPE/Commando/args/TargetArgument.php new file mode 100644 index 0000000..d22b551 --- /dev/null +++ b/src/CortexPE/Commando/args/TargetArgument.php @@ -0,0 +1,72 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args; + + +use CortexPE\Commando\args\selector\AllEntitiesSelector; +use CortexPE\Commando\args\selector\AllPlayersSelector; +use CortexPE\Commando\args\selector\ExecutorSelector; +use CortexPE\Commando\args\selector\PlayerSelector; +use CortexPE\Commando\args\selector\RandomPlayerSelector; +use CortexPE\Commando\args\selector\SelectorParser; +use pocketmine\command\CommandSender; +use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; + +class TargetArgument extends BaseArgument { + /** @var SelectorParser */ + private $parser; + + public function __construct(string $name, bool $optional) { + parent::__construct($name, $optional); + + $this->parser = new SelectorParser(); + $this->parser->registerSelector(new AllEntitiesSelector()); + $this->parser->registerSelector(new AllPlayersSelector()); + $this->parser->registerSelector(new ExecutorSelector()); + $this->parser->registerSelector(new PlayerSelector()); + $this->parser->registerSelector(new RandomPlayerSelector()); + } + + public function getNetworkType(): int { + return AvailableCommandsPacket::ARG_TYPE_TARGET; + } + + public function getTypeName(): string { + return "target"; + } + + public function canParse(string $testString, CommandSender $sender): bool { + return $this->parser->isValid($sender, $testString); + } + + public function parse(string $argument, CommandSender $sender) { + return $this->parser->parse($sender, $argument); + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/TextArgument.php b/src/CortexPE/Commando/args/TextArgument.php index 582d35f..e768bc1 100644 --- a/src/CortexPE/Commando/args/TextArgument.php +++ b/src/CortexPE/Commando/args/TextArgument.php @@ -30,7 +30,6 @@ namespace CortexPE\Commando\args; -use pocketmine\command\CommandSender; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; class TextArgument extends RawStringArgument { diff --git a/src/CortexPE/Commando/args/Vector3Argument.php b/src/CortexPE/Commando/args/Vector3Argument.php index 8c7205a..573c7e1 100644 --- a/src/CortexPE/Commando/args/Vector3Argument.php +++ b/src/CortexPE/Commando/args/Vector3Argument.php @@ -97,4 +97,4 @@ public function parse(string $argument, CommandSender $sender) { public function getSpanLength(): int { return 3; } -} +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/AllEntitiesSelector.php b/src/CortexPE/Commando/args/selector/AllEntitiesSelector.php new file mode 100644 index 0000000..0edcd71 --- /dev/null +++ b/src/CortexPE/Commando/args/selector/AllEntitiesSelector.php @@ -0,0 +1,49 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use pocketmine\command\CommandSender; +use function array_merge; + +class AllEntitiesSelector extends BaseSelector { + public function getChar(): string { + return "e"; + } + + public function getTargets(CommandSender $sender, array $args): array { + $entities = []; + foreach($sender->getServer()->getLevels() as $level) { + $entities = array_merge($entities, $level->getEntities()); + } + + return $entities; + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/AllPlayersSelector.php b/src/CortexPE/Commando/args/selector/AllPlayersSelector.php new file mode 100644 index 0000000..f05cb04 --- /dev/null +++ b/src/CortexPE/Commando/args/selector/AllPlayersSelector.php @@ -0,0 +1,43 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use pocketmine\command\CommandSender; + +class AllPlayersSelector extends BaseSelector { + public function getChar(): string { + return "a"; + } + + public function getTargets(CommandSender $sender, array $args): array { + return $sender->getServer()->getOnlinePlayers(); + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/BaseSelector.php b/src/CortexPE/Commando/args/selector/BaseSelector.php new file mode 100644 index 0000000..28a431b --- /dev/null +++ b/src/CortexPE/Commando/args/selector/BaseSelector.php @@ -0,0 +1,39 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use pocketmine\command\CommandSender; + +abstract class BaseSelector { + abstract public function getChar(): string; + + abstract public function getTargets(CommandSender $sender, array $args): array; +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/ExecutorSelector.php b/src/CortexPE/Commando/args/selector/ExecutorSelector.php new file mode 100644 index 0000000..0753ef8 --- /dev/null +++ b/src/CortexPE/Commando/args/selector/ExecutorSelector.php @@ -0,0 +1,45 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use pocketmine\command\CommandSender; +use pocketmine\level\Position; +use pocketmine\Player; + +class ExecutorSelector extends BaseSelector { + public function getChar(): string { + return "s"; + } + + public function getTargets(CommandSender $sender, array $args): array { + return [$sender]; + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/PlayerSelector.php b/src/CortexPE/Commando/args/selector/PlayerSelector.php new file mode 100644 index 0000000..4c63e50 --- /dev/null +++ b/src/CortexPE/Commando/args/selector/PlayerSelector.php @@ -0,0 +1,53 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use pocketmine\command\CommandSender; +use pocketmine\level\Position; +use pocketmine\Player; + +class PlayerSelector extends BaseSelector { + public function getChar(): string { + return "p"; + } + + public function getTargets(CommandSender $sender, array $args): array { + if($sender instanceof Position) { + return [ + $sender->getLevel()->getNearestEntity( + $sender, PHP_INT_MAX, Player::class, true + ) + ]; + } + + return []; + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/RandomPlayerSelector.php b/src/CortexPE/Commando/args/selector/RandomPlayerSelector.php new file mode 100644 index 0000000..dbb78b8 --- /dev/null +++ b/src/CortexPE/Commando/args/selector/RandomPlayerSelector.php @@ -0,0 +1,47 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use pocketmine\command\CommandSender; + +class RandomPlayerSelector extends BaseSelector { + public function getChar(): string { + return "r"; + } + + public function getTargets(CommandSender $sender, array $args): array { + $players = $sender->getServer()->getOnlinePlayers(); + + return [ + $players[array_rand($players)] + ]; + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/args/selector/SelectorParser.php b/src/CortexPE/Commando/args/selector/SelectorParser.php new file mode 100644 index 0000000..dc2246e --- /dev/null +++ b/src/CortexPE/Commando/args/selector/SelectorParser.php @@ -0,0 +1,73 @@ +. + * + * Written by @CortexPE + * + */ +declare(strict_types=1); + +namespace CortexPE\Commando\args\selector; + + +use function array_keys; +use function implode; +use pocketmine\command\CommandSender; +use pocketmine\command\utils\InvalidCommandSyntaxException; +use function preg_match; +use function preg_match_all; + +class SelectorParser { + /** @var BaseSelector[] */ + private $selectors = []; + /** @var string */ + private $selRegex = ""; + + public function registerSelector(BaseSelector $selector):void { + $c = strtolower($selector->getChar(){0}); + if(!isset($this->selectors[$c])){ + $this->selectors[$c] = $selector; + } + $this->selRegex = "/(?:@([" . implode("", array_keys($this->selectors)) . "])(?:\[(.+)\])?)/"; + } + + public function parse(CommandSender $sender, string $arg):array { + preg_match_all($this->selRegex, $arg, $matches); + $args = []; + if(!empty($matches[2])){ + foreach(explode(",", $matches[2][0]) as $arg){ + $arg = explode("=", trim($arg)); + if(count($arg) === 2){ + $args[$arg[0]] = $arg[1]; + }else{ + throw new InvalidCommandSyntaxException("Invalid selector syntax"); + } + } + } + return $this->selectors[$matches[1][0]]->getTargets($sender, $args); + } + + public function isValid(CommandSender $sender, string $arg) :bool{ + return (bool)preg_match($this->selRegex, $arg); + } +} \ No newline at end of file diff --git a/src/CortexPE/Commando/traits/ArgumentableTrait.php b/src/CortexPE/Commando/traits/ArgumentableTrait.php index 58270e8..3c1dc27 100644 --- a/src/CortexPE/Commando/traits/ArgumentableTrait.php +++ b/src/CortexPE/Commando/traits/ArgumentableTrait.php @@ -33,11 +33,11 @@ use CortexPE\Commando\args\BaseArgument; use CortexPE\Commando\args\TextArgument; use CortexPE\Commando\BaseCommand; -use function array_slice; use CortexPE\Commando\exception\ArgumentOrderException; +use pocketmine\command\CommandSender; +use function array_slice; use function count; use function implode; -use pocketmine\command\CommandSender; use function usort; trait ArgumentableTrait { @@ -181,4 +181,4 @@ public function hasArguments(): bool { public function getArgumentList(): array { return $this->argumentList; } -} +} \ No newline at end of file