User:Pizzahut/msqp.php: Difference between revisions
Jump to navigation
Jump to search
m (This seems to be fixed on Valve's end - getting 130 to 150 servers now.) |
(Added seeding for long server lists (more than 231 servers).) |
||
Line 1: | Line 1: | ||
This is a code example for querying a Half-Life master server using the PHP language | This is a code example for querying a Half-Life master server using the PHP language. | ||
<pre> | <pre> | ||
<?php | <?php | ||
/* | /* | ||
Version history | |||
1 Initial release. | 1 Initial release. | ||
2 Added option to retry same server if timeout occurs. | 2 Added option to retry same server if timeout occurs. | ||
2.1 Added more master servers. | 2.1 Added more master servers. | ||
2.1.1 Fixed a bug, program didn't terminate if all master servers time out. | 2.1.1 Fixed a bug, program didn't terminate if all master servers time out. | ||
2.1.2 Removed a now redundant variable. | 2.1.2 Removed a now redundant variable. | ||
2.2 Seeding for long server lists. | |||
*/ | */ | ||
$master_servers = array("72.165.61.136", "68.142.72.250", "72.165.61.189", | |||
"72.165.61.190", "69.28.151.162"); | |||
function query_timeout(&$socket, $seed) | |||
function | |||
{ | { | ||
// region=world, filter: game=Half-Life | |||
if (!fwrite($socket, "1\xFF$seed\0\\gamedir\\valve\0")) | |||
// region=world, filter: game= | |||
if (!fwrite($ | |||
{ | { | ||
fclose($ | fclose($socket); | ||
exit("fwrite error\n"); | exit("fwrite error\n"); | ||
} | } | ||
$s = bin2hex(fread($ | $s = bin2hex(fread($socket, 6)); | ||
$info = stream_get_meta_data($ | $info = stream_get_meta_data($socket); | ||
if ($info['timed_out']) | if ($info['timed_out']) | ||
{ | { | ||
echo "Master server \"$ | echo "Master server \"$seed\" timed out.\n"; | ||
fclose($ | fclose($socket); | ||
} else { | } | ||
if ($s !== "ffffffff660a") { | else | ||
fclose($ | { | ||
if ($s !== "ffffffff660a") | |||
{ | |||
fclose($socket); | |||
exit("Expected ff ff ff ff 66 0a (hex) but got $s."); | exit("Expected ff ff ff ff 66 0a (hex) but got $s."); | ||
} | } | ||
Line 59: | Line 46: | ||
} | } | ||
// Connect to master server, return timeout info. | |||
// The socket is passed as reference and thus returned as well. | |||
function master_server_timeout(&$socket, $ip) | |||
{ | { | ||
$ | $port = 27010; | ||
$timeout = 1; | |||
echo "Connecting to master server \"$ip\".\n"; | |||
$socket = fsockopen("udp://$ip", $port, $errno, $errstr, $timeout); | |||
if (!$socket) | |||
exit("Error $errno : $errstr \n"); | |||
stream_set_timeout($socket, $timeout); | |||
return query_timeout($socket, "0.0.0.0:0"); | |||
} | } | ||
// Try all master servers unless we find one that isn't timing out. | |||
$abort = 1; | |||
foreach ($master_servers as $ip) | |||
{ | { | ||
if (!master_server_timeout($socket, $ip)) | |||
{ | { | ||
$abort = 0; | |||
break; | |||
} | } | ||
} | } | ||
if ($abort == 1) | |||
exit("All master servers timed out, aborting.\n"); | |||
// Read list with server addresses (IP:port). | |||
$count = 0; | $count = 0; | ||
do { | do | ||
$ | { | ||
$info = stream_get_meta_data($ | $new_a1 = ord(fread($socket,1)); | ||
if ($info['timed_out']) { | $info = stream_get_meta_data($socket); | ||
echo " | if ($info['timed_out']) | ||
{ | |||
if (query_timeout($socket, "$a1.$a2.$a3.$a4:$a5")) | |||
break; | |||
$a1 = ord(fread($socket,1)); | |||
$info = stream_get_meta_data($socket); | |||
if ($info['timed_out']) | |||
{ | |||
echo "Timeout occured.\n"; | |||
break; | |||
} | |||
echo "New seed, decreasing count.\n"; | |||
$count--; | |||
} | } | ||
else | |||
$a1 = $new_a1; | |||
if ($a1 != 0) | |||
{ | |||
$a2 = ord(fread($socket,1)); | |||
$a3 = ord(fread($socket,1)); | |||
$a4 = ord(fread($socket,1)); | |||
$a5 = ord(fread($socket,1))*256 + ord(fread($socket,1)); | |||
$count++; | $count++; | ||
echo "$count $a1.$a2.$a3.$a4:$a5\n"; | echo "$count $a1.$a2.$a3.$a4:$a5\n"; | ||
} | } | ||
} while ($a1 != 0); | } while ($a1 != 0); | ||
echo "Retrieved $count | fclose($socket); | ||
echo "Retrieved $count server addresses.\n"; | |||
?> | ?> | ||
</pre> | </pre> |
Revision as of 11:29, 11 December 2010
This is a code example for querying a Half-Life master server using the PHP language.
<?php /* Version history 1 Initial release. 2 Added option to retry same server if timeout occurs. 2.1 Added more master servers. 2.1.1 Fixed a bug, program didn't terminate if all master servers time out. 2.1.2 Removed a now redundant variable. 2.2 Seeding for long server lists. */ $master_servers = array("72.165.61.136", "68.142.72.250", "72.165.61.189", "72.165.61.190", "69.28.151.162"); function query_timeout(&$socket, $seed) { // region=world, filter: game=Half-Life if (!fwrite($socket, "1\xFF$seed\0\\gamedir\\valve\0")) { fclose($socket); exit("fwrite error\n"); } $s = bin2hex(fread($socket, 6)); $info = stream_get_meta_data($socket); if ($info['timed_out']) { echo "Master server \"$seed\" timed out.\n"; fclose($socket); } else { if ($s !== "ffffffff660a") { fclose($socket); exit("Expected ff ff ff ff 66 0a (hex) but got $s."); } } return $info['timed_out']; } // Connect to master server, return timeout info. // The socket is passed as reference and thus returned as well. function master_server_timeout(&$socket, $ip) { $port = 27010; $timeout = 1; echo "Connecting to master server \"$ip\".\n"; $socket = fsockopen("udp://$ip", $port, $errno, $errstr, $timeout); if (!$socket) exit("Error $errno : $errstr \n"); stream_set_timeout($socket, $timeout); return query_timeout($socket, "0.0.0.0:0"); } // Try all master servers unless we find one that isn't timing out. $abort = 1; foreach ($master_servers as $ip) { if (!master_server_timeout($socket, $ip)) { $abort = 0; break; } } if ($abort == 1) exit("All master servers timed out, aborting.\n"); // Read list with server addresses (IP:port). $count = 0; do { $new_a1 = ord(fread($socket,1)); $info = stream_get_meta_data($socket); if ($info['timed_out']) { if (query_timeout($socket, "$a1.$a2.$a3.$a4:$a5")) break; $a1 = ord(fread($socket,1)); $info = stream_get_meta_data($socket); if ($info['timed_out']) { echo "Timeout occured.\n"; break; } echo "New seed, decreasing count.\n"; $count--; } else $a1 = $new_a1; if ($a1 != 0) { $a2 = ord(fread($socket,1)); $a3 = ord(fread($socket,1)); $a4 = ord(fread($socket,1)); $a5 = ord(fread($socket,1))*256 + ord(fread($socket,1)); $count++; echo "$count $a1.$a2.$a3.$a4:$a5\n"; } } while ($a1 != 0); fclose($socket); echo "Retrieved $count server addresses.\n"; ?>