|
Moderator
Join Date: May 2002
Location: us.ca
Posts: 4,470
|
i spent some time a while ago on this. i had a class working for 1.6 (originally coded by madhatter) but then the implementation changed with source. lots of tweaking, trial, and error and i finally got it working. the last few lines instanciates the class and runs the query. enjoy
PHP Code:
<? function get_float32($fourchars) { $bin=''; for($loop = 0; $loop <= 3; $loop++) { $bin = str_pad(decbin(ord(substr($fourchars, $loop, 1))), 8, '0', STR_PAD_LEFT).$bin; } $exponent = bindec(substr($bin, 1, 8)); $exponent = ($exponent)? $exponent - 127 : $exponent; if($exponent) { $int = bindec('1'.substr($bin, 9, $exponent)); $dec = bindec(substr($bin, 9 + $exponent)); $time = "$int.$dec"; return number_format($time / 60, 2); } else { return 0.0; } }
class sourceQueryCS{
function sourceQueryCS($ip,$port){
$this->ip=$ip; $this->port=$port; $this->address=$ip.":".$port; $this->hostname = ""; $this->map = ""; $this->mod = ""; $this->modname = ""; $this->active = ""; $this->max = ""; $this->cvars = array(); $this->players = array(); $this->excluded_cvars = array(); /* // you can define cvars you wish to exclude // this may be useful if you are looping through // the cvar array instead of just calling individual cvars $this->excluded_cvars = array( "mp_falldamage", "mp_weaponstay", "mp_forcerespawn", "mp_autocrosshair", "decalfrequency", "coop", "mp_teamlist", "mp_allowNPCs", "sv_stopspeed", "sv_noclipaccelerate", "sv_noclipspeed", "sv_specaccelerate", "sv_specspeed", "sv_specnoclip", "sv_maxspeed", "sv_accelerate", "sv_airaccelerate", "sv_wateraccelerate", "sv_waterfriction", "sv_rollspeed", "sv_rollangle", "sv_friction", "sv_bounce", "sv_stepsize", "r_VehicleViewDampen", "r_JeepViewDampenFreq", "r_JeepViewDampenDamp", "r_JeepViewZHeight", "r_AirboatViewDampenFreq", "r_AirboatViewDampenDamp", "r_AirboatViewZHeight", "sv_pausable" ); */ $this->_sock = fsockopen("udp://".$this->ip,$this->port, $errno, $errstr, 3);
if (!$this->_sock) { echo "unable to connect to ".$this->ip.":".$this->port; exit; } $this->getInfo(); $this->getRules(); $this->getPlayers();
fclose($this->_sock); } function getInfo(){ $array = array(); $query=chr(0xFF).chr(0xFF).chr(0xFF).chr(0xFF).chr(0x54); fwrite($this->_sock, $query); socket_set_timeout($this->_sock, 2,0); $buffer=fread($this->_sock,1); $stat=socket_get_status($this->_sock); $buffer.=fread($this->_sock, $stat["unread_bytes"]); $buffer=substr($buffer,6); $text=""; $count=0; $arr=array(0); do { $tmp=substr($buffer,0,1);$buffer=substr($buffer,1); if (!ord($tmp)) { $array[$count++]=$text; $text=""; } else { $text.=$tmp; } } while ($count<5); for($i=0;$i<=6;$i++, $count++) { $tmp=substr($buffer,0,1);$buffer=substr($buffer,1); if($count==8 || $count==9) $array[$count]=$tmp; else $array[$count]=ord($tmp); } //count = 12 if($array[$count-1]) { //if ismod do { $tmp=substr($buffer,0,1);$buffer=substr($buffer,1); if (ord($tmp)!=0) $array[$count].=$tmp; // mod website [12] } while(ord($tmp)!=0); $count++; do { $tmp=substr($buffer,0,1);$buffer=substr($buffer,1); if (ord($tmp)!=0) $array[$count].=$tmp; // mod FTP [13] } while(ord($tmp)!=0); $count++; $array[$count++]=ord(substr($buffer,0,1)); $buffer=substr($buffer,1); //Dummy bit? [14] o_0 -- SHOULD be server-only bit... ^_^ $tmp=substr($buffer,0,4);$buffer=substr($buffer,4); for($j=0;$j<4;$j++) { $array[$count]+=(pow(256,$j) * ord(substr($tmp,$j,1))); //Ver [15] } $count++; $tmp=substr($buffer,0,4);$buffer=substr($buffer,4); for($j=0;$j<4;$j++) { $array[$count]+=(pow(256,$j) * ord(substr($tmp,$j,1))); //Size [16] } $count++; $array[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //server-only [17] $array[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //custom client.dll [18] $array[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //Secure! [19] } else { for($i=0;$i<8;$i++) $array[$count++]='\0'; } $this->hostname = $array[0]; $this->map = $array[1]; $this->mod = $array[2]; $this->modname = $array[3]; $this->active = $array[6]; $this->max = $array[7]; } function getplayers(){ $query=chr(0xFF).chr(0xFF).chr(0xFF).chr(0xFF).chr(0x55); fwrite($this->_sock, $query); socket_set_timeout($this->_sock, 2,0); $buffer=fread($this->_sock,1); $stat=socket_get_status($this->_sock); $buffer.=fread($this->_sock, $stat["unread_bytes"]); $buffer=substr($buffer,5); $count=ord(substr($buffer,0,1)); //Num active players $buffer=substr($buffer,1); $tfrags=""; $ttime=0; $array=array(0); for($i=0;$i<$count;$i++){ $rfrags=0.0; $rtime=0; $stime=0; $tind=ord(substr($buffer,0,1)); $buffer=substr($buffer,1); $tname=""; do { $tmp=substr($buffer,0,1); $buffer=substr($buffer,1); $tname.=$tmp; }while(ord($tmp)!=0); $tfrags=substr($buffer,0,4); $buffer=substr($buffer,4); for($j=0;$j<4;$j++) { $rfrags+=(pow(256,$j) * ord(substr($tfrags,$j,1))); } if($rfrags > 2147483648) { $rfrags-=4294967296; } $tmp=substr($buffer,0,4); $buffer=substr($buffer,4); $rtime=get_float32($tmp); $array[$i]=array("index" => $tind,"name" => $tname,"frags" => $rfrags, "time" => $rtime); } $this->players = $array; } function getRules(){ $array = array(); $rules = array(); $query=chr(0xFF).chr(0xFF).chr(0xFF).chr(0xFF).chr(0x56); fwrite($this->_sock, $query); socket_set_timeout($this->_sock, 2,0); $buffer=fread($this->_sock,1); $stat=socket_get_status($this->_sock); $buffer.=fread($this->_sock, $stat["unread_bytes"]);
$array = explode(chr(0),$buffer); $count = (count($array)-1); for($i=1;$i<$count;$i++){ if(in_array($array[$i],$this->excluded_cvars)){ $i++; continue; } $rules[$array[$i]]=$array[++$i]; } $this->cvars = $rules; } }
header("content-type: text/plain"); $sq = new sourceQueryCS("192.18.1.250",27016); print_r($sq); ?>
__________________
Mike
|