Skip to content

Instantly share code, notes, and snippets.

@Neo-Desktop
Created August 1, 2020 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Neo-Desktop/43cff8f7bed77517778c998636cb6a4a to your computer and use it in GitHub Desktop.
Save Neo-Desktop/43cff8f7bed77517778c998636cb6a4a to your computer and use it in GitHub Desktop.
starsiege server query script
<?php
const MASTER_SERVER = "master2.starsiege.pw";
const MASTER_PORT = 29000;
const PROTOCOL_VERSION = 0x10;
const STATUS_REQUEST = 0x03;
const GAME_SERVER_STATUS_RESPONSE = 0x04;
const MASTER_SERVER_STATUS_RESPONSE = 0x06;
const GAME_INFO_REQUEST = 0x07;
const GAME_INFO_RESPONSE = 0x08;
$query = queryMasterServer(MASTER_SERVER, MASTER_PORT);
if (count($query['servers']) <= 0) {
printf("Error server count was 0");
exit;
}
printf("Acquired %d servers in %s ms\n", count($query['servers']), $query['request_duration']);
$gameServers = [];
$start = microtime(true);
foreach ($query['servers'] as $id => $server) {
$gameServers[] = queryGameServers($server["host"], $server["port"], $id);
}
$end = microtime(true);
printf("Queried %d servers in %s ms\n", count($query['servers']), $end - $start);
//print_r($gameServers);
function queryMasterServer($host, $port, $requestID = 0) {
$fp = @fsockopen("udp://".$host, $port, $errno, $errstr, 1);
if (!$fp)
{
printf("Error opening socket to: %s:%d\nError#:%d\nError:%s", $host, $port, $errno, $errstr);
return [];
}
//time the search
$start = microtime(true);
//request server info
$request = pack("C4v2", PROTOCOL_VERSION, STATUS_REQUEST, 0xff, 0x00, $requestID, 0x00);
fwrite($fp, $request, 8);
$packet = [];
$packet['header'] = fread($fp, 8);
$packet['hostname_length'] = fread($fp, 1);
$packet['motd'] = "";
do {
$byte = fread($fp, 1);
if (ord($byte) > 0) {
$packet['motd'] .= $byte;
}
}
while (ord($byte) != 0);
$packet['server_count'] = ord(fread($fp, 1));
$packet['servers'] = [];
for ($i=0; $i < $packet['server_count']; $i++) {
fread($fp, 1); // separator \0x06
$ip = sprintf("%d.%d.%d.%d", unpack("C", fread($fp, 1))[1], unpack("C", fread($fp, 1))[1], unpack("C", fread($fp, 1))[1], unpack("C", fread($fp, 1))[1]);
$packet['servers'][$i]["host"] = ($ip == "127.0.0.1") ? $host : $ip;
$packet['servers'][$i]["port"] = unpack("v", fread($fp, 2))[1];
}
$end = microtime(true);
$packet['request_duration'] = $end - $start;
fclose($fp);
return $packet;
}
function queryGameServers($host, $port, $requestID = 0) {
$fp = @fsockopen("udp://".$host, $port, $errno, $errstr, 1);
if (!$fp)
{
printf("Error opening socket to: %s:%d\nError#:%d\nError:%s", $host, $port, $errno, $errstr);
return [];
}
// socket_set_timeout($fp, 1, 500);
printf("\tQuerying %s:%d\n", $host, $port);
//time the search
$start = microtime(true);
//request server info
$request = pack("C4v2", PROTOCOL_VERSION, STATUS_REQUEST, 0xff, 0x00, $requestID, 0x00);
fwrite($fp, $request, 8);
// fixed packet size: 40 bytes
$packet['header'] = fread($fp, 06); // header (6 bytes)
$packet['status_bytes'] = fread($fp, 07); // status (7 bytes)
$packet['version'] = fread($fp, 10); // game server version string (10 bytes)
$packet['server_name'] = fread($fp, 17); // server name (23 bytes)
//request game info
// $request = pack("C4v2", PROTOCOL_VERSION, GAME_INFO_REQUEST, 0xff, 0x00, $requestID, 0x00);
// fwrite($fp, $request, 8);
$end = microtime(true);
$packet["request_duration"] = $end - $start;
fclose($fp);
return $packet;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment