View Single Post
Old 06-16-2006, 09:54 AM   #2 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,470
sde is on a distinguished road
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$loop1))), 8'0'STR_PAD_LEFT).$bin
    } 
    
$exponent bindec(substr($bin18)); 
    
$exponent = ($exponent)? $exponent 127 $exponent
    if(
$exponent) { 
        
$int bindec('1'.substr($bin9$exponent)); 
        
$dec bindec(substr($bin$exponent)); 
        
$time "$int.$dec";     
        return 
number_format($time 602); 
    } 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$errstr3);

    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->_sock2,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==|| $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->_sock2,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->_sock2,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
sde is offline   Reply With Quote