Location: PHPKode > scripts > CzarQuery > czarquery/czarquery.php
<?
##########################################
### 
### CzarQuery v1.00
### Made by: Czaries  [hide@address.com]
### http://www.czaries.net/scripts/
### for more scripts and updates.
###
/* #

CzarQuery is made to retrieve information from a Half-Life
server about who is playing, what mod it is running, and
what map the server is currently playing.

This script has been tested with and includes map pictures
for the following mods:
- Counter-Strike
- Day of Defeat
- Natural Selection
- Team Fortress Classic
- Action Half-Life

CzarQuery is based on code by madCoder called madQuery,
and merely provides a way to display the reults given from
his script.  I take no credit for his coding for retrieving the
information from the Half-Life server, but only the credit for
the work done displaying the information.

*/ #
###
##########################################

// Enter your server IP address and port number below
$server_ip = "216.178.199.11";
$server_port = "27015"; // If you do not know the port number, enter '27015'

/*
Display type - Tells script to display as a full page by itself, or as
an included file, without all the HTML formatting

Accepted values are:
$page = "full"; - Displays as full page, automatically linking CSS file
											and generating proper HTML formatting
$page = "include"; - Displays as a lighter version that only displays
														the server information, and requires you to include
														the CSS file in the <head> tags of your header file,
														or to make your own CSS formatting.  Instructions
														on including the CSS file in your own <head> tags
														can be found in the readme.txt in the ZIP package,
														or you may simply place the line:
														<link rel="stylesheet" type="text/css" href="czarquery.css">
														in between your <head> tags
*/
$page = "full";


if($page != "include") {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Counter-Strike Server Information</title>
<link rel="stylesheet" type="text/css" href="czarquery.css">
</head>

<body>

<?php
}
### Include madQuery.php (not made by me)

/***************************************************
 * madQuery																								*
 * Copyright (C) 2002 madCoder                     *
 * http://www.utdallas.edu/~madcoder/              *
 * COMMENTS (NO support requests)may be sent to:   *
 *    hide@address.com                *
 ***************************************************
 * Use of this class assumes agreement to all      *
 * of the following terms of use:                  *
 ***************************************************
 * 1) This class is provided as-is, with no        *
 *    offering of technical support, or help       *
 *    in any way with setting up this class.       *
 * 2) madCoder will not, in any way, take          *
 *    responsibility for what you do with this     *
 *    script.                                      *
 * 3) This class may not be reproduced, or         *
 *    altered, without prior authoriazation from   *
 *    madCoder.                                    *
 * 4) ALL Copyright and credit notices MUST remain *
 *    intact, as released.                         *
 ***************************************************/


define("ERROR_NOERROR" ,0);
define("ERROR_NOSERVER",-1);
define("ERROR_INSOCKET",-2);
//define("DEBUG",1);

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; 
	} 
}

/******
 * getmicrotime()
 * as provided in the PHP manual
 ******/
function getmicrotime(){ 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
} 
   
function dodebug($dbgstr="") {
	if(defined('DEBUG')) echo "<!-- [DEBUG] " . $dbgstr . " -->\n";
}
/***********************************************
 * madQuery Class
 ***********************************************/
class madQuery {
	var $_arr=array();
	var $_ip="";
	var $_port=0;
	var $_isconnected=0;
	var $_players=array();
	var $_rules=array();
	var $_errorcode=ERROR_NOERROR;
	var $_seed="madQuery for server (%s:%d)";
	var $_sk; //socket
	
	//Constructor
	function madQuery($serverip, $serverport=27015) 
	{
		$this->_ip=$serverip;
		$this->_port=$serverport;
		$this->_seed="\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x20\x20\x20\x53\x65\x72\x76\x65\x72\x20\x6d\x61\x64\x51\x75\x65\x72\x79\x20\x43"
				."\x6c\x61\x73\x73\x20\x20\x20\x20\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x43\x6f\x70\x79\x72\x69"
				."\x67\x68\x74\x20\x28\x43\x29\x20\x32\x30\x30\x32\x20\x6d\x61\x64\x43\x6f\x64\x65\x72\x20\x20\x20\x20\x2d\x2d\x3e\x0a"
				."\x3c\x21\x2d\x2d\x20\x20\x20\x6d\x61\x64\x63\x6f\x64\x65\x72\x40\x73\x74\x75\x64\x65\x6e\x74\x2e\x75\x74\x64\x61\x6c"
				."\x6c\x61\x73\x2e\x65\x64\x75\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77"
				."\x2e\x75\x74\x64\x61\x6c\x6c\x61\x73\x2e\x65\x64\x75\x2f\x7e\x6d\x61\x64\x63\x6f\x64\x65\x72\x20\x2d\x2d\x3e\x0a\x0a";
		$this->_arr=array_pad($this->_arr, 21, 0);
		$this->_sk = fsockopen("udp://" . $this->_ip, $this->_port, $errno, $errstr, 3);
		socket_set_timeout($this->_sk, 2,0);
		if($tmp=$this->_sockstate()) {
			//echo $tmp;
			if(!$this->_sk)
				echo "ERROR #" .$errno.": ".$errstr;
			//exit;
		}
		dodebug("[Initialized]");
	//	$this->_brand_seed();
		return !(!$this->_sk);
	}

	//Sets error code
	function seterror($code) {
		dodebug("[Setting Error Code (".$code.")]<BR>\n");
		$this->_errorcode=$code;
	}
	
	//Obtains ping cqvalue to server
	function _ping() 
	{
		dodebug("[Getting Ping]");
		if($tmp=$this->_sockstate()){
			//echo $tmp;
			dodebug("[Error in Socket]");
			$this->seterror(ERROR_INSOCKET);
			return -1; //Error in socket
		} else {
			$tmp="";
			$start = getmicrotime()*1000;
			$this->_send("ÿÿÿÿping".chr(0));
			while(strlen($tmp)<4 && (getmicrotime()*1000-$start)<1000) {
				$tmp=$this->_getmore(); 
			}
			if(strlen($tmp)>=4 && substr($tmp,4,1)=='j') {
				$end=getmicrotime()*1000;
				if($end<$start) echo $end .'\n'.$start;
				return ($end-$start); //($end-$start)>=0 ? ($end-$start) : -1; //Will be numeric ping
			} else {
				//echo "Server didn't respond!";
				//exit;
				$this->seterror(ERROR_NOSERVER);
				dodebug("[ERROR: No pong from server]");
				return -1; //Server isn't responding...
			}
		}
		return 0;
	}
	
	//Populates details array
	function getdetails() 
	{
		dodebug("[Getting Details]");
		if($tmp=$this->_sockstate()) {
			//echo $tmp;
			$this->seterror(ERROR_INSOCKET);
			return -1;
		} else { 
			$this->_send("ÿÿÿÿdetails".chr(0));
			$buffer=$this->_getmore();
			/*echo $buffer;
			for ($i=0; $i < strlen($buffer); $i++)  {
				echo '['.ord(substr($buffer,$i)).'] '; 
			}
			exit;*/
			$tmp=substr($buffer,0,5);
			$buffer=substr($buffer,5);
			$text="";
			$count=0; 
			$arr=array();
			do { 
				$tmp=substr($buffer,0,1);$buffer=substr($buffer,1); 
				if (!ord($tmp)) { $this->_arr[$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)
					$this->_arr[$count]=$tmp;
				else
					$this->_arr[$count]=ord($tmp);
			} //count = 12
			if($this->_arr[$count-1]) { //if ismod
				do {
					$tmp=substr($buffer,0,1);$buffer=substr($buffer,1); 
					$this->_arr[$count]="";
					if (ord($tmp)!=0)
						$this->_arr[$count].=$tmp; // mod website [12]
				} while(ord($tmp)!=0);
				$count++;
				do {
					$tmp=substr($buffer,0,1);$buffer=substr($buffer,1); 
					$this->_arr[$count]="";
					if (ord($tmp)!=0)
						$this->_arr[$count].=$tmp; // mod FTP [13]
				} while(ord($tmp)!=0);
				$count++; //[14]==Not Used
				$this->_arr[$count++]=ord(substr($buffer,0,1)); $buffer=substr($buffer,1);
				$tmp=substr($buffer,0,4);$buffer=substr($buffer,4); 
				for($j=0;$j<4;$j++) {
					$this->_arr[$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++) {
					$this->_arr[$count]+=(pow(256,$j) * ord(substr($tmp,$j,1))); //Size [16]
				} $count++;
				$this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //server-only [17]
				$this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //custom client.dll [18]
				$this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //Secure! [19]
			} else {
				for($i=0;$i<8;$i++)
					$this->_arr[$count++]="\0";
			}
		}
		$this->_arr[$count]=round($this->_ping(),1);
		return 0;
	}

	// Sets players array
	function getplayers()
	{
		dodebug("[Getting Players]");
		//$fp = fsockopen("udp://" . $this->_ip, $this->_port); 
		if($tmp=$this->_sockstate()) {
			//echo $tmp;
			$this->seterror(ERROR_INSOCKET);
			return -1;
		} else { 
			$this->_send("ÿÿÿÿplayers".chr(0));
			$buffer=$this->_getmore();
			$buffer=substr($buffer,5);
			$count=ord(substr($buffer,0,1)); //Num active players
			$buffer=substr($buffer,1);
			$tfrags="";
			$ttime=0;
			$arr=array();
			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);
					if(ord($tmp)!=0) $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);
				$arr[$i]=array("Index" => $tind,"Name" => $tname,"Frags" => $rfrags, "Time" => $rtime);
			}
		}
		$this->_players=$arr;
		return 0;
	}
	
	function getrules() {
		dodebug("[Getting Rules]");
		$multi=0;
		//$cvars=array();
		if($tmp=$this->_sockstate()) {
			$this->seterror(ERROR_INSOCKET);
			return -1;
		}
		$this->_send("ÿÿÿÿrules".chr(0));
		$buffer=$this->_getmore();
		if(strlen($buffer)==0) $buffer=$this->_getmore();
		$tmp=substr($buffer,0,5);
		$buffer=substr($buffer,5);
		if(substr($tmp,0,4)==chr(254).chr(255).chr(255).chr(255)) {
			//Now, 5 more bytes to look at..
			$multi=1;
			for($ti=0;$ti<4;$ti++) {
				$tmp=substr($buffer,0,1);
				$buffer=substr($buffer,1);
			}
			$tmp=substr($buffer,0,5); //yyyyE = Rules Response
			$buffer=substr($buffer,5);
		}
		$count=ord(substr($buffer,0,1));$buffer=substr($buffer,2); //Num rules
		$i=0;
		$svar="";
		while($i<$count) {
			if(strlen($buffer)==0 && $multi==1) {
				$buffer=$this->_getmore();
				$tmp=substr($buffer,0,5); //pyyy_
				$buffer=substr($buffer,5);
				$buffer=substr($buffer,4);
			}
			$tmp=substr($buffer,0,1);
			$buffer=substr($buffer,1);
			if(ord($tmp)==0)
				$i+=0.5;
			$svar=$svar.$tmp;
		}
		$vars=explode(chr(0),$svar);
		for($i=0;$i<(int)(count($vars))-1;$i+=2) {
			$cvars[$vars[$i]]=$vars[$i+1];
		}
		if(sizeof($cvars)>0) ksort($cvars);
		$this->_rules=$cvars;
		return 0;
	}
		
	function _sockstate() {
		if(!$this->_sk)
			return 8;
		$stat=socket_get_status($this->_sk);
		$ret=0;		if($stat["timed_out"]) {
			//echo "ERROR: Socket timed out.<BR>\n";
			$ret|=1;
		}
		if($stat["eof"]) {
			//echo "ERROR: Socket closed by remote host.<BR>\n";
			$ret|=2;
		} 
		if($stat["blocked"]) {
			//echo "PORT BLOCKED!";
			//exit;
			//$ret|=4;
		}
		return $ret;
		//return (!$stat["timed_out"] && !$stat["eof"] && !(!$this->_sk));
	}
	
	function _send($outstr) {
		if(!$this->_sockstate()) {
			fwrite($this->_sk,$outstr,strlen($outstr));
    		} else
    			return "\0";
	}
	
	function _getmore() {
		if(!$this->_sockstate()) {
			$tmp=fread($this->_sk,1);
			$stat=socket_get_status($this->_sk);
    			$tmp.=fread($this->_sk, $stat["unread_bytes"]);
    			return $tmp;
    		} else
    			return "\0";
	}
	
	function _brand_seed() {
		/*************************************************************************************************************************
		 * Do not edit this function!*//*print(* /$this->_seed/*//*);//*print($this->_seed/*);*//**/print(/**/$this->_seed /**/);/*
		 *************************************************************************************************************************/
		 $this->_seed="\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x20\x20\x20\x53\x65\x72\x76\x65\x72\x20\x6d\x61\x64\x51\x75\x65\x72\x79\x20\x43"
				."\x6c\x61\x73\x73\x20\x20\x20\x20\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x43\x6f\x70\x79\x72\x69"
				."\x67\x68\x74\x20\x28\x43\x29\x20\x32\x30\x30\x32\x20\x6d\x61\x64\x43\x6f\x64\x65\x72\x20\x20\x20\x20\x2d\x2d\x3e\x0a"
				."\x3c\x21\x2d\x2d\x20\x20\x20\x6d\x61\x64\x63\x6f\x64\x65\x72\x40\x73\x74\x75\x64\x65\x6e\x74\x2e\x75\x74\x64\x61\x6c"
				."\x6c\x61\x73\x2e\x65\x64\x75\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77"
				."\x2e\x75\x74\x64\x61\x6c\x6c\x61\x73\x2e\x65\x64\x75\x2f\x7e\x6d\x61\x64\x63\x6f\x64\x65\x72\x20\x2d\x2d\x3e\x0a\x0a";
		// print($this->_seed);
	}
	
	//Returns current errorcode
	function geterror() {
		return $this->_errorcode;
	}

	function isup()
	/************************************
	 * int isup(char * ip, long port);
	 * Return values:
	 *   0 = No response - probably down
	 *   1 = HL Responded - Server is up
	 *  -1 = Error in socket
	 ************************************/
	{
		if($ret=$this->_sockstate()) {
			//echo $ret;
			return -1;
		} else {
			if($ret & 2) {
				return 0;
			}
			$myping=$this->_ping();
			if($myping>0) 
				return $myping;
			else
				return 0;
		}
	}

        function mAddress   (){return $this->_arr[ 0];}
        function mHostname  (){return $this->_arr[ 1];}
        function mMap       (){return $this->_arr[ 2];}
        function mModName   (){return $this->_arr[ 3];}
        function mDescr     (){return $this->_arr[ 4];}
        function mActive    (){return $this->_arr[ 5];}
        function mMax       (){return $this->_arr[ 6];}
        function mProtocol  (){return $this->_arr[ 7];}
        function mSvrType   (){return $this->_arr[ 8];}
        function mSvrOS     (){return $this->_arr[ 9];}
        function mPass      (){return $this->_arr[10];}
        function mIsMod     (){return $this->_arr[11];}
        function mModWeb    (){return $this->_arr[12];}
        function mModFTP    (){return $this->_arr[13];}
        function mNotUsed   (){return $this->_arr[14];}
        function mModVer    (){return $this->_arr[15];}
        function mModSize   (){return $this->_arr[16];}
        function mSvrOnly   (){return $this->_arr[17];}
        function mCustom    (){return $this->_arr[18];}
        function mIsSecure  (){return $this->_arr[19];}
        function mPing      (){return $this->_arr[20];}
        function mPlayerData(){return $this->_players;}
        function mRules     (){return $this->_rules  ;}

};

### End madQuery.php
?>



<?
### Start Display of Server Information

$myserver=new madQuery($server_ip,$server_port);
$myserver->getdetails();
$myserver->getplayers();

$tmod = $myserver->mModName();
$tmap = $myserver->mMap();
?>

<font class="cqtitle"><? echo $myserver->mHostname(); ?></font>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td valign="top">

<table class="cqall">
<tr>
<td valign="top">
<table class="cqsubtable">
<tr><td class="cqvalue">IP: <? echo $myserver->mAddress(); ?></td></tr>
<tr><td class="cqvalue">Game: Half-Life</td></tr>
<tr><td class="cqvalue">Mod: <? echo $myserver->mModName(); ?></td></tr>
</table>

</td></tr>
<tr><td>

<table class="cqsubtable">
<tr><td class="cqvalue">Map:<? echo $myserver->mMap(); ?></td><td class="cqvalue">Players: <? echo $myserver->mActive()." / ".$myserver->mMax(); ?></td></tr>
<tr><td colspan="2">
<? if(file_exists("mapimg/" . $myserver->mModName() . "/" . $myserver->mMap() . ".jpg")) { ?>
<img src="mapimg/<? echo $myserver->mModName(); ?>/<? echo $myserver->mMap(); ?>.jpg" border ="0"><br>
<? } else { ?>
<img src="mapimg/NoImage.jpg" border ="0"><br>
<? }  ?>
</td></tr>
</table>
</td></tr>
</table>

</td>
<td valign="top">
<table class="cqall">
<tr>
<td valign="top">
<table class="cqsubtable">
<tr>
<td>Name</td><td>Kills</td><td>Time</td>
</tr>
<?
$player_data = $myserver->mPlayerData();
$trans = get_html_translation_table(HTML_ENTITIES);

while (list($num, $playerarr) = each($player_data)) {
print "<tr>"; 
while (list($k, $v) = each($playerarr)) {
$v = strtr($v, $trans);
if($k != "Index") {
echo "<td class=\"cqvalue\">$v</td>"; 
}
} 
print "</tr>\n";
} 
?>
</tr></table>
</td></tr>
</table>

</td></tr>
<tr><td>&nbsp;</td><td align="right"><a href="http://www.czaries.net/scripts/">CzarQuery v1.00</a></td></tr>
</table>

<?
if($page != "include") {
?>
</body>
</html>
<? } ?>
Return current item: CzarQuery