Implemented OpenClonk update System, updated files, updated to version 1.2.0

Benedict Etzel 2010-11-17 18:55:37 +01:00
parent a49116bdc4
commit 62e17d2499
8 changed files with 427 additions and 334 deletions

View File

@ -7,27 +7,38 @@ The installation should now be complete and ready to use. You can see the server
__Database__
CREATE TABLE IF NOT EXISTS `c4ms_flood` (
`ip` char(32) NOT NULL,
CREATE TABLE `c4ms_flood` (
`ip` char(32) CHARACTER SET latin1 NOT NULL,
`count` int(11) NOT NULL,
`time` char(20) NOT NULL,
`time` char(20) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `c4ms_games` (
CREATE TABLE `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,
`ip` varchar(255) CHARACTER SET latin1 NOT NULL,
`csid` varchar(255) CHARACTER SET latin1 NOT NULL,
`data` text CHARACTER SET latin1 NOT NULL,
`start` varchar(255) CHARACTER SET latin1 NOT NULL,
`time` varchar(255) CHARACTER SET latin1 NOT NULL,
`valid` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
__Updates__
If you are running an update service for OpenClonk, you also need to insert the following table and specifiy the config entries. (see there for more details)
CREATE TABLE `c4ms_update` (
`old_version` varchar(16) CHARACTER SET latin1 NOT NULL,
`new_version` varchar(16) CHARACTER SET latin1 NOT NULL,
`platform` varchar(64) CHARACTER SET latin1 NOT NULL,
`file` varchar(255) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`old_version`,`platform`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
__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)
Please also note that 'Clonk' is a registered trademark of Matthes Bender (http://www.clonk.de).

View File

@ -3,7 +3,7 @@
* C4Masterserver main frontend
*
* @package C4Masterserver
* @version 1.1.5-en
* @version 1.2.0-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
@ -17,46 +17,46 @@ 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
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
$server = new C4Masterserver($link, $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);
$list = $server->getReferenceArray(true);
$players = '';
$count = 0;
foreach($list as $reference) {
if($reference['valid']) {
$games .= '<tr>';
$games .= '<td>'.htmlspecialchars(ParseINI::ParseValue('Title', $reference['data'])).'</td>';
$games .= '<td>'.htmlspecialchars(ParseINI::ParseValue('State', $reference['data'])).'</td>';
$games .= '<td>'.htmlspecialchars(ParseINI::parseValue('Title', $reference['data'])).'</td>';
$games .= '<td>'.htmlspecialchars(ParseINI::parseValue('State', $reference['data'])).'</td>';
$games .= '<td>'.date("Y-m-d H:i", $reference['start']).'</td>';
$players = '';
$player_list = ParseINI::ParseValuesByCategory('Name', 'Player', $reference['data']);
$player_list = ParseINI::parseValuesByCategory('Name', 'Player', $reference['data']);
foreach($player_list as $player) {
if(!empty($players)) $players .= ', ';
$players .= $player;
}
$games .= '<td>'.htmlspecialchars($players).'</td>';
}
if((ParseINI::ParseValue('State', $reference['data']) == 'Running') && $reference['time'] >= time() - 60*60*24) {
if((ParseINI::parseValue('State', $reference['data']) == 'Running') && $reference['time'] >= time() - 60*60*24) {
$count++;
}
}
$games = C4Network::CleanString($games);
$server->CleanUp();
$games = C4Network::cleanString($games);
$server->cleanUp();
}
$dirname = dirname($_SERVER['SCRIPT_NAME']);
@ -67,7 +67,7 @@ if($dirname != '/') {
$dirname .= $path.'server/';
$server_link = strtolower($_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$dirname);
$engine = '';
$engine_string = ParseINI::ParseValue('c4ms_engine', $config);
$engine_string = ParseINI::parseValue('c4ms_engine', $config);
if(!empty($engine_string)) {
$engine = '('.$engine_string.' only)';
}
@ -117,7 +117,7 @@ if(!empty($engine_string)) {
}
?>
<div id="masterserver_footer">
<p>Powered by C4Masterserver v<?php echo C4Masterserver::GetVersion(); ?> &bull; Coded by Benedict Etzel</p>
<p>Powered by C4Masterserver v<?php echo C4Masterserver::GetVersion(); ?> &raquo; Coded by Benedict Etzel</p>
</div>
</div>
</body>

View File

@ -1,187 +1,199 @@
<?php
/**
* Provides functionality to add, update and remove
* game references based on a MySQL table.
*
* @package C4Masterserver
* @version 1.1.5-en
* @author Benedict Etzel <b.etzel@live.de>
* @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';
/**
* Provides functionality to add, update and remove
* game references based on a MySQL table.
*
* @package C4Masterserver
* @version 1.2.0-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
class C4Masterserver {
/**
* Stores the MySQL connection resource.
*
* @var resource
*/
private $link;
/**
* Stores the masterserver version.
*
* @var string
*/
static public $version = '1.2.0';
/**
* Stores the MySQL connection resource.
*
* @var resource
*/
private $link;
/**
* Stores the MySQL table prefix.
*
* @var string
*/
private $config;
/**
* 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;
/**
* Stores the MySQL table prefix.
*
* @var string
*/
private $prefix;
/**
* The C4Masterserver constructor.
*
* @param resource $link
* @return C4Masterserver
*/
public function __construct($link, $config) {
$this->link = $link;
$this->config = $config;
$this->timeoutgames = 600;
$this->deletegames = 60 * 60 * 24;
$this->maxgames = 5;
}
/**
* Stores the seconds after which games timeout.
*
* @var int
*/
private $timeoutgames;
/**
* Returns the C4Masterserver version.
*
* @param void
* @return string
*/
public static function getVersion() {
return(C4Masterserver::$version);
}
/**
* Stores the seconds after which games are removed.
*
* @var int
*/
private $deletegames;
/**
* Sets the seconds after which games timeout.
*
* @param int $timeoutgames
* @return void
*/
public function setTimeoutgames($timeoutgames) {
$this->timeoutgames = $timeoutgames;
}
/**
* Stores the maximum amount of games per ip.
*
* @var int
*/
private $maxgames;
/**
* 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;
}
/**
* 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 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 `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'games`' . $append);
$list = array();
while ($row = mysql_fetch_assoc($result)) {
$list[$row['id']] = $row;
}
return $list;
}
/**
* Returns the C4Masterserver version.
*
* @param void
* @return string
*/
public static function GetVersion() {
return(C4Masterserver::$version);
}
/**
* 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 `' . ParseINI::parseValue('mysql_prefix', $this->config) . '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 `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'games` (`id`, `ip`,`csid`, `data`, `start`, `time`, `valid`) VALUES (\'\', \'' . $_SERVER['REMOTE_ADDR'] . '\', \'' . $csid . '\', \'' . $reference . '\', \'' . time() . '\', \'' . time() . '\', \'1\')', $this->link);
return $csid;
}
/**
* Sets the seconds after which games timeout.
*
* @param int $timeoutgames
* @return void
*/
public function SetTimeoutgames($timeoutgames) {
$this->timeoutgames = $timeoutgames;
}
/**
* 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 `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'games` SET `data`=\'' . $newreference . '\',`time` = \'' . time() . '\', `valid` = \'1\' WHERE `csid` = \'' . $csid . '\'', $this->link);
return true;
}
/**
* Sets the seconds after which games are removed.
*
* @param int $deletegames
* @return void
*/
public function SetDeletegames($deletegames) {
$this->deletegames = $deletegames;
}
/**
* Removes a reference by setting it invalid.
*
* @param string $csid
* @return bool
*/
public function removeReference($csid) {
if (!$this->link)
return false;
mysql_query('UPDATE `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'games` SET `time` = \'' . time() . '\', `valid` = \'0\' WHERE `csid` = \'' . $csid . '\'', $this->link);
return true;
}
/**
* Sets the maximum amount of games per ip.
*
* @param int $maxgames
* @return void
*/
public function SetMaxgames($maxgames) {
$this->maxgames = $maxgames;
}
/**
* 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 `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'games` SET `valid` = \'0\' WHERE `time` < \'' . (time() - $this->timeoutgames) . '\'', $this->link);
}
if ($this->deletegames != 0) {
mysql_query('DELETE FROM `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'games` WHERE `valid` = \'0\' AND `time` < \'' . (time() - $this->deletegames) . '\'', $this->link);
}
}
/**
* 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;
}
public function getDownloadURL($platform) {
$result = mysql_query('SELECT `file` FROM `' . ParseINI::parseValue('mysql_prefix', $this->config) . 'update` WHERE `old_version` = \'\' AND `platform` = \'' . $platform . '\'');
if ($result) {
$row = mysql_fetch_assoc($result);
if ($row['file'])
return ParseINI::parseValue('oc_update_url', $this->config) . $row['file'];
}
return false;
}
/**
* 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);
}
}
}
?>

View File

@ -4,7 +4,7 @@
* Clonk 4 engine with ini-style strings.
*
* @package C4Masterserver
* @version 1.1.5-en
* @version 1.2.0-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
@ -16,7 +16,7 @@ abstract class C4Network {
* @param array $data
* @return string
*/
public static function CreateAnswer($data) {
public static function createAnswer($data) {
$message = '[Response]'."\n";
foreach ($data as $key => $value) {
$message .= $key.'='.$value."\n";
@ -30,8 +30,8 @@ abstract class C4Network {
* @param string message
* @return string
*/
public static function CreateError($message) {
return C4Network::CreateAnswer(array("Status" => "Failure", "Message" => $message));
public static function createError($message) {
return C4Network::createAnswer(array("Status" => "Failure", "Message" => $message));
}
/**
@ -40,8 +40,8 @@ abstract class C4Network {
* @param string $message
* @return void
*/
public static function SendAnswer($message) {
//header('Content-Length: '.strlen($message));
public static function sendAnswer($message) {
header('Content-Length: '.strlen($message));
echo $message;
}
@ -51,12 +51,12 @@ abstract class C4Network {
* @param string $message
* @return string
*/
public static function CleanString($message) {
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);
$decoded[$num] = C4Network::decodeEntitiyString($num);
}
foreach($decoded as $num => $entity) {
$message = str_replace('\\'.$num, $entity, $message);
@ -70,7 +70,7 @@ abstract class C4Network {
* @param string $string
* @return string
*/
public static function DecodeEntitiyString($string) {
public static function decodeEntitiyString($string) {
$num = ereg_replace("[^0-9]", "", $string);
$num = octdec($num);
return iconv('Windows-1252', 'UTF-8', chr($num));

View File

@ -4,7 +4,7 @@
* flooding attempts by ip.
*
* @package C4Masterserver
* @version 1.1.5-en
* @version 1.2.0-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
@ -49,7 +49,7 @@ class FloodProtection {
* @param int $maxflood
* @return void
*/
public function SetMaxflood($maxflood) {
public function setMaxflood($maxflood) {
$this->maxflood = $maxflood;
}
@ -59,7 +59,7 @@ class FloodProtection {
* @param string $ip
* @return bool
*/
public function CheckRequest($ip) {
public function checkRequest($ip) {
if(!$this->link) return false;
if($this->UserKnown($ip)) {
$this->UpdateUser($ip);
@ -77,7 +77,7 @@ class FloodProtection {
* @param string $ip
* @return bool
*/
private function UserKnown($ip) {
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) {
@ -92,7 +92,7 @@ class FloodProtection {
* @param string $ip
* @return bool
*/
private function AddUser($ip) {
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) {
@ -107,7 +107,7 @@ class FloodProtection {
* @param string $ip
* @return bool
*/
private function UpdateUser($ip) {
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);
@ -119,7 +119,7 @@ class FloodProtection {
* @param string $ip
* @return bool
*/
private function UserFlooding($ip) {
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) {
@ -133,7 +133,7 @@ class FloodProtection {
*
* @return void
*/
private function CleanUp() {
private function cleanUp() {
mysql_query('DELETE FROM `'.$this->prefix.'flood` WHERE `time` <= \'' . (time()- 600) . '\'', $this->link);
}
}

View File

@ -4,7 +4,7 @@
* from an ini-like string.
*
* @package C4Masterserver
* @version 1.1.5-en
* @version 1.2.0-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
@ -17,7 +17,7 @@ abstract class ParseINI {
* @param string $string
* @return string
*/
public static function ParseValue($key, $string) {
public static function parseValue($key, $string) {
if(!$key || !$string) {
return false;
}
@ -34,7 +34,10 @@ abstract class ParseINI {
$value = substr($string, $key_start, $key_end - $key_start);
}
$value = trim($value);
return trim($value, '"');
$value = trim($value, '"');
if($value == 'true') $value = 1;
if($value == 'false') $value = 0;
return $value;
}
/**
@ -45,7 +48,7 @@ abstract class ParseINI {
* @param string $string
* @return array
*/
public static function ParseValuesByCategory($key, $category, $string) {
public static function parseValuesByCategory($key, $category, $string) {
if(!$key || !$string || !$category) {
return false;
}
@ -65,9 +68,7 @@ abstract class ParseINI {
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, '"');
$values[] = ParseINI::parseValue($key, $line);
}
return $values;
}

View File

@ -14,17 +14,35 @@ mysql_db=c4ms
;your MySQL prefix, default c4ms_
mysql_prefix=c4ms_
;accepted engine strings, leave empty to allow all (Example: OpenClonk)
;accepted engine strings, has to be set (Example: OpenClonk)
c4ms_title_engine=OpenClonk
;accepted engine strings (to forbid certain engines), leave empty to allow all (Example: OpenClonk)
c4ms_engine=
;seconds after timing out old games, default 60*10 = 600
c4ms_timeoutgames=600
;message of the day (shown in the network screen)
c4ms_motd=<c 0fff0f>Which is worse: ignorance or apathy? Who knows? Who cares?</c>
;seconds after timing out old games, default 60*3 = 180
c4ms_timeoutgames=180
;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 games per ip, default 1
c4ms_maxgames=1
;maximum alloud requests per second, default 5
flood_maxrequests=5
flood_maxrequests=5
;enable the OpenClonk update system, default 0
oc_enable_update=false
;path to the update files
oc_update_path=
;url to the update files with trailing slash, shouldn't be empty
oc_update_url=http://www.example.com/
;secret key for the HAMC-updating system (using sha256) to verify files
oc_update_secret=

View File

@ -1,107 +1,158 @@
<?php
/**
* C4Masterserver engine backend
*
* @package C4Masterserver
* @version 1.1.5-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
//error_reporting(E_NONE); //suppress errors
/**
* C4Masterserver engine backend
*
* @package C4Masterserver
* @version 1.2.0-en
* @author Benedict Etzel <b.etzel@live.de>
* @license http://creativecommons.org/licenses/by/3.0/ CC-BY 3.0
*/
//error_reporting(E_ALL); //suppress errors
require_once('include/C4Masterserver.php');
require_once('include/C4Network.php');
require_once('include/FloodProtection.php');
require_once('include/ParseINI.php');
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
$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
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 = "[OpenClonk]\nVersion=4,10,0,3\nMOTD=<c 0fff0f>Which is worse: ignorance or apathy? Who knows? Who cares?\n\n";
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.'));
}
if ($link && $db) {
$prefix = ParseINI::parseValue('mysql_prefix', $config);
$server = new C4Masterserver($link, $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, $prefix);
$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 (ParseINI::parseValue('oc_enable_update', $config) == 1 && isset($_GET['action']) && $_GET['action'] == 'release-file' && isset($_GET['file']) && isset($_GET['hash']) && isset($_GET['new_version']) && isset($_GET['platform'])) {
$file = ParseINI::parseValue('oc_update_path', $config) . $_GET['file'];
if (file_exists($file) && hash_hmac_file('sha256', $file, ParseINI::parseValue('oc_update_secret', $config)) == $_GET['hash']) {
$old_version = isset($_GET['old_version']) ? explode(',', mysql_real_escape_string($_GET['old_version'], $link)) : array();
$new_version = mysql_real_escape_string($_GET['new_version'], $link);
$platform = mysql_real_escape_string($_GET['platform'], $link);
$file = mysql_real_escape_string($file, $link);
if (!empty($old_version)) {
if (isset($_GET['delete_old_files']) && $_GET['delete_old_files'] == 'yes') {
$result = mysql_query('SELECT `file` FROM `' . $prefix . 'update` WHERE `new_version` != \'' . $new_version . '\' AND `old_version` != \'\' AND `platform` = \'' . $platform . '\'');
while (($row = mysql_fetch_assoc($result)) != false) {
unlink(ParseINI::parseValue('oc_update_path', $config) . $row['file']);
}
}
mysql_query('DELETE FROM `' . $prefix . 'update` WHERE `new_version` != \'' . $new_version . '\' AND `old_version` != \'\' AND `platform` = \'' . $platform . '\'');
foreach ($old_version as $version) {
mysql_query('INSERT INTO `' . $prefix . 'update` (`old_version`, `new_version`, `platform`, `file`) VALUES (\'' . $version . '\', \'' . $new_version . '\', \'' . $platform . '\', \'' . $file . '\')');
}
} else {
if (isset($_GET['delete_old_files']) && $_GET['delete_old_files'] == 'yes') {
$row = mysql_fetch_assoc(mysql_query('SELECT `file` FROM `' . $prefix . 'update` WHERE `old_version` = \'\' AND `platform` = \'' . $platform . '\''));
unlink(ParseINI::parseValue('oc_update_path', $config) . $row['file']);
}
mysql_query('DELETE FROM `' . $prefix . 'update` WHERE `old_version` = \'\' AND `platform` = \'' . $platform . '\'');
mysql_query('INSERT INTO `' . $prefix . 'update` (`old_version`, `new_version`, `platform`, `file`) VALUES (\'\', \'' . $new_version . '\', \'' . $platform . '\', \'' . $file . '\')');
}
} else {
C4Network::sendAnswer(C4Network::createError('File not found or hash incorrect.'));
}
} else 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, "' . ParseINI::parseValue('Game', $input) . '" expected.'));
}
} else { //list availabe games
if (!isset($_GET['action']) || $_GET['action'] == 'version')
$list = $server->getReferenceArray(false);
$message = '';
$engine = ParseINI::parseValue('c4ms_title_engine', $config);
$platform = isset($_GET['platform']) ? mysql_real_escape_string($_GET['platform'], $link) : 0;
$client_version = isset($_GET['version']) ? mysql_real_escape_string($_GET['version'], $link) : 0;
if (!empty($engine)) {
$message .= '[' . $engine . ']' . PHP_EOL;
if (ParseINI::parseValue('oc_enable_update', $config) == 1) {
if ($platform && $client_version) {
$result = mysql_query('SELECT `new_version` FROM `' . ParseINI::parseValue('mysql_prefix', $config) . 'update` WHERE `old_version` = \'\' AND `platform` = \'' . $platform . '\'');
$row = mysql_fetch_assoc($result);
$version = $row['new_version'];
if ($version) {
$message .= 'Version=' . $version . PHP_EOL;
if (version_compare($client_version, $version) < 0) { //We need to update
$result = mysql_query('SELECT `file` FROM `' . $prefix . 'update` WHERE `old_version` = \'' . $client_version . '\' AND `platform` = \'' . $platform . '\'');
$row = mysql_fetch_assoc($result);
if ($row['file'])
$message .= 'UpdateURL=' . ParseINI::parseValue('oc_update_url', $config) . $row['file'] . PHP_EOL;
}
}
}
}
$motd = ParseINI::parseValue('c4ms_motd', $config);
if (!empty($motd))
$message .= 'MOTD=' . $motd . PHP_EOL;
}
foreach ($list as $reference) {
if (!empty($message))
$message .= PHP_EOL;
$message .= $reference['data'];
$message .= 'GameId=' . $reference['id'] . PHP_EOL;
$message .= 'OfficialServer=false' . PHP_EOL;
}
C4Network::sendAnswer($message);
}
mysql_close($link);
}
else {
C4Network::sendAnswer(C4Network::createError('Database error.'));
}
?>