<?
// ------------------------------------------------------------------------
// BATTLEFIELD 2 - GAME SERVER QUERY CLASS
// ------------------------------------------------------------------------
// Written by: Bogdan Zarchievici <hide@address.com>
// Version: 5.0.1.a
// Revision: Monday, February 06, 2006 at 5:10:15 PM
// ------------------------------------------------------------------------
// Comments: works with any PHP version greater than 4.1.0.
// ------------------------------------------------------------------------
// Special thanks to: Michael Damato, Brian Manning and all of you who have
// been actively interested in the development of this class.
// ------------------------------------------------------------------------
// For more details on the Gamespy Query Format please visit:
// http://forums.gametrack.org/viewtopic.php?t=311
// http://dev.kquery.com/index.php?article=47
// ------------------------------------------------------------------------
class battlefield_2
{ var $timeout=10; // packet TTL in seconds
//
// MAIN FUNCTION OF THE CLASS (CONSTRUCTOR)
//
function battlefield_2($ip,$port=29900,$players=true)
{ $transmission = chr(254).chr(253).chr(0);
$transmission.= chr(4).chr(5).chr(6).chr(7);
$transmission.= chr(255).chr(255).chr(255).chr(1);
# (begin) socket code
$socket=socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,array('sec'=>$this->timeout,'usec'=>0));
if (!$socket) return; $packet=null; $this->packets=null;
if (!socket_sendto($socket,$transmission,strlen($transmission),0x100,$ip,$port)) return;
while (!$this->receiving($packet)) if (!socket_recvfrom($socket,$packet,2048,0,$client['ip'],$client['port'])) return;
socket_close($socket);
# (end) socket code
# (begin) packet parsing code
ksort($this->received);
$this->results=array('server'=>array(),'teams'=>array());
if ($players) $this->results['players']=array();
foreach ($this->received as $content)
{ if (isset($content['server'])) $this->results['server']=array_merge($this->results['server'],$content['server']);
if (isset($content['players']) && $players) foreach ($content['players'] as $field=>$data) foreach ($data as $player=>$value) $this->results['players'][$player][preg_replace('/[^a-z]/i','',$field)]=$value;
if (isset($content['teams'])) $this->results['teams']=array_merge($this->results['teams'], $content['teams']);
}
# (end) packet parsing code
# (begin) unset variables that are no longer needed
unset($this->received);
unset($this->timeout);
# (end) unset variables that are no longer needed
}
//
// FUNCTION THAT HANDLES THE WAY A PACKET IS RECEIVED
//
function receiving($raw)
{ if (empty($raw)) return(0);
if (!$parsed=$this->parsing($raw)) return(1);
if ($parsed['header']>0x7F) $this->packets=$parsed['header']-0x7F;
$this->received[$parsed['header']]=$parsed;
if (!isset($this->packets) OR count($this->received)!=$this->packets) return(0);
unset($this->packets); return(1);
}
//
// FUNCTION THAT PARSES THE PACKET
//
function parsing($raw)
{ if ($id=substr($raw,1,4)) $pointer=5; else $pointer=1;
if ($id!=chr(4).chr(5).chr(6).chr(7)) return(0);
$piece=null; while ($raw{$pointer}!=chr(0)) { $piece.=$raw{$pointer}; if (($pointer>=strlen($raw))) $piece=false; else $pointer++; }
if ($piece!='splitnum') return(0);
$pointer++;
if ($pointer<strlen($raw)) { $parsed['header']=ord($raw{$pointer}); $pointer++; }
while ($pointer<strlen($raw))
{ if ($pointer<strlen($raw)) { $section=ord($raw{$pointer}); $pointer++; }
switch ($section)
{ case 0:
while(!($pointer<strlen($raw) && $raw{$pointer}==chr(0)))
{ $key=null;
while ($raw{$pointer}!=chr(0)) { $key.=$raw{$pointer}; if (($pointer>=strlen($raw))) $key=false; else $pointer++; }
$pointer++; $value=null;
while ($raw{$pointer}!=chr(0)) { $value.=$raw{$pointer}; if (($pointer>=strlen($raw))) $value=false; else $pointer++; }
$pointer++; $parsed['server'][$key]=$value;
}
$pointer++;
break;
case 1 OR 2:
while ($pointer<strlen($raw) && !($raw{$pointer}==chr(0)))
{ while ($pointer<strlen($raw) && !($raw{$pointer}==chr(0)))
{ $column=null;
while ($raw{$pointer}!=chr(0)) { $column.=$raw{$pointer}; if (($pointer>=strlen($raw))) $column=false; else $pointer++; }
}
$pointer++;
if ($pointer<strlen($raw)) { $row=ord($raw{$pointer}); $pointer++; }
while ($pointer<strlen($raw) && !($raw{$pointer}==chr(0)))
{ $piece=null;
while ($raw{$pointer}!=chr(0)) { $piece.=$raw{$pointer}; if (($pointer>=strlen($raw))) return(0); else $pointer++; }
$parsed[($section==1?'players':'teams')][$column][$row]=$piece; $row++; $pointer++;
}
$pointer++;
}
$pointer++;
break;
}
}
return $parsed;
}
}
?>