6
Here is the gamespy class
/*
gamespy.php v1.1
Copyright : 2004-2005 by FiRe^
Created : 2004-11-04
Last edit : 2005-05-13
License : GPL (http://www.gnu.org/licenses/gpl.txt)
Requirements : PHP4 (Sockets enabled :D)
Description : The GameSpy-Class allows you to get the Serverlists for
GameSpy-supported Games. The list of all Gamenames is here:
http://motd.gamespy.com/software/services/index.aspx
You can get the Handoff by visiting the following page:
http://motd.gamespy.com/software/services/index.aspx?mode=full&services=GAMENAME
To-Do : Improve the socket code
Example : require("gamespy.php"); // Path to this php file
$GS = new GameSpy(); // Create new GameSpy-Instance
$Servers = $GS->GetServers("bfield1942", "XoHHptWIxA9sz3"); // Get the Serverlist for 'Battlefield 1942'
if(!$Servers) { // Check if an error has occurred..
echo "Error while retrieving the Serverlist!!!";
} else {
// Debug-Print the Serverlist:
print_r($Servers);
}
*/
class GameSpy {
var $Host;
var $Port;
var $Sock;
function GameSpy($Host = "master.gamespy.com", $Port = 28900) {
/*
--Constructor--
$Host: GameSpy-Master IP
$Port: GameSpy-Master Port
*/
$this->Host = $Host;
$this->Port = $Port;
}
function GetServers($Gamename, $Handoff, $Filter = "") {
/*
This function will return the Serverlist for $Gamename in an Array.
$Gamename: (http://motd.gamespy.com/software/services/index.aspx)
$Handoff: (http://motd.gamespy.com/software/services/index.aspx?mode=full&services=$Gamename)
If the Handoff is >= 13 chars, it will be sized to an 6-char Handoff
$Filter: The GS-Filter
Example:
Array
(
[0] => Array
(
[ip] => 69.44.61.202
[port] => 23000
)
[1] => Array
(
[ip] => 195.140.135.250
[port] => 23000
)
...
)
*/
// Try to connect to the GameSpy-Master:
$this->Sock = @fsockopen("tcp://$this->Host", $this->Port, &$errno, &$errstr, 2);
@stream_set_timeout($this->Sock, 2);
if(!$this->Sock) { // Error while connecting
return false; // :-(
} else {
$this->Connected = true;
}
// Receive the Secure-Key:
$SecureKey = substr(fgets($this->Sock, 256), -7, 6);
// Create the Validate-Key:
$ValidateKey = $this->__MakeValidate($SecureKey, $Handoff);
// Send the packet
$Packet = "\gamename\$Gamename\enctype\0\validate\$ValidateKey\final\" .
"\queryid\1.1\list\cmp\gamename\$Gamename\where\$Filter\final\";
fwrite($this->Sock, $Packet);
// Receive the (compressed) Serverlist:
$Data = "";
do {
$Data .= fgets($this->Sock, 2048);
$Buffer = socket_get_status($this->Sock);
} while($Buffer["unread_bytes"] > 0);
fclose($this->Sock); // Close socket
return $this->__ParseCompressedIPs($Data); // Return the parsed Serverlist
}
function __ParseCompressedIPs($Data) {
/*
Parse the 6-Byte-IP packet and return the Serverlist-Array
$Data: Compressed IPs received from the Server
*/
$UnComp = array();
$i = 0;
$c = 0;
// Remove the "final":
$Data = str_replace("\final\", "", $Data);
while($i <= strlen($Data) - 6) {
// IP
$UnComp[$c]["ip"] = ord($Data{$i++}).".".ord($Data{$i++}).".".ord($Data{$i++}).".".ord($Data{$i++});
// Port
$UnComp[$c++]["port"] = (ord($Data{$i++}) * 256) + ord($Data{$i++});
}
return $UnComp;
}
function __MakeValidate($SecureKey, $Handoff) {
/*
MakeValidate creates a Validate-Key for you :D
$SecureKey: The Secure-Key received from the GS Master
$Handoff: See GetServers()
*/
$Temp = array(0, 0, 0, 0, $Handoff); // Array for some temporary Variables
$Table = array();
for($i = 0; $i <= 255; $i++) {
$Table[$i] = $i; // Fill the buffer
}
// Check the Handoff-Length:
if(strlen($Handoff) >= 13) {
$Handoff = "";
// Invalid Handoff! -> Need 6-char Handoff
for($i = 2; $i <= 13; $i += 2) {
$Handoff .= $Temp[4]{$i};
}
}
// Add the length of the Keys to the array:
$Length = array(strlen($Handoff), strlen($SecureKey));
for($i = 0; $i <= 255; $i++) {
// Scramble the Table with the Handoff:
$Temp[0] = ($Temp[0] + $Table[$i] + ord($Handoff{$i % $Length[0]})) & 255;
$Temp[1] = $Table[$Temp[0]];
// Update the buffer:
$Table[$Temp[0]] = $Table[$i];
$Table[$i] = $Temp[1];
}
$Temp[0] = 0;
$Key = array();
// Scramble the SecureKey with the Table:
for($i = 0; $i < $Length[1]; $i++) {
// Add the next char to the Array
$Key[$i] = ord($SecureKey{$i});
$Temp[0] = ($Temp[0] + $Key[$i] + 1) & 255;
$Temp[1] = $Table[$Temp[0]];
$Temp[2] = ($Temp[2] + $Temp[1]) & 255;
$Temp[3] = $Table[$Temp[2]];
$Table[$Temp[2]] = $Temp[1];
$Table[$Temp[0]] = $Temp[3];
// XOR the Key with the Buffer:
$Key[$i] ^= $Table[($Temp[1] + $Temp[3]) & 255];
}
$Length[1] /= 3;
$i = 0;
$ValidateKey = "";
// Create the ValidateKey:
while($Length[1]--) {
$Temp[1] = $Key[$i++];
$Temp[3] = $Key[$i++];
$ValidateKey .= $this->__AddChar($Temp[1] >> 2);
$ValidateKey .= $this->__AddChar((($Temp[1] & 3) << 4) | ($Temp[3] >> 4));
$Temp[1] = $Key[$i++];
$ValidateKey .= $this->__AddChar((($Temp[3] & 15) << 2) | ($Temp[1] >> 6));
$ValidateKey .= $this->__AddChar($Temp[1] & 63);
}
return $ValidateKey;
}
function __AddChar($Number) {
// Return a new char
if($Number < 26) {
return chr($Number + 65);
} elseif($Number < 52) {
return chr($Number + 71);
} elseif($Number < 62) {
return chr($Number - 4);
} elseif($Number == 62) {
return "+";
} elseif($Number == 63) {
return "/";
}
}
}
?>
Here is the code that is supposed to display it on your site, but I cant get it to work.
include("include/gamespy.php"); // GameSpy Class
$GS = new GameSpy(); // Create new GameSpy-Instance
$Gamename = "battlefield2d";
$Handoff = "NqhaWF6Hms9Vao";
$Servers = $GS->GetServers("$Gamename", "$Handoff", ""); // Get the Serverlist for 'Battlefield 1942'
if(!$Servers) { // Check if an error has occurred..
echo "Error while retrieving the Serverlist!!!";
} else {
// Print the Serverlist:
foreach($Servers as $Server) {
echo $Server["ip"] .":". $Server["port"] ."
n";
}
}
?>
Mithy, if you have time, could you look at this and tell me what is causing it to white screen on me? I commented out the call to the function GetServers and it works. Any and all help is greatly appreciated.