dongzha0149 2014-02-20 20:13
浏览 42
已采纳

PHP Gameserver查询

I have a script I found that queries SRCDS gameservers and outputs information such as hostname, IP, connected players etc. (Note I have edited it so it only displayes currently connected players and map) I would like the script to first ping the server to check if it is online or not and then continue with the queries.

PHP Script

function source_query($ip){
$cut = explode(":", $ip);
$HL2_address = $cut[0];
$HL2_port = $cut[1];

$HL2_command = "\377\377\377\377TSource Engine Query\0";

$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
fwrite($HL2_socket, $HL2_command); 
$JunkHead = fread($HL2_socket,4);
$CheckStatus = socket_get_status($HL2_socket);

if($CheckStatus["unread_bytes"] == 0)return 0;

$do = 1;
while($do){
    $str = fread($HL2_socket,1);
    $HL2_stats.= $str;
    $status = socket_get_status($HL2_socket);
    if($status["unread_bytes"] == 0){
           $do = 0;
    }
}
fclose($HL2_socket);

$x = 0;
while ($x <= strlen($HL2_stats)){
    $x++;
    $result.= substr($HL2_stats, $x, 1);    
}

// ord ( string $string );
$result = str_split($result);
$info['network'] = ord($result[0]);$char = 1;
while(ord($result[$char]) != "%00"){$info['name'] .= $result[$char];$char++;}$char++;
while(ord($result[$char]) != "%00"){$info['map'] .= $result[$char];$char++;}$char++;
while(ord($result[$char]) != "%00"){$info['dir'] .= $result[$char];$char++;}$char++;
while(ord($result[$char]) != "%00"){$info['description'] .= $result[$char];$char++;}$char++;
$info['appid'] = ord($result[$char].$result[($char+1)]);$char += 2;        
$info['players'] = ord($result[$char]);$char++;    
$info['max'] = ord($result[$char]);$char++;    
$info['bots'] = ord($result[$char]);$char++;    
$info['dedicated'] = ord($result[$char]);$char++;    
$info['os'] = chr(ord($result[$char]));$char++;    
$info['password'] = ord($result[$char]);$char++;    
$info['secure'] = ord($result[$char]);$char++;    
while(ord($result[$char]) != "%00"){$info['version'] .= $result[$char];$char++;}

return $info;
}

Display code

include 'status.php'; // name of file including above script
$q = source_query('ip:port'); // replaced with real IP address and port
echo "Players: " .$q['players'];
echo "/" .$q['max'];
echo "<br>";
echo "Map: ".$q['map'];

To clarify: this script works fine in returning currently connected players and current map being played when the server is online. When the server is offline is loads for a while then just prints

Players: /
Map: 

I want the server to be pinged beforehand. If it is online it does as above, but if it is offline I want it to echo "Offline", remove the

Players: /
Map: 

and do not continue with the query to minimise the length of time it takes to load the page.

  • 写回答

2条回答 默认 最新

  • duanchi1230 2014-02-20 20:38
    关注

    This most likely won't speed things up a whole lot, but it's probably better than what you have now at least. However, I'll note that the PHP manual says this in reference to the unread_bytes usage: Note: You shouldn't use this value in a script. You could also decrease the timeout (the last parameter) on the call to fsockopen.

    function ping($host)
    {
        exec(sprintf('ping -c 1 -W 5 %s', escapeshellarg($host)), $res, $rval);
        return $rval === 0;
    }
    
    $HL2_command = "\377\377\377\377TSource Engine Query\0";
    
    if(!ping($HL2_address))
    {
        return 0;
    }
    
    $HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
    

    Display code

    include 'status.php'; // name of file including above script
    $q = source_query('ip:port'); // replaced with real IP address and port
    
    if($q === 0)
    {
        echo "Offline";
    }
    else
    {
        echo "Players: " .$q['players'];
        echo "/" .$q['max'];
        echo "<br>";
        echo "Map: ".$q['map'];
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 51单片机中C语言怎么做到下面类似的功能的函数(相关搜索:c语言)
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比