Current time: 17.09.2024, 00:29 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
Ошибки, баги и недочёты ERA
» crash logs / errors / bugs of era
Author Message
Berserker Offline
Administrators

Posts: 16623
Post: #811

Quote:Странный скрипт. Номер последнего города в WoG/ERA/ERA+ на карте всё время меняется, т.к. это не константа
Не нашёл ничего странного в скрипте. Порядок элементов массива городов ведь не меняется? Если меняется, то другой вопрос.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
22.08.2024 16:58
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #812

(22.08.2024 16:58)Berserker Wrote:  Порядок элементов массива городов ведь не меняется? Если меняется, то другой вопрос.

Порядок не меняется, меняется количество при добавлении новых городов на карту скриптами или кодом игры. Порядок городов тоже можно сменить если написать код, который будет удалять город с карты (соотвественно, часть или все города на карте получат новые ID).
22.08.2024 17:21
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16623
Post: #813

XEPOMAHT, ну так функция же принимает конкретный номер города аргументов, который может быть получен из координат города на карте. А проверка на невыход из максимального размера массива. Конечно, оптимально считывать поле Length вектора, если там вектор, но на худой конец наличие проверки лучше её отсутствия.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
23.08.2024 01:34
Find all posts by this user Quote this message in a reply
igrik Offline
Administrators

Posts: 2819
Post: #814

(22.08.2024 11:25)XEPOMAHT Wrote:  Странный скрипт. Номер последнего города в WoG/ERA/ERA+ на карте всё время меняется, т.к. это не константа. Тифон, к примеру, сначала проверяет возможную структуру на 0 (т.к. городов на карте может просто не быть), а затем вычисляет номер последнего города (на выходе будет 0, если скрптёр попытается получить структуру несуществующего города).

Непонятный кастыль. Зачем так через опу???

И да, прямой функции получения структуры города ни в WoG, ни в ERA+ нет просто потому что она не нужна, т.к. доступ к данным структуры города осуществляется по-разному (в основном это функции-циклы, проходящие стразу по структурам всех городов, а не конкретно одного, или, чаще, получение структуры прямо от координат на карте).
Чё за наезд на ровном месте?!
Причем здесь то, что номер последнего города меняется к тому что указано в этом коде? Херомант, ты нормально прочитал и понял код функции прежде чем в сотый раз жаловаться на неясное для тебя решение.
Второе - Если скриптер будет пытаться получать номер несуществующего города, то по правилам программирования нужно выкидывать исключение, а не возвращать структуру первого города. Как ты потом будешь отлаживать приложение? Как обнаружить такую ошибку? Ее нереально найти в большом приложении. За такие ходы тупо увольняют с работы, потому что это очень, очень подлый поступок!
Третье, под ERA+ ты сам должен подстраивать существующие скрипты, потому что ты очень много где сам модифицирует базовый код игры, поэтому будь добр и модифицируй скрипты тоже. Все твои новые плюшки невозможно прогнозировать, чтобы написать универсальный скрипт, который будет работать всегда и везде. Для этого ты слишком глубоко модифицирует логику игры

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


game bug fixes extended.dll || My Plugins || My GitHub
23.08.2024 10:09
Visit this user's website Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #815

(23.08.2024 01:34)Berserker Wrote:  А проверка на невыход из максимального размера массива.

Если считать максимальный размер массива на структуры городов, то получится 360*48 = 17280 байт. Скрипт же проверяет адрес памяти 43200000, что выглядит... странно. Автор скрипта никакого комментария по этому поводу не оставил, т.к. теоретически, игра может записать структуры городов куда угодно в выделенной виндовозом памяти.

(23.08.2024 01:34)Berserker Wrote:  Конечно, оптимально считывать поле Length вектора, если там вектор, но на худой конец наличие проверки лучше её отсутствия.

Оптимально - да, но в скрипте этого нет.

(23.08.2024 10:09)igrik Wrote:  ты нормально прочитал и понял код функции прежде чем в сотый раз жаловаться на неясное для тебя решение.

В том то и дело, что человек, который знает как получить структуру города из номера на карте, не может понять соотвествующий ERM-скрипт. Чёрная магия какая-то.

(23.08.2024 10:09)igrik Wrote:  Второе - Если скриптер будет пытаться получать номер несуществующего города, то по правилам программирования нужно выкидывать исключение, а не возвращать структуру первого города. Как ты потом будешь отлаживать приложение? Как обнаружить такую ошибку? Ее нереально найти в большом приложении. За такие ходы тупо увольняют с работы, потому что это очень, очень подлый поступок!

Если проверки на получение структуры города провалены, то функция возвращает 0 (по крайней мере в ВоГ-е так). В вышеприведённом примере на ERM фукция вернёт молоко, т.к. расчёт города по несуществующему индексу всё равно произойдёт и процесс выполнения ERM при этом остановлен не будет, хотя без проблем можно добавить новую ERM-команду, которая принудительно сбросит игру, например, в главное меню или на рабочий стол. Ну или вызывать собственно окно ERM-ошибки. В скрипте же используется обычный игровой ERM-Message (или опять ничего не понял я в ERM) без аварийного завершения игры.

(23.08.2024 10:09)igrik Wrote:  Третье, под ERA+ ты сам должен подстраивать существующие скрипты, потому что ты очень много где сам модифицирует базовый код игры, поэтому будь добр и модифицируй скрипты тоже. Все твои новые плюшки невозможно прогнозировать, чтобы написать универсальный скрипт, который будет работать всегда и везде. Для этого ты слишком глубоко модифицирует логику игры

Всё так, именно по-этому я отказался от поддерки всех существующих ERM-опций. Под ERA+ переписаны только самые любимые, многие встроены прямо в игру по примеру опций Славы Сальникова. Именно по-этому ERA+ никто не любит, т.к. под неё не работают моды от обычной ЭРЫ. В рамках ERA+ мною сделана максимальная совместимость с компонентами платформы ЭРА, точнее там где у меня получилось это сделать, но из-за использования команды UN:C многие эровские скрипты являются несовместимыми, т.к. UN:C часто будет выдавать неверный результат в глобальных модификациях с изменённым кодом игры. Меня одного не хватает, чтобы хотя бы довести ERA+ до финальной версии, не говоря о переписывании всех ERM-скриптов (их проще по-человечески переписать с 0 на lua, чем бесконечно латать, т.к. многие написаны криво).

(23.08.2024 10:09)igrik Wrote:  Берите, и переписывайте скрипты как сочтёте нужным сами. Все исходники и ресурсы у вас для этого есть

Увы, давно не пишу я на ERM, уже стал плохо понимать этот язык. Напреное пришла деменция ко мне.
23.08.2024 11:49
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #816

Ещё по-поводу ERA 3.9.15

Эта версия ЭРЫ не позволяет инициализировать сразу несколько ВоГ-диалогов, поэтому для ERA+ по-прежнему актуальной остаётся ERA 3.9.14.

В ERA 3.9.14 можно было из одного ВоГ-диалога инициализировать и открывать другой ВоГ-диалог без ограничений. В ERA 3.9.15 попытка двойной инициализации приводит к вылету:

Quote:Failed to write data at CA0F1A2.
EIP: Ntdll.30121. Code: C0000005

> Registers
EAX: Zvslib1.2F1A0 (int: 211874208, pint: 0x558B0638 = 1435174456)
ECX: 0000008B (int: 139)
EDX: H3era.0193A633 (int: 26453555, pint: 0x00000000)
EBX: 000077FE (int: 30718)
ESP: 00229C20 (int: 2268192, pint: 0x000076A3 = 30371)
EBP: 00229E3C (int: 2268732, pint: 0x00229E78 = 2268792)
ESI: 0C9D3198 (int: 211628440, pint: 0x00000003)
EDI: 0C9D31B0 (int: 211628464, pint: 0x000377FE = 227326)

> Callstack
H3era.0077F686
H3era.0077F6A8
Typhon.FA96
Typhon.6AB1
Era.89FDF
036F8997
H3era.0040561C
H3era.005FFACB
H3era.005FFA3D
H3era.0072921E
Typhon.952B
03088979
03088901
030A3E2C
03657C77
_hd3_.F535
03080068
Kernel32.123CD

> Stack
00229C0C: 00000000 (int: 0)
00229C10: 00000000 (int: 0)
00229C14: 00000000 (int: 0)
00229C18: 00000000 (int: 0)
00229C1C: 00000000 (int: 0)
00229C20*: 000076A3 (int: 30371)
00229C24: 0000000C (int: 12)
00229C28: 0022A03C (int: 2269244, pint: 0x00000200 = 512)
00229C2C: 0F180D60 (int: 253234528, pint: 0x0063D6B0 = 6543024)
00229C30: 00000000 (int: 0)
00229C34: 00000000 (int: 0)
00229C38: 0F0C1880 (int: 252450944, pint: 0x00643D5C = 6569308)
00229C3C: 00000000 (int: 0)
00229C40: 00000080 (int: 128)
00229C44: 00000014 (int: 20)
00229C48: 10060028 (int: 268828712, pint: 0x00000000)
00229C4C: 00000098 (int: 152)
00229C50: 00000078 (int: 120)
00229C54: 00000400 (int: 1024)
00229C58: 000002BC (int: 700)
00229C5C: 00001000 (int: 4096)
00229C60: 00000000 (int: 0)
00229C64: 00000001 (int: 1)
00229C68: 00000000 (int: 0)
00229C6C: 104F4018 (int: 273629208, pint: 0x00793B00 = 7944960)
00229C70: 00229C9C (int: 2268316, pint: 0x00229D0C = 2268428)
00229C74: 00229C88 (int: 2268296, pint: 0x00000014 = 20)
00229C78: 0000000E (int: 14)
00229C7C: 0C9D31B0 (int: 211628464, pint: 0x000377FE = 227326)
00229C80: 0000000F (int: 15)
00229C84: 00229CE0 (int: 2268384, pint: 0x0F180050 = 253231184)
00229C88: 00000014 (int: 20)
00229C8C: 0000000C (int: 12)
00229C90: 0F180D60 (int: 253234528, pint: 0x0063D6B0 = 6543024)
00229C94: 0000000E (int: 14)
00229C98: 00229CE0 (int: 2268384, pint: 0x0F180050 = 253231184)
00229C9C: 00229D0C (int: 2268428, pint: 0x0FE4E0D0 = 266658000)
00229CA0: Era.1C8F9 (int: 59361529, pint: 0x4B8D13EB = 1267536875)
00229CA4: 0C9D0178 (int: 211616120, pint: 0x0C9D0178 = 211616120)
00229CA8: Era.42C0 (int: 59261632, pint: 0x64FC458B = 1694254475)

Сам код инициализации вог-диалога следующий:

Code:
proc InitDialog
       push ebp
       mov ebp,esp
       push edi
       push 00Ch
       mov eax, 77D6B8h
       call eax
       pop ecx
       mov edi, eax
       push 0
       mov ecx, eax
       mov eax, 72B760h
       call eax
       push dword [ebp+0Ch]
       push dword [ebp+08h]
       mov ecx,eax
       mov eax, 729B27h
       call eax
       mov eax,edi
       pop edi
       leave
       retn 08h
endp

Что нужно поменять для совместимости с ERA 3.9.15 ???
23.08.2024 14:28
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16623
Post: #817

XEPOMAHT, изменилась работы с подсказками. Есть в коде выше установка подсказок (hints) элементам диалога?


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
23.08.2024 18:54
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #818

(23.08.2024 18:54)Berserker Wrote:  Есть в коде выше установка подсказок (hints) элементам диалога?

Нету. Хинты устанавливает воговский код согласно шаблону диалога - ячейка №12. Пример:

Code:
    F    95    40    40    128    20    GSPBUT2.def    Обзор городов    msmlfont.fnt    1    2    Кнопка

И да, воговские хинты с ERA 3.9.15 как раз и не работают на в одном воговском DL-диалоге.

Если это важно, ERA+ добавляет все моповские новведения для шаблонов DL-диалогов - кейс элементов воговских диалогов следующий:

Code:
кейс_DL = $
dd Расширение_DL_команд.Переходник_на_анимированный_DEF ; A - анимированный Def
dd Расширение_DL_команд.Переходник_на_кнопку ;72A200h ; B - обычная кнопка
dd Расширение_DL_команд.Переходник_на_DEF    ;72A007h ; D - Def
dd 72A895h ; E - Edit text - оставить воговский код, т.к. особо не используется
dd Расширение_DL_команд.Переходник_на_PCX    ;729E64h ; P - pcx-картинка
dd Расширение_DL_команд.Переходник_на_текст_с_прокруткой ;72A66Ah ; S - Scrolled Text
dd Расширение_DL_команд.Переходник_на_текст  ;72A3B1h ; T - Text
dd 72AA4Ch ; V - видео - оставить воговский код, т.к. особо не используется
dd 72AB2Bh ; ничего
dd Расширение_DL_команд.Переходник_на_кнопку_с_текстом ; F
dd Расширение_DL_команд.Переходник_на_список_с_прокруткой ; G

Но функцию-установщих воговских хинтов это вроде не затрагивает, т.к. оно - в самом конце портянки воговского конструктора диалога-из-шаблона, Тифон там ничего не меняет. По логу Патчера, эровский хук по адресу 72A1F6h не выполняется, но он не нужен, т.к. поддержка анимированных дефов реализована в Тифоне независимо от era.dll, остальные эровские хуки там срабатывают (если конечно они у тебя не скрытые от чужих глаз).

Так же Тифон позволяет убирать отрисовку рамки с элементом подсказки по параметру из шаблона DL-диалога и отрисовывать её в синий цвет, если диалог так же отрисовывается в синий - в обычной ЭРЕ таких возможностей нет, а ЭРЕ+ они были нужны позарез. Но там тоже пересечений с хуками ERA 3.9.15 лог патчера не показывает. Возможно, искать причину поломки работы подсказок в ERA 3.9.15 надо где-то глубже.

И ещё один важный момент: ERA+ УВЕЛИЧИВАЕТ ПАМЯТЬ ПОД DL-ДИАЛОГИ. Это тоже было портировано с MoP, сделано точно так же в MoP. Возможно, era.dll об этом не знает.
(This post was last modified: 23.08.2024 20:46 by XEPOMAHT.)
23.08.2024 19:40
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16623
Post: #819

Функция AddHint перехвачена по адресу 72986E
Теперь все подсказки хранятся в динамически выделяемой памяти. Подсказки освобождаются в деструкторе диалога в
72B897

Нужен простой мод-пример на ЕРМ с диалогом, если подсказки не работают. Я тестировал на примере Archer. Работало с DL:H всё, но не проверял, какие там подсказки из текстовика взяты.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
23.08.2024 23:03
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #820

(23.08.2024 23:03)Berserker Wrote:  Функция AddHint перехвачена по адресу 72986E

Если затереть этот хук, то подсказки начинают работать и следующая инициализация диалога работает без вылета.

(23.08.2024 23:03)Berserker Wrote:  Нужен простой мод-пример на ЕРМ с диалогом, если подсказки не работают. Я тестировал на примере Archer. Работало с DL:H всё, но не проверял, какие там подсказки из текстовика взяты.

В ERA+ нажмите кнопку строительства города, наведите на любой город, например на Причал, и посмотрите поле подсказки.

Image: image.jpg
24.08.2024 00:07
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16623
Post: #821

XEPOMAHT, у нас не выходит повторить вылеты на чистой Эре. Возможно, всё дело в других перехватах Эры+. Подсказки из txt без DL:H тоже отображаются корректно. Я сделал лишь две вещи: AddHint выделяет новую память под каждую подсказку, а ClearHints удаляет блок памяти каждой подсказки. Поэтому DL:H теперь позволяет назначить любую подсказку и после этого менять содержимое переменных без опасения порчи подсказок.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
24.08.2024 18:24
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #822

(24.08.2024 18:24)Berserker Wrote:  Возможно, всё дело в других перехватах Эры+.

Возможно, но где - найти я не могу.

(24.08.2024 18:24)Berserker Wrote:  Я сделал лишь две вещи: AddHint выделяет новую память под каждую подсказку, а ClearHints удаляет блок памяти каждой подсказки.

Нельзя ли посмотреть код, как это сделано в era.dll? Вполне возможно, что era.dll просто не может выделить память (у меня её не много), а потом пытается выгружать несуществующую, из-за чего и вылетает.
24.08.2024 20:22
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16623
Post: #823

Code:
function Hook_ZvsDlg_AddHint_Assign (Context: ApiJack.PHookContext): longbool; stdcall;
var
{Un} DlgLink:     Heroes.PWogDialogLink;
     ItemId:      integer;
     ItemHintInd: integer;
     OldHint:     pchar;
     NewHint:     pchar;
     NewHintCopy: pchar;
     NewHintSize: integer;

begin
  DlgLink     := ppointer(Context.EBP - 12)^;
  ItemId      := pinteger(Context.EBP + 8)^;
  NewHint     := ppointer(Context.EBP + 12)^;
  ItemHintInd := pinteger(Context.EBP - 4)^;
  OldHint     := DlgLink.Dlg.Hints[ItemHintInd].Text;
  NewHintSize := Windows.LStrLen(NewHint) + Length(#0);

  if OldHint <> nil then begin
    Heroes.MemFreeAndNil(OldHint);
  end;

  NewHintCopy := Heroes.MemAlloc(NewHintSize);
  Utils.CopyMem(NewHintSize, NewHint, NewHintCopy);

  DlgLink.Dlg.Hints[ItemHintInd].ItemId := ItemId;
  DlgLink.Dlg.Hints[ItemHintInd].Text   := NewHintCopy;

  Context.RetAddr := Ptr($72989C);
  result          := false;
end;

function Hook_ZvsDlg_Delete_FreeHints (Context: ApiJack.PHookContext): longbool; stdcall;
var
  DlgLink: Heroes.PWogDialogLink;
  i:       integer;

begin
  DlgLink := ppointer(Context.EBP - 16)^;

  for i := 0 to DlgLink.Dlg.NumItems - 1 do begin
    Heroes.MemFreeAndNil(DlgLink.Dlg.Hints[i].Text);
  end;

  result := true;
end;

(* Force WoG dialog to make hint copy during hint assignment *)
ApiJack.Hook(Ptr($72986E), @Hook_ZvsDlg_AddHint_Assign);

(* Disable DL:H item hint interpolation during call to HDlg::GetHint *)
Core.p.WriteDataPatch(Ptr($729916), ['90909090909090909090909090909090909090']);

(* Force WoG dialog to free allocated hints memory on dialog destruction *)
ApiJack.Hook(Ptr($72B897), @Hook_ZvsDlg_Delete_FreeHints);


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
25.08.2024 01:13
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2328
Post: #824

(25.08.2024 01:13)Berserker Wrote:      if OldHint <> nil then begin
    Heroes.MemFreeAndNil(OldHint);
    end;

    NewHintCopy := Heroes.MemAlloc(NewHintSize);
    Utils.CopyMem(NewHintSize, NewHint, NewHintCopy);

    DlgLink.Dlg.Hints[ItemHintInd].ItemId := ItemId;
    DlgLink.Dlg.Hints[ItemHintInd].Text := NewHintCopy;

Тут наверное не должно быть подмены на нулевую строку.

Code:
if NewHint <> nil then begin // если нет подменного хинта - не затирать предыдущий
  if OldHint <> nil then begin
    Heroes.MemFreeAndNil(OldHint);
  end;

  NewHintCopy := Heroes.MemAlloc(NewHintSize);
  Utils.CopyMem(NewHintSize, NewHint, NewHintCopy);

  DlgLink.Dlg.Hints[ItemHintInd].ItemId := ItemId;
  DlgLink.Dlg.Hints[ItemHintInd].Text   := NewHintCopy;
end;
25.08.2024 02:32
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16623
Post: #825

По идее пустые подсказки (нулевой адрес) вообще не должны быть. В коде вога проверка:

if(hint[0]!=0) AddHint(iid,hint);

А в DL:H попадёт пустая строка (#0), но не нулевой адрес. Ты передаёшь нулевой? Я тогда сделаю нулевой адрес аналогом #0.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
25.08.2024 06:03
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2024 MyBB Group