getServer()->getPluginManager()->registerEvents($this, $this); // Registering the default selectors self::registerSelector(new ClosestPlayer()); self::registerSelector(new AllPlayers()); self::registerSelector(new RandomPlayer()); self::registerSelector(new WorldPlayers()); self::registerSelector(new Entities()); self::registerSelector(new SelfSelector()); } /** * When a command is executed, check for selectors * * @param PlayerCommandPreProcessEvent $event * @return void */ public function onCommandPreProcess(PlayerCommandPreProcessEvent $event): void{ $m = $event->getMessage(); $this->execSelectors($m, $event->getPlayer()); $event->setCancelled(); } /** * When a command is executed, check for selectors * * @param PlayerCommandPreProcessEvent $event * @return void */ public function onServerCommand(ServerCommandEvent $event): void{ $m = $event->getCommand(); $this->execSelectors($m, $event->getSender()); $event->setCancelled(); } /** * Parses selectors and executes the commands * * @param string $m The command * @param CommandSender $sender * @return void */ public function execSelectors(string $m, CommandSender $sender): void{ preg_match_all($this->buildRegExr(), $m, $matches); $commandsToExecute = [$m]; foreach($matches[0] as $index => $match){ if(isset(self::$selectors[$matches[1][$index]])){ // Does the selector exist? // Search for the parameters echo $matches[1][$index]; $params = self::$selectors[$matches[1][$index]]->acceptsModifiers() ? $this->checkArgParams($matches, $index): []; // Applying the selector $newCommandsToExecute = []; foreach($commandsToExecute as $index => $cmd){ // Foreaching the returning commands to push them to the new commands to be executed at the next run. foreach(self::$selectors[$matches[1][$index]]->applySelector($sender, $params) as $selectorStr){ $newCommandsToExecute[] = substr_replace($cmd, " " . $selectorStr . " ", strpos($cmd, $match), strlen($match)); } if(count($newCommandsToExecute) == 0) { $sender->sendMessage("§cYour selector $match (" . self::$selectors[$matches[1][$index]]->getName() . ") did not mactch any player/entity."); return; } } $commandsToExecute = $newCommandsToExecute; } } // Then we have all the commands here and we can execute them foreach($commandsToExecute as $cmd){ $this->getServer()->dispatchCommand($sender, $cmd); } } /** * Return all the params in an array form in a match. * * @param array $match * @return void */ public function checkArgParams(array $match, int $index): array{ $params = []; if(strlen($match[2][$index]) !== 0){ // Is there any command parameter? if(strpos($match[3][$index], ",") !== -1){ // Is there multiple arguments foreach(explode(",", $match[3][$index]) as $param){ // Param here is in form argName=argproperty. // Parsing it to put it into the $params $parts = explode("=", $param); $params[$parts[0]] = $parts[1]; } } else { // There is one argument $parts = explode("=", $match[3][$index]); $params[$parts[0]] = $parts[1]; } } return $params; } /** * Build the regexr for parsing selectors in commands * $1 is the selector character(s) * $2 is "Is there any arguments to the command?" * $3 is the list of arguments * * @return string */ public function buildRegExr(): string { $regexr = "/ @("; // Space is to check that it's an argument on it's own and not a part of one // Adding the selectors $regexr .= preg_replace("/(\\$|\\(|\\)|\\^|\\[|\\])/", "\\\\$1", // Always parse input we don't trust! implode("|", array_keys(self::$selectors)) ); // Adding the arguments $regexr .= ")(\\[(((\w+)?=(.)+(,)?){1,})\\])?"; // Closing the regexr $regexr .= "( |$)/"; // Space is to check that it's an argument on it's own and not a part of one (cf twitter accounts would we used with @+some letters) return $regexr; } /** * Registers a selector * * @param Selector $sel * @return void */ public static function registerSelector(Selector $sel): void{ self::$selectors[$sel->getSelectorChar()] = $sel; } /** * Unregisters a selector * * @param string $selChar The selector character * @return void */ public static function unregisterSelector(string $selChar): void{ unset(self::$selectors[$selChar]); } /** * Returns a selector * * @param string $selChar The selector character * @return Selector */ public static function getSelector(string $selChar): Selector{ return self::$selectors[$selChar]; } }