Blog (3)
Komentarze (15)
Recenzje (0)
@Grzesie1k[PHP]Status serwera Battlefield 4

[PHP]Status serwera Battlefield 4

24.02.2014 | aktual.: 25.02.2014 15:46

Gry Battlefield 4 nie trzeba nikomu przedstawiać. Ostatnio stanąłem przed problemem wyświetlenia statusu serwera serwera gry Battlefield 4 na stronie www. Wujek Google z trudem odpowiadał na jakiekolwiek pytania z związane z tym tematem. Jedyną opcją wydawał się GameTracker, lecz przecież on też musiał jakoś te informacje pobierać. Znalazłem w końcu sposób na bezpośrednie pobranie statusu z serwera. Oto moje wypociny w tym temacie:

<?php
error_reporting(E_ALL);
set_time_limit(1);

class server {
    private $ip,$port,$timeout;
    protected $queryString=array();
    public function __construct($address,$timeout=1){
        list($this->ip,$this->port)=explode(':',$address);
        $this->timeout=$timeout;
    }
    public function query($type='status'){
        if(!array_key_exists($type,$this->queryString)) return false;
        $fp=@fsockopen($this->ip,$this->port,$errno,$errstr,$this->timeout);
        if(!$fp) return array("Error $errno: $errstr");
        fwrite($fp,$this->queryString[$type]);
        $buffer='';
        while(!feof($fp)){
            $buffer.=fread($fp,1024);
            $meta=stream_get_meta_data($fp);
            if($meta['unread_bytes']<=0) break;
        }
        return $this->parseBuffer($type,$buffer);
    }
    private function parseBuffer($type,$buffer){
        $buffer=substr($buffer,12);
        $response=array();
        while(!empty($buffer)){
            if($buffer[0]!="\x00")
                $response[]=substr($buffer,4,ord($buffer[0]));
            $buffer=substr($buffer,ord($buffer[0])+5);
        }
        return $this->interpreteResponse($type,$response);
    }
    protected function interpreteResponse($type,$response){
        return $response;
    }
}
class bf4server extends server{
    protected $queryString=array(
        'status'    =>"\x00\x00\x00\x00\x1b\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00serverInfo\x00",
        'version'   =>"\x00\x00\x00\x00\x18\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00version\x00",
        'players'   =>"\x00\x00\x00\x00\x24\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00listPlayers\x00\x03\x00\x00\x00\x61ll\x00",
    );
    protected function interpreteResponse($type,$response){
        if($response[0]!='OK')return false;
        unset($response[0]);
        switch($type){
            case 'status':{
                $th=array('serverName','players','slots','gametype','map','round','roundTotal','scoreCount','scoreA','scoreB','scoreMatchEnd','ranked','joinQueueEnable','password','uptime','roundTime','address','pbVersion','pb','region','pingSite','country','matchMaking','state');
                switch(count($response)){
					case 21:
						unset($th[16]);
					case 22:
						unset($th[8]);
                        unset($th[9]);
						break;
					default:
						return $response;
                }
				return array_combine($th,$response);
				
            }
            case 'version':{
                return array_combine(array('game','gameversion'),$response);
            }
            case 'players':{
                $n=$response[$response[1]+2];
                $th=array_values(array_slice($response,1,$response[1]));
                unset($th[1]); //dice bug...?
                $response=array_values(array_slice($response,count($th)+3));
                $players=array();
                for($i=0;$i<$n;$i++){
                    $players[]=array_combine($th,array_slice($response,$i*9,9));
                }
                return $players;
            }
        }
    }
}

$start=microtime(true);
$server=new bf4server('173.199.83.95:30010'); //random server
echo 'Server status ';
print_r($server->query());
echo 'Server version ';
print_r($server->query('version'));
echo 'Players ';
print_r($server->query('players'));
echo 'Wygenerowano w '.Number_format(microtime(true)-$start,3)."s\n";

A oto przykładowy efekt działania tego programu na losowym serwerze:

Server status Array
(
    [serverName] =>  =NOOBS WELCOME= 24/7 Siege of Shanghai | FAST XP
    [players] => 64
    [slots] => 64
    [gametype] => ConquestLarge0
    [map] => MP_Siege
    [round] => 0
    [roundTotal] => 2
    [scoreCount] => 2
    [scoreA] => 745.4487
    [scoreB] => 681.2927
    [scoreMatchEnd] => 0
    [ranked] => true
    [joinQueueEnable] => true
    [password] => false
    [uptime] => 544014
    [roundTime] => 2006
    [address] => 108.61.112.27:30100
    [pbVersion] => v1.883 | A1390 C2.333
    [pb] => true
    [region] => EU
    [pingSite] => ams
    [country] => DE
    [matchMaking] => 65
    [state] => IN_GAME
)
Server version Array
(
    [game] => BF4
    [gameversion] => 109758
)
Players Array
(
    [0] => Array
        (
            [name] => Burgher
            [teamId] => 1
            [squadId] => 2
            [kills] => 13
            [deaths] => 13
            [score] => 5188
            [rank] => 51
            [ping] => 55
            [type] => 0
        )

    [1] => Array
        (
            [name] => AdamJ76
            [teamId] => 2
            [squadId] => 8
            [kills] => 24
            [deaths] => 9
            [score] => 11752
            [rank] => 92
            [ping] => 34
            [type] => 0
        )

    [2] => Array
        (
            [name] => MrKumar85
            [teamId] => 1
            [squadId] => 1
            [kills] => 2
            [deaths] => 4
            [score] => 2349
            [rank] => 16
            [ping] => 35
            [type] => 0
        )

    [3] => Array
        (
            [name] => DanishB00y
            [teamId] => 1
            [squadId] => 4
            [kills] => 7
            [deaths] => 14
            [score] => 2667
            [rank] => 36
            [ping] => 43
            [type] => 0
        )
  ...

    [63] => Array
        (
            [name] => Akotoje
            [teamId] => 0
            [squadId] => 0
            [kills] => 0
            [deaths] => 0
            [score] => 0
            [rank] => 38
            [ping] => 156
            [type] => 0
        )

)
Wygenerowano w 0.427s

Mam nadzieję, że komuś się przyda. Do zobaczenia na polu bitwy ;)

Wybrane dla Ciebie
Komentarze (1)