PDA

Просмотр полной версии : [разработка]Wow Packet Parser


alien
11.07.2010, 21:43
Вот решил заняться разработкой утилитки для парсинга снифов.
Видел что существуют такие и даже какое то время пользовался WoWPacketViewer(я его тут выкладывал недавно)
Но все что я видел оно довольно неудобно.
И вот взялся за написание.
Пока проект в стадии активного написания. Во вложение набросок интерфейса(там где список пакетов планируется таблица в которой будет номер пакета, а также разный цвет фона в зависимости от направления)

Основная фишка парсера в том чтобы добавить поддержку разбора нового пакета не нужно перекомпилировать полностью приложение. Разбор осуществляет Скрипт на Lua
Вот пример скрипта разбора CMSG_AUTH_SESSION
ClientBuild=Packet:ReadInt32()
unk=Packet:ReadInt32()
acc=Packet:ReadString()
function GetClientBuild()
return "Client: "..ClientBuild.."\n";
end

function Tmpe()
Packet:DeCompress();
local addon_count=Packet:ReadInt32();
local addonTable={};
for i=1,addon_count do
local addonName = Packet:ReadString();
local enabled = Packet:ReadByte();
local crc = Packet:ReadUInt32();
local unk4 = Packet:ReadUInt32();
table.insert(addonTable,{["name"]=addonName,["value"]={{["name"]="Enabled",value=enabled},{["name"]="Crc",value=crc},{["name"]="Unk4",value=unk4}}});
end
return {{["name"]="Addon Count",value=addon_count},{["name"]="Addons",value=addonTable}};
end

function GetTextResult()
return GetClientBuild().."unk0: "..unk.."\nAccount: "..acc;
end

testtableret={
{["name"]="Client",value=ClientBuild},
{["name"]="Unk",value=unk},
{["name"]="Account",value=acc},
{["name"]="Unk2",value=Packet:ReadInt32()},
{["name"]="Client Seed",value=Packet:ReadInt32()},
{["name"]="Unk3",value=Packet:ReadInt64()},
{["name"]="Digest",value=Packet:HexPrint(Packet:ReadBytes(20))},
{["name"]="Decompressed",value=Tmpe()},
{["name"]="Unk5",value=Packet:ReadUInt32()},

}
Да скрипт пока выглядит не очень эстетично но это еще из-за того что не решил еще полностью как лучше будет сделать.
В общем проект лично для меня носит обучающий характер. В написании используется Qt+luabind
Если есть желающие присоединится милости прошу(скорее всего как только будет что не стыдно показать в качестве сорцов проект будет опенсорс)

RomanRom2
11.07.2010, 22:41
насколько я понял речь идет именно о pktViewer? парсер обычно парсит инфу и куда то ее складывает.

да, давно пора. я тоже хотел сделать код, который бы не нужно было перекомпилять, что бы добавить новый опкод. какой нибудь описатель делать и подкладывать его в каталог. не придумал как сделать такое:

pkt.AddLong(itAttributesCount);
for i:=1 to itAttributesCount do
begin
pkt.AddLong(ItemTPL[item_id].itAttributes[i].ItemStatType);
pkt.AddLong(ItemTPL[item_id].itAttributes[i].ItemStatValue);
end;

я скрипты не люблю, пытаюсь их максимально исключить. и придумать что то вроде на манер:

SpellCastTimes.ini
[TYPE]
0=index
[FIELD]
0=id
1=casting_time_1
2=step
3=casting_time_2

alien
11.07.2010, 23:20
Да наверно парсер неправильное слово в данном контексте )
Но WoWPacketViewer уже есть ) можно конечно назвать что-то типа wpView ))
Ладно название программы не самое важное.
А насчет скриптов. Да было бы хорошо обойтись без скриптов. Но тут скорее всего не получится(вовсяком случае простым способом, придется жестко извращаться)

RomanRom2
11.07.2010, 23:27
название не самое главное, да. но... как корабль назовешь, так он и поплывет :)
мой так называется - zPktViewer (http://wowcore.ru/images/zPktViewer.png). буковка z - ну так уж вышло, сортировка что бы в конец списка выводила :)

Konctantin
11.07.2010, 23:59
Не знаю как в делфи, но в С# есть такая штука как CodeDomProvider (http://msdn.microsoft.com/ru-ru/library/system.codedom.compiler.codedomprovider.aspx)
то есть получается на лету можно вставлять программный код и сразу его выполнять.

ЗЫ. Можно хранить отдельные парсеры для разных опкодов, а когда нужно, просто загружать.
как при старте программы, так и при работе.

или же есть CSharpCodeProvider (http://msdn.microsoft.com/ru-ru/library/microsoft.csharp.csharpcodeprovider.aspx), то же самое, только более специфическое.

RomanRom2
12.07.2010, 00:12
это фишка исключительно C#, в дельфи такого нет, к сожалению.
в дельфи либо внешние скриптовые движки либо думать, как сделать инишник. засада там только одна - счетчики данных.

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

alien
12.07.2010, 00:33
не знаю только, можно ли сделать так, что бы плагины можно было писать на разных языках, что бы они потом работали на дельфевом приложении.
Можно.
Только зачем тогда проще подключить внешний скриптовый двиг который все и будет делать.
ЗЫ. Можно хранить отдельные парсеры для разных опкодов, а когда нужно, просто загружать.
как при старте программы, так и при работе.
У меня например так и есть для каждого пакета свой файл.
Скрипт выполняется когда выбираешь пакет в списке.

Йоха
12.07.2010, 08:13
а что данные содержашиеся в пакетах настолько нетривиальны что требуют обработки скриптом ? Недостаточно задать описание структуры данных, и обрабатывать их в движке, а не писать скрипт для каждого опкода

RomanRom2
12.07.2010, 09:26
они тривиальны до тех пор, пока нет счетчиков

field_count;
{
field_count_val1,
field_count_val2,
...
field_count_val(count)
}

как описать это?

LordJZ
12.07.2010, 10:06
они тривиальны до тех пор, пока нет счетчиков

field_count;
{
field_count_val1,
field_count_val2,
...
field_count_val(count)
}

как описать это?В WCell — через xml...

RomanRom2
12.07.2010, 10:31
получается так или иначе городить какой то "умный" парсер. формат на самом деле значения не имеет, что xml, что какой то свой формат...

alien
12.07.2010, 11:55
Да и вот еще не только счетчики могут быть.
От значения определенного поля размер и формат пакета тоже может меняться.

Konctantin
12.07.2010, 12:18
С помощью структуры можно разбирать только примитивные пакеты с прямолинейной структурой, без сложных зависимостей, а так надо прибегать к скриптам.

Или же разделить как-то, простые пакеты обрабатывать по структуре, а сложные скриптом.

Konctantin
16.08.2010, 06:16
Тема еще актуальна?

Fmut
18.08.2010, 15:53
Вот держите, Наш вариант lua парсера :)
--[[ описание комманды CMSG_CHAR_ENUM и обслуживающая функция ]]--

local CEnumCode, nCEnumCode = 55, 'CMSG_CHAR_ENUM'
local CEnumVers = 'Версия клиента: 3.3.5 [12340], Дата изменения: 07.07.2010'

CMSG_CHAR_ENUM = function (dBuf, lBuf, index)
AddCodeNameMem (index, CEnumCode, nCEnumCode, lBuf)
AddMem2(CEnumVers)
end

--[[ описание комманды SMSG_CHAR_ENUM и обслуживающая функция ]]--

local SEnumCode, nSEnumCode = 59, 'SMSG_CHAR_ENUM'
local SEnumVers = 'Версия клиента: 3.3.5 [12340], Дата изменения: 08.07.2010'

SMSG_CHAR_ENUM = function (dBuf, lBuf, index)
AddCodeNameMem (index, SEnumCode, nSEnumCode, lBuf)
AddMem2(SEnumVers)
AddMem2('')
local CharCount, Iter, Val = 0, 4, 0
CharCount, Iter = ReadByte(dBuf, Iter)
AddMem2('Characters count (byte) = '..CharCount..' ($'..ByteToHexStr(CharCount)..')')
local i, j = 0, 0
while i < CharCount do
AddMem2('')
AddMem2('-------------------- Char '..i..' --------------------')
Val, Iter = ReadInt64Hex(dBuf, Iter)
AddMem2('CharGUID (int64) = $'..Val)
Val, Iter = ReadString(dBuf, Iter)
AddMem2('Name (str) = '..Val)
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Race (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Class (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Gender (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Skin (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Face (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('HairStyle (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('HairColour (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('FacialHair (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Level (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('ZoneId (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('MapId (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadFloat(dBuf, Iter)
AddMem2('PosX (float) = '..Val)
Val, Iter = ReadFloat(dBuf, Iter)
AddMem2('PosY (float) = '..Val)
Val, Iter = ReadFloat(dBuf, Iter)
AddMem2('PosZ (float) = '..Val)
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('GuildId (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('EnumFlag (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('Unk_Wotlk (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2('Rested (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('PetInfoId (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('PetLevel (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2('PetFamilyId (int) = '..Val..' ($'..IntToHexStr(Val)..')')
for j = 0, 19, 1 do
AddMem2(' ============== Item '..j..' ==============')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2(' Model (int) = '..Val..' ($'..IntToHexStr(Val)..')')
Val, Iter = ReadByte(dBuf, Iter)
AddMem2(' InvType (byte) = '..Val..' ($'..ByteToHexStr(Val)..')')
Val, Iter = ReadInteger(dBuf, Iter)
AddMem2(' Unk (int) = '..Val..' ($'..IntToHexStr(Val)..')')
end
i = i + 1
end
end

--[[ регистрация функций в основной программе ]]--

Register_Code(CEnumCode, nCEnumCode)
Register_Code(SEnumCode, nSEnumCode)

Konctantin
18.08.2010, 16:11
а у нас есть 2 вида парсеров ХМЛ структуры и хард код, править структуры (ХМЛ парсер) можно не закрывая сам парсер, есть возможность перегрузки структур.

alien
20.08.2010, 18:48
да тема актуально. Просто я щас в таком месте где компа под рукой нету. как приеду буду дописывать.
Зы у меня тоже скрипты луашные тоже без перезапуска программы обновляются

ispanec
21.08.2010, 08:32
С помощью структуры можно разбирать только примитивные пакеты с прямолинейной структурой, без сложных зависимостей, а так надо прибегать к скриптам.

Или же разделить как-то, простые пакеты обрабатывать по структуре, а сложные скриптом.
"Работам техничкам ничо не знам" и сейчас может хрень спорю, но что мешает хранить всё в JSON (http://www.json.org/json-ru.html), а потом его "парсить" - есть готовые (де)сериализаторы.

Konctantin
21.08.2010, 08:52
а это кому как удобней...

RomanRom2
18.04.2011, 01:46
в общем повтыкал я в этот JSON...
все отлично, все замечательно просто, ровно до того места, когда нужно сделать зависимость от байта (или того интересней - от флага). или счетчики структур. короче не подходит. надо скриптовые движки использовать. ну или что то свое городить...

HuntsMan
20.04.2011, 16:36
Я обработчики пишу на шарпе без привлечения сторонних движков, и не жалуюсь :)

Йоха
20.04.2011, 16:45
Я обработчики пишу на шарпе без привлечения сторонних движков, и не жалуюсь :)

Это не очень удобно, структура постоянно меняется от билда к билду, и с каждым билдом надо пересобирать программу. Потом по мере разбора новых опокодов опять дописывать код и компилировать ...
А со скриптами гораздо проще, поправил текстовый файлик и вперед

Lordronn
20.04.2011, 16:49
Потом по мере разбора новых опокодов опять дописывать код и компилировать ...

Десериализация рулит

Йоха
20.04.2011, 16:59
эм... не совсем понятно
объясни что имеется в виду

Lordronn
20.04.2011, 19:18
Структура пакетов хранится в XML файле. При запуске программы файлы десериализуются. При выборе пакета создается ридер пакета, который читается по структуре из XML файла, которую мы уже занесли в List\Dictionary. реализовать можно довольно много:
switch
case
format (X4, X16...)
compare
Можно также указывать название enum - а

При необходимости легко можно сменить структуру без перезагрузки всего вайвера.

.:: Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 50 сообщение(ий)) ::.

Йоха
20.04.2011, 19:33
да епрст, ну об этом же и говорится, что формат пакетов задается внешними файлами.
там просто HuntsMan написал что у него обработчики захардкодены, вот это и неудобно

Lordronn
20.04.2011, 19:56
Я сейчас с этим мучаюсь. Написал около 100 обработчиков в коде. Теперь мучаюсь с их переносом в XML-ки

LordJZ
20.04.2011, 20:00
А у меня для обработки пакетов используется вот такой интерфейс:.:: Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 10 сообщение(ий)) ::.*PROUD*

zergtmn
20.04.2011, 21:03
обработчики захардкодены, вот это и неудобно
Зато удобно делать произвольную фильтрацию и собирать данные для внесения в базу.

Lordronn
20.04.2011, 21:18
Это да, это можно только через код. Но речь идет о мелких пакетах типа CMSG_QUEST_QUERY и о пакетах из который не получить информации для базы. У меня для пакетов(респонзы, вендор лист, и т.п) сделан специальный оутпут в скул. Достаточно нажать на одну кнопочку в меню и выбрать директорию. Для UPDATE_OBJECT у меня плагин написан

TOM_RUS
21.04.2011, 07:05
Поигрался седня ночью с сериализацией/десериализацией, очень удобная штука :)

http://paste2.org/p/1375139

Допустим есть пакет:

0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00


Если например он имеет структуру:

uint32
uint32
uint32


то XML для него получается что-то типа:

<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="CMSG_TEST_ACTION">
<Fields xsi:type="Simple" Name="Field1" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Field2" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Field3" DataType="UInt32"/>
</Fields>
</Definition>


если например структура:

uint32
uint32
switch(uint32)
{
case 3:
break;
}



<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="CMSG_TEST_ACTION">
<Fields xsi:type="Simple" Name="Field1" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Field2" DataType="UInt32"/>
<Fields xsi:type="Switch" Name="Switch1" DataType="UInt32">
<Fields xsi:type="Case" Name="Case2" DataType="UInt32" CaseValue="3"/>
</Fields>
</Definition>



for(uint32)
{
uint32
uint32
}



<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="CMSG_TEST_ACTION">
<Fields xsi:type="DynamicLoop" Name="Loop1" DataType="UInt32">
<Fields xsi:type="Simple" Name="LoopField1" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="LoopField2" DataType="UInt32"/>
</Fields>
</Definition>



for(1)
{
uint32
uint32
}



<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="CMSG_TEST_ACTION">
<Fields xsi:type="StaticLoop" Name="Loop1" DataType="UInt32" LoopLength="1">
<Fields xsi:type="Simple" Name="LoopField1" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="LoopField2" DataType="UInt32"/>
</Fields>
</Definition>



if(uint32 == 1)
{
uint32
uint32
}



<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="CMSG_TEST_ACTION">
<Fields xsi:type="Condition" Name="Condition1" DataType="UInt32" ConditionType="Equal" ConditionValue="1">
<Fields xsi:type="Simple" Name="ConditionField1" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="ConditionField2" DataType="UInt32"/>
</Fields>
</Definition>

HuntsMan
21.04.2011, 07:41
Это не очень удобно, структура постоянно меняется от билда к билду, и с каждым билдом надо пересобирать программу. Потом по мере разбора новых опокодов опять дописывать код и компилировать ...
А со скриптами гораздо проще, поправил текстовый файлик и вперед
Я в нем постоянно что-нибудь дописываю, поэтому запуск у меня по умолчанию идет в дебаге и из студии)

Опять же большую часть пакетов я стараюсь парсить и в sql. Например:
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '674', 'Бой двумя оружиями (674)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '6478', 'Открывание (6478)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '6603', 'Автоматическая атака (6603)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '45927', 'Призыв друга (45927)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '22027', 'Удаление знака отличия (22027)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '22810', 'Открытие - без текста (22810)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '2382', 'Стандартный (2382)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '3365', 'Открывание (3365)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '3050', 'Обнаружение (3050)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '9125', 'Стандартный (9125)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '21651', 'Открывание (21651)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '21652', 'Закрытие (21652)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '8386', 'Удар (8386)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '7266', 'Дуэль (7266)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '7267', 'Ползание (7267)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '7355', 'Застревание (7355)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '6233', 'Закрытие (6233)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '6246', 'Закрытие (6246)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '6247', 'Открывание (6247)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '6477', 'Открывание (6477)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '63645', 'Первый набор талантов (63645)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '63644', 'Второй набор талантов (63644)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '52665', 'Реликвия (52665)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '61437', 'Открывание (61437)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '68398', 'Открывание (68398)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '96220', 'Начальная фаза (96220)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '668', 'Всеобщий язык (668)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '202', 'Двуручные мечи (202)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '196', 'Одноручные топоры (196)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '197', 'Двуручные топоры (197)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '10846', 'Первая помощь (10846)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '3275', 'Льняные бинты (3275)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '18630', 'Плотные бинты из рунической ткани (18630)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '7934', 'Противоядие (7934)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '3276', 'Плотные льняные бинты (3276)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '3277', 'Шерстяные бинты (3277)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '3278', 'Плотные шерстяные бинты (3278)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '7928', 'Шелковые бинты (7928)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '7929', 'Плотные шелковые бинты (7929)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '10840', 'Бинты из магической ткани (10840)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '10841', 'Плотные бинты из магической ткани (10841)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '18629', 'Бинты из рунической ткани (18629)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '203', 'Рукопашный бой (203)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '750', 'Латы (750)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '8737', 'Кольчужные доспехи (8737)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '9077', 'Кожа (9077)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '200', 'Древковое оружие (200)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '199', 'Двуручное дробящее оружие (199)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '89964', 'Убрать символ (89964)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '45902', 'Кровавый удар (45902)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '49410', 'Силовое отражение (49410)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '82246', 'Парирование (82246)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '89832', 'Death Strike Enabler (89832)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '45477', 'Ледяное прикосновение (45477)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '48266', 'Власть льда (48266)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '59921', 'Озноб (59921)');
INSERT INTO `playercreateinfo_spell` (`race`,`class`,`Spell`,`Note`) VALUES ('@RACE', '@CLASS', '61455', 'Руническое средоточие (61455)');

ЗЫ: Лучше уж lua чем xml :)

TOM_RUS
21.04.2011, 08:50
ЗЫ: Лучше уж lua чем xml :)

И зачем этот геморой с lua, если даже встроенной поддержки lua в .NET Framework нет? С XML все прекрасно работает.

HuntsMan
21.04.2011, 09:58
И зачем этот геморой с lua, если даже встроенной поддержки lua в .NET Framework нет? С XML все прекрасно работает.
lua визуально понятнее :)

Konctantin
21.04.2011, 11:19
Ну если уж на то пошло, то проще тогда выполнять динамическую компиляцию, и писать все на С#, но не lua.

alien
21.04.2011, 18:41
Я думаю что если пишешь на шарпе то лучше не паримся и юзаем XML
Если на C/C++ то тогде уже лучше lua прикрутить.

TOM_RUS
21.04.2011, 18:57
Я в своем WoWPacketViewer прикрутил динамическую компиляцию парсеров (http://code.google.com/p/mywowtools/source/detail?r=327) для эксперимента (файл parsers\SMSG_TUTORIAL_FLAGS.cs компилится при выполнении программы).

Йоха
28.04.2011, 10:38
Я не совсем понял есть ли в природе опенсоурс проект "просмотрщик пакетов" который поддерживается и развивается ? Или ситуация такая же как со сниферами - каждый делает себе свой ?

[добавлено]

Я думаю «народный» аналог PacketViewer-а от TOM_RUS или zPktViewer-а, с поддержкой последних форматов сниффов (у меня сейчас самые распространенные — три) был бы гораздо полезнее, чем народный-же сниффер.

Я набросал каркас приложения, но как мне кажется никто заниматься этим не будет ...

LordJZ
28.04.2011, 14:47
Ну PacketViewer от TOM_RUS открытый.

Йоха
28.04.2011, 14:55
но он не актуальный на данный момент ? я там глянул на опкоды, они все старые

LordJZ
28.04.2011, 14:58
Чем больше опкодов появляется в паблике, тем сильнее защиту делает близзард :)

Йоха
28.04.2011, 15:50
Ага, ясно.
Ну тем не менее я потихоньку допишу хотя бы минимально функциональный код, может что получится из открытого проекта.
Предполагается что список опкодов и все скрипты - парсеры опкодов будут вшешними. Следовательно движок один, а уж опкоды каждый сам у себя приводит в актуальное состояние.

RomanRom2
28.04.2011, 20:49
ну я могу отдать на растерзание свой zPktViewer, сорцы всмысле. времени сейчас им заниматься нет совсем...
только как у вас с delphi? :)

Йоха, я смотрю дизайн вьювера никак не хочет меняться :) как я его придумал 500 тыщ лет назад, а он всё такой же :) прям как с нортон командером =)

Йоха
28.04.2011, 21:37
Йоха, я смотрю дизайн вьювера никак не хочет меняться :) как я его придумал 500 тыщ лет назад, а он всё такой же :) прям как с нортон командером =)

ну да, я просто прикинул другие варианты, как-то места мало остается под остальные окна. Ничего толкового в общем не придумал. Завтра на работе если не будет особо дел, то доделаю хотя бы простое чтение чтение файла и может быть хекс вью.
Язык с++, фреймворк - WTL, есть желающие присоединиться к разработке ? =)))

TOM_RUS
28.04.2011, 22:28
но он не актуальный на данный момент ? я там глянул на опкоды, они все старые

Мой PacketViewer под 3.3.5а если вы об этом. Смысла что-то писать под катаклизм я на вижу.

Йоха
04.05.2011, 09:53
Сделал загрузку имен опкодов из внешнего файла.
Файл ищется в папке с программой в подпапке равному номер билда
Номер билда берется их заголовка pkt файла.
Например открываем сниф от билда 13623, сама программа находится в папке c:\packetview.
Будет загружен файл c:\packetview\13623\opcodes.txt
Если для опкода нет символьного представления, то выводится просто его значение

ЗЫ, в догонку вопрос, какой контейнер лучше использовать вместо std::vector для составления индекса pkt файла.
Просто при открытии больших снифов (порядка 160000 пакетов) возникает задержка при формировании индекса. Насколько я помню vector делает перемещения памяти для того что бы все данные располагались единым блоком. Мне это не нужно, от контейнера требуется 2 вещи - быстрая вставка в конец списка и произвольный доступ к элементам посредством оператора [].
К сожалению в STL не силен, знаю так основы.

alien
04.05.2011, 10:45
поидее std::deque должен подойти

Йоха
04.05.2011, 11:03
во! то что надо, теперь открытие любых файлов осуществляется почти мгновенно!

Йоха
05.05.2011, 12:56
Озадачился поиском скриптового языка который надо прикрутить к программе для парсинга сложных опкодов.
Оказывается их сейчас развелось вагон. В луа я почти не разбирался, так в легкой форме только, поэтому вопрос: насколько этот язык пойдет для парсинга пакетов ?
Прикрутить его к программе дело плевое, как я понял прочитав документацию.

И как лучше отдавать пакет в луа код ? просто как последовательность байт ? В луа есть возможности для анализа массива байт ?
А, посмотрел на пример у топикстартера, лучше реализовать функции для чтения данных из пакета:

Read8 - число 8бит
Read16
Read32
Read64
ReadPG - пакованый GUID
ReadString


какие еще "элементарные" типы данных понадобятся ?

Lordronn
05.05.2011, 14:50
Bool
Guid
Vector2
Vector3
Vector4
PackedVector
PacketQuaternion

UintBool - по другому не знаю как назвать. Близы используют в некоторых пакетах 4 байта для передачи да или нет, а не бул.

.:: Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 40 сообщение(ий)) ::.

LordJZ
05.05.2011, 14:57
PackedVector это разница между будущем и текущем векторами, просто так его читать нельзя

Йоха, а вы только на С++ пишете?

Йоха
05.05.2011, 15:15
В общем ясно, это надо допилить по ходу дела. Сейчас допишу элементарное взаимодействие со скриптами.

В целом архитектура вырисовывается такая, для работы программы требуются 2 файла:
opcodes.txt
parsers.lua

оба файла загружаются из папки соответсвующей номеру билда снифа (берется из заголовка pkt файла)
формат opcodes.txt:
опкод, текстовое_представление_оп кода, имя_функции_для_парсинга
опкод может быть как в десятичной системе, так и в шестьнадцатеричной. Для последней число должно начинаться с "0x"
например:
0x8581, CMSG_WORLD_TELEPORT, cmsg_world_teleport

для этого примера файл parsers.lua должен содержать функцию cmsg_world_teleport
function cmsg_world_teleport()
// тут написать собственно сам парсер пакета
end

внутри lua функции доступен объект "packet" который используется для чтения данных из пакета, например:
function cmsg_world_teleport()
packet.Read8()
packet.Read32()
end

ну и конечно какой-нибудь объект для вывода отпарсеной информации в окно программы, название пока не придумал

RomanRom2
05.05.2011, 15:17
к своему парсеру я тоже собирался луа прикручивать. еще есть PascalScript и оно вроде как даже по главнее будет, но отдавая себе отчет в том, что вьюверы будут еще и что бы как то стандартизировать и унифицировать формат "плагинов"-"парсеров", я бы выбрал луа. грубо говоря один и тот же парсер какого нить опкода, написанный на луа (скажем SMSG_CHAR_ENUM.lua) одинаково хавался бы всеми вьюверами, и моим, и йохавским, и томаруса и еще чьим угодно.

Йоха
05.05.2011, 16:23
Йоха, а вы только на С++ пишете?

на с++, на придурашном языке 1С (это слава богу в прошлом), на ассемблере, на делфи немного (давно не практиковался)
ах да, забыл добавить - еще на бейсике -)))) со школы его не забуду

Добавлено через 3 минуты
как то стандартизировать и унифицировать формат "плагинов"-"парсеров", я бы выбрал луа. грубо говоря один и тот же парсер какого нить опкода, написанный на луа (скажем SMSG_CHAR_ENUM.lua) одинаково хавался бы всеми вьюверами, и моим, и йохавским, и томаруса и еще чьим угодно.

ну тут как мне кажется стандартизации подлежат только объекты которые будут предоставляться скриптам типа того что я описал выше, для чтения данных из пакета и для вывода информации обратно в программу

Добавлено через 1 час 1 минуту
UintBool - по другому не знаю как назвать. Близы используют в некоторых пакетах 4 байта для передачи да или нет, а не бул.


ну для этого можно использовать Read32

alien
05.05.2011, 18:24
Еще из луа пригодилась бы возможность распаковывать zlib'нутые данные.
То есть к функциям чтения добавить функцию распаковки.

Йоха
05.05.2011, 19:25
Еще из луа пригодилась бы возможность распаковывать zlib'нутые данные.
То есть к функциям чтения добавить функцию распаковки.

ну это не проблема, добавляется легко

Minimajack
12.05.2011, 08:40
build 12340
XML замечательно описывает формат пакета ( не считая условий )
<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="SMSG_CHAR_ENUM">
<Fields xsi:type="DynamicLoop" Name="Characters" DataType="Byte">
<Fields xsi:type="Simple" Name="PlayerGuid" DataType="UInt64"/>
<Fields xsi:type="Simple" Name="PlayerName" DataType="String"/>
<Fields xsi:type="Simple" Name="Race" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Class" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Gender" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Skin" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Face" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Hairstyle" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Haircolor" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Facialhair" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Level" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Zone" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Map" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Coords" DataType="Coords3"/>
<Fields xsi:type="Simple" Name="GuildId" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Char_flags" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="LoginFlags" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Firstlogin" DataType="Byte"/>
<Fields xsi:type="Simple" Name="PetDisplayId" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="PetLevel" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="PetFamily" DataType="UInt32"/>
<Fields xsi:type="StaticLoop" Name="Items" DataType="UInt32" LoopLength="19">
<Fields xsi:type="Simple" Name="DisplayInfoID" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="InventoryType" DataType="Byte"/>
<Fields xsi:type="Simple" Name="EnchantAuraId" DataType="UInt32"/>
</Fields>
<Fields xsi:type="StaticLoop" Name="Items2" DataType="UInt32" LoopLength="4">
<Fields xsi:type="Simple" Name="Bag" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Slot" DataType="Byte"/>
<Fields xsi:type="Simple" Name="Enchant" DataType="UInt32"/>
</Fields>
</Fields>
</Definition>
Про JSON такого сказать не получится, но он и не для этого предназначается(может я его и не так использую...?)
[{"name":"Characters","type":"DynamicLoop","loopvalue":"Byte","chield":{"PlayerGuid":{"type":"UInt64"},"PlayerName":{"type":"String"},"Race":{"type":"Byte"},"Class":{"type":"Byte"},"Gender":{"type":"Byte"},"Skin":{"type":"Byte"},"Face":{"type":"Byte"},"Hairstyle":{"type":"Byte"},"Haircolor":{"type":"Byte"},"Facialhair":{"type":"Byte"},"Level":{"type":"Byte"},"Zone":{"type":"UInt32"},"Map":{"type":"UInt32"},"Coords":{"type":"Coords3"},"GuildId":{"type":"UInt32"},"Char_flags":{"type":"UInt32"},"LoginFlags":{"type":"UInt32"},"Firstlogin":{"type":"Byte"},"PetDisplayId":{"type":"UInt32"},"PetLevel":{"type":"UInt32"},"PetFamily":{"type":"UInt32"},"Items":{"name":"Items","type":"StaticLoop","LoopLength":19,"chield":{"DisplayInfoID":{"type":"UInt32"},"InventoryType":{"type":"Byte"},"EnchantAuraId":{"type":"UInt32"}}},"Items2":{"name":"Items2","type":"StaticLoop","LoopLength":4,"chield":{"Bag":{"type":"UInt32"},"Slot":{"type":"Byte"},"Enchant":{"type":"UInt32"}}}}}]
Ипользуя XML можно организовать чтение пакетов, или кодогенератор...да и зрительно просто песня
может сообразим какой нить формат описания данных? =)))
зы текущий XML формат позаимствован у TOM_RUS

RomanRom2
12.05.2011, 10:36
LoopLength не достаточно. попробуйте описать в xml пакет 00А9. если получится, то можно смело пользовать xml.

Minimajack
12.05.2011, 11:55
<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="SMSG_COMPRESSED_UPDATE_OBJECT">
<Fields xsi:type="Compress" DataType="gz" >
<Fields xsi:type="DynamicLoop" Name="UpdateObject" DataType="UInt32">
<Fields xsi:type="Switch" DataType="Byte">
<Fields xsi:type="Case" Value="0">
<Fields xsi:type="Simple" Name="ObjGuid" DataType="Guid"/>
<Fields xsi:type="Struct" DataType="WoWObjectUpdate"/>
</Fields>
<Fields xsi:type="Case" Value="1">
<Fields xsi:type="Struct" DataType="MovementInfo"/>
</Fields>
<Fields xsi:type="Case" Value="2">
<Fields xsi:type="Simple" Name="ObjGuid" DataType="Guid"/>
<Fields xsi:type="Simple" Name="ObjectType" DataType="Byte"/>
<Fields xsi:type="Struct" DataType="MovementInfo"/>
<Fields xsi:type="Struct" DataType="WoWObjectUpdate"/>
</Fields>
<Fields xsi:type="Case" Value="3">
<Fields xsi:type="Simple" Name="ObjGuid" DataType="Guid"/>
<Fields xsi:type="Simple" Name="ObjectType" DataType="Byte"/>
<Fields xsi:type="Struct" DataType="MovementInfo"/>
<Fields xsi:type="Struct" DataType="WoWObjectUpdate"/>
</Fields>
<Fields xsi:type="Case" Value="4">
<Fields xsi:type="DynamicLoop" Name="NumbRangeObject" DataType="UInt32">
<Fields xsi:type="Simple" Name="ObjGuid" DataType="Guid"/>
</Fields>
</Fields>
<Fields xsi:type="Case" Value="5">
<Fields xsi:type="DynamicLoop" Name="NumbNearObject" DataType="UInt32">
<Fields xsi:type="Simple" Name="ObjGuid" DataType="Guid"/>
</Fields>
</Fields>
</Fields>
</Fields>
</Fields>
</Definition>

RomanRom2
12.05.2011, 13:23
ну это понятно, а где собсно самое интересное то? =)
где чтение блоков данных в завимости от флагов? где чтение и разбор битовой маски? где собсно разбор MovementInfo? не обязательно всё, ключевые моменты.

Minimajack
12.05.2011, 13:31
ну это понятно, а где собсно самое интересное то? =)
где чтение блоков данных в завимости от флагов? где чтение и разбор битовой маски? где собсно разбор MovementInfo? не обязательно всё, ключевые моменты.
к сожалению нормально разобрать этот пакет у меня не получается( точнее ее часть с созданием объекта... где то не доглядел)
как приду на работу ( 30 мин ), скину парочку основных моментов, в общем то из-за них и начал, т.к. не всем может быть понятно такое описание.

RomanRom2
12.05.2011, 13:52
разобрать пакет не проблема, он давно разобран, спрашивай что непонятно.
проблема описать это для вьювера и использовать в нем то, что описал.

TOM_RUS
12.05.2011, 14:25
Пакет:

0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00


Структура:

uint32 flags;
if(flags & 0x1)
uint32 value1;
if(flags & 0x2)
uint32 value2;


Описание в XML:

<Definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Opcode="CMSG_TEST_ACTION">
<Fields xsi:type="ConditionMultiple" Name="Condition2" DataType="UInt32">
<Fields xsi:type="ConditionCheck" Name="Condition2Field1" DataType="UInt32" ConditionType="And" ConditionValue="1">
<Fields xsi:type="Simple" Name="ConditionCheckField1" DataType="UInt32"/>
</Fields>
<Fields xsi:type="ConditionCheck" Name="Condition2Field2" DataType="UInt32" ConditionType="And" ConditionValue="2">
<Fields xsi:type="Simple" Name="ConditionCheckField2" DataType="UInt32"/>
</Fields>
</Fields>
</Definition>



Opcode: CMSG_TEST_ACTION
Condition2: 3
ConditionCheck: type And, value 1
ConditionCheckField1: 4
ConditionCheck: type And, value 2
ConditionCheckField2: 8

Minimajack
12.05.2011, 14:59
пока только обычные Condition :pardon:

<Struct xsi:type="Struct" StructName="MovementInfo">
<Fields xsi:type="Simple" Name="UpdateFlags" DataType="Byte"/>
<Fields xsi:type="Condition" ConditionType="8" variable="UpdateFlags" ConditionValue="32"> //ConditionType::And
<Fields xsi:type="Simple" Name="Flags" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Flags2" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="TimeStamp" DataType="UInt32"/>
<Fields xsi:type="Simple" Name="Position" DataType="Coords3"/>
<Fields xsi:type="Simple" Name="Facing" DataType="Single"/>
<Fields xsi:type="Condition" ConditionType="8" variable="Flags" ConditionValue="512">
<Fields xsi:type="Struct" DataType="TransportInfo"/>
</Fields>
</Fields>
.....
</Struct>

Йоха
13.05.2011, 11:52
Vector2
Vector3
Vector4
PackedVector
PacketQuaternion


1 вопрос : какой тип (применительно к с++) имеют вышеперечисленные данные ?

2 вопрос - float используется где-нибудь ?

Konctantin
13.05.2011, 12:06
2 - да, используется...

Minimajack
13.05.2011, 12:13
1 вопрос : какой тип (применительно к с++) имеют данные ?
2 вопрос - float используется где-нибудь ?
PackedVector = размер DWord, потом распаковка
Vector3 = размер 3* DWord , грубо говоря 3 float - x,y,z ...
остальные пока не встретил...

Minimajack
01.06.2011, 11:12
надумал собрать, что то вроде, парсера-конструктора структуры пакетов...
то есть - при выводе пакета, выводить hex, отпарсенные данные и структуру пакета с возможностью изменения.
Думаю реально, но как это можно удобно представить...так как хотелось бы ввести побольше плюшек для лентяев как я...
кто то пытался такое соорудить?
остановился на тулбаре, деревом структуры пакета и панелью для изменения( настройки ) узла. Не знаю куда втулить вложенные структуры...или отдельной панелью...или вообще отдельно хранить и при надобности использовать...часто ли в пакетах присутствуют повторяющиеся структуры?
ps вообще хочется размять мозги...скучно стало =)))

Konctantin
01.06.2011, 11:53
Спасибо за идею

Minimajack
02.06.2011, 15:45
черновое расположение
http://img818.imageshack.us/img818/5033/testinterface.th.jpg (http://img818.imageshack.us/i/testinterface.jpg/)
места мало...
прикидываю:

заменить верхнюю панель на тулбар...
если структура (опкода) не вместится, придется резать и лист со списком опкодов
все еще некуда вставить структуры( создание, правка, изменение )...хотя идеи есть

:friends: желательна "здоровая" критика

Minimajack
03.06.2011, 17:02
"если структуры пакета можно представить в виде дерева, то почему бы и результаты разбора так не отображать..."
Экономия, при написании вывода. Думаю в структуре выделить пунктик и под необходимость вывода элементов.
1001
пока что, только фейковый разбор( структура еще не редактируется)...но это только пока

RomanRom2
03.06.2011, 18:53
мне не нравится колонка direction. зачем она? я поэтому и сделал в своем вьювере слева отображаются клиентские, справа серверные опкоды. по мне так как то нагляднее.

далее, как ни крути - хочется видеть хекс и парсинг ОДНОВРЕМЕННО, а не через закладки. ну, опять же - имхо.

парсинг в виде дерева - здраво. наверное. время покажет.

Minimajack
03.06.2011, 19:15
мне не нравится колонка direction. зачем она? я поэтому и сделал в своем вьювере слева отображаются клиентские, справа серверные опкоды. по мне так как то нагляднее.

далее, как ни крути - хочется видеть хекс и парсинг ОДНОВРЕМЕННО, а не через закладки. ну, опять же - имхо.

парсинг в виде дерева - здраво. наверное. время покажет.
все колонки настраиваемые...то есть сортировка, группировка, скрытие и т.п.
а поподробнее можно почему так нагляднее (опять же есть группировка...но результат будет не тот конечно), Возможно слева ввести дополнительную панель и по кнопочке разбросать...
хекс и парсинг...да пришлось на вкладочки - ибо место ограниченное.Либо уменьшить шрифт, либо делить одну вкладку по горизонтали, либо придумать кнопочку настройки "Отображения" - это надо подумать( имхо лучший вариант, но жесткий ).
можно увидеть скриншот парсера?

LordJZ
03.06.2011, 20:43
все колонки настраиваемые...то есть сортировка, группировка, скрытие и т.п.
а поподробнее можно почему так нагляднее (опять же есть группировка...но результат будет не тот конечно), Возможно слева ввести дополнительную панель и по кнопочке разбросать...
хекс и парсинг...да пришлось на вкладочки - ибо место ограниченное.Либо уменьшить шрифт, либо делить одну вкладку по горизонтали, либо придумать кнопочку настройки "Отображения" - это надо подумать( имхо лучший вариант, но жесткий ).
можно увидеть скриншот парсера?Мой «классический» парсер выглядит вот так: http://dl.dropbox.com/u/9241118/packetviewer-overview.gif
Но я вижу мало смысла в Hex View. Подумываю о вынесении во вкладки Hex View и Parsed View.

alien
03.06.2011, 23:22
Если посмотреть на первый скрин темы то там уже была идея с выводом структурой )

Minimajack
04.06.2011, 00:20
Если посмотреть на первый скрин темы то там уже была идея с выводом структурой )
Ух....даже расположение панелей получилось похоже =)))
вывод( как и парсинг ) - происходит исключительно за счет описания структуры пакета. Если у тебя аналогично - значит мыслим в одном направлении. Кстати как проект живет?
Пока 3 варианта хранения:

использовать XML - как возможно-перспективный (экспорт-импорт)
хранить сериализованное описание в бд - имхо, самый удобный
в файлах - реализовано сейчас

RomanRom2
04.06.2011, 09:58
ну собственно я ничего нового не скажу, просто приведу скриншот июля далекого 2007го: http://wowcore.ru/downloads/zPktViewer.png

Но я вижу мало смысла в Hex View. Подумываю о вынесении во вкладки Hex View и Parsed View.
это можно сделать раздвигающимся, как это модно сейчас. кликаешь на как бы бордюр "окна" и оно схлопывается. кликаешь снова - раскрывается. таким образом хекс можно убрать, кому не надо. но херс и парсер ДОЛЖНЫ быть на одном экране! :ireful2:
имхо =)))

Minimajack
10.06.2011, 12:11
расположение панелей для изменения структуры...
правая панель пока пустует(для описание элемента и его настройки)
добавил схематическое изображение циклам...
вот думаю все в одну кучу валить или разбивать на подменю? Логично циклы объединить, структуры впихнуть, но и лишние клики тоже не хочется делать =)))
1005

Minimajack
21.06.2011, 23:37
не прошло и пол года...остановился на вложенных структурах.
Понемногу правлю тулбар....после очередной правки оказалось - наследование кривоватое ...буду переписывать (не хочется - что бы после удаления сложных структур - удалялись вложенные или ненужные драг-н-дроп нормальный прикрутить)
1010
пока скрестил комбобокс+дерево...не нравится...буду скрещивать комбобокс с меню...