MegaGlest/source/masterserver/addServerInfo.php

311 lines
15 KiB
PHP

<?php
// Copyright (C) 2012 Mark Vejvoda, Titus Tscharntke and Tom Reynolds
// The Megaglest Team, under GNU GPL v3.0
// ==============================================================
define( 'INCLUSION_PERMITTED', true );
require_once( 'config.php' );
require_once( 'functions.php' );
// Consider using HTTP POST instead of HTTP GET here, data should always be sent via POST for privacy and security reasons
// Alternatively, do not retrieve (and transmit) this data at all via HTTP (other than the IP address the game servers advertises) but fetch it from the game server instead
// general info:
$glestVersion = (string) clean_str( $_GET['glestVersion'] );
$platform = (string) clean_str( $_GET['platform'] );
$binaryCompileDate = (string) clean_str( $_GET['binaryCompileDate'] );
if ( isset( $_GET['privacyPlease'] ) ) {
$privacyPlease = (int) $_GET['privacyPlease'];
}
else
{
$privacyPlease = 0;
}
// game info:
$serverTitle = (string) clean_str( $_GET['serverTitle'] );
$remote_ip = (string) clean_str( $_SERVER['REMOTE_ADDR'] );
// If the clients' IP address belongs to a RFC1918 IP range...
if ( strncmp( $remote_ip, get_localsubnet_ip_prefix(), strlen( get_localsubnet_ip_prefix() ) ) == 0 )
{
// ...then replace it by the master servers' public IP address.
$remote_ip = get_external_ip();
}
$service_port = (int) clean_str( $_GET['externalconnectport'] );
// If the game server port was not transmitted...
if ( $service_port == '' || $service_port == 0 )
{
// ..then assume the default port
$service_port = 61357;
// ... alternatively, refuse such servers
/*
header( 'Content-Type: text/plain; charset=utf-8' );
die( 'Invalid external connect port.');
*/
}
// game setup info:
$tech = (string) clean_str( $_GET['tech'] );
$map = (string) clean_str( $_GET['map'] );
$tileset = (string) clean_str( $_GET['tileset'] );
$activeSlots = (int) clean_str( $_GET['activeSlots'] );
$networkSlots = (int) clean_str( $_GET['networkSlots'] );
$connectedClients = (int) clean_str( $_GET['connectedClients'] );
$status = 0;
if(isset($_GET["gameStatus"])) {
$status = (int) clean_str( $_GET['gameStatus'] );
}
$gameCmd = "";
if(isset($_GET["gameCmd"])) {
$gameCmd = (string) clean_str( $_GET['gameCmd'] );
}
define( 'DB_LINK', db_connect() );
// consider replacing this by a cron job
cleanupServerList();
$gameUUID = "";
$whereClause = 'ip=\'' . mysql_real_escape_string( $remote_ip ) . '\' && externalServerPort=\'' . mysql_real_escape_string( $service_port ) . '\';';
if ( isset( $_GET['gameUUID'] ) ) {
$gameUUID = (string) clean_str( $_GET['gameUUID'] );
$whereClause = 'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';';
}
// echo '#1 ' . $whereClause;
$server_in_db = @mysql_query( 'SELECT ip, externalServerPort FROM glestserver WHERE ' . $whereClause );
$server = @mysql_fetch_row( $server_in_db );
// Representation starts here (but it should really be starting much later, there is way too much logic behind this point)
header( 'Content-Type: text/plain; charset=utf-8' );
if ( (version_compare($glestVersion,"v3.4.0-dev","<") && $connectedClients == $networkSlots) || $gameCmd == "gameOver") // game servers' slots are all full
{
if($gameCmd == "gameOver" && $gameUUID != "")
{
// update database info on this game server; no checks are performed
mysql_query( 'UPDATE glestserver SET ' .
'glestVersion=\'' . mysql_real_escape_string( $glestVersion ) . '\', ' .
'platform=\'' . mysql_real_escape_string( $platform ) . '\', ' .
'binaryCompileDate=\'' . mysql_real_escape_string( $binaryCompileDate ) . '\', ' .
'serverTitle=\'' . mysql_real_escape_string( $serverTitle ) . '\', ' .
'tech=\'' . mysql_real_escape_string( $tech ) . '\', ' .
'map=\'' . mysql_real_escape_string( $map ) . '\', ' .
'tileset=\'' . mysql_real_escape_string( $tileset ) . '\', ' .
'activeSlots=\'' . mysql_real_escape_string( $activeSlots ) . '\', ' .
'networkSlots=\'' . mysql_real_escape_string( $networkSlots ) . '\', ' .
'connectedClients=\'' . mysql_real_escape_string( $connectedClients ) . '\', ' .
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'lasttime=' . 'now()' . ' ' .
'WHERE ' . $whereClause);
}
else
{
// delete server; no checks are performed
mysql_query( 'DELETE FROM glestserver WHERE ' . $whereClause );
}
echo 'OK' ;
} // game in progress
else
{
$game_host_ip = $server[0];
$game_host_port = $server[1];
if ( $gameUUID != "" ) {
$server_in_db_not_timedout = @mysql_query( 'DELETE FROM glestserver WHERE ip=\'' .
mysql_real_escape_string( $remote_ip ) . '\' AND externalServerPort=\'' .
mysql_real_escape_string( $service_port ) . '\' AND gameUUID <> \'' .
mysql_real_escape_string( $gameUUID ) . '\' AND status in (0,1,2);' );
}
if ( ($remote_ip == $game_host_ip && $service_port == $game_host_port) || $status == 2 ) // this server is contained in the database
{
if ( $remote_ip == $game_host_ip && $service_port == $game_host_port)
{
// update database info on this game server; no checks are performed
mysql_query( 'UPDATE glestserver SET ' .
'glestVersion=\'' . mysql_real_escape_string( $glestVersion ) . '\', ' .
'platform=\'' . mysql_real_escape_string( $platform ) . '\', ' .
'binaryCompileDate=\'' . mysql_real_escape_string( $binaryCompileDate ) . '\', ' .
'serverTitle=\'' . mysql_real_escape_string( $serverTitle ) . '\', ' .
'tech=\'' . mysql_real_escape_string( $tech ) . '\', ' .
'map=\'' . mysql_real_escape_string( $map ) . '\', ' .
'tileset=\'' . mysql_real_escape_string( $tileset ) . '\', ' .
'activeSlots=\'' . mysql_real_escape_string( $activeSlots ) . '\', ' .
'networkSlots=\'' . mysql_real_escape_string( $networkSlots ) . '\', ' .
'connectedClients=\'' . mysql_real_escape_string( $connectedClients ) . '\', ' .
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'lasttime=' . 'now()' . ' ' .
'WHERE ' . $whereClause);
//updateServer($remote_ip, $service_port, $serverTitle, $connectedClients, $networkSlots);
echo 'OK';
}
else if ($status == 2)
{
if ( extension_loaded('geoip') ) {
if ( $privacyPlease == 0 )
{
$country = geoip_country_code_by_name( $remote_ip );
}
else
{
$country = '';
}
}
// cleanup old entrys with same remote port and ip
// I hope this fixes those double entrys of servers
mysql_query( 'DELETE FROM glestserver WHERE '. $whereClause );
// insert new entry
mysql_query( 'INSERT INTO glestserver SET ' .
'glestVersion=\'' . mysql_real_escape_string( $glestVersion ) . '\', ' .
'platform=\'' . mysql_real_escape_string( $platform ) . '\', ' .
'binaryCompileDate=\'' . mysql_real_escape_string( $binaryCompileDate ) . '\', ' .
'serverTitle=\'' . mysql_real_escape_string( $serverTitle ) . '\', ' .
'ip=\'' . mysql_real_escape_string( $remote_ip ) . '\', ' .
'tech=\'' . mysql_real_escape_string( $tech ) . '\', ' .
'map=\'' . mysql_real_escape_string( $map ) . '\', ' .
'tileset=\'' . mysql_real_escape_string( $tileset ) . '\', ' .
'activeSlots=\'' . mysql_real_escape_string( $activeSlots ) . '\', ' .
'networkSlots=\'' . mysql_real_escape_string( $networkSlots ) . '\', ' .
'connectedClients=\'' . mysql_real_escape_string( $connectedClients ) . '\', ' .
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'country=\'' . mysql_real_escape_string( $country ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';'
);
echo 'OK';
}
}
else // this game server is not listed in the database, yet
{ // check whether this game server is available from the Internet; if it is, add it to the database
sleep(8); // was 3
$socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
if ( $socket < 0 ) {
echo 'socket_create() failed.' . PHP_EOL . ' Reason: ' . socket_strerror( $socket ) . PHP_EOL;
}
socket_set_nonblock( $socket )
or die( 'Unable to set nonblock on socket.' );
$timeout = 10; //timeout in seconds
echo 'Trying to connect to \'' . $remote_ip . '\' using port \'' . $service_port . '\'...' . PHP_EOL;
$canconnect = true;
$time = time();
error_reporting( E_ERROR );
for ( ; !@socket_connect( $socket, $remote_ip, $service_port ); )
{
$socket_last_error = socket_last_error( $socket );
if ( $socket_last_error == 115 || $socket_last_error == 114)
{
if ( ( time() - $time ) >= $timeout )
{
$canconnect = false;
echo 'socket_connect() failed.' . PHP_EOL . ' Reason: (' . $socket_last_error . ') ' . socket_strerror( $socket_last_error ) . PHP_EOL;
break;
}
sleep( 1 );
continue;
}
// for answers on this see: http://bobobobo.wordpress.com/2008/11/09/resolving-winsock-error-10035-wsaewouldblock/
else if($socket_last_error == 10035 || $socket_last_error == 10037) {
break;
}
$canconnect = false;
echo 'socket_connect() failed.' . PHP_EOL . ' Reason: (' . $socket_last_error . ') ' . socket_strerror( $socket_last_error ) . PHP_EOL;
break;
}
socket_set_block( $socket )
or die( 'Unable to set block on socket.' );
//echo "and now read ....";
//$buf = socket_read($socket, 161);
//echo $buf ."\n";
// Make sure its a glest server connecting
//
// struct Data{
// int8 messageType;
// NetworkString<maxVersionStringSize> versionString;
// NetworkString<maxNameSize> name;
// int16 playerIndex;
// int8 gameState;
// };
if ( $canconnect == true ) {
$data_from_server = socket_read( $socket, 1 );
}
socket_close( $socket );
error_reporting( E_ALL );
if ( $canconnect == false )
{
echo 'wrong router setup';
}
/*
else if ( $data_from_server != 1 ) // insert serious verification here
{
echo "invalid handshake!";
}
*/
else // connection to game server succeeded, protocol verification succeeded
{ // add this game server to the database
if ( extension_loaded('geoip') ) {
if ( $privacyPlease == 0 )
{
$country = geoip_country_code_by_name( $remote_ip );
}
else
{
$country = '';
}
}
// cleanup old entrys with same remote port and ip
// I hope this fixes those double entrys of servers
mysql_query( 'DELETE FROM glestserver WHERE '. $whereClause );
// insert new entry
mysql_query( 'INSERT INTO glestserver SET ' .
'glestVersion=\'' . mysql_real_escape_string( $glestVersion ) . '\', ' .
'platform=\'' . mysql_real_escape_string( $platform ) . '\', ' .
'binaryCompileDate=\'' . mysql_real_escape_string( $binaryCompileDate ) . '\', ' .
'serverTitle=\'' . mysql_real_escape_string( $serverTitle ) . '\', ' .
'ip=\'' . mysql_real_escape_string( $remote_ip ) . '\', ' .
'tech=\'' . mysql_real_escape_string( $tech ) . '\', ' .
'map=\'' . mysql_real_escape_string( $map ) . '\', ' .
'tileset=\'' . mysql_real_escape_string( $tileset ) . '\', ' .
'activeSlots=\'' . mysql_real_escape_string( $activeSlots ) . '\', ' .
'networkSlots=\'' . mysql_real_escape_string( $networkSlots ) . '\', ' .
'connectedClients=\'' . mysql_real_escape_string( $connectedClients ) . '\', ' .
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'country=\'' . mysql_real_escape_string( $country ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';'
);
echo 'OK';
//addLatestServer($remote_ip, $service_port, $serverTitle, $connectedClients, $networkSlots);
}
}
}
db_disconnect( DB_LINK );
?>