/** Gets a RCon instance for the specified server. * This function returns an instance of RCon (the same as the innerAPI one) for the specified server in argument. * * \param $server The wanted server's name. * * \return If the server exists, it returns an instance of RCon class. Else, it returns FALSE. */ public static function getServerRCon($server) { $self = self::getInstance(); if (!isset($self->_leelabot->servers[$server])) { return FALSE; } $rcon = new RCon(); $rcon->setServer($self->_leelabot->servers[$server]); return $rcon; }
function minecraftCommand($service_id, $command) { if (strlen($command > 1000)) { return "Error: the entered command is too long!"; } //get the configuration $configuration = minecraftGetConfiguration($service_id, false); if (isset($configuration['rcon.password']) && isset($configuration['rcon.port'])) { $hostname = "localhost"; if (!empty($configuration['server-ip'])) { $hostname = $configuration['server-ip']; } require_once includePath() . "/rcon.php"; try { $rcon = new RCon($hostname, $configuration['rcon.port'], $configuration['rcon.password']); } catch (Exception $e) { return "Error: {$e}"; } if ($rcon->Auth()) { //allow execution of multiple commands if (is_array($command)) { foreach ($command as $str) { $rcon->rconCommand($command); } } else { $rcon->rconCommand($command); } return true; } else { return "Error: failed to connect and authenticate with Minecraft server (is it online?)."; } } else { return "Error: could not find rcon port and password to use."; } }
/** Executes a step of parsing. * This function executes a step of parsing, i.e. reads the log, parses the read lines and calls the adapted events. * * \return TRUE if all gone correctly, FALSE otherwise. */ public function step() { $time = time(); if (!$this->_enabled || $this->_hold && $time == $this->_lastRead) { return TRUE; } if ($this->_shutdownTime !== FALSE && $time - 10 > $this->_shutdownTime && !empty($this->players)) { //Properly sending the events, allowing plugins to perform their actions. foreach ($this->players as $id => $player) { $this->_leelabot->plugins->callServerEvent('ClientDisconnect', $id); } $this->players = array(); Leelabot::message('Deleted player data for server $0', array($this->_name), E_DEBUG); } $this->_lastRead = time(); $data = $this->readLog(); if ($data) { $data = explode("\n", trim($data, "\n")); foreach ($data as $line) { //Parsing line for event and arguments $line = substr($line, 7); //Remove the time (todo : see if elapsed time for the map is useful (more than when we count it ourselves)) Leelabot::printText('[' . $this->_name . '] ' . $line); $line = explode(':', $line, 2); if (isset($line[1])) { $line[1] = trim($line[1]); } switch ($line[0]) { //A client connects case 'ClientConnect': $id = intval($line[1]); $this->players[$id] = new Storage(array('id' => $id, 'begin' => FALSE, 'team' => Server::TEAM_SPEC, 'level' => $this->_defaultLevel, 'time' => time(), 'uuid' => Leelabot::UUID())); Leelabot::message('Client connected: $0', array($id), E_DEBUG); $this->_leelabot->plugins->callServerEvent('ClientConnect', $id); break; //A client has disconnected //A client has disconnected case 'ClientDisconnect': $id = intval($line[1]); $this->_leelabot->plugins->callServerEvent('ClientDisconnect', $id); Leelabot::message('Client disconnected: $0', array($id), E_DEBUG); unset($this->players[$id]); break; //The client has re-sent his personal info (like credit name, weapons, weapmodes, card number) //The client has re-sent his personal info (like credit name, weapons, weapmodes, card number) case 'ClientUserinfo': list($id, $infostr) = explode(' ', $line[1], 2); $userinfo = Server::parseInfo($infostr); Leelabot::message('Client send user info: $0', array($id), E_DEBUG); Leelabot::message(' Name: $0', array($userinfo['name']), E_DEBUG); //Basically it's a copypasta of the code user above for initial data storage if (isset($userinfo['characterfile'])) { $playerData['isBot'] = TRUE; Leelabot::message(' Is a bot.', array(), E_DEBUG); } else { $playerData['isBot'] = FALSE; $address = explode(':', $userinfo['ip']); $playerData['addr'] = $address[0]; $playerData['port'] = $address[1]; $playerData['guid'] = $userinfo['cl_guid']; Leelabot::message(' GUID: $0', array($playerData['guid'])); Leelabot::message(' IP: $0', array($playerData['addr'])); } $playerData['name'] = preg_replace('#^[0-9]#', '', $userinfo['name']); $playerData['id'] = $id; $this->_leelabot->plugins->callServerEvent('ClientUserinfo', array($id, $userinfo)); $this->players[$id]->merge($playerData); //Binding IP pointer if (!isset($this->players[$id]->ip)) { $this->players[$id]->ip =& $this->players[$id]->addr; } if (!isset($this->players[$id]->other)) { $this->players[$id]->other = $userinfo; } else { $this->players[$id]->other = array_merge($this->players[$id]->other, $userinfo); } break; //Change in client userinfo, useful for gathering teams //Change in client userinfo, useful for gathering teams case 'ClientUserinfoChanged': list($id, $infostr) = explode(' ', $line[1], 2); $userinfo = Server::parseInfo($infostr); Leelabot::message('Client has send changed user info: $0', array($id), E_DEBUG); Leelabot::message(' Name: $0', array($userinfo['n']), E_DEBUG); Leelabot::message(' Team: $0', array(Server::getTeamName($userinfo['t'])), E_DEBUG); $this->_leelabot->plugins->callServerEvent('ClientUserinfoChanged', array($id, $userinfo)); $this->players[$id]->team = $userinfo['t']; $this->players[$id]->other['cg_rgb'] = $userinfo['a0'] . ' ' . $userinfo['a1'] . ' ' . $userinfo['a2']; $this->players[$id]->name = preg_replace('#^[0-9]#', '', $userinfo['n']); break; //Player start to play //Player start to play case 'ClientBegin': $id = intval($line[1]); Leelabot::message('Client has begun: $0', array($id), E_DEBUG); $this->_leelabot->plugins->callServerEvent('ClientBegin', $id); $this->players[$id]->begin = TRUE; break; //New round, map info is re-sended //New round, map info is re-sended case 'InitRound': $serverinfo = Server::parseInfo($line[1]); Leelabot::message('New round started', array(), E_DEBUG); $this->_leelabot->plugins->callServerEvent('InitRound', $serverinfo); //New map, with new info //New map, with new info case 'InitGame': if ($line[0] == 'InitGame') { $this->enable(); $this->_shutdownTime = FALSE; $serverinfo = Server::parseInfo($line[1]); Leelabot::message('New map started: $0', array($serverinfo['mapname']), E_DEBUG); $this->_leelabot->plugins->callServerEvent('InitGame', $serverinfo); $this->scores = array(1 => 0, 2 => 0); } if (!empty($this->serverInfo)) { $this->serverInfo = array_merge($this->serverInfo, $serverinfo); } else { $this->serverInfo = $serverinfo; } break; //The game has ended. Usually, next to that line are written the scores, but we just don't care about them //The game has ended. Usually, next to that line are written the scores, but we just don't care about them case 'Exit': Leelabot::message('Map ended', array(), E_DEBUG); $this->_leelabot->plugins->callServerEvent('Exit', $line[1]); break; //Survivor round has ended, with the winner //Survivor round has ended, with the winner case 'SurvivorWinner': Leelabot::message('Round ended, winner: $0', array($line[1]), E_DEBUG); $winner = Server::getTeamNumber($line[1]); $this->_leelabot->plugins->callServerEvent('SurvivorWinner', $winner); if ($winner) { $this->scores[$winner]++; } break; //The server goes down (it occurs also with a map change) //The server goes down (it occurs also with a map change) case 'ShutdownGame': Leelabot::message('The server is going down', array(), E_DEBUG); $this->_leelabot->plugins->callServerEvent('ShutdownGame'); //Starting the countdown before resetting user data. $this->_shutdownTime = time(); if ($this->_autoHold) { $this->hold(); } break; //One player kills another, probably the most common action that will occur ? //One player kills another, probably the most common action that will occur ? case 'Kill': $kill = explode(':', $line[1]); $kill = explode(' ', $kill[0]); $this->_leelabot->plugins->callServerEvent('Kill', $kill); break; //One player hit another, OMG FLOOD OF GAME LOG ! //One player hit another, OMG FLOOD OF GAME LOG ! case 'Hit': $hit = explode(':', $line[1]); $hit = explode(' ', $hit[0]); $this->_leelabot->plugins->callServerEvent('Hit', $hit); break; //Item of player, example : take kevlar. (utility ?) //Item of player, example : take kevlar. (utility ?) case 'Item': $item = explode(' ', $line[1]); $this->_leelabot->plugins->callServerEvent('Item', $item); break; //Actions on flag //Actions on flag case 'Flag': $flag = explode(':', $line[1]); $flag = explode(' ', $flag[0]); $this->_leelabot->plugins->callServerEvent('Flag', $flag); //If flag has been captured if ($flag[1] == 2) { $player = Server::getPlayer($flag[0]); $this->scores[$player->team]++; } break; //Player message //Player message case 'say': case 'sayteam': $message = explode(' ', $line[1], 2); $id = intval($message[0]); $contents = explode(':', $message[1], 2); $contents = substr($contents[1], 1); Leelabot::message('$0 sended a message: $1', array($this->players[$id]->name, $contents), E_DEBUG); $this->_leelabot->plugins->callServerEvent('Say', array($id, $contents)); //We check if it's a command if ($contents[0] == '!' && !$this->_hold) { $contents = substr($contents, 1); $args = explode(' ', $contents); $command = array_shift($args); Leelabot::message('Command catched: !$0', array($command), E_DEBUG); $this->_leelabot->plugins->callCommand($command, $id, $args); } break; // Hotpotato // Hotpotato case 'Hotpotato': $this->_leelabot->plugins->callServerEvent('Hotpotato'); break; // Player call a vote // Player call a vote case 'Callvote': $param = explode('-', $line[1]); array_walk($param, 'trim'); $id = intval($param[0]); $votestring = explode('"', $param[1]); $votestring = $vote[1]; $this->_leelabot->plugins->callServerEvent('Callvote', array($id, $votestring)); break; // Player vote (1=yes, 2=no) // Player vote (1=yes, 2=no) case 'Vote': $param = explode('-', $line[1]); array_walk($param, 'trim'); array_walk($param, 'intval'); $id = $param[0]; $vote = $param[1]; $this->_leelabot->plugins->callServerEvent('Vote', array($id, $vote)); break; // Player call a radio alert // Player call a radio alert case 'Radio': // idnum - msg_group - msg_id - "player_location" - "message" $param = explode('-', $line[1]); array_walk($param, 'trim'); $id = intval($param[0]); $groupid = intval($param[1]); $msgid = intval($param[2]); $location = explode('"', $param[3]); $location = $location[1]; $message = explode('"', $param[4]); $message = $message[1]; $this->_leelabot->plugins->callServerEvent('Radio', array($id, $groupid, $msgid, $location, $message)); break; case 'AccountKick': $param = explode('-', $line[1]); array_walk($param, 'trim'); $id = intval($param[0]); $reason = explode(':', $param[1]); $reason = trim($reason[1]); $this->_leelabot->plugins->callServerEvent('AccountKick', $id, $reason); break; case 'AccountBan': // idnum - login - [nb_days]d - [nb_hours]h - [nb_mins]m $param = explode('-', $line[1]); array_walk($param, 'trim'); $id = intval($param[0]); $login = $param[1]; $days = intval(str_replace('d', '', $param[2])); $hours = intval(str_replace('h', '', $param[3])); $mins = intval(str_replace('m', '', $param[4])); $this->_leelabot->plugins->callServerEvent('AccountBan', array($id, $login, $days, $hours, $mins)); break; case 'AccountValidated': // idnum - login - rcon_level - "notoriety" $param = explode(' - ', $line[1]); array_walk($param, 'trim'); $id = intval($param[0]); $login = $param[1]; $rconlevel = intval($param[2]); $notoriety = explode('"', $param[3]); $notoriety = $notoriety[1]; //Setting player properties $this->players[$id]->authLogin = $login; $this->players[$id]->authRConLevel = $rconlevel; $this->players[$id]->authNotoriety = $notoriety; $this->_leelabot->plugins->callServerEvent('AccountValidated', array($id, $login, $rconlevel, $notoriety)); break; case 'AccountRejected': // idnum - login - "reason" $param = explode('-', $line[1]); array_walk($param, 'trim'); $id = intval($param[0]); $login = $param[1]; $reason = explode('"', $param[2]); $reason = $reason[1]; $this->_leelabot->plugins->callServerEvent('AccountRejected', array($id, $login, $reason)); break; } } } //Then, we read incoming data on the RCon socket if any, only every 100ms if (microtime(TRUE) - $this->_rconLastRead >= 0.1) { $data = RCon::getReply(); //If there is incoming data which is not an error if (!empty($data)) { Leelabot::message('RCon data received: $0', array($data), E_DEBUG); if (strpos($data, 'rconPassword') === 0) { $split = explode(' ', $data, 2); $this->_rconpassword = $split[1]; $this->_rcon->setRConPassword($this->_rconpassword); Leelabot::message('Updated RCon password.', array(), E_NOTICE); $this->_rcon->resend(); //FIXME: See if we have to re-send the command or not (re-sending can cause random behavior) } } elseif ($data === FALSE && $this->_rcon->lastError() != Quake3RCon::E_NOREPLY) { Leelabot::message('RCon error: $0', array($this->_rcon->getErrorString($this->_rcon->lastError())), E_WARNING); if ($this->_rcon->lastError() == Quake3RCon::E_BADRCON && !empty($this->_recoverPassword)) { $this->_rcon->send('rconRecovery ' . $this->_recoverPassword); } } } //Before returning, we execute all routines $this->_leelabot->plugins->callAllRoutines(); return TRUE; }
/** Grants the given player rights. * This function grants the player his rights when he's authed. No auth verification is performed with this function. * * \param $player The player to grant rights to. * \param $authname The name on which the player is authed. * \param $auth The auth parameters (IP, aliases, GUIDs). * * \return Nothing. */ private function grantAuthedRights($player, $authname, $auth) { //Auth the player $player->auth = $authname; $player->level = $auth['level']; //Save player data modification $modif = TRUE; if (!in_array($player->name, $auth['aliases'])) { $this->rights[$authname]['aliases'][] = $player->name; } elseif ($player->ip != $auth['IP']) { $this->rights[$authname]['IP'] = $player->ip; } elseif (!isset($auth['GUID'][Server::getName()]) || $auth['GUID'][Server::getName()] != $player->guid) { $this->rights[$authname]['GUID'][Server::getName()] = $player->guid; } else { $modif = FALSE; } //If a modification occured, we save the authlist if ($modif) { $this->saveRights($this->config['RightsFile']); } if ($this->config['Verbose']) { RCon::tell($player->id, 'You\'re now authed as $0', $authname); } $this->_plugins->callEventSimple('rights', 'authenticate', $player->id, $authname); }
/** Loads all the server instances and defining their parameters * This function loads all the server instances found in Leelabot::$config, and initializes them with their config. * * \returns TRUE if instances loaded successfully, FALSE otherwise. */ public function loadServerInstances() { if (!isset($this->config['Server'])) { Leelabot::message('No server defined in configuration.', array(), E_ERROR); exit; } $this->servers = array(); Leelabot::message('Loading server instances.'); //Checking default configuration if (isset($this->config['Server']['default'])) { $defaultConfig = $this->config['Server']['default']; unset($this->config['Server']['default']); } foreach ($this->config['Server'] as $name => $instance) { if (isset($instance['name'])) { $name = $instance['name']; } Leelabot::message('Loading server "$0".', array($name)); $this->servers[$name] = new ServerInstance($this); //Using config name if not specified $this->servers[$name]->setName($name); //Loading config if (!$this->servers[$name]->loadConfig($instance)) { Leelabot::message('Can\'t load config for server "$0".', array($name), E_WARNING); unset($this->servers[$name]); continue; } //Setting servers for static inner API RCon::setServer($this->servers[$name]); Server::setServer($this->servers[$name]); //Connecting to server if (!$this->servers[$name]->connect()) { Leelabot::message('Can\'t connect to server "$0".', array($name), E_WARNING); unset($this->servers[$name]); } } }
/** Bans the last disconnected player. * This function bans the last player who disconnected from the server, with all the options available from the regular ban command. * * \param $id The player ID who used the command. * \param $command The command parameters. * * \return Nothing. * * \see PluginBans::CommandBan() */ public function CommandBanExit($id, $command) { //If no player has disconnected yet, we send an error if (!isset($this->_lastDisconnect[Server::getName()])) { RCon::tell($id, 'No player found.'); return FALSE; } $ban = $this->_parseBanCommand($command); //Adding the entry to the banlist $player = $this->_lastDisconnect[Server::getName()]; $banID = Leelabot::UUID(); if ($ban['duration'] !== 'forever' && $ban['duration'] < $this->_durations['day'] && count($ban['servers']) == 1) { $this->_banlist[$banID] = array('GUIDList' => array($player->guid), 'IP' => FALSE, 'Aliases' => array($player->name), 'Duration' => $ban['duration'], 'Begin' => time(), 'Realm' => join(',', $ban['servers']), 'Identifier' => $player->name, 'Description' => ''); } elseif ($ban['duration'] !== 'forever' && $ban['duration'] < $this->_durations['month']) { $this->_banlist[$banID] = array('GUIDList' => array($player->guid), 'IP' => $player->ip, 'Aliases' => array($player->name), 'Duration' => $ban['duration'], 'Begin' => time(), 'Realm' => join(',', $ban['servers']), 'Identifier' => $player->name, 'Description' => ''); if (!isset($this->_bannedIP[$player->ip])) { $this->_bannedIP[$player->ip] = array(); } $this->_bannedIP[$player->ip][] = $banID; } else { $ip = explode('.', $player->ip); array_pop($ip); $ip = join('.', $ip) . '.0'; $this->_banlist[$banID] = array('GUIDList' => array($player->guid), 'IP' => $ip, 'Aliases' => array($player->name), 'Duration' => $ban['duration'], 'Begin' => time(), 'Realm' => join(',', $ban['servers']), 'Identifier' => $player->name, 'Description' => ''); if (!isset($this->_bannedIP[$player->ip])) { $this->_bannedIP[$player->ip] = array(); } $this->_bannedIP[$ip] = $banID; } //Adding the alias for better GUID search if (!isset($this->_bannedGUID[$player->guid])) { $this->_bannedGUID[$player->guid] = array(); } $this->_bannedGUID[$player->guid] = $banID; //We save the banlist and we kick the player $this->saveBanlist(); $this->_plugins->callEventSimple('bans', 'exitnew', $banID); //Calling the event }
public function RightsAuthenticate($id, $auth) { RCon::tell($id, 'Hey, you\'re authed as $0 !', $auth); }
<?php include_once "../includes/config.php"; if (isset($_SESSION['connected']) && $_SESSION['connected']) { //find some status information $rcon = new RCon($_SESSION['server'], $_SESSION['port'], $_SESSION['password']); $rcon->authenticate(); $status = $rcon->getStatus(); echo '({ "ip": ' . json_encode($status['ip']) . ', "hostname": ' . json_encode($status['hostname']) . ', "map": ' . json_encode($status['map']) . ', "difficulty": ' . json_encode($status['difficulty']) . ', "players": ' . json_encode($status['players']) . ', "playercount": ' . $status['playercount'] . ', "playerinfo": ['; for ($i = 1; $i <= $status['playercount']; $i++) { echo '{ "id": ' . json_encode($status['player' . $i]['id']) . ', "name": ' . json_encode($status['player' . $i]["name"]) . ', "uniqid": ' . json_encode($status['player' . $i]["uniqid"]) . ', "connected": ' . json_encode($status['player' . $i]["connected"]) . ', "ping": ' . json_encode($status['player' . $i]["ping"]) . ', "state": ' . json_encode($status['player' . $i]["state"]) . ', "ip": ' . json_encode($status['player' . $i]["ip"]) . ' }'; if ($i != $status['playercount']) { echo ','; } } echo '
/** Balances teams. * This function balances the teams according to the arrival order of the players. * It is executed on new connections and when a player changes team (if AutoTeams is enabled in plugin config). * It only changes the team of new players. * * \param $player The player who send the command. (if is player has send command) * * \return Nothing. */ private function _balance($player = null) { //We take player count of each team. $teams_count = Server::getTeamCount(); if ($teams_count[Server::TEAM_RED] >= $teams_count[Server::TEAM_BLUE] + 2) { $too_many_player = floor(($teams_count[Server::TEAM_RED] - $teams_count[Server::TEAM_BLUE]) / 2); $src_team = Server::TEAM_RED; $dest_team = strtolower(Server::getTeamName(Server::TEAM_BLUE)); $balance = TRUE; } elseif ($teams_count[Server::TEAM_BLUE] >= $teams_count[Server::TEAM_RED] + 2) { $too_many_player = floor(($teams_count[Server::TEAM_BLUE] - $teams_count[Server::TEAM_RED]) / 2); $src_team = Server::TEAM_BLUE; $dest_team = strtolower(Server::getTeamName(Server::TEAM_RED)); $balance = TRUE; } else { $balance = FALSE; } //If the teams are unbalanced if ($balance) { //We get player list $players = Server::getPlayerList($src_team); $last = array(); foreach ($players as $player) { $last[$player->time] = $player->id; } //We sorts the players of the team by time spent on the server. krsort($last); //Processing loop while ($too_many_player > 0) { //We take the last player of the team $player = array_shift($last); //Add on ClientUserinfoChanged ignore list $this->_ClientUserinfoChangedIgnore[$player] = $player; //We change the team of the player RCon::forceteam($player, $dest_team); --$too_many_player; } RCon::say('Teams are now balanced'); } else { if ($player !== NULL) { RCon::tell($player, 'Teams are already balanced'); } } }
while (list($var, $param) = @each($post_var_list)) { if (!empty($_POST[$param]) && strlen(trim($_POST[$param]))) { $_POST[$param] = strtolower(trim(addslashes($_POST[$param]))); } else { setError("Connection failed: invalid server/authentication details", "../index.php"); } } //find port from server post var $serverInfo = explode(":", $_POST['server']); if (count($serverInfo) < 2 || strlen($serverInfo[1]) < 1) { $port = 27015; } else { $port = $serverInfo[1]; } $_SESSION['server'] = $_POST['server']; $_SESSION['port'] = $port; $_SESSION['password'] = $_POST['password']; $rcon = new RCon($_SESSION['server'], $_SESSION['port'], $_SESSION['password']); //abort if no connection is possible at all if ($rcon->_Sock == null) { setError("Connection failed: cannot connect to that server", "../index.php"); } //attempt to authenticate with rcon password $success = $rcon->authenticate(); if ($success) { $_SESSION['connected'] = true; setNotice("Connection made", "../index.php"); } else { $_SESSION['connected'] = false; setError("Connection failed: incorrect rcon password", "../index.php"); }
public function WSMethodKickAll($server, $mask) { if (!ServerList::serverEnabled($server)) { throw new WebserviceException('Server not found'); } $server = ServerList::getServer($server); $target = $server->searchPlayer($mask); if ($target === FALSE) { throw new WebserviceException('No player found.'); } elseif (is_array($target)) { $players = array(); $kick = true; foreach ($target as $p) { $kick = $kick && RCon::kick($p); } return $target; } else { return Leelabot::boolString(RCon::kick($target)); } }
<?php include_once "../includes/config.php"; if (!isset($_SESSION['server'])) { echo '({"command": "", "responseSuccess": "failure", "responseText": "Connection with server lost. Please log in again"})'; exit; } //concat full command $command = ""; if (!empty($_POST['prefix']) && strlen(trim($_POST['prefix']))) { $command .= trim(addslashes($_POST['prefix'])) . " "; } //check for content, trim and crap-strip fields if (!empty($_POST['command']) && strlen(trim($_POST['command']))) { $command .= trim(addslashes($_POST['command'])); } else { echo '({"command": "", "responseSuccess": "failure", "responseText": "Invalid command"})'; } $rcon = new RCon($_SESSION['server'], $_SESSION['port'], $_SESSION['password']); $success = $rcon->authenticate(); echo '({"command": ' . json_encode($command) . ', "responseSuccess": "","responseText": ' . json_encode($rcon->rconCommand($command)) . '})';
public function CommandClearWarns($id, $cmd) { if (!empty($cmd[0])) { $target = Server::searchPlayer($cmd[0]); if (!$target) { RCon::tell($id, "No player found."); } elseif (is_array($target)) { $players = array(); foreach ($target as $p) { $players[] = Server::getPlayer($p)->name; } RCon::tell($id, 'Multiple players found : $0', array(join(', ', $players))); } else { $this->_clearWarn($target); Rcon::tell($id, 'The warnings of $player are cleared.', array('player' => Server::getPlayer($target)->name)); Rcon::tell($target, "Your warnings are cleared."); } } else { Rcon::tell($id, 'Missing parameters.'); } }
/** Calls a client command. * This function executes all the callback methods bound to the given event. * * \param $event The server event called. * \param $player The ID of the player who sent the event * \param $params Parameter(s) to send to the callbacks. * * \return TRUE if callbacks executed correctly, FALSE otherwise. */ public function callCommand($event, $player, $params) { $player = Server::getPlayer($player); $ret = $this->callEvent('command', $event, $player->level, Server::getPlugins(), $player->id, $params); if ($ret !== TRUE) { switch ($ret) { case Events::ACCESS_DENIED: RCon::tell($player->id, "You're not allowed to use this command."); break; case Events::UNDEFINED_EVENT: case Events::UNDEFINED_LISTENER: RCon::tell($player->id, "Command not found."); break; } } }