PDA

Просмотр полной версии : Альтернативный парсер пакетов


NLObP
21.09.2011, 00:12
Неспешно делается парсер пакетов в пакетхаке на основе java исходников серверов. Есть определенные успехи.
Как известно из java исходников можно сделать расшифровку пакетов для packets.ini. Дело муторное, не все возможности предусмотрены. Захотелось сделать, что то типа такого, чтобы кинул эти исходники с минимальными исправлениями в папку settings и пакетхак мог сам их просматривая показывать содержимое пакета.

Так выглядит исходник пакета SM_SKILL_LIST для Aion.

protected void writeImpl(AionConnection con, ByteBuffer buf)
{
final int size = skillList.length;
writeH(buf, size); //skills list size
for (SkillListEntry entry : size)
{
writeH(buf, entry.getSkillId());
writeH(buf, entry.getSkillLevel());
writeC(buf, 0x00);
writeC(buf, entry.getExtraLvl());
writeD(buf, 0); //use time? [s]
writeC(buf, entry.isStigma() ? 1 : 0); // stigma flag
}
writeD(buf, messageId);
if (messageId != 0) ;
{
writeH(buf, 0x24);
writeD(buf, skillNameId);
writeH(buf, 0x00);
writeS(buf, skillLvl);
}
}


Во вложении картинка как выглядит пакет в пакетхаке.

Планируется исходники пакетов хранить так:


settings
packets.ini
aion21
clientpackets
CM_ABYSS_RANKING_LEGIONS.java
CM_ABYSS_RANKING_PLAYERS.java
...
serverpackets
SM_ABNORMAL_EFFECT.java
SM_ABNORMAL_STATE.java
...
aion25
clientpackets
serverpackets
gracia
clientpackets
Action.java
AddTradeItem.java
...
serverpackets
AbnormalStatusUpdate.java
AcquireSkillDone.java
...
и т.д.

Имеются и плюсы и минусы.
Из плюсов: легко модифицировать пакет.
Из минусов: неспешность вывода показа пакета, особенно заметно если исходник имеет большой размер.

Осталось найти приличные исходники java сервера Aion и LineageII и подготовить пакеты.
В принципе за день я смог в черновом варианте обработать клиентские пакеты Aion 2.1, так что это может занять не так много времени.

PS: код до конца еще не дописан.
PPS: просьба накидать мне логов пакетов для Aion 2.1 и 2.5, чтобы можно было тестировать правильность разбора пакетов.

PPPS: тестовый вариант я выложу на FTP (http://l2ph.coderx.ru/arhive/) (Внимание! При ошибках в описании пакета намертво виснет пакетхак!).

warlock9000
21.09.2011, 23:19
Тестировал на 2.5 (http://aion.atomixro.com/) пакеты бредовые показывает, совсем не соответствующие действительности. *.166 версия л2пх показывает нормальные пакеты. И еще вопрос не в тему (сорри), gamezaion.com работает на 2.6 евроклиенте пакеты вообще непонятно что показывают... кодировка поменялась чтоль в 2.6?

supernewbie
22.09.2011, 09:19
не легче ли переводить в нормальный формат?

NLObP
22.09.2011, 21:36
warlock9000, дай мне в лс лог пакетов для тестирования.

warlock9000
28.09.2011, 18:39
Хоть бы отписал, как идет процесс доводки:)

NLObP
30.09.2011, 12:08
Кратко, как работает.
В папке \settings находится packetsAionXX.ini из которого по коду пакета выбирается имя пакета, например для серверного пакета 00 находим имя пакета SM_STATUPDATE_HP

[server]
00=SM_STATUPDATE_HP
...

Сами пакеты лежат в папке \settings\packets.ini\aionXX или для LineageII лежат в папке \settings\packets.ini\gracia и т.д по названию хроник соответственно в папках clientpackets и serverpackets

\settings
|packetsAion21.ini
|packetsGracia.ini
+-\packets.ini
+aion21
|clientpackets
|serverpackets
+gracia
|clientpackets
|serverpackets
...

Описание для клиентских пакетов ищется в секции readImpl()
protected void readImpl()
{
...
}

Описание для серверных пакетов ищется в секции writeImpl()
protected void writeImpl()
{
...
}


Фигурные скобки {} должны быть на отдельной строке!

Обрабатываются конструкции:
Чтение из пакета c=1 байт, h=2 байта, d=4 байта, s=string, f=8 байт, n=4 байта, b=блок в N байт:

writeD(buf, effectedId); //имя поля будет effectedId
или
raceId = readC(); //имя поля будет raceId

writeB(buf, new byte[18]); //будет пропущено 18 байт

Цикл:

writeH(buf, size); //// цикл по переменной size
for (size)
{
...
}

или

amount = readH(); // цикл по переменной amount
for (int i = 0; i < amount; i++)
{
...
}

Условия:

raceId = readC();
switch (raceId)
{
case 0:
...
break;
case 1:
...
break;
default:
...
break;
}


или


if (type == 2) // возможные варианты (>|>=|<|<=|!|!=|==)
{
...
}
else
{
...
}

или

if (type) // возможные варианты (>|>=|<|<=|!|!=|==)
{
...
}



Поддерживаются подпрограммы (SM_INVENTORY_UPDATE.java):

protected void writeGeneralInfo()
{
...
}

protected void writeImpl(AionConnection con, ByteBuffer buf)
{
...
writeH(buf, size); // number of entries
for (size)
{
writeGeneralInfo(buf, item);
...
}
}


Присвоение:

Size = 8;
//size будет равно 8

или
Size = 8;
Len=Size
//Len будет равно 8

или
int size = 134 - (history.getName().length() * 2 + 2);
//size будет равно вычислению 134 - длина строки getName *2+2

Комментарии в тексте пропускаются

writeC(buf, chatType); // type

или

/*
* 0 : all 1 : elyos 2 : asmodians
*/
writeD(buf, senderObjectId); // sender object id

NLObP
30.09.2011, 12:38
Для подготовки packetsAionXX.ini по данным из файлов AionPacketHandlerFactory.java и ServerPacketsOpcodes.java сделана маленькая утилита makeOpcodesAion.
Обновил до версии 0.2

xkor
30.09.2011, 12:47
NLObP, и всё таки мне кажется что оптимальнее было бы делать не в пакетхаке возможность использовать сорци явы, а просто конвертер сорцев в packets.ini

NLObP
30.09.2011, 12:51
NLObP, и всё таки мне кажется что оптимальнее было бы делать не в пакетхаке возможность использовать сорци явы, а просто конвертер сорцев в packets.ini

Я не настаиваю. Могу исходники отдельно выложить.
В packets.ini плохо проработана работа с пакетами. Да и саму её трудно делать. И для понимания одна длинная строка хуже чем нормальный листинг программы.

PS: причем совместимость со старыми packets.ini не потеряна. Новый парсер включается галочкой в настройках.

xkor
30.09.2011, 23:59
Я не настаиваю. Могу исходники отдельно выложить.
а я не протестую против твоей фичи, просто выражаю мнение, ничего против её наличия не имею)
ЗЫ в новом пакетхаке (если всётfки допишу когданить что то внятное) у меня наборот будет просто: разбираться пакеты будут скриптом, но скрипт сможет генерироваться из формата похожего на текущий packets.ini

NLObP
19.12.2011, 23:50
Набор утилит для работы с пакетами.

dec2hex - для преобразования ID из DEC в HEX в файле packetsX.ini

makeLineagePackets - выбрасывает из *.java файлов всё за исключением процедур readImpl() и writeImpl(), имена пакетов берем из packets.ini. Сами java файлы исходников пакетов должны лежать в папках script\clientpackets и script\serverpackets.

makeLineageServerPackets - готовим серверные опкоды из *.java серверных пакетов для LineageII.
1. Выполняем в папке serverpackets команду DIR > server.ini
2. Удаляем в полученом текстовом файле server.ini всё кроме имен пакетов
3. Указываем в поле ввода имя файла, если оно отличается от server.ini
4. жмём MAKE и ждём...
5. результат в файле server.ini~
6. отсортировать имена пакетов по их ID можно по команде SORT server.ini~ /O server.ini~~, в файле server.ini~~ будет результат сортировки.

NLObP
25.12.2011, 05:20
Набор утилит для работы с пакетами.

MakePacketsIni v0.2 - для подготовки packetsX.ini из *.java файлов.
[+] обновил до версии 0.3

описание пакета берем из процедур readImpl() и writeImpl(), имена пакетов берем из packets.ini. Сами java файлы исходников пакетов должны лежать в папках script\clientpackets и script\serverpackets.

PS: допиливать packets.ini руками обязательно!

Давайте разберем как допиливать packets.ini, на примере пакета CM_CASTSPELL
Исходник
protected void readImpl() {
spellid = readH();
level = readC();
targetType = readC();
switch (targetType) {
case 0:
targetObjectId = readD();
break;
case 1:
x = readF();
y = readF();
z = readF();
break;
default:
break;
}
time = readH();
}


Кусочек
spellid = readH();
это будет
h(spellid)

Кусочек
level = readC();
это будет
c(level)

Кусочек
targetType = readC();
switch (targetType) {

это будет
c(targetType:switch.0.2)
где первый параметр после switch это элемент_с_которого_начинать, т.е. 0 - начать с первого
второй параметр после switch это сколько_элементов_входит, т.е. 2 - подсчитываем сколько case входит в этот switch (default не учитывать)

Кусочек
l case 0:
targetObjectId = readD();
break;

это будет
_(id:case.0.1)d(targetOID)
где _(подчерк) просто так должно быть, id просто так должно быть,
первый параметр после case это с чем идет сравнение, в нашем случае с цифрой 0 (ноль)
второй параметр после case это количество_элементов_в_блоке, в нашем случае 1 (один)

Кусочек
l case 1:
x = readF();
y = readF();
z = readF();
break;

это будет
_(id:case.1.3)n(x)n(y)n(z)
где _(подчерк) просто так должно быть, id просто так должно быть,
первый параметр после case это с чем идет сравнение, в нашем случае с цифрой 1 (один)
второй параметр после case это количество_элементов_в_блоке, в нашем случае 3 (три)

и в конце
Кусочек
time = readH();
это будет
h(time)

В итоге получаем строку
0090=CM_CASTSPELL:c(static)h(id2)h(spellID)c(level )c(targetType:switch.0.2)_(id:case.0.1)d(targetOID )_(id:case.1.3)n(x)n(y)n(z)h(time)

Конструкция FOR по аналогии (можно глянуть описание в packetsGracia.ini). Конструкцию IF надо преобразовать в конструкцию switch, так как IF в пакетхаке не поддерживается.

PS: надеюсь понятно объяснил.

NLObP
04.01.2012, 00:56
Еще один пример:
00A3=CM_MOVE:c(static)h(id2)n(x)n(y)n(z)c(heading) c(movementType:switch.0.6)_(id:case.224.3)n(x2)n(y 2)n(z2)_(id:case.192.3)n(x2)n(y2)n(z2)_(id:case.19 6.3)n(x2)n(y2)n(z2)_(id:case.228.3)n(x2)n(y2)n(z2) _(id:case.132.1)c(glideFlag)_(id:case.164.1)c(glid eFlag)


Исходный код
protected void readImpl() {
Player player = getConnection().getActivePlayer();
if (!player.isSpawned())
return;
x = readF();
y = readF();
z = readF();
heading = (byte) readC();
movementType = (byte) readC();
type = MovementType.getMovementTypeById(movementType);
switch (type) {
case MOVEMENT_START_MOUSE:
case MOVEMENT_START_KEYBOARD:
x2 = readF();
y2 = readF();
z2 = readF();
break;
case MOVEMENT_GLIDE_DOWN:
case MOVEMENT_GLIDE_START_MOUSE:
x2 = readF();
y2 = readF();
z2 = readF();
// no break
case MOVEMENT_GLIDE_UP:
case VALIDATE_GLIDE_MOUSE:
glideFlag = (byte) readC();
break;
default:
break;
}
}


public enum MovementType {
MOVEMENT_START_MOUSE(-32),
MOVEMENT_START_KEYBOARD(-64),
VALIDATE_MOUSE(-96),
VALIDATE_KEYBOARD(-128),
VALIDATE_JUMP(8),
VALIDATE_JUMP_WHILE_MOVING(72),
MOVEMENT_GLIDE_UP(-124),
MOVEMENT_GLIDE_DOWN(-60),
MOVEMENT_GLIDE_START_MOUSE(-28),
VALIDATE_GLIDE_MOUSE(-92),
MOVEMENT_STOP(0),

MOVEMENT_STAYIN_ELEVATOR(24),
MOVEMENT_JUMPIN_ELEVATOR(-48), //sometimes not jump
MOVEMENT_VALIDATEIN_ELEVATOR(-112), //unk
MOVEMENT_MOVIN_ELEVATOR(-16),
MOVEMENT_ON_ELEVATOR(16),
MOVEMENT_GO_UPDOWN_ELEVATOR(-80),

UNKNOWN(1);
}

Silent
11.01.2012, 11:31
В пакете UserInfo на серверах NCWest перепутаны местами curHP/curMP, если нужно вечером могу выложить распарсенный пакет Вашей версией программы.

NLObP
12.01.2012, 01:55
Закоммитил на SVN, чтобы не пропала зря работа.
Revision: 267
Author: nlobp
Date: 12 января 2012 г. 0:49:11
Message:
[+] альтернативный парсер пакетов по исходникам java-сервера
----
Added : /3.5.x/Build/settings/packets.ini
Added : /3.5.x/Build/settings/packets.ini/aion21
Added : /3.5.x/Build/settings/packets.ini/aion21/clientpackets
Added : /3.5.x/Build/settings/packets.ini/aion21/serverpackets
Added : /3.5.x/Build/settings/packets.ini/aion27
Added : /3.5.x/Build/settings/packets.ini/aion27/clientpackets
Added : /3.5.x/Build/settings/packets.ini/aion27/serverpackets
Added : /3.5.x/Build/settings/packets.ini/c4
Added : /3.5.x/Build/settings/packets.ini/freya
Added : /3.5.x/Build/settings/packets.ini/god
Added : /3.5.x/Build/settings/packets.ini/god/clientpackets
Added : /3.5.x/Build/settings/packets.ini/god/serverpackets
Added : /3.5.x/Build/settings/packets.ini/gracia
Added : /3.5.x/Build/settings/packets.ini/gracia/clientpackets
Added : /3.5.x/Build/settings/packets.ini/gracia/serverpackets
Added : /3.5.x/Build/settings/packets.ini/graciaepilogue
Added : /3.5.x/Build/settings/packets.ini/graciafinal
Added : /3.5.x/Build/settings/packets.ini/highfive
Added : /3.5.x/Build/settings/packets.ini/highfive/clientpackets
Added : /3.5.x/Build/settings/packets.ini/highfive/serverpackets
Added : /3.5.x/Build/settings/packets.ini/interlude
Modified : /3.5.x/Build/settings/packetsAion27.ini
Modified : /3.5.x/l2ph.cfg
Modified : /3.5.x/l2ph.dpr
Added : /3.5.x/l2ph.dproj
Modified : /3.5.x/l2ph.res
Modified : /3.5.x/units/uAboutDialog.dfm
Modified : /3.5.x/units/uData.pas
Added : /3.5.x/units/uJavaParser.pas
Modified : /3.5.x/units/uMain.dfm
Modified : /3.5.x/units/uMainReplacer.dfm
Modified : /3.5.x/units/uPacketView.dfm
Modified : /3.5.x/units/uPacketView.pas
Modified : /3.5.x/units/uPacketViewer.dfm
Modified : /3.5.x/units/uProcessRawLog.dfm
Modified : /3.5.x/units/uScripts.dfm
Modified : /3.5.x/units/uScripts.pas
Modified : /3.5.x/units/uSettingsDialog.dfm
Modified : /3.5.x/units/uSettingsDialog.pas
Modified : /3.5.x/units/uVisualContainer.dfm
Modified : /3.5.x/units/uVisualContainer.pas
Modified : /3.5.x/units/uglobalfuncs.pas
Modified : /3.5.x/units/usharedstructs.pas



PS: простые пакеты показывает без какой либо модификации *.java файлов.
PPS: пилю дальше, по мере времени.

NLObP
12.01.2012, 02:02
Залил скрин и заметил, что заслонил настройку - "обрабатывать пакеты"

Caesarbogdan
28.04.2015, 19:18
не могу настроить и понять как работает эта програма можете помоч?