Перейти к содержанию

Text.dll 2025 (мой неоффициальный апдейт на современный лад)


Рекомендуемые сообщения

1 минуту назад, ksteel сказал:

Да, я согласен с вами полностью прогресс не должен вредить совместимости н ив коем случае, но что делать, допустим, с 4гб патчем? MCP находит в заголовке Morrowind.exe (PE header) специальное поле «Характеристики» и вписывает в него флаг 0x0020 (IMAGE_FILE_LARGE_ADDRESS_AWARE), говоря Windows: «Этому приложению можно доверять, позволь ему видеть больше памяти». Таким образом даются 4 ГБ памяти. И всё, это потолок. Но если сделать 8 ГБ памяти тем же путём что и MGE XE, только на уровне движка, а не со стороны внешнего органа MGE XE?

4 гб патч не влияет напрямую на работу именно игровой логики, скрипты диалоги квесты работают в не зависимости от объема памяти.
Если сможете заставить использовать больше и при этом не вылетать, то да проще дать рекомендацию ру пользователям не отмечать в MCP фикс 4гб.
 

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 118
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

7 минут назад, Pirate443 сказал:

4 гб патч не влияет напрямую на работу именно игровой логики, скрипты диалоги квесты работают в не зависимости от объема памяти.
Если сможете заставить использовать больше и при этом не вылетать, то да проще дать рекомендацию ру пользователям не отмечать в MCP фикс 4гб.
 

Вот я о том же. Я не буду переносить из MCP такие мелкие фиксы как "широкое меню, фикс карты для TR и т.д."- это мелкие правки, в сравнении будто я переношу мелкую правочку из esp в esm, хотя правочка и так работает идеально. Для сохранения совместимости и универсальности надо перенести более глобальные и общие масштабные фиксы. Начнём с малого с MCP, через MGE (вообще прикрутить рендер DX9-11 нафиг 😄 ) к большему - MWSE.

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

7 минут назад, ksteel сказал:

 Начнём с малого с MCP, через MGE (вообще прикрутить рендер DX9-11 нафиг 😄 ) к большему - MWSE.

Ну тогда лучше всего начинать с фиксов которые mcp вносит в text.dll, что бы модифицированный файл в полной мере заменял предыдущее решение, а не ставил пользователя перед выбором или или.

Ссылка на комментарий
Поделиться на другие сайты

10 минут назад, Pirate443 сказал:

Ну тогда лучше всего начинать с фиксов которые mcp вносит в text.dll, что бы модифицированный файл в полной мере заменял предыдущее решение, а не ставил пользователя перед выбором или или.

Этим я сейчас и занимаюсь =)

Ссылка на комментарий
Поделиться на другие сайты

Уважаемые форумчане! Что удалось выяснить на данный момент. 

MCP устанавливает патч в 2 этапа:
 

1. MCP сверяет ХЭШ Morrowind.exe, таким образом выбирается версия игры (хэш оригинальной русской версии от 1с ecb347304134f63cabf1ab38f0728dcff5fbfb11e7ac2b87a03c8639936ab094), в этой папке и лежит файл patch для .exe, а также 3 папки, в каждой их которых лежат патчи для 3‑х версий text.dll: оригинальная 48 кб, от Angel Death v.3.01 170 кб и ещё непонятная какая-то версия text.dll, которую, скорее всего, в жизни никто не видел или не использовал).
 

2. MCP сверяет ХЭШ text.dll, таким образом он внутри папки ecb347304134f63cabf1ab38f0728dcff5fbfb11e7ac2b87a03c8639936ab094 находит вторую папку e8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8, в названии которой установлен ХЭШ text.dll, откуда он берёт свои патчи для этой text.dll).

3. Я сравнил все 3 версии патча для разных версий text.dll (смотрел через HEX редактор Visual Studio Code):

  • нашу общеиспользуемуюe8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8image.png.368df6c7f5e1bd1cb3b9dc4b3ce7cb68.png
  • первую отличную от нашей общеиспользуемой: 23c36ef153f5b183fc13d06ef339d9356c0da6b30a90aa7359baedce2135f036 image.png.ac9fa9b0262ff52285078a02b586d62b.png
  • вторую отличную от нашей общеиспользуемой: f027a20356e788cf1a48d6f89f8b11eb61b34dda2fecb6fab59a74e3dae3f83aimage.png.1a2a90bc525c4a08318846a5c09a46ff.png

Как вы сами можете увидеть, две другие версии вносят:

  • а) немного другие правки в сам text.dll
  • б) вносят больше правок в text.dll, что намекает о старых версиях text.dll (скорее всего версии 3.00 и ниже).

Вывод: т.к. версия text.dll 3.01 не менялась внутренне структурно (что мы также выяснили в этой теме), то патч из вышеуказанной папки e8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8 как раз и влияет на text.dll. Собственно к анализу этого патча от MCP я и приступаю, буду смотреть что он вносит или что модифицирует.
 

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

Цитата

Многие моды сделаны из рассчета MCP, если фикс будет вносится иным способом не факт что мод корректно заработает.

В мсп есть 2 типа правок.
- БагФИксы (все флаги выбраны по умолчанию).
- хотелки и улучшайзеры.
Первые это фикс очевидных косяков, вторые, навроде камеры за плечом, хотелки.
Т.е. переносить очевидные багфиксы в "хардкод" дело Справедливое по определению.
И как вариант, в дальнейшем, связаться с Двемером согласовав с ним этот момент. Дабы МСП учитывало правленный техтДлл и не правило уже поправленное.
А еще, сделать свой билд МСП (пока Двемера нету на месте). Нечто подобное, было проделано с МГЕ 19ой версии.


А "улучшайзеры" они сами по себе, конечно переносить камеру за плечо прямо в код, не всем будет симпатично.

Ссылка на комментарий
Поделиться на другие сайты

 

4 часа назад, ksteel сказал:

Уважаемые форумчане! Что удалось выяснить на данный момент. 

MCP устанавливает патч в 2 этапа:
 

1. MCP сверяет ХЭШ Morrowind.exe, таким образом выбирается версия игры (хэш оригинальной русской версии от 1с ecb347304134f63cabf1ab38f0728dcff5fbfb11e7ac2b87a03c8639936ab094), в этой папке и лежит файл patch для .exe, а также 3 папки, в каждой их которых лежат патчи для 3‑х версий text.dll: оригинальная 48 кб, от Angel Death v.3.01 170 кб и ещё непонятная какая-то версия text.dll, которую, скорее всего, в жизни никто не видел или не использовал).
 

2. MCP сверяет ХЭШ text.dll, таким образом он внутри папки ecb347304134f63cabf1ab38f0728dcff5fbfb11e7ac2b87a03c8639936ab094 находит вторую папку e8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8, в названии которой установлен ХЭШ text.dll, откуда он берёт свои патчи для этой text.dll).

3. Я сравнил все 3 версии патча для разных версий text.dll (смотрел через HEX редактор Visual Studio Code):

  • нашу общеиспользуемуюe8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8image.png.368df6c7f5e1bd1cb3b9dc4b3ce7cb68.png
  • первую отличную от нашей общеиспользуемой: 23c36ef153f5b183fc13d06ef339d9356c0da6b30a90aa7359baedce2135f036 image.png.ac9fa9b0262ff52285078a02b586d62b.png
  • вторую отличную от нашей общеиспользуемой: f027a20356e788cf1a48d6f89f8b11eb61b34dda2fecb6fab59a74e3dae3f83aimage.png.1a2a90bc525c4a08318846a5c09a46ff.png

Как вы сами можете увидеть, две другие версии вносят:

  • а) немного другие правки в сам text.dll
  • б) вносят больше правок в text.dll, что намекает о старых версиях text.dll (скорее всего версии 3.00 и ниже).

Вывод: т.к. версия text.dll 3.01 не менялась внутренне структурно (что мы также выяснили в этой теме), то патч из вышеуказанной папки e8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8 как раз и влияет на text.dll. Собственно к анализу этого патча от MCP я и приступаю, буду смотреть что он вносит или что модифицирует.
 

Что я выяснил про MCP:

MCP меняет системные переменные CRT:

  • __commode - режим ввода/вывода
  • __fmode - режим работы с файлами
  • __umaskval - маска прав доступа

image.png.daf846d3ca02bf8587af8b7cd329b691.png

Пока мой Text.dll разрабатывается, его хэш постоянно меняется. Если разрешить MCP патчить мой text.dll (у которого уже съехали все байты в сторону от преобразования), то MCP попросту сломает text.dll.

Что это может вызвать?

  • а) проблемы с кодировками
  • б) сшибки ввода/вывода
  • в) в целом разные странности с файловыми операциями


Я хочу узнать : для чего MCP патчит text.dll? 
Далее либо я сам внесу правки в text.dll, либо добавлю совместимость с МСР, посмотрю какой вариант будет универсальнее (учитывая темпы разработки, лучше конечно самому сделать то что хочет сделать МСР, тем не менее MCP патчит нормально Morrowind.exe). 

У dll до патчинга и после патчинга (как показал Hex Workshop Hex Editor) Идеальные не тронутые внутренности. Они светятся оба зелёным и различий нет (проверено на обеих версиях отсюда https://www.fullrest.ru/files/russian_text_input/files😞image.thumb.png.6eb023622d0b6e2bdf84f87e84a9c1f4.png

НО хэш меняется:
image.png.32996470cebf51633b8dabf2a085d51e.png

Что это за магия ВНЕ Хогвартса, я пока НЕ понимаю.
Но судя по байтам из патча MCP он ставит на text.dll какую-то заглушку.

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

Хм.

Ёж, а Хрнчамд совсем пропал с радаров? Или его можно выцепить в личке где-нибудь в Дискорде?

Ссылка на комментарий
Поделиться на другие сайты

Итак. Мои предположения (если изменить подход) патч меняет какую-то конкретную функцию по адресу 0x0C90 - заменяет её на заглушку B8 AF 88 56 38 C3:

1. Предположение № 1: При рассмотрении text.map 0x0C90 я не нашёл. Значит 0х0С90 находится между функциями:
"0x0c60 - ??0bad_array_new_length@std@@QAE@ABV01@@Z" и "0x0ca0 - ??0bad_array_new_length@std@@QAE@XZ"      
Я прихожу к выводу, что это внутренняя, скрытая функция C++ рантайма и MCP меняет внутреннюю логику C++ рантайма, а не игровые функции, это системный патч для совместимости со старым движком Morrowind (возможно) с моим text.dll морровинд запускается, MCP патчит экзешник. Проще говоря в рантайме Morrowind вызывает эту внутреннюю функцию C++ после чего MCP заглушает её, чтобы изменить поведение при ошибках памяти. А учитывая проделанный мною рефакторинг - все изначальные возможные переполнения я уже убрал, когда фиксил overload консоли. О чём расскажу в п.2 ниже.

2. Предположение № 2 (более сложное): Если посмотреть с третьей стороны 0x0C90 в text.map я не нашёл, значит она может попасть МЕЖДУ соседними функциями, смотрим text.map:image.png.b9429d18709e119a21ba494ff4d9dc4d.png
Что это такое? Это тот же самый DialogEngine.cpp который просто из глиняного сырого кирпичика превратился в обожженный кирпич для стройки всего text.dll.

  • Цель: ??0bad_array_new_length@std@@QAE@XZ
  • Расшифровка (Demangled Name): public: __thiscall std::bad_array_new_length::bad_array_new_length(void)
  • Конструктор по умолчанию для исключения std::bad_array_new_length

А теперь по русски: в этом случае патч так-же не бьёт по игровой логике. Он вмешивается в запросы Morrowind.exe к рантайму C++.

Так что это за функция? std::bad_array_new_lengthэто исключение, которое выбрасывается, когда программа пытается выделить массив недопустимого (например, отрицательного или слишком большого) размера. 

Что делает MCP патч? Как я установил ранее, патч заменяет начало этой функции на команду "немедленно вернуться". Он предотвращает создание и выброс исключения.

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

А теперь конкретика ядро той самой нестабильности, тот самый пациент DialogEngine.cpp. В нём была одна такая весёленькая функция под названием void InitFileLists( )И выглядела она вот так:

Спойлер

image.png.c9bfcf07b4e8d00f0fc60c9e92638ab8.png

Вот как эта, казалось бы, простая конструкция превращается в бомбу замедленного действия, способную вызвать то самое исключение std::bad_array_new_length:

  1. Бесконечный цикл: Цикл for ( int i = 0;; i++ ) — это вечный двигатель. Он будет работать до тех пор, пока его принудительно не остановят.
  2. Слепое доверие: Остановка происходит, когда функция GetPrivateProfileString не находит в Morrowind.ini очередной ключ (GameFile0, GameFile1, GameFile5,... GameFileN) и возвращает 0. Код полностью доверяет тому, что файл Morrowind.ini корректен и что эта последовательность когда-нибудь прервётся и будет чёткой НЕ НАРУШЕННОЙ.
  3. Сценарий катастрофы: А теперь представьте, что Morrowind.ini повреждён: другой мод, или сам пользователь по ошибке добавил туда запись вида GameFile214742=some_file.esp, следом сразу(а лучше ещё через 15 пустых строк) GameFile2147483647=some_file.esp. (знаю, что число модов ограничено, это я утрирую).
  • Цикл будет послушно перебирать миллионы и миллиарды несуществующих ключей, прежде чем дойдёт до этого аномально высокого номера.
  • Счётчик i (целое 32-битное число) в какой-то момент достигнет своего предела (2,147,483,647) и переполнится, обернувшись в отрицательное число (-2,147,483,648).
  • Цикл не остановится! Он продолжит работать, теперь уже в отрицательном диапазоне.

      4. Взрыв вектора: В это время gamefilelist.push_back( fname ) продолжает добавлять элементы. Вектор gamefilelist будет постоянно расти, требуя всё больше и больше памяти. При каждом удвоении своего размера он вычисляет новую ёмкость. В условиях, когда счётчик i ведёт себя непредсказуемо, внутренние механизмы вектора могут попытаться вычислить новый размер, который окажется недопустимо огромным или отрицательным.

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

Но хватит страшных сказок, хочу вас успокоить, в версии 3.01.1 я уже исправил этот недочёт, ещё на момент когда фиксил консоль от переполнения буфера. Вот как выглядит DialogEngine.cpp:

Спойлер

image.png.4601301708c096976fbd28dfdf9eefd4.png



Всё ясно, понятно и главное безопасно. НО это всего лишь моё предположение № 2 про то что патчит MCP в text.dll.

В любом случае MCP пропустит мой dll и не навредит ему, т.к. данный ХЭШ ему НЕ ИЗВЕСТЕН. Модификации text.dll будут работать, игра будет работать.
П.с. если я пойму логику фикса и он НЕ БУДЕТ избыточным - я её добавлю в text.dll, он там будет по умолчанию.

На этом спасибо за внимание.

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, Марк К. Марцелл сказал:

Хм.

Ёж, а Хрнчамд совсем пропал с радаров? Или его можно выцепить в личке где-нибудь в Дискорде?

Заодно узнать про другие патчи, какие байты меняются какими патчами в morrowind.exe для успешного переноса на уровень ядра =)

upd добавил в шапку темы частые вопросы по проекту.

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

10 часов назад, Марк К. Марцелл сказал:

Хм.

Ёж, а Хрнчамд совсем пропал с радаров? Или его можно выцепить в личке где-нибудь в Дискорде?

У него "график" (прослеживается).
Появляется, где-то в конце января - феврале и сидит до середины лета.

Затем исчезает до следующего февраля.
Хотя пару раз пропадал на пару лет, но в целом, лет 10 так,  отмечается подобный распорядок.
А так, в ЛС он отвечает и на посты отписывается, но только когда есть на месте.  ))

Изменено пользователем EJ-12
Ссылка на комментарий
Поделиться на другие сайты

6 часов назад, EJ-12 сказал:

У него "график" (прослеживается).
Появляется, где-то в конце января - феврале и сидит до середины лета.

Затем исчезает до следующего февраля.
Хотя пару раз пропадал на пару лет, но в целом, лет 10 так,  отмечается подобный распорядок.
А так, в ЛС он отвечает и на посты отписывается, но только когда есть на месте.  ))

Для пользователей, которые подумали о неком "тупике" для разработки (пока не появится товарищ Hrnchmad). Я прошу вас не расстраиваться, ведь это не тупик, а время чтобы отладить мою версию 3.01.1! Прогресс это конечно хорошо, быстрый прогресс - ещё лучше. Но надо давать прорасти зернышкам и собрать хлеб, прежде чем сеять новые зерна ;-)

Во первых - ввести логирование всех органов text.dll, с выносом параметра в angel.ini:

EnableLogConsole = 1, EnebleLogMorrTextDLL = 1, EnableLogHelperFunctions = 1

И так далее. То есть прямое медицинское наблюдение text.dll и всех его органов.

А во-вторых, пока ответ по патчам MCP не получен, у меня есть время для маленького безумства - научить Morrowind кодировке UTF-8 хе-хе.

Ну и не забываем про подготовку "глобального обновления", скриншот которого я кидал раннее..

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Доброго времени суток уважаемые форумчане! 

Хочу поделиться с вами о проделанной работе. (в основном это обновление будет касаться самой структуры text.dll, исключения ошибок при компиляции, разработки text.dll. Но также будут и нововведения (о чем расскажу ниже).

1. Обновление CMakeLists.txt. Был наведён порядок, добавлены комментарии к каждому пункту.

Старый CMakeLists.txt:

Спойлер

image.png.8bd8ee9f1cf8f17770f0d185e03504f8.png

Новый CMakeLists.txt:

Спойлер

image.thumb.png.dbba0908580cc2421952aa382cab8d9b.png

image.thumb.png.325dcaad8a326a013f40a684f9a292ab.png

Как вы можете заметить - была проведена колоссальная работа.

  • Были указаны прямые пути компилятору для поиска заголовочных файлов.
  • Файлы .cpp были разбиты на модули (какие-то были вообще созданы с нуля).
  • Подключены новые библиотеки: а) библиотека, что использует оригинальный движок - d3d8(найти было не просто 😃 ); б) библиотека для перехвата - minhook (об этой библиотеке можете почитать здесь https://github.com/TsudaKageyu/minhook ). 
  • Были убраны макросы из старого Visual Code

2. Был отредактирован morr_text_dll.rc (для избежания ошибок компиляции):

Старый morr_text_dll.rc:

Спойлер

image.thumb.png.9fe32aa5b9e64f4697d244785e37e8dc.png

Новый morr_text_dll.rc:

Спойлер

image.thumb.png.11f6ebfa3f21489c3d90b54c47a98425.png

И тут изменения сразу заметны - убраны старые макросы, исключены варианты перебора "if", теперь dll сама просто понимает какие ресурсы игры может подхватывать.

3. Был отредактирован заголовочный файл resource.h (resource.h вообще переехал из главной папки ко всем заголовочным файлам в папку include). 

Старый resouce.h:

Спойлер

image.png.467a673a3590cd993a8544cdea3eaf0f.png

Новый resource.h:

Спойлер

image.png.1846d25e40f3e6270d9745d38bafc7d1.png

Также была проведена очистка от старых макросов, добавление комментариев.

4. Был отредактирован заголовочный файл stdafx.h:

Старый вариант stdafx.h:

Спойлер

image.png.b73495def213a0bfe722bb37a3142fbc.png

Новый stdafx.h:

Спойлер

image.thumb.png.569d0f1f284c08e0e97faecb41d55e76.png

image.png.c948d5a6e602f6163b9f3c6cf8d3e219.png

Теперь stdafx.h действительно главный заголовочный файл всего проекта.

--------------------------------------------------------

Теперь перейду к изменениям самих .сpp файлов, их расположения и структуры всего проекта.

1. Изменение структуры проекта:

Было : 

Спойлер

image.thumb.png.35caa136324d489e4aaf919d03d1ca8b.png

Стало (задержите дыхание (с) Михаил Задорнов):

Спойлер

image.thumb.png.0fa93ddbc435c9994c27b64b8d31e972.png

image.thumb.png.b92f67f12551069349145db427f20820.png

image.thumb.png.e1e1b6f41e142e523ddaee2623e9113a.png

image.thumb.png.b56faf040cc34a6667fa47d05a90de5c.png

image.thumb.png.7e335cec67b55e1db800db795e71fc9d.png

image.thumb.png.50a56d30a133ebf7088ac09cd299a4f0.png

Был наведён порядок в файлах проекта в целом. Оригинальные патчи и локализация были перенесены в папку 0AngelOriginalPatches (туда же я засунул фикс по сообщениям при повышении уровня).

----------------------------------------------------

Основные изменения коснулись файлов DialogEngine.cpp, HelperFunctions.cpp и Console.cpp. Была полностью сохранена оригинальная логика файлов. Они были просто разбиты на модули — из монолита в отдельные лёгкие файлы, которые позволяют вносить в них изменения отдельно, не рискуя работоспособностью других файлов.

2. А теперь по каждому модифицированному файлу отдельно:

2.1 DialogEngine.cpp (движок диалогов), DictStr.cpp (словарь), Topic.cpp (система топиков).
 

Спойлер

Расположение: src\0AngelOriginalPatches\0DialogSystem

В них осталась только оригинальная логика того что они должны делать. А вот то как они это должны делать было вынесено в отдельные файлы-модули в папки \src\0AngelOriginalPatches\0DialogSystem\DataLoaders и  \src\0AngelOriginalPatches\0DialogSystem\DialogEngine.

Содержимое папки \src\0AngelOriginalPatches\0DialogSystem\DataLoaders:

image.png.10edadcc656401d24b723401c3bec3d8.png

Из названий понятно для чего нужен какой инструмент. Также были переведены "все сообщения об ошибках" на русский язык. Пример:

Спойлер

image.thumb.png.e6c56ed8028477c021c6fee1d307eeb3.png

Содержимое папки \src\0AngelOriginalPatches\0DialogSystem\DialogEngine:

image.png.2c300b118adbcb56d51f6fec5a833015.png

Мухи отдельно, котлеты отдельно (с) Ангел. Инструменты для самого движка диалогов.

Результат разбиения диалоговой системы: раньше DialogEngine.cpp, Topic.cpp и DictStr.cpp были жестко завязаны между собой, и завязаны на русском языке, т.к. знали каждый о существовании друг друга. Теперь мало того, что о существовании всех трёх файлов знает только главный DialogEngine.cpp, теперь они не завязаны на русском языке, т.е. можно внедрить любой другой язык, который страдает от кодировки cp1251, либо загрузки файлов .mrk .cell и т.д. Можно просто добавлять новые языки (правильным образом — внося константы в сам DialogEngine.cpp) и DialogEngine.cpp будет с ними работать.

Это зачаточная реализация. Позже надо будет реализовать переключатель по языку внутри файлов перевода, что позволит переводить моды сразу на несколько языков. Т.е. поддержка 1 esp - несколько языков, без танцев с бубнами. Как это сделаю, сообщения об ошибках надо будет так-же сделать мльтиязычными.

----------------------------------------------------------

2.2 Console.cpp - главный дирижер консоли. Файл также был разбит на модули. Оригинальная логика сохранена, мой фикс по переполнению буфера сохранён. 

Расположение: файл Console.cpp остался в главной папке /src/, вся его логика была перенесена в папку \src\1ConsoleEngine:

image.png.312d5bd1dd5cf52ef142e1f8c3df9750.png

ConsoleEngine.cpp - создает логику работы расширения консоли оригинальной игры.

В папке ConsoleCommand теперь лежит реестр команд ConsoleCommands.cpp:

Спойлер

image.png.8c61d37e6a6d89aec572c1710b55ac4e.png

и каждая команда в отдельном файле:

image.png.b578f9cfe1e7b628f457833990ccb995.png

Также теперь в игре, при введении какой-либо команды из расширения консоли от Angel - выводится подробная справка:

  • версия text.dll и дата его сборки
  • для чего эта команда
  • какие доступные значения для этой команды
  • пример, как использовать эту команду
  • какое значение сейчас установлено
Спойлер

Screenshot_2.thumb.png.b8cde8437e8b2e1fedf6fd860e9c1d1c.png

ВНИМАНИЕ!!! text.dll из-за ограничения "вывода номера версии" не поддерживает множественные номера версий. Т.е. он пишет номер версии 3.01, хотя по факту это 3.01.2. Я пока думаю как реализовать нормальный показ версии.

image.thumb.png.2d1c612fb1a4d07f31da105c54624a00.png

-------------------------------------------------------------------------

2.3 HelperFunctions.cpp разбит на модули. Этот файл БОЛЬШЕ НЕ СУЩЕСТВУЕТ В ЕГО ИЗНАЧАЛЬНОМ ВИДЕ. Вместо него созданы отдельные файлы по принципу 1 файл - 1 функция (1 инструмент-хелпер). Сделано это для того, чтобы не загружать "лишними инструментами" память.

Реализация: была создана папка для функций-инструментов всего text.dll: \src\2HelperFunctions:

Спойлер

image.png.90b69fed31984425f822f4a9c371d142.png

  • ByteFiller.cpp - функция FillBytes
  • CodeInterceptor.cpp - функция Intercept
  • CodeReplacer.cpp - функция ReplaceCode
  • DWordWriter.cpp - функция PutDWord
  • MemoryReader.cpp - функция SafeReadMemory
  • SafeMemCopy.cpp - функция  newmemcpy
  • WordWriter.cpp - функция PutWord

Новые функции — инструменты:

  • AngelLogger.cpp - логирование (в разработке, расскажу ниже)
  • ErrorUtils.cpp - вывод ошибок в логи (в разработке, расскажу ниже)
  • MorrowindEngineDiagnostic.cpp - диагностика движка (в разработке, расскажу ниже)
  • MorrowindEngineNotCriticalWarnings.cpp - некритические ошибки (в разработке, расскажу ниже)

Результат разбиение HelperFunctions.cpp - можно загружать отдельный инструмент — функцию в нужный .cpp файл, не мусоря в памяти игры лишним переполнением не нужных функций в этом .cpp файле.

-----------------------------------------------------------

real-time система мониторинга Morrowind.exe (в разработке)

Новая папка \src\3EngineHealthMonitorSystem со следующим содержимым:

image.thumb.png.892d246d88633fbc8599a31d07ddf45b.png

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

Данная система разрабатывается для того чтобы:

  • у разработчиков модов был инструмент, который будет отслеживать то, как игра ведёт себя с их новым модом и т.д.
  • у пользователей (тестеров модов) были логи, которые они смогут отправлять разработчикам.
  • для выявления ошибок оригинального движка Morrowind.exe и дальнейших его фиксов.

Как с этим работать?

Для этого в Angel.ini были добавлены следующие блоки:

image.png.6bac51557c9e8a664eef3e4caaa64fee.png

0 - выключить, 1 - включить.

Важно понимать, что данные мониторы ещё находятся в разработке и настройке.

Для того чтобы включить что-то из блока [DeepScanner] - необходимо полностью включить [Morrowind Engine Diagnostic System]. Не забудьте также о самом переключателе Enable=0 ! Такая двухступенчатая активация сделана специально, чтобы кто-либо случайно не нагрузил систему лишним мониторингом.

Я НАСТОЯТЕЛЬНО НЕ РЕКОМЕНДУЮ включать больше 1-2 мониторов (если у вас слабенький ПК) из раздела DeepScanner!

Что будет при включении мониторинга? 

На том же уровне, где находится text.dll будет:

  • создан файл 00_text_dll_first_light.log в котором будет вестись логирование по самому взаимодействию Morrowind.exe и text.dll:
Спойлер

image.png.349f63db30ae1742c195195732b3abff.png

со следующим содержимым:

image.png.117610cd767d4b574414808bc714eac1.png

Просто показывает что всё успешно. Если на каком-то этапе произойдёт сбой запуска системы мониторов или какое-то нарушение взаимодействия с text.dll, это будет здесь описано. 

  • На том же уровне, где находится сам text.dll создастся папка "text_DLL"

 image.png.78a7b9c44eef42f0709bad16dd2c4800.png 

в которой будет дочерняя папка image.png.8eb0210c696a9e5d92147e50d708fe8b.png

 Т.е. все логи мониторинговой системы будут находится по пути: \Morrowind\text_DLL\text_DLL_logs и логи не будут захламлять основную папку с игрой.

Содержимое папки text_DLL_logs будет зависеть от того какие модули вы подключили. Вот пример содержимого папки со всеми включенными модулями:

Спойлер

image.png.d2fb970263d3283c9e7eb166a897f562.png

(как вы можете увидеть log_FileSystemMonitor_cpp.txt самый тяжелый, в нём очень много информации, т.к. сейчас я работаю конкретно над настройкой FileSystemMonitor.cpp. (А ведь я только запустил игру, загрузил сохранение и провел в ней 10 секунд. С учетом того, что персонаж только создан и находится в Сейда Нин, на улице около Фаргота)).

Теперь о каждом файле и мониторе из папок \src\2HelperFunctions и \src\3EngineHealthMonitorSystem подробнее. Какой смысл каждого файла, задача, что в целом файл должен будет делать после настройки:

Начну с папки \src\2HelperFunctions, а именно файлы AngelLogger.cpp, MorrowindEngineDiagnostic.cpp и MorrowindEngineNotCriticalWarnings.cpp.

  • AngelLogger.cpp — "Центральный Диспетчер", ядро системы логирования. Он выполняет двойную роль: записывает донесения в локальные журналы для каждого модуля и одновременно отправляет копию каждого события в центральный  журнал "Пророка" (О системе "Пророк" расскажу отдельно😞

          1.  Производительность и Безопасность: Вместо буфера на стеке AngelLogger использует динамический std::vector размером 16КБ. Это предотвращает переполнение стека при логировании очень больших объёмов данных и повышает общую стабильность системы мониторинга.

          2.  Интеграция с "Пророком": Функция теперь создаёт структуру LogEvent и отправляет её в EventStream с помощью AddEventToStream(), питая "мозг" нашего Сканера данными.

          3.  Безопасность (Post-check😞SecureZeroMemory для очистки буфера после использования.

          4.  Отладка: Сообщения теперь также выводятся в отладочную консоль Windows (OutputDebugStringA), что позволяет видеть логи в реальном времени, не открывая файлы (да-да открыли консоль windows и играете в realtime).

  • MorrowindEngineDiagnostic.cpp - специализированный инструмент, который вызывается CrashDumpSystem в момент сбоя для создания быстрого, читаемого отчёта о "причине смерти процесса Morrowind.exe": 

          1.  Собирает улики: Получает код исключения, адрес и модуль сбоя.

          2.  Ставит диагноз: Расшифровывает код исключения, предоставляя детальную информацию (например, для EXCEPTION_ACCESS_VIOLATION указывает тип операции и адрес).

          3.  Делает "снимок мозга": Записывает состояние всех регистров процессора в момент сбоя.

          4.  Вызывает "Нейросканер" (система "Пророк"): Вызывает GetStackTrace() для получения полной и понятной истории вызовов, приведшей к сбою.

  •  

    MorrowindEngineNotCriticalWarnings.cpp наш "Монитор Здоровья", пассивный "слушатель", неинвазивный мониторинг. Он перехватывает все сообщения, которые игра сама решает отправить в свою консоль или в виде всплывающего окна (субтитры, окошки warning), и логирует их. 

    Angel_ConsolePrintf_Hook / Angel_PopupPrint_Hook  - две функции-"шпионы".  Они перехватывают вызовы, записывают сообщение в наш лог-файл, а затем вызывают оригинальную функцию, чтобы игра продолжила работать как обычно.

    InitNotCriticalWarnings - Функция-инициализатор. Она устанавливает хуки путём прямой подмены указателей на функции, адреса которых мы получаем из "Анатомического атласа (в разработке, требует дополнений и настройки)".

  • ErrorUtils.cpp - "Системный Переводчик". Его единственная задача — превращать непонятные числовые коды ошибок Windows в читаемый человеком текст. Функция использует системный вызов FormatMessageA, чтобы запросить у самой Windows официальное описание кода ошибки. Если по какой-то причине это не удаётся, она предоставляет резервный вариант, просто печатая числовой код ошибки.

 

 

Далее перейдём к основной системе мониторинга \src\3EngineHealthMonitorSystem 

Ядро (папка \src\3EngineHealthMonitorSystem\Core):

 

  • CoreScanner.cpp"Системный Интегратор" или "Мозг" всего "Глубинного Сканера". Он является главным дирижёром, который "пробуждает" и "усыпляет" всю систему. Его задачи: прочитать конфигурацию, подготовить "хирургический набор" (`MinHook`) и последовательно запустить все активные модули-мониторы.

          Коротко об архитектуре функции InitCoreScanner:

          1.  Чтение конфигурации: Считывает все флаги из секции [DeepScanner] в angel.ini и сохраняет их в глобальную структуру g_scannerConfig.

          2.  Инициализация "Памяти": в правильной последовательности вызывает InitEventStream() перед инициализацией MinHook, гарантируя, что система логирования будет готова с самого начала.

          3.  Инициализация "Хирургии": Вызывает MH_Initialize() для подготовки нашего "набора мониторов".

          4.  Запуск модулей: Последовательно, основываясь на флагах из g_scannerConfig, "пробуждает" каждый дочерний модуль, вызывая его Init...() функцию.

          Коротко об архитектуре функции ShutdownCoreScanner

          1.  Отключение модулей: Сначала "усыпляет" все дочерние модули (Shutdown...()).

          2.  Деинициализация "Хирургии": Затем отключает MinHook (MH_Uninitialize()), что безопасно снимает все хуки.

          3.  Очистка "Памяти": В самом конце вызывает ShutdownEventStream(), чтобы очистить "Летопись (логи)" и освободить ресурсы.

  • EventStream.cpp - "Хранитель Летописи (виртуального логгирования)", защищённая "Память системы Пророк". Его единственная задача — безопасно (потокобезопасно) принимать и хранить "ленту событий" (`LogEvent`) от всех модулей Сканера, защищая её от хаоса многопоточности. volatile bool флаг, чтобы AngelLogger не пытался отправлять события в "Летопись" до того, как она будет полностью готова. Это протокол безопасности, предотвращающий гонку потоков при запуске. Правильно создаёт 'замок' (InitializeCriticalSection) и в самом конце устанавливает флаг g_eventStreamInitialized = true, сигнализируя всей системе, что Память готова к работе и приёму логирования. Функция сначала "закрывает" доступ к "летописи" (EnterCriticalSection), затем добавляет запись и немедленно "открывает" доступ (LeaveCriticalSection). Это гарантирует, что два потока никогда не смогут повредить "память". Во время выхода из игры корректно и безопасно очищает 'летопись' и уничтожает 'замок' (DeleteCriticalSection), освобождая все системные ресурсы.

 

 

Модули анализа и диагностики (в разработке, требуют дальнейшей настройки) (папка \src\3EngineHealthMonitorSystem\Modules_analysis_and_diagnostics):

  • ConflictReporter.cpp - (часть системы Пророк) его задача взять готовую "Карту Конфликтов", проанализировать её и сгенерировать финальный, читаемый человеком отчёт.
  • CorrelationEngine.cpp - ядро "Пророка"- дирижёр, "мозг" "мониторинговой нейросети". Он не выполняет анализ сам, а лишь запускает и останавливает своих узкоспециализированных помощников, которые анализируют: карту конфликов в скриптах, подключенных esp, загрузке файлов, создании(рендеринге) окружения, звуков и прочего.

  • CrashDumpSystem.cpp - местный "Патологоанатом". Он является главным и единственным обработчиком критических сбоев игры. В момент "смерти" Morrowind.exe (пациента 😄 ) он берёт на себя управление, чтобы сохранить все улики краша игры. 

          1.  Вызов "Парамедика": Первым делом вызывает GenerateTextualCrashReport() для создания быстрого текстового отчёта.

          2.  Создание дампа: Затем приступает к основной задаче — созданию полного "слепка души" (.dmp) с помощью MiniDumpWriteDump.

  • EspParser.cppсамый сложный специалист, отвечающий за "вскрытие" и анализ бинарной структуры .esp и .esm файлов.

          Реализация бинарного парсера:

          1.  Валидация: Корректно читает и проверяет заголовок TES3.

          2.  Итерация: В цикле читает заголовки всех записей (RecordHeader).

          3.  Поиск ID: Для целевых типов записей (Armor, Clothing, NPC и так далее) ищет подзапись NAME и извлекает из неё ID объекта.

          4.  Безопасность: проверка if (subRecSize > recData.size()), которая защищает парсер от вылета при анализе повреждённых модов.

  • IniReader.cpp -  "Чтец", специалист по .ini файлам. Его единственная задача — прочитать секцию [Game Files] из Morrowind.ini и вернуть точный порядок загрузки плагинов. 

  • ModConflictAnalyzer.cpp - "Архивариус"-дирижёр. Координирует действия своих узкоспециализированных помощников для анализа конфликтов модов. 

         Архитектура :

          1.  Приказ "Чтецу": Вызывает ReadMorrowindIni() для получения порядка загрузки.

          2.  Приказ "Парсеру": В цикле вызывает ParseEspFile() для каждого мода, собирая результаты в локальную conflictMap.

          3.  Приказ "Аналитику": Передаёт собранную карту GenerateConflictReport() для создания финального отчёта.

  • PatternMatcher.cpp - специалист системы "Пророк" по поиску известных паттернов ошибок, которые уже случались на данном ПК. Функция, выполняемая в фоновом потоке.

  • StackTracer.cpp - "Нейросканер". Это диагностический инструмент, который превращает "сырые" адреса памяти из стека вызовов в понятную, читаемую человеком "историю" событий, приведших к сбою. 

          1.  Инициализация: Корректно инициализирует библиотеку DbgHelp с помощью SymInitialize.

          2.  Проход по стеку: Использует StackWalk64 для итерации по каждому кадру стека вызовов, от места сбоя "вверх" по цепочке событий. Ограничение в 100 кадров — решение для предотвращения зависаний при анализе повреждённого стека.

          3.  Расшифровка: Для каждого кадра пытается получить имя функции (SymFromAddr) и, если возможно, имя файла и номер строки (SymGetLineFromAddr64).

          4.  Очистка: Корректно освобождает ресурсы с помощью SymCleanup

  • TemporalAnalyzer.cpp — "Аналитик Ритма", специалист "Пророка" по поиску "каскада ошибок". Это второй "нейронный центр" системы "Пророк". Задача - выявлять последовательность ошибок, предупреждать о возможности появления новых ошибок из "пережитого опыта прошлых ошибок". Пример: в прошлую сессию, спустя 4 минуты 32 секунды вылезла ошибка *такая то*, в тот момент в памяти игры были те-то данные. Сейчас в памяти игры подгружаются похожие данные, снова вылезла та самая первая ошибка, скорее всего вылезут следующие ошибки, из-за повторения причиной может быть такие процессы в памяти игры, логирую их. И т.д.

 

 

Специализированные модули, которые будут мониторить отдельные участки в памяти игры (папка \src\3EngineHealthMonitorSystem\Modules_organs) (в разработке, требуется настройка😞

  • AudioMonitor.cpp - "Отоларинголог", специализированный "слуховой" орган. Он внедряется в аудиосистему игры, перехватывая создание объекта DirectSound для диагностики проблем со звуком. 
  • FileSystemMonitor.cpp - "Разведчик", самый важный "орган чувств" нашего Сканера. Он перехватывает все обращения игры к файловой системе - папкам и файлам в структуре папок и файлов внутри игры (все текстуры, нифы, бса архивы и т.д.), обращения к Windows, создание - чтение (CreateFileA, ReadFileA и так далее), позволяя нам "слышать" каждую попытку загрузить ресурс и фиксировать ошибки, связанные с отсутствующими файлами, поврежденными ресурсами.
  • GraphicsMonitor.cpp - "Оптический Нерв". Он внедряется в графический конвейер игры, перехватывая самую первую функцию создания объекта DirectX.
  • MemoryMonitor.cpp - "Монитор Дыхания". Он следит за тем, как игра "дышит", перехватывая ключевые функции управления памятью, чтобы отслеживать выделение и освобождение ресурсов, утечек памяти, проблемы в памяти процесса Morrowind.
  • ModelMonitor.cpp - стоит заглушка. В будущем станет инспектором по "nif" файлам, выявляя и показывая ошибки, что именно не может обработать Morrowind
  • PhysicsMonitor.cpp - стоит заглушка. В будущем станет инспектором по коллизиям и физике, выявляя и показывая ошибки, что именно не может обработать Morrowind
  • ScriptMonitor.cpp - стоит заглушка. В будущем станет инспектором по скриптам, выявляя и показывая ошибки, что именно не может обработать Morrowind
  • TextureMonitor.cpp - стоит заглушка. В будущем станет инспектором по текстурам, выявляя и показывая ошибки, что именно не может обработать Morrowind

 

ПОДВЕДЕНИЕ ИТОГА: Работа идёт полным ходом, Проведена тотальная ревизия, рефакторинг "монолитных" больших файлов, положено начало мониторингу здоровья процесса Morrowind.

Для теста (по обычаю) прикладываю:

  • скомпелированный text.dll,
  • angel.ini(в архиве с text.dll),
  • morrowind.ini (не изменялся, в архиве с text.dll)
  • исходники text.dll.

 И да, text.dll заметно потяжелел ~ на 120 КБ. Сейчас он весит ~361 КБ

 

 

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

и на последок (на сегодня) БОНУС АПДЕЙТ: теперь, если какой-либо создатель мода по ошибке в локализации напишет букву Ё, то конечный пользователь вместо кракозябр на экране увидит читаемый текст, просто вместо буквы Ё в слове будет буква Е!

Я долго и муторно пытался научить Морровинд букве "Ё". 

Это было чем-то похоже, когда я пытался исправить слепое пятно со знаком номер "", но сложнее.
Вместо маленькой ё - Морровинд упорно писал , (запятую).
Вместо большой Ё - Морровинд упорно писал " (двойные верхние кавычки).

Я понимаю, что случайные ошибки с буквой "Ё" в файлах локализации могут довольно-таки сильно раздражать локализаторов (создателей модов), потому вот что было сделано: 

1. Для начала ради теста введено в одну из команд консоли явное наличие буквы Ё:
image.png.80e3e93b79add6de34f5d8017f58ce52.png

Что писало мне в игре, при введении этой команды раньше:

image.png.4933b3fcc2dd98c2d24d849f57d385d4.png

Довольно грустно 😞 .

Итак, что я сделал. Вместо обычной буквы Ё, я заставил Морровинд использовать букву Ё с диакритическим знаком (или просто Е).

В файл Topic.cpp был добавлен следующий блок кода:
 

Спойлер

image.thumb.png.2989b6ea67da7d1a0296f5b50e093cb4.png

В файл DictStr.cpp тоже добавил такое же преобразование:

Спойлер

image.png.d49e72ae1647ff55304cf935915f88cf.png

После данных манипуляций и колдовства я получил вот такое сообщение в консоли:
image.png.615d472d228f7f9f8bae084681513360.png

притом, что в файле Priority.cpp до сих пор написано вот так:

image.png.5bd60079c849125e3c7ef709ed86ff50.png

Теперь с этим text.dll даже если создатель мода забудется и начёт везде писать букву Ё, то она нормально преобразуется в букву Е на вашем экране!

Вот собственно скомпилированный text.dll и его исходники. версия 3.01.2 от 27.10.2025 с уже модульной архитектурой и начальной системой мониторинга.

(исходники) morr_text_dll-master-v_3.01.2_modules_structure_add_logging.zip text_dll_v_3.01.2.zip

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

Ну ничего себе! Я, конечно, в этих ваших перехватах функций не разбираюсь, но, судя по общему тону - здесь заявка на серъёзный инструмент диагностики и, возможно, управления.

Ссылка на комментарий
Поделиться на другие сайты

15 часов назад, Марк К. Марцелл сказал:

Ну ничего себе! Я, конечно, в этих ваших перехватах функций не разбираюсь, но, судя по общему тону - здесь заявка на серъёзный инструмент диагностики и, возможно, управления.

Вы уловили самую суть x)

Ссылка на комментарий
Поделиться на другие сайты

ДОБРЫЙ ДЕНЬ! Уважаемые форумчане!

Хочу вам рассказать о проделанной работе за эту неделю:

  1. ФИКС БАГОВ НЕКОНТРОЛИРУЕМОГО ЛОГИРОВАНИЯ.

Что было выявлено:

При установке Enable=0 в секции [DeepScanner] файла angel.ini, система мониторинга продолжала создавать логи:

  • eventstream_direct.log
  • log_CoreScanner_cpp.txt

Причина: Инициализация подсистем логирования происходила ДО проверки главного флага Enable, что делало настройки неэффективными.

Какие файлы были изменены:

  • CoreScannerDefines.h - структура конфигурации
  • CoreScanner.cpp - главный координатор системы
  • EventStream.cpp - система хранения событий
  • AngelLogger.cpp - универсальный логгер

Цели изменения: 

  • Архитектурная цель: Создать четкую иерархию управления, где все подсистемы подчиняются единому главному выключателю.
  • Практическая цель: Полностью отключать все логи мониторинга при Enable=0, сохраняя при этом работоспособность основных логов text.dll.

Что конкретно было внесено:

  • Немаловажное изменение в Angel.ini. Строка Enable=1 была переименована в enableScanner=1 для исключения путаницы в будущем!
Спойлер

image.png.434833c9b14f7cb3c605779c3e8b6081.png

  • CoreScannerDefines.h добавлен главный переключатель под новым именем enableScanner.
Спойлер

image.png.58efcc374a7cd24eec65631b5c7ab0cf.png

  • CoreScanner.cpp переименовано Enable → enableScanner. Проверка условия перемещена в самое начало файла:

Спойлер

image.png.49dca1af95c3a7818b14f2fe960397a1.png

  • EventStream.cpp добавлены отсутствующие проверки условий на каждый уровень записи:

Спойлер

image.png.cf8f0cc2384bea0cb233fcf706e0470c.pngimage.png.3b1c99d29752e88a24c6a3b04adc3b1a.png

  • AngelLogger.cpp - введена интеллектуальная фильтрация. Разделение логов мониторинга и системных логов. Проще говоря, данный инструмент логирования теперь понимает и отличает логи системы мониторинга от логов, которые необходимы для отладки самой text.dll (лог 00_text_dll_first_light.log на уровне с text.dll и Morrowind.exe нормально создается при выключенной системе мониторинга в Angel.ini)

Спойлер

image.png.9d1ec7c603c26e1f3a34bea3c1e37b31.png

image.png.1898a5038fe30a1be6ade3d72a6d082d.png

Результат фикса - Система работает как швейцарские часы:

  • при enableScanner=1 ведётся обычный мониторинг 
  • при enableScanner=0 - абсолютная тишина, никаких лишних файлов в папке (нагрузки на систему).
  • Логи text.dll - работают всегда для отладки моих изменений в структуре самой dll (в релизе я их убираю)
  • Логи мониторинга — только по команде
  • полное послушание и контроль систем 😃 

 

НО, я бы даже не написал сегодня на форуме, если бы не другое масштабное обновление. На оформление следующего сообщения мне потребуется немного больше времени (да и не хочу я перегружать одно сообщение несколькими обновлениями, так что ждите, через пару часов новый пост, где уже будут прикреплены файлы и исходники).

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

Собственно я продолжаю. Далее речь пойдём вот о чём. TEXT.DLL в СТИМЕ БЫТЬ! :О 

(сначала немного теории, реализацию покажу в конце)

Цель: Создать универсальный text.dll, который будет работать как с русской версией от 1с, так и с международной версией Morrowind GOTY (steam).

Как выполнено: добавлен флаг EnableRussianLocalization=0/1 в angel.ini, он будет централизованно управлять всей русскоязычной подсистемой.

Новые горизонты: англоязычные пользователи (или те кто пытается играть на английском) смогут тестировать DLL без конфликтов с подгрузкой файлов .top .cell .mrk

Точки вмешательства: 

  • Инициализация - пропустить загрузку словарей если флаг = 0
  • Патчинг памяти - не применять русскоязычные хуки
  • Сортировка - отключить кириллический алфавит

Т.е. превратить text.dll в билингвальный (во какое слово 😃).

Итак, с инструктажем закончил, перехожу к наглядным (наскальным) рисункам:

1. первый "пациент" Angel.ini:

Введена строка EnableRussianLocalization=0/1 тот самый переключатель русской локали. 

image.thumb.png.a1e9ca782cd0a78e970b99129512863b.png

Также в целом все комментарии в Angel.ini были переведены на английский язык дублирующей строкой. НО чтобы не раздувать сильно Основное тело "включателей" вся справка по DeepScanner переехала в конец файла:

Основной блок с выключателями:

Спойлер

image.thumb.png.f7caf3d957b254d0734bc12c4dafb9bc.png

Справка (после блока выключателей):

Спойлер

image.thumb.png.43b784477391a884a434d6700e1f8b22.png

image.thumb.png.eb8cef7c08ed4e50dbcd704c6eab1200.png

2. Второй "пациент" - файл include/Headers_0DialogSystem/DialogEngineMaster.h. В нём был объявлен наш переключатель локали. 

image.png.bb5340b5894471cf46d8960143a8ed8d.png

3. Третий "пациент" - файл src/0AngelOriginalPatches/0DialogSystem/1DialogEngine/DialogEngineCore.cpp. Добавил условия подключения инструментов-загрузчиков LoadCellData, LoadTopicData, LoadMarkTopicData. При отключенном флаге русской локали данные инструменты просто НЕ загружаются. Также обратите внимание на шаг 2.2 - Патчи и хуки не применяются в этом случае к процессу Morrowind.exe при отключенном флаге русской локали.

Спойлер

image.png.71b9090997dd4f03793e90258031e8a6.png

В этом уже идёт вся прелесть модульной архитектуры и прошедшего рефакторинга! Благодаря им мне не нужно  модифицировать MemoryPatcher.cpp, AlphavitEngine.cpp, DictStr.cpp или любой другой из "Загрузчиков"! Достаточно поставить одну перемычку и произойдёт каскадное отключение русской локали!

4. Четвертый "пациент" - файл src/morr_text_dll.cpp. Добавлен наш флаг и строчка, которая будет сообщать в лог-файл 00_text_dll_first_light.log (на уровне с Morrowind.exe и text.dll) в каком режиме запущен Morrowind.exe (с какой локалью).

Спойлер

image.png.62bdaf4c9077f6496afc64779476cc13.png

image.png.b10ef657ba9886c8665fbeeee645a1c5.png

image.png.0d58a057716f2dd2ff3c845d5be1948a.png

 

И вот вроде бы всё хорошо, русская локаль может быть включена или выключена, ура.....но чего-то не хватает, смекаете? (с) Капитан Джек Воробей. И вы молодцы, если так. Дальше я продолжил колдовать с консолью и командами, а точнее справкой к командам расширения консоли.

Но как не загрязнять код всякими if | else, этими миллиардами условий и выводить отдельно:

  • сообщения на английском языке при отключении русской локали
  • сообщения на русском языке при включении русской локали?
  • Правильно! МАКРОС!

И в этом опять поможет модульная архитектура. Достаточно вписать макрос в один файлик и по паутине через stdafx.h о нём узнает вся консоль, её движок, её команды! И все файлы, где есть русский текст об ошибках, логах!

5. Пятый "пациент" - файл include/Headers_1ConsoleEngine/ConsoleEngine.h. Вот он наш "золотой" билингвик-макрос.

Спойлер

image.png.a34c24d0aec66b976fbde8aa0c604052.png

Просто и со вкусом ру / ен.

Ну, а дальше пошла (мочавода по трубам, буду просто перечислять файлы, где был применён билингвик-макрос и прикладывать скриншот:

5.1 Файл src/1ConsoleEngine/ConsoleCommand/VersionCommand.cpp

Спойлер

image.thumb.png.8bc7975a5266322f2a442f7b42c4485b.png

5.2 Файл src/1ConsoleEngine/ConsoleCommand/PriorityCommand.cpp (и да я вернул нормальное слово "изменён" вместо "изменёЁёЁёЁн" 😄Хотя, наверное, как исторический момент принятия Морровиндом буквы "Ё", можно было бы оставить, как напоминание):

Спойлер

image.thumb.png.0281638e5ba00ceb796fffd52dd81d2c.png

5.3 Файл src/1ConsoleEngine/ConsoleCommand/DumpCommand.cpp

Спойлер

image.thumb.png.8e15a0b82b65f81b872d1efc3777ce15.png

image.png.f96580fb569c7ceb3bf770455ce018e5.png

image.png.6852e1860477d7ffe963a2f7db2c8523.png

5.4 Файл src/1ConsoleEngine/ConsoleCommand/FPSCommand.cpp:
 

Спойлер

image.png.177a7625f4a6bbb71b7b3551efc2bc05.png

image.png.d9b6fd18e759082db1a3bee04b418cee.png

Вроде бы всё....но нет, давайте оживим "мёртвый код" Angel Death.

И вот о чём я говорю: обратите внимание на старый реестр команд 

src/1ConsoleEngine/ConsoleCommand/ConsoleCommands.cpp:

Спойлер

image.png.cbe25d45725e4b2002991302db55ff86.png

Вы когда-нибудь видели эти строки-справки в консоли? Нет, а знаете почему? Потому что в блоке команды .help был сломанный цикл:

Спойлер

image.png.bcaed327029f07a9d161f508a21af817.png

Перевожу на понятный язык: 

  • текст находится в поле szUsage (Описание)
  • команда help в своём цикле читает только поле szName (первую строчку, имя команды)
  • szUsage никогда не используется и не выводится в консоль. Это был "мёртвый код" или "артефакт", если хотите.

Что ж, давайте оживим этот артефакт прошлого, и сделаем то — что хотел сделать Angel Death, а именно при вводе команды .help будет выводиться не только список команд, но и короткая справка по командам. Но мы немножко усовершенствуем этот механизм.

 

Я не стал придумывать велосипед. У меня уже есть билингвик-макрос, который прекрасно работает. Вместо сломанного цикла я обрезал реестр команд, в нём осталась только логика: 

Спойлер

image.png.be549ac3f7dfdc6486f0dc22ab40b8cc.png

То, к чему я постоянно стремлюсь - ничего лиш-не-го.

А все пояснения я перенёс в команду .help. Теперь хэлп - действительно ХЭЛП! Встречайте файл src/1ConsoleEngine/ConsoleCommand/HelpCommand.cpp:

Спойлер

image.thumb.png.f7d5309719bb11a627f101065abc498d.png

Билингвик-макрос + идея Angel Death. Красота! Также я написал явное пояснение, что команду можно ввести пустой (без значения) и получить подробную справку по команде.

Думаете всё? Ан-нет, не всё. А как-же смена раскладки? Зачем она нужна при игре на английском языке? иероглифы в игре писать? Давайте и её "подрежем"!

Файл src/0AngelOriginalPatches/mw_input.cpp. Добавлено условие по смене локали:

Спойлер

image.png.0806dc91182761b74373ae161d5daf6e.png

image.png.e3d18b38da4a32df5bc047ef621e354e.png

ИТОГ: text.dll работает в двух языках - английский, русский!

Скриншоты консоли (у меня установлено два морровинда обычный 1с и GOTY в Steam):

GOTY версия с EnableRussianLocalization=0 (в angel.ini):

Спойлер

image.thumb.png.df42d83123d712b300f51ca96f5f453b.png

1c версия с EnableRussianLocalization=1 (в angel.ini):

Спойлер

image.thumb.png.d5fc20e7f616ddddefa5160a1c82df87.png

И вот, теперь text.dll полностью готов к работе в стим библиотеке! 

Вопрос: как добавить этот text.dll в стим версию?

Ответ: необходимо проделать несколько шагов и путей.

  • Путь а) без подключения оверлея СТИМ
  • Путь б) с подключением оверлея СТИМ.

Рассмотрим оба "путя" 😄 

Путь А) без подключения оверлея СТИМ:

  1. В папке стим версии заархивировать оригинальный Morrowind.exe
  2. Скопировать из папки версии 1с четыре файла : Morrowind.exe, text.dll, angel.ini, morrowind.ini
  3. Поместить скопированные файлы версии 1с в папку стим версии с заменой.
  4. Выставить в angel.ini на ноль значение строки EnableRussianLocalization=1 (<--вот эту единичку на 0 поменять)
  5. Вы молодец! Играйте!

Путь Б) с подключением оверлея СТИМ (немного сложнее).

  1. В папке стим версии заархивировать оригинальные Morrowind.exe и Morrowind Launcher.exe
  2. Переименовать оригинальный стимовский лаунчер, в Morrowind Launcher Original.exe (необязательно именно так назвать, можно выбрать другое имя, главное чтобы вы понимали, что это оригинальный лаунчер из стима)
  3. Оригинальный стимовский Morrowind.exe из папки можно удалить (он не пригодится, главное сохраните его в архиве, на всякий случай, мало-ли).
  4. Скопировать из папки версии 1с четыре файла : Morrowind.exe, text.dll, angel.ini, morrowind.ini
  5. Поместить скопированные файлы версии 1с в папку стим версии
  6. Выставить в angel.ini на ноль значение строки EnableRussianLocalization=1 (<--вот эту единичку на 0 поменять)
  7. ЕСЛИ ВЫ ИСПОЛЬЗУЕТЕ МСP (MGE), ТО СЕЙЧАС САМОЕ ВРЕМЯ ИХ ЗАПУСТИТЬ! ЧТОБЫ ОНИ ПРОПАТЧИЛИ ВАШ МОРРОВИНД.EXE ОТ 1с в папке стима!!!
  8. Переименовать скопированный в папку стим Morrowind.exe в Morrowind Launcher.exe (ОБЯЗАТЕЛЬНО И ИМЕННО ТАК! Morrowind Launcher.exe !!)
  9. Вы молодец! Прошли более сложный путь! Можете запускать игру через стим! Играйте!

И не включайте русскую локализацию в стимовской версии, игра просто не запустится.

Если хотите полностью русскую версию в стиме, то тогда копируйте всю папку data files с заменойа также файл

topdata.bin из папки версии от 1с!!! Только после этих действий включайте в angel.ini EnableRussianLocalization=1

Небольшой вопрос ответ:

-------------------------------------------------------------------------------------

В1: Почему надо заменять стимовский Morrowind.exe на экзешник от 1с? Неужели нельзя внедрить text.dll ???

О1: Можно так сделать, и тогда вся сила text.dll превратится в "тыкву". Он станет не более чем MWSE, MGE или MCP, т.к. будет работать снаружи, а не изнутри и раскладку переключать не сможет, не сможет влиять на движок.

-------------------------------------------------------------------------------------

В2: Можно ли переносить сохранения между версиями?

О2: Если скопировать из версии 1с в версию steam - будут ошибки, т.к. в 1с сохранения загружены файлы .mrk .top .cell. Обратную совместимость я НЕ проверял. Что будет, если не меняя BSA архивы подкинуть в data files стим только .mrk .top .cell файлы, а также файл topdata.bin из папки Morrowind, я также не проверял — экспериментируйте.

-------------------------------------------------------------------------------------

В3: Почему такие сложные манипуляции для версии с оверлеем? Что за обряды и колдовство с переименовыванием?

О3: Необъяснимо, но факт. Разложу по полочкам:

Оверлей не работает даже в оригинальном GOTY издании.

Это происходит потому что:

  • Сначала стим запускает лаунчер игры (и тут подрубается оверлей).
  • Когда в лаунчере нажимается кнопка Играть/Play, процесс Morrowind Launcher.exe ЗАКРЫВАЕТСЯ
  • Открывается НОВЫЙ процесс Morrowind.exe, о котором стим не знает ни сном ни духом, не то что оверлей не работает, даже счётчик часов не идёт.

Мы немного "обманываем" стим, говоря что Morrowind.exe это Morrowind Launcher.exe.

А стиму по барабану что запускать, главное чтобы название было то самое.

-------------------------------------------------------------------------------------

Я думаю над тем, как реализовать прокладку между процессами Morrowind.exe и Morrowind Laucher.exe, чтобы забыть про "переименовывание файлов". В связи с этим я обновил оглавление шапки. 

И вот, как я и обещал, прикладываю исходники и скомпилированный text.dll. По умолчанию русская локаль в angel.ini ВКЛЮЧЕНА!!! Так же я загружу два архива: в 1-ом архиве будет Morrowind.exe и Morrowind Launcher.exe от 1с, во 2-ом архиве экзешники от стим версии GOTY edition. Доступны они будут на странице загрузки файла https://www.fullrest.ru/files/russkiy-vvod-teksta-neofitsialnyiy-apdeyt-2025 в разделе "опциональные"

image.png.6429df08039bd5a83faf73ce72d5d726.png

image.png.bbe3ab1235f60ceb6dd8498dd588deaa.png

(source code)_text_dll_v_3.01.3_to_steam.zip

text_dll_v_3.01.3.zip

Изменено пользователем ksteel
Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...