Allods Developers Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Аллоды 1.0.02.0/1.1.02 + ЛР - запуск локального сервера в 2 клика

на выходных постараюсь полностью гайд написать со всеми скринами, готовыми структурами и тп. пока опишу в целом откуда можно брать типы, мб уже вам будет поле для работы (хотя вроде ничего нового не сообщаю, информация давно известна)
За пример буду брать клиент 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)
    }
3) дизассемблирование - т.к. клиент парсит .xdb файлы, вооружаемся идой и идем искать функции парсинга типов со всеми полями и т.п., но метод на крайний случай, т.к все типы вручную перебирать это ужас) может помочь, если более простые методы использовать нельзя
4) не думаю, что это можно рассматривать как полноценный метод, скорее как метод отладки (а она точно будет) - ручное изучение в пямяти, например через cheatEngine "Dissect Data/Structures", очень удобная штука
5) реплики java классов на сервере - просто допишу, вообще ни разу не использовал, но часть ресурсов можнт помочь распаковать, т.к. они с них собственно и генерируются
 
Back
Top