diff --git a/application/.idea/workspace.xml b/application/.idea/workspace.xml
index 855b8922..e7b71b4d 100644
--- a/application/.idea/workspace.xml
+++ b/application/.idea/workspace.xml
@@ -23,10 +23,46 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -35,34 +71,16 @@
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
@@ -80,9 +98,12 @@
-
+
+
+
+
@@ -119,7 +140,18 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -166,6 +198,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -240,24 +286,24 @@
-
+
-
+
-
-
-
-
+
+
+
+
+
-
@@ -276,51 +322,65 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
diff --git a/application/configs/plugins.ManiaControl.xml b/application/configs/plugins.ManiaControl.xml
index 7f546f47..d9022328 100644
--- a/application/configs/plugins.ManiaControl.xml
+++ b/application/configs/plugins.ManiaControl.xml
@@ -1,12 +1,12 @@
-
+
diff --git a/application/core/authentication.ManiaControl.php b/application/core/authentication.ManiaControl.php
deleted file mode 100644
index a083b215..00000000
--- a/application/core/authentication.ManiaControl.php
+++ /dev/null
@@ -1,103 +0,0 @@
- 'none', 0 => 'superadmin', 1 => 'admin', 2 => 'operator', 3 => 'all');
-
- /**
- * Private properties
- */
- private $mControl = null;
-
- private $config = null;
-
- /**
- * Construct authentication manager
- */
- public function __construct($mControl) {
- $this->mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('authentication.ManiaControl.xml');
- }
-
- /**
- * Check if the player has enough rights
- *
- * @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;
- }
- $hasLevel = array_search($hasRight, $this->RIGHTS_LEVELS);
- $neededLevel = array_search($neededRight, $this->RIGHTS_LEVELS);
- if ($hasLevel > $neededLevel) {
- return false;
- }
- else {
- return true;
- }
- }
-
- /**
- * Get rights of the given login
- *
- * @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;
- }
-
- /**
- * Sends an error message to the login
- *
- * @param string $login
- */
- public function sendNotAllowed($login) {
- if (!$this->iControl->chat->sendError('You do not have the required rights to perform this command!', $login)) {
- trigger_error("Couldn't send forbidden message to login '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
-}
-
-?>
diff --git a/application/core/callbacks.ManiaControl.php b/application/core/callbacks.ManiaControl.php
deleted file mode 100644
index 6a6d7a0f..00000000
--- a/application/core/callbacks.ManiaControl.php
+++ /dev/null
@@ -1,191 +0,0 @@
-mControl = $mControl;
-
- // Init values
- $this->last1Second = time();
- $this->last5Second = time();
- $this->last1Minute = time();
- $this->last3Minute = time();
- }
-
- /**
- * Perform OnInit callback
- */
- public function onInit() {
- // On init callback
- $this->triggerCallback(self::CB_IC_ONINIT, array(self::CB_IC_ONINIT));
-
- // Simulate begin map
- $map = $this->iControl->server->getMap();
- if ($map) {
- $this->triggerCallback(self::CB_IC_BEGINMAP, array(self::CB_IC_BEGINMAP, array($map)));
- }
- }
-
- /**
- * Handles the given array of callbacks
- */
- public function handleCallbacks() {
- // Perform ManiaControl callbacks
- if ($this->last1Second <= time() - 1) {
- $this->last1Second = time();
-
- // 1 second
- $this->triggerCallback(self::CB_IC_1_SECOND, array(self::CB_IC_1_SECOND));
-
- if ($this->last5Second <= time() - 5) {
- $this->last5Second = time();
-
- // 5 second
- $this->triggerCallback(self::CB_IC_5_SECOND, array(self::CB_IC_5_SECOND));
-
- if ($this->last1Minute <= time() - 60) {
- $this->last1Minute = time();
-
- // 1 minute
- $this->triggerCallback(self::CB_IC_1_MINUTE, array(self::CB_IC_1_MINUTE));
-
- if ($this->last3Minute <= time() - 180) {
- $this->last3Minute = time();
-
- // 3 minute
- $this->triggerCallback(self::CB_IC_3_MINUTE, array(self::CB_IC_3_MINUTE));
- }
- }
- }
- }
-
- // Get server callbacks
- if (!$this->iControl->client) return;
- $this->iControl->client->resetError();
- $this->iControl->client->readCB();
- $callbacks = $this->iControl->client->getCBResponses();
- if (!is_array($callbacks) || $this->iControl->client->isError()) {
- trigger_error("Error reading server callbacks. " . $this->iControl->getClientErrorText());
- return;
- }
-
- // Handle callbacks
- foreach ($callbacks as $index => $callback) {
- $callbackName = $callback[0];
- switch ($callbackName) {
- case self::CB_MP_BEGINMAP:
- {
- // Map begin
- $this->triggerCallback($callbackName, $callback);
- $this->triggerCallback(self::CB_IC_BEGINMAP, $callback);
- break;
- }
- case self::CB_MP_ENDMAP:
- {
- // Map end
- $this->triggerCallback($callbackName, $callback);
- $this->triggerCallback(self::CB_IC_ENDMAP, $callback);
- break;
- }
- default:
- {
- $this->triggerCallback($callbackName, $callback);
- break;
- }
- }
- }
- }
-
- /**
- * Trigger a specific callback
- *
- * @param string $callbackName
- * @param mixed $data
- */
- public function triggerCallback($callbackName, $data) {
- if (!array_key_exists($callbackName, $this->callbackHandlers) || !is_array($this->callbackHandlers[$callbackName])) return;
- foreach ($this->callbackHandlers[$callbackName] as $handler) {
- call_user_func(array($handler[0], $handler[1]), $data);
- }
- }
-
- /**
- * Add a new callback handler
- */
- public function registerCallbackHandler($callback, $handler, $method) {
- if (!is_object($handler) || !method_exists($handler, $method)) {
- trigger_error("Given handler can't handle callback '" . $callback . "' (no method '" . $method . "')!");
- return;
- }
- if (!array_key_exists($callback, $this->callbackHandlers) || !is_array($this->callbackHandlers[$callback])) {
- // Init callback handler array
- $this->callbackHandlers[$callback] = array();
- }
- // Register callback handler
- array_push($this->callbackHandlers[$callback], array($handler, $method));
- }
-}
-
-?>
diff --git a/application/core/chat.ManiaControl.php b/application/core/chat.ManiaControl.php
deleted file mode 100644
index 1e4895ae..00000000
--- a/application/core/chat.ManiaControl.php
+++ /dev/null
@@ -1,85 +0,0 @@
-';
-
- /**
- * Construct ManiaControl chat
- */
- public function __construct($mControl) {
- $this->mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('chat.ManiaControl.xml');
- }
-
- /**
- * Send a chat message to the given login
- *
- * @param string $login
- * @param string $message
- * @param bool $prefix
- */
- public function sendChat($message, $login = null, $prefix = false) {
- if (!$this->iControl->client) return false;
- if ($login === null) {
- return $this->iControl->client->query('ChatSendServerMessage', ($prefix ? $this->prefix : '') . $message);
- }
- else {
- return $this->iControl->client->query('ChatSendServerMessageToLogin', ($prefix ? $this->prefix : '') . $message, $login);
- }
- }
-
- /**
- * Send an information message to the given login
- *
- * @param string $login
- * @param string $message
- * @param bool $prefix
- */
- public function sendInformation($message, $login = null, $prefix = false) {
- $format = (string) $this->config->messages->information;
- return $this->sendChat($format . $message, $login);
- }
-
- /**
- * Send a success message to the given login
- *
- * @param string $message
- * @param string $login
- * @param bool $prefix
- */
- public function sendSuccess($message, $login = null, $prefix = false) {
- $format = (string) $this->config->messages->success;
- return $this->sendChat($format . $message, $login);
- }
-
- /**
- * Send an error message to the given login
- *
- * @param string $login
- * @param string $message
- * @param bool $prefix
- */
- public function sendError($message, $login = null, $prefix = false) {
- $format = (string) $this->config->messages->error;
- return $this->sendChat($format . $message, $login);
- }
-}
-
-?>
diff --git a/application/core/commands.ManiaControl.php b/application/core/commands.ManiaControl.php
deleted file mode 100644
index 2ac5bb22..00000000
--- a/application/core/commands.ManiaControl.php
+++ /dev/null
@@ -1,684 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('commands.ManiaControl.xml');
-
- // Register for callbacks
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_5_SECOND, $this, 'each5Seconds');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_BILLUPDATED, $this, 'handleBillUpdated');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCHAT, $this, 'handleChatCallback');
-
- // Register basic commands
- $commands = array('help', 'version', 'shutdown', 'shutdownserver', 'networkstats', 'systeminfo', 'getservername',
- 'setservername', 'getplanets', 'donate', 'pay', 'kick', 'nextmap', 'restartmap', 'addmap', 'removemap', 'startwarmup',
- 'stopwarmup');
- foreach ($commands as $command) {
- $this->registerCommandHandler($command, $this, 'command_' . $command);
- }
- }
-
- /**
- * Register a command handler
- *
- * @param string $commandName
- * @param object $handler
- * @param string $method
- */
- public function registerCommandHandler($commandName, $handler, $method) {
- $command = strtolower($commandName);
- if (!is_object($handler) || !method_exists($handler, $method)) {
- trigger_error("Given handler can't handle command '" . $command . "' (no method '" . $method . "')!");
- return;
- }
- if (!array_key_exists($command, $this->commandHandlers) || !is_array($this->commandHandlers[$command])) {
- // Init handlers array
- $this->commandHandlers[$command] = array();
- }
- // Register command handler
- array_push($this->commandHandlers[$command], array($handler, $method));
- }
-
- /**
- * Handle chat callback
- */
- public function handleChatCallback($callback) {
- $chat = $callback[1];
- // Check for command
- if (!$chat[3]) return;
- // Check for valid player
- if ($chat[0] <= 0 || strlen($chat[1]) <= 0) return;
- // Handle command
- $command = explode(" ", substr($chat[2], 1));
- $command = strtolower($command[0]);
- if (!array_key_exists($command, $this->commandHandlers) || !is_array($this->commandHandlers[$command])) {
- // No command handler registered
- return;
- }
- // Inform command handlers
- foreach ($this->commandHandlers[$command] as $handler) {
- call_user_func(array($handler[0], $handler[1]), $callback);
- }
- }
-
- /**
- * Handle bill updated callback
- */
- public function handleBillUpdated($callback) {
- $bill = $callback[1];
- if (!array_key_exists($bill[0], $this->openBills)) return;
- $login = $this->openBills[$bill[0]];
- switch ($bill[1]) {
- case 4:
- {
- // Payed
- $message = 'Success! Thanks.';
- $this->iControl->chat->sendSuccess($message, $login);
- unset($this->openBills[$bill[0]]);
- break;
- }
- case 5:
- {
- // Refused
- $message = 'Transaction cancelled.';
- $this->iControl->chat->sendError($message, $login);
- unset($this->openBills[$bill[0]]);
- break;
- }
- case 6:
- {
- // Error
- $this->iControl->chat->sendError($bill[2], $login);
- unset($this->openBills[$bill[0]]);
- break;
- }
- }
- }
-
- /**
- * 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->iControl->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
- */
- private function command_version($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('version', 'all'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- if (!$this->iControl->chat->sendInformation('This server is using ManiaControl v' . ManiaControl::VERSION . '!', $login)) {
- trigger_error("Couldn't send version to '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
-
- /**
- * Send help list
- */
- private function command_help($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('help', 'all'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- // TODO: improve help command
- // TODO: enable help for specific commands
- $list = 'Available commands: ';
- $commands = array_keys($this->commandHandlers);
- $count = count($commands);
- for ($index = 0; $index < $count; $index++) {
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel($commands[$index], 'superadmin'))) {
- unset($commands[$index]);
- }
- }
- $count = count($commands);
- $index = 0;
- foreach ($commands as $command) {
- $list .= $command;
- if ($index < $count - 1) {
- $list .= ', ';
- }
- $index++;
- }
- if (!$this->iControl->chat->sendInformation($list, $login)) {
- trigger_error("Couldn't send help list to '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
-
- /**
- * Handle getplanets command
- */
- private function command_getplanets($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('getplanets', 'admin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- if (!$this->iControl->client->query('GetServerPlanets')) {
- trigger_error("Couldn't retrieve server planets. " . $this->iControl->getClientErrorText());
- }
- else {
- $planets = $this->iControl->client->getResponse();
- if (!$this->iControl->chat->sendInformation('This Server has ' . $planets . ' Planets!', $login)) {
- trigger_error("Couldn't send server planets to '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
- }
-
- /**
- * Handle donate command
- */
- private function command_donate($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('donate', 'all'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $params = explode(' ', $chat[1][2]);
- if (count($params) < 2) {
- // TODO: send usage information
- return;
- }
- $amount = (int) $params[1];
- if (!$amount || $amount <= 0) {
- // TODO: send usage information
- return;
- }
- if (count($params) >= 3) {
- $receiver = $params[2];
- $receiverPlayer = $this->iControl->database->getPlayer($receiver);
- $receiverName = ($receiverPlayer ? $receiverPlayer['NickName'] : $receiver);
- }
- else {
- $receiver = '';
- $receiverName = $this->iControl->server->getName();
- }
- $message = 'Donate ' . $amount . ' Planets to $<' . $receiverName . '$>?';
- if (!$this->iControl->client->query('SendBill', $login, $amount, $message, $receiver)) {
- trigger_error(
- "Couldn't create donation of " . $amount . " planets from '" . $login . "' for '" . $receiver . "'. " .
- $this->iControl->getClientErrorText());
- $this->iControl->chat->sendError("Creating donation failed.", $login);
- }
- else {
- $bill = $this->iControl->client->getResponse();
- $this->openBills[$bill] = $login;
- }
- }
-
- /**
- * Handle pay command
- */
- private function command_pay($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('pay', 'superadmin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $params = explode(' ', $chat[1][2]);
- if (count($params) < 2) {
- // TODO: send usage information
- return;
- }
- $amount = (int) $params[1];
- if (!$amount || $amount <= 0) {
- // TODO: send usage information
- return;
- }
- if (count($params) >= 3) {
- $receiver = $params[2];
- }
- else {
- $receiver = $login;
- }
- $message = 'Payout from $<' . $this->iControl->server->getName() . '$>.';
- if (!$this->iControl->client->query('Pay', $receiver, $amount, $message)) {
- trigger_error(
- "Couldn't create payout of" . $amount . " planets by '" . $login . "' for '" . $receiver . "'. " .
- $this->iControl->getClientErrorText());
- $this->iControl->chat->sendError("Creating payout failed.", $login);
- }
- else {
- $bill = $this->iControl->client->getResponse();
- $this->openBills[$bill] = $login;
- }
- }
-
- /**
- * Handle networkstats command
- */
- private function command_networkstats($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('networkstats', 'superadmin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $networkStats = $this->iControl->server->getNetworkStats();
- $message = 'NetworkStats: ' . 'uptime=' . $networkStats['Uptime'] . ', ' . 'nbConn=' . $networkStats['NbrConnection'] . ', ' .
- 'recvRate=' . $networkStats['RecvNetRate'] . ', ' . 'sendRate=' . $networkStats['SendNetRate'] . ', ' . 'recvTotal=' .
- $networkStats['SendNetRate'] . ', ' . 'sentTotal=' . $networkStats['SendNetRate'];
- if (!$this->iControl->chat->sendInformation($message, $login)) {
- trigger_error("Couldn't send network stats to '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
-
- /**
- * Handle systeminfo command
- */
- private function command_systeminfo($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('systeminfo', 'superadmin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $systemInfo = $this->iControl->server->getSystemInfo();
- $message = 'SystemInfo: ' . 'ip=' . $systemInfo['PublishedIp'] . ', ' . 'port=' . $systemInfo['Port'] . ', ' . 'p2pPort=' .
- $systemInfo['P2PPort'] . ', ' . 'title=' . $systemInfo['TitleId'] . ', ' . 'login=' . $systemInfo['ServerLogin'] . ', ';
- if (!$this->iControl->chat->sendInformation($message, $login)) {
- trigger_error("Couldn't send system info to '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
-
- /**
- * Handle shutdown command
- */
- private function command_shutdown($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('shutdown', 'superadmin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $this->iControl->quit("ManiaControl shutdown requested by '" . $login . "'");
- }
-
- /**
- * Handle startwarmup command
- */
- private function command_startwarmup($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('startwarmup', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- if (!$this->iControl->client->query("SetWarmUp", true)) {
- trigger_error("Couldn't start warmup. " . $this->iControl->getClientErrorText());
- $player = $this->iControl->database->getPlayer($login);
- $this->iControl->chat->sendInformation('$<' . ($player ? $player['NickName'] : $login) . '$> started WarmUp!');
- }
- }
-
- /**
- * Handle stopwarmup command
- */
- private function command_stopwarmup($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('stopwarmup', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- if (!$this->iControl->client->query("SetWarmUp", false)) {
- trigger_error("Couldn't stop warmup. " . $this->iControl->getClientErrorText());
- }
- else {
- $player = $this->iControl->database->getPlayer($login);
- $this->iControl->chat->sendInformation('$<' . ($player ? $player['NickName'] : $login) . '$> stopped WarmUp!');
- }
- }
-
- /**
- * Handle server shutdown command
- */
- private function command_shutdownserver($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('shutdownserver', 'superadmin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- // Check for delayed shutdown
- $params = explode(' ', $chat[1][2]);
- if (count($params) >= 2) {
- $param = $params[1];
- if ($param == 'empty') {
- $this->serverShutdownEmpty = !$this->serverShutdownEmpty;
- if ($this->serverShutdownEmpty) {
- $this->iControl->chat->sendInformation("The server will shutdown as soon as it's empty!", $login);
- }
- else {
- $this->iControl->chat->sendInformation("Empty-shutdown cancelled!", $login);
- }
- }
- else {
- $delay = (int) $param;
- if ($delay <= 0) {
- // Cancel shutdown
- $this->serverShutdownTime = -1;
- $this->iControl->chat->sendInformation("Delayed shutdown cancelled!", $login);
- }
- else {
- // Trigger delayed shutdown
- $this->serverShutdownTime = time() + $delay * 60.;
- $this->iControl->chat->sendInformation("The server will shut down in " . $delay . " minutes!", $login);
- }
- }
- }
- else {
- $this->shutdownServer($login);
- }
- }
-
- /**
- * Handle kick command
- */
- private function command_kick($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('kick', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $params = explode(' ', $chat[1][2], 3);
- if (count($params) < 2) {
- // TODO: show usage
- return;
- }
- $target = $params[1];
- $players = $this->iControl->server->getPlayers();
- foreach ($players as $player) {
- if ($player['Login'] != $target) continue;
- // Kick player
- if (isset($params[2])) {
- $message = $params[2];
- }
- else {
- $message = "";
- }
- if (!$this->iControl->client->query('Kick', $target, $message)) {
- trigger_error("Couldn't kick player '" . $target . "'! " . $this->iControl->getClientErrorText());
- }
- return;
- }
- $this->iControl->chat->sendError("Invalid player login.", $login);
- }
-
- /**
- * Handle removemap command
- */
- private function command_removemap($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('kick', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- // TODO: allow params
- // Get map name
- $map = $this->iControl->server->getMap();
- if (!$map) {
- $this->iControl->chat->sendError("Couldn't remove map.", $login);
- }
- else {
- $mapName = $map['FileName'];
-
- // Remove map
- if (!$this->iControl->client->query('RemoveMap', $mapName)) {
- trigger_error("Couldn't remove current map. " . $this->iControl->getClientErrorText());
- }
- else {
- $this->iControl->chat->sendSuccess('Map removed.', $login);
- }
- }
- }
-
- /**
- * Handle addmap command
- */
- private function command_addmap($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('addmap', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $params = explode(' ', $chat[1][2], 2);
- if (count($params) < 2) {
- // TODO: show usage
- return;
- }
- // Check if ManiaControl can even write to the maps dir
- if (!$this->iControl->client->query('GetMapsDirectory')) {
- trigger_error("Couldn't get map directory. " . $this->iControl->getClientErrorText());
- $this->iControl->chat->sendError("ManiaControl couldn't retrieve the maps directory.", $login);
- return;
- }
- else {
- $mapDir = $this->iControl->client->getResponse();
- if (!is_dir($mapDir)) {
- trigger_error("ManiaControl doesn't have have access to the maps directory in '" . $mapDir . "'.");
- $this->iControl->chat->sendError("ManiaControl doesn't have access to the maps directory.", $login);
- return;
- }
- $dlDir = (string) $this->iControl->config->maps_dir;
- // Create mx directory if necessary
- if (!is_dir($mapDir . $dlDir) && !mkdir($mapDir . $dlDir)) {
- trigger_error("ManiaControl doesn't have to rights to save maps in'" . $mapDir . $dlDir, "'.");
- $this->iControl->chat->sendError("ManiaControl doesn't have to rights to save maps.", $login);
- return;
- }
- $mapDir .= $dlDir . '/';
- // Download the map
- if (is_numeric($params[1])) {
- $serverInfo = $this->iControl->server->getSystemInfo();
- $title = strtolower(substr($serverInfo['TitleId'], 0, 2));
- // Check if map exists
- $url = 'http://' . $title . '.mania-exchange.com/api/tracks/get_track_info/id/' . $params[1] . '?format=json';
- $mapInfo = Tools::loadFile($url);
- if (!$mapInfo || strlen($mapInfo) <= 0) {
- // Invalid id
- $this->iControl->chat->sendError('Invalid MX-Id!', $login);
- return;
- }
- $mapInfo = json_decode($mapInfo, true);
- $url = 'http://' . $title . '.mania-exchange.com/tracks/download/' . $params[1];
- $file = Tools::loadFile($url);
- if (!$file) {
- // Download error
- $this->iControl->chat->sendError('Download failed!', $login);
- return;
- }
- // Save map
- $fileName = $mapDir . $mapInfo['TrackID'] . '_' . $mapInfo['Name'] . '.Map.Gbx';
- if (!file_put_contents($fileName, $file)) {
- // Save error
- $this->iControl->chat->sendError('Saving map failed!', $login);
- return;
- }
- // Check for valid map
- if (!$this->iControl->client->query('CheckMapForCurrentServerParams', $fileName)) {
- trigger_error("Couldn't check if map is valid. " . $this->iControl->getClientErrorText());
- }
- else {
- $response = $this->iControl->client->getResponse();
- if (!$response) {
- // Inalid map type
- $this->iControl->chat->sendError("Invalid map type.", $login);
- return;
- }
- }
- // Add map to map list
- if (!$this->iControl->client->query('InsertMap', $fileName)) {
- $this->iControl->chat->sendError("Couldn't add map to match settings!", $login);
- return;
- }
- $this->iControl->chat->sendSuccess('Map $<' . $mapInfo['Name'] . '$> successfully added!');
- }
- else {
- // TODO: check if map exists locally
- // TODO: load map from direct url
- }
- }
- }
-
- /**
- * Handle nextmap command
- */
- private function command_nextmap($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('nextmap', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- if (!$this->iControl->client->query('NextMap')) {
- trigger_error("Couldn't skip map. " . $this->iControl->getClientErrorText());
- }
- }
-
- /**
- * Handle retartmap command
- */
- private function command_restartmap($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('restartmap', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- if (!$this->iControl->client->query('RestartMap')) {
- trigger_error("Couldn't restart map. " . $this->iControl->getClientErrorText());
- }
- }
-
- /**
- * Handle getservername command
- */
- private function command_getservername($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('getservername', 'operator'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $serverName = $this->iControl->server->getName();
- $this->iControl->chat->sendInformation("Server Name: " . $serverName, $login);
- }
-
- /**
- * Handle setservername command
- */
- private function command_setservername($chat) {
- $login = $chat[1][1];
- if (!$this->iControl->authentication->checkRight($login, $this->getRightsLevel('setservername', 'admin'))) {
- // Not allowed!
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
- $params = explode(' ', $chat[1][2], 2);
- if (count($params) < 2) {
- // TODO: show usage
- return;
- }
- $serverName = $params[1];
- if (!$this->iControl->client->query('SetServerName', $serverName)) {
- trigger_error("Couldn't set server name. " . $this->iControl->getClientErrorText());
- $this->iControl->chat->sendError("Error!");
- }
- else {
- $serverName = $this->iControl->server->getName();
- $this->iControl->chat->sendInformation("New Name: " . $serverName);
- }
- }
-
- /**
- * Check stuff each 5 seconds
- */
- public function each5Seconds() {
- // Empty shutdown
- if ($this->serverShutdownEmpty) {
- $players = $this->iControl->server->getPlayers();
- if (count($players) <= 0) {
- $this->shutdownServer('empty');
- }
- }
-
- // Delayed shutdown
- if ($this->serverShutdownTime > 0) {
- if (time() >= $this->serverShutdownTime) {
- $this->shutdownServer('delayed');
- }
- }
- }
-
- /**
- * Perform server shutdown
- */
- private function shutdownServer($login = '#') {
- $this->iControl->client->resetError();
- if (!$this->iControl->client->query('StopServer') || $this->iControl->client->isError()) {
- trigger_error("Server shutdown command from '" . $login . "' failed. " . $this->iControl->getClientErrorText());
- return;
- }
- $this->iControl->quit("Server shutdown requested by '" . $login . "'");
- }
-}
-
-?>
diff --git a/application/core/core.ManiaControl.php b/application/core/core.ManiaControl.php
deleted file mode 100644
index 8b781b0a..00000000
--- a/application/core/core.ManiaControl.php
+++ /dev/null
@@ -1,348 +0,0 @@
-config = Tools::loadConfig('core.ManiaControl.xml');
- $this->startTime = time();
-
- // Load chat tool
- $this->chat = new Chat($this);
-
- // Load callbacks handler
- $this->callbacks = new Callbacks($this);
-
- // Load database
- $this->database = new Database($this);
-
- // Load server
- $this->server = new Server($this);
-
- // Load authentication
- $this->authentication = new Authentication($this);
-
- // Load commands handler
- $this->commands = new Commands($this);
-
- // Load stats manager
- $this->stats = new Stats($this);
-
- // Register for core callbacks
- $this->callbacks->registerCallbackHandler(Callbacks::CB_MP_ENDMAP, $this, 'handleEndMap');
- }
-
- /**
- * Return message composed of client error message and error code
- *
- * @param object $client
- * @return string
- */
- public function getClientErrorText($client = null) {
- if (is_object($client)) {
- return $client->getErrorMessage() . ' (' . $client->getErrorCode() . ')';
- }
- return $this->client->getErrorMessage() . ' (' . $this->client->getErrorCode() . ')';
- }
-
- /**
- * Quit ManiaControl and log the given message
- */
- public function quit($message = false) {
- if ($this->shutdownRequested) return;
-
- if ($this->client) {
- // Announce quit
- $this->chat->sendInformation('ManiaControl shutting down.');
-
- // Hide manialinks
- $this->client->query('SendHideManialinkPage');
- }
-
- // Log quit reason
- if ($message) {
- error_log($message);
- }
-
- // Shutdown
- if ($this->client) $this->client->Terminate();
-
- error_log("Quitting ManiaControl!");
- exit();
- }
-
- /**
- * Run ManiaControl
- */
- public function run($debug = false) {
- error_log('Starting ManiaControl v' . self::VERSION . '!');
- $this->debug = (bool) $debug;
-
- // Load plugins
- $this->loadPlugins();
-
- // Connect to server
- $this->connect();
-
- // Loading finished
- error_log("Loading completed!");
-
- // Announce ManiaControl
- if (!$this->chat->sendInformation('ManiaControl v' . self::VERSION . ' successfully started!')) {
- trigger_error("Couldn't announce ManiaControl. " . $this->iControl->getClientErrorText());
- }
-
- // OnInit
- $this->callbacks->onInit();
-
- // Main loop
- while (!$this->shutdownRequested) {
- $loopStart = microtime(true);
-
- // Disable script timeout
- set_time_limit(30);
-
- // Handle server callbacks
- $this->callbacks->handleCallbacks();
-
- // Loop plugins
- foreach ($this->plugins as $plugin) {
- if (!method_exists($plugin, 'loop')) {
- continue;
- }
- $plugin->loop();
- }
-
- // Yield for next tick
- $loopEnd = microtime(true);
- $sleepTime = 300000 - $loopEnd + $loopStart;
- if ($sleepTime > 0) {
- usleep($sleepTime);
- }
- }
-
- // Shutdown
- $this->client->Terminate();
- }
-
- /**
- * Connect to ManiaPlanet server
- */
- private function connect() {
- $enable = $this->server->config->xpath('enable');
- $enable = Tools::toBool($enable[0]);
- if (!$enable) return;
-
- // Load remote client
- $this->client = new \IXR_ClientMulticall_Gbx();
-
- $host = $this->server->config->xpath('host');
- if (!$host) trigger_error("Invalid server configuration (host).", E_USER_ERROR);
- $host = (string) $host[0];
- $port = $this->server->config->xpath('port');
- if (!$host) trigger_error("Invalid server configuration (port).", E_USER_ERROR);
- $port = (string) $port[0];
- $timeout = $this->config->xpath('timeout');
- if (!$timeout) trigger_error("Invalid core configuration (timeout).", E_USER_ERROR);
- $timeout = (int) $timeout[0];
-
- error_log("Connecting to server at " . $host . ":" . $port . "...");
-
- // Connect
- if (!$this->client->InitWithIp($host, $port, $timeout)) {
- trigger_error(
- "Couldn't connect to server! " . $this->client->getErrorMessage() . "(" . $this->client->getErrorCode() . ")",
- E_USER_ERROR);
- }
-
- $login = $this->server->config->xpath('login');
- if (!$login) trigger_error("Invalid server configuration (login).", E_USER_ERROR);
- $login = (string) $login[0];
- $pass = $this->server->config->xpath('pass');
- if (!$pass) trigger_error("Invalid server configuration (password).", E_USER_ERROR);
- $pass = (string) $pass[0];
-
- // Authenticate
- if (!$this->client->query('Authenticate', $login, $pass)) {
- trigger_error(
- "Couldn't authenticate on server with user '" . $login . "'! " . $this->client->getErrorMessage() . "(" .
- $this->client->getErrorCode() . ")", E_USER_ERROR);
- }
-
- // Enable callback system
- if (!$this->client->query('EnableCallbacks', true)) {
- trigger_error("Couldn't enable callbacks! " . $this->client->getErrorMessage() . "(" . $this->client->getErrorCode() . ")",
- E_USER_ERROR);
- }
-
- // Wait for server to be ready
- if (!$this->server->waitForStatus($this->client, 4)) {
- trigger_error("Server couldn't get ready!", E_USER_ERROR);
- }
-
- // Set api version
- if (!$this->client->query('SetApiVersion', self::API_VERSION)) {
- trigger_error(
- "Couldn't set API version '" . self::API_VERSION . "'! This might cause problems. " .
- $this->iControl->getClientErrorText());
- }
-
- // Connect finished
- error_log("Server connection succesfully established!");
-
- // Enable service announces
- if (!$this->client->query("DisableServiceAnnounces", false)) {
- trigger_error("Couldn't enable service announces. " . $this->iControl->getClientErrorText());
- }
-
- // Enable script callbacks if needed
- if ($this->server->getGameMode() === 0) {
- if (!$this->client->query('GetModeScriptSettings')) {
- trigger_error("Couldn't get mode script settings. " . $this->iControl->getClientErrorText());
- }
- else {
- $scriptSettings = $this->client->getResponse();
- if (array_key_exists('S_UseScriptCallbacks', $scriptSettings)) {
- $scriptSettings['S_UseScriptCallbacks'] = true;
- if (!$this->client->query('SetModeScriptSettings', $scriptSettings)) {
- trigger_error(
- "Couldn't set mode script settings to enable script callbacks. " . $this->iControl->getClientErrorText());
- }
- else {
- error_log("Script callbacks successfully enabled.");
- }
- }
- }
- }
- }
-
- /**
- * Load ManiaControl plugins
- */
- private function loadPlugins() {
- $pluginsConfig = Tools::loadConfig('plugins.ManiaControl.xml');
- if (!$pluginsConfig || !isset($pluginsConfig->plugin)) {
- trigger_error('Invalid plugins config.');
- return;
- }
-
- // Load plugin classes
- $classes = get_declared_classes();
- foreach ($pluginsConfig->xpath('plugin') as $plugin) {
- $fileName = ManiaControlDir . '/plugins/' . $plugin;
- if (!file_exists($fileName)) {
- trigger_error("Couldn't load plugin '" . $plugin . "'! File doesn't exist. (/plugins/" . $plugin . ")");
- }
- else {
- require_once $fileName;
- error_log("Loading plugin: " . $plugin);
- }
- }
- $plugins = array_diff(get_declared_classes(), $classes);
-
- // Create plugins
- foreach ($plugins as $plugin) {
- $nameIndex = stripos($plugin, 'plugin');
- if ($nameIndex === false) continue;
- array_push($this->plugins, new $plugin($this));
- }
- }
-
- /**
- * Handle EndMap callback
- */
- public function handleEndMap($callback) {
- // Autosave match settings
- $autosaveMatchsettings = $this->config->xpath('autosave_matchsettings');
- if ($autosaveMatchsettings) {
- $autosaveMatchsettings = (string) $autosaveMatchsettings[0];
- if ($autosaveMatchsettings) {
- if (!$this->client->query('SaveMatchSettings', 'MatchSettings/' . $autosaveMatchsettings)) {
- trigger_error("Couldn't autosave match settings. " . $this->iControl->getClientErrorText());
- }
- }
- }
- }
-
- /**
- * Check config settings
- */
- public function checkConfig($config, $settings, $name = 'Config XML') {
- if (!is_array($settings)) $settings = array($settings);
- foreach ($settings as $setting) {
- $settingTags = $config->xpath('//' . $setting);
- if (empty($settingTags)) {
- trigger_error("Missing property '" . $setting . "' in config '" . $name . "'!", E_USER_ERROR);
- }
- }
- }
-}
-
-?>
diff --git a/application/core/database.ManiaControl.php b/application/core/database.ManiaControl.php
deleted file mode 100644
index 57fe8865..00000000
--- a/application/core/database.ManiaControl.php
+++ /dev/null
@@ -1,401 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('database.ManiaControl.xml');
- $this->mControl->checkConfig($this->config, array("host", "user"), 'database.ManiaControl.xml');
-
- // Get mysql server information
- $host = $this->config->xpath('host');
- if (!$host) trigger_error("Invalid database configuration (host).", E_USER_ERROR);
- $host = (string) $host[0];
-
- $port = $this->config->xpath('port');
- if (!$port) trigger_error("Invalid database configuration (port).", E_USER_ERROR);
- $port = (int) $port[0];
-
- $user = $this->config->xpath('user');
- if (!$user) trigger_error("Invalid database configuration (user).", E_USER_ERROR);
- $user = (string) $user[0];
-
- $pass = $this->config->xpath('pass');
- if (!$pass) trigger_error("Invalid database configuration (pass).", E_USER_ERROR);
- $pass = (string) $pass[0];
-
- // Open database connection
- $this->mysqli = new \mysqli($host, $user, $pass, null, $port);
- if ($this->mysqli->connect_error) {
- // Connection error
- throw new \Exception(
- "Error on connecting to mysql server. " . $this->mysqli->connect_error . " (" . $this->mysqli->connect_errno . ")");
- }
-
- // Set charset
- $this->mysqli->set_charset("utf8");
-
- // Create/Connect database
- $this->initDatabase();
-
- // Init tables
- $this->initTables();
-
- // Register for callbacks
- $this->mControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_5_SECOND, $this, 'handle5Second');
- $this->mControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_BEGINMAP, $this, 'handleBeginMap');
- }
-
- /**
- * Destruct database connection
- */
- public function __destruct() {
- $this->mysqli->close();
- }
-
- /**
- * Connect to the defined database (create it if needed)
- */
- private function initDatabase() {
- $dbname = $this->config->xpath('database');
- if (!$dbname) trigger_error("Invalid database configuration (database).", E_USER_ERROR);
- $dbname = (string) $dbname[0];
-
- // Try to connect
- $result = $this->mysqli->select_db($dbname);
- if (!$result) {
- // Create database
- $query = "CREATE DATABASE `" . $this->escape($dbname) . "`;";
- $result = $this->mysqli->query($query);
- if (!$result) {
- trigger_error(
- "Couldn't create database '" . $dbname . "'. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')',
- E_USER_ERROR);
- }
- else {
- // Connect to database
- $result = $this->mysqli->select_db($dbname);
- if (!$result) {
- trigger_error(
- "Couldn't select database '" . $dbname . "'. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')',
- E_USER_ERROR);
- }
- }
- }
- }
-
- /**
- * Create the needed tables
- */
- private function initTables() {
- $query = "";
-
- // Players table
- $query .= "CREATE TABLE IF NOT EXISTS `" . self::TABLE_PLAYERS . "` (
- `index` int(11) NOT NULL AUTO_INCREMENT,
- `Login` varchar(100) NOT NULL,
- `NickName` varchar(250) NOT NULL,
- `PlayerId` int(11) NOT NULL,
- `LadderRanking` int(11) NOT NULL,
- `Flags` varchar(50) NOT NULL,
- `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`index`),
- UNIQUE KEY `Login` (`Login`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store player metadata' AUTO_INCREMENT=1;";
-
- // Maps table
- $query .= "CREATE TABLE IF NOT EXISTS `ic_maps` (
- `index` int(11) NOT NULL AUTO_INCREMENT,
- `UId` varchar(100) NOT NULL,
- `Name` varchar(100) NOT NULL,
- `FileName` varchar(200) NOT NULL,
- `Author` varchar(150) NOT NULL,
- `Environnement` varchar(50) NOT NULL,
- `Mood` varchar(50) NOT NULL,
- `BronzeTime` int(11) NOT NULL DEFAULT '-1',
- `SilverTime` int(11) NOT NULL DEFAULT '-1',
- `GoldTime` int(11) NOT NULL DEFAULT '-1',
- `AuthorTime` int(11) NOT NULL DEFAULT '-1',
- `CopperPrice` int(11) NOT NULL DEFAULT '-1',
- `LapRace` tinyint(1) NOT NULL,
- `NbLaps` int(11) NOT NULL DEFAULT '-1',
- `NbCheckpoints` int(11) NOT NULL DEFAULT '-1',
- `MapType` varchar(100) NOT NULL,
- `MapStyle` varchar(100) NOT NULL,
- `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`index`),
- UNIQUE KEY `UId` (`UId`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store map metadata' AUTO_INCREMENT=1;";
-
- // Perform queries
- if (!$this->multiQuery($query)) {
- trigger_error("Creating basic tables failed. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')', E_USER_ERROR);
- }
-
- // Optimize all existing tables
- $query = "SHOW TABLES;";
- $result = $this->query($query);
- if (!$result || !is_object($result)) {
- trigger_error("Couldn't select tables. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
- }
- else {
- $query = "OPTIMIZE TABLE ";
- $count = $result->num_rows;
- $index = 0;
- while ($row = $result->fetch_row()) {
- $query .= "`" . $row[0] . "`";
- if ($index < $count - 1) $query .= ", ";
- $index++;
- }
- $query .= ";";
- if (!$this->query($query)) {
- trigger_error("Couldn't optimize tables. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
- }
- }
- }
-
- /**
- * Wrapper for performing a simple query
- *
- * @param string $query
- * @return mixed query result
- */
- public function query($query) {
- if (!is_string($query)) return false;
- if (strlen($query) <= 0) return true;
- return $this->mysqli->query($query);
- }
-
- /**
- * Perform multi query
- *
- * @param
- * string multi_query
- * @return bool whether no error occured during executing the multi query
- */
- public function multiQuery($query) {
- if (!is_string($query)) return false;
- if (strlen($query) <= 0) return true;
- $noError = true;
- $this->mysqli->multi_query($query);
- if ($this->mysqli->error) {
- trigger_error("Executing multi query failed. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
- $noError = false;
- }
- while ($this->mysqli->more_results() && $this->mysqli->next_result()) {
- if ($this->mysqli->error) {
- trigger_error("Executing multi query failed. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
- $noError = false;
- }
- }
- return $noError;
- }
-
- /**
- * Handle 5Second callback
- */
- public function handle5Second($callback = null) {
- // Save current players in database
- $players = $this->mControl->server->getPlayers();
- if ($players) {
- $query = "";
- foreach ($players as $player) {
- if (!Tools::isPlayer($player)) continue;
- $query .= $this->composeInsertPlayer($player);
- }
- $this->multiQuery($query);
- }
- }
-
- /**
- * Handle BeginMap callback
- */
- public function handleBeginMap($callback) {
- $map = $callback[1][0];
- $query = $this->composeInsertMap($map);
- $result = $this->query($query);
- if ($this->mysqli->error) {
- trigger_error("Couldn't save map. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
- }
- }
-
- /**
- * Get the player index for the given login
- *
- * @param string $login
- * @return int null
- */
- public function getPlayerIndex($login) {
- $query = "SELECT `index` FROM `" . self::TABLE_PLAYERS . "` WHERE `Login` = '" . $this->escape($login) . "';";
- $result = $this->query($query);
- $result = $result->fetch_assoc();
- if ($result) {
- return $result['index'];
- }
- return null;
- }
-
- /**
- * Get the map index for the given UId
- *
- * @param string $uid
- * @return int null
- */
- public function getMapIndex($uid) {
- $query = "SELECT `index` FROM `" . self::TABLE_MAPS . "` WHERE `UId` = '" . $this->escape($uid) . "';";
- $result = $this->query($query);
- $result = $result->fetch_assoc();
- if ($result) {
- return $result['index'];
- }
- return null;
- }
-
- /**
- * Compose a query string for inserting the given player
- *
- * @param array $player
- */
- private function composeInsertPlayer($player) {
- if (!Tools::isPlayer($player)) return "";
- return "INSERT INTO `" . self::TABLE_PLAYERS . "` (
- `Login`,
- `NickName`,
- `PlayerId`,
- `LadderRanking`,
- `Flags`
- ) VALUES (
- '" . $this->escape($player['Login']) . "',
- '" . $this->escape($player['NickName']) . "',
- " . $player['PlayerId'] . ",
- " . $player['LadderRanking'] . ",
- '" . $this->escape($player['Flags']) . "'
- ) ON DUPLICATE KEY UPDATE
- `NickName` = VALUES(`NickName`),
- `PlayerId` = VALUES(`PlayerId`),
- `LadderRanking` = VALUES(`LadderRanking`),
- `Flags` = VALUES(`Flags`);";
- }
-
- /**
- * Compose a query string for inserting the given map
- *
- * @param array $map
- */
- private function composeInsertMap($map) {
- if (!$map) return "";
- return "INSERT INTO `" . self::TABLE_MAPS . "` (
- `UId`,
- `Name`,
- `FileName`,
- `Author`,
- `Environnement`,
- `Mood`,
- `BronzeTime`,
- `SilverTime`,
- `GoldTime`,
- `AuthorTime`,
- `CopperPrice`,
- `LapRace`,
- `NbLaps`,
- `NbCheckpoints`,
- `MapType`,
- `MapStyle`
- ) VALUES (
- '" . $this->escape($map['UId']) . "',
- '" . $this->escape($map['Name']) . "',
- '" . $this->escape($map['FileName']) . "',
- '" . $this->escape($map['Author']) . "',
- '" . $this->escape($map['Environnement']) . "',
- '" . $this->escape($map['Mood']) . "',
- " . $map['BronzeTime'] . ",
- " . $map['SilverTime'] . ",
- " . $map['GoldTime'] . ",
- " . $map['AuthorTime'] . ",
- " . $map['CopperPrice'] . ",
- " . Tools::boolToInt($map['LapRace']) . ",
- " . $map['NbLaps'] . ",
- " . $map['NbCheckpoints'] . ",
- '" . $this->escape($map['MapType']) . "',
- '" . $this->escape($map['MapStyle']) . "'
- ) ON DUPLICATE KEY UPDATE
- `Name` = VALUES(`Name`),
- `FileName` = VALUES(`FileName`),
- `Author` = VALUES(`Author`),
- `Environnement` = VALUES(`Environnement`),
- `Mood` = VALUES(`Mood`),
- `BronzeTime` = VALUES(`BronzeTime`),
- `SilverTime` = VALUES(`SilverTime`),
- `GoldTime` = VALUES(`GoldTime`),
- `AuthorTime` = VALUES(`AuthorTime`),
- `CopperPrice` = VALUES(`CopperPrice`),
- `LapRace` = VALUES(`LapRace`),
- `NbLaps` = VALUES(`NbLaps`),
- `NbCheckpoints` = VALUES(`NbCheckpoints`),
- `MapType` = VALUES(`MapType`),
- `MapStyle` = VALUES(`MapStyle`);";
- }
-
- /**
- * Retrieve all information about the player with the given login
- */
- public function getPlayer($login) {
- if (!$login) return null;
- $query = "SELECT * FROM `" . self::TABLE_PLAYERS . "` WHERE `Login` = '" . $this->escape($login) . "';";
- $result = $this->mysqli->query($query);
- if ($this->mysqli->error || !$result) {
- trigger_error(
- "Couldn't select player with login '" . $login . "'. " . $this->mysqli->error . ' (' . $this->mysqli->errno . ')');
- return null;
- }
- else {
- while ($player = $result->fetch_assoc()) {
- return $player;
- }
- return null;
- }
- }
-
- /**
- * Escapes the given string for a mysql query
- *
- * @param string $string
- * @return string
- */
- public function escape($string) {
- return $this->mysqli->escape_string($string);
- }
-}
-
-?>
diff --git a/application/core/plugin.php b/application/core/plugin.php
index 1f5c3aa4..8664ff04 100644
--- a/application/core/plugin.php
+++ b/application/core/plugin.php
@@ -14,20 +14,21 @@ namespace ManiaControl;
/**
* Private properties
*/
- private $mControl;
+ private $mc;
private $version;
private $author;
private $updateUrl;
private $name;
+ private $active;
-
-
- public function __construct($mControl, $name, $version = 0, $author = '', $updateUrl = ''){
- $this->mControl = $mControl;
+ public function __construct($mc, $name, $version = 0, $author = '', $updateUrl = ''){
+ $this->mc = $mc;
$this->name = $name;
$this->version = $version;
$this->author = $author;
$this->updateUrl = $updateUrl;
+
+ $this->mc->pluginHandler->registerPlugin($this);
}
/**
@@ -37,13 +38,37 @@ namespace ManiaControl;
* @return array with manialink Ids
*/
public function reserveManialinkIds($count){
- return $this->mControl->manialinkIdHandler->reserveManialikIds($count);
+ return $this->mc->manialinkIdHandler->reserveManialikIds($count);
}
-
+
public function checkUpdate(){
}
+ /**
+ * Enables the Plugin
+ */
+ public function enablePlugin()
+ {
+ $this->active = true;
+ }
+
+ /**
+ * Disable the Plugin
+ */
+ public function disablePlugin()
+ {
+ $this->active = true;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function isActive()
+ {
+ return $this->active;
+ }
+
/**
* @param mixed $author
*/
diff --git a/application/core/pluginHandler.php b/application/core/pluginHandler.php
index 5b5d0f19..850be99a 100644
--- a/application/core/pluginHandler.php
+++ b/application/core/pluginHandler.php
@@ -11,6 +11,19 @@ namespace ManiaControl;
class PluginHandler {
+ /**
+ * Private properties
+ */
+ private $mc;
+ private $plugins;
+ public function __construct($mc){
+ $this->mControl = $mc;
+ $this->plugins = array();
+ }
+
+ public function registerPlugin($plugin){
+ array_push($this->plugins, $plugin);
+ }
}
?>
\ No newline at end of file
diff --git a/application/core/server.ManiaControl.php b/application/core/server.ManiaControl.php
deleted file mode 100644
index 3018bd0e..00000000
--- a/application/core/server.ManiaControl.php
+++ /dev/null
@@ -1,381 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('server.ManiaControl.xml');
- $this->iControl->checkConfig($this->config, array('host', 'port', 'login', 'pass'), 'server');
-
- // Register for callbacks
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_1_SECOND, $this, 'eachSecond');
- }
-
- /**
- * Perform actions every second
- */
- public function eachSecond() {
- // Delete cached information
- $this->players = null;
- }
-
- /**
- * Fetch game directory of the server
- *
- * @return string
- */
- public function getDataDirectory() {
- if (!$this->iControl->client->query('GameDataDirectory')) {
- trigger_error("Couldn't get data directory. " . $this->iControl->getClientErrorText());
- return null;
- }
- return $this->iControl->client->getResponse();
- }
-
- /**
- * Checks if ManiaControl has access to the given directory (server data directory if no param)
- *
- * @param string $directory
- * @return bool
- */
- public function checkAccess($directory = null) {
- if (!$directory) {
- $directory = $this->getDataDirectory();
- }
- return is_dir($directory) && is_writable($directory);
- }
-
- /**
- * Fetch server login
- */
- public function getLogin($client = null) {
- $systemInfo = $this->getSystemInfo(false, $client);
- if (!$systemInfo) return null;
- return $systemInfo['ServerLogin'];
- }
-
- /**
- * Get detailed server info
- */
- public function getInfo($detailed = false) {
- if ($detailed) {
- $login = $this->getLogin();
- if (!$this->iControl->client->query('GetDetailedPlayerInfo', $login)) {
- trigger_error("Couldn't fetch detailed server player info. " . $this->iControl->getClientErrorText());
- return null;
- }
- }
- else {
- if (!$this->iControl->client->query('GetMainServerPlayerInfo')) {
- trigger_error("Couldn't fetch server player info. " . $this->iControl->getClientErrorText());
- return null;
- }
- }
- return $this->iControl->client->getResponse();
- }
-
- /**
- * Get server options
- */
- public function getOptions() {
- if (!$this->iControl->client->query('GetServerOptions')) {
- trigger_error("Couldn't fetch server options. " . $this->iControl->getClientErrorText());
- return null;
- }
- return $this->iControl->client->getResponse();
- }
-
- /**
- * Fetch server name
- */
- public function getName() {
- if (!$this->iControl->client->query('GetServerName')) {
- trigger_error("Couldn't fetch server name. " . $this->iControl->getClientErrorText());
- return null;
- }
- return $this->iControl->client->getResponse();
- }
-
- /**
- * Fetch server version
- */
- public function getVersion($forceRefresh = false) {
- if (isset($this->iControl->client->version) && !$forceRefresh) return $this->iControl->client->version;
- if (!$this->iControl->client->query('GetVersion')) {
- trigger_error("Couldn't fetch server version. " . $this->iControl->getClientErrorText());
- return null;
- }
- else {
- $this->iControl->client->version = $this->iControl->client->getResponse();
- return $this->iControl->client->version;
- }
- }
-
- /**
- * Fetch server system info
- */
- public function getSystemInfo($forceRefresh = false, &$client = null) {
- if (!$this->iControl->client && !$client) return null;
- if (!$client) $client = $this->iControl->client;
- if (isset($client->systemInfo) && !$forceRefresh) return $client->systemInfo;
- if (!$client->query('GetSystemInfo')) {
- trigger_error("Couldn't fetch server system info. " . $this->iControl->getClientErrorText($client));
- return null;
- }
- else {
- $client->systemInfo = $client->getResponse();
- return $client->systemInfo;
- }
- }
-
- /**
- * Fetch network status
- */
- public function getNetworkStats($forceRefresh = false) {
- if (isset($this->iControl->client->networkStats) && !$forceRefresh) return $this->iControl->client->networkStats;
- if (!$this->iControl->client->query('GetNetworkStats')) {
- trigger_error("Couldn't fetch network stats. " . $this->iControl->getClientErrorText());
- return null;
- }
- else {
- $this->iControl->client->networkStats = $this->iControl->client->getResponse();
- return $this->iControl->client->networkStats;
- }
- }
-
- /**
- * Fetch current game mode
- *
- * @param bool $stringValue
- * @param int $parseValue
- * @return int | string
- */
- public function getGameMode($stringValue = false, $parseValue = null) {
- if (is_int($parseValue)) {
- $gameMode = $parseValue;
- }
- else {
- if (!$this->iControl->client->query('GetGameMode')) {
- trigger_error("Couldn't fetch current game mode. " . $this->iControl->getClientErrorText());
- return null;
- }
- $gameMode = $this->iControl->client->getResponse();
- }
- if ($stringValue) {
- switch ($gameMode) {
- case 0:
- {
- return 'Script';
- }
- case 1:
- {
- return 'Rounds';
- }
- case 2:
- {
- return 'TimeAttack';
- }
- case 3:
- {
- return 'Team';
- }
- case 4:
- {
- return 'Laps';
- }
- case 5:
- {
- return 'Cup';
- }
- case 6:
- {
- return 'Stunts';
- }
- default:
- {
- return 'Unknown';
- }
- }
- }
- return $gameMode;
- }
-
- /**
- * Fetch player info
- *
- * @param string $login
- * @return struct
- */
- public function getPlayer($login, $detailed = false) {
- if (!$login) return null;
- $command = ($detailed ? 'GetDetailedPlayerInfo' : 'GetPlayerInfo');
- if (!$this->iControl->client->query($command, $login)) {
- trigger_error("Couldn't player info for '" . $login . "'. " . $this->iControl->getClientErrorText());
- return null;
- }
- return $this->iControl->client->getResponse();
- }
-
- /**
- * Fetch all players
- */
- public function getPlayers(&$client = null, &$purePlayers = null, &$pureSpectators = null) {
- if (!$this->iControl->client && !$client) return null;
- if (!$client) $client = $this->iControl->client;
- $fetchLength = 30;
- $offset = 0;
- $players = array();
- if (!is_array($purePlayers)) $purePlayers = array();
- if (!is_array($pureSpectators)) $pureSpectators = array();
- $tries = 0;
- while ($tries < 10) {
- if (!$client->query('GetPlayerList', $fetchLength, $offset)) {
- trigger_error("Couldn't get player list. " . $this->iControl->getClientErrorText($client));
- $tries++;
- }
- else {
- $chunk = $client->getResponse();
- $count = count($chunk);
- $serverLogin = $this->getLogin($client);
- for ($index = 0; $index < $count; $index++) {
- $login = $chunk[$index]['Login'];
- if ($login === $serverLogin) {
- // Ignore server
- unset($chunk[$index]);
- }
- else {
- if ($chunk[$index]['SpectatorStatus'] > 0) {
- // Pure spectator
- array_push($pureSpectators, $chunk[$index]);
- }
- else {
- // Pure player
- array_push($purePlayers, $chunk[$index]);
- }
- }
- }
- $players = array_merge($players, $chunk);
- $offset += $count;
- if ($count < $fetchLength) break;
- }
- }
- return $players;
- }
-
- /**
- * Retrieve validation replay for given login
- *
- * @param string $login
- * @return string
- */
- public function getValidationReplay($login) {
- if (!$login) return null;
- if (!$this->iControl->client->query('GetValidationReplay', $login)) {
- trigger_error("Couldn't get validation replay of '" . $login . "'. " . $this->iControl->getClientErrorText());
- return null;
- }
- return $this->iControl->client->getResponse();
- }
-
- public function getGhostReplay($login) {
- $dataDir = $this->getDataDirectory();
- if (!$this->checkAccess($dataDir)) {
- return null;
- }
-
- // Build file name
- $map = $this->getMap();
- $gameMode = $this->getGameMode();
- $time = time();
- $fileName = 'Ghost.' . $login . '.' . $gameMode . '.' . $time . '.' . $map['UId'] . '.Replay.Gbx';
-
- // Save ghost replay
- if (!$this->iControl->client->query('SaveBestGhostsReplay', $login, self::GHOSTREPLAYDIR . $fileName)) {
- trigger_error("Couldn't save ghost replay. " . $this->iControl->getClientErrorText());
- return null;
- }
-
- // Load replay file
- $ghostReplay = file_get_contents($dataDir . 'Replays/' . self::GHOSTREPLAYDIR . $fileName);
- if (!$ghostReplay) {
- trigger_error("Couldn't retrieve saved ghost replay.");
- return null;
- }
- return $ghostReplay;
- }
-
- /**
- * Fetch current map
- */
- public function getMap() {
- if (!$this->iControl->client) return null;
- if (!$this->iControl->client->query('GetCurrentMapInfo')) {
- trigger_error("Couldn't fetch map info. " . $this->iControl->getClientErrorText());
- return null;
- }
- return $this->iControl->client->getResponse();
- }
-
- /**
- * Waits for the server to have the given status
- */
- public function waitForStatus($client, $statusCode = 4) {
- $client->query('GetStatus');
- $response = $client->getResponse();
- // Check if server reached given status
- if ($response['Code'] === 4) return true;
- // Server not yet in given status -> Wait for it...
- $waitBegin = time();
- $timeoutTags = $this->iControl->config->xpath('timeout');
- $maxWaitTime = (!empty($timeoutTags) ? (int) $timeoutTags[0] : 20);
- $lastStatus = $response['Name'];
- error_log("Waiting for server to reach status " . $statusCode . "...");
- error_log("Current Status: " . $lastStatus);
- while ($response['Code'] !== 4) {
- sleep(1);
- $client->query('GetStatus');
- $response = $client->getResponse();
- if ($lastStatus !== $response['Name']) {
- error_log("New Status: " . $response['Name']);
- $lastStatus = $response['Name'];
- }
- if (time() - $maxWaitTime > $waitBegin) {
- // It took too long to reach the status
- trigger_error(
- "Server couldn't reach status " . $statusCode . " after " . $maxWaitTime . " seconds! " .
- $this->iControl->getClientErrorText());
- return false;
- }
- }
- return true;
- }
-}
-
-?>
diff --git a/application/core/stats.ManiaControl.php b/application/core/stats.ManiaControl.php
deleted file mode 100644
index 8a5e7c52..00000000
--- a/application/core/stats.ManiaControl.php
+++ /dev/null
@@ -1,297 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('stats.ManiaControl.xml');
- $this->loadSettings();
-
- // Init database tables
- $this->initTables();
-
- // Register for needed callbacks
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_ENDMAP, $this, 'handleEndMap');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCHAT, $this, 'handlePlayerChat');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCONNECT, $this, 'handlePlayerConnect');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_TM_PLAYERFINISH, $this, 'handlePlayerFinish');
- }
-
- /**
- * Create the database tables
- */
- private function initTables() {
- $query = "";
-
- // Server stats
- $query .= "CREATE TABLE IF NOT EXISTS `" . self::TABLE_STATS_SERVER . "` (
- `index` int(11) NOT NULL AUTO_INCREMENT,
- `day` date NOT NULL,
- `connectCount` int(11) NOT NULL DEFAULT '0',
- `maxPlayerCount` int(11) NOT NULL DEFAULT '0',
- `playedMaps` int(11) NOT NULL DEFAULT '0',
- `finishCount` int(11) NOT NULL DEFAULT '0',
- `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`index`),
- UNIQUE KEY `day` (`day`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stores server stats' AUTO_INCREMENT=1;";
-
- // Player stats
- $query .= "CREATE TABLE IF NOT EXISTS `" . self::TABLE_STATS_PLAYERS . "` (
- `index` int(11) NOT NULL AUTO_INCREMENT,
- `Login` varchar(100) NOT NULL,
- `playTime` int(11) NOT NULL DEFAULT '0',
- `connectCount` int(11) NOT NULL DEFAULT '0',
- `chatCount` int(11) NOT NULL DEFAULT '0',
- `finishCount` int(11) NOT NULL DEFAULT '0',
- `hitCount` int(11) NOT NULL DEFAULT '0',
- `eliminationCount` int(11) NOT NULL DEFAULT '0',
- `lastJoin` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`index`),
- UNIQUE KEY `Login` (`Login`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Tracks player stats' AUTO_INCREMENT=1;";
-
- // Perform queries
- if (!$this->iControl->database->multiQuery($query)) {
- trigger_error("Creating stats tables failed.");
- }
- }
-
- /**
- * Load settings from config
- */
- private function loadSettings() {
- $this->settings = new \stdClass();
-
- $this->settings->track_server_connects = Tools::checkSetting($this->config, 'track_server_connects');
- $this->settings->track_server_max_players = Tools::checkSetting($this->config, 'track_server_max_players');
- $this->settings->track_server_played_maps = Tools::checkSetting($this->config, 'track_server_played_maps');
- $this->settings->track_server_finishes = Tools::checkSetting($this->config, 'track_server_finishes');
-
- $this->settings->track_player_connects = Tools::checkSetting($this->config, 'track_player_connects');
- $this->settings->track_player_playtime = Tools::checkSetting($this->config, 'track_player_playtime');
- $this->settings->track_player_chats = Tools::checkSetting($this->config, 'track_player_chats');
- $this->settings->track_player_finishes = Tools::checkSetting($this->config, 'track_player_finishes');
- }
-
- /**
- * Handle EndMap callback
- */
- public function handleEndMap($callback) {
- $multiquery = "";
-
- // Track played server maps
- if ($this->settings->track_server_played_maps) {
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
- `day`,
- `playedMaps`
- ) VALUES (
- CURDATE(),
- 1
- ) ON DUPLICATE KEY UPDATE
- `playedMaps` = `playedMaps` + VALUES(`playedMaps`)
- ;";
- }
-
- // Perform query
- if (!$this->iControl->database->multiQuery($multiquery)) {
- trigger_error("Perform queries on end map failed.");
- }
- }
-
- /**
- * Handle PlayerChat callback
- */
- public function handlePlayerChat($callback) {
- if ($callback[1][0] <= 0) return;
- $multiquery = "";
- $login = $callback[1][1];
-
- // Track chats
- if ($this->settings->track_player_chats) {
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
- `Login`,
- `chatCount`
- ) VALUES (
- '" . $this->iControl->database->escape($login) . "',
- 1
- ) ON DUPLICATE KEY UPDATE
- `chatCount` = `chatCount` + VALUES(`chatCount`)
- ;";
- }
-
- // Perform query
- if (!$this->iControl->database->multiQuery($multiquery)) {
- trigger_error("Perform queries on player chat failed.");
- }
- }
-
- /**
- * Handle PlayerConnect callback
- */
- public function handlePlayerConnect($callback) {
- $multiquery = "";
- $login = $callback[1][0];
-
- // Track server connect
- if ($this->settings->track_server_connects) {
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
- `day`,
- `connectCount`
- ) VALUES (
- CURDATE(),
- 1
- ) ON DUPLICATE KEY UPDATE
- `connectCount` = `connectCount` + VALUES(`connectCount`)
- ;";
- }
-
- // Track server max players
- if ($this->settings->track_server_max_players) {
- $players = $this->iControl->server->getPlayers();
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
- `day`,
- `maxPlayerCount`
- ) VALUES (
- CURDATE(),
- " . count($players) . "
- ) ON DUPLICATE KEY UPDATE
- `maxPlayerCount` = GREATEST(`maxPlayerCount`, VALUES(`maxPlayerCount`))
- ;";
- }
-
- // Track player connect
- if ($this->settings->track_player_connects) {
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
- `Login`,
- `lastJoin`,
- `connectCount`
- ) VALUES (
- '" . $this->iControl->database->escape($login) . "',
- NOW(),
- 1
- ) ON DUPLICATE KEY UPDATE
- `lastJoin` = VALUES(`lastJoin`),
- `connectCount` = `connectCount` + VALUES(`connectCount`)
- ;";
- }
-
- // Perform query
- if (!$this->iControl->database->multiQuery($multiquery)) {
- trigger_error("Perform queries on player connect failed.");
- }
- }
-
- /**
- * Handle PlayerDisconnect callback
- */
- public function handlePlayerDisconnect($callback) {
- $multiquery = "";
- $login = $callback[1][0];
-
- // Track player playtime
- if ($this->settings->track_player_playtime) {
- $query = "SELECT `lastJoin` FROM `" . self::TABLE_STATS_PLAYERS . "`
- WHERE `Login` = '" . $this->iControl->database->escape($login) . "'
- ;";
- $result = $this->iControl->database->query($query);
- if (!$result) {
- // Error
- trigger_error("Error selecting player join time from '" . $login . "'.");
- }
- else {
- // Add play time
- while ($row = $result->fetch_object()) {
- if (!property_exists($row, 'lastJoin')) continue;
- $lastJoin = strtotime($row->lastJoin);
- $lastJoin = ($lastJoin > $this->iControl->startTime ? $lastJoin : $this->iControl->startTime);
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
- `Login`,
- `playTime`
- ) VALUES (
- '" . $this->iControl->database->escape($login) . "',
- TIMESTAMPDIFF(SECOND, '" . Tools::timeToTimestamp($lastJoin) . "', NOW())
- ) ON DUPLICATE KEY UPDATE
- `playTime` = `playTime` + VALUES(`playTime`)
- ;";
- break;
- }
- }
- }
-
- // Perform query
- if (!$this->iControl->database->multiQuery($multiquery)) {
- trigger_error("Perform queries on player connect failed.");
- }
- }
-
- /**
- * Handle the PlayerFinish callback
- */
- public function handlePlayerFinish($callback) {
- if ($callback[1][0] <= 0) return;
- if ($callback[1][2] <= 0) return;
-
- $multiquery = "";
- $login = $callback[1][1];
-
- // Track server finishes
- if ($this->settings->track_server_finishes) {
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_SERVER . "` (
- `day`,
- `finishCount`
- ) VALUES (
- CURDATE(),
- 1
- ) ON DUPLICATE KEY UPDATE
- `finishCount` = `finishCount` + VALUES(`finishCount`)
- ;";
- }
-
- // Track player finishes
- if ($this->settings->track_player_finishes) {
- $multiquery .= "INSERT INTO `" . self::TABLE_STATS_PLAYERS . "` (
- `Login`,
- `finishCount`
- ) VALUES (
- '" . $this->iControl->database->escape($login) . "',
- 1
- ) ON DUPLICATE KEY UPDATE
- `finishCount` = `finishCount` + VALUES(`finishCount`)
- ;";
- }
-
- // Perform query
- if (!$this->iControl->database->multiQuery($multiquery)) {
- trigger_error("Perform queries on player finish failed.");
- }
- }
-}
-
-?>
diff --git a/application/core/tools.ManiaControl.php b/application/core/tools.ManiaControl.php
deleted file mode 100644
index 76d959b7..00000000
--- a/application/core/tools.ManiaControl.php
+++ /dev/null
@@ -1,240 +0,0 @@
-xpath('//' . $setting);
- if (empty($settings)) {
- return false;
- }
- else {
- foreach ($settings as $setting) {
- return self::toBool((string) $setting[0]);
- }
- }
- }
-
- /**
- * Check if the given data describes a player
- *
- * @param array $player
- * @return bool
- */
- public static function isPlayer($player) {
- if (!$player || !is_array($player)) return false;
- if (!array_key_exists('PlayerId', $player) || !is_int($player['PlayerId']) || $player['PlayerId'] <= 0) return false;
- return true;
- }
-
- /**
- * Convert the given time int to mysql timestamp
- *
- * @param int $time
- * @return string
- */
- public static function timeToTimestamp($time) {
- return date("Y-m-d H:i:s", $time);
- }
-
- /**
- * Add alignment attributes to an xml element
- *
- * @param simple_xml_element $xml
- * @param string $halign
- * @param string $valign
- */
- public static function addAlignment($xml, $halign = 'center', $valign = 'center2') {
- if (!is_object($xml) || !method_exists($xml, 'addAttribute')) return;
- if (!property_exists($xml, 'halign')) $xml->addAttribute('halign', $halign);
- if (!property_exists($xml, 'valign')) $xml->addAttribute('valign', $valign);
- }
-
- /**
- * Add translate attribute to an xml element
- *
- * @param simple_xml_element $xml
- * @param bool $translate
- */
- public static function addTranslate($xml, $translate = true) {
- if (!is_object($xml) || !method_exists($xml, 'addAttribute')) return;
- if (!property_exists($xml, 'translate')) $xml->addAttribute('translate', ($translate ? 1 : 0));
- }
-
- /**
- * Load a remote file
- *
- * @param string $url
- * @return string || null
- */
- public static function loadFile($url) {
- if (!$url) return false;
- $urlData = parse_url($url);
- $port = (isset($urlData['port']) ? $urlData['port'] : 80);
-
- $fsock = fsockopen($urlData['host'], $port);
- stream_set_timeout($fsock, 3);
-
- $query = 'GET ' . $urlData['path'] . ' HTTP/1.0' . PHP_EOL;
- $query .= 'Host: ' . $urlData['host'] . PHP_EOL;
- $query .= 'Content-Type: UTF-8' . PHP_EOL;
- $query .= 'User-Agent: ManiaControl v' . ManiaControl::VERSION . PHP_EOL;
- $query .= PHP_EOL;
-
- fwrite($fsock, $query);
-
- $buffer = '';
- $info = array('timed_out' => false);
- while (!feof($fsock) && !$info['timed_out']) {
- $buffer .= fread($fsock, 1024);
- $info = stream_get_meta_data($fsock);
- }
- fclose($fsock);
-
- if ($info['timed_out'] || !$buffer) {
- return null;
- }
- if (substr($buffer, 9, 3) != "200") {
- return null;
- }
-
- $result = explode("\r\n\r\n", $buffer, 2);
-
- if (count($result) < 2) {
- return null;
- }
-
- return $result[1];
- }
-
- /**
- * Formats the given time (milliseconds)
- *
- * @param int $time
- * @return string
- */
- public static function formatTime($time) {
- if (!is_int($time)) $time = (int) $time;
- $milliseconds = $time % 1000;
- $seconds = floor($time / 1000);
- $minutes = floor($seconds / 60);
- $hours = floor($minutes / 60);
- $minutes -= $hours * 60;
- $seconds -= $hours * 60 + $minutes * 60;
- $format = ($hours > 0 ? $hours . ':' : '');
- $format .= ($hours > 0 && $minutes < 10 ? '0' : '') . $minutes . ':';
- $format .= ($seconds < 10 ? '0' : '') . $seconds . ':';
- $format .= ($milliseconds < 100 ? '0' : '') . ($milliseconds < 10 ? '0' : '') . $milliseconds;
- return $format;
- }
-
- /**
- * Convert given data to real boolean
- *
- * @param
- * mixed data
- */
- public static function toBool($var) {
- if ($var === true) return true;
- if ($var === false) return false;
- if ($var === null) return false;
- if (is_object($var)) {
- $var = (string) $var;
- }
- if (is_int($var)) {
- return ($var > 0);
- }
- else if (is_string($var)) {
- $text = strtolower($var);
- if ($text === 'true' || $text === 'yes') {
- return true;
- }
- else if ($text === 'false' || $text === 'no') {
- return false;
- }
- else {
- return ((int) $text > 0);
- }
- }
- else {
- return (bool) $var;
- }
- }
-
- /**
- * Converts the given boolean to an int representation
- *
- * @param bool $bool
- * @return int
- */
- public static function boolToInt($bool) {
- return ($bool ? 1 : 0);
- }
-
- /**
- * Build new simple xml element
- *
- * @param string $name
- * @param string $id
- * @return \SimpleXMLElement
- */
- public static function newManialinkXml($id = null) {
- $xml = new \SimpleXMLElement('');
- $xml->addAttribute('version', '1');
- if ($id) $xml->addAttribute('id', $id);
- return $xml;
- }
-
- /**
- * Load config xml-file
- *
- * @param string $fileName
- * @return \SimpleXMLElement
- */
- public static function loadConfig($fileName) {
- // Load config file from configs folder
- $fileLocation = ManiaControlDir . '/configs/' . $fileName;
- if (!file_exists($fileLocation)) {
- trigger_error("Config file doesn't exist! (" . $fileName . ")", E_USER_ERROR);
- }
- return simplexml_load_file($fileLocation);
- }
-
- /**
- * Send the given manialink to players
- *
- * @param string $manialink
- * @param array $logins
- */
- public static function sendManialinkPage($client, $manialink, $logins = null, $timeout = 0, $hideOnClick = false) {
- if (!$client || !$manialink) return;
- if (!$logins) {
- // Send manialink to all players
- $client->query('SendDisplayManialinkPage', $manialink, $timeout, $hideOnClick);
- }
- else if (is_array($logins)) {
- // Send manialink to players
- foreach ($logins as $login) {
- $client->query('SendDisplayManialinkPageToLogin', $login, $manialink, $timeout, $hideOnClick);
- }
- }
- else if (is_string($logins)) {
- // Send manialink to player
- $client->query('SendDisplayManialinkPageToLogin', $logins, $manialink, $timeout, $hideOnClick);
- }
- }
-}
-
-?>
diff --git a/application/plugins/chatlog.plugin.php b/application/plugins/chatlog.plugin.php
deleted file mode 100644
index 8b77449b..00000000
--- a/application/plugins/chatlog.plugin.php
+++ /dev/null
@@ -1,85 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('chatlog.plugin.xml');
-
- // Check for enabled setting
- if (!Tools::toBool($this->config->enabled)) return;
-
- // Load settings
- $this->loadSettings();
-
- // Register for callbacksc
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCHAT, $this, 'handlePlayerChatCallback');
-
- error_log('Chatlog Pugin v' . self::VERSION . ' ready!');
- }
-
- /**
- * Load settings from config
- */
- private function loadSettings() {
- $this->settings = new \stdClass();
-
- // File name
- $fileName = (string) $this->config->filename;
- $this->settings->fileName = ManiaControlDir . '/' . $fileName;
-
- // log_server_messages
- $log_server_messages = $this->config->xpath('log_server_messages');
- $this->settings->log_server_messages = ($log_server_messages ? (Tools::toBool($log_server_messages[0])) : false);
- }
-
- /**
- * Handle PlayerChat callback
- */
- public function handlePlayerChatCallback($callback) {
- $data = $callback[1];
- if ($data[0] <= 0 && !$this->settings->log_server_messages) {
- // Skip server message
- return;
- }
- $this->logText($data[2], $data[1]);
- }
-
- /**
- * Log the given message
- *
- * @param string $message
- * @param string $login
- */
- private function logText($text, $login = null) {
- $message = date(ManiaControl::DATE) . '>> ' . ($login ? $login . ': ' : '') . $text . PHP_EOL;
- file_put_contents($this->settings->fileName, $message, FILE_APPEND);
- }
-}
-
-?>
diff --git a/application/plugins/karma.plugin.php b/application/plugins/karma.plugin.php
deleted file mode 100644
index 26b5cf91..00000000
--- a/application/plugins/karma.plugin.php
+++ /dev/null
@@ -1,305 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('karma.plugin.xml');
- if (!Tools::toBool($this->config->enabled)) return;
-
- // Init database
- $this->initDatabase();
-
- // Register for callbacks
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_ONINIT, $this, 'handleOnInitCallback');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_BEGINMAP, $this, 'handleBeginMapCallback');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCONNECT, $this, 'handlePlayerConnectCallback');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERMANIALINKPAGEANSWER, $this,
- 'handleManialinkPageAnswerCallback');
-
- error_log('Karma Pugin v' . self::VERSION . ' ready!');
- }
-
- /**
- * Repetitive actions
- */
- public function loop() {
- if ($this->sendManialinkRequested > 0 && $this->sendManialinkRequested <= time()) {
- $this->sendManialinkRequested = -1;
-
- // Send manialink to all players
- $players = $this->iControl->server->getPlayers();
- foreach ($players as $player) {
- $login = $player['Login'];
- $manialink = $this->buildManialink($login);
- if (!$manialink) {
- // Skip and retry
- $this->sendManialinkRequested = time() + 5;
- continue;
- }
- Tools::sendManialinkPage($this->iControl->client, $manialink->asXml(), $login);
- }
- }
- }
-
- /**
- * Handle OnInit ManiaControl callback
- *
- * @param array $callback
- */
- public function handleOnInitCallback($callback) {
- // Send manialink to all players once
- $this->sendManialinkRequested = time() + 3;
- }
-
- /**
- * Handle ManiaControl BeginMap callback
- *
- * @param array $callback
- */
- public function handleBeginMapCallback($callback) {
- // Send manialink to all players once
- $this->sendManialinkRequested = time() + 2;
- }
-
- /**
- * Handle PlayerConnect callback
- *
- * @param array $callback
- */
- public function handlePlayerConnectCallback($callback) {
- $login = $callback[1][0];
- $manialink = $this->buildManialink($login);
- if (!$manialink) return;
- Tools::sendManialinkPage($this->iControl->client, $manialink->asXml(), $login);
- }
-
- /**
- * Create necessary tables
- */
- private function initDatabase() {
- $query = "CREATE TABLE IF NOT EXISTS `" . self::TABLE_KARMA . "` (
- `index` int(11) NOT NULL AUTO_INCREMENT,
- `mapIndex` int(11) NOT NULL,
- `playerIndex` int(11) NOT NULL,
- `vote` tinyint(1) NOT NULL,
- `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`index`),
- UNIQUE KEY `player_map_vote` (`mapIndex`, `playerIndex`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Save players map votes' AUTO_INCREMENT=1;";
- $result = $this->iControl->database->query($query);
- if ($this->iControl->database->mysqli->error) {
- trigger_error('MySQL Error on creating karma table. ' . $this->iControl->database->mysqli->error, E_USER_ERROR);
- }
- }
-
- /**
- * Handle ManialinkPageAnswer callback
- *
- * @param array $callback
- */
- public function handleManialinkPageAnswerCallback($callback) {
- $action = $callback[1][2];
- if (substr($action, 0, strlen(self::MLID_KARMA)) !== self::MLID_KARMA) return;
-
- // Get vote
- $action = substr($action, -4);
- $vote = null;
- switch ($action) {
- case '.pos':
- {
- $vote = 1;
- break;
- }
- case '.neu':
- {
- $vote = 0;
- break;
- }
- case '.neg':
- {
- $vote = -1;
- break;
- }
- default:
- {
- return;
- }
- }
-
- // Save vote
- $login = $callback[1][1];
- $playerIndex = $this->iControl->database->getPlayerIndex($login);
- $map = $this->iControl->server->getMap();
- $mapIndex = $this->iControl->database->getMapIndex($map['UId']);
- $query = "INSERT INTO `" . self::TABLE_KARMA . "` (
- `mapIndex`,
- `playerIndex`,
- `vote`
- ) VALUES (
- " . $mapIndex . ",
- " . $playerIndex . ",
- " . $vote . "
- ) ON DUPLICATE KEY UPDATE
- `vote` = VALUES(`vote`);";
- $result = $this->iControl->database->query($query);
- if (!$result) return;
-
- // Send success message
- $this->iControl->chat->sendSuccess('Vote successfully updated!', $login);
-
- // Send updated manialink
- $this->sendManialinkRequested = time() + 1;
- }
-
- /**
- * Build karma voting manialink xml for the given login
- */
- private function buildManialink($login) {
- // Get config
- $title = (string) $this->config->title;
- $pos_x = (float) $this->config->pos_x;
- $pos_y = (float) $this->config->pos_y;
-
- $mysqli = $this->iControl->database->mysqli;
-
- // Get indezes
- $playerIndex = $this->iControl->database->getPlayerIndex($login);
- if ($playerIndex === null) return null;
- $map = $this->iControl->server->getMap();
- if (!$map) return null;
- $mapIndex = $this->iControl->database->getMapIndex($map['UId']);
- if ($mapIndex === null) return null;
-
- // Get votings
- $query = "SELECT
- (SELECT `vote` FROM `" .
- self::TABLE_KARMA . "` WHERE `mapIndex` = " . $mapIndex . " AND `playerIndex` = " . $playerIndex . ") as `playerVote`,
- (SELECT COUNT(`vote`) FROM `" .
- self::TABLE_KARMA . "` WHERE `mapIndex` = " . $mapIndex . " AND `vote` = 1) AS `positiveVotes`,
- (SELECT COUNT(`vote`) FROM `" .
- self::TABLE_KARMA . "` WHERE `mapIndex` = " . $mapIndex . " AND `vote` = 0) AS `neutralVotes`,
- (SELECT COUNT(`vote`) FROM `" .
- self::TABLE_KARMA . "` WHERE `mapIndex` = " . $mapIndex . " AND `vote` = -1) AS `negativeVotes`
- FROM `" . self::TABLE_KARMA . "`;";
- $result = $mysqli->query($query);
- if ($mysqli->error) {
- trigger_error('MySQL ERROR: ' . $mysqli->error);
- }
- $votes = $result->fetch_assoc();
- if (!$votes) {
- $votes = array('playerVote' => null, 'positiveVotes' => 0, 'neutralVotes' => 0, 'negativeVotes' => 0);
- }
-
- // Build manialink
- $xml = Tools::newManialinkXml(self::MLID_KARMA);
-
- $frameXml = $xml->addChild('frame');
- $frameXml->addAttribute('posn', $pos_x . ' ' . $pos_y);
-
- // Title
- $labelXml = $frameXml->addChild('label');
- Tools::addAlignment($labelXml);
- $labelXml->addAttribute('posn', '0 4.5 -1');
- $labelXml->addAttribute('sizen', '22 0');
- $labelXml->addAttribute('style', 'TextTitle1');
- $labelXml->addAttribute('textsize', '1');
- $labelXml->addAttribute('text', $title);
-
- // Background
- $quadXml = $frameXml->addChild('quad');
- Tools::addAlignment($quadXml);
- $quadXml->addAttribute('sizen', '23 15 -2');
- $quadXml->addAttribute('style', 'Bgs1InRace');
- $quadXml->addAttribute('substyle', 'BgTitleShadow');
-
- // Votes
- for ($i = 1; $i >= -1; $i--) {
- $x = $i * 7.;
-
- // Vote button
- $quadXml = $frameXml->addChild('quad');
- Tools::addAlignment($quadXml);
- $quadXml->addAttribute('posn', $x . ' 0 0');
- $quadXml->addAttribute('sizen', '6 6');
- $quadXml->addAttribute('style', 'Icons64x64_1');
-
- // Vote count
- $labelXml = $frameXml->addChild('label');
- Tools::addAlignment($labelXml);
- $labelXml->addAttribute('posn', $x . ' -4.5 0');
- $labelXml->addAttribute('style', 'TextTitle1');
- $labelXml->addAttribute('textsize', '2');
-
- if ((string) $i === $votes['playerVote']) {
- // Player vote X
- $voteQuadXml = $frameXml->addChild('quad');
- Tools::addAlignment($voteQuadXml);
- $voteQuadXml->addAttribute('posn', $x . ' 0 1');
- $voteQuadXml->addAttribute('sizen', '6 6');
- $voteQuadXml->addAttribute('style', 'Icons64x64_1');
- $voteQuadXml->addAttribute('substyle', 'Close');
- }
-
- switch ($i) {
- case 1:
- {
- // Positive
- $quadXml->addAttribute('substyle', 'LvlGreen');
- $quadXml->addAttribute('action', self::MLID_KARMA . '.pos');
- $labelXml->addAttribute('text', $votes['positiveVotes']);
- break;
- }
- case 0:
- {
- // Neutral
- $quadXml->addAttribute('substyle', 'LvlYellow');
- $quadXml->addAttribute('action', self::MLID_KARMA . '.neu');
- $labelXml->addAttribute('text', $votes['neutralVotes']);
- break;
- }
- case -1:
- {
- // Negative
- $quadXml->addAttribute('substyle', 'LvlRed');
- $quadXml->addAttribute('action', self::MLID_KARMA . '.neg');
- $labelXml->addAttribute('text', $votes['negativeVotes']);
- break;
- }
- }
- }
-
- return $xml;
- }
-}
-
-?>
diff --git a/application/plugins/obstacle.plugin.php b/application/plugins/obstacle.plugin.php
deleted file mode 100644
index 0084b486..00000000
--- a/application/plugins/obstacle.plugin.php
+++ /dev/null
@@ -1,63 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('obstacle.plugin.xml');
-
- // Check for enabled setting
- if (!Tools::toBool($this->config->enabled)) return;
-
- // Register for jump command
- $this->iControl->commands->registerCommandHandler('jumpto', $this, 'command_jumpto');
-
- error_log('Obstacle Pugin v' . self::VERSION . ' ready!');
- }
-
- /**
- * Handle jumpto command
- */
- public function command_jumpto($chat) {
- $login = $chat[1][1];
- $rightLevel = (string) $this->config->jumps_rightlevel;
- if (!$this->iControl->authentication->checkRight($login, $rightLevel)) {
- // Not allowed
- $this->iControl->authentication->sendNotAllowed($login);
- }
- else {
- // Send jump callback
- $params = explode(' ', $chat[1][2], 2);
- $param = $login . ";" . $params[1] . ";";
- if (!$this->iControl->client->query('TriggerModeScriptEvent', self::CB_JUMPTO, $param)) {
- trigger_error("Couldn't send jump callback for '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
- }
-}
-
-?>
diff --git a/application/plugins/plugin.ManiaControl.php b/application/plugins/plugin.ManiaControl.php
deleted file mode 100644
index a51d9066..00000000
--- a/application/plugins/plugin.ManiaControl.php
+++ /dev/null
@@ -1,37 +0,0 @@
-mControl = $mControl;
-
- error_log('Pugin v' . self::VERSION . ' ready!');
- }
-
- /**
- * Perform actions during each loop
- */
- public function loop() {
- }
-}
-
-?>
diff --git a/application/plugins/records.plugin.php b/application/plugins/records.plugin.php
deleted file mode 100644
index 71dbbefd..00000000
--- a/application/plugins/records.plugin.php
+++ /dev/null
@@ -1,1216 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('records.plugin.xml');
-
- // Check for enabled setting
- if (!Tools::toBool($this->config->enabled)) return;
-
- // Load settings
- $this->loadSettings();
-
- // Init tables
- $this->initTables();
-
- // Register for callbacks
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_ONINIT, $this, 'handleOnInit');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_1_SECOND, $this, 'handle1Second');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_1_MINUTE, $this, 'handle1Minute');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_3_MINUTE, $this, 'handle3Minute');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_BEGINMAP, $this, 'handleMapBegin');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_CLIENTUPDATED, $this, 'handleClientUpdated');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_ENDMAP, $this, 'handleMapEnd');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCONNECT, $this, 'handlePlayerConnect');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_TM_PLAYERFINISH, $this, 'handlePlayerFinish');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_TM_PLAYERCHECKPOINT, $this, 'handlePlayerCheckpoint');
-
- error_log('Records Pugin v' . self::VERSION . ' ready!');
- }
-
- /**
- * Init needed database tables
- */
- private function initTables() {
- $database = $this->iControl->database;
-
- // Records table
- $query = "CREATE TABLE IF NOT EXISTS `" . self::TABLE_RECORDS . "` (
- `index` int(11) NOT NULL AUTO_INCREMENT,
- `mapUId` varchar(100) NOT NULL,
- `Login` varchar(100) NOT NULL,
- `time` int(11) NOT NULL,
- `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`index`),
- UNIQUE KEY `player_map_record` (`mapUId`,`Login`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;";
- if (!$database->query($query)) {
- trigger_error("Couldn't create records table. " . $database->mysqli->error);
- }
- }
-
- /**
- * Load settings from config
- */
- private function loadSettings() {
- $this->settings = new \stdClass();
-
- $this->settings->enabled = Tools::toBool($this->config->enabled);
-
- $this->settings->local_records_enabled = $this->settings->enabled && Tools::toBool($this->config->local_records->enabled);
- $this->settings->dedimania_enabled = $this->settings->enabled && Tools::toBool($this->config->dedimania_records->enabled);
- }
-
- /**
- * Handle ManiaControl init
- */
- public function handleOnInit($callback = null) {
- // Let manialinks update
- if ($this->settings->local_records_enabled) {
- $this->updateManialinks[self::MLID_LOCAL] = true;
- }
-
- // Update mapinfo
- $this->mapInfo = $this->getMapInfo();
-
- if ($this->settings->dedimania_enabled) {
- // Open dedimania session
- $accounts = $this->config->xpath('dedimania_records/account');
- if (!$accounts) {
- trigger_error('Invalid dedimania_code in config.');
- $this->settings->dedimania_enabled = false;
- }
- else {
- $this->openDedimaniaSession();
- }
- $this->fetchDedimaniaRecords();
- $this->updateManialinks[self::MLID_DEDI] = true;
- }
- }
-
- /**
- * Fetch dedimania records of the current map
- */
- private function fetchDedimaniaRecords($reset = true) {
- if (!isset($this->dedimaniaData['context'])) return false;
- if ($reset || !isset($this->dedimaniaData['records']) && !is_array($this->dedimaniaData['records'])) {
- // Reset records
- $this->dedimaniaData['records'] = array();
- }
-
- // Fetch records
- $servInfo = $this->getSrvInfo();
- $playerInfo = $this->getPlayerList();
- $gameMode = $this->getGameModeString();
- $data = array($this->dedimaniaData['sessionId'], $this->mapInfo, $gameMode, $servInfo, $playerInfo);
- $request = $this->encode_request(self::DEDIMANIA_GETRECORDS, $data);
- stream_context_set_option($this->dedimaniaData['context'], 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $this->dedimaniaData['context']);
-
- // Handle response
- $response = $this->decode($file);
- if (is_array($response)) {
- foreach ($response as $index => $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- return false;
- }
- else if ($index <= 0) {
- $responseData = $methodResponse[0];
- $this->dedimaniaData['records'] = $responseData;
- }
- }
- }
- return true;
- }
-
- /**
- * Checks dedimania session
- */
- private function checkDedimaniaSession() {
- if (!$this->settings->dedimania_enabled) return false;
- if (!isset($this->dedimaniaData['context'])) return false;
- if (!isset($this->dedimaniaData['sessionId']) || !is_string($this->dedimaniaData['sessionId'])) return false;
-
- // Check session
- $request = $this->encode_request(self::DEDIMANIA_CHECKSESSION, array($this->dedimaniaData['sessionId']));
- stream_context_set_option($this->dedimaniaData['context'], 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $this->dedimaniaData['context']);
-
- // Handle response
- $response = $this->decode($file);
- $result = false;
- if (is_array($response)) {
- foreach ($response as $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- }
- else {
- $responseData = $methodResponse[0];
- if (is_bool($responseData)) {
- $result = $responseData;
- }
- }
- }
- }
- return $result;
- }
-
- /**
- * Renews dedimania session
- */
- private function openDedimaniaSession($init = false) {
- if (!$this->settings->dedimania_enabled) return false;
-
- // Get server data
- if ($init || !array_key_exists('serverData', $this->dedimaniaData) || !is_array($this->dedimaniaData['serverData'])) {
- $serverData = array();
- $serverData['Game'] = 'TM2';
- $serverInfo = $this->iControl->server->getInfo(true);
-
- // Get dedimania account data
- $accounts = $this->config->xpath('dedimania_records/account');
- foreach ($accounts as $account) {
- $login = (string) $account->login;
- if ($login != $serverInfo['Login']) continue;
- $code = (string) $account->code;
- $serverData['Login'] = $login;
- $serverData['Code'] = $code;
- break;
- }
-
- if (!isset($serverData['Login']) || !isset($serverData['Code'])) {
- // Wrong configuration for current server
- trigger_error("Records Plugin: Invalid dedimania configuration for login '" . $serverInfo['Login'] . "'.");
- if (isset($this->dedimaniaData['context'])) unset($this->dedimaniaData['context']);
- if (isset($this->dedimaniaData['sessionId'])) unset($this->dedimaniaData['sessionId']);
- return false;
- }
-
- // Complete seesion data
- $serverData['Path'] = $serverInfo['Path'];
- $systemInfo = $this->iControl->server->getSystemInfo();
- $serverData['Packmask'] = substr($systemInfo['TitleId'], 2);
- $serverVersion = $this->iControl->server->getVersion();
- $serverData['ServerVersion'] = $serverVersion['Version'];
- $serverData['ServerBuild'] = $serverVersion['Build'];
- $serverData['Tool'] = 'ManiaControl';
- $serverData['Version'] = ManiaControl::VERSION;
- $this->dedimaniaData['serverData'] = $serverData;
- }
-
- // Init header
- if ($init || !array_key_exists('header', $this->dedimaniaData) || !is_array($this->dedimaniaData['header'])) {
- $header = '';
- $header .= 'Accept-Charset: utf-8;' . PHP_EOL;
- $header .= 'Accept-Encoding: gzip;' . PHP_EOL;
- $header .= 'Content-Type: text/xml; charset=utf-8;' . PHP_EOL;
- $header .= 'Keep-Alive: 300;' . PHP_EOL;
- $header .= 'User-Agent: ManiaControl v' . ManiaControl::VERSION . ';' . PHP_EOL;
- $this->dedimaniaData['header'] = $header;
- }
-
- // Open session
- $request = $this->encode_request(self::DEDIMANIA_OPENSESSION, array($this->dedimaniaData['serverData']));
- $context = stream_context_create(array('http' => array('method' => 'POST', 'header' => $this->dedimaniaData['header'])));
- stream_context_set_option($context, 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $context);
-
- // Handle response
- $response = $this->decode($file);
- $result = false;
- if (is_array($response)) {
- foreach ($response as $index => $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- }
- else if ($index <= 0) {
- $responseData = $methodResponse[0];
- $this->dedimaniaData['context'] = $context;
- $this->dedimaniaData['sessionId'] = $responseData['SessionId'];
- $result = true;
- }
- }
- }
- if ($result) error_log("Dedimania connection successfully established.");
- return $result;
- }
-
- /**
- * Handle 1Second callback
- */
- public function handle1Second() {
- if (!$this->settings->enabled) return;
-
- // Send records manialinks if needed
- foreach ($this->updateManialinks as $id => $update) {
- if (!$update) continue;
- if (array_key_exists($id, $this->lastSendManialinks) && $this->lastSendManialinks[$id] + 2 > time()) continue;
-
- switch ($id) {
- case self::MLID_LOCAL:
- {
- $this->manialinks[$id] = $this->buildLocalManialink();
- break;
- }
- case self::MLID_DEDI:
- {
- $this->manialinks[$id] = $this->buildDedimaniaManialink();
- break;
- }
- default:
- {
- continue 2;
- break;
- }
- }
- $this->updateManialinks[$id] = false;
- $this->lastSendManialinks[$id] = time();
- $this->sendManialink($this->manialinks[$id]);
- }
- }
-
- /**
- * Handle 1Minute callback
- */
- public function handle1Minute($callback = null) {
- if ($this->settings->dedimania_enabled) {
- // Keep dedimania session alive
- if (!$this->checkDedimaniaSession()) {
- // Renew session
- $this->openDedimaniaSession();
- }
- }
- }
-
- /**
- * Handle PlayerConnect callback
- */
- public function handlePlayerConnect($callback) {
- $login = $callback[1][0];
- if ($this->settings->local_records_enabled) $this->sendManialink($this->manialinks[self::MLID_LOCAL], $login);
-
- if ($this->settings->dedimania_enabled && $this->dedimaniaData['context']) {
- $player = $this->iControl->server->getPlayer($login, true);
- if ($player) {
- // Send dedimania request
- $data = array($this->dedimaniaData['sessionId'], $player['Login'], $player['NickName'], $player['Path'],
- $player['IsSpectator']);
- $request = $this->encode_request(self::DEDIMANIA_PLAYERCONNECT, $data);
- stream_context_set_option($this->dedimaniaData['context'], 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $this->dedimaniaData['context']);
-
- // Handle response
- $response = $this->decode($file);
- if (is_array($response)) {
- foreach ($response as $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- }
- }
- }
- else {
- if (!$response) {
- trigger_error('XmlRpc Error.');
- var_dump($response);
- }
- }
- }
- $this->sendManialink($this->manialinks[self::MLID_DEDI], $login);
- }
- }
-
- /**
- * Handle PlayerDisconnect callback
- */
- public function handlePlayerDisconnect($callback) {
- $login = $callback[1][0];
-
- if ($this->settings->dedimania_enabled && $this->dedimaniaData['context']) {
- // Send dedimania request
- $data = array($this->dedimaniaData['sessionId'], $login, '');
- $request = $this->encode_request(self::DEDIMANIA_PLAYERDISCONNECT, $data);
- stream_context_set_option($this->dedimaniaData['context'], 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $this->dedimaniaData['context']);
-
- // Handle response
- $response = $this->decode($file);
- if (is_array($response)) {
- foreach ($response as $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- }
- }
- }
- else {
- if (!$response) {
- trigger_error('XmlRpc Error.');
- var_dump($response);
- }
- }
- }
- }
-
- /**
- * Handle BeginMap callback
- */
- public function handleMapBegin($callback) {
- // Update map
- $this->mapInfo = $this->getMapInfo();
-
- if ($this->settings->local_records_enabled) {
- // Update local records
- $this->updateManialinks[self::MLID_LOCAL] = true;
- }
-
- if ($this->settings->dedimania_enabled) {
- // Update dedimania records
- $this->fetchDedimaniaRecords(true);
- $this->updateManialinks[self::MLID_DEDI] = true;
- }
- }
-
- /**
- * Build map info struct for dedimania requests
- */
- private function getMapInfo() {
- $map = $this->iControl->server->getMap();
- if (!$map) return null;
- $mapInfo = array();
- $mapInfo['UId'] = $map['UId'];
- $mapInfo['Name'] = $map['Name'];
- $mapInfo['Author'] = $map['Author'];
- $mapInfo['Environment'] = $map['Environnement'];
- $mapInfo['NbCheckpoints'] = $map['NbCheckpoints'];
- $mapInfo['NbLaps'] = $map['NbLaps'];
- return $mapInfo;
- }
-
- /**
- * Handle EndMap callback
- */
- public function handleMapEnd($callback) {
- if ($this->settings->dedimania_enabled) {
- // Send dedimania records
- $gameMode = $this->getGameModeString();
- $times = array();
- $replays = array();
- foreach ($this->dedimaniaData['records']['Records'] as $record) {
- if (!isset($record['New']) || !$record['New']) continue;
- array_push($times, array('Login' => $record['Login'], 'Best' => $record['Best'], 'Checks' => $record['Checks']));
- if (!isset($replays['VReplay'])) {
- $replays['VReplay'] = $record['VReplay'];
- }
- if (!isset($replays['Top1GReplay']) && isset($record['Top1GReplay'])) {
- $replays['Top1GReplay'] = $record['Top1GReplay'];
- }
- // TODO: VReplayChecks
- }
- if (!isset($replays['VReplay'])) $replays['VReplay'] = '';
- if (!isset($replays['VReplayChecks'])) $replays['VReplayChecks'] = '';
- if (!isset($replays['Top1GReplay'])) $replays['Top1GReplay'] = '';
-
- xmlrpc_set_type($replays['VReplay'], 'base64');
- xmlrpc_set_type($replays['Top1GReplay'], 'base64');
-
- $data = array($this->dedimaniaData['sessionId'], $this->mapInfo, $gameMode, $times, $replays);
- $request = $this->encode_request(self::DEDIMANIA_SETCHALLENGETIMES, $data);
- stream_context_set_option($this->dedimaniaData['context'], 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $this->dedimaniaData['context']);
-
- // Handle response
- $response = $this->decode($file);
- if (is_array($response)) {
- foreach ($response as $index => $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- }
- else {
- if ($index <= 0) {
- // Called method response
- $responseData = $methodResponse[0];
- if (!$responseData) {
- trigger_error("Records Plugin: Submitting dedimania records failed.");
- }
- continue;
- }
-
- // Warnings and TTR
- $errors = $methodResponse[0]['methods'][0]['errors'];
- if ($errors) {
- trigger_error($errors);
- }
- }
- }
- }
- }
- }
-
- /**
- * Get current checkpoint string for dedimania record
- *
- * @param string $login
- * @return string
- */
- private function getChecks($login) {
- if (!$login || !isset($this->checkpoints[$login])) return null;
- $string = '';
- $count = count($this->checkpoints[$login]);
- foreach ($this->checkpoints[$login] as $index => $check) {
- $string .= $check;
- if ($index < $count - 1) $string .= ',';
- }
- return $string;
- }
-
- /**
- * Build server info struct for callbacks
- */
- private function getSrvInfo() {
- $server = $this->iControl->server->getOptions();
- if (!$server) return null;
- $client = null;
- $players = null;
- $spectators = null;
- $this->iControl->server->getPlayers($client, $players, $spectators);
- if (!is_array($players) || !is_array($spectators)) return null;
- return array('SrvName' => $server['Name'], 'Comment' => $server['Comment'], 'Private' => (strlen($server['Password']) > 0),
- 'NumPlayers' => count($players), 'MaxPlayers' => $server['CurrentMaxPlayers'], 'NumSpecs' => count($spectators),
- 'MaxSpecs' => $server['CurrentMaxSpectators']);
- }
-
- /**
- * Build simple player list for callbacks
- */
- private function getPlayerList($votes = false) {
- $client = null;
- $players;
- $spectators;
- $allPlayers = $this->iControl->server->getPlayers($client, $players, $spectators);
- if (!is_array($players) || !is_array($spectators)) return null;
- $playerInfo = array();
- foreach ($allPlayers as $player) {
- array_push($playerInfo, array('Login' => $player['Login'], 'IsSpec' => in_array($player, $spectators)));
- }
- return $playerInfo;
- }
-
- /**
- * Get dedi string representation of the current game mode
- */
- private function getGameModeString() {
- $gameMode = $this->iControl->server->getGameMode();
- if ($gameMode === null) {
- trigger_error("Couldn't retrieve game mode. " . $this->iControl->getClientErrorText());
- return null;
- }
- switch ($gameMode) {
- case 1:
- case 3:
- case 5:
- {
- return 'Rounds';
- }
- case 2:
- case 4:
- {
- return 'TA';
- }
- }
- return null;
- }
-
- /**
- * Build votes info struct for callbacks
- */
- private function getVotesInfo() {
- $map = $this->iControl->server->getMap();
- if (!$map) return null;
- $gameMode = $this->getGameModeString();
- if (!$gameMode) return null;
- return array('UId' => $map['UId'], 'GameMode' => $gameMode);
- }
-
- /**
- * Handle 3Minute callback
- */
- public function handle3Minute($callback = null) {
- if ($this->settings->dedimania_enabled) {
- // Update dedimania players
- $servInfo = $this->getSrvInfo();
- $votesInfo = $this->getVotesInfo();
- $playerList = $this->getPlayerList(true);
- if ($servInfo && $votesInfo && $playerList) {
- $data = array($this->dedimaniaData['sessionId'], $servInfo, $votesInfo, $playerList);
- $request = $this->encode_request(self::DEDIMANIA_UPDATESERVERPLAYERS, $data);
- stream_context_set_option($this->dedimaniaData['context'], 'http', 'content', $request);
- $file = file_get_contents(self::DEDIMANIA_URL, false, $this->dedimaniaData['context']);
-
- // Handle response
- $response = $this->decode($file);
- if (is_array($response)) {
- foreach ($response as $methodResponse) {
- if (xmlrpc_is_fault($methodResponse)) {
- $this->handleXmlRpcFault($methodResponse);
- }
- }
- }
- else if (!$response) {
- trigger_error('XmlRpc Error.');
- var_dump($response);
- }
- }
- }
- }
-
- /**
- * Handle PlayerCheckpoint callback
- */
- public function handlePlayerCheckpoint($callback) {
- $data = $callback[1];
- $login = $data[1];
- $time = $data[2];
- $lap = $data[3];
- $cpIndex = $data[4];
- if (!isset($this->checkpoints[$login]) || $cpIndex <= 0) $this->checkpoints[$login] = array();
- $this->checkpoints[$login][$cpIndex] = $time;
- }
-
- /**
- * Handle PlayerFinish callback
- */
- public function handlePlayerFinish($callback) {
- $data = $callback[1];
- if ($data[0] <= 0 || $data[2] <= 0) return;
-
- $login = $data[1];
- $time = $data[2];
- $newMap = $this->iControl->server->getMap();
- if (!$newMap) return;
- if (!$this->mapInfo || $this->mapInfo['UId'] !== $newMap['UId']) {
- $this->mapInfo = $this->getMapInfo();
- }
- $map = $newMap;
-
- $player = $this->iControl->server->getPlayer($login);
-
- if ($this->settings->local_records_enabled) {
- // Get old record of the player
- $oldRecord = $this->getLocalRecord($map['UId'], $login);
- $save = true;
- if ($oldRecord) {
- if ($oldRecord['time'] < $time) {
- // Not improved
- $save = false;
- }
- else if ($oldRecord['time'] == $time) {
- // Same time
- $message = '$<' . $player['NickName'] . '$> equalized her/his $<$o' . $oldRecord['rank'] . '.$> Local Record: ' .
- Tools::formatTime($oldRecord['time']);
- $this->iControl->chat->sendInformation($message);
- $save = false;
- }
- }
- if ($save) {
- // Save time
- $database = $this->iControl->database;
- $query = "INSERT INTO `" . self::TABLE_RECORDS . "` (
- `mapUId`,
- `Login`,
- `time`
- ) VALUES (
- '" . $database->escape($map['UId']) . "',
- '" . $database->escape($login) . "',
- " . $time . "
- ) ON DUPLICATE KEY UPDATE
- `time` = VALUES(`time`);";
- if (!$database->query($query)) {
- trigger_error("Couldn't save player record. " . $database->mysqli->error);
- }
- else {
- // Announce record
- $newRecord = $this->getLocalRecord($map['UId'], $login);
- if ($oldRecord == null || $newRecord['rank'] < $oldRecord['rank']) {
- // Gained rank
- $improvement = 'gained the';
- }
- else {
- // Only improved time
- $improvement = 'improved her/his';
- }
- $message = '$<' . $player['NickName'] . '$> ' . $improvement . ' $<$o' . $newRecord['rank'] . '.$> Local Record: ' .
- Tools::formatTime($newRecord['time']);
- $this->iControl->chat->sendInformation($message);
- $this->updateManialinks[self::MLID_LOCAL] = true;
- }
- }
- }
-
- if ($this->settings->dedimania_enabled) {
- // Get old record of the player
- $oldRecord = $this->getDediRecord($login);
- $save = true;
- if ($oldRecord) {
- if ($oldRecord['Best'] < $time) {
- // Not improved
- $save = false;
- }
- else if ($oldRecord['Best'] == $time) {
- // Same time
- $save = false;
- }
- }
- if ($save) {
- // Save time
- $newRecord = array('Login' => $login, 'NickName' => $player['NickName'], 'Best' => $data[2],
- 'Checks' => $this->getChecks($login), 'New' => true);
- $inserted = $this->insertDediRecord($newRecord, $oldRecord);
- if ($inserted) {
- // Get newly saved record
- foreach ($this->dedimaniaData['records']['Records'] as $key => &$record) {
- if ($record['Login'] !== $newRecord['Login']) continue;
- $newRecord = $record;
- break;
- }
-
- // Announce record
- if (!$oldRecord || $newRecord['Rank'] < $oldRecord['Rank']) {
- // Gained rank
- $improvement = 'gained the';
- }
- else {
- // Only improved time
- $improvement = 'improved her/his';
- }
- $message = '$<' . $player['NickName'] . '$> ' . $improvement . ' $<$o' . $newRecord['Rank'] .
- '.$> Dedimania Record: ' . Tools::formatTime($newRecord['Best']);
- $this->iControl->chat->sendInformation($message);
- $this->updateManialinks[self::MLID_DEDI] = true;
- }
- }
- }
- }
-
- /**
- * Get max rank for given login
- */
- private function getMaxRank($login) {
- if (!isset($this->dedimaniaData['records'])) return null;
- $records = $this->dedimaniaData['records'];
- $maxRank = $records['ServerMaxRank'];
- foreach ($records['Players'] as $player) {
- if ($player['Login'] === $login) {
- if ($player['MaxRank'] > $maxRank) $maxRank = $player['MaxRank'];
- break;
- }
- }
- return $maxRank;
- }
-
- /**
- * Inserts the given new dedimania record at the proper position
- *
- * @param struct $newRecord
- * @return bool
- */
- private function insertDediRecord(&$newRecord, $oldRecord) {
- if (!$newRecord || !isset($this->dedimaniaData['records']) || !isset($this->dedimaniaData['records']['Records'])) return false;
-
- $insert = false;
- $newRecords = array();
-
- // Get max possible rank
- $maxRank = $this->getMaxRank($newRecord['Login']);
- if (!$maxRank) $maxRank = 30;
-
- // Loop through existing records
- foreach ($this->dedimaniaData['records']['Records'] as $key => &$record) {
- if ($record['Rank'] > $maxRank) {
- // Max rank reached
- return false;
- }
-
- if ($record['Login'] === $newRecord['Login']) {
- // Old record of the same player
- if ($record['Best'] <= $newRecord['Best']) {
- // It's better - Do nothing
- return false;
- }
-
- // Replace old record
- unset($this->dedimaniaData['records']['Records'][$key]);
- $insert = true;
- break;
- }
-
- // Other player's record
- if ($record['Best'] <= $newRecord['Best']) {
- // It's better - Skip
- continue;
- }
-
- // New record is better - Insert it
- $insert = true;
- if ($oldRecord) {
- // Remove old record
- foreach ($this->dedimaniaData['records']['Records'] as $key2 => $record2) {
- if ($record2['Login'] !== $oldRecord['Login']) continue;
- unset($this->dedimaniaData['records']['Records'][$key2]);
- break;
- }
- }
- break;
- }
-
- if (!$insert && count($this->dedimaniaData['records']['Records']) < $maxRank) {
- // Records list not full - Append new record
- $insert = true;
- }
-
- if ($insert) {
- // Insert new record
- array_push($this->dedimaniaData['records']['Records'], $newRecord);
-
- // Update ranks
- $this->updateDediRecordRanks();
-
- // Save replays
- foreach ($this->dedimaniaData['records']['Records'] as $key => &$record) {
- if ($record['Login'] !== $newRecord['Login']) continue;
- $this->setRecordReplays($record);
- break;
- }
-
- // Record inserted
- return true;
- }
-
- // No new record
- return false;
- }
-
- /**
- * Updates the replay values for the given record
- *
- * @param struct $record
- */
- private function setRecordReplays(&$record) {
- if (!$record || !$this->settings->dedimania_enabled) return;
-
- // Set validation replay
- $validationReplay = $this->iControl->server->getValidationReplay($record['Login']);
- if ($validationReplay) $record['VReplay'] = $validationReplay;
-
- // Set ghost replay
- if ($record['Rank'] <= 1) {
- $dataDirectory = $this->iControl->server->getDataDirectory();
- if (!isset($this->dedimaniaData['directoryAccessChecked'])) {
- $access = $this->iControl->server->checkAccess($dataDirectory);
- if (!$access) {
- trigger_error("No access to the servers data directory. Can't retrieve ghost replays.");
- }
- $this->dedimaniaData['directoryAccessChecked'] = $access;
- }
- if ($this->dedimaniaData['directoryAccessChecked']) {
- $ghostReplay = $this->iControl->server->getGhostReplay($record['Login']);
- if ($ghostReplay) $record['Top1GReplay'] = $ghostReplay;
- }
- }
- }
-
- /**
- * Update the sorting and the ranks of all dedimania records
- */
- private function updateDediRecordRanks() {
- if (!isset($this->dedimaniaData['records']) || !isset($this->dedimaniaData['records']['Records'])) return;
-
- // Sort records
- usort($this->dedimaniaData['records']['Records'], array($this, 'compareRecords'));
-
- // Update ranks
- $rank = 1;
- foreach ($this->dedimaniaData['records']['Records'] as &$record) {
- $record['Rank'] = $rank;
- $rank++;
- }
- }
-
- /**
- * Compare function for sorting dedimania records
- *
- * @param struct $first
- * @param struct $second
- * @return int
- */
- private function compareRecords($first, $second) {
- if ($first['Best'] < $second['Best']) {
- return -1;
- }
- else if ($first['Best'] > $second['Best']) {
- return 1;
- }
- else {
- if ($first['Rank'] < $second['Rank']) {
- return -1;
- }
- else {
- return 1;
- }
- }
- }
-
- /**
- * Get the dedimania record of the given login
- *
- * @param string $login
- * @return struct
- */
- private function getDediRecord($login) {
- if (!isset($this->dedimaniaData['records'])) return null;
- $records = $this->dedimaniaData['records']['Records'];
- foreach ($records as $index => $record) {
- if ($record['Login'] === $login) return $record;
- }
- return null;
- }
-
- /**
- * Send manialink to clients
- */
- private function sendManialink($manialink, $login = null) {
- if (!$manialink || !$this->iControl->client) return;
- if (!$login) {
- if (!$this->iControl->client->query('SendDisplayManialinkPage', $manialink->asXML(), 0, false)) {
- trigger_error("Couldn't send manialink to players. " . $this->iControl->getClientErrorText());
- }
- }
- else {
- if (!$this->iControl->client->query('SendDisplayManialinkPageToLogin', $login, $manialink->asXML(), 0, false)) {
- trigger_error("Couldn't send manialink to player '" . $login . "'. " . $this->iControl->getClientErrorText());
- }
- }
- }
-
- /**
- * Handle ClientUpdated callback
- *
- * @param mixed $data
- */
- public function handleClientUpdated($data) {
- $this->openDedimaniaSession(true);
- if (isset($this->updateManialinks[self::MLID_LOCAL])) $this->updateManialinks[self::MLID_LOCAL] = true;
- if (isset($this->updateManialinks[self::MLID_DEDI])) $this->updateManialinks[self::MLID_DEDI] = true;
- }
-
- /**
- * Update local records manialink
- */
- private function buildLocalManialink() {
- $map = $this->iControl->server->getMap();
- if (!$map) {
- return null;
- }
-
- $pos_x = (float) $this->config->local_records->widget->pos_x;
- $pos_y = (float) $this->config->local_records->widget->pos_y;
- $title = (string) $this->config->local_records->widget->title;
- $width = (float) $this->config->local_records->widget->width;
- $lines = (int) $this->config->local_records->widget->lines;
- $line_height = (float) $this->config->local_records->widget->line_height;
-
- $recordResult = $this->getLocalRecords($map['UId']);
- if (!$recordResult) {
- trigger_error("Couldn't fetch player records.");
- return null;
- }
-
- $xml = Tools::newManialinkXml(self::MLID_LOCAL);
-
- $frame = $xml->addChild('frame');
- $frame->addAttribute('posn', $pos_x . ' ' . $pos_y);
-
- // Background
- $quad = $frame->addChild('quad');
- Tools::addAlignment($quad, 'center', 'top');
- $quad->addAttribute('sizen', ($width * 1.05) . ' ' . (7. + $lines * $line_height));
- $quad->addAttribute('style', 'Bgs1InRace');
- $quad->addAttribute('substyle', 'BgTitleShadow');
-
- // Title
- $label = $frame->addChild('label');
- Tools::addAlignment($label);
- Tools::addTranslate($xml);
- $label->addAttribute('posn', '0 ' . ($line_height * -0.9));
- $label->addAttribute('sizen', $width . ' 0');
- $label->addAttribute('style', 'TextTitle1');
- $label->addAttribute('textsize', '2');
- $label->addAttribute('text', $title);
-
- // Times
- $index = 0;
- while ($record = $recordResult->fetch_assoc()) {
- $y = -8. - $index * $line_height;
-
- $recordFrame = $frame->addChild('frame');
- $recordFrame->addAttribute('posn', '0 ' . $y);
-
- // Background
- $quad = $recordFrame->addChild('quad');
- Tools::addAlignment($quad);
- $quad->addAttribute('sizen', $width . ' ' . $line_height);
- $quad->addAttribute('style', 'Bgs1InRace');
- $quad->addAttribute('substyle', 'BgTitleGlow');
-
- // Rank
- $label = $recordFrame->addChild('label');
- Tools::addAlignment($label, 'left');
- $label->addAttribute('posn', ($width * -0.47) . ' 0');
- $label->addAttribute('sizen', ($width * 0.06) . ' ' . $line_height);
- $label->addAttribute('textsize', '1');
- $label->addAttribute('textprefix', '$o');
- $label->addAttribute('text', $record['rank']);
-
- // Name
- $label = $recordFrame->addChild('label');
- Tools::addAlignment($label, 'left');
- $label->addAttribute('posn', ($width * -0.4) . ' 0');
- $label->addAttribute('sizen', ($width * 0.6) . ' ' . $line_height);
- $label->addAttribute('textsize', '1');
- $label->addAttribute('text', $record['NickName']);
-
- // Time
- $label = $recordFrame->addChild('label');
- Tools::addAlignment($label, 'right');
- $label->addAttribute('posn', ($width * 0.47) . ' 0');
- $label->addAttribute('sizen', ($width * 0.25) . ' ' . $line_height);
- $label->addAttribute('textsize', '1');
- $label->addAttribute('text', Tools::formatTime($record['time']));
-
- $index++;
- }
-
- return $xml;
- }
-
- /**
- * Update dedimania records manialink
- */
- private function buildDedimaniaManialink() {
- if (!isset($this->dedimaniaData['records'])) {
- return;
- }
- $records = $this->dedimaniaData['records']['Records'];
-
- $pos_x = (float) $this->config->dedimania_records->widget->pos_x;
- $pos_y = (float) $this->config->dedimania_records->widget->pos_y;
- $title = (string) $this->config->dedimania_records->widget->title;
- $width = (float) $this->config->dedimania_records->widget->width;
- $lines = (int) $this->config->dedimania_records->widget->lines;
- $line_height = (float) $this->config->dedimania_records->widget->line_height;
-
- $xml = Tools::newManialinkXml(self::MLID_DEDI);
-
- $frame = $xml->addChild('frame');
- $frame->addAttribute('posn', $pos_x . ' ' . $pos_y);
-
- // Background
- $quad = $frame->addChild('quad');
- Tools::addAlignment($quad, 'center', 'top');
- $quad->addAttribute('sizen', ($width * 1.05) . ' ' . (7. + $lines * $line_height));
- $quad->addAttribute('style', 'Bgs1InRace');
- $quad->addAttribute('substyle', 'BgTitleShadow');
-
- // Title
- $label = $frame->addChild('label');
- Tools::addAlignment($label);
- Tools::addTranslate($xml);
- $label->addAttribute('posn', '0 ' . ($line_height * -0.9));
- $label->addAttribute('sizen', $width . ' 0');
- $label->addAttribute('style', 'TextTitle1');
- $label->addAttribute('textsize', '2');
- $label->addAttribute('text', $title);
-
- // Times
- foreach ($records as $index => $record) {
- $y = -8. - $index * $line_height;
-
- $recordFrame = $frame->addChild('frame');
- $recordFrame->addAttribute('posn', '0 ' . $y);
-
- // Background
- $quad = $recordFrame->addChild('quad');
- Tools::addAlignment($quad);
- $quad->addAttribute('sizen', $width . ' ' . $line_height);
- $quad->addAttribute('style', 'Bgs1InRace');
- $quad->addAttribute('substyle', 'BgTitleGlow');
-
- // Rank
- $label = $recordFrame->addChild('label');
- Tools::addAlignment($label, 'left');
- $label->addAttribute('posn', ($width * -0.47) . ' 0');
- $label->addAttribute('sizen', ($width * 0.06) . ' ' . $line_height);
- $label->addAttribute('textsize', '1');
- $label->addAttribute('textprefix', '$o');
- $label->addAttribute('text', $record['Rank']);
-
- // Name
- $label = $recordFrame->addChild('label');
- Tools::addAlignment($label, 'left');
- $label->addAttribute('posn', ($width * -0.4) . ' 0');
- $label->addAttribute('sizen', ($width * 0.6) . ' ' . $line_height);
- $label->addAttribute('textsize', '1');
- $label->addAttribute('text', $record['NickName']);
-
- // Time
- $label = $recordFrame->addChild('label');
- Tools::addAlignment($label, 'right');
- $label->addAttribute('posn', ($width * 0.47) . ' 0');
- $label->addAttribute('sizen', ($width * 0.25) . ' ' . $line_height);
- $label->addAttribute('textsize', '1');
- $label->addAttribute('text', Tools::formatTime($record['Best']));
-
- if ($index >= $lines - 1) break;
- }
-
- return $xml;
- }
-
- /**
- * Fetch local records for the given map
- *
- * @param string $mapUId
- * @param int $limit
- * @return array
- */
- private function getLocalRecords($mapUId, $limit = -1) {
- $query = "SELECT * FROM (
- SELECT recs.*, @rank := @rank + 1 as `rank` FROM `" . self::TABLE_RECORDS . "` recs, (SELECT @rank := 0) ra
- WHERE recs.`mapUId` = '" . $this->iControl->database->escape($mapUId) . "'
- ORDER BY recs.`time` ASC
- " . ($limit > 0 ? "LIMIT " . $limit : "") . ") records
- LEFT JOIN `" . Database::TABLE_PLAYERS . "` players
- ON records.`Login` = players.`Login`;";
- return $this->iControl->database->query($query);
- }
-
- /**
- * Retrieve the local record for the given map and login
- *
- * @param string $mapUId
- * @param string $login
- * @return array
- */
- private function getLocalRecord($mapUId, $login) {
- if (!$mapUId || !$login) return null;
- $database = $this->iControl->database;
- $query = "SELECT records.* FROM (
- SELECT recs.*, @rank := @rank + 1 as `rank` FROM `" . self::TABLE_RECORDS . "` `recs`, (SELECT @rank := 0) r
- WHERE recs.`mapUid` = '" . $database->escape($mapUId) . "'
- ORDER BY recs.`time` ASC) `records`
- WHERE records.`Login` = '" . $database->escape($login) . "';";
- $result = $database->query($query);
- if (!$result || !is_object($result)) {
- trigger_error("Couldn't retrieve player record for '" . $login . "'." . $database->mysqli->error);
- return null;
- }
- while ($record = $result->fetch_assoc()) {
- return $record;
- }
- return null;
- }
-
- /**
- * Encodes the given xml rpc method and params
- *
- * @param string $method
- * @param array $params
- * @return string
- */
- private function encode_request($method, $params) {
- $paramArray = array(array('methodName' => $method, 'params' => $params),
- array('methodName' => self::DEDIMANIA_WARNINGSANDTTR2, 'params' => array()));
- return xmlrpc_encode_request(self::XMLRPC_MULTICALL, array($paramArray), array('encoding' => 'UTF-8', 'escaping' => 'markup'));
- }
-
- /**
- * Decodes xml rpc response
- *
- * @param string $response
- * @return mixed
- */
- private function decode($response) {
- return xmlrpc_decode($response, 'utf-8');
- }
-
- /**
- * Handles xml rpc fault
- *
- * @param struct $fault
- */
- private function handleXmlRpcFault($fault) {
- trigger_error('XmlRpc Fault: ' . $fault['faultString'] . ' (' . $fault['faultCode'] . ')');
- }
-}
-
-?>
diff --git a/application/plugins/united.plugin.php b/application/plugins/united.plugin.php
deleted file mode 100644
index f4cdb774..00000000
--- a/application/plugins/united.plugin.php
+++ /dev/null
@@ -1,677 +0,0 @@
-mControl = $mControl;
-
- // Load config
- $this->config = Tools::loadConfig('united.plugin.xml');
- $this->loadSettings();
-
- // Check for enabled setting
- if (!$this->settings->enabled) return;
-
- // Load clients
- $this->loadClients();
-
- // Register for callbacks
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_ONINIT, $this, 'handleOnInitCallback');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_IC_5_SECOND, $this, 'handle5Seconds');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERCONNECT, $this, 'handlePlayerConnect');
- $this->iControl->callbacks->registerCallbackHandler(Callbacks::CB_MP_PLAYERMANIALINKPAGEANSWER, $this,
- 'handleManialinkPageAnswer');
-
- // Register for commands
- $this->iControl->commands->registerCommandHandler('nextserver', $this, 'handleNextServerCommand');
-
- if ($this->settings->widgets_enabled) {
- // Build addfavorite manialink
- $this->buildFavoriteManialink();
- }
-
- error_log('United Pugin v' . self::VERSION . ' ready!');
- }
-
- /**
- * Handle ManiaControl OnInit callback
- *
- * @param array $callback
- */
- public function handleOnInitCallback($callback) {
- if ($this->settings->widgets_enabled) {
- // Send widgets to all players
-
- if (Tools::toBool($this->config->widgets->addfavorite->enabled)) {
- // Send favorite widget
- if (!$this->iControl->client->query('SendDisplayManialinkPage', $this->manialinks[self::ML_ADDFAVORITE]->asXml(), 0,
- false)) {
- trigger_error("Couldn't send favorite widget! " . $this->iControl->getClientErrorText());
- }
- }
- }
- }
-
- /**
- * Load settings from config
- */
- private function loadSettings() {
- $this->settings = new \stdClass();
-
- // Enabled
- $this->settings->enabled = Tools::toBool($this->config->enabled);
-
- // Timeout
- $timeout = $this->iControl->server->config->xpath('timeout');
- if ($timeout) {
- $this->settings->timeout = (int) $timeout[0];
- }
- else {
- $this->settings->timeout = 30;
- }
-
- // Game mode
- $mode = $this->config->xpath('mode');
- if ($mode) {
- $mode = (int) $mode[0];
- if ($mode < 1 || $mode > 6) {
- $this->settings->gamemode = 2;
- }
- else {
- $this->settings->gamemode = $mode;
- }
- }
-
- // Server status
- $hide_game_server = $this->config->xpath('hide_game_server');
- if ($hide_game_server) {
- $this->settings->hide_game_server = Tools::toBool($hide_game_server[0]);
- }
- else {
- $this->settings->hide_game_server = true;
- }
-
- // Passwords
- $lobbyPassword = $this->config->xpath('lobbies/password');
- if ($lobbyPassword) {
- $this->settings->lobbyPassword = (string) $lobbyPassword[0];
- }
- else {
- $this->settings->lobbyPassword = '';
- }
- $gamePassword = $this->config->xpath('gameserver/password');
- if ($gamePassword) {
- $this->settings->gamePassword = (string) $gamePassword[0];
- }
- else {
- $this->settings->gamePassword = '';
- }
-
- // Widgets
- $this->settings->widgets_enabled = Tools::toBool($this->config->widgets->enabled);
- }
-
- /**
- * Loop events on clients
- */
- public function loop() {
- if (!$this->settings->enabled) return;
-
- // Check callbacks all clients
- $clients = array_merge($this->gameServer, $this->lobbies);
- $currentServer = $this->gameServer[$this->currentClientIndex];
- foreach ($clients as $index => $client) {
- $client->resetError();
- $client->readCB();
- $callbacks = $client->getCBResponses();
- if (!is_array($callbacks) || $client->isError()) {
- trigger_error("Error reading server callbacks! " . $this->iControl->getClientErrorText($client));
- }
- else {
- if ($client == $currentServer) {
- // Currently active game server
- foreach ($callbacks as $index => $callback) {
- $callbackName = $callback[0];
- switch ($callbackName) {
- case Callbacks::CB_MP_ENDMAP:
- {
- $this->switchToNextServer(false);
- break;
- }
- }
- }
-
- if ($this->lastStatusCheck + 2 > time()) continue;
- $this->lastStatusCheck = time();
-
- if (!$client->query('CheckEndMatchCondition')) {
- trigger_error("Couldn't get game server status. " . $this->iControl->getClientErrorText($client));
- }
- else {
- $response = $client->getResponse();
- switch ($response) {
- case 'Finished':
- {
- if ($this->finishedBegin < 0) {
- $this->finishedBegin = time();
- }
- else if ($this->finishedBegin + 13 <= time()) {
- $this->switchToNextServer(true);
- }
- break;
- }
- default:
- {
- $this->finishedBegin = -1;
- break;
- }
- }
- }
- }
- else {
- // Lobby or inactive game server -> Redirect players
- foreach ($callbacks as $callback) {
- switch ($callback[0]) {
- case Callbacks::CB_MP_PLAYERCONNECT:
- {
- $this->playerJoinedLobby($client, $callback);
- break;
- }
- }
- }
- }
- }
- }
-
- // Check for switch server request
- if ($this->switchServerRequested > 0 && $this->switchServerRequested <= time()) {
- $this->switchServerRequested = -1;
-
- // Switch server
- $this->switchToNextServer(true);
- }
- }
-
- /**
- * Handle 5 seconds callback
- */
- public function handle5Seconds($callback = null) {
- // Update lobby infos
- $players = $this->iControl->server->getPlayers();
- if (is_array($players)) {
- $playerCount = count($players);
- $playerLevel = 0.;
- if ($playerCount > 0) {
- foreach ($players as $player) {
- $playerLevel += $player['LadderRanking'];
- }
- $playerLevel /= $playerCount;
- }
- foreach ($this->lobbies as $lobby) {
- if (!$lobby->query('SetLobbyInfo', true, $playerCount, 255, $playerLevel)) {
- trigger_error("Couldn't update lobby info. " . $this->iControl->getClientErrorText($lobby));
- }
- }
- }
-
- // Check for not-redirected players
- $clients = array_merge($this->gameServer, $this->lobbies);
- $joinLink = $this->getJoinLink();
- foreach ($clients as $client) {
- if ($client == $this->gameServer[$this->currentClientIndex]) continue;
- $players = $this->iControl->server->getPlayers($client);
- if (!is_array($players)) continue;
- foreach ($players as $player) {
- $login = $player['Login'];
- if (!$client->query('SendOpenLinkToLogin', $login, $joinLink, 1)) {
- trigger_error(
- "Couldn't redirect player '" . $login . "' to active game server. " .
- $this->iControl->getClientErrorText($client));
- }
- }
- }
- }
-
- /**
- * Handle player manialink page answer callback
- */
- public function handleManialinkPageAnswer($callback) {
- $login = $callback[1][1];
- $action = $callback[1][2];
- switch ($action) {
- case self::ML_ADDFAVORITE:
- {
- // Open manialink to add server logins to favorite
- $serverLogins = array();
- $add_all = Tools::toBool($this->config->widgets->addfavorite->add_all);
- if ($add_all) {
- // Add all server
- foreach ($this->gameServer as $serverClient) {
- array_push($serverLogins, $this->iControl->server->getLogin($serverClient));
- }
- foreach ($this->lobbies as $serverClient) {
- array_push($serverLogins, $this->iControl->server->getLogin($serverClient));
- }
- }
- else {
- // Add only current server
- array_push($serverLogins, $this->iControl->server->getLogin());
- }
-
- // Build manialink url
- $manialink = 'iControl?favorite';
- foreach ($serverLogins as $serverLogin) {
- $manialink .= '&' . $serverLogin;
- }
-
- // Send url to player
- if (!$this->iControl->client->query('SendOpenLinkToLogin', $login, $manialink, 1)) {
- trigger_error(
- "Couldn't open manialink to add server to favorite for '" . $login . "'! " .
- $this->iControl->getClientErrorText());
- }
- break;
- }
- }
- }
-
- /**
- * Switch to the next server
- *
- * @param bool $simulateMapEnd
- * Simulate end of the map by sending callbacks
- */
- private function switchToNextServer($simulateMapEnd) {
- $this->finishedBegin = -1;
- $oldClient = $this->gameServer[$this->currentClientIndex];
-
- $random_order = Tools::toBool($this->config->random_order);
- if ($random_order) {
- // Random next server
- $this->currentClientIndex = rand(0, count($this->gameServer) - 1);
- }
- else {
- // Next server in list
- $this->currentClientIndex++;
- }
- if ($this->currentClientIndex >= count($this->gameServer)) $this->currentClientIndex = 0;
-
- $newClient = $this->gameServer[$this->currentClientIndex];
- if ($newClient == $oldClient) return;
-
- // Restart map on next game server
- if (!$newClient->query('RestartMap')) {
- trigger_error("Couldn't restart map on next game server. " . $this->iControl->getClientErrorText($newClient));
- }
-
- if ($simulateMapEnd) {
- // Simulate EndMap on old client
- $this->iControl->callbacks->triggerCallback(Callbacks::CB_IC_ENDMAP, array(Callbacks::CB_IC_ENDMAP));
- }
-
- // Transfer players to next server
- $joinLink = $this->getJoinLink($newClient);
- if (!$oldClient->query('GetPlayerList', 255, 0)) {
- trigger_error("Couldn't get player list. " . $this->iControl->getClientErrorText($oldClient));
- }
- else {
- $playerList = $oldClient->getResponse();
- foreach ($playerList as $player) {
- $login = $player['Login'];
- if (!$oldClient->query('SendOpenLinkToLogin', $login, $joinLink, 1)) {
- trigger_error("Couldn't redirect player to next game server. " . $this->iControl->getClientErrorText($oldClient));
- }
- }
-
- $this->iControl->client = $newClient;
- }
-
- // Trigger client updated callback
- $this->iControl->callbacks->triggerCallback(Callbacks::CB_IC_CLIENTUPDATED, "Plugin_United.SwitchedServer");
-
- if ($simulateMapEnd) {
- // Simulate BeginMap on new client
- $map = $this->iControl->server->getMap();
- if ($map) {
- $this->iControl->callbacks->triggerCallback(Callbacks::CB_IC_BEGINMAP, array(Callbacks::CB_IC_BEGINMAP, array($map)));
- }
- }
- }
-
- /**
- * Handle nextserver command
- *
- * @param mixed $command
- */
- public function handleNextServerCommand($command) {
- if (!$command) return;
- $login = $command[1][1];
-
- if (!$this->iControl->authentication->checkRight($login, 'operator')) {
- // Not allowed
- $this->iControl->authentication->sendNotAllowed($login);
- return;
- }
-
- // Request skip to next server
- $this->switchServerRequested = time() + 3;
-
- // Send chat message
- $this->iControl->chat->sendInformation("Switching to next server in 3 seconds...");
- }
-
- /**
- * Handle PlayerConnect callback
- */
- public function playerJoinedLobby($client, $callback) {
- if (!$client) return;
-
- $data = $callback[1];
- $login = $data[0];
-
- // Redirect player to current game server
- $gameserver = $this->gameServer[$this->currentClientIndex];
- $joinLink = $this->getJoinLink($gameserver, !$data[1]);
- if (!$client->query('SendOpenLinkToLogin', $login, $joinLink, 1)) {
- trigger_error(
- "United Plugin: Couldn't redirect player to current game server. " . $this->iControl->getClientErrorText($client));
- }
- }
-
- /**
- * Connect to the game server defined in the config
- */
- private function loadClients() {
- $gameserver = $this->config->xpath('gameserver/server');
- $lobbies = $this->config->xpath('lobbies/server');
-
- $clientsConfig = array_merge($gameserver, $lobbies);
- foreach ($clientsConfig as $index => $serv) {
- $isGameServer = (in_array($serv, $gameserver));
-
- $host = $serv->xpath('host');
- $port = $serv->xpath('port');
- if (!$host || !$port) {
- trigger_error("Invalid configuration!", E_USER_ERROR);
- }
- $host = (string) $host[0];
- $port = (string) $port[0];
-
- error_log("Connecting to united " . ($isGameServer ? 'game' : 'lobby') . " server at " . $host . ":" . $port . "...");
- $client = new \IXR_ClientMulticall_Gbx();
-
- // Connect
- if (!$client->InitWithIp($host, $port, $this->settings->timeout)) {
- trigger_error(
- "Couldn't connect to united " . ($isGameServer ? 'game' : lobby) . " server! " . $client->getErrorMessage() .
- "(" . $client->getErrorCode() . ")", E_USER_ERROR);
- }
-
- $login = $serv->xpath('login');
- $pass = $serv->xpath('pass');
- if (!$login || !$pass) {
- trigger_error("Invalid configuration!", E_USER_ERROR);
- }
- $login = (string) $login[0];
- $pass = (string) $pass[0];
-
- // Authenticate
- if (!$client->query('Authenticate', $login, $pass)) {
- trigger_error(
- "Couldn't authenticate on united " . ($isGameServer ? 'game' : 'lobby') . " server with user '" . $login . "'! " .
- $client->getErrorMessage() . "(" . $client->getErrorCode() . ")", E_USER_ERROR);
- }
-
- // Enable callback system
- if (!$client->query('EnableCallbacks', true)) {
- trigger_error("Couldn't enable callbacks! " . $client->getErrorMessage() . "(" . $client->getErrorCode() . ")",
- E_USER_ERROR);
- }
-
- // Wait for server to be ready
- if (!$this->iControl->server->waitForStatus($client, 4)) {
- trigger_error("Server couldn't get ready!", E_USER_ERROR);
- }
-
- // Set api version
- if (!$client->query('SetApiVersion', ManiaControl::API_VERSION)) {
- trigger_error(
- "Couldn't set API version '" . ManiaControl::API_VERSION . "'! This might cause problems. " .
- $this->iControl->getClientErrorText($client));
- }
-
- // Set server settings
- $password = ($isGameServer ? $this->settings->gamePassword : $this->settings->lobbyPassword);
- $hideServer = ($isGameServer && $this->settings->hide_game_server ? 1 : 0);
- // Passwords
- if (!$client->query('SetServerPassword', $password)) {
- trigger_error("Couldn't set server join password. " . $this->iControl->getClientErrorText($client));
- }
- if (!$client->query('SetServerPasswordForSpectator', $password)) {
- trigger_error("Couldn't set server spec password. " . $this->iControl->getClientErrorText($client));
- }
- // Show/Hide server
- if (!$client->query('SetHideServer', $hideServer)) {
- trigger_error(
- "Couldn't set server '" . ($hideServer == 0 ? 'shown' : 'hidden') . "'. " .
- $this->iControl->getClientErrorText($client));
- }
-
- // Enable service announces
- if (!$client->query("DisableServiceAnnounces", false)) {
- trigger_error("Couldn't enable service announces. " . $this->iControl->getClientErrorText($client));
- }
-
- // Set game mode
- if (!$client->query('SetGameMode', $this->settings->gamemode)) {
- trigger_error(
- "Couldn't set game mode (" . $this->settings->gamemode . "). " . $this->iControl->getClientErrorText($client));
- }
- else if (!$client->query('RestartMap')) {
- trigger_error("Couldn't restart map to change game mode. " . $this->iControl->getClientErrorText($client));
- }
-
- // Save client
- $client->index = $index;
- if ($isGameServer) {
- array_push($this->gameServer, $client);
- if (count($this->gameServer) === 1) {
- $this->iControl->client = $client;
- }
- }
- else {
- array_push($this->lobbies, $client);
- }
- }
-
- error_log("United Plugin: Connected to all game and lobby server!");
- }
-
- /**
- * Handle PlayerConnect callback
- *
- * @param array $callback
- */
- public function handlePlayerConnect($callback) {
- if ($this->settings->widgets_enabled) {
- // Send manialinks to the client
- $login = $callback[1][0];
-
- if (Tools::toBool($this->config->widgets->addfavorite->enabled)) {
- // Send favorite widget
- if (!$this->iControl->client->query('SendDisplayManialinkPageToLogin', $login,
- $this->manialinks[self::ML_ADDFAVORITE]->asXml(), 0, false)) {
- trigger_error("Couldn't send favorite widget to player '" . $login . "'! " . $this->iControl->getClientErrorText());
- }
- }
- }
- }
-
- /**
- * Build join link for the given client
- */
- private function getJoinLink(&$client = null, $play = true) {
- if (!$client) {
- $client = $this->gameServer[$this->currentClientIndex];
- }
- if (!$client->query('GetSystemInfo')) {
- trigger_error("Couldn't fetch server system info. " . $this->iControl->getClientErrorText($client));
- return null;
- }
- else {
- $systemInfo = $client->getResponse();
- $password = '';
- if (!$client->query('GetServerPassword')) {
- trigger_error("Couldn't get server password. " . $this->iControl->getClientErrorText($client));
- }
- else {
- $password = $client->getResponse();
- }
- return '#q' . ($play ? 'join' : 'spectate') . '=' . $systemInfo['ServerLogin'] .
- (strlen($password) > 0 ? ':' . $password : '') . '@' . $systemInfo['TitleId'];
- }
- }
-
- /**
- * Build manialink for addfavorite button
- */
- private function buildFavoriteManialink() {
- // Load configs
- $config = $this->config->widgets->addfavorite;
- if (!Tools::toBool($config->enabled)) return;
-
- $pos_x = (float) $config->pos_x;
- $pos_y = (float) $config->pos_y;
- $height = (float) $config->height;
- $width = (float) $config->width;
- $add_all = Tools::toBool($config->add_all);
-
- // Build manialink
- $xml = Tools::newManialinkXml(self::ML_ADDFAVORITE);
-
- $frameXml = $xml->addChild('frame');
- $frameXml->addAttribute('posn', $pos_x . ' ' . $pos_y);
-
- // Background
- $quadXml = $frameXml->addChild('quad');
- Tools::addAlignment($quadXml);
- $quadXml->addAttribute('posn', '0 0 0');
- $quadXml->addAttribute('sizen', $width . ' ' . $height);
- $quadXml->addAttribute('style', 'Bgs1InRace');
- $quadXml->addAttribute('substyle', 'BgTitleShadow');
- $quadXml->addAttribute('action', self::ML_ADDFAVORITE);
-
- // Heart
- $quadXml = $frameXml->addChild('quad');
- Tools::addAlignment($quadXml);
- $quadXml->addAttribute('id', 'Quad_AddFavorite');
- $quadXml->addAttribute('posn', '0 0 1');
- $quadXml->addAttribute('sizen', ($width - 1.) . ' ' . ($height - 0.8));
- $quadXml->addAttribute('style', 'Icons64x64_1');
- $quadXml->addAttribute('substyle', 'StateFavourite');
- $quadXml->addAttribute('scriptevents', '1');
-
- // Tooltip
- $tooltipFrameXml = $frameXml->addChild('frame');
- $tooltipFrameXml->addAttribute('id', 'Frame_FavoriteTooltip');
- $tooltipFrameXml->addAttribute('posn', '0 ' . ($pos_y >= 0 ? '-' : '') . '13');
- $tooltipFrameXml->addAttribute('hidden', '1');
-
- $quadXml = $tooltipFrameXml->addChild('quad');
- Tools::addAlignment($quadXml);
- $quadXml->addAttribute('posn', '0 0 2');
- $quadXml->addAttribute('sizen', '28 16');
- $quadXml->addAttribute('style', 'Bgs1InRace');
- $quadXml->addAttribute('substyle', 'BgTitleShadow');
-
- $labelXml = $tooltipFrameXml->addChild('label');
- Tools::addAlignment($labelXml);
- Tools::addTranslate($labelXml);
- $labelXml->addAttribute('posn', '0 0 3');
- $labelXml->addAttribute('sizen', '26 0');
- $labelXml->addAttribute('style', 'TextTitle1');
- $labelXml->addAttribute('textsize', '2');
- $labelXml->addAttribute('autonewline', '1');
- $countText = '';
- if ($add_all) {
- $count = count($this->gameServer) + count($this->lobbies);
- $countText = 'all ' . $count . ' ';
- }
- $labelXml->addAttribute('text', 'Add ' . $countText . 'server to Favorite!');
-
- // Script for tooltip
- $script = '
-declare Frame_FavoriteTooltip <=> (Page.GetFirstChild("Frame_FavoriteTooltip") as CMlFrame);
-while (True) {
- yield;
- foreach (Event in PendingEvents) {
- switch (Event.Type) {
- case CMlEvent::Type::MouseOver: {
- switch (Event.ControlId) {
- case "Quad_AddFavorite": {
- Frame_FavoriteTooltip.Visible = True;
- }
- }
- }
- case CMlEvent::Type::MouseOut: {
- switch (Event.ControlId) {
- case "Quad_AddFavorite": {
- Frame_FavoriteTooltip.Visible = False;
- }
- }
- }
- }
- }
-}';
- $xml->addChild('script', $script);
-
- $this->manialinks[self::ML_ADDFAVORITE] = $xml;
- }
-}
-
-?>
-
\ No newline at end of file