User:Pizzahut/msqp.php
Jump to navigation
Jump to search
This is a code example for querying a Half-Life master server using the PHP language. For querying more than 231 servers it needs to be extended. The purpose of this program is to get a list of TFC servers, there are only about 150 left at the time of writing so it doesn't check for more. Btw currently the master servers only return 50 to 70 TFC servers, but as stated there are about 150, which you can verify with HLSW's Gamers Search (when it's not having one of its off days).
<?php /* Version history 1 Initial release. 2 Added option to retry same server if timeout occurs. (This is just a minor update, I should have released it as v1.1.) 2.1 Added more master servers. 2.1.1 Fixed a bug, program didn't terminate if all master servers time out. */ // Method 1: Try a different server if one is timing out. // Method 2: Retry the same server if a timeout occurs. $method = 1; $servers = array( "72.165.61.136:27010", "68.142.72.250:27010", "72.165.61.189:27010", "72.165.61.190:27010", "69.28.151.162:27010"); $server = "hl1master.steampowered.com"; function master_server_timeout(&$fp, $ip) { $port = 27010; $timeout = 1; echo "Connecting to master server \"$ip\".\n"; $fp = fsockopen("udp://$ip", $port, $errno, $errstr, $timeout); if (!$fp) exit("Error $errno : $errstr"); stream_set_timeout($fp, $timeout); // region=world, filter: game=Team Fortress Classic if (!fwrite($fp, "1\xFF0.0.0.0:0\0\\gamedir\\tfc\0")) { fclose($fp); exit("fwrite error\n"); } $s = bin2hex(fread($fp, 6)); $info = stream_get_meta_data($fp); if ($info['timed_out']) { echo "Master server \"$ip\" timed out.\n"; fclose($fp); } else { if ($s !== "ffffffff660a") { fclose($fp); exit("Expected ff ff ff ff 66 0a (hex) but got $s."); } } return $info['timed_out']; } if ($method == 1) { $abort = 1; foreach ($servers as $server_number => $server_address) { if (!master_server_timeout($fp, $server_address)) { $abort = 0; break; } } if ($abort == 1) exit("All servers timed out, aborting.\n"); } if ($method == 2) { for ($i = 1; $i <= 10; $i++) { if (!master_server_timeout($fp, $server)) break; if ($i == 10) exit("Giving up after 10 tries.\n"); else echo "Retrying ($i).\n"; } } $count = 0; do { $a1 = ord(fread($fp,1)); $info = stream_get_meta_data($fp); if ($info['timed_out']) { echo "Time out occured.\n"; break; } // Let's always read the rest of the address, even if it starts with 0. // This may avoid subsequent problems, but I'm paranoid here. $a2 = ord(fread($fp,1)); $a3 = ord(fread($fp,1)); $a4 = ord(fread($fp,1)); $a5 = ord(fread($fp,1))*256 + ord(fread($fp,1)); if ($a1 != 0) { $count++; echo "$count $a1.$a2.$a3.$a4:$a5\n"; } } while ($a1 != 0); echo "Retrieved $count servers.\n"; fclose($fp); ?>