Помогите Получение онлайна на сайт

SoulRain

26 Фев 2023
9
0
0
Хай
Пытаюсь получить онлайн на сайт, но все плохо.

Всю инфу сервера получаю, а текущий онлайн не могу получить никак.
Вот скрипт который использую
[CODE lang="php" title="Index.php"]
<?php

function getSourceServerInfo(string $ip, string $port): array
{
$info = [
'status' => 0,
'ip' => $ip,
'port' => $port
];

$socket = @fsockopen("udp://{$ip}", $port, $errno, $errstr, 1);

if (!$socket) {
return $info;
}

stream_set_timeout($socket, 1);
stream_set_blocking($socket, true);

fwrite($socket, "\xFF\xFF\xFF\xFF\x54Source Engine Query\x00");
$packet = fread($socket, 4096);
@fclose($socket);

if (!$packet) {
return $info;
}

if (substr($packet, 4, 1) != "I") {
exit("NOT A SOURCE SERVER");
}

$packet_array = explode("\x00", substr($packet, 6), 5);
$info['name'] = $packet_array[0];
$info['map'] = $packet_array[1];
$info['game'] = $packet_array[2];
$info['description'] = $packet_array[3];
$packet = $packet_array[4];
$info['players'] = ord(substr($packet, 2, 1));
$info['playersmax'] = ord(substr($packet, 3, 1));
$info['bots'] = ord(substr($packet, 4, 1));
$info['status'] = 1;
$info['vac'] = ord(substr($packet, 8, 1));

return $info;
}


$query = getSourceServerInfo("94.103.88.61", '28333');
echo '<pre>';
echo print_r($query, 1);
echo '</pre>';
echo $info['players'];
?>
[/CODE]

Получаю данные вот такие
1678371114784.png
Players > 0, хотя по факту на сервере не 0

Кто шарит?
 
Хай
Пытаюсь получить онлайн на сайт, но все плохо.

Всю инфу сервера получаю, а текущий онлайн не могу получить никак.
Вот скрипт который использую
[CODE lang="php" title="Index.php"]
<?php

function getSourceServerInfo(string $ip, string $port): array
{
$info = [
'status' => 0,
'ip' => $ip,
'port' => $port
];

$socket = @fsockopen("udp://{$ip}", $port, $errno, $errstr, 1);

if (!$socket) {
return $info;
}

stream_set_timeout($socket, 1);
stream_set_blocking($socket, true);

fwrite($socket, "\xFF\xFF\xFF\xFF\x54Source Engine Query\x00");
$packet = fread($socket, 4096);
@fclose($socket);

if (!$packet) {
return $info;
}

if (substr($packet, 4, 1) != "I") {
exit("NOT A SOURCE SERVER");
}

$packet_array = explode("\x00", substr($packet, 6), 5);
$info['name'] = $packet_array[0];
$info['map'] = $packet_array[1];
$info['game'] = $packet_array[2];
$info['description'] = $packet_array[3];
$packet = $packet_array[4];
$info['players'] = ord(substr($packet, 2, 1));
$info['playersmax'] = ord(substr($packet, 3, 1));
$info['bots'] = ord(substr($packet, 4, 1));
$info['status'] = 1;
$info['vac'] = ord(substr($packet, 8, 1));

return $info;
}


$query = getSourceServerInfo("94.103.88.61", '28333');
echo '<pre>';
echo print_r($query, 1);
echo '</pre>';
echo $info['players'];
?>
[/CODE]

Получаю данные вот такие
1678371114784.png
Players > 0, хотя по факту на сервере не 0

Кто шарит?
Для получения точной информации по текущему онлайну на сервере, Вы можете воспользоваться дополнительным запросом к серверу. Для этого, после отправки запроса "Source Engine Query" на сервер, необходимо отправить еще один запрос, который позволит получить информацию о текущем состоянии сервера. Вот модифицированный код функции getSourceServerInfo, который позволит получить более точную информацию:

PHP:
function getSourceServerInfo(string $ip, string $port): array
{
    $info = [
        'status' => 0,
        'ip' => $ip,
        'port' => $port
    ];

    $socket = @fsockopen("udp://{$ip}", $port, $errno, $errstr, 1);

    if (!$socket) {
        return $info;
    }

    stream_set_timeout($socket, 1);
    stream_set_blocking($socket, true);

    // Отправляем запрос Source Engine Query
    fwrite($socket, "\xFF\xFF\xFF\xFF\x54Source Engine Query\x00");
    $packet = fread($socket, 4096);

    if (!$packet) {
        return $info;
    }

    if (substr($packet, 4, 1) != "I") {
        exit("NOT A SOURCE SERVER");
    }

    $packet_array = explode("\x00", substr($packet, 6), 5);
    $info['name'] = $packet_array[0];
    $info['map'] = $packet_array[1];
    $info['game'] = $packet_array[2];
    $info['description'] = $packet_array[3];
    $packet = $packet_array[4];
    $info['players'] = ord(substr($packet, 2, 1));
    $info['playersmax'] = ord(substr($packet, 3, 1));
    $info['bots'] = ord(substr($packet, 4, 1));
    $info['status'] = 1;
    $info['vac'] = ord(substr($packet, 8, 1));

    // Отправляем запрос A2S_PLAYER для получения списка игроков
    fwrite($socket, "\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF");
    $packet = fread($socket, 4096);

    if (!$packet) {
        return $info;
    }

    if (substr($packet, 4, 1) != "D") {
        exit("NOT A SOURCE SERVER");
    }

    $info['players'] = ord(substr($packet, 5, 1));
    $player_info = substr($packet, 6);
    $players = [];

    for ($i = 0; $i < strlen($player_info); $i++) {
        $player = [];
        $player['index'] = ord($player_info{$i});
        $i++;
        $player['name'] = substr($player_info, $i, strpos($player_info, "\x00", $i) - $i);
        $i += strlen($player['name']) + 1;
        $player['score'] = unpack("i", substr($player_info, $i, 4))[1];
        $i += 4;
        $players[] = $player;
    }

    $info['players_info'] = $players;

    // Отправляем запрос A2S_RULES для получения дополнительной информации о сервере
    fwrite($socket, "\xFF\xFF\xFF\xFF\x56\xFF\xFF\xFF\xFF");
    $packet = fread($socket, 4096);

    if (!$packet) {
        return $info;
    }

    if (substr($packet, 4, 1) != "E") {
        exit("NOT A SOURCE SERVER");
    }

    $rules_info = substr($packet, 5);
    $rules = [];

    while (strlen($rules_info) > 0) {
        $rule_name = substr($rules_info, 0, strpos($rules_info, "\x00"));
        $rules_info = substr($rules_info, strlen($rule_name) + 1);
        $rule_value = substr($rules_info, 0, strpos($rules_info, "\x00"));
        $rules_info = substr($rules_info, strlen($rule_value) + 1);
        $rules[$rule_name] = $rule_value;
    }

    $info['rules'] = $rules;

    @fclose($socket);

    return $info;
}

После получения данных с помощью этой функции, Вы сможете получить более точную информацию о текущем онлайне на сервере.
 
Для получения точной информации по текущему онлайну на сервере, Вы можете воспользоваться дополнительным запросом к серверу. Для этого, после отправки запроса "Source Engine Query" на сервер, необходимо отправить еще один запрос, который позволит получить информацию о текущем состоянии сервера. Вот модифицированный код функции getSourceServerInfo, который позволит получить более точную информацию:

PHP:
function getSourceServerInfo(string $ip, string $port): array
{
    $info = [
        'status' => 0,
        'ip' => $ip,
        'port' => $port
    ];

    $socket = @fsockopen("udp://{$ip}", $port, $errno, $errstr, 1);

    if (!$socket) {
        return $info;
    }

    stream_set_timeout($socket, 1);
    stream_set_blocking($socket, true);

    // Отправляем запрос Source Engine Query
    fwrite($socket, "\xFF\xFF\xFF\xFF\x54Source Engine Query\x00");
    $packet = fread($socket, 4096);

    if (!$packet) {
        return $info;
    }

    if (substr($packet, 4, 1) != "I") {
        exit("NOT A SOURCE SERVER");
    }

    $packet_array = explode("\x00", substr($packet, 6), 5);
    $info['name'] = $packet_array[0];
    $info['map'] = $packet_array[1];
    $info['game'] = $packet_array[2];
    $info['description'] = $packet_array[3];
    $packet = $packet_array[4];
    $info['players'] = ord(substr($packet, 2, 1));
    $info['playersmax'] = ord(substr($packet, 3, 1));
    $info['bots'] = ord(substr($packet, 4, 1));
    $info['status'] = 1;
    $info['vac'] = ord(substr($packet, 8, 1));

    // Отправляем запрос A2S_PLAYER для получения списка игроков
    fwrite($socket, "\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF");
    $packet = fread($socket, 4096);

    if (!$packet) {
        return $info;
    }

    if (substr($packet, 4, 1) != "D") {
        exit("NOT A SOURCE SERVER");
    }

    $info['players'] = ord(substr($packet, 5, 1));
    $player_info = substr($packet, 6);
    $players = [];

    for ($i = 0; $i < strlen($player_info); $i++) {
        $player = [];
        $player['index'] = ord($player_info{$i});
        $i++;
        $player['name'] = substr($player_info, $i, strpos($player_info, "\x00", $i) - $i);
        $i += strlen($player['name']) + 1;
        $player['score'] = unpack("i", substr($player_info, $i, 4))[1];
        $i += 4;
        $players[] = $player;
    }

    $info['players_info'] = $players;

    // Отправляем запрос A2S_RULES для получения дополнительной информации о сервере
    fwrite($socket, "\xFF\xFF\xFF\xFF\x56\xFF\xFF\xFF\xFF");
    $packet = fread($socket, 4096);

    if (!$packet) {
        return $info;
    }

    if (substr($packet, 4, 1) != "E") {
        exit("NOT A SOURCE SERVER");
    }

    $rules_info = substr($packet, 5);
    $rules = [];

    while (strlen($rules_info) > 0) {
        $rule_name = substr($rules_info, 0, strpos($rules_info, "\x00"));
        $rules_info = substr($rules_info, strlen($rule_name) + 1);
        $rule_value = substr($rules_info, 0, strpos($rules_info, "\x00"));
        $rules_info = substr($rules_info, strlen($rule_value) + 1);
        $rules[$rule_name] = $rule_value;
    }

    $info['rules'] = $rules;

    @fclose($socket);

    return $info;
}

После получения данных с помощью этой функции, Вы сможете получить более точную информацию о текущем онлайне на сервере.
Выдает ошибку NOT A SOURCE SERVER, почему ?
 
Если все игроки с лицензии и сервер есть на BattleMetrics, то можно через их апи:
[CODE lang="php" title="php"] $country = file_get_contents('https://api.battlemetrics.com/servers/АЙДИ_СЕРВЕРА');
$country = json_decode($country);
$online = $country->data->attributes->players;[/CODE]
 
А пиратский можно так, если он есть на мониторинге алкада, я правда никогда не интересовался, отдают ли библиотеки подобной выше онлайн пиратки, поэтому костылил что-то такое:
[CODE title="php"] include 'simple_html_dom.php';
$html = file_get_html('https://monitoring.[Бомжи]/server/АЙПИ_ТУТ');
$data = $html->find('table', 0)->find('td', 9)->innertext(2);
preg_match_all('!\d+!', $data, $matches);
$sum = $matches[0][0];[/CODE]
 
Выдает ошибку NOT A SOURCE SERVER, почему ?

Ошибка NOT A SOURCE SERVER возникает, когда запрос не является запросом Source Engine Query, либо сервер не является сервером Source Engine. Проверьте, что IP-адрес и порт сервера указаны верно, а также убедитесь, что сервер работает на движке Source Engine.

Если после проверки все указано правильно, попробуйте установить значение параметра stream_set_blocking равным false, как показано ниже:

PHP:
stream_set_blocking($socket, false);

Также убедитесь, что у Вас установлены необходимые расширения для работы с сокетами в PHP.
 
Хай
Пытаюсь получить онлайн на сайт, но все плохо.

Кто шарит?
Привет, могу написать вспомогательный плагин который будет по веб запросу отправлять онлайн при заходе/выходе игроков. Так у тебя 100% будет показывать верный онлайн.
 
Привет, могу написать вспомогательный плагин который будет по веб запросу отправлять онлайн при заходе/выходе игроков. Так у тебя 100% будет показывать верный онлайн.
Нужно написать мега веб сервис, обязатель в свзяке должен быть nodejs, bootstrap и все современные стеки. Так же все запихать по докерам, да бы было все отказоустойчево.

Но НЕ в коем случае, не нужно читать документацию, и искать там EDF & 0x20, и уже плясать от него)
 
  • Мне нравится
Реакции: Drop Dead
Активность
Пока никто не печатает сообщение

Похожие темы