<?
// **********************************************************************************************
// Class Unreal
// Author : Henrik Schack Jensen (henrik@schack.dk)
//
// Changelog:
// Version 1.00 03/16/2001 Initial release
// A utilityclass (PHP4 only) to do serverstatus-queries against UnrealTournament 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 Unreal {
var $m_playerinfo =""; // Info about players
var $m_servervars =""; // Info about the server
var $errmsg ="";
//
// Get exact time, used for timeout counting
//
function timenow() {
return doubleval(ereg_replace('^0\.([0-9]*) ([0-9]*)$','\\2.\\1',microtime()));
}
//
// 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+1,$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 (substr($serverdata,strlen($serverdata)-7)!="\\final\\");
fclose($cssocket);
return $serverdata;
}
// **********************************************************************
// getServerStatus
// Read rules/setup from the gameserver into servervars
// Return true if successful
// **********************************************************************
function getServerStatus($serveraddress,$portnumber,$timeout) {
$cmd="\\status\\";
$serverdata=$this->getServerData($cmd,$serveraddress,$portnumber,$timeout);
// Is data complete ?
// This strange doublecheck is needed since UT serverdata sometimes arrives out of order
if ((substr($serverdata,strlen($serverdata)-7)!="\\final\\") || (substr($serverdata,1,8)!="gamename")) {
$this->errmsg="Data incomplete";
return false;
}
// Remove \\final\\ text at end of data
$serverdata=substr($serverdata,1,strlen($serverdata)-7);
// Split data and fill into array
$name_tok = strtok ($serverdata,"\\");
$val_tok = strtok ("\\");
while (strlen($name_tok)) {
if ($name_tok!="queryid") {
$vars[$name_tok]=$val_tok;
}
$name_tok = strtok ("\\");
$val_tok = strtok ("\\");
}
while (list($key,$data) = each ($vars)) {
if (!strncmp($key,"player_",7)) {
$player[substr($key,7)]["name"]=$data;
} elseif (!strncmp($key,"ping_",5)) {
$player[substr($key,5)]["ping"]=$data;
} elseif (!strncmp($key,"frags_",6)) {
$player[substr($key,6)]["frags"]=$data;
} elseif (!strncmp($key,"team_",5)) {
$player[substr($key,5)]["team"]=$data;
} elseif (!strncmp($key,"skin_",5)) {
$player[substr($key,5)]["skin"]=$data;
} elseif (!strncmp($key,"mesh_",5)) {
$player[substr($key,5)]["mesh"]=$data;
} elseif (!strncmp($key,"face_",5)) {
$player[substr($key,5)]["face"]=$data;
} elseif (!strncmp($key,"ngsecret_",9)) {
$player[substr($key,9)]["ngsecret"]=$data;
} else {
$this->m_servervars[$key]=$data;
}
}
// Move playerinfo to membervariable
for ($i=0;$i<$this->m_servervars["numplayers"];$i++) {
$this->m_playerinfo[$i]=array("name"=>$player[$i]["name"],"ping"=>$player[$i]["ping"],"frags"=>$player[$i]["frags"]);
}
// If there are players on the server we sort them by frags
if ($this->m_servervars["numplayers"]>0) usort($this->m_playerinfo,"fragsort");
// Make maptitle lowercase
$this->m_servervars["mapname"]=strtolower($this->m_servervars["mapname"]);
return true;
}
}
?>
|