рукопожатие с сервером Minecraft Bukkit — не удалось отправить поле хоста сервера

Я пытаюсь сделать клиент / бот для сервера Minecraft для автоматической защиты чата и запрета спамеров. (первое достижение)
Я нашел несколько документов здесь, и я реализовал типы данных отсюда (так они выглядят так — и я еще не закончил). Сейчас я пытаюсь отправить в интим 0x02 пакет, который должен выглядеть так:

Мой формат пакета

size    value                comment

1       0x02                 Packet ID
2+?     string               Username (I send "jakub")
2+?     another string       Server host name - here, the program FAILS*
4       25565                Port number

* Fails означает, что сервер bukkit выводит следующее в консоли, а сокет закрыт:

11:09:45 [INFO] /127.0.0.1:51256 потерянное соединение

Теперь я вижу способ, как проверить правильность моих типов данных, но поскольку я, кажется, отправляю имя пользователя без проблем, я думаю, что я отправляю неверная информация, хотя в правильный формат.

Генерация строки

Но в любом случае мне любопытно, все ли я сделал правильно. У меня есть класс для mc_short а также mc_string, Вот как mc_short создает 2 байта самого себя:

//mc_short::val is type of short
void mc_short::asBytes(char* data) {
for (int i = 0; i < 2; i++)
data[endianity?i:1-i] = (val >> (i * 8));  //Some magic with byteshifting.
//endianity is set to false, because java uses BigEndian everywhere** (UNFRIENDLY PERSONS!!)
}

**Ссылаться на http://wiki.vg/Data_Types:

Все типы в Java (и, как таковые, в Minecraft) имеют порядок с прямым порядком байтов, то есть самый старший байт идет первым.

Затем сама строка использует mc_short а также std::string заполнить байты char*,

void mc_string::asBytes(char* data) {
mc_short size((short)val.length());  //val is std::string
size.endianity = endianity;          //mc_string::endianity is boolean, and is ony used to determine endianity of the first 2 bytes
size.asBytes(data);  //Filling 2 bytes in data - length info
for(short i=0; i<size.value(); i++) {
data[i+2] = val[i];  //Copying std::string to data
}
}

Резюме вопроса

  1. Что я должен отправить как «имя хоста сервера», третье поле 0x02?
  2. Я правильно отправляю строку? Разве не требуется какое-либо другое преобразование?

Я знаю, что мой вопрос касается не очень известной темы, и поэтому вы можете не знать ни ответа, ни самой темы. Просто игнорируйте вопрос при таких обстоятельствах.

2

Решение

Строки кодируются в формате Юникод с прямым порядком байтов (UTF-16, но с прямым порядком байтов). Вы не можете отобразить свои символы непосредственно из памяти, если вы не используете Java (ну, вы можете обмануть, если просто напишите ноль между каждым символом и примете, что это дерьмовый способ сделать это). В C # есть пример кодирования строк Minecraft Вот.

Что касается содержимого этой строки, это должно быть имя хоста для подключения. Если Google запускает сервер Minecraft, эта строка может быть minecraft.google.com,

Пример работы с этим фактическим пакетом Вот.

Итак, на ваш вопрос на самом деле ответили несколько советов. Протокол Minecraft ужасен, и написание клиента займет много работы. Вы должны быть в состоянии поддерживать все пакеты в протоколе (да, все они), и вам нужно реализовать базовую физику, чтобы упасть на землю, чтобы вас не пинали за полет. Есть несколько вариантов, от лучшего к худшему:

  • Используйте Bukkit и напишите плагин для этого
  • Написать прокси вместо клиента
  • Напишите клиент, как вы пытаетесь сейчас

Итак, если вы сделаете первое, вам нужно написать плагин на Java. Я не знаю много об этом.

Я много знаю о последних двух вариантах. Я поддерживаю Craft.Net, это набор библиотек, в том числе универсальная сетевая библиотека и клиентская библиотека. Вы можете собрать клиента или прокси через несколько часов. Пример клиента находится в том же репо, и есть прокси Вот. Все они используют C #.

Если ты все еще хочешь полностью бросить свою собственную, удачи и счастливого пути.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]