【发布时间】:2014-01-16 23:26:34
【问题描述】:
数据包格式来源:http://wiki.vg/Protocol
我正在尝试用 php 编写一个程序,它将数据包发送到我托管的 minecraft 服务器。这可能适用于不支持相同 API 格式的手机的多人游戏实现。我下面的代码是我失败的尝试使这项工作。我怎样才能正确地做到这一点?服务器正在识别某些东西,但它要么没有发回任何东西,要么是什么东西。下面应该发送 0x00,即握手包以使用下一个状态 ID 请求服务器上的统计信息: 1. Minecraft 应该使用相同的 ID 进行响应,但使用服务器 motd 和玩家计数。对于 1.7.2,这将用于,它还将发送一个 server-icon.png。但我可以放心地忽略这些数据,因为它只是直接连接。
我做错了什么,我该如何解决?
Main.php
require("socket.php");
$f = getStat("zontreck.dyndns.biz",25565);
/*$za = 0x00;
$za[0] = 74;
$za[1] = "zontreck.dyndns.biz";
$za[2] = 25565;
$za[3] = 1;
*/
$za = array(0x00,"Protocol Version"=>73,
"Server Address"=>"zontreck.dyndns.biz",
"Server Port"=>25565,
"Next State"=>1);
$dd = doWrite(pack("a",$za),$f);
echo("Response from doWrite: " .$dd."\n");
echo("Sending: " . pack("a",$za)."\n");
/*if(doWrite(pack("a",$za),$f))
{
echo(fgets($f));
} else {
echo(fgets($f));
}*/
$ff = fgets($f);
//$u = unpack("a",$ff);
fclose($f);
echo("Data from server: " . $ff."\n");
echo("Data from server length: " . strlen($ff)."\n");
//fclose($f);
?>
socket.php
<?
function getStat($url = "",$port=25565)
{
$f = fsockopen($url,$port);
return $f;
}
function doWrite($packet,$socket)
{
return fwrite($socket,$packet);
}
?>
main.php 的输出
root@zontreck:/var/www/slmc# php main.php
PHP Notice: Array to string conversion in /var/www/slmc/main.php on line 16
Response from doWrite: 1
PHP Notice: Array to string conversion in /var/www/slmc/main.php on line 18
Sending: A
Data from server:
Data from server length: 0
root@zontreck:/var/www/slmc#
【问题讨论】:
-
Pack 需要一个 STRING,而您正在推入一个数组。你不能这样做。由于您在字符串上下文中使用数组,因此您正在打包文字词
Array。由于您的包格式只是a,因此您正在打包传入字符串的单个字符。您希望a*接受无限数量的数据字符 -
好吧,那我应该用什么来代替数组呢?我把“a”改成了“a*”。
-
阅读协议文档会有所帮助:wiki.vg/Pocket_Minecraft_Protocol#Types 您需要准确地构建命令/握手数据包,而不仅仅是将一些数据放入数组中并希望一切正常。
标签: php sockets network-protocols minecraft packets