예제 #1
0
파일: bzfquery.php 프로젝트: akooos/bzflag
function bzfquery($hostport)
{
    list($server['host'], $server['port']) = split(":", $hostport, 2);
    $protocol = 'tcp';
    $get_prot = getprotobyname($protocol);
    if ($get_prot == -1) {
        // if nothing found, returns -1
        echo 'Invalid Protocol';
        return $server;
    }
    if (!$server['port']) {
        $server['port'] = 5154;
    } elseif (!ctype_digit($server['port'])) {
        $server['port'] = getservbyname($server['port'], $protocol);
    }
    $server['ip'] = gethostbyname($server['host']);
    $fp = fsockopen($server['host'], $server['port'], $errno, $errstr, 5);
    if (!$fp) {
        echo "{$errstr} ({$errno})\n";
        return $server;
    }
    fwrite($fp, "BZFLAG\r\n\r\n");
    $buffer = fread($fp, 9);
    //var_dump($buffer);
    if (strlen($buffer) != 9) {
        echo "not a bzflag server";
        return $server;
    }
    # parse reply
    $server += unpack("a4magic/a4protocol/Cid", $buffer);
    //var_dump($server);
    if ($server['magic'] != "BZFS") {
        echo "not a bzflag server\n";
        fclose($fp);
        return $server;
    }
    if ($server['protocol'] != '0222') {
        echo "incompatible version\n";
        fclose($fp);
        return $server;
    }
    # MsgQueryGame + MsgQueryPlayers
    $request = pack("n2", 0, 0x7167);
    $request .= pack("n2", 0, 0x7170);
    //var_dump($request);
    fwrite($fp, $request);
    $loop = 0;
    $have = array();
    $have['QueryGame'] = false;
    $have['QueryPlayers'] = false;
    $have['TeamUpdate'] = false;
    $have['AllAddPlayer'] = false;
    while (in_array(false, $have) && $loop < 64) {
        $loop++;
        $packet = readpacket($fp);
        if ($GLOBALS['debug']) {
            echo "Length: " . $packet['len'] . "\n";
            echo "Code: " . $packet['code'] . " (" . dechex($packet['code']) . ") [" . chr(hexdec(substr(dechex($packet['code']), 0, 2))) . chr(hexdec(substr(dechex($packet['code']), 2, 2))) . "]\n";
            echo "Data: " . $packet['data'] . "\n\n";
        }
        switch ($packet['code']) {
            case MsgQueryGame:
                $server += unpack("ngameStyle/ngameOptions/nmaxPlayers/nmaxShots/nrogueSize/nredSize/ngreenSize/nblueSize/npurpleSize/nobserverSize/nrogueMax/nredMax/ngreenMax/nblueMax/npurpleMax/nobserverMax/nshakeWins/nshakeTimeout/nmaxPlayerScore/nmaxTeamScore/nmaxTime/ntimeElapsed", $packet['data']);
                $have['QueryGame'] = true;
                break;
            case MsgQueryPlayers:
                $server += unpack("nnumTotalTeams/nnumPlayers", $packet['data']);
                unset($server['numTotalTeams']);
                $have['QueryPlayers'] = true;
                if ($server['numPlayers'] == 0) {
                    $have['AllAddPlayer'] = true;
                }
                break;
            case MsgTeamUpdate:
                $server += unpack("CnumTeams", $packet['data']);
                $packet['data'] = substr($packet['data'], 1);
                for ($team = 0; $team < $server['numTeams']; $team++) {
                    $server['team'][$team] = unpack("nnum/nsize/nwon/nlost", $packet['data']);
                    $packet['data'] = substr($packet['data'], 8);
                }
                $have['TeamUpdate'] = true;
                break;
            case MsgAddPlayer:
                $player = unpack("Cid/ntype/nteam/nwon/nlost/ntks/a32sign/a128motto", $packet['data']);
                $server['player'][$player['id']] = $player;
                if (sizeof($server['player']) >= $server['numPlayers']) {
                    $have['AllAddPlayer'] = true;
                }
                break;
        }
    }
    fclose($fp);
    return $server;
}
예제 #2
0
function bzfquery0048($server, &$fp)
{
    # MsgQueryGame + MsgQueryPlayers
    $request = pack("n2", 0, 0x7167);
    $request .= pack("n2", 0, 0x7170);
    //var_dump($request);
    fwrite($fp, $request);
    $loop = 0;
    $have = array();
    $have['QueryGame'] = false;
    $have['QueryPlayers'] = false;
    $have['TeamUpdate'] = false;
    $have['AllAddPlayer'] = false;
    while (in_array(false, $have) && $loop < 64) {
        $packet = readpacket($fp);
        if ($GLOBALS['debug']) {
            echo "Length: " . $packet['len'] . "\n";
            echo "Code: " . $packet['code'] . " (" . dechex($packet['code']) . ") [" . chr(hexdec(substr(dechex($packet['code']), 0, 2))) . chr(hexdec(substr(dechex($packet['code']), 2, 2))) . "]\n";
            echo "Data: " . $packet['data'] . "\n\n";
        }
        switch ($packet['code']) {
            case MsgQueryGame:
                $server += unpack("ngameType/ngameOptions/nmaxPlayers/nmaxShots/nrogueSize/nredSize/ngreenSize/nblueSize/npurpleSize/nobserverSize/nrogueMax/nredMax/ngreenMax/nblueMax/npurpleMax/nobserverMax/nshakeWins/nshakeTimeout/nmaxPlayerScore/nmaxTeamScore/nmaxTime/ntimeElapsed", $packet['data']);
                $have['QueryGame'] = true;
                break;
            case MsgQueryPlayers:
                $server += unpack("nnumTotalTeams/nnumPlayers", $packet['data']);
                $have['QueryPlayers'] = true;
                if ($server['numPlayers'] == 0) {
                    $have['AllAddPlayer'] = true;
                }
                break;
            case MsgTeamUpdate:
                $server += unpack("CnumTeams", $packet['data']);
                $packet['data'] = substr($packet['data'], 1);
                for ($team = 0; $team < $server['numTeams']; $team++) {
                    $server['team'][$team] = unpack("nnum/nsize/nwon/nlost", $packet['data']);
                    $packet['data'] = substr($packet['data'], 8);
                }
                $have['TeamUpdate'] = true;
                break;
            case MsgAddPlayer:
                $player = unpack("Cid/ntype/nteam/nwon/nlost/ntks/a32sign/a128email", $packet['data']);
                $server['player'][$player['id']] = $player;
                if (sizeof($server['player']) >= $server['numPlayers']) {
                    $have['AllAddPlayer'] = true;
                }
                break;
        }
    }
    fclose($fp);
    return $server;
}