- updated authentication class and levels

This commit is contained in:
Steffen Schröder 2013-11-10 19:30:14 +01:00
parent 1f6ac61897
commit 8c9a1af65d
7 changed files with 221 additions and 307 deletions

View File

@ -2,35 +2,12 @@
<!-- Configure authentication for players --> <!-- Configure authentication for players -->
<authentication-config> <authentication-config>
<!-- SuperAdmins with full access --> <!-- SuperAdmins that can't be removed ingame -->
<superadmin> <xsuperadmins>
<!-- <login>login1</login> <login>login2</login> -->
<login>steeffeen</login> <login>steeffeen</login>
<login>kremsy</login> <login>kremsy</login>
</superadmin> </xsuperadmins>
<!-- Admins with almost full access --> <!-- You can add other admins and operators ingame -->
<admin>
<!-- <login>login1</login> <login>login2</login> -->
<login>gorby</login>
<login>canyondrive</login>
</admin>
<!-- Operators with only moderating access -->
<operator>
<!-- <login>login1</login> <login>login2</login> -->
<login>eyebo</login>
<login>jojo95183</login>
<login>xanashea</login>
<login>ardid</login>
<login>gugli</login>
<login>phil13hebert</login>
<login>xcaliber</login>
<login>eole</login>
<login>fix</login>
<login>papychampy</login>
<login>titishu</login>
<login>wurstigewurst</login>
</operator>
</authentication-config> </authentication-config>

View File

@ -5,98 +5,148 @@ namespace ManiaControl;
/** /**
* Class handling authentication levels * Class handling authentication levels
* *
* @author steeffeen * @author steeffeen & kremsy
*/ */
class Authentication { class Authentication {
/** /**
* Constants * Constants
*/ */
public $RIGHTS_LEVELS = array(-1 => 'none', 0 => 'superadmin', 1 => 'admin', 2 => 'operator', 3 => 'all'); const AUTH_LEVEL_PLAYER = 0;
const AUTH_LEVEL_OPERATOR = 1;
const AUTH_LEVEL_ADMIN = 2;
const AUTH_LEVEL_SUPERADMIN = 3;
const AUTH_LEVEL_XSUPERADMIN = 4;
/** /**
* Private properties * Private properties
*/ */
private $mc = null; private $maniaControl = null;
private $config = null;
/** /**
* Construct authentication manager * Construct authentication manager
*
* @param ManiaControl $maniaControl
*/ */
public function __construct($mc) { public function __construct(ManiaControl $maniaControl) {
$this->mc = $mc; $this->maniaControl = $maniaControl;
$this->loadConfig();
}
/**
* Load config and initialize strong superadmins
*
* @return bool
*/
private function loadConfig() {
$config = FileUtil::loadConfig('authentication.xml');
$mysqli = $this->maniaControl->database->mysqli;
// Load config // Remove all XSuperadmins
$this->config = FileUtil::loadConfig('authentication.xml'); $adminQuery = "UPDATE `" . PlayerHandler::TABLE_PLAYERS . "`
} SET `authLevel` = ?
WHERE `authLevel` = ?;";
/** $adminStatement = $mysqli->prepare($adminQuery);
* Check if the player has enough rights if ($mysqli->error) {
* trigger_error($mysqli->error, E_USER_ERROR);
* @param string $login
* @param string $defaultRight
* @param string $neededRight
* @return bool
*/
public function checkRight($login, $neededRight) {
$right = $this->getRights($login);
return $this->compareRights($right, $neededRight);
}
/**
* Compare if the rights are enough
*
* @param string $hasRight
* @param string $neededRight
* @return bool
*/
public function compareRights($hasRight, $neededRight) {
if (!in_array($hasRight, $this->RIGHTS_LEVELS) || !in_array($neededRight, $this->RIGHTS_LEVELS)) {
return false; return false;
} }
$hasLevel = array_search($hasRight, $this->RIGHTS_LEVELS); $adminLevel = self::AUTH_LEVEL_SUPERADMIN;
$neededLevel = array_search($neededRight, $this->RIGHTS_LEVELS); $xAdminLevel = self::AUTH_LEVEL_XSUPERADMIN;
if ($hasLevel > $neededLevel) { $adminStatement->bind_param('ii', $adminLevel, $xAdminLevel);
$adminStatement->execute();
if ($adminStatement->error) {
trigger_error($adminStatement->error);
}
$adminStatement->close();
// Set XSuperAdmins
$xAdmins = $config->xsuperadmins->xpath('login');
$adminQuery = "INSERT INTO `" . PlayerHandler::TABLE_PLAYERS . "` (
`login`,
`authLevel`
) VALUES (
?, ?
) ON DUPLICATE KEY UPDATE
`authLevel` = VALUES(`authLevel`);";
$adminStatement = $mysqli->prepare($adminQuery);
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
return false; return false;
} }
else { $adminStatement->bind_param('si', $login, $xAdminLevel);
return true; $success = true;
} foreach ($xAdmins as $xAdmin) {
} $login = (string) $xAdmin;
$adminStatement->execute();
/** if ($adminStatement->error) {
* Get rights of the given login trigger_error($adminStatement->error);
* $success = false;
* @param string $login
* @param string $defaultRights
* @return string
*/
public function getRights($login, $defaultRight = 'all') {
$groups = $this->config->xpath('//login[text()="' . $login . '"]/..');
if (empty($groups)) return $defaultRight;
$right = $defaultRight;
$rightLevel = array_search($right, $this->RIGHTS_LEVELS);
foreach ($groups as $group) {
$level = array_search($group->getName(), $this->RIGHTS_LEVELS);
if ($level === false) continue;
if ($level < $rightLevel || $rightLevel === false) {
$right = $group->getName();
$rightLevel = $level;
} }
} }
return $right; $adminStatement->close();
return $success;
}
/**
* Grant the auth level to the player
*
* @param Player $player
* @param int $authLevel
* @return bool
*/
public function grantAuthLevel(Player $player, $authLevel) {
if (!$player || $authLevel  >= self::AUTH_LEVEL_XSUPERADMIN) {
return false;
}
$mysqli = $this->maniaControl->database->mysqli;
$authQuery = "INSERT INTO `" . PlayerHandler::TABLE_PLAYERS . "` (
`login`,
`authLevel`
) VALUES (
?, ?
) ON DUPLICATE KEY UPDATE
`authLevel` = VALUES(`authLevel`);";
$authStatement = $mysqli->prepare($authQuery);
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
return false;
}
$authStatement->bind_param('si', $player->login, $authLevel);
$authStatement->execute();
if ($authStatement->error) {
trigger_error($authStatement->error);
$authStatement->close();
return false;
}
$authStatement->close();
return $success;
} }
/** /**
* Sends an error message to the login * Sends an error message to the login
* *
* @param string $login * @param string $login
* @return bool
*/ */
public function sendNotAllowed($login) { public function sendNotAllowed(Player $player) {
if (!$this->mc->chat->sendError('You do not have the required rights to perform this command!', $login)) { if (!$player) {
trigger_error("Couldn't send forbidden message to login '" . $login . "'. " . $this->mc->getClientErrorText()); return false;
} }
return $this->maniaControl->chat->sendError('You do not have the required rights to perform this command!', $player->login);
}
/**
* Check if the player has enough rights
*
* @param Player $login
* @param int $neededAuthLevel
* @return bool
*/
public static function checkRight(Player $player, $neededAuthLevel) {
if (!$player) {
return false;
}
return ($player->authLevel >= $neededAuthLevel);
} }
} }

View File

@ -7,13 +7,13 @@ namespace ManiaControl;
* *
* @author steeffeen & kremsy * @author steeffeen & kremsy
*/ */
// TODO: settings for command auth levels
class Commands { class Commands {
/** /**
* Private properties * Private properties
*/ */
private $maniaControl = null; private $maniaControl = null;
private $config = null;
private $commandHandlers = array(); private $commandHandlers = array();
private $openBills = array(); private $openBills = array();
private $serverShutdownTime = -1; private $serverShutdownTime = -1;
@ -25,17 +25,14 @@ class Commands {
public function __construct(ManiaControl $maniaControl) { public function __construct(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl; $this->maniaControl = $maniaControl;
// Load config
$this->config = FileUtil::loadConfig('commands.xml');
// Register for callbacks // Register for callbacks
$this->maniaControl->callbacks->registerCallbackHandler(Callbacks::CB_MC_5_SECOND, $this, 'each5Seconds'); $this->maniaControl->callbacks->registerCallbackHandler(Callbacks::CB_MC_5_SECOND, $this, 'each5Seconds');
$this->maniaControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_BILLUPDATED, $this, 'handleBillUpdated'); $this->maniaControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_BILLUPDATED, $this, 'handleBillUpdated');
$this->maniaControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCHAT, $this, 'handleChatCallback'); $this->maniaControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCHAT, $this, 'handleChatCallback');
// Register basic commands // Register basic commands
$commands = array('help', 'version', 'shutdown', 'shutdownserver', 'networkstats', 'systeminfo', 'setservername', 'getplanets', $commands = array('help', 'version', 'shutdown', 'shutdownserver', 'systeminfo', 'setservername', 'getplanets', 'donate',
'donate', 'pay', 'kick', 'nextmap', 'restartmap', 'addmap', 'removemap', 'startwarmup', 'stopwarmup'); 'pay', 'kick', 'nextmap', 'restartmap', 'addmap', 'removemap');
foreach ($commands as $command) { foreach ($commands as $command) {
$this->registerCommandHandler($command, $this, 'command_' . $command); $this->registerCommandHandler($command, $this, 'command_' . $command);
} }
@ -77,7 +74,8 @@ class Commands {
return false; return false;
} }
// Check for valid player // Check for valid player
if ($chat[0] <= 0 || strlen($chat[1]) <= 0) { $player = $this->maniaControl->playerHandler->getPlayer($login);
if (!$player) {
return false; return false;
} }
// Handle command // Handle command
@ -89,7 +87,7 @@ class Commands {
} }
// Inform command handlers // Inform command handlers
foreach ($this->commandHandlers[$command] as $handler) { foreach ($this->commandHandlers[$command] as $handler) {
call_user_func(array($handler[0], $handler[1]), $callback); call_user_func(array($handler[0], $handler[1]), $callback, $player);
} }
return true; return true;
} }
@ -134,33 +132,6 @@ class Commands {
return true; return true;
} }
/**
* Retrieve the needed rights level to perform the given command
*
* @param string $commandName
* @param string $defaultLevel
* @return string
*/
private function getRightsLevel($commandName, $defaultLevel) {
$command_rights = $this->config->xpath('//' . strtolower($commandName) . '/..');
if (empty($command_rights)) {
return $defaultLevel;
}
$rights = $this->maniaControl->authentication->RIGHTS_LEVELS;
$highest_level = null;
foreach ($command_rights as $right) {
$levelName = $right->getName();
$levelInt = array_search($levelName, $rights);
if ($levelInt !== false && ($highest_level === null || $highest_level < $levelInt)) {
$highest_level = $levelInt;
}
}
if ($highest_level === null || !array_key_exists($highest_level, $rights)) {
return $defaultLevel;
}
return $rights[$highest_level];
}
/** /**
* Send ManiaControl version * Send ManiaControl version
* *
@ -169,11 +140,6 @@ class Commands {
*/ */
private function command_version(array $chat) { private function command_version(array $chat) {
$login = $chat[1][1]; $login = $chat[1][1];
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('version', 'all'))) {
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false;
}
$message = 'This server is using ManiaControl v' . ManiaControl::VERSION . '!'; $message = 'This server is using ManiaControl v' . ManiaControl::VERSION . '!';
return $this->maniaControl->chat->sendInformation($message, $login); return $this->maniaControl->chat->sendInformation($message, $login);
} }
@ -186,11 +152,6 @@ class Commands {
*/ */
private function command_help(array $chat) { private function command_help(array $chat) {
$login = $chat[1][1]; $login = $chat[1][1];
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('help', 'all'))) {
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false;
}
// TODO: improve help command // TODO: improve help command
// TODO: enable help for specific commands // TODO: enable help for specific commands
$list = 'Available commands: '; $list = 'Available commands: ';
@ -217,13 +178,12 @@ class Commands {
* Handle getplanets command * Handle getplanets command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_getplanets(array $chat) { private function command_getplanets(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_ADMIN)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('getplanets', 'admin'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
if (!$this->maniaControl->client->query('GetServerPlanets')) { if (!$this->maniaControl->client->query('GetServerPlanets')) {
@ -232,22 +192,17 @@ class Commands {
} }
$planets = $this->maniaControl->client->getResponse(); $planets = $this->maniaControl->client->getResponse();
$message = "This Server has {$planets} Planets!"; $message = "This Server has {$planets} Planets!";
return $this->maniaControl->chat->sendInformation($message, $login); return $this->maniaControl->chat->sendInformation($message, $player->login);
} }
/** /**
* Handle donate command * Handle donate command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_donate(array $chat) { private function command_donate(array $chat, Player $player) {
$login = $chat[1][1];
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('donate', 'all'))) {
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return;
}
$params = explode(' ', $chat[1][2]); $params = explode(' ', $chat[1][2]);
if (count($params) < 2) { if (count($params) < 2) {
// TODO: send usage information // TODO: send usage information
@ -260,7 +215,7 @@ class Commands {
} }
if (count($params) >= 3) { if (count($params) >= 3) {
$receiver = $params[2]; $receiver = $params[2];
$receiverPlayer = $this->maniaControl->database->getPlayer($receiver); $receiverPlayer = $this->maniaControl->playerHandler->getPlayer($receiver);
$receiverName = ($receiverPlayer ? $receiverPlayer['NickName'] : $receiver); $receiverName = ($receiverPlayer ? $receiverPlayer['NickName'] : $receiver);
} }
else { else {
@ -268,16 +223,15 @@ class Commands {
$receiverName = $this->maniaControl->server->getName(); $receiverName = $this->maniaControl->server->getName();
} }
$message = 'Donate ' . $amount . ' Planets to $<' . $receiverName . '$>?'; $message = 'Donate ' . $amount . ' Planets to $<' . $receiverName . '$>?';
if (!$this->maniaControl->client->query('SendBill', $login, $amount, $message, $receiver)) { if (!$this->maniaControl->client->query('SendBill', $pl, $amount, $message, $receiver)) {
trigger_error( trigger_error(
"Couldn't create donation of {$amount} planets from '{$login}' for '{$receiver}'. " . "Couldn't create donation of {$amount} planets from '{$player->login}' for '{$receiver}'. " .
$this->maniaControl->getClientErrorText()); $this->maniaControl->getClientErrorText());
$this->maniaControl->chat->sendError("Creating donation failed.", $login); $this->maniaControl->chat->sendError("Creating donation failed.", $player->login);
return false; return false;
} }
$bill = $this->maniaControl->client->getResponse(); $bill = $this->maniaControl->client->getResponse();
$this->openBills[$bill] = $login; $this->openBills[$bill] = $player->login;
return true; return true;
} }
@ -285,13 +239,12 @@ class Commands {
* Handle pay command * Handle pay command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_pay(array $chat) { private function command_pay(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_SUPERADMIN)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('pay', 'superadmin'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
$params = explode(' ', $chat[1][2]); $params = explode(' ', $chat[1][2]);
@ -308,119 +261,64 @@ class Commands {
$receiver = $params[2]; $receiver = $params[2];
} }
else { else {
$receiver = $login; $receiver = $player->login;
} }
$message = 'Payout from $<' . $this->maniaControl->server->getName() . '$>.'; $message = 'Payout from $<' . $this->maniaControl->server->getName() . '$>.';
if (!$this->maniaControl->client->query('Pay', $receiver, $amount, $message)) { if (!$this->maniaControl->client->query('Pay', $receiver, $amount, $message)) {
trigger_error( trigger_error(
"Couldn't create payout of {$amount} planets by '{$login}' for '{$receiver}'. " . "Couldn't create payout of {$amount} planets by '{$player->login}' for '{$receiver}'. " .
$this->maniaControl->getClientErrorText()); $this->maniaControl->getClientErrorText());
$this->maniaControl->chat->sendError("Creating payout failed.", $login); $this->maniaControl->chat->sendError("Creating payout failed.", $player->login);
return false; return false;
} }
$bill = $this->maniaControl->client->getResponse(); $bill = $this->maniaControl->client->getResponse();
$this->openBills[$bill] = $login; $this->openBills[$bill] = $player->login;
return true; return true;
} }
/**
* Handle networkstats command
*
* @param array $chat
* @return bool
*/
private function command_networkstats(array $chat) {
$login = $chat[1][1];
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('networkstats', 'superadmin'))) {
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false;
}
$networkStats = $this->maniaControl->server->getNetworkStats();
$message = 'NetworkStats: uptime=' . $networkStats['Uptime'] . ', nbConn=' . $networkStats['NbrConnection'] . ', recvRate=' .
$networkStats['RecvNetRate'] . ', sendRate=' . $networkStats['SendNetRate'] . ', recvTotal=' .
$networkStats['SendNetRate'] . ', sentTotal=' . $networkStats['SendNetRate'];
return $this->maniaControl->chat->sendInformation($message, $login);
}
/** /**
* Handle systeminfo command * Handle systeminfo command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_systeminfo(array $chat) { private function command_systeminfo(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_SUPERADMIN)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('systeminfo', 'superadmin'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
$systemInfo = $this->maniaControl->server->getSystemInfo(); $systemInfo = $this->maniaControl->server->getSystemInfo();
$message = 'SystemInfo: ip=' . $systemInfo['PublishedIp'] . ', port=' . $systemInfo['Port'] . ', p2pPort=' . $message = 'SystemInfo: ip=' . $systemInfo['PublishedIp'] . ', port=' . $systemInfo['Port'] . ', p2pPort=' .
$systemInfo['P2PPort'] . ', title=' . $systemInfo['TitleId'] . ', login=' . $systemInfo['ServerLogin'] . ', '; $systemInfo['P2PPort'] . ', title=' . $systemInfo['TitleId'] . ', login=' . $systemInfo['ServerLogin'] . ', ';
return $this->maniaControl->chat->sendInformation($message, $login); return $this->maniaControl->chat->sendInformation($message, $player->login);
} }
/** /**
* Handle shutdown command * Handle shutdown command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_shutdown(array $chat) { private function command_shutdown(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_SUPERADMIN)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('shutdown', 'superadmin'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
return $this->maniaControl->quit("ManiaControl shutdown requested by '{$login}'"); return $this->maniaControl->quit("ManiaControl shutdown requested by '{$player->login}'");
}
/**
* Handle startwarmup command
*
* @param array $chat
* @return bool
*/
private function command_startwarmup(array $chat) {
$login = $chat[1][1];
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('startwarmup', 'operator'))) {
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false;
}
return $this->maniaControl->client->query("SetWarmUp", true);
}
/**
* Handle stopwarmup command
*
* @param array $chat
* @return bool
*/
private function command_stopwarmup(array $chat) {
$login = $chat[1][1];
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('stopwarmup', 'operator'))) {
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false;
}
return $this->maniaControl->client->query("SetWarmUp", false);
} }
/** /**
* Handle server shutdown command * Handle server shutdown command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_shutdownserver(array $chat) { private function command_shutdownserver(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_SUPERADMIN)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('shutdownserver', 'superadmin'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
// Check for delayed shutdown // Check for delayed shutdown
@ -430,38 +328,37 @@ class Commands {
if ($param == 'empty') { if ($param == 'empty') {
$this->serverShutdownEmpty = !$this->serverShutdownEmpty; $this->serverShutdownEmpty = !$this->serverShutdownEmpty;
if ($this->serverShutdownEmpty) { if ($this->serverShutdownEmpty) {
$this->maniaControl->chat->sendInformation("The server will shutdown as soon as it's empty!", $login); $this->maniaControl->chat->sendInformation("The server will shutdown as soon as it's empty!", $player->login);
return true; return true;
} }
$this->maniaControl->chat->sendInformation("Empty-shutdown cancelled!", $login); $this->maniaControl->chat->sendInformation("Empty-shutdown cancelled!", $player->login);
return true; return true;
} }
$delay = (int) $param; $delay = (int) $param;
if ($delay <= 0) { if ($delay <= 0) {
// Cancel shutdown // Cancel shutdown
$this->serverShutdownTime = -1; $this->serverShutdownTime = -1;
$this->maniaControl->chat->sendInformation("Delayed shutdown cancelled!", $login); $this->maniaControl->chat->sendInformation("Delayed shutdown cancelled!", $player->login);
return true; return true;
} }
// Trigger delayed shutdown // Trigger delayed shutdown
$this->serverShutdownTime = time() + $delay * 60.; $this->serverShutdownTime = time() + $delay * 60.;
$this->maniaControl->chat->sendInformation("The server will shut down in " . $delay . " minutes!", $login); $this->maniaControl->chat->sendInformation("The server will shut down in {$delay} minutes!", $player->login);
return true; return true;
} }
return $this->shutdownServer($login); return $this->shutdownServer($player->login);
} }
/** /**
* Handle kick command * Handle kick command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_kick(array $chat) { private function command_kick(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_OPERATOR)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('kick', 'operator'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
$params = explode(' ', $chat[1][2], 3); $params = explode(' ', $chat[1][2], 3);
@ -470,49 +367,44 @@ class Commands {
return false; return false;
} }
$target = $params[1]; $target = $params[1];
$players = $this->maniaControl->server->getPlayers(); $target = $this->maniaControl->playerHandler->getPlayer($target);
foreach ($players as $player) { if (!$target) {
if ($player['Login'] != $target) { $this->maniaControl->chat->sendError("Invalid player login.", $player->login);
continue; return false;
}
// Kick player
$message = '';
if (isset($params[2])) {
$message = $params[2];
}
return $this->maniaControl->client->query('Kick', $target, $message);
} }
$this->maniaControl->chat->sendError("Invalid player login.", $login); $message = '';
return false; if (isset($params[2])) {
$message = $params[2];
}
return $this->maniaControl->client->query('Kick', $target->login, $message);
} }
/** /**
* Handle removemap command * Handle removemap command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_removemap(array $chat) { private function command_removemap(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_OPERATOR)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('kick', 'operator'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
// TODO: allow params
// Get map name // Get map name
$map = $this->maniaControl->server->getMap(); $map = $this->maniaControl->server->getMap();
if (!$map) { if (!$map) {
$this->maniaControl->chat->sendError("Couldn't remove map.", $login); $this->maniaControl->chat->sendError("Couldn't remove map.", $player->login);
return false; return false;
} }
$mapName = $map['FileName']; $mapName = $map['FileName'];
// Remove map // Remove map
if (!$this->maniaControl->client->query('RemoveMap', $mapName)) { if (!$this->maniaControl->client->query('RemoveMap', $mapName)) {
trigger_error("Couldn't remove current map. " . $this->maniaControl->getClientErrorText()); trigger_error("Couldn't remove current map. " . $this->maniaControl->getClientErrorText());
$this->maniaControl->chat->sendError("Couldn't remove map.", $player->login);
return false; return false;
} }
$this->maniaControl->chat->sendSuccess('Map removed.', $login); $this->maniaControl->chat->sendSuccess('Map removed.', $player->login);
return true; return true;
} }
@ -520,13 +412,12 @@ class Commands {
* Handle addmap command * Handle addmap command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_addmap(array $chat) { private function command_addmap(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_OPERATOR)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('addmap', 'operator'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
$params = explode(' ', $chat[1][2], 2); $params = explode(' ', $chat[1][2], 2);
@ -537,20 +428,20 @@ class Commands {
// Check if ManiaControl can even write to the maps dir // Check if ManiaControl can even write to the maps dir
if (!$this->maniaControl->client->query('GetMapsDirectory')) { if (!$this->maniaControl->client->query('GetMapsDirectory')) {
trigger_error("Couldn't get map directory. " . $this->maniaControl->getClientErrorText()); trigger_error("Couldn't get map directory. " . $this->maniaControl->getClientErrorText());
$this->maniaControl->chat->sendError("ManiaControl couldn't retrieve the maps directory.", $login); $this->maniaControl->chat->sendError("ManiaControl couldn't retrieve the maps directory.", $player->login);
return false; return false;
} }
$mapDir = $this->maniaControl->client->getResponse(); $mapDir = $this->maniaControl->client->getResponse();
if (!is_dir($mapDir)) { if (!is_dir($mapDir)) {
trigger_error("ManiaControl doesn't have have access to the maps directory in '{$mapDir}'."); trigger_error("ManiaControl doesn't have have access to the maps directory in '{$mapDir}'.");
$this->maniaControl->chat->sendError("ManiaControl doesn't have access to the maps directory.", $login); $this->maniaControl->chat->sendError("ManiaControl doesn't have access to the maps directory.", $player->login);
return false; return false;
} }
$downloadDirectory = $this->maniaControl->settingManager->getSetting($this, 'MapDownloadDirectory', 'mx'); $downloadDirectory = $this->maniaControl->settingManager->getSetting($this, 'MapDownloadDirectory', 'mx');
// Create download directory if necessary // Create download directory if necessary
if (!is_dir($mapDir . $downloadDirectory) && !mkdir($mapDir . $downloadDirectory)) { if (!is_dir($mapDir . $downloadDirectory) && !mkdir($mapDir . $downloadDirectory)) {
trigger_error("ManiaControl doesn't have to rights to save maps in '{$mapDir}{$downloadDirectory}'."); trigger_error("ManiaControl doesn't have to rights to save maps in '{$mapDir}{$downloadDirectory}'.");
$this->maniaControl->chat->sendError("ManiaControl doesn't have the rights to save maps.", $login); $this->maniaControl->chat->sendError("ManiaControl doesn't have the rights to save maps.", $player->login);
return false; return false;
} }
$mapDir .= $downloadDirectory . '/'; $mapDir .= $downloadDirectory . '/';
@ -565,7 +456,7 @@ class Commands {
$mapInfo = FileUtil::loadFile($url); $mapInfo = FileUtil::loadFile($url);
if (!$mapInfo || strlen($mapInfo) <= 0) { if (!$mapInfo || strlen($mapInfo) <= 0) {
// Invalid id // Invalid id
$this->maniaControl->chat->sendError('Invalid MX-Id!', $login); $this->maniaControl->chat->sendError('Invalid MX-Id!', $player->login);
return false; return false;
} }
$mapInfo = json_decode($mapInfo, true); $mapInfo = json_decode($mapInfo, true);
@ -573,34 +464,34 @@ class Commands {
$file = FileUtil::loadFile($url); $file = FileUtil::loadFile($url);
if (!$file) { if (!$file) {
// Download error // Download error
$this->maniaControl->chat->sendError('Download failed!', $login); $this->maniaControl->chat->sendError('Download failed!', $player->login);
return false; return false;
} }
// Save map // Save map
$fileName = $mapDir . $mapInfo['TrackID'] . '_' . $mapInfo['Name'] . '.Map.Gbx'; $fileName = $mapDir . $mapInfo['TrackID'] . '_' . $mapInfo['Name'] . '.Map.Gbx';
if (!file_put_contents($fileName, $file)) { if (!file_put_contents($fileName, $file)) {
// Save error // Save error
$this->maniaControl->chat->sendError('Saving map failed!', $login); $this->maniaControl->chat->sendError('Saving map failed!', $player->login);
return false; return false;
} }
// Check for valid map // Check for valid map
if (!$this->maniaControl->client->query('CheckMapForCurrentServerParams', $fileName)) { if (!$this->maniaControl->client->query('CheckMapForCurrentServerParams', $fileName)) {
trigger_error("Couldn't check if map is valid. " . $this->maniaControl->getClientErrorText()); trigger_error("Couldn't check if map is valid. " . $this->maniaControl->getClientErrorText());
$this->maniaControl->chat->sendError('Error checking map!', $login); $this->maniaControl->chat->sendError('Error checking map!', $player->login);
return false; return false;
} }
$response = $this->maniaControl->client->getResponse(); $response = $this->maniaControl->client->getResponse();
if (!$response) { if (!$response) {
// Inalid map type // Inalid map type
$this->maniaControl->chat->sendError("Invalid map type.", $login); $this->maniaControl->chat->sendError("Invalid map type.", $player->login);
return false; return false;
} }
// Add map to map list // Add map to map list
if (!$this->maniaControl->client->query('InsertMap', $fileName)) { if (!$this->maniaControl->client->query('InsertMap', $fileName)) {
$this->maniaControl->chat->sendError("Couldn't add map to match settings!", $login); $this->maniaControl->chat->sendError("Couldn't add map to match settings!", $player->login);
return false; return false;
} }
$this->maniaControl->chat->sendSuccess('Map $<' . $mapInfo['Name'] . '$> successfully added!'); $this->maniaControl->chat->sendSuccess('Map $<' . $mapInfo['Name'] . '$> added!');
return true; return true;
} }
// TODO: add local map by filename // TODO: add local map by filename
@ -611,13 +502,12 @@ class Commands {
* Handle nextmap command * Handle nextmap command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_nextmap(array $chat) { private function command_nextmap(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_OPERATOR)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('nextmap', 'operator'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
return $this->maniaControl->client->query('NextMap'); return $this->maniaControl->client->query('NextMap');
@ -627,13 +517,12 @@ class Commands {
* Handle retartmap command * Handle retartmap command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_restartmap(array $chat) { private function command_restartmap(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_OPERATOR)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('restartmap', 'operator'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
return $this->maniaControl->client->query('RestartMap'); return $this->maniaControl->client->query('RestartMap');
@ -643,13 +532,12 @@ class Commands {
* Handle setservername command * Handle setservername command
* *
* @param array $chat * @param array $chat
* @param Player $player
* @return bool * @return bool
*/ */
private function command_setservername(array $chat) { private function command_setservername(array $chat, Player $player) {
$login = $chat[1][1]; if (!$this->maniaControl->authentication->checkRight($player, Authentication::AUTH_LEVEL_ADMIN)) {
if (!$this->maniaControl->authentication->checkRight($login, $this->getRightsLevel('setservername', 'admin'))) { $this->maniaControl->authentication->sendNotAllowed($player);
// Not allowed!
$this->maniaControl->authentication->sendNotAllowed($login);
return false; return false;
} }
$params = explode(' ', $chat[1][2], 2); $params = explode(' ', $chat[1][2], 2);
@ -660,11 +548,11 @@ class Commands {
$serverName = $params[1]; $serverName = $params[1];
if (!$this->maniaControl->client->query('SetServerName', $serverName)) { if (!$this->maniaControl->client->query('SetServerName', $serverName)) {
trigger_error("Couldn't set server name. " . $this->maniaControl->getClientErrorText()); trigger_error("Couldn't set server name. " . $this->maniaControl->getClientErrorText());
$this->maniaControl->chat->sendError("Error!", $login); $this->maniaControl->chat->sendError("Error setting server name!", $player->login);
return false; return false;
} }
$serverName = $this->maniaControl->server->getName(); $serverName = $this->maniaControl->server->getName();
$this->maniaControl->chat->sendInformation("New Name: " . $serverName, $login); $this->maniaControl->chat->sendInformation("New Name: " . $serverName, $player->login);
return true; return true;
} }
@ -699,7 +587,7 @@ class Commands {
*/ */
private function shutdownServer($login = '#') { private function shutdownServer($login = '#') {
if (!$this->maniaControl->client->query('StopServer')) { if (!$this->maniaControl->client->query('StopServer')) {
trigger_error("Server shutdown command from '{$login}' failed. " . $this->maniaControl->getClientErrorText()); trigger_error("Server shutdown command from '{login}' failed. " . $this->maniaControl->getClientErrorText());
return false; return false;
} }
$this->maniaControl->quit("Server shutdown requested by '{$login}'"); $this->maniaControl->quit("Server shutdown requested by '{$login}'");

View File

@ -72,8 +72,8 @@ class ManiaControl {
$this->chat = new Chat($this); $this->chat = new Chat($this);
$this->callbacks = new Callbacks($this); $this->callbacks = new Callbacks($this);
$this->server = new Server($this); $this->server = new Server($this);
$this->authentication = new Authentication($this);
$this->playerHandler = new PlayerHandler($this); $this->playerHandler = new PlayerHandler($this);
$this->authentication = new Authentication($this);
$this->manialinkIdHandler = new ManialinkIdHandler(); $this->manialinkIdHandler = new ManialinkIdHandler();
$this->commands = new Commands($this); $this->commands = new Commands($this);
$this->pluginHandler = new PluginHandler($this); $this->pluginHandler = new PluginHandler($this);

View File

@ -16,6 +16,7 @@ class Player {
public $login = ''; public $login = '';
public $nickname = ''; public $nickname = '';
public $path = ''; public $path = '';
public $authLevel = 0;
public $joinCount = 0; public $joinCount = 0;
public $totalPlayed = 0; public $totalPlayed = 0;
public $language = ''; public $language = '';
@ -64,6 +65,7 @@ class Player {
* *
* @return bool * @return bool
*/ */
// TODO: check for bot players
public function isFakePlayer() { public function isFakePlayer() {
return ($this->pid <= 0); return ($this->pid <= 0);
} }

View File

@ -15,11 +15,6 @@ class PlayerHandler {
*/ */
const TABLE_PLAYERS = 'mc_players'; const TABLE_PLAYERS = 'mc_players';
/**
* Public properties
*/
public $rightLevels = array(0 => 'Player', 1 => 'Operator', 2 => 'Admin', 3 => 'MasterAdmin', 4 => 'Owner');
/** /**
* Private properties * Private properties
*/ */
@ -53,6 +48,8 @@ class PlayerHandler {
`login` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `login` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`nickname` varchar(150) COLLATE utf8_unicode_ci NOT NULL, `nickname` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`path` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `path` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`authLevel` int(11) NOT NULL DEFAULT '0',
`joinCount` int(11) NOT NULL DEFAULT '0',
`totalPlayed` int(11) NOT NULL DEFAULT '0' COMMENT 'Seconds', `totalPlayed` int(11) NOT NULL DEFAULT '0' COMMENT 'Seconds',
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`index`), PRIMARY KEY (`index`),
@ -201,7 +198,7 @@ class PlayerHandler {
$playerStatement->close(); $playerStatement->close();
// Fill up properties // Fill up properties
$playerQuery = "SELECT `joinCount`, `totalPlayed` FROM `" . self::TABLE_PLAYERS . "` $playerQuery = "SELECT `authLevel`, `joinCount`, `totalPlayed` FROM `" . self::TABLE_PLAYERS . "`
WHERE `index` = ?;"; WHERE `index` = ?;";
$playerStatement = $mysqli->prepare($playerQuery); $playerStatement = $mysqli->prepare($playerQuery);
if ($mysqli->error) { if ($mysqli->error) {
@ -216,7 +213,7 @@ class PlayerHandler {
return false; return false;
} }
$playerStatement->store_result(); $playerStatement->store_result();
$playerStatement->bind_result($player->joinCount, $player->totalPlayed); $playerStatement->bind_result($player->authLevel, $player->joinCount, $player->totalPlayed);
$playerStatement->fetch(); $playerStatement->fetch();
$playerStatement->free_result(); $playerStatement->free_result();
$playerStatement->close(); $playerStatement->close();

View File

@ -22,7 +22,7 @@ SETUP:
Enter your mysql server information. Enter your mysql server information.
2.3 Open the file 'configs/authentication.xml'. 2.3 Open the file 'configs/authentication.xml'.
Add the player logins who should have access to the commands of ManiaControl. Add the player logins of administrators.
3. Run the tool via the shell script 'ManiaControl.sh' (UNIX) or the batch file 'ManiaControl.bat' (Windows) 3. Run the tool via the shell script 'ManiaControl.sh' (UNIX) or the batch file 'ManiaControl.bat' (Windows)