我有一个脚本,我发现它可以查询SRCDS游戏服务器并输出信息,如主机名、IP、连接播放器等(注意,我已经编辑了它,所以它只显示当前连接的播放器和地图)我希望脚本首先平服务器以检查它是否在线,然后继续查询。
PHP脚本
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;
}显示代码
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'];澄清:此脚本可以很好地返回当前连接的播放机和服务器联机时正在播放的当前地图。当服务器离线加载一段时间后,只需打印
Players: /
Map: 我想让服务器事先按下键。如果它是联机的,它会像上面那样做,但是如果它是脱机的,我希望它回显“脱机”,删除
Players: /
Map: 不要继续查询,以尽量减少加载页面所需的时间。
发布于 2014-02-20 20:38:01
这很可能不会让事情变得更快,但至少比你现在所拥有的要好。但是,我要注意的是,PHP手册在引用unread_bytes使用时这样说:Note: You shouldn't use this value in a script. --您还可以减少调用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);显示代码
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'];
}发布于 2014-02-20 20:28:12
根据手册 of fsockopen,特别是对于UDP连接,您应该考虑执行更多的错误处理:
警告 UDP套接字有时会显示打开时没有错误,即使远程主机无法访问。只有在将数据读写到/从套接字中读取或写入数据时,错误才会变得明显。这是因为UDP是一个“无连接”协议,这意味着操作系统在实际需要发送或接收数据之前不会尝试为套接字建立链接。
https://stackoverflow.com/questions/21918515
复制相似问题