<?php
echo "<pre>";
//HL1
//207.173.177.11:27010
//69.28.151.178:27010
//69.28.151.162:27010

//Source
//207.173.177.11:27011
//69.28.151.178:27011
//69.28.151.162:27011

/*This information is taken from a HLDS_APPS mailinglist post by Alred  Reynolds
 The upcoming steam release has a couple small changes to the hlmaster server protocol.

 Firstly the address for the master servers has changed,  our public server can be accessed via hlmaster1.hlauth.net. This server  currently doesn't have any servers listed as we have yet to release the steam  client, but in the next day or two it will.

 We have also changed the "batch request" protocol. The new protocol consists of sending:
 WriteByte( A2M_GET_SERVERS_BATCH2 ); // character '1'  WriteByte( 2 );// write the region we want info on  WriteString( startIP ); // the first ip address we are interested in  WriteString(filterString); // a backslash delimited string for filtering of  servers

 The change has been adding the region field and changing the batch parameter to use the last IP you received rather than a counter. Valid values for the region are between 0-7 and the correspond to the following geographical areas:
 0: US East coast  1: US West coast  2: South America  3: Europe  4: Asia  5: Australia  6: Middle East  7: Africa
 If you don't want the master server to do any  filtering you can just send NULL for the filter parameter.*/


$ipport = "69.28.151.162:27010";

/*Valid values for the region are between 0-7 and the correspond to the following geographical areas:

255: All Servers
0: US East coast
1: US West coast
2: South America
3: Europe
4: Asia
5: Australia
6: Middle East
7: Africa

*/

/* Filter:

\type\d
Servers running dedicated
\secure\1
Servers using anti-cheat technology (VAC)
\gamedir\[mod]
Servers running the specified modification (ex. cstrike)
\map\[map]
Servers running the specified map (ex. cs_italy)
\linux\1
Servers running on a Linux platform
\empty\1
Servers that are not empty
\full\1
Servers that are not full
\proxy\1
Servers that are spectator proxies

*/

$region = "255";
$filter = array(
		'type'	=> '',
		'secure'	=> '',
		'gamedir'	=> 'cstrike',
		'map'	=> 'de_dust',
		'linux'	=> '1',
		'empty'	=> '',
		'full'	=> '1',
		'proxy'	=> '',
);

$filterstr = "";
foreach ($filter as $key => $value) {
	if ($value !== '') {
		$filterstr .= "\\$key\\$value";
	}
}

echo "$filterstr\n\n";

list($ip,$port) = explode(":",$ipport);

$sock = fsockopen("udp://" . $ip, $port);

stream_set_timeout($sock, 10);

$lastip = "0.0.0.0:0";
$iplist = array();

do {

	$command = '1' . pack("C", $region) . $lastip . "\0" . $filterstr . "\0";


	fwrite($sock, $command);
	$packet = fread($sock, 1500);

	//Start at Position 4
	$strpos = 4;



	if (mb_substr($packet, $strpos, 1) != 'f') {
		echo "Incorrect Query String Returned (" . mb_substr($packet, 4, 1) . ")";
		die;
	}

	//Advance 2 positions to get to the IP data
	$strpos += 2;

	$currentlist = array();

	while (mb_substr($packet, $strpos, 1) != '') {

		//Get the IP one octet at a time
		$newip = ord(mb_substr($packet, $strpos++, 1)) . '.';
		$newip .= ord(mb_substr($packet, $strpos++, 1)) . '.';
		$newip .= ord(mb_substr($packet, $strpos++, 1)) . '.';
		$newip .= ord(mb_substr($packet, $strpos++, 1));

		//Get the Port
		$unpacked = unpack("n",mb_substr($packet, $strpos, 2));
		$newip .= ":" . $unpacked[1];
		$strpos += 2;

		if ($newip == $lastip) continue;

		$lastip = $newip;
		$currentlist[] = $newip;
		echo "$newip\n";
	}

	$iplist = array_merge($iplist, $currentlist);

} while ($lastip != '0.0.0.0:0');

array_pop($iplist);
sort($iplist,SORT_NUMERIC);

echo print_r($iplist);
echo "</pre>";

?>