Pobieranie danych z serwera gier GldSrc


(Pifarek) #1

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;

	}

}