Napisałem sobie taką klasę, ale…
Pobierając dane na temat zasad serwera, dane te są wysyłane jako dwa pakiety, a na początku drugiego występują dziwne znaki, które nie wiem o czym informują. Tym samym podstawiając to pod tablice, powstaje niepotrzebne przesunięcie. Widać to tu: http://wcee.org.pl/ss/?p=rules . Ma ktoś jakiś pomysł jak temu zaradzić?
class server {
var $server;
var $ip;
var $port;
var $timeout;
var $data;
var $put;
function server ($ip, $port, $timeout = 3) {
$this->server = fsockopen ('udp://' . $ip, $port);
$this->timeout = $timeout;
}
function getServerInfo () {
$this->writeData ($this->sendQuery ("A2S_INFO"));
fread($this->server, 5);
$info[ip] = $this->readData("string");
$info[hostname] = $this->readData("string");
$info[map] = $this->readData("string");
$info[dir] = $this->readData("string");
$info[game] = $this->readData("string");
$info[num_players] = ord($this->readData("byte"));
$info[max_players] = ord($this->readData("byte"));
$info[version] = ord($this->readData("byte"));
$info[dedicated] = $this->readData("byte") == "d" ? "Dedicated" : "Listen";
$info[os] = $this->readData("byte") == "l" ? "Linux" : "Windows";
$info[password] = ord($this->readData("byte"));
$info[isMod] = ord($this->readData("byte"));
$info[mod_url] = $this->readData("string");
$info[mod_dl] = $this->readData("string");
$this->readData("byte");
$info[mod_version] = ord($this->readData("long"));
$info[mod_size] = ord($this->readData("long"));
$info[mod_sv] = ord($this->readData("byte"));
$info[mod_customdll] = ord($this->readData("byte"));
return $info;
}
function getPlayersInfo () {
$this->writeData ($this->sendQuery ("A2S_PLAYER"));
fread($this->server, 5);
$number = ord($this->readData("byte"));
for ($i = 0; $i < $number; $i++) {
$players[$i][id] = ord($this->readData("byte"));
$players[$i][name] = $this->readData("string");
$players[$i][kills] = $this->convertToString($this->readData("long"));
$players[$i][time] = $this->convertToString($this->readData("long"));
}
return $this->sortPlayers ($players);
}
function getRulesInfo () {
$this->writeData ($this->sendQuery ("A2S_RULES")); / **buggy when rules send in two packages** /
fread($this->server, 14);
$number = ord($this->readData("short"));
for ($i = 0; $i < $number; $i++) {
$rules[$i][value] = $this->readData("string");
$rules[$i][name] = $this->readData("string");
}
return $rules;
}
function sendQuery ($query) {
switch ($query) {
case 'A2S_SERVERQUERY_GETCHALLENGE':
return "\xFF\xFF\xFF\xFF\x57";
case 'A2S_INFO':
return "\xFF\xFF\xFF\xFF\x54\x53\x6F\x75\x72\x63\x65\x20\x45\x6E\x67\x69\x6E\x65\x20\x51\x75\x65\x72\x79\x00";
case 'A2S_PLAYER':
$challenge = $this->getChallange();
return "\xFF\xFF\xFF\xFF\x55" . $challenge;
case 'A2S_RULES':
$challenge = $this->getChallange();
return "\xFF\xFF\xFF\xFF\x56" . $challenge;
}
}
function convertToString ($data) {
list (, $data) = unpack("L", $data);
return $data;
}
function getChallange () {
$this->writeData ($this->sendQuery ("A2S_SERVERQUERY_GETCHALLENGE"));
fread($this->server, 5);
return fread($this->server, 4);
}
function writeData ($put) {
if ($this->server) {
fwrite ($this->server, $put);
socket_set_timeout($this->server, $this->timeout);
}
}
function readData ($type) {
switch ($type) {
case 'byte':
return fread($this->server, 1);
break;
case 'string':
$do = True;
while ($do) {
$char = fread($this->server, 1);
if ($char != "\x00") {
$string .= $char;
} else {
$do = False;
}
}
return $string;
break;
case 'long':
return fread($this->server, 4);
break;
case 'float':
return fread($this->server, 4);
break;
case 'short':
return fread($this->server, 2);
break;
}
}
function sortPlayers ($players) {
foreach ($players as $key => $line) {
$kills[$key] = $line[kills];
$name[$key] = $line[name];
}
array_multisort($kills, SORT_DESC, $name, SORT_DESC, $players);
return $players;
}
}