Объявления

Форум о Героях Меча и Магии и King's Bounty. Если Вы любите эти игры, мы будем рады видеть Вас в наших рядах. :smile2:.

Программа для разведки

Не запускается игра? Проблемы со звуком? Где, в конце концов, взять игру, скачать патчи, приложения и карты? Как установить все это? Все проблемы обсуждаем в этом разделе

Re: Программа для разведки

Сообщение AlexSpl » 14 май 2014, 15:06

Обновлений в ближайшее время не будет.
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение AlexSpl » 12 июн 2014, 11:24

Исходники LMOracle.SkillTreeAPI.dll

 SkillTreeAPI.h
Код: Выделить всё
#include <windows.h>

#define DllExport extern "C" __declspec(dllexport)

struct THero
{
   BYTE Class;
   BYTE Level;
   BYTE TreeNumber;
   BYTE LastWisdom;
   BYTE LastMagic;
   BYTE Attack;
   BYTE Defense;
   BYTE SpellPower;
   BYTE Knowledge;
   BYTE SkillCount;
   BYTE Skill[28];
};

struct TWeights
{
   BYTE PW[4];
   BYTE PW10[4];
   BYTE SW[28];
   bool SR[28];
};

struct TSecondary
{
   BYTE Left;
   BYTE Right;
};

struct TSkillOffer
{
   BYTE Primary;
   TSecondary Secondary;
};

struct TSkillExcept
{
   BYTE Last_Wisdom;
   BYTE Last_Magic;
   BYTE Delta_Wisdom;
   BYTE Delta_Magic;
};

enum {ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE};

enum
{
   PATHFINDING, ARCHERY, LOGISTICS, SCOUTING, DIPLOMACY, NAVIGATION, LEADERSHIP,
   WISDOM, MYSTICISM, LUCK, BALLISTICS, EAGLE_EYE, NECROMANCY, ESTATES,
   FIRE_MAGIC, AIR_MAGIC, WATER_MAGIC, EARTH_MAGIC, SCHOLAR, TACTICS, ARTILLERY,
   LEARNING, OFFENSE, ARMORER, INTELLIGENCE, SORCERY, RESISTANCE, FIRST_AID, NONE
};

enum {BASIC = 1, ADVANCED, EXPERT};

const DWORD HAddr[4] = {0x0069CC88, 0x006994E8, 0x00699538, 0x006388D8};
const DWORD WAddr[4] = {0x0067EFDC, 0x0067DCEC, 0x0067DCEC, 0x0061C194};
const DWORD BB_CFAddr[3] = {0x0069AEEC, 0x0069774C, 0x0069774C};
const DWORD BB_SRAddr[3] = {0x0067AF90, 0x00679CA0, 0x00679CA0};

DllExport DWORD GetProcessID(const wchar_t *Title);
DllExport DWORD GetHStartPoint(const HANDLE hProcess, const BYTE Version);
DllExport int RAMHero(const HANDLE hProcess, const DWORD HStartPoint, const BYTE ID, void *HeroRecord);
DllExport int RAMWeights(const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE Class, void *WeightsRecord);
DllExport int LevelUp(void *HeroRecord, const void *WeightsRecord, void *SkillOfferRecord, const BYTE Option);
DllExport bool isStandardWeights(const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE ID);
DllExport int RAMBBWeights(const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE Class, void *WeightsRecord);


 SkillTreeAPI.cpp
Код: Выделить всё
#include "SkillTreeAPI.h"

DWORD GetProcessID(const wchar_t *Title)
{
   HWND HWindow = FindWindow(NULL, Title);
   DWORD PID = 0;
   GetWindowThreadProcessId(HWindow, &PID);
   return PID;
}

DWORD GetHStartPoint(const HANDLE hProcess, const BYTE Version)
{
   DWORD HStartPoint = 0;
   if ( Version < 4 )
   {
      DWORD BR;
      ReadProcessMemory(hProcess, LPCVOID(HAddr[Version]), &HStartPoint, 4, &BR);
      HStartPoint += ( Version == 3 ) ? 0x21608 : 0x21620;
   }
   return HStartPoint;
}

int RAMHero(const HANDLE hProcess, const DWORD HStartPoint, const BYTE ID, void *HeroRecord)
{
   if ( ID < 156 )
   {
      DWORD BR;
      DWORD BAddr = HStartPoint + ID * 0x492;

      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0x30), (BYTE *)HeroRecord, 1, &BR);
      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0x55), (BYTE *)HeroRecord + 1, 1, &BR);
      
      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0x8F), (BYTE *)HeroRecord + 2, 2, &BR);
      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0x3F), (BYTE *)HeroRecord + 4, 1, &BR);

      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0x476), (BYTE *)HeroRecord + 5, 4, &BR);
            
      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0x101), (BYTE *)HeroRecord + 9, 1, &BR);
      ReadProcessMemory(hProcess, LPCVOID(BAddr + 0xC9), (BYTE *)HeroRecord + 10, 28, &BR);
   }   
   return 0;
}

bool isStandardWeights(const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE ID)
{
   bool StandardWeights = true;
   if ( Version < 3 )
   {
      DWORD BR;
      BYTE CF, SF, HF;

      ReadProcessMemory(hProcess, LPCVOID(BB_CFAddr[Version]), &CF, 1, &BR);
      ReadProcessMemory(hProcess, LPCVOID(HStartPoint - 0x21C4), &SF, 1, &BR);
      ReadProcessMemory(hProcess, LPCVOID(HStartPoint + ID * 0x492 + 0x1A), &HF, 1, &BR);

      StandardWeights = !( (CF) && (SF == 0x0E) && (HF == 0x2D) );
   }
   return StandardWeights;
}

int RAMBBWeights(const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE Class, void *WeightsRecord)
{
   if ( (Version < 3) && (Class < 18) )
   {
      DWORD BR;
      DWORD WeightsAddr;
      
      ReadProcessMemory(hProcess, LPCVOID(WAddr[Version]), &WeightsAddr, 4, &BR);
      ReadProcessMemory(hProcess, LPCVOID(WeightsAddr + 0x310), (BYTE *)WeightsRecord, 8, &BR);
      ReadProcessMemory(hProcess, LPCVOID(WeightsAddr + (Class << 6) + 0x18), (BYTE *)WeightsRecord + 8, 28, &BR);
      ReadProcessMemory(hProcess, LPCVOID(BB_SRAddr[Version]), (bool *)WeightsRecord + 36, 28, &BR);
   }
   return 0;
}

int RAMWeights(const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE Class, void *WeightsRecord)
{
   if ( (Version < 4) && (Class < 18) )
   {
      DWORD BR;
      DWORD WeightsAddr;
      
      ReadProcessMemory(hProcess, LPCVOID(WAddr[Version]), &WeightsAddr, 4, &BR);
      ReadProcessMemory(hProcess, LPCVOID(WeightsAddr + (Class << 6) + 0x10), (BYTE *)WeightsRecord, 36, &BR);
      ReadProcessMemory(hProcess, LPCVOID(HStartPoint + 0x2D038), (bool *)WeightsRecord + 36, 28, &BR);
   }
   return 0;
}

int Rand(const DWORD Seed, DWORD &R)
{
   R =  0x343FD * Seed + 0x269EC3;
   return ( (R >> 0x10) & 0x7FFF );
}

BYTE GetSkillOffer(const THero *Hero, const TWeights *Weights, const BYTE Level, const TSkillExcept *SkillExcept,
   const BYTE MinLevel, const BYTE MaxLevel, const BYTE LeftSkill, DWORD &R)
{
   if ( MinLevel >= MaxLevel ) return NONE;
         
   // Wisdom
   if ( ((*SkillExcept).Last_Wisdom + (*SkillExcept).Delta_Wisdom <= Level) &&
       ((*Hero).Skill[WISDOM] >= MinLevel) && ((*Hero).Skill[WISDOM] < MaxLevel) &&
       (!(*Weights).SR[WISDOM]) && (LeftSkill != WISDOM) ) return WISDOM;

   int SUM_W = 0;
   int Q;
   
   // Magic
   if ( ((*SkillExcept).Last_Magic + (*SkillExcept).Delta_Magic <= Level) &&
      (LeftSkill != FIRE_MAGIC) && (LeftSkill != AIR_MAGIC) && (LeftSkill != WATER_MAGIC) && (LeftSkill != EARTH_MAGIC) )
   {
      for (int i = FIRE_MAGIC; i <= EARTH_MAGIC; ++i)
         if ( ((*Hero).Skill[i] >= MinLevel) && ((*Hero).Skill[i] < MaxLevel) && (!(*Weights).SR[i]) )
            (*Hero).Skill[i] ? ++SUM_W : SUM_W += (*Weights).SW[i];
      
      if ( SUM_W )
      {
         if ( SUM_W > 1 )
         {
            Q = Rand(R, R);
            ++(Q %= SUM_W);
         } else Q = 1;

         SUM_W = Q;
         for (int i = FIRE_MAGIC; i <= EARTH_MAGIC; ++i)
         {
            if ( ((*Hero).Skill[i] >= MinLevel) && ((*Hero).Skill[i] < MaxLevel) && (!(*Weights).SR[i]) )
                (*Hero).Skill[i]  ? --SUM_W : SUM_W -= (*Weights).SW[i];

            if ( SUM_W <= 0 ) return (BYTE)i;
         }
      }
   }

   // Other Skills
   SUM_W = 0;
   for (int i = PATHFINDING; i < NONE; ++i)
      if ( ((*Hero).Skill[i] >= MinLevel) && ((*Hero).Skill[i] < MaxLevel) && (i != LeftSkill) )
         if ( (!(*Weights).SR[i]) && ((*Weights).SW[i]) ) SUM_W += (*Weights).SW[i]; else
            if ( (*Hero).Skill[i] > 0 ) ++SUM_W;
   
   if ( SUM_W )
   {
      if ( SUM_W > 1 )
      {
         Q = Rand(R, R);
         ++(Q %= SUM_W);
      } else Q = 1;

      SUM_W = Q;
      for (int i = PATHFINDING; i < NONE; ++i)
      {
         if ( ((*Hero).Skill[i] >= MinLevel) && ((*Hero).Skill[i] < MaxLevel) && (i != LeftSkill) )
            if ( (!(*Weights).SR[i]) && ((*Weights).SW[i]) ) SUM_W -= (*Weights).SW[i]; else
               if ( (*Hero).Skill[i] > 0 ) --SUM_W;
            
         if ( SUM_W <= 0 ) return (BYTE)i;
      }
   }

   return NONE;
}

int LevelUp(void *HeroRecord, const void *WeightsRecord, void *SkillOfferRecord, const BYTE Option)
{
   THero *Hero;
   TWeights *Weights;
   TSkillOffer *SkillOffer;

   Hero = (THero *)HeroRecord;
   Weights = (TWeights *)WeightsRecord;
   SkillOffer = (TSkillOffer *)SkillOfferRecord;
   
   BYTE Level = (*Hero).Level;
   BYTE Slot = Option & 3;

   Slot ? Level = ++(*Hero).Level : ++Level;
         
   DWORD R = 0;
   int Q = Rand(0x343FD * Level + 0x26497 * (*Hero).TreeNumber + 0x259DF, R);
   ++(Q %= 100);
   
   // BB Campaign
   if ( Option & 4 )
   {
      int SUM = (Level > 9) ? (*Weights).PW10[ATTACK] + (*Weights).PW10[DEFENSE] : (*Weights).PW[ATTACK] + (*Weights).PW[DEFENSE];
      if ( SUM > 1 )
      {
         Q = Rand(R, R);
         ++(Q %= SUM);
      } else Q = SUM;
   }
   
   // Primary Skills
   int Primary_ID = 0;
   int W;
   do
   {
      W = ( Level > 9 ) ? (*Weights).PW10[Primary_ID] : (*Weights).PW[Primary_ID];
      if ( Q <= W ) break;
      Q -= W;
      ++Primary_ID;
   }
   while ( true );
      
   (*SkillOffer).Primary = Primary_ID;
   if ( Slot ) ++*((BYTE *)HeroRecord + 5 + Primary_ID);

   // Secondary Skills
   TSkillExcept SkillExcept = { (*Hero).LastWisdom, (*Hero).LastMagic, 6, 4 };
   BYTE MinLevel = (*Hero).SkillCount > 7;
      
   if ( ((*Hero).Class & 0x11) == 1 ) SkillExcept.Delta_Wisdom = SkillExcept.Delta_Magic = 3;
   
   BYTE LeftSkill = GetSkillOffer(Hero, Weights, Level, &SkillExcept, BASIC, EXPERT, NONE, R);
   if ( LeftSkill == NONE )
      LeftSkill = GetSkillOffer(Hero, Weights, Level, &SkillExcept, MinLevel, EXPERT, NONE, R);

   if ( LeftSkill == WISDOM ) SkillExcept.Last_Wisdom = Level;
   if ( (LeftSkill >= FIRE_MAGIC) && (LeftSkill <= EARTH_MAGIC) ) SkillExcept.Last_Magic = Level;

   BYTE RightSkill = GetSkillOffer(Hero, Weights, Level, &SkillExcept, MinLevel, BASIC, LeftSkill, R);
   if ( RightSkill == NONE )
      RightSkill = GetSkillOffer(Hero, Weights, Level, &SkillExcept, MinLevel, EXPERT, LeftSkill, R);

   if ( RightSkill == WISDOM ) SkillExcept.Last_Wisdom = Level;
   if ( (RightSkill >= FIRE_MAGIC) && (RightSkill <= EARTH_MAGIC) ) SkillExcept.Last_Magic = Level;
   
   (*SkillOffer).Secondary.Left = LeftSkill;
   (*SkillOffer).Secondary.Right = RightSkill;
      
   if ( Slot )
   {
      (*Hero).LastWisdom = SkillExcept.Last_Wisdom;
      (*Hero).LastMagic = SkillExcept.Last_Magic;
   } else return 0;

   BYTE Skill_ID = ( Slot == 1 ) ? LeftSkill : RightSkill;

   if ( Skill_ID < NONE )
   {
      if ( !(*Hero).Skill[Skill_ID] ) ++(*Hero).SkillCount;
      ++(*Hero).Skill[Skill_ID];
   }
   
   return 0;
}


А вот так можно потестить получившуюся DLL-ку:

 Test.h
Код: Выделить всё
#include <iostream>
#include <windows.h>

using namespace std;

struct THero
{
   BYTE Class;
   BYTE Level;
   BYTE TreeNumber;
   BYTE LastWisdom;
   BYTE LastMagic;
   BYTE Attack;
   BYTE Defense;
   BYTE SpellPower;
   BYTE Knowledge;
   BYTE SkillCount;
   BYTE Skill[28];
};

struct TWeights
{
   BYTE PW[4];
   BYTE PW10[4];
   BYTE SW[28];
   bool SR[28];
};

struct TSecondary
{
   BYTE Left;
   BYTE Right;
};

struct TSkillOffer
{
   BYTE Primary;
   TSecondary Secondary;
};

enum {ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE};

enum
{
   PATHFINDING, ARCHERY, LOGISTICS, SCOUTING, DIPLOMACY, NAVIGATION, LEADERSHIP,
   WISDOM, MYSTICISM, LUCK, BALLISTICS, EAGLE_EYE, NECROMANCY, ESTATES,
   FIRE_MAGIC, AIR_MAGIC, WATER_MAGIC, EARTH_MAGIC, SCHOLAR, TACTICS, ARTILLERY,
   LEARNING, OFFENSE, ARMORER, INTELLIGENCE, SORCERY, RESISTANCE, FIRST_AID, NONE
};

const char *PrimSkillName[4] = {"ATTACK", "DEFENSE", "SPELL_POWER", "KNOWLEDGE"};

const char *SecSkillName[29] =
{
   "PATHFINDING", "ARCHERY", "LOGISTICS", "SCOUTING", "DIPLOMACY", "NAVIGATION", "LEADERSHIP",
   "WISDOM", "MYSTICISM", "LUCK", "BALLISTICS", "EAGLE_EYE", "NECROMANCY", "ESTATES",
   "FIRE_MAGIC", "AIR_MAGIC", "WATER_MAGIC", "EARTH_MAGIC", "SCHOLAR", "TACTICS", "ARTILLERY",
   "LEARNING", "OFFENSE", "ARMORER", "INTELLIGENCE", "SORCERY", "RESISTANCE", "FIRST_AID", "NONE"
};


 Test.cpp
Код: Выделить всё
#include "Test.h"

int main()
{
   // Объявляем указатели на импортируемые функции.
   DWORD (*GetProcessID) (const wchar_t *Title);
   DWORD (*GetHStartPoint) (const HANDLE hProcess, const BYTE Version);
   int (*RAMHero) (const HANDLE hProcess, const DWORD HStartPoint, const BYTE ID, void *HeroRecord);
   int (*RAMWeights) (const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE Class, void *WeightsRecord);
   int (*LevelUp) (void *HeroRecord, const void *WeightsRecord, void *SkillOfferRecord, const BYTE Option);
   
   // Специальные функции для кампании "Рождение варвара" ("Birth of a Barbarian").
   bool (*isStandardWeights) (const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE ID);
   int (*RAMBBWeights) (const HANDLE hProcess, const DWORD HStartPoint, const BYTE Version, const BYTE Class, void *WeightsRecord);

   // Загружаем библиотеку и получаем адреса функций.
   HINSTANCE hDLL = LoadLibrary(L"LMOracle.SkillTreeAPI.dll");
   if ( !hDLL ) return -1;

   GetProcessID = (DWORD (*) (const wchar_t *)) GetProcAddress(hDLL, "GetProcessID");
   GetHStartPoint = (DWORD (*) (const HANDLE, const BYTE)) GetProcAddress(hDLL, "GetHStartPoint");
   RAMHero = (int (*) (const HANDLE, const DWORD, const BYTE, void *)) GetProcAddress(hDLL, "RAMHero");
   RAMWeights = (int (*) (const HANDLE, const DWORD, const BYTE, const BYTE, void *)) GetProcAddress(hDLL, "RAMWeights");
   LevelUp = (int (*) (void *, const void *, void *, const BYTE)) GetProcAddress(hDLL, "LevelUp");
   isStandardWeights = (bool (*) (const HANDLE, const DWORD, const BYTE, const BYTE)) GetProcAddress(hDLL, "isStandardWeights");
   RAMBBWeights = (int (*) (const HANDLE, const DWORD, const BYTE, const BYTE, void *)) GetProcAddress(hDLL, "RAMBBWeights");

   // Получаем PID и открываем процесс для чтения.
   DWORD ProcessID = GetProcessID(L"Heroes of Might and Magic III");
   HANDLE hProcess = OpenProcess(PROCESS_VM_READ, false, ProcessID);

   // Определяем адрес в памяти процесса, по которому хранятся структуры героев: GetHStartPoint(<хендл процесса>, <версия игры>), где
   // <версия игры> = 0 для 4.0 RU,
   // <версия игры> = 1 для 4.0 EN,
   // <версия игры> = 2 для 3.2 EN,
   // <версия игры> = 3 для Heroes Chronicles 1.0 RU.
   DWORD HStartPoint = GetHStartPoint(hProcess, 2);
   
   // Объявляем экземпляры структур THero, TWeights и TSkillOffer.
   THero Hero;
   TWeights Weights;
   TSkillOffer SkillOffer;
   
   // Вводим идентификатор героя ID и количество уровней MaxLevel, на которое будем прокачивать героя.
   int ID, MaxLevel, Slot;
   cout << "Enter ID and MaxLevel: ";
   cin >> ID >> MaxLevel;
   cout << endl;

   // Читаем данные из структуры героя с идентификатором ID.
   RAMHero(hProcess, HStartPoint, ID, &Hero);
   
   // Читаем веса первичных и вторичных навыков для класса, к которому принадлежит герой Hero,
   // с учётом особенностей прокачки Йога в кампании "Рождение варвара" ("Birth of a Barbarian").
   // Для этого определим флаг BBFlag, который будет равен 0 для стандартной прокачки и 4 - для исключения
   BYTE BBFlag = isStandardWeights(hProcess, HStartPoint, 2, ID) ? 0 : 4;
   BBFlag ? RAMBBWeights(hProcess, HStartPoint, 2, Hero.Class, &Weights) : RAMWeights(hProcess, HStartPoint, 2, Hero.Class, &Weights);
   
   // Тестируем
   for (int i = 0; i < MaxLevel; ++i)
   {
      // Option = 000b = 0 - получить SkillOffer, не повышая уровень героя Hero;
      // Option = 001b = 1 - получить SkillOffer и повысить уровень героя Hero, выбрав навык из левого слота;
      // Option = 010b = 2 - получить SkillOffer и повысить уровень героя Hero, выбрав навык из правого слота;
      // Option = 1xxb - получить SkillOffer c учётом особенностей кампании "Рождение варвара" ("Birth of a Barbarian"),
      // где xx = 00, 01 или 10 (см. выше).
      
      // Пример.
      // Option = 110b = 6 - получить SkillOffer c учётом особенностей кампании "Рождение варвара" ("Birth of a Barbarian")
      // и повысить уровень героя Hero, выбрав навык из правого слота.
      LevelUp(&Hero, &Weights, &SkillOffer, BBFlag); // Option = 000b OR BBFlag

      // Выводим предлагаемые при повышении уровня навыки
      cout << "SkillOffer = [" << PrimSkillName[SkillOffer.Primary] << ", ["
          << SecSkillName[SkillOffer.Secondary.Left] << ", " << SecSkillName[SkillOffer.Secondary.Right] << "]]"
          << endl << endl;

      // Выбираем навык: 1 - левый, 2 - правый
      cout << "Slot = ";
      cin >> Slot;
      cout << endl;

      LevelUp(&Hero, &Weights, &SkillOffer, Slot | BBFlag); // Option = Slot OR BBFlag
      
      // Наблюдаем за изменениями характеристик героя.
      cout << "Level = " << (int)Hero.Level << endl
          << "LastWisdom = " << (int)Hero.LastWisdom << endl
          << "LastMagic = " << (int)Hero.LastMagic << endl
          << "Primary = " << (int)Hero.Attack << " " << (int)Hero.Defense
          << " " << (int)Hero.SpellPower << " " << (int)Hero.Knowledge
          << endl << endl;
         
      cout << "SkillCount = " << (int)Hero.SkillCount << endl << "Secondary = ";
      for (int i = PATHFINDING; i < NONE; ++i) cout << (int)Hero.Skill[i] << " ";
      cout << endl << endl;
      
      system("Pause");
      cout << endl;
   }   
      
   // Закрываем хендл, выгружаем библиотеку и выходим.
   CloseHandle(hProcess);
   FreeLibrary(hDLL);
   
   return 0;
}
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение AlexSpl » 13 окт 2014, 03:15

LM Oracle 3.19.0.0 XE (x64) с поддержкой HotA 1.3.3 EN (возможно, будет работать и с русской версией; не тестировал).

http://dropmefiles.com/HNHgo

MD5 (LMOracle.zip, 838,072 bytes): 92237bf3a6649d3842facf0e8f5b86cb
MD5 (LMOracle.exe, 845,824 bytes): eee34e3a355ebb5922f84a86df50134a
Ссылка действительна в течение 7 дней
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение VDV_forever » 13 окт 2014, 10:51

AlexSpl писал(а):

LM Oracle 3.19.0.0 XE (x64) с поддержкой HotA 1.3.3 EN (возможно, будет работать и с русской версией; не тестировал).

http://dropmefiles.com/HNHgo

MD5 (LMOracle.zip, 838,072 bytes): 92237bf3a6649d3842facf0e8f5b86cb
MD5 (LMOracle.exe, 845,824 bytes): eee34e3a355ebb5922f84a86df50134a
Ссылка действительна в течение 7 дней


Залил ее на справочник: LM_Oracle_3.19.0.0_XE.zip XE (x64) с поддержкой HotA 1.3.3 EN

P.S. Увеличил объем файла который можно выкладывать на форуме, до 2 МБт. ;)
http://www.handbookhmm.ru- Познай все тонкости игры!
Аватара пользователя
VDV_forever
Администратор
 
Сообщения: 3553
Зарегистрирован: 22 мар 2009, 12:36
Награды: 39
Высшая медаль (1) Победителю этапа по HMM1 (1) Лучшему из лучших (2) Победителю турнира по KB (1) 1 место 1 этапа по HMM1 (2) 1 место 2 этапа по HMM2 (1)
2 место 2 этапа по HMM2 (1) Победителю турнира по KBL (7) KBL - клановые испытания 1.2 (4) KBL - клановые испытания 1.3 (2) KBL - клановые испытания 3.1 (2) KBL - клановые испытания 2.2 (4)
KBL - клановые испытания 2.3 (3) KBL - клановые испытания 3.2 (1) KBL - клановые испытания 3.3 (1) KBL - клановые испытания 2.1 (5) Ледяной Шлем (1)
Поблагодарили: 829 раз.

Re: Программа для разведки

Сообщение AlexSpl » 20 окт 2014, 23:32

LM Oracle 3.19.0.1 XE

 
Исправлены ошибки в Battle Supervisor, возникшие при портировании программы на x64.

Полное дерево на Core i5-3570:

Изображение
Последний раз редактировалось AlexSpl 29 фев 2016, 14:15, всего редактировалось 1 раз.
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение AlexSpl » 29 ноя 2014, 19:28

Небольшой апдейт, связанный с обнаружением бага в x64 версии. Игроки "в теме", возможно, также оценят новую консольную команду GETR.

LM Oracle 3.19.0.2 XE (x64)

 
[ HoMM II 2.1 RU ]
1. Исправлена ошибка x64 версии, возникающая при двойном клике на MP героя в списке (не запускался LM Oracle Hero Viewer).
2. Добавлена консольная команда GETR, показывающая текущее значение "боевого" ГПСЧ.
3. Теперь консольная команда PLAYER показывает мировоззрение (Alignment) игроков.


Для работы LM Oracle Hero Viewer папка BMP должна находиться в той же директории, что и исполняемый файл.
Последний раз редактировалось AlexSpl 29 фев 2016, 14:16, всего редактировалось 1 раз.
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение DeathLust » 30 ноя 2014, 11:58

AlexSpl писал(а):

Небольшой апдейт, связанный с обнаружением бага в x64 версии. Игроки "в теме", возможно, также оценят новую консольную команду GETR.

Где-то можно почитать список всех команд? ;) х86 версия не будет обновлена?
Аватара пользователя
DeathLust
Подмастерье
Подмастерье
 
Сообщения: 140
Зарегистрирован: 29 ноя 2012, 15:19
Поблагодарили: 60 раз.

Re: Программа для разведки

Сообщение AlexSpl » 30 ноя 2014, 14:29

Цитата:
Где-то можно почитать список всех команд?

Отдельного справочника по консольным командам нет. Но все они более или менее подробно описаны в документах Readme.pdf и History.txt, что находятся в папке Readme.

Цитата:
х86 версия не будет обновлена?

Скорее всего, будет. Пока неохота выпускать обе ради небольших исправлений.
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение AlexSpl » 08 дек 2014, 18:42

Работаю над новой версией 3.19.1.0 XE. Уже запилил сортировку со "стрелочками" ([A], [Z], [0], [9] напрягать стали) и добавил новую консольную команду GETCHEAT (раньше была бы полезна, теперь больше для фана). Теперь планирую объединить мелкие окошки в одно: для Героев 1 - "дерево" прокачки + информацию о герое; Mage Guild Oracle + информацию о городе/замке. Для Героев 2 - Mage Guild Oracle + наконец добавить информацию о городских постройках, здесь же будет информация о гарнизоне. Если у Вас есть идеи насчёт того, какой информации о текущей карте не хватает в LMOracle, чтобы, например, не юзать другой софт, делитесь.
Аватара пользователя
AlexSpl
Эксперт
Эксперт
 
Сообщения: 2598
Зарегистрирован: 17 сен 2010, 12:58
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 1135 раз.

Re: Программа для разведки

Сообщение DR28 » 10 дек 2014, 05:36

AlexSpl писал(а):

Если у Вас есть идеи насчёт того, какой информации о текущей карте не хватает в LMOracle, чтобы, например, не юзать другой софт, делитесь.

1. Координаты героев. Было бы наглядно и удобно при переходе хода смотреть, куда пошли компы. Для умерших невыкупленных - координаты точки слива соответственно.
2. Построенную магию в замках выделять цветом
Аватара пользователя
DR28
Мастер
Мастер
 
Сообщения: 251
Зарегистрирован: 25 июн 2012, 18:59
Откуда: Санкт-Петербург
Награды: 8
Победителю турнира по HMM2 (1) Победителю этапа по HMM2 (3) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) 3 место 2 этапа по HMM2 (1)
Поблагодарили: 91 раз.

Пред.След.

Вернуться в Техническая часть

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1