Перехват ванильных пакетов

Версия Minecraft
1.6.4
355
2
17
Доброго времени суток!

Собственно перехват ванильных пакетов и интересует. А если подробнее, как можно начать перехватывать все пакеты поступающие со стороны сервера и наоборот? Методом форжа желательно, но подойдут любые варианты. Хочется взглянуть на частоту отправки и в целом на общение между клиентом и сервером.

И еще один вопрос из ряда этой же темы, как можно отправить пакет Плагин>Клиент, при подключении клиента, таким образом чтобы он 100% не потерялся?
При PlayerJoinEvent насколько я знаю ставится небольшая задержка в 0.5-1.0 сек при отправке, иначе пакет просто будет утерян, но клиент может грузится как и за 0.1 сек на сервер, так и все 5.0сек висеть. А делать какие-либо пинг-понги такое себе занятие.
 

tox1cozZ

aka Agravaine
8,456
598
2,893
1. Обработка всех пакетов происходит в NetworkManager#processReceivedPackets. Метод для клиентских пакетов вызывается в Minecraft#runTick, для серверных - сначала идет предварительная обработка(если соединение с игроком закрылось - удаляем его) в NetworkSystem#networkTick, а вызывается уже этот метод в MinecraftServer#updateTimeLightAndEntities.
Собственно, хукайся туда и делай чего надобно)
2. С плагинами не работал вообще, но там вроде есть шуделеры, можно ими задержку сделать. Но хз.
 
355
2
17
2. С плагинами не работал вообще, но там вроде есть шуделеры, можно ими задержку сделать. Но хз.
Ну там да, делается задержка в секунду. Но дело в опять же в том, что задержка у всех разная, у клиента может вообще повиснуть JVM и он будет подключаться секунд 10, соответственно потеряет все пакеты которые должен был получить при подключении.

Насчет первого пункта благодарю, попробую.
 
1,111
47
420
При подключении(т.е. авторизации) пакеты с клиента обрабатывает NetHandlerLoginServer а после того как авторизация прошла успешно в дело вступает NetHandlerPlayServer. Соответственно если тебе нужно отправить пакет в момент авторизации, то нужно регистрировать пакет где то в net.minecraft.network.EnumConnectionState на обеих сторонах и как то извращаться со статусом авторизации(net.minecraft.server.network.NetHandlerLoginServer.LoginState). Если же ты хочешь отправить пакет сразу после авторизации, то достаточно хукнутся в конструктор NetHandlerPlayServer. Там уже никаких состояний нет и можно просто брать и посылать пакеты.
 
1,111
47
420
Обработка всех пакетов происходит в NetworkManager#processReceivedPackets
Это, кстати, не совсем правда. У Packet есть метод hasPriority. Если он вернет true, пакет будет обработан в момент получения без добавления в очередь. Имеет смысл хукаться в метод net.minecraft.network.NetworkManager#channelRead0. Главное не забывать что он выполняется вне главного потока.
 
1,111
47
420
Без б
Смотри в net.minecraft.network.NetworkManager#field_152462_h.
Если не хватит можешь хукнутся в net.minecraft.util.MessageSerializer#encode. Например ты можешь хукнуться в конец метода и записать позицию вритера ByteBuf'a. Это и будет кол-во отправляемых байт. Есть еще препендер который добавляет инт фрэймы, можешь к каждому пакету добавлять 4 байта сверху.
Чтобы узнать сколько клиент получает, можно хукнутся в net.minecraft.util.MessageDeserializer#decode. Сколько лежит в ByteBuf'е, столько и пришло. Ну еще 4 байта сверху.
 
Сверху