/** Gives a player a specific level. * This function gives to the specified player a specific level. It can only be used by an admin with super cow powers. * The first command parameter is the search mask for the wanted player, and the second one is the player's new right level. * * \param $id The client ID. * \param $command The command parameters. * * \return Nothing. */ public function CommandGiveRights($id, $command) { if (!isset($command[1])) { RCon::tell($id, 'Not enough parameters'); return TRUE; } $player = Server::searchPlayer($command[0]); if (!$player) { RCon::tell($id, 'Unknown player'); return TRUE; } elseif (is_array($player)) { RCon::tell($id, 'Multiple players found : $0', array(join(', ', Server::getPlayerNames($player)))); return TRUE; } $level = intval($command[1]); $player = Server::getPlayer($player); //If the player is not authed, we create an entry for him in the rights file if (!$player->auth) { $name = preg_replace("#[^a-zA-Z0-9]#", '', $player->name); $this->rights[$name] = array(); $this->rights[$name]['aliases'] = array($player->name); $this->rights[$name]['GUID'] = array(Server::getName() => $player->guid); $this->rights[$name]['IP'] = $player->ip; $this->rights[$name]['level'] = $level; if (!empty($player->authLogin)) { $this->rights[$name]['auth'] = $player->authLogin; } $this->saveRights($this->config['RightsFile']); $player->auth = $name; $this->_plugins->callEventSimple('rights', 'authenticate', $player->id, $name); if ($this->config['Verbose']) { RCon::tell($id, 'Created auth user $0', $name); RCon::tell($player->id, 'You\'re now authed as $0', $name); } } else { $this->rights[$player->auth] = $level; } $this->saveRights($this->config['RightsFile']); $player->level = $level; RCon::tell($id, 'User $0 level set to $1', array($player->auth, $player->level)); return TRUE; }
/** 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; }
/** Bans a player. * This command bans the player passed in first parameter, and parses the other parameters to add modifiers to the ban : * \li from <server(s)> : Specifies the range of the ban : servers can be defined one by one by separating them with a space, * and the special keyword in PluginBans::GLOBALBAN can be used to make the ban bot-wide (if a server is named like that, you can use * server:<PluginBans::GLOBALBAN> to bypass that). * \li for <duration> : Specifies the duration of the ban. You can use numbers and modifiers to specify the duration (valid modifiers : * second(s), minute(s), hour(s), day(s), week(s), month(s), year(s)). * \li forever : Makes the ban permanent. Can't be used with the "for" parameter. * * If none parameter specified, the defaults from config file are taken. If a default duration or range is not specified in the config, * the default applied are 1 day and the current server from which the command has been emitted. * * Examples : * \li Simple ban : !ban linkboss * \li Ban from only one server : !ban linkboss from myserver * \li Ban from multiple servers, including one server name <PluginBans::GLOBALBAN> : !ban linkboss from myserver, otherserver, * server:<PluginBans::GLOBALBAN> * \li Ban from all servers : !ban linkboss from <PluginBans::GLOBALBAN> * \li Ban for 1 month and a half : !ban linkboss for 1 month 2 weeks * \li Ban from one server during 1 day : !ban linkboss from myserver for 1 day * \li Permanent ban : !ban linkboss forever * * \note * When you specify the ban duration, if you use 2 numbers one after another, their values will be additionned. For example : * \li !ban linkboss for 1 2 months * Will result of a 3 months ban. Also, if you use a non-recognized keyword between durations, only the last before a recognized keyword * will be used. For example : * \li !ban linkboss for 1 and 2 months * Will result of a 2 months ban. If you do not use any modifier at all, the default modifier applied is the day. * * \param $id The player ID who used the command. * \param $command The command parameters. * * \return Nothing. */ public function CommandBan($id, $command) { $ban = $this->_parseBanCommand($command); $error = FALSE; if ($ban['duration'] != 'forever' && $ban['duration'] <= 0) { $error = 'Cannot ban for this duration.'; } if (empty($ban['servers'])) { $error = 'Cannot ban from zero servers.'; } if (empty($ban['banned'])) { $error = 'There is nobody to ban.'; } if ($error !== FALSE) { RCon::tell($id, $error); return; } $banned = array(); foreach ($ban['banned'] as $player) { $pid = Server::searchPlayer($player); if (is_array($pid)) { RCon::tell('Multiple results found for search $0 : $1', array($player, Server::getPlayerNames($pid))); continue; } elseif ($pid === FALSE) { RCon::tell('No player found for search $0.', array($player)); continue; } //Adding the entry to the banlist $player = Server::getPlayer($pid); $banID = Leelabot::UUID(); if ($ban['duration'] !== 'forever' && $ban['duration'] < $this->_durations['day'] && count($ban['servers']) == 1) { //GUID save $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(); //We call the event $this->_plugins->callEventSimple('bans', 'new', $player->id, $banID); if (in_array(Server::getName(), $ban['servers']) || $ban['servers'][0] == self::GLOBALBAN) { //NEED TEST, CALL APERTURE SCIENCE RCon::kick($player->id); } } }
public function WSMethodPlayer($id) { if (!is_null($player = Server::getPlayer($id))) { return array('success' => true, 'data' => $player->toArray()); } return array('success' => false, 'error' => 'Unknown player ID'); }
public function IrcStats($pseudo, $channel, $cmd, $message) { $server = LeelaBotIrc::nameOfServer($cmd[2], FALSE); $actual = Server::getName(); if (isset($cmd[1])) { if ($server !== false) { Server::setServer($this->_main->servers[$server]); $target = Server::searchPlayer(trim($cmd[1])); if (!$target) { LeelaBotIrc::sendMessage("Unknown player"); } elseif (is_array($target)) { $players = array(); foreach ($target as $p) { $players[] = Server::getPlayer($p)->name; } LeelaBotIrc::sendMessage("Multiple players found : " . join(', ', $players)); } else { $buffer = array(); $_stats = Server::get('stats'); $_awards = Server::get('awards'); $player = Server::getPlayer($target); if ($_stats[$player->id]['deaths'] != 0) { $ratio = $_stats[$player->id]['kills'] / $_stats[$player->id]['deaths']; } else { $ratio = $_stats[$player->id]['kills']; } if (in_array('hits', $this->config['ShowStats'])) { //Gestion des hits en fonction de la configuration du plugin de stats $hits = "Hits : " . $_stats[$player->id]['hits'] . " - "; } if (Server::getServer()->serverInfo['g_gametype'] == 7) { //Gestion des caps uniquement en CTF $caps = " - Caps : " . $_stats[$player->id]['caps']; } LeelaBotIrc::sendMessage("Stats de " . $player->name . " : " . $hits . "Kills : " . $_stats[$player->id]['kills'] . " - Deaths : " . $_stats[$player->id]['deaths'] . " - Ratio : " . $ratio . $caps . " - Streaks : " . $_stats[$player->id]['streaks']); } Server::setServer($this->_main->servers[$actual]); } } else { LeelaBotIrc::sendMessage("Player name missing"); } }
/** !help command. Get help and list of commands. * This function is the command !help. It get list of commands and help. * * \param $player The player who send the command. * \param $command The command's parameters. * * \return Nothing. */ public function CommandHelp($player, $command) { $list = Plugins::getCommandList(); $player = Server::getPlayer($player); if (empty($command[0])) { foreach ($list as $cmd => $level) { unset($list[$cmd]); if ($level <= $player->level) { $list['!' . $cmd] = $level; } } $list = implode(', ', array_keys($list)); Rcon::tell($player->id, 'List of commands : $list', array('list' => $list)); } else { $cmdHelp = strtolower(str_replace('!', '', $command[0])); //need into translate files for example : #id help_nextmap #to Return next map. Rcon::tell($player->id, '$cmd: ' . Locales::translate('help_' . $cmdHelp), array('cmd' => '!' . $cmdHelp), FALSE); } }
public function StatsShowAwards($awards) { $buffer = array(); $serverinfo = Server::getServer()->serverInfo; foreach ($awards as $award => $infos) { if ($infos !== NULL) { $player = Server::getPlayer($infos[0]); if ($serverinfo['g_gametype'] != '0') { if ($player->team == 1) { $color = "04"; } elseif ($player->team == 2) { $color = "02"; } elseif ($player->team == 3) { $color = "14"; } } else { $color = "08"; } $buffer[] = $infos[1] . " " . $award . ' : ' . $color . $player->name . ""; } else { $buffer[] = $award . ' : nobody'; } } LeelaBotIrc::privmsg($this->config['MainChannel'], "Awards on " . LeelaBotIrc::rmColor($serverinfo['sv_hostname']) . " : " . join(' | ', $buffer)); }
public function IrcMute($pseudo, $channel, $cmd, $message) { $server = LeelaBotIrc::nameOfServer($cmd[1]); if ($server !== false) { $rcon = ServerList::getServerRCon($server); $serverlist = ServerList::getList(); if (in_array($cmd[1], $serverlist)) { $mute = $cmd[2]; } else { $mute = $cmd[1]; } if (isset($mute)) { $target = Server::searchPlayer(trim($mute)); if (!$target) { LeelaBotIrc::sendMessage("Unknown player"); } elseif (is_array($target)) { $players = array(); foreach ($target as $p) { $players[] = Server::getPlayer($p)->name; } LeelaBotIrc::sendMessage("Multiple players found : " . join(', ', $players)); } else { $rcon->mute($target); LeelaBotIrc::sendMessage(Server::getPlayer($target)->name . " was muted."); } } else { LeelaBotIrc::sendMessage("Player name missing"); } } }
public function SrvEventHit($player, $shooter, $partOfBody, $weapon) { $shooter = Server::getPlayer($shooter); $player = Server::getPlayer($player); $gametype = Server::getServer()->serverInfo['g_gametype']; if ($shooter->team == $player->team and !in_array($gametype, array(Server::GAME_FFA, Server::GAME_LMS))) { $warns = $this->_addWarn($shooter->id, $player->id); Rcon::say('Warning : $shooter has team hit $player ! (He has $warns warnings)', array('shooter' => $shooter->name, 'player' => $player->name, 'warns' => $warns)); Rcon::tell($player->id, 'Please type !fp if you want to forgive him.'); } }
/** 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; } } }
/** Client message : notify it in the necessary logs. * This function is triggered by the say event. It will log the message in the chat log, and if it's a command, it will log it in the * commands log. * * \param $id The ID of the client who sent a message. * \param $message The message itself. * * \return Nothing. */ public function SrvEventSay($id, $message) { Leelabot::message('Logging say message'); print_r($this->_logFiles); $player = Server::getPlayer($id); $this->log('chat', $player->name . ' <' . $player->uuid . '>: ' . $message); $cmd = explode(' ', $message); //Checking if the message is a command if (strlen($cmd[0]) && $cmd[0][0] == '!') { if ($this->_plugins->eventExists('command', substr($cmd[0], 1))) { $cmdlevel = $this->_plugins->getEventLevel('command', substr($cmd[0], 1)); } else { $cmdlevel = '?'; } $this->log('commands', $player->name . ' <' . $player->uuid . '>: ' . $message); if (!empty($player->auth)) { $this->log('commands', "\t" . 'Authname: ' . $player->auth); } $this->log('commands', "\t" . 'Level check: ' . $player->level . '/' . $cmdlevel); if ($cmdlevel === '?') { $this->log('commands', "\t" . 'Command not found.'); } elseif ($cmdlevel > $player->level) { $this->log('commands', "\t" . 'Access denied.'); } else { $this->log('commands', "\t" . 'Access granted.'); } } }