Nihaz
Member
на выходных постараюсь полностью гайд написать со всеми скринами, готовыми структурами и тп. пока опишу в целом откуда можно брать типы, мб уже вам будет поле для работы (хотя вроде ничего нового не сообщаю, информация давно известна)
За пример буду брать клиент 1.1 и рекомендую сразу скипать типы ресурсов, которые есть на сервере, чтобы зря времени не терять)
Всего есть 4 вида типов, которые используются:
1) примитивы - сюда относятся int64, double, float, int, bool
2) базовые структуры - nstl::vector, wstring, string, dbPointer (ссылка на dbid = ресурс .xdb), fileRef (бинарные файлы), textFileRef (текстовые файлы)
3) энамы
4) структуры - обычные и генерики
5) классы - это собственно и есть отображение одного .xdb файла, ресурса
если примитивы и базовые структуры нам придется имплементировать самостоятельно(можно подсмотреть в отладочных файлах), то вот классы, энамы и структуры можно взять из четырех источников (за исключением базового класса NDb::Resource и InlineStruct):
1) types.xml
Тут все просто, все типы для клиента описаны в серверном types.xml, 90% структур можно бездумно воссоздать из них, написав парсер и генератор кода, иногда встречается так, что не все типы описаны в types.xml или описаны неверно. Я начинаю именно с этого, а потом подгоняю кривые структуры при помощи других методов
в большинстве случаев, если поле у класса или структуры имеет аттрибут noCode, то оно просто пропускается
если базовый класс = "00000000", то это означает отсутствие базового класса, за исключением структур с аттрибутами inline или abstract, тогда родителем для них будет InlineStruct (как правило это генерики)
ну и базовый класс для всех ресурсов NDb::Resource (resourceDb.resources.Resourceclassfile)
Важно помнить, что ВСЕ структуры и классы начинаются с поля чексумы
unsigned long __dwCheckSum
за исключением client.commonDBTypes.*
и не забываем про выравнивание для типа bool
2) отладочные файлы .pdb, из них можно получить все as is, для вытягивания можно использовать например llvm-pdbutil
3) дизассемблирование - т.к. клиент парсит .xdb файлы, вооружаемся идой и идем искать функции парсинга типов со всеми полями и т.п., но метод на крайний случай, т.к все типы вручную перебирать это ужас) может помочь, если более простые методы использовать нельзя
4) не думаю, что это можно рассматривать как полноценный метод, скорее как метод отладки (а она точно будет) - ручное изучение в пямяти, например через cheatEngine "Dissect Data/Structures", очень удобная штука
5) реплики java классов на сервере - просто допишу, вообще ни разу не использовал, но часть ресурсов можнт помочь распаковать, т.к. они с них собственно и генерируются
За пример буду брать клиент 1.1 и рекомендую сразу скипать типы ресурсов, которые есть на сервере, чтобы зря времени не терять)
Всего есть 4 вида типов, которые используются:
1) примитивы - сюда относятся int64, double, float, int, bool
2) базовые структуры - nstl::vector, wstring, string, dbPointer (ссылка на dbid = ресурс .xdb), fileRef (бинарные файлы), textFileRef (текстовые файлы)
3) энамы
4) структуры - обычные и генерики
5) классы - это собственно и есть отображение одного .xdb файла, ресурса
если примитивы и базовые структуры нам придется имплементировать самостоятельно(можно подсмотреть в отладочных файлах), то вот классы, энамы и структуры можно взять из четырех источников (за исключением базового класса NDb::Resource и InlineStruct):
1) types.xml
Тут все просто, все типы для клиента описаны в серверном types.xml, 90% структур можно бездумно воссоздать из них, написав парсер и генератор кода, иногда встречается так, что не все типы описаны в types.xml или описаны неверно. Я начинаю именно с этого, а потом подгоняю кривые структуры при помощи других методов
в большинстве случаев, если поле у класса или структуры имеет аттрибут noCode, то оно просто пропускается
если базовый класс = "00000000", то это означает отсутствие базового класса, за исключением структур с аттрибутами inline или abstract, тогда родителем для них будет InlineStruct (как правило это генерики)
C:
extern (C) struct NDbBase_InlineStruct_MetaInfo
{
void* type_pointer;
ubyte[4] __padding_1;
ubyte[4] __padding_2;
ubyte[4] __padding_3;
char* name;
}
// base struct for all inline structures
extern (C) struct NDbBase_InlineStruct
{
void* type_pointer;
ubyte[4] __padding_1;
ubyte[4] __padding_2;
NDbBase_InlineStruct_MetaInfo* meta_info;
}
ну и базовый класс для всех ресурсов NDb::Resource (resourceDb.resources.Resourceclassfile)
C:
extern (C) struct NDbBase_Resource
{
void* type_pointer;
ubyte[4] __padding_1;
ubyte[4] __padding_2;
char* dbid;
bool b_loaded;
ubyte[3] __padding_3;
}
Важно помнить, что ВСЕ структуры и классы начинаются с поля чексумы
unsigned long __dwCheckSum
за исключением client.commonDBTypes.*
и не забываем про выравнивание для типа bool
2) отладочные файлы .pdb, из них можно получить все as is, для вытягивания можно использовать например llvm-pdbutil
C:
enum NDb::ParticleAnimation::RenderEffect {
STD_MODE = 0
Z_QUAD = 1
Z_BOX = 2
}
C:
struct NDb::ParticleAnimation::ParticleEmitter [sizeof = 52] {
data +0x00 [sizeof=4] unsigned long __dwCheckSum
data +0x04 [sizeof=4] float virtualOffset
data +0x08 [sizeof=4] float pivotY
data +0x0c [sizeof=4] float pivotX
data +0x10 [sizeof=12] nstl::basic_string<char> name
base +0x10 [sizeof=12] nstl::_String_base<char>
data +0x10 [sizeof=4] char* _M_start
data +0x14 [sizeof=4] char* _M_finish
data +0x18 [sizeof=4] char* _M_end_of_storage
data +0x1c [sizeof=1] bool distortionEmitter
data +0x1d [sizeof=1] bool decalEmitter
<padding> (2 bytes)
data +0x20 [sizeof=4] float ambientLightFactor
data +0x24 [sizeof=1] bool worldSpaceEmitter
data +0x25 [sizeof=1] bool useLooping
<padding> (2 bytes)
data +0x28 [sizeof=4] NDb::ParticleAnimation::RenderEffect renderEffect
data +0x2c [sizeof=4] int color
data +0x30 [sizeof=4] NDb::ParticleAnimation::BlendEffect blendEffect
}
C:
struct NDb::TextureSingleElement [sizeof = 64]
: public NDb::CResource {
<padding> (20 bytes) // NDb::CResource
data +0x14 [sizeof=4] unsigned long __dwCheckSum
data +0x18 [sizeof=4] int y
data +0x1c [sizeof=4] int x
data +0x20 [sizeof=4] int width
data +0x24 [sizeof=12] File::FilePath sourceFile
base +0x24 [sizeof=12] nstl::basic_string<char>
base +0x24 [sizeof=12] nstl::_String_base<char>
data +0x24 [sizeof=4] char* _M_start
data +0x28 [sizeof=4] char* _M_finish
data +0x2c [sizeof=4] char* _M_end_of_storage
data +0x30 [sizeof=4] int height
data +0x34 [sizeof=4] int crc
data +0x38 [sizeof=8] DBPtr<NDb::TextureAtlas,NDb::TextureAtlas *> atlas
data +0x38 [sizeof=4] NDb::TextureAtlas* pObj
data +0x3c [sizeof=1] bool bLoaded
<padding> (3 bytes)
}
4) не думаю, что это можно рассматривать как полноценный метод, скорее как метод отладки (а она точно будет) - ручное изучение в пямяти, например через cheatEngine "Dissect Data/Structures", очень удобная штука
5) реплики java классов на сервере - просто допишу, вообще ни разу не использовал, но часть ресурсов можнт помочь распаковать, т.к. они с них собственно и генерируются