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# 
Author: Tyler, 2013-12-30

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

Он также использует сокеты, поэтому вы всегда можете взять часть кода и изменить его в соответствии с вашими потребностями, но я настоятельно рекомендую вам просто использовать библиотеку как есть, потому что он делает то, чего вы пытаетесь достичь.

 1
Author: tkon99, 2014-07-19 13:40:52

Оба комментатора правы, вам нужно пересмотреть, как вы это делаете.

Более конкретно, протокол 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 на самом деле не предназначен для этого, поэтому примеров не так много.

 0
Author: ckm, 2014-07-15 23:52:05