From 39c06d80b0ef83827318bc82ec5d5f734d974db7 Mon Sep 17 00:00:00 2001 From: Benedict Etzel Date: Sun, 26 Sep 2010 21:58:21 +0200 Subject: [PATCH] Added C4Masterserver 1.1.5 --- masterserver/readme.txt | 33 ++++ masterserver/web/index.php | 124 ++++++++++++ masterserver/web/masterserver.css | 54 +++++ masterserver/web/server/include/.htaccess | 2 + .../web/server/include/C4Masterserver.php | 187 ++++++++++++++++++ masterserver/web/server/include/C4Network.php | 79 ++++++++ .../web/server/include/FloodProtection.php | 140 +++++++++++++ masterserver/web/server/include/ParseINI.php | 75 +++++++ masterserver/web/server/include/config.ini | 30 +++ masterserver/web/server/index.php | 107 ++++++++++ 10 files changed, 831 insertions(+) create mode 100644 masterserver/readme.txt create mode 100644 masterserver/web/index.php create mode 100644 masterserver/web/masterserver.css create mode 100644 masterserver/web/server/include/.htaccess create mode 100644 masterserver/web/server/include/C4Masterserver.php create mode 100644 masterserver/web/server/include/C4Network.php create mode 100644 masterserver/web/server/include/FloodProtection.php create mode 100644 masterserver/web/server/include/ParseINI.php create mode 100644 masterserver/web/server/include/config.ini create mode 100644 masterserver/web/server/index.php diff --git a/masterserver/readme.txt b/masterserver/readme.txt new file mode 100644 index 000000000..beb624fe7 --- /dev/null +++ b/masterserver/readme.txt @@ -0,0 +1,33 @@ +__Quick start__ +To directly use the masterserver you will need a webserver with PHP >= 5 and access to a MySQL-database. Start by opening the folder web and navigating through server and include, open the config.ini. Enter you're preferences there, everything is documented. +IMPORTANT: Before you continue make sure this folder will be inaccessible through the web later by making sure a working .htaccess is present on an Apache server or there is a corresponding chmod on the whole include folder after uploading later on. +Open a connection to your MySQL-server directly or via a tool like phpMyAdmin and query the command listet below to create the table structure. You can change the default prefix without any problems, just don't forget to change it in your config file. +Now upload the contents of the web/ folder. Now you should be able to open the root and see the server frontend. Make sure again, that the /server/include folder can NOT be accessed via web, since it contains your MySQL-data. +The installation should now be complete and ready to use. You can see the server link on the frontend, just put it in your Clonk network settings and you're done! + +__Database__ + +CREATE TABLE IF NOT EXISTS `c4ms_flood` ( + `ip` char(32) NOT NULL, + `count` int(11) NOT NULL, + `time` char(20) NOT NULL, + PRIMARY KEY (`ip`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + + +CREATE TABLE IF NOT EXISTS `c4ms_games` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(255) NOT NULL, + `csid` varchar(255) NOT NULL, + `data` text NOT NULL, + `start` varchar(255) NOT NULL, + `time` varchar(255) NOT NULL, + `valid` tinyint(4) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +__License__ +This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. + +__Append__ +Please also note that 'Clonk' is a registered trademark of Matthes Bender (http://www.clonk.de) \ No newline at end of file diff --git a/masterserver/web/index.php b/masterserver/web/index.php new file mode 100644 index 000000000..b9a14d14d --- /dev/null +++ b/masterserver/web/index.php @@ -0,0 +1,124 @@ + + * @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0 + */ + +//error_reporting(E_NONE); //suppress errors + +require_once('server/include/C4Masterserver.php'); +require_once('server/include/C4Network.php'); +require_once('server/include/FloodProtection.php'); +require_once('server/include/ParseINI.php'); + +$config = file_get_contents('server/include/config.ini'); +$link = mysql_connect( + ParseINI::ParseValue('mysql_host', $config), + ParseINI::ParseValue('mysql_user', $config), + ParseINI::ParseValue('mysql_password', $config)); //connect to MySQL +$db = mysql_selectdb(ParseINI::ParseValue('mysql_db', $config), $link); //select the database + +if($link && $db) { + $server = new C4Masterserver($link, ParseINI::ParseValue('mysql_prefix', $config)); + $server->SetTimeoutgames(intval(ParseINI::ParseValue('c4ms_timeoutgames', $config))); + $server->SetDeletegames(intval(ParseINI::ParseValue('c4ms_deletegames', $config))); + $server->SetMaxgames(intval(ParseINI::ParseValue('c4ms_maxgames', $config))); + $protect = new FloodProtection($link, ParseINI::ParseValue('mysql_prefix', $config)); + $protect->SetMaxflood(intval(ParseINI::ParseValue('flood_maxrequests', $config))); + if($protect->CheckRequest($_SERVER['REMOTE_ADDR'])) { //flood protection + header('Content-Type: text/plain'); + die('Flood protection.'); + } + $games = ''; + $list = $server->GetReferenceArray(true); + $players = ''; + $count = 0; + foreach($list as $reference) { + if($reference['valid']) { + $games .= ''; + $games .= ''.htmlspecialchars(ParseINI::ParseValue('Title', $reference['data'])).''; + $games .= ''.htmlspecialchars(ParseINI::ParseValue('State', $reference['data'])).''; + $games .= ''.date("Y-m-d H:i", $reference['start']).''; + $players = ''; + $player_list = ParseINI::ParseValuesByCategory('Name', 'Player', $reference['data']); + foreach($player_list as $player) { + if(!empty($players)) $players .= ', '; + $players .= $player; + } + $games .= ''.htmlspecialchars($players).''; + } + if((ParseINI::ParseValue('State', $reference['data']) == 'Running') && $reference['time'] >= time() - 60*60*24) { + $count++; + } + } + $games = C4Network::CleanString($games); + $server->CleanUp(); +} + +$dirname = dirname($_SERVER['SCRIPT_NAME']); +$path = ''; +if($dirname != '/') { + $path .= '/'; +} +$dirname .= $path.'server/'; +$server_link = strtolower($_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$dirname); +$engine = ''; +$engine_string = ParseINI::ParseValue('c4ms_engine', $config); +if(!empty($engine_string)) { + $engine = '('.$engine_string.' only)'; +} +?> + + + + C4Masterserver + + + + + +
+

Masterserver

+ You can reach the masterserver by using the address '.$server_link.''; + if($engine) { + echo ' '.$engine; + } + echo '.

'; + if(!empty($games)) { + echo '

Following games are running now:

'; + echo ''; + echo ''; + echo $games; + echo '
RoundStateBeginPlayers
'; + } + else { + echo '

No games are currently running.

'; + } + if($count > 0) { + if($count > 1) { + echo '

There have been '.$count.' running games in the last 24 hours.

'; + } + else { + echo '

There has been one running game in the last 24 hours.

'; + } + } + else { + echo '

There have been no games running in the last 24 hours.

'; + } + } + else { + echo '

Error: Could not connect to database specified in config.

'; + } + ?> + +
+ + \ No newline at end of file diff --git a/masterserver/web/masterserver.css b/masterserver/web/masterserver.css new file mode 100644 index 000000000..9a9adcb27 --- /dev/null +++ b/masterserver/web/masterserver.css @@ -0,0 +1,54 @@ +body { + font-family: 'Verdana', sans-serif; +} + +#masterserver { + background: none repeat scroll 0 0 transparent; + margin: 0 auto; + padding-left: 76px; + padding-right: 76px; + padding-top: 7px; +} + +#masterserver a, p, table { + font-size: 10pt; + color: black; + text-decoration: none; +} + +#masterserver a { + border-bottom: 1px dotted black; + text-decoration: none; +} + +#masterserver a:hover { + border-bottom: 1px solid black; +} + +#masterserver h1 { + margin: 0 0 2px; + font-size: 1.3em; + font-weight: normal; + color: #222222; + padding: 0px; +} + +#masterserver th { + text-align: center; +} + +#masterserver td { + padding: 5px 30px; +} + +#masterserver_footer { + margin-top: 10px; + border-top: 1px dotted gray; +} + +#masterserver_footer p { + color: gray; + font-size: 0.7em; + margin-top: 2px; + float: right; +} \ No newline at end of file diff --git a/masterserver/web/server/include/.htaccess b/masterserver/web/server/include/.htaccess new file mode 100644 index 000000000..896fbc5a3 --- /dev/null +++ b/masterserver/web/server/include/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all \ No newline at end of file diff --git a/masterserver/web/server/include/C4Masterserver.php b/masterserver/web/server/include/C4Masterserver.php new file mode 100644 index 000000000..a03d89f5c --- /dev/null +++ b/masterserver/web/server/include/C4Masterserver.php @@ -0,0 +1,187 @@ + + * @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0 + */ +class C4Masterserver { + + /** + * Stores the masterserver version. + * + * @var string + */ + static public $version = '1.1.5'; + + /** + * Stores the MySQL connection resource. + * + * @var resource + */ + private $link; + + /** + * Stores the MySQL table prefix. + * + * @var string + */ + private $prefix; + + /** + * Stores the seconds after which games timeout. + * + * @var int + */ + private $timeoutgames; + + /** + * Stores the seconds after which games are removed. + * + * @var int + */ + private $deletegames; + + /** + * Stores the maximum amount of games per ip. + * + * @var int + */ + private $maxgames; + + + /** + * The C4Masterserver constructor. + * + * @param resource $link + * @return C4Masterserver + */ + public function __construct($link, $prefix) { + $this->link = $link; + $this->prefix = $prefix; + $this->timeoutgames = 600; + $this->deletegames = 60*60*24; + $this->maxgames = 5; + } + + /** + * Returns the C4Masterserver version. + * + * @param void + * @return string + */ + public static function GetVersion() { + return(C4Masterserver::$version); + } + + /** + * Sets the seconds after which games timeout. + * + * @param int $timeoutgames + * @return void + */ + public function SetTimeoutgames($timeoutgames) { + $this->timeoutgames = $timeoutgames; + } + + /** + * Sets the seconds after which games are removed. + * + * @param int $deletegames + * @return void + */ + public function SetDeletegames($deletegames) { + $this->deletegames = $deletegames; + } + + /** + * Sets the maximum amount of games per ip. + * + * @param int $maxgames + * @return void + */ + public function SetMaxgames($maxgames) { + $this->maxgames = $maxgames; + } + + /** + * Returns all valid references. If $show_all is true, it returns all references. + * + * @param bool $show_all + * @return array + */ + public function GetReferenceArray($show_all = false) { + if(!$this->link) return false; + $append = $show_all ? '' : 'WHERE `valid` = \'1\''; + $result = mysql_query('SELECT * FROM `'.$this->prefix.'games`'.$append); + $list = array(); + while($row = mysql_fetch_assoc($result)) { + $list[$row['id']] = $row; + } + return $list; + } + + /** + * Adds a new reference and returns the new CSID. + * + * @param string $reference + * @return string + */ + public function AddReference($reference) { + if(!$this->link) return false; + $reference = str_replace('0.0.0.0', $_SERVER['REMOTE_ADDR'], $reference); + $query = mysql_query('SELECT * FROM `'.$this->prefix.'games` WHERE `ip` = \''.$_SERVER['REMOTE_ADDR'].'\' AND `valid` = \'1\'', $this->link); + if(mysql_num_rows($query) > $this->maxgames) { + return false; + } + $csid = sha1(uniqid(mt_rand(), true)); + mysql_query('INSERT INTO `'.$this->prefix.'games` (`id`, `ip`,`csid`, `data`, `start`, `time`, `valid`) VALUES (\'\', \''.$_SERVER['REMOTE_ADDR'].'\', \''.$csid.'\', \''.$reference.'\', \''.time().'\', \''.time().'\', \'1\')', $this->link); + return $csid; + } + + /** + * Updates a reference. + * + * @param string $csid + * @param string $newreference + * @return bool + */ + public function UpdateReference($csid, $newreference) { + if(!$this->link) return false; + $newreference = str_replace('0.0.0.0', $_SERVER['REMOTE_ADDR'], $newreference); + mysql_query('UPDATE `'.$this->prefix.'games` SET `data`=\''.$newreference.'\',`time` = \''.time().'\', `valid` = \'1\' WHERE `csid` = \''.$csid.'\'', $this->link); + return true; + } + + /** + * Removes a reference by setting it invalid. + * + * @param string $csid + * @return bool + */ + public function RemoveReference($csid) { + if(!$this->link) return false; + mysql_query('UPDATE `'.$this->prefix.'games` SET `time` = \''.time().'\', `valid` = \'0\' WHERE `csid` = \''.$csid.'\'', $this->link); + return true; + } + + /** + * Sets old references invalid and removes very old ones if $remove is true. + * + * @param void + * @return void + */ + public function CleanUp() { + if(!$this->link) return false; + if($this->timeoutgames != 0) { + mysql_query('UPDATE `'.$this->prefix.'games` SET `valid` = \'0\' WHERE `time` < \''.(time() - $this->timeoutgames).'\'', $this->link); + } + if($this->deletegames != 0) { + mysql_query('DELETE FROM `'.$this->prefix.'games` WHERE `valid` = \'0\' AND `time` < \''.(time() - $this->deletegames).'\'', $this->link); + } + } +} +?> diff --git a/masterserver/web/server/include/C4Network.php b/masterserver/web/server/include/C4Network.php new file mode 100644 index 000000000..d2c86f391 --- /dev/null +++ b/masterserver/web/server/include/C4Network.php @@ -0,0 +1,79 @@ + + * @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0 + */ +abstract class C4Network { + + /** + * Creates a Clonk 4 conform answer string. + * + * @param array $data + * @return string + */ + public static function CreateAnswer($data) { + $message = '[Response]'."\n"; + foreach ($data as $key => $value) { + $message .= $key.'='.$value."\n"; + } + return $message; + } + + /** + * Returns a Clonk 4 conform error string. + * + * @param string message + * @return string + */ + public static function CreateError($message) { + return C4Network::CreateAnswer(array("Status" => "Failure", "Message" => $message)); + } + + /** + * Sends a Clonk 4 conform answer string. + * + * @param string $message + * @return void + */ + public static function SendAnswer($message) { + header('Content-Length: '.strlen($message)); + echo $message; + } + + /** + * Cleans a Clonk 4 conform text sting human readable. + * + * @param string $message + * @return string + */ + public static function CleanString($message) { + $coded = $decoded = array(); + preg_match_all('|\\\[0-9]{3}|', $message, $coded); + foreach($coded[0] as $numstr) { + $num = ereg_replace("[^0-9]", "", $numstr); + $decoded[$num] = C4Network::DecodeEntitiyString($num); + } + foreach($decoded as $num => $entity) { + $message = str_replace('\\'.$num, $entity, $message); + } + return $message; + } + + /** + * Decodes Clonk 4 conform entitiy string to its character. + * + * @param string $string + * @return string + */ + public static function DecodeEntitiyString($string) { + $num = ereg_replace("[^0-9]", "", $string); + $num = octdec($num); + return iconv('Windows-1252', 'UTF-8', chr($num)); + } +} +?> \ No newline at end of file diff --git a/masterserver/web/server/include/FloodProtection.php b/masterserver/web/server/include/FloodProtection.php new file mode 100644 index 000000000..bc500b1ba --- /dev/null +++ b/masterserver/web/server/include/FloodProtection.php @@ -0,0 +1,140 @@ + + * @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0 + */ +class FloodProtection { + + /** + * Stores the MySQL connection resource. + * + * @var resource + */ + private $link; + + /** + * Stores the MySQL table prefix. + * + * @var string + */ + private $prefix; + + /** + * Stores the maximum alloud requests per second per ip. + * + * @var int + */ + private $maxflood; + + /** + * The FloodProtection constructor. + * + * @param resource $link + * @return FloodProtection + */ + public function __construct($link, $prefix) { + $this->link = $link; + $this->prefix = $prefix; + $this->maxflood = 5; + } + + /** + * Sets the maximum alloud requests per second per ip. + * + * @param int $maxflood + * @return void + */ + public function SetMaxflood($maxflood) { + $this->maxflood = $maxflood; + } + + /** + * Checks a request and returns true if the user is flooding. + * + * @param string $ip + * @return bool + */ + public function CheckRequest($ip) { + if(!$this->link) return false; + if($this->UserKnown($ip)) { + $this->UpdateUser($ip); + $this->CleanUp(); + return $this->UserFlooding($ip); + } + $this->AddUser($ip); + $this->CleanUp(); + return false; + } + + /** + * Returns, if a user is already in the table. + * + * @param string $ip + * @return bool + */ + private function UserKnown($ip) { + if(!$this->link) return false; + $query = mysql_query('SELECT `time` FROM `'.$this->prefix.'flood` WHERE `ip` = \' '.$ip. '\' LIMIT 1', $this->link); + if(mysql_num_rows($query) > 0) { + return true; + } + return false; + } + + /** + * Adds a new user to the table. + * + * @param string $ip + * @return bool + */ + private function AddUser($ip) { + if(!$this->link) return false; + $query = mysql_query('INSERT INTO `'.$this->prefix.'flood` (`ip`, `count`, `time`) VALUES (\' '.$ip. '\', \'0\',\''. time() .'\') ', $this->link); + if(!$query) { + return false; + } + return true; + } + + /** + * Checks if the given user is flooding the server. + * + * @param string $ip + * @return bool + */ + private function UpdateUser($ip) { + if(!$this->link) return false; + mysql_query('UPDATE `'.$this->prefix.'flood` SET `count` = \'0\' WHERE `ip` = \' '.$ip.'\' AND `time` != \''.time().'\'', $this->link); + mysql_query('UPDATE `'.$this->prefix.'flood` SET `count` = `count`+\'1\', `time` = \''.time().'\' WHERE `ip` = \' '. mysql_real_escape_string($ip, $this->link).'\'', $this->link); + } + + /** + * Checks if the given user is flooding the server. + * + * @param string $ip + * @return bool + */ + private function UserFlooding($ip) { + if(!$this->link) return false; + $query = mysql_query('SELECT `time` FROM `'.$this->prefix.'flood` WHERE `ip` = \' '.$ip.'\' AND `count` >= \''.$this->maxflood.'\' LIMIT 1', $this->link); + if(mysql_num_rows($query) > 0) { + return true; + } + return false; + } + + /** + * Removes old entrys. + * + * @return void + */ + private function CleanUp() { + mysql_query('DELETE FROM `'.$this->prefix.'flood` WHERE `time` <= \'' . (time()- 600) . '\'', $this->link); + } +} +?> \ No newline at end of file diff --git a/masterserver/web/server/include/ParseINI.php b/masterserver/web/server/include/ParseINI.php new file mode 100644 index 000000000..807e539e9 --- /dev/null +++ b/masterserver/web/server/include/ParseINI.php @@ -0,0 +1,75 @@ + + * @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0 + */ +abstract class ParseINI { + + /** + * Returns the value belonging to the key from an ini-like string. + * + * @param string $key + * @param string $string + * @return string + */ + public static function ParseValue($key, $string) { + if(!$key || !$string) { + return false; + } + if(strpos($string, $key) === false) { + return false; + } + $value = ''; + $key_start = strpos($string, $key."=") + strlen($key) + 1; + $key_end = strpos($string, "\n", $key_start); + if($key_end === false) { + $value = substr($string, $key_start); + } + else { + $value = substr($string, $key_start, $key_end - $key_start); + } + $value = trim($value); + return trim($value, '"'); + } + + /** + * Returns all values in a certain category and supports multiple appereances. + * + * @param string $key + * @param string $category + * @param string $string + * @return array + */ + public static function ParseValuesByCategory($key, $category, $string) { + if(!$key || !$string || !$category) { + return false; + } + if(strpos($string, $key) === false || strpos($string, '['.$category.']') === false) { + return false; + } + $values = array(); + $lines = explode("\n", $string); + $current_category = ''; + foreach($lines as $line) { + $line = trim($line); + if(strpos($line, '[') !== false && strpos($line, ']') !== false && strpos($line, '=') === false) { + $start = strpos($line, '[') + 1; + $end = strpos($line, ']') - 1; + $current_category = substr($line, $start, $end); + } + if($current_category != $category) continue; //wrong category + if(strpos($line, ';') === 0) continue; //comment + if(strpos($line, $key) === false) continue; //not needed + $value = ParseINI::ParseValue($key, $line); + $value = trim($value); + $values[] = trim($value, '"'); + } + return $values; + } +} +?> diff --git a/masterserver/web/server/include/config.ini b/masterserver/web/server/include/config.ini new file mode 100644 index 000000000..9c429e8ca --- /dev/null +++ b/masterserver/web/server/include/config.ini @@ -0,0 +1,30 @@ +[C4Masterserver] +;your MySQL host, usually localhost +mysql_host=localhost + +;your MySQL user +mysql_user=root + +;your MySQL password +mysql_password= + +;your MySQL database +mysql_db=c4ms + +;your MySQL prefix, default c4ms_ +mysql_prefix=c4ms_ + +;accepted engine strings, leave empty to allow all (Example: OpenClonk) +c4ms_engine= + +;seconds after timing out old games, default 60*10 = 600 +c4ms_timeoutgames=600 + +;seconds after deleting old games, default 60*60*24 = 86400 +c4ms_deletegames=86400 + +;maximum alloud games per ip, default 5 +c4ms_maxgames=5 + +;maximum alloud requests per second, default 5 +flood_maxrequests=5 \ No newline at end of file diff --git a/masterserver/web/server/index.php b/masterserver/web/server/index.php new file mode 100644 index 000000000..dce166a40 --- /dev/null +++ b/masterserver/web/server/index.php @@ -0,0 +1,107 @@ + + * @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0 + */ + +//error_reporting(E_NONE); //suppress errors + +require_once('include/C4Masterserver.php'); +require_once('include/C4Network.php'); +require_once('include/FloodProtection.php'); +require_once('include/ParseINI.php'); + +$config = file_get_contents('include/config.ini'); +$link = mysql_connect( + ParseINI::ParseValue('mysql_host', $config), + ParseINI::ParseValue('mysql_user', $config), + ParseINI::ParseValue('mysql_password', $config)); //connect to MySQL +$db = mysql_selectdb(ParseINI::ParseValue('mysql_db', $config), $link); //select the database + +header('Content-Type: text/plain'); //output as plain text + +if($link && $db) { + $server = new C4Masterserver($link, ParseINI::ParseValue('mysql_prefix', $config)); + $server->SetTimeoutgames(intval(ParseINI::ParseValue('c4ms_timeoutgames', $config))); + $server->SetDeletegames(intval(ParseINI::ParseValue('c4ms_deletegames', $config))); + $server->SetMaxgames(intval(ParseINI::ParseValue('c4ms_maxgames', $config))); + $protect = new FloodProtection($link, ParseINI::ParseValue('mysql_prefix', $config)); + $protect->SetMaxflood(intval(ParseINI::ParseValue('flood_maxrequests', $config))); + if($protect->CheckRequest($_SERVER['REMOTE_ADDR'])) { //flood protection + C4Network::SendAnswer(C4Network::CreateError('Flood protection.')); + die(); + } + $server->CleanUp(true); //Cleanup old stuff + if(isset($GLOBALS['HTTP_RAW_POST_DATA'])) { //data sent from engine? + $input = $GLOBALS['HTTP_RAW_POST_DATA']; + $action = ParseINI::ParseValue('Action', $input); + $csid = ParseINI::ParseValue('CSID', $input); + $csid = mysql_real_escape_string($csid, $link); + $reference = mysql_real_escape_string(strstr($input, '[Reference]'), $link); + $engine_string = ParseINI::ParseValue('c4ms_engine', $config); + if(empty($engine_string) || ParseINI::ParseValue('Game', $input) == $engine_string) { + switch($action) { + case 'Start': //start a new round + if(ParseINI::ParseValue('LeagueAddress', $reference)) { + C4Network::SendAnswer(C4Network::CreateError('League not supported!')); + } + else { + $csid = $server->AddReference($reference); + if($csid) { + C4Network::SendAnswer(C4Network::CreateAnswer(array('Status' => 'Success', 'CSID' => $csid))); + } + else { + C4Network::SendAnswer(C4Network::CreateError('Round signup failed. (To many tries?)')); + } + } + break; + case 'Update': //update an existing round + if($server->UpdateReference($csid, $reference)) { + C4Network::SendAnswer(C4Network::CreateAnswer(array('Status' => 'Success'))); + } + else { + C4Network::SendAnswer(C4Network::CreateError('Round update failed.')); + } + break; + case 'End': //remove a round + if($server->RemoveReference($csid)) { + C4Network::SendAnswer(C4Network::CreateAnswer(array('Status' => 'Success'))); + } + else { + C4Network::SendAnswer(C4Network::CreateError('Round end failed.')); + } + break; + default: + if (!empty($action)) { + C4Network::SendAnswer(C4Network::CreateError('Unknown action.')); + } + else { + C4Network::SendAnswer(C4Network::CreateError('No action defined.')); + } + break; + } + } + else { + C4Network::SendAnswer(C4Network::CreateError('Wrong engine.')); + } + } + else { //list availabe games + $list = $server->GetReferenceArray(false); + $message = ''; + foreach($list as $reference) { + if(!empty($message)) $message .= "\n\n"; + $message .= $reference['data']; + $message .= 'GameId='.$reference['id']."\n"; + } + C4Network::SendAnswer($message); + } + mysql_close($link); +} +else { + C4Network::SendAnswer(C4Network::CreateError('Database error.')); +} +?> \ No newline at end of file