Login   Register  
PHP Classes
elePHPant
Icontem

File: quake3.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Henrik Schack  >  Quake3  >  quake3.php  >  Download  
File: quake3.php
Role: ???
Content type: text/plain
Description: Quake3Arena Class
Class: Quake3
Author: By
Last change:
Date: 2001-03-13 17:57
Size: 4,441 bytes
 

Contents

Class file image Download
<?
//	**********************************************************************************************
//	Class Quake3
//	Author : Henrik Schack Jensen (henrik@schack.dk)
// 
//	Changelog:
// 	Version 1.00		03/13/2001 Initial release
//	A utilityclass (PHP4 only) to do serverstatus-queries against Quake3Arena servers
//
//	Syntax:
// 
//	Function getServerStatus(serveraddress,serverport,timeout)
//	Get player/servervar info from server
//
//	All results are returned in membervariables:
//
//
//	Demosource is available at http://www.gameserver.dk/
//	**********************************************************************************************


//
//	Function used to sort players by frags
//	Needs to be defined globally in order for usort to call it
// 	

function fragsort ($a, $b) {   
	if ($a["frags"] == $b["frags"]) return 0;
	if ($a["frags"] > $b["frags"]) {
		return -1;
	} else {
		return 1;
	}
}	

Class Quake3 {
	var $m_playerinfo		="";		// Info about players
	var $m_servervars		="";		// Info about the server 
	
	//
	// Get exact time, used for timeout counting
	//
	function timenow() {
		return doubleval(ereg_replace('^0\.([0-9]*) ([0-9]*)$','\\2.\\1',microtime()));
	}	
	
	//
	// Function to remove funny characters from playernames
	//
	function removefunchars($data) {
		$result="";
		$skipnextchar=false;
		for ($i=0;$i<strlen($data);$i++) {
			if (!$skipnextchar) {
				$currentchar=ord(substr($data,$i,1));
				if (($currentchar==27) || ($currentchar==94)) {
					$skipnextchar=true;
				} else {
					if (($currentchar>=32) && ($currentchar<=127)) $result=$result.chr($currentchar);
					if (($currentchar>=160) && ($currentchar<=255)) $result=$result.chr($currentchar-128);
				}
			} else {
				$skipnextchar=false;
			}
		}
		return $result;
	}

	//
	// Read raw data from server
	//
	function getServerData($command,$serveraddress,$portnumber,$waittime) {
		$serverdata		="";
		$serverdatalen=0;
		
		if ($waittime< 500) $waittime= 500;
		if ($waittime>2000) $waittime=2000;
		$waittime=doubleval($waittime/1000.0);

		if (!$cssocket=fsockopen("udp://".$serveraddress,$portnumber,$errnr)) {
			$this->errmsg="No connection";
			return "";
		}
		socket_set_blocking($cssocket,true);
		socket_set_timeout($cssocket,0,500000);
		fwrite($cssocket,$command,strlen($command));	
		// Mark
		$starttime=$this->timenow();
		do {
			$serverdata.=fgetc($cssocket);
			$serverdatalen++;
			$socketstatus=socket_get_status($cssocket);
			if ($this->timenow()>($starttime+$waittime)) {
				$this->errmsg="Connection timed out";
				fclose($cssocket);
				return "";
			}
		} while ($socketstatus["unread_bytes"] );
		fclose($cssocket);
		return $serverdata;		
	}	


	// **********************************************************************
	// getServerStatus
	// Read rules/setup from the gameserver into m_servervars
	// Return true if successful
	// **********************************************************************	
	function getServerStatus($serveraddress,$portnumber,$timeout) {
		
		$cmd="\xFF\xFF\xFF\xFFgetstatus\n";		
		$serverdata=$this->getServerData($cmd,$serveraddress,$portnumber,$timeout);
		if (strlen($serverdata)>20) {
			$serverdata=substr($serverdata,20);
		} else {
			return false;
		}

		$srvvars=substr($serverdata,0,strpos($serverdata,"\n"))."\\";
		$players=substr($serverdata,strpos($serverdata,"\n")+1);
		
		// Skip the last linefeed
		$players=substr($players,0,strlen($players)-1);
		
		// Split playerinfo and fill into array
		$playercount=0;
		if (strlen($players)) {
			$playercollection=explode("\n",$players);
			while (list($key,$data) = each ($playercollection)) {
				eregi("^([-0-9]+) ([-0-9]+) \"(.*)\"",$data,$player);
				$this->m_playerinfo[$key]=array("frags"=>$player[1],"ping"=>$player[2],"name"=>$this->removefunchars($player[3]));
				$playercount++;
			}
		}
		// Fake servervar containing number of current players
		$this->m_servervars["sv_currentclients"]=$playercount;
		
		if ($playercount>0) usort($this->m_playerinfo,"fragsort");

		// Split servervars and fill into array
		$name_tok = strtok ($srvvars,"\\");
		$val_tok  = strtok ("\\");
		while (strlen($name_tok)) {
			$this->m_servervars[$name_tok]=$val_tok;
			$name_tok = strtok ("\\");
			$val_tok  = strtok ("\\");
		}
		return true;
	}	
}
?>