Объявления
Поздравляем
Roman2211


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

База данных IDA от void17

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 27 ноя 2021, 23:21

Короче, сизифов труд это :smile3: Гораздо легче переписать функцию, чем получить в IDA нормальный листинг функции с повторным использованием адресного пространства переменных другими переменными.

Попробовал ввести вспомогательный union:

Код: Выделить всё
int __thiscall type_AI_spellcaster::get_frenzy_value(
        type_AI_spellcaster *this,
        army *army,
        type_enchant_data_union unionData)
{
  army *frenzyStack; // esi
  army *frenzyTarget; // edi
  int speed; // eax
  int targetHealth; // eax
  INT32 hitPoints; // ecx
  bool canShoot; // bl
  int avgDamage_0; // eax
  bool canShoot_0; // al
  int adjustedDamage; // ebx
  int targetHealth_1; // eax
  type_AI_spellcaster *spellCaster_0; // ecx
  int frenzyWeight; // eax
  signed int numberAlive; // [esp-Ch] [ebp-44h]
  double avgDamage_1; // [esp+Ch] [ebp-2Ch]
  double killedEnemyRatio; // [esp+14h] [ebp-24h]
  int *attackValue; // [esp+1Ch] [ebp-1Ch]
  int targetHealth_0; // [esp+20h] [ebp-18h] BYREF
  type_AI_spellcaster_union spellCaster; // [esp+24h] [ebp-14h]
  int avgDamage; // [esp+2Ch] [ebp-Ch]
  auxStruct aux; // [esp+30h] [ebp-8h]
  int health; // [esp+40h] [ebp+8h] FORCED BYREF

  frenzyStack = army;
  spellCaster.spellCaster[1] = this;
  frenzyTarget = army->spellsData.frenzyTarget;
  // Если нет цели, вес заклинания 0
  if ( !frenzyTarget )
    return 0;
  speed = army::GetSpeed(army);
  // Если отряд под Frenzy не может добраться до цели за 1 ход, вес заклинания 0
  if ( army::get_AI_target_time(frenzyStack, speed) > 1 )
    return 0;
  // Может ли отряд под Frenzy стрелять?
  aux.tmp = army::can_shoot(frenzyStack, 0);
  // Получаем здоровье отряда под Frenzy
  health = army::get_total_hit_points(frenzyStack, 0);
  // Получаем здоровье цели
  targetHealth = army::get_total_hit_points(frenzyTarget, 0);
  hitPoints = frenzyStack->info.hitPoints;
  targetHealth_0 = targetHealth;
  canShoot = aux.tmp;
  avgDamage = army::get_average_damage(frenzyStack, frenzyTarget, aux.tmp, (hitPoints + health - 1) / hitPoints, 1, 0);
  // this->attackValue
  attackValue = &spellCaster.spellCaster[1]->attackValue;
  // Симулируем атаку
  type_AI_combat_parameters::simulate_attack(
    &spellCaster.spellCaster[1]->attackValue,
    frenzyStack,
    &health,
    frenzyTarget,
    &targetHealth_0,
    aux.tmp,
    0);
  if ( !health )
    return 0;
  // Средний урон после атаки
  avgDamage_0 = army::get_average_damage(
                  frenzyStack,
                  frenzyTarget,
                  canShoot,
                  (frenzyStack->info.hitPoints + health - 1) / frenzyStack->info.hitPoints,
                  1,
                  0);
  if ( canShoot && (*&frenzyStack->info.flags & CF_TWO_ATTACKS) != 0 )
    avgDamage_0 /= 2;
  *&aux.tmp = avgDamage + avgDamage_0;
  numberAlive = frenzyStack->numberAlive;
  // 1 + avgDamageAfterAttack / avgDamage
  *&aux = (avgDamage + avgDamage_0) / avgDamage;
  canShoot_0 = army::can_shoot(frenzyStack, 0);
  avgDamage = army::get_average_damage(frenzyStack, frenzyTarget, canShoot_0, numberAlive, 1, 0);
  // Коэффициент потерь
  killedEnemyRatio = *&aux;
  avgDamage_1 = avgDamage;
  adjustedDamage = (avgDamage_1 * *&aux);
  targetHealth_1 = army::get_total_hit_points(frenzyTarget, 0);
  *&aux.tmp = targetHealth_1;
  if ( adjustedDamage > targetHealth_1 )
  {
    adjustedDamage = targetHealth_1;
    // Помним, что в числителе - здоровье отряда противника
    killedEnemyRatio = *&aux.tmp / avgDamage_1;
  }
  if ( adjustedDamage <= avgDamage )
    return 0;
  spellCaster_0 = spellCaster.spellCaster[1];
  spellCaster.spellCaster[1] = spellCaster.spellCaster[1]->spellDuration;
  // if (data->spellDuration < this->spellDuration)
  if ( SLODWORD(unionData.data.spellDuration) < spellCaster.spellCaster[1] )
  {
    unionData.data.spellDuration = SLODWORD(unionData.data.spellDuration);
    // data.spellDuration / this->spellDuration
    unionData.data.spellDuration = unionData.data.spellDuration / spellCaster.spellCaster[1];
  }
  else
  {
    // Иначе 1.0
    unionData.data.spellDuration = 1.0;
  }
  if ( (*&frenzyStack->info.flags & CF_DONE) != 0
    && (unionData.data.spellDuration = unionData.data.spellDuration - 1.0 / spellCaster.spellCaster[1],
        unionData.data.spellDuration < 0.0) )
  {
    spellCaster.k = 0.0;
  }
  else
  {
    spellCaster.k = unionData.data.spellDuration;
  }
  unionData.data.spellDuration = army::get_total_combat_value(frenzyStack, *attackValue, spellCaster_0->defenseValue);
  *&frenzyWeight = ((sqrt(killedEnemyRatio) - 1.0) * unionData.data.spellDuration * spellCaster.k);
  return frenzyWeight;
}

Вроде, намного лучше стало. Должны же быть в IDA инструменты, помогающие бороться с повторным использованием переменных (причём для совершенно других типов)? Это ещё функция небольшая, а что делать, когда функция 10 килобайт с хардкорным реюзом адресного пространства? Там никакой декомпилятор не поможет :smile1:

* * *
А реально, если в результате симуляции атаки отряд под Frenzy погибает, то комп не кастует Frenzy, но это не значит, что отряд не может погибнуть. Симуляция работает со средними уронами всё-таки.

Далее, вот это условие для Frenzy никогда не выполнится из-за того, что длительность Frenzy 1 раунд:

Код: Выделить всё
// if (data->spellDuration < this->spellDuration)
if ( SLODWORD(unionData.data.spellDuration) < spellCaster.spellCaster[1] )
{
  unionData.data.spellDuration = SLODWORD(unionData.data.spellDuration);
  // data.spellDuration / this->spellDuration
  unionData.data.spellDuration = unionData.data.spellDuration / spellCaster.spellCaster[1];
}

Поэтому в расчётах можно смело брать единицу (здесь идёт сравнение реальной длительности 1 и стандартной для заклинаний - сила_магии + артефакты_повышающие_длительность_заклинаний, а сила магии героя не может быть 0).

Соответственно, вот это тоже никогда не выполнится:

Код: Выделить всё
if ( (*&frenzyStack->info.flags & CF_DONE) != 0
  && (unionData.data.spellDuration = unionData.data.spellDuration - 1.0 / spellCaster.spellCaster[1],
      unionData.data.spellDuration < 0.0) )
{
  spellCaster.k = 0.0;
}

Например, для героя с силой магии 10 и без артефактов - здесь идёт повторное использование переменной, поэтому заменим на k - k = 1.0 - 1.0 / 10 = 0.9. Как видим, k не может быть 0. Стоп! При стандартной длительности 1 может! Но здесь есть ещё и первое условие, которое требует, чтобы отряд уже сделал свой ход. Нужно проверить, кастует ли Frenzy герой с силой магии 1 на походившие отряды (и кастует ли на такие отряды вообще) :!: По формулам выходит, что нет. Так, уже туплю, там же условие меньше 0.0, а этого не может быть.

Итого, вес Frenzy находится по формуле Weight(Frenzy) = [k * (sqrt(killedEnemyRatio) - 1)], где k = 1, если Frenzy кастуют до того, как отряд походил, и k = 1 - 1 / NormalSpellDuration, если после (не знаю, возможен ли в игре второй случай, но Frenzy может и на ответке сработать).

* * *
Судя по вот этому:

Код: Выделить всё
type_AI_combat_parameters::simulate_attack(&spellCaster.spellCaster[1]->attackValue, frenzyStack, &health, frenzyTarget, &targetHealth_0, aux.tmp, 0);

и сигнатуре функции:

Код: Выделить всё
public: void __cdecl type_AI_combat_parameters::simulate_attack(class army const &, long &, class army const &, long &, bool, long)const

можно сделать вывод, что type_AI_combat_parameters является частью структуры type_AI_spellcaster (оффсет 0x20). Есть мысли на этот счёт?

Текущая структура type_AI_combat_parameters:

Код: Выделить всё
#pragma pack(push, 4)
struct type_AI_combat_parameters
{
  int attack_modifier;
  int defense_modifier;
  char isOpponentDangerous;
  char isBattleSimulated;
  int casterTotalCombatValue;
  int enemyTotalCombatValue;
  int casterActiveStacksCombatValue;
  int enemyActiveStacksCombatValue;
  int dangerRating;
  int side[2];
};
#pragma pack(pop)

Cтруктура type_AI_spellcaster с 0x20 оффсета:

Код: Выделить всё
void *attackValue;
int defenseValue;
char IsFightValueCapped;
char field_29;
char field_2A;
char field_2B;
  ...

Тут, кстати, нужно исправить void* на int. attackValue и defenseValue - это атака и защита вражеского героя (как минимум в первом раунде, потом, может быть, модифицированные значения).

Более того, конструктор type_AI_combat_parameters вызывается первым делом в конструкторе type_AI_spellcaster:

Код: Выделить всё
type_AI_combat_parameters::type_AI_combat_parameters(&this->attackValue, CombatManager, side);

И тоже смещение 0x20.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 28 ноя 2021, 01:49

Ура, всё срастается!

Код: Выделить всё
#pragma pack(push, 1)
struct type_AI_combat_parameters
{
  int enemyHeroAttack;
  int enemyHeroDefense;
  char isOpponentDangerous;
  char isBattleSimulated;
  char field_A;
  char field_B;
  int casterTotalCombatValue;
  int enemyTotalCombatValue;
  int casterActiveStacksCombatValue;
  int enemyActiveStacksCombatValue;
  char dangerRating;
  char field_1B;
  char spellDuration;
  char field_1D;
  int side[2];
};
#pragma pack(pop)

Код: Выделить всё
#pragma pack(push, 1)
struct type_AI_spellcaster
{
  type_AI_spellcaster *(__thiscall **VMT)(void *, char);
  hero *hero[2];
  int side[2];
  int shootingThreats;
  int meleeThreats;
  bool destroyedOrWarMachine;
  bool isCreatureCast;
  char field_1E;
  char field_1F;
  type_AI_combat_parameters combatParams;
  type_AI_spellcaster *spellCaster;
  char done;
  char field_4D;
  char field_4E;
  char field_4F;
  AI_ArmyInfo AI_MeleeEnemy[20];
  AI_ArmyInfo AI_ShootingEnemy[20];
  AI_ArmyInfo AI_MostPowerfulEnemy[20];
};
#pragma pack(pop)

Выравнивание, скорее всего, 4 байта, но я для отлова багов 1 поставил.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 28 ноя 2021, 04:42

Было:
Код: Выделить всё
int __thiscall type_AI_spellcaster::get_mass_damage_effect(int this, signed int a2, signed int a3)
{
  signed int v5; // edx
  double v6; // st7
  float v7; // [esp+Ch] [ebp-4h]
  float v8; // [esp+18h] [ebp+8h]
  float v9; // [esp+18h] [ebp+8h]
  float v10; // [esp+1Ch] [ebp+Ch]

  if ( a2 <= 0 )
    return 0;
  v5 = a3;
  if ( a3 < 0 )
  {
    v5 = 0;
    a3 = 0;
  }
  if ( a2 <= v5 )
    return 0;
  v8 = a2;
  v7 = *(this + 48);
  v6 = v8 / v7;
  v10 = a3;
  v9 = *(this + 44);
  if ( v10 / v9 >= v6 )
    return 0;
  if ( v5 < *(this + 44) )
    return a2 - v5;
  return 0;

Стало:
Код: Выделить всё
int __thiscall type_AI_spellcaster::get_mass_damage_effect(
        type_AI_spellcaster *this,
        int damageToEnemies,
        int damageToAllies)
{
  int damageToAllies_1; // edx
  double k; // st7
  float enemyTotalCombatValue; // [esp+Ch] [ebp-4h]
  float damageToEnemies_1; // [esp+18h] [ebp+8h]
  float casterTotalCombatValue; // [esp+18h] [ebp+8h]
  float damageToAllies_2; // [esp+1Ch] [ebp+Ch]

  if ( damageToEnemies <= 0 )
    return 0;
  damageToAllies_1 = damageToAllies;
  if ( damageToAllies < 0 )
  {
    damageToAllies_1 = 0;
    damageToAllies = 0;
  }
  if ( damageToEnemies <= damageToAllies_1 )
    return 0;
  damageToEnemies_1 = damageToEnemies;
  enemyTotalCombatValue = this->combatParams.enemyTotalCombatValue;
  k = damageToEnemies_1 / enemyTotalCombatValue;
  damageToAllies_2 = damageToAllies;
  casterTotalCombatValue = this->combatParams.casterTotalCombatValue;
  if ( damageToAllies_2 / casterTotalCombatValue >= k )
    return 0;
  if ( damageToAllies_1 < this->combatParams.casterTotalCombatValue )
    return damageToEnemies - damageToAllies_1;
  return 0;
}

Сила - в правильных типах :smile1: Решил использовать маленькие буквы для полей структур, так как IDA автоматически назначает переменным имена полей структуры, а мне удобнее, когда локальные переменные начинаются с маленькой буквы.

Эту функцию можно смело красить в зелёный цвет. Даже словами нечего описывать. Прям шикарные формулы и автоматом :smile20:

Ещё одна, чуть побольше, но тоже хорошо читается:

Код: Выделить всё
int __thiscall type_AI_spellcaster::get_area_effect_value(
        type_AI_spellcaster *this,
        enum SpellID spell,
        int damage,
        enum TSkillMastery skillMastery,
        int hex)
{
  int damageToEnemies_1; // ebx
  _DWORD *First; // edx
  int armyNum; // eax
  int armyNum_1; // ecx
  int i; // eax
  int damage_value_ally; // eax
  int damage_value_enemy; // eax
  bool breakCondition; // cc
  int damageToAllies_1; // ecx
  int result; // ebx
  double k; // st7
  const struct army *targetArmy; // [esp-4h] [ebp-34h]
  vector armyVector; // [esp+Ch] [ebp-24h] BYREF
  int damageToAllies; // [esp+1Ch] [ebp-14h]
  int damageToEnemies; // [esp+20h] [ebp-10h]
  int v22; // [esp+2Ch] [ebp-4h]
  float enemyTotalCombatValue; // [esp+38h] [ebp+8h]
  int j; // [esp+40h] [ebp+10h]
  int damageToAllies_2; // [esp+40h] [ebp+10h]
  float damageToAllies_3; // [esp+40h] [ebp+10h]
  float damageToEnemies_2; // [esp+44h] [ebp+14h]
  float casterTotalCombatValue; // [esp+44h] [ebp+14h]

  damageToEnemies_1 = 0;
  damageToAllies = 0;
  damageToEnemies = 0;
  LOBYTE(armyVector.Allocator) = HIBYTE(skillMastery);
  memset(&armyVector.First, 0, 12);
  v22 = 0;
  combatManager::mark_area_effect(gpCombatManager, spell, hex, skillMastery, &armyVector);
  First = armyVector.First;
  if ( armyVector.First )
    armyNum = (armyVector.Last - armyVector.First) >> 2;
  else
    armyNum = 0;
  armyNum_1 = armyNum;
  i = armyNum - 1;
  j = i;
  if ( armyNum_1 > 0 )
  {
    while ( 1 )
    {
      targetArmy = First[i];
      if ( targetArmy->side == this->side[AI_CASTER] )
      {
        damage_value_ally = type_AI_spellcaster::get_damage_value(
                              this,
                              spell,
                              damage,
                              this->hero[AI_CASTER],
                              targetArmy);
        damageToAllies += damage_value_ally;
      }
      else
      {
        damage_value_enemy = type_AI_spellcaster::get_damage_value(
                               this,
                               spell,
                               damage,
                               this->hero[AI_ENEMY],
                               targetArmy);
        damageToEnemies += damage_value_enemy;
      }
      breakCondition = j <= 0;
      First = armyVector.First;
      --j;
      if ( breakCondition )
        break;
      i = j;
    }
    damageToEnemies_1 = damageToEnemies;
  }
  damageToAllies_1 = damageToAllies;
  damageToAllies_2 = damageToAllies;
  if ( damageToEnemies_1 > 0 )
  {
    if ( damageToAllies < 0 )
    {
      damageToAllies_1 = 0;
      damageToAllies_2 = 0;
    }
    if ( damageToEnemies_1 > damageToAllies_1 )
    {
      damageToEnemies_2 = damageToEnemies;
      enemyTotalCombatValue = this->combatParams.enemyTotalCombatValue;
      k = damageToEnemies_2 / enemyTotalCombatValue;
      damageToAllies_3 = damageToAllies_2;
      casterTotalCombatValue = this->combatParams.casterTotalCombatValue;
      if ( damageToAllies_3 / casterTotalCombatValue < k )
      {
        if ( damageToAllies_1 < this->combatParams.casterTotalCombatValue )
          result = damageToEnemies_1 - damageToAllies_1;
        else
          result = 0;
      }
      else
      {
        result = 0;
      }
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  operator delete(First);
  return result;
}


Привет, ещё одна разобранная функция. На этот раз Chain Lightning:

Код: Выделить всё
int __thiscall type_AI_spellcaster::get_chain_lightning_value(
        type_AI_spellcaster *this,
        int spellPower,
        TSkillMastery skillMastery,
        army *targetArmy)
{
  int targetsNum; // esi
  int damage; // edi
  int NextChainLightningTarget; // eax
  TSkillMastery damageToEnemies_1; // edx
  int damageToAllies_1; // ecx
  double k; // st7
  int damageToAllies; // [esp+Ch] [ebp-4h]
  int i; // [esp+18h] [ebp+8h]
  int damageToAllies_2; // [esp+18h] [ebp+8h]
  float casterTotalCombatValue; // [esp+18h] [ebp+8h]
  TSkillMastery damageToEnemies; // [esp+1Ch] [ebp+Ch]
  float damageToEnemies_2; // [esp+1Ch] [ebp+Ch]
  float damageToAllies_3; // [esp+1Ch] [ebp+Ch]
  float enemyTotalCombatValue; // [esp+20h] [ebp+10h]

  targetsNum = ChainLightningNumberOfTargets[skillMastery];
  damageToEnemies = 0;
  damageToAllies = 0;
  combatManager::ClearEffects(gpCombatManager);
  damage = spellPower * akSpelltraits[SPL_CHAIN_LIGHTNING].effPower
         + akSpelltraits[SPL_CHAIN_LIGHTNING].Effect[skillMastery];
  i = targetsNum - 1;
  if ( targetsNum )
  {
    do
    {
      if ( targetArmy->side == this->side[AI_CASTER] )
        damageToAllies += type_AI_spellcaster::get_damage_value(
                            this,
                            SPL_CHAIN_LIGHTNING,
                            damage,
                            this->hero[AI_CASTER],
                            targetArmy);
      else
        damageToEnemies += type_AI_spellcaster::get_damage_value(
                             this,
                             SPL_CHAIN_LIGHTNING,
                             damage,
                             this->hero[AI_ENEMY],
                             targetArmy);
      gpCombatManager->massSpellTarget[targetArmy->side][targetArmy->sideIndex] = 1;
      NextChainLightningTarget = combatManager::GetNextChainLightningTarget(gpCombatManager, targetArmy, 0);
      if ( NextChainLightningTarget < 0 )
        break;
      if ( NextChainLightningTarget >= 187 )
        break;
      targetArmy = hexcell::get_army(&gpCombatManager->squares[NextChainLightningTarget]);
      // Уменьшаем урон в два раза для следующей цели
      damage /= 2;
    }
    while ( i-- != 0 );
  }
  damageToEnemies_1 = damageToEnemies;
  damageToAllies_1 = damageToAllies;
  damageToAllies_2 = damageToAllies;
  if ( damageToEnemies <= 0 )
    return 0;
  if ( damageToAllies < 0 )
  {
    damageToAllies_1 = 0;
    damageToAllies_2 = 0;
  }
  if ( damageToEnemies <= damageToAllies_1 )
    return 0;
  damageToEnemies_2 = damageToEnemies;
  enemyTotalCombatValue = this->combatParams.enemyTotalCombatValue;
  k = damageToEnemies_2 / enemyTotalCombatValue;
  damageToAllies_3 = damageToAllies_2;
  casterTotalCombatValue = this->combatParams.casterTotalCombatValue;
  if ( damageToAllies_3 / casterTotalCombatValue >= k )
    return 0;
  if ( damageToAllies_1 < this->combatParams.casterTotalCombatValue )
    return damageToEnemies_1 - damageToAllies_1;
  return 0;
}

В принципе, я уже понял систему оценок.
Последний раз редактировалось AlexSpl 28 ноя 2021, 06:01, всего редактировалось 2 раз(а).
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 28 ноя 2021, 05:48

Великолепная работа, AlexSpl! Сказать даже нечего, во! IDA, конечно вещь в чем-то неудобная и недоработанная, но что поделать. Лишь писать разработчикам.

Каждый раз при завершении дневной работы, обновляйте, пожалуйста, базу на сервере... Я сегодня хочу на весь день базу занять и заняться восстановлением сигнатур на этот раз связанных нетолько с ИИ.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 28 ноя 2021, 06:10

Насчёт базы. Я немного переделал структуры, кое-что взял из кода RoseKavalier, где-то вместо оригинальных типов его типы, а где-то просто void*. Нужно закрыть эти моменты. Всё-таки неудобно кидаться базой :smile1: туда и обратно. Если б это была работа, было бы расписание. А так, каждый занимается в своё свободное время и по желанию. Не очень мне по душе идея попеременной работы. Нужен человек, который будет делать одну базу из разных. Тогда реально можно будет работать параллельно. Но кто ж согласится выполнять двойную работу? Была бы в IDA система дифференциалов. Поработал, скинул разницу. Вы применили эту разницу. Если нигде не пересеклись, то ОК, если да, то посмотрели ошибки и выбрали какой-то один вариант.
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 28 ноя 2021, 06:12

AlexSpl писал(а):

Насчёт базы. Я немного переделал структуры, кое-что взял из кода RoseKavalier, где-то вместо оригинальных типов его типы, а где-то просто void*. Нужно закрыть эти моменты. Всё-таки неудобно кидаться базой :smile1: туда и обратно. Если б это была работа, было бы расписание. А так, каждый занимается в своё свободное время и по желанию. Не очень мне по душе идея попеременной работы. Нужен человек, который будет делать одну базу из разных. Тогда реально можно будет работать параллельно. Но кто ж согласится выполнять двойную работу? Была бы в IDA система дифференциалов. Поработал, скинул разницу. Вы применили эту разницу. Если нигде не пересеклись, то ОК, если да, то посмотрели ошибки и выбрали какой-то один вариант.


Предлагаю бомбардировать электронную почту и форумы IDA на эту тему. Действительно неудобно работать поочередно, но по другому пока что никак. Так все же, вы сегодня будете работать над базой?
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 28 ноя 2021, 06:13

Цитата:
где-то вместо оригинальных типов его типы

Так лучше не делать.. Я наоборот сделал все возможное чтобы избежать типов RoseKavalier и чтобы было удобнее работать потом при переносе все в cpp/h файлы. Оригинальное имя типа соответствует оригинальному названию классов, меньше головной боли.

Если что, пишите просто typedef.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 28 ноя 2021, 06:19

Цитата:
Предлагаю бомбардировать электронную почту и форумы IDA на эту тему. Действительно неудобно работать поочередно, но по другому пока что никак. Так все же, вы сегодня будете работать над базой?

Конечно. Сегодня же выходной. В понедельник скину.

Цитата:
Так лучше не делать

Знаю, но либо Вы не полностью заполнили combatManager, либо он слетел. У меня после army army[2][21] образовался большущий gap, пришлось брать поля из H3API. Понятия не имею, как такое могло произойти, ведь я не менял структуру :smile5: Короче, случилась авария. Я позже сравню структуру с бэкапом базы и верну типы на место. А ещё я писал о названии полей. Я предлагаю называть с маленькой, т.к. IDA автоматически назначает имена полей структур локальным переменным, а они должны быть, как и аргументы функций, с маленькой буквы. Как Вы на это смотрите?
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 28 ноя 2021, 06:21

Цитата:
Знаю, но либо Вы не полностью заполнили combatManager

Да, я знаю. Моя вина и вина воговцев, которые на тот момент не до конца его изучили, база-то старая основная. Оставьте старый, просто скопируйте его поля из RoseKavalier-овского.
Последний раз редактировалось void_17 28 ноя 2021, 06:24, всего редактировалось 1 раз.
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 28 ноя 2021, 06:22

Цитата:
А ещё я писал о названии полей. Я предлагаю называть с маленькой, т.к. IDA автоматически назначает имена полей структур локальным переменным, а они должны быть, как и аргументы функций, с маленькой буквы. Как Вы на это смотрите?


Большая путаница, все получается одинаково выглядящим. Я думал делать так
 
, но в последнее время базой занимаетесь вы, поэтому не хотел вам мешать
:
поля с префиксом m_НазваниеПоля
аргументы с префиксом a_Аргумент
Локальные переменные без префикса строчные.

Также делали NWC.
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

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

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

cron