PHP-пакеты на сервер minecraft?
Источник формата пакета: http://wiki.vg/Protocol
Я пытаюсь написать программу на php, которая будет отправлять пакеты на сервер minecraft, который я размещаю. Скорее всего, это будет для многопользовательской реализации для телефонов, которые не поддерживают одни и те же форматы API. Приведенный ниже код - это моя неудачная попытка заставить это работать. Как я могу сделать это правильно? Сервер что-то распознает, но либо ничего не отправляет обратно, либо что-то еще. Это ниже должно отправьте 0x00, пакет подтверждения, чтобы запросить статистику на сервере, используя следующий идентификатор состояния: 1. Minecraft должен отвечать тем же идентификатором, но с идентификатором сервера motd и количеством игроков. Для 1.7.2, для которого это будет, он также отправит значок сервера.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#
2 answers
Вы, вероятно, захотите взглянуть на это: https://forums.bukkit.org/threads/web-php-simple-to-use-minecraft-server-status-query.144329/
В основном это некоторое объяснение этой библиотеки, которая делает именно то, что вы хотите: https://github.com/FunnyItsElmo/PHP-Minecraft-Server-Status-Query
Он также использует сокеты, поэтому вы всегда можете взять часть кода и изменить его в соответствии с вашими потребностями, но я настоятельно рекомендую вам просто использовать библиотеку как есть, потому что он делает то, чего вы пытаетесь достичь.
Оба комментатора правы, вам нужно пересмотреть, как вы это делаете.
Более конкретно, протокол Minecraft использует UDP, что означает, что вам необходимо иметь доступ к необработанному сокету с помощью socket_create
- http://php.net/manual/en/function.socket-create.php
Затем вам нужно создать string
, который правильно содержит все необходимые пакеты, как описано в @Marc B. Затем вы можете записать эту строку в сокет. Обратите внимание, что, поскольку UDP является как без гражданства, так и не имеет исправления ошибок, вам также придется написать процедуры повторных попыток, если вы получите ошибку обратно.
В настоящее время вы создаете структуры данных на одном языке (PHP), а затем пытаетесь записать их в проводной протокол (совершенно другой), что практически невозможно.
Это, безусловно, возможно сделать в PHP, но вам придется работать на гораздо более низком уровне, чем сейчас, с необработанными сокетами, шестнадцатеричными строками данных и обработкой сетевых ошибок. Я бы посоветовал вам взглянуть на другие библиотеки PHP, которые обрабатывают данные UDP, чтобы узнать, есть ли какой-то код, который вы можете использовать повторно.
В комментариях к странице socket_create
есть некоторый код, который вы могли бы использовать/изучить. В частности, есть пример TFTP, который вы, возможно, сможете изменить.
Не простой ответ, но это нетривиально сделать на любом языке, и PHP на самом деле не предназначен для этого, поэтому примеров не так много.