https://www.battleye.com/downloads/BERConProtocol.txt
以下代码是通过游戏服务器的远程连接。 (RCon)BattlEye协议(上面的链接)。基本上它只是在套接字上读写。
脚本将命令比如说测试
正如你所看到的,它是一个无趣的循环。
睡眠1秒后,应发送cmd并重新开始循环。
$pass = "my_rcon_pw";
$ip = "12.34.56.78";
$port = 2309;
//
$authCRC = sprintf('%x', crc32(chr(255).chr(00).trim($pass)));
$authCRC = array(substr($authCRC,-2,2), substr($authCRC,-4,2), substr($authCRC,-6,2), substr($authCRC,0,2));
$loginMsg = 'BE'.chr(hexdec($authCRC[0])).chr(hexdec($authCRC[1])).chr(hexdec($authCRC[2])).chr(hexdec($authCRC[3]));
$loginMsg .= chr(hexdec('ff')).chr(hexdec('00')).trim($pass);
$hbMsg = 'BE'.chr(hexdec('7d')).chr(hexdec('8f')).chr(hexdec('ef')).chr(hexdec('73'));
$hbMsg .= chr(hexdec('ff')).chr(hexdec('02')).chr(hexdec('00'));
//
$server = @fsockopen( "udp://" . $ip, $port, $errno, $errstr, 1 );
if( $server === false ) throw new \Exception( 'Could not bind to socket: ' . $errstr );
//
$sent = fwrite( $server, $loginMsg );
if( $sent === false ) throw new \Exception( 'Failed to send login!' );
$result = fread( $server, 16 );
if( @ord( $result[strlen( $result ) - 1] ) == 0 ) throw new \Exception( 'Login failed, wrong password or wrong port!' );
//
for(;;)
{
sleep(1);
$command = "say -1 TEST";
$msgCRC = sprintf('%x', crc32(chr(255).chr(01).chr(hexdec(sprintf('%01b', 0))).trim($command)));
$msgCRC = array(substr($msgCRC,-2,2),substr($msgCRC,-4,2),substr($msgCRC,-6,2),substr($msgCRC,0,2));
$cmdHead = 'BE'.chr(hexdec($msgCRC[0])).chr(hexdec($msgCRC[1])).chr(hexdec($msgCRC[2])).chr(hexdec($msgCRC[3])).chr(hexdec('ff')).chr(hexdec('01')).chr(hexdec(sprintf('%01b', 0)));
$cmdMsg = $cmdHead.trim($command);
//
$cmd = fwrite( $server, $cmdMsg );
if( $cmd === false ) throw new \Exception( 'Failed to send command!' );
}
9-10秒后,服务器将关闭客户端的连接。发生这种情况是因为客户端需要向他仍然活着的服务器发送验证。
以下代码添加"心跳"约每10秒进入循环。
for(;;)
{
if( !isset( $i ) ) $i = 0;
sleep(1);
$command = "say -1 TEST";
$msgCRC = sprintf('%x', crc32(chr(255).chr(01).chr(hexdec(sprintf('%01b', 0))).trim($command)));
$msgCRC = array(substr($msgCRC,-2,2),substr($msgCRC,-4,2),substr($msgCRC,-6,2),substr($msgCRC,0,2));
$cmdHead = 'BE'.chr(hexdec($msgCRC[0])).chr(hexdec($msgCRC[1])).chr(hexdec($msgCRC[2])).chr(hexdec($msgCRC[3])).chr(hexdec('ff')).chr(hexdec('01')).chr(hexdec(sprintf('%01b', 0)));
$cmdMsg = $cmdHead.trim($command);
//
$cmd = fwrite( $server, $cmdMsg );
if( $cmd === false ) throw new \Exception( 'Failed to send command!' );
$i++;
//
if( $i == 9 )
{
$hb = fwrite( $server, $hbMsg );
if( $hb === false ) throw new \Exception( 'Failed to send heartbeat!' );
unset( $i );
}
}
奇怪的是,这种心跳只能一次。 这意味着客户在开始后不超过10秒就超时,现在开始后不到20秒左右。
这就是这段代码的全部问题。
我在PHP控制台中运行它 - 所以没有最大执行时间或其他任何内容。
目标是将其作为"执行"客户端和服务器之间的连接。
问题
与协议一样,客户端需要确认服务器的数据包或将超时。
如何确认协议中描述的传入数据包?
我的心跳包到服务器可能有问题吗?
我真的很感激任何提示或帮助:)
到目前为止,感谢德国人的问候!