-
Постов
89 -
Зарегистрирован
-
Посещение
Тип контента
Профили
Форумы
Календарь
Весь контент 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 тот самый переключатель русской локали. Также в целом все комментарии в Angel.ini были переведены на английский язык дублирующей строкой. НО чтобы не раздувать сильно Основное тело "включателей" вся справка по DeepScanner переехала в конец файла: Основной блок с выключателями: Справка (после блока выключателей): 2. Второй "пациент" - файл include/Headers_0DialogSystem/DialogEngineMaster.h. В нём был объявлен наш переключатель локали. 3. Третий "пациент" - файл src/0AngelOriginalPatches/0DialogSystem/1DialogEngine/DialogEngineCore.cpp. Добавил условия подключения инструментов-загрузчиков LoadCellData, LoadTopicData, LoadMarkTopicData. При отключенном флаге русской локали данные инструменты просто НЕ загружаются. Также обратите внимание на шаг 2.2 - Патчи и хуки не применяются в этом случае к процессу Morrowind.exe при отключенном флаге русской локали. В этом уже идёт вся прелесть модульной архитектуры и прошедшего рефакторинга! Благодаря им мне не нужно модифицировать MemoryPatcher.cpp, AlphavitEngine.cpp, DictStr.cpp или любой другой из "Загрузчиков"! Достаточно поставить одну перемычку и произойдёт каскадное отключение русской локали! 4. Четвертый "пациент" - файл src/morr_text_dll.cpp. Добавлен наш флаг и строчка, которая будет сообщать в лог-файл 00_text_dll_first_light.log (на уровне с Morrowind.exe и text.dll) в каком режиме запущен Morrowind.exe (с какой локалью). И вот вроде бы всё хорошо, русская локаль может быть включена или выключена, ура.....но чего-то не хватает, смекаете? (с) Капитан Джек Воробей. И вы молодцы, если так. Дальше я продолжил колдовать с консолью и командами, а точнее справкой к командам расширения консоли. Но как не загрязнять код всякими if | else, этими миллиардами условий и выводить отдельно: сообщения на английском языке при отключении русской локали сообщения на русском языке при включении русской локали? Правильно! МАКРОС! И в этом опять поможет модульная архитектура. Достаточно вписать макрос в один файлик и по паутине через stdafx.h о нём узнает вся консоль, её движок, её команды! И все файлы, где есть русский текст об ошибках, логах! 5. Пятый "пациент" - файл include/Headers_1ConsoleEngine/ConsoleEngine.h. Вот он наш "золотой" билингвик-макрос. Просто и со вкусом ру / ен. Ну, а дальше пошла (моча) вода по трубам, буду просто перечислять файлы, где был применён билингвик-макрос и прикладывать скриншот: 5.1 Файл src/1ConsoleEngine/ConsoleCommand/VersionCommand.cpp 5.2 Файл src/1ConsoleEngine/ConsoleCommand/PriorityCommand.cpp (и да я вернул нормальное слово "изменён" вместо "изменёЁёЁёЁн" 😄Хотя, наверное, как исторический момент принятия Морровиндом буквы "Ё", можно было бы оставить, как напоминание): 5.3 Файл src/1ConsoleEngine/ConsoleCommand/DumpCommand.cpp 5.4 Файл src/1ConsoleEngine/ConsoleCommand/FPSCommand.cpp: Вроде бы всё....но нет, давайте оживим "мёртвый код" Angel Death. И вот о чём я говорю: обратите внимание на старый реестр команд src/1ConsoleEngine/ConsoleCommand/ConsoleCommands.cpp: Вы когда-нибудь видели эти строки-справки в консоли? Нет, а знаете почему? Потому что в блоке команды .help был сломанный цикл: Перевожу на понятный язык: текст находится в поле szUsage (Описание) команда help в своём цикле читает только поле szName (первую строчку, имя команды) szUsage никогда не используется и не выводится в консоль. Это был "мёртвый код" или "артефакт", если хотите. Что ж, давайте оживим этот артефакт прошлого, и сделаем то — что хотел сделать Angel Death, а именно при вводе команды .help будет выводиться не только список команд, но и короткая справка по командам. Но мы немножко усовершенствуем этот механизм. Я не стал придумывать велосипед. У меня уже есть билингвик-макрос, который прекрасно работает. Вместо сломанного цикла я обрезал реестр команд, в нём осталась только логика: То, к чему я постоянно стремлюсь - ничего лиш-не-го. А все пояснения я перенёс в команду .help. Теперь хэлп - действительно ХЭЛП! Встречайте файл src/1ConsoleEngine/ConsoleCommand/HelpCommand.cpp: Билингвик-макрос + идея Angel Death. Красота! Также я написал явное пояснение, что команду можно ввести пустой (без значения) и получить подробную справку по команде. Думаете всё? Ан-нет, не всё. А как-же смена раскладки? Зачем она нужна при игре на английском языке? иероглифы в игре писать? Давайте и её "подрежем"! Файл src/0AngelOriginalPatches/mw_input.cpp. Добавлено условие по смене локали: ИТОГ: text.dll работает в двух языках - английский, русский! Скриншоты консоли (у меня установлено два морровинда обычный 1с и GOTY в Steam): GOTY версия с EnableRussianLocalization=0 (в angel.ini): 1c версия с EnableRussianLocalization=1 (в angel.ini): И вот, теперь text.dll полностью готов к работе в стим библиотеке! Вопрос: как добавить этот text.dll в стим версию? Ответ: необходимо проделать несколько шагов и путей. Путь а) без подключения оверлея СТИМ Путь б) с подключением оверлея СТИМ. Рассмотрим оба "путя" 😄 Путь А) без подключения оверлея СТИМ: В папке стим версии заархивировать оригинальный Morrowind.exe Скопировать из папки версии 1с четыре файла : Morrowind.exe, text.dll, angel.ini, morrowind.ini Поместить скопированные файлы версии 1с в папку стим версии с заменой. Выставить в angel.ini на ноль значение строки EnableRussianLocalization=1 (<--вот эту единичку на 0 поменять) Вы молодец! Играйте! Путь Б) с подключением оверлея СТИМ (немного сложнее). В папке стим версии заархивировать оригинальные Morrowind.exe и Morrowind Launcher.exe Переименовать оригинальный стимовский лаунчер, в Morrowind Launcher Original.exe (необязательно именно так назвать, можно выбрать другое имя, главное чтобы вы понимали, что это оригинальный лаунчер из стима) Оригинальный стимовский Morrowind.exe из папки можно удалить (он не пригодится, главное сохраните его в архиве, на всякий случай, мало-ли). Скопировать из папки версии 1с четыре файла : Morrowind.exe, text.dll, angel.ini, morrowind.ini Поместить скопированные файлы версии 1с в папку стим версии Выставить в angel.ini на ноль значение строки EnableRussianLocalization=1 (<--вот эту единичку на 0 поменять) ЕСЛИ ВЫ ИСПОЛЬЗУЕТЕ МСP (MGE), ТО СЕЙЧАС САМОЕ ВРЕМЯ ИХ ЗАПУСТИТЬ! ЧТОБЫ ОНИ ПРОПАТЧИЛИ ВАШ МОРРОВИНД.EXE ОТ 1с в папке стима!!! Переименовать скопированный в папку стим Morrowind.exe в Morrowind Launcher.exe (ОБЯЗАТЕЛЬНО И ИМЕННО ТАК! Morrowind Launcher.exe !!) Вы молодец! Прошли более сложный путь! Можете запускать игру через стим! Играйте! И не включайте русскую локализацию в стимовской версии, игра просто не запустится. Если хотите полностью русскую версию в стиме, то тогда копируйте всю папку 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 в разделе "опциональные" (source code)_text_dll_v_3.01.3_to_steam.zip text_dll_v_3.01.3.zip
-
ДОБРЫЙ ДЕНЬ! Уважаемые форумчане! Хочу вам рассказать о проделанной работе за эту неделю: ФИКС БАГОВ НЕКОНТРОЛИРУЕМОГО ЛОГИРОВАНИЯ. Что было выявлено: При установке 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 для исключения путаницы в будущем! CoreScannerDefines.h добавлен главный переключатель под новым именем enableScanner. CoreScanner.cpp переименовано Enable → enableScanner. Проверка условия перемещена в самое начало файла: EventStream.cpp добавлены отсутствующие проверки условий на каждый уровень записи: AngelLogger.cpp - введена интеллектуальная фильтрация. Разделение логов мониторинга и системных логов. Проще говоря, данный инструмент логирования теперь понимает и отличает логи системы мониторинга от логов, которые необходимы для отладки самой text.dll (лог 00_text_dll_first_light.log на уровне с text.dll и Morrowind.exe нормально создается при выключенной системе мониторинга в Angel.ini) Результат фикса - Система работает как швейцарские часы: при enableScanner=1 ведётся обычный мониторинг при enableScanner=0 - абсолютная тишина, никаких лишних файлов в папке (нагрузки на систему). Логи text.dll - работают всегда для отладки моих изменений в структуре самой dll (в релизе я их убираю) Логи мониторинга — только по команде полное послушание и контроль систем 😃 НО, я бы даже не написал сегодня на форуме, если бы не другое масштабное обновление. На оформление следующего сообщения мне потребуется немного больше времени (да и не хочу я перегружать одно сообщение несколькими обновлениями, так что ждите, через пару часов новый пост, где уже будут прикреплены файлы и исходники).
-
и на последок (на сегодня) БОНУС АПДЕЙТ: теперь, если какой-либо создатель мода по ошибке в локализации напишет букву Ё, то конечный пользователь вместо кракозябр на экране увидит читаемый текст, просто вместо буквы Ё в слове будет буква Е! Я долго и муторно пытался научить Морровинд букве "Ё". Это было чем-то похоже, когда я пытался исправить слепое пятно со знаком номер "№", но сложнее. Вместо маленькой ё - Морровинд упорно писал , (запятую). Вместо большой Ё - Морровинд упорно писал " (двойные верхние кавычки). Я понимаю, что случайные ошибки с буквой "Ё" в файлах локализации могут довольно-таки сильно раздражать локализаторов (создателей модов), потому вот что было сделано: 1. Для начала ради теста введено в одну из команд консоли явное наличие буквы Ё: Что писало мне в игре, при введении этой команды раньше: Довольно грустно 😞 . Итак, что я сделал. Вместо обычной буквы Ё, я заставил Морровинд использовать букву Ё с диакритическим знаком (или просто Е). В файл Topic.cpp был добавлен следующий блок кода: В файл DictStr.cpp тоже добавил такое же преобразование: После данных манипуляций и колдовства я получил вот такое сообщение в консоли: притом, что в файле Priority.cpp до сих пор написано вот так: Теперь с этим 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
-
Доброго времени суток уважаемые форумчане! Хочу поделиться с вами о проделанной работе. (в основном это обновление будет касаться самой структуры text.dll, исключения ошибок при компиляции, разработки text.dll. Но также будут и нововведения (о чем расскажу ниже). 1. Обновление CMakeLists.txt. Был наведён порядок, добавлены комментарии к каждому пункту. Старый CMakeLists.txt: Новый CMakeLists.txt: Как вы можете заметить - была проведена колоссальная работа. Были указаны прямые пути компилятору для поиска заголовочных файлов. Файлы .cpp были разбиты на модули (какие-то были вообще созданы с нуля). Подключены новые библиотеки: а) библиотека, что использует оригинальный движок - d3d8(найти было не просто 😃 ); б) библиотека для перехвата - minhook (об этой библиотеке можете почитать здесь https://github.com/TsudaKageyu/minhook ). Были убраны макросы из старого Visual Code 2. Был отредактирован morr_text_dll.rc (для избежания ошибок компиляции): Старый morr_text_dll.rc: Новый morr_text_dll.rc: И тут изменения сразу заметны - убраны старые макросы, исключены варианты перебора "if", теперь dll сама просто понимает какие ресурсы игры может подхватывать. 3. Был отредактирован заголовочный файл resource.h (resource.h вообще переехал из главной папки ко всем заголовочным файлам в папку include). Старый resouce.h: Новый resource.h: Также была проведена очистка от старых макросов, добавление комментариев. 4. Был отредактирован заголовочный файл stdafx.h: Старый вариант stdafx.h: Новый stdafx.h: Теперь stdafx.h действительно главный заголовочный файл всего проекта. -------------------------------------------------------- Теперь перейду к изменениям самих .сpp файлов, их расположения и структуры всего проекта. 1. Изменение структуры проекта: Было : Стало (задержите дыхание (с) Михаил Задорнов): Был наведён порядок в файлах проекта в целом. Оригинальные патчи и локализация были перенесены в папку 0AngelOriginalPatches (туда же я засунул фикс по сообщениям при повышении уровня). ---------------------------------------------------- Основные изменения коснулись файлов DialogEngine.cpp, HelperFunctions.cpp и Console.cpp. Была полностью сохранена оригинальная логика файлов. Они были просто разбиты на модули — из монолита в отдельные лёгкие файлы, которые позволяют вносить в них изменения отдельно, не рискуя работоспособностью других файлов. 2. А теперь по каждому модифицированному файлу отдельно: 2.1 DialogEngine.cpp (движок диалогов), DictStr.cpp (словарь), Topic.cpp (система топиков). ---------------------------------------------------------- 2.2 Console.cpp - главный дирижер консоли. Файл также был разбит на модули. Оригинальная логика сохранена, мой фикс по переполнению буфера сохранён. Расположение: файл Console.cpp остался в главной папке /src/, вся его логика была перенесена в папку \src\1ConsoleEngine: ConsoleEngine.cpp - создает логику работы расширения консоли оригинальной игры. В папке ConsoleCommand теперь лежит реестр команд ConsoleCommands.cpp: и каждая команда в отдельном файле: Также теперь в игре, при введении какой-либо команды из расширения консоли от Angel - выводится подробная справка: версия text.dll и дата его сборки для чего эта команда какие доступные значения для этой команды пример, как использовать эту команду какое значение сейчас установлено ВНИМАНИЕ!!! text.dll из-за ограничения "вывода номера версии" не поддерживает множественные номера версий. Т.е. он пишет номер версии 3.01, хотя по факту это 3.01.2. Я пока думаю как реализовать нормальный показ версии. ------------------------------------------------------------------------- 2.3 HelperFunctions.cpp разбит на модули. Этот файл БОЛЬШЕ НЕ СУЩЕСТВУЕТ В ЕГО ИЗНАЧАЛЬНОМ ВИДЕ. Вместо него созданы отдельные файлы по принципу 1 файл - 1 функция (1 инструмент-хелпер). Сделано это для того, чтобы не загружать "лишними инструментами" память. Реализация: была создана папка для функций-инструментов всего text.dll: \src\2HelperFunctions: 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 со следующим содержимым: Для чего это было сделано и для чего разрабатывается? Все мы прекрасно видели ошибки в игре, в том или ином виде: фиолетовые текстуры, желтые ромбики вместо моделей, непонятные молчаливые краши самой игры без логов, жуткое падение фпс и так далее. Данная система разрабатывается для того чтобы: у разработчиков модов был инструмент, который будет отслеживать то, как игра ведёт себя с их новым модом и т.д. у пользователей (тестеров модов) были логи, которые они смогут отправлять разработчикам. для выявления ошибок оригинального движка Morrowind.exe и дальнейших его фиксов. Как с этим работать? Для этого в Angel.ini были добавлены следующие блоки: 0 - выключить, 1 - включить. Важно понимать, что данные мониторы ещё находятся в разработке и настройке. Для того чтобы включить что-то из блока [DeepScanner] - необходимо полностью включить [Morrowind Engine Diagnostic System]. Не забудьте также о самом переключателе Enable=0 ! Такая двухступенчатая активация сделана специально, чтобы кто-либо случайно не нагрузил систему лишним мониторингом. Я НАСТОЯТЕЛЬНО НЕ РЕКОМЕНДУЮ включать больше 1-2 мониторов (если у вас слабенький ПК) из раздела DeepScanner! Что будет при включении мониторинга? На том же уровне, где находится text.dll будет: создан файл 00_text_dll_first_light.log в котором будет вестись логирование по самому взаимодействию Morrowind.exe и text.dll: На том же уровне, где находится сам text.dll создастся папка "text_DLL" в которой будет дочерняя папка Т.е. все логи мониторинговой системы будут находится по пути: \Morrowind\text_DLL\text_DLL_logs и логи не будут захламлять основную папку с игрой. Содержимое папки text_DLL_logs будет зависеть от того какие модули вы подключили. Вот пример содержимого папки со всеми включенными модулями: (как вы можете увидеть 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 КБ
-
Для пользователей, которые подумали о неком "тупике" для разработки (пока не появится товарищ Hrnchmad). Я прошу вас не расстраиваться, ведь это не тупик, а время чтобы отладить мою версию 3.01.1! Прогресс это конечно хорошо, быстрый прогресс - ещё лучше. Но надо давать прорасти зернышкам и собрать хлеб, прежде чем сеять новые зерна Во первых - ввести логирование всех органов text.dll, с выносом параметра в angel.ini: EnableLogConsole = 1, EnebleLogMorrTextDLL = 1, EnableLogHelperFunctions = 1 И так далее. То есть прямое медицинское наблюдение text.dll и всех его органов. А во-вторых, пока ответ по патчам MCP не получен, у меня есть время для маленького безумства - научить Morrowind кодировке UTF-8 хе-хе. Ну и не забываем про подготовку "глобального обновления", скриншот которого я кидал раннее..
-
Итак. Мои предположения (если изменить подход) патч меняет какую-то конкретную функцию по адресу 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: Что это такое? Это тот же самый 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( )И выглядела она вот так: Вот как эта, казалось бы, простая конструкция превращается в бомбу замедленного действия, способную вызвать то самое исключение std::bad_array_new_length: Бесконечный цикл: Цикл for ( int i = 0;; i++ ) — это вечный двигатель. Он будет работать до тех пор, пока его принудительно не остановят. Слепое доверие: Остановка происходит, когда функция GetPrivateProfileString не находит в Morrowind.ini очередной ключ (GameFile0, GameFile1, GameFile5,... GameFileN) и возвращает 0. Код полностью доверяет тому, что файл Morrowind.ini корректен и что эта последовательность когда-нибудь прервётся и будет чёткой НЕ НАРУШЕННОЙ. Сценарий катастрофы: А теперь представьте, что 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: Всё ясно, понятно и главное безопасно. НО это всего лишь моё предположение № 2 про то что патчит MCP в text.dll. В любом случае MCP пропустит мой dll и не навредит ему, т.к. данный ХЭШ ему НЕ ИЗВЕСТЕН. Модификации text.dll будут работать, игра будет работать. П.с. если я пойму логику фикса и он НЕ БУДЕТ избыточным - я её добавлю в text.dll, он там будет по умолчанию. На этом спасибо за внимание.
-
Что я выяснил про MCP: MCP меняет системные переменные CRT: __commode - режим ввода/вывода __fmode - режим работы с файлами __umaskval - маска прав доступа Пока мой 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😞 НО хэш меняется: Что это за магия ВНЕ Хогвартса, я пока НЕ понимаю. Но судя по байтам из патча 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): нашу общеиспользуемую: e8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8 первую отличную от нашей общеиспользуемой: 23c36ef153f5b183fc13d06ef339d9356c0da6b30a90aa7359baedce2135f036 вторую отличную от нашей общеиспользуемой: f027a20356e788cf1a48d6f89f8b11eb61b34dda2fecb6fab59a74e3dae3f83a Как вы сами можете увидеть, две другие версии вносят: а) немного другие правки в сам text.dll б) вносят больше правок в text.dll, что намекает о старых версиях text.dll (скорее всего версии 3.00 и ниже). Вывод: т.к. версия text.dll 3.01 не менялась внутренне структурно (что мы также выяснили в этой теме), то патч из вышеуказанной папки e8503809bad3d088b367cffe85b13965565c4655f457919db18cdefe76edbad8 как раз и влияет на text.dll. Собственно к анализу этого патча от MCP я и приступаю, буду смотреть что он вносит или что модифицирует.
-
Вот я о том же. Я не буду переносить из MCP такие мелкие фиксы как "широкое меню, фикс карты для TR и т.д."- это мелкие правки, в сравнении будто я переношу мелкую правочку из esp в esm, хотя правочка и так работает идеально. Для сохранения совместимости и универсальности надо перенести более глобальные и общие масштабные фиксы. Начнём с малого с MCP, через MGE (вообще прикрутить рендер DX9-11 нафиг 😄 ) к большему - MWSE.
-
Да, я согласен с вами полностью прогресс не должен вредить совместимости н ив коем случае, но что делать, допустим, с 4гб патчем? MCP находит в заголовке Morrowind.exe (PE header) специальное поле «Характеристики» и вписывает в него флаг 0x0020 (IMAGE_FILE_LARGE_ADDRESS_AWARE), говоря Windows: «Этому приложению можно доверять, позволь ему видеть больше памяти». Таким образом даются 4 ГБ памяти. И всё, это потолок. Но если мы хотим сделать 8 ГБ памяти тем же путём что и MGE XE, только на уровне движка, а не со стороны внешнего органа MGE XE?
-
Загрузил стабильную версию 3.01.1 (сообщения при повышении уровня, буфер консоли гибридный) в раздел плагины, закрепил её файлы в шапке темы. Это будет отправной точкой в дальнейшем совершенствовании, в принципе с ней можно играть. (Она в оригинальном виде, каким сделал его Angel Death). Я уже провел полный рефакторинг файлов/кода. Разместил все по отдельным папкам. Теперь каждый файл .CPP либо .H структурно элегантен, не выполняет один всю работу. А именно console.cpp и helperfunctions.cpp. Приступаю к анализу того, какие правки необходимо перенести из MCP в text.dll на уровень движка. Необходимо не только text.dll вырвать из состояния "застыло во времени" но и правки из MCP.
-
И снова здравствуйте форумчане! Спешу вас порадовать тем, что я внёс исправление в расширение консоли (если включена функция EnableConsole=1 в Angel.ini)! Теперь при наличии длинных скриптов text.dll должен вести себя так, как и задумывалось! Коротко о том что было сделано: 1. Безопасность памяти. Увеличен буфер вывода с 1024 до 2048 байт в Con_Printf Заменён опасный sprintf на безопасный strncpy с принудительной нуль-терминацией Добавлена проверка памяти в .dump s команде через IsBadReadPtr 2. Умное управление ресурсами. Гибридная система буферов в GameCommandLine Быстрый стековый буфер 1КБ для обычных команд (как изначально было в статичной версии) Динамический буфер 4КБ для длинных скриптов (автовыделение) 3. Защита от переполнений. _vsnprintf с sizeof() вместо магических чисел Гарантированная нуль-терминация во всех строковых операциях Уменьшен массив argv со 1024 до 64 элементов для безопасности (если будет обрезаться строка, сделаю и его гибким, с изначальным значением 64 и он сможет увеличиваться по мере необходимости). А теперь о каждом действии и подробно: 1. Безопасность памяти (Buffer Overrun в Con_Printf): 2. Самое главное изменение - умная система буферов в GameCommandLine: Изначальная строгая статичная версия: Моя версия - гибкая, при получении текста/длинного скрипта сама выбирает какой буфер выделять для текущей операции: 3. Защита дампа памяти: Было (чтение любой памяти): Стало (проверка доступности): 4. Добавление защиты в сам файл Console.cpp: Прикрепляю новый text.dll c пофикшенной консолью и изменённым исходником консоли. Сохранена кодировка cp1251 (ох как же она мне дорога, кто бы знал....). Все предыдущие фиксы включены в эту версию. Версия изменена на 3.01.1 п.с если мне кто-то подскажет как я могу скрывать длинные рулоны сообщений под спойлер, буду премного благодарен. text.dll Console.cpp
-
и волки целы, и овцы сыты (с) Тогда решено - я сделаю одну версию, пофикшенную, которая останется на версии 3.01 (консоль, мб еще какие баги найду в коде) А вторая версия будет увеличивать свою версию 3.01-> 3.02 и т.д., но там будет меняться и развиваться патчи, фиксы модульность и другие фьюча хотелки. Либо предлагайте идеи, я всегда рад и открыт для предложений, ведь я не только для себя это делаю) п. с. Я тоже думал, что 1с - лицензия.
-
Из этой старой программы и заплатки можно абсолютно все стереть и написать в неё все что угодно. И многократно исправленная кем? Как мы выяснили в этой теме - сам .DLL не переделывался с того момента, как Ангел внес исправление 3.01 по табличкам при повышении уровня. DLL "застыл во времени" в его первоначальном виде. OpenMW когда-то тоже была "сверхзадачей". Теперь это прекрасная реальность, родившая из себя Tes 3 mp. То же самое можно сказать про MWSE, MCP, MGE, Tamriel Rebuil - титанов творчества плагоностроителей и мододелов. По поводу языка (не знаю причем тут пуп земли и для чего вы это сказали) когда я говорю про сам процесс локализации и то как это было реализовано с технической точки зрения. По поводу поддержки других языков/версий Морровинда/операционных систем. Вы слишком строго относитесь к тому что только только начало зарождаться. То что открылось - полностью неизведанная земля, всех возможностей которых и я не знаю, потому даже не смею предполагать где у неё предел - "край мира". И вас никто ничего не заставляет/принуждает или обязывает делать, ни в коем случае ) вы правы, цели и идеалы у всех разные. Кто-то довольствуется тем что есть, а кто-то готов искать пути для новых возможностей. Upd. Теоретически, если Ангел просто напросто вписал русский алфавит в text.dll, то что мешает внести любой другой алфавит в этот DLL, в другой .cpp файл. Вынести переключение языка в Angel.ini как я это сделал с клавишей смены языка. У пользователя будет его родной язык+английский.
-
А куда еще пихать исправления багов движка, как не в DLL, к которому привязан оригинальный Морровинд? После того , как версия 3.01 подтвердится я займусь модульностю этого длл , что DLL будет подгружать за собой еще более мелкие правки: Бесит следование нпс, которые постоянно глючат, теряют вас если вы прыгнули, или НЕ ДАЙ БОГ встали на камешек, который на 1 см выше, чем тот уровень, где они стоят - следуйте в (гипотетическую пока) папку textDLL\npclogic\следованиеиnpc.DLL (с исходниками). Постоянно проваливаетесь под пол Вивека , при акробатике 100 и из-за подгрузки ячеек? Проследуйте в папку textDLL\playerlogic\playermovement.dll(с исходниками) Надоел мусор в сохранениях, который постоянно надо чистить через (xEdit.... вроде так называется программа? не помню точное название), порадуйтесь мусора в сохранениях больше не будет, потому что это будет в ядре textDLL\core А вылеты при смене ячеек? Или появление мусора от быстрой телепортации/силтстрайдера? Очень много чего можно будет избежать, убрав это накорню 😁 И вся прелесть в том, что это все работает из коробки, в момент запуска игры, а не после ее загрузки. Все это будет максимально гибким и редактируемым. upd. Вы абсолютно правы в той части, что МСР/mwse делают уже что-то, что делает text.dll (или может делать), но в случае с text.dll вы просто оденете ошейник на Morrowind.exe и будете командовать ему что делать. Сами. В то время как mwse/MCP чужеродные пришитые органы для morrowind.exe, то text.dll для него икона и второе сердце.
-
Я наверное неправильно выразился и вы не так поняли. А. Если этот синдром наблюдается только в русской версии от 1с, то решение сейчас лежит у меня в файлах в пк. Б. Если это проблема обеих версий, то решение лежит в morrowind.exe, который надо дизассемблить и искать байты памяти в которых задаются координаты, что явно дольше будет. В text.dll и фикса бездоспешного боя не должно было быть и других фиксов, потому что это TEXT dll изначально был (насколько я понимаю) для простого перевода x) Решение № 1: Double - самое сложное техническое решение, вы предлагаете вручную в 32 битный оригинальный движок внести 64 бита, что требует глубокой переработки. Решение № 2: Смещение координатной системы: вместо 0.0 использовать локальные координаты относительно региона, которые будут идти к какому то одному "центральному региону" Решение №3: самое глупое привязать центр мира к игроку. И получится как в том кошмаре, когда вы бежите и не занимаетесь с места одновременно, потому что здания как-то-привязаны к координатам (хотя почему тогда они не трясутся, а только НПС и тарелки/ложки) Я не модостроитель, я не знаю как влияют координаты на моддинг и как Tes construction set с ними воздействует. На данный момент я могу просто строить гипотизы, пока четко не увижу код-цифры
-
Не для текущего конечно состояния DLL (он еще сырой), но для задела на будущее. Эта проблема наблюдалась и в английской версии? Или это "особенность" русской локализации? upd Вообще, после изучения console.cpp могу предположить вот что: Где-то в оригинальном движке есть что-то типа: struct Object { float x, y, z; (32-битные float) }; Что это значит? (все еще гипотеза): 1. Float (32-bit) имеет ограниченную точность ~6-7 знаков 2. При больших координатах (в тысячах единиц) младшие биты по просту теряются 3. Округление происходит "скачками" → объекты "дрожат"
-
Итак, быстренько перед работой проанализировав Console.cpp (заметка: надо бы вообще полную ревизию .cpp файлов всего text.dll сделать на предмет уязвимостей и сделать их "современными"), я выявил несколько потенциальных проблем: Проблемное место №1: sprintf без ограничения. КОМБО sprintf(buf, "%s", raw)+char buf[1024]; вот как раз таки если raw будет длиннее 1024 символов — будет переполнение буфера!!! (как вариант заменить на char buf[1024] strncpy(buf, raw, sizeof(buf) - 1) buf[sizeof(buf) - 1] = '\0' (гарантирует нуль-терминацию, но надо смотреть). Потенциальная проблема №2: _vsnprintf с магическим числом. (в этом случае немного ЛУЧШЕ, но не идеально, надо думать). _vsnprintf(tmp, 1024, format, argptr)+char tmp[1024] _vsnprintf ограничивает вывод, но если строка слишком длинная, она может быть обрезана. (как вариант заменить char tmp[1024]; _vsnprintf(tmp, sizeof(tmp), format, argptr) tmp[sizeof(tmp) - 1] = '\0' (гарантирует нуль-терминацию, но надо смотреть) Потенциальная проблема №3: Работа с указателями: В функции GameCommandLineDump идёт опасное приведение типа: Сon_Printf( "%8.8X: %s", adress, ( char * ) adress ). Что это значит? Берется произвольный адрес памяти и трактуется как строка и если в этом участке памяти нет нуль-терминатора, то всё пиши прощай, привет "segfault". Вобщем тоже надо думать. Возможно что-то ещё. Выводы из быстрого анализа: buf имеет размер 1024 байта sprintf копирует ВСЮ строку raw в buf без проверки длины Если raw длиннее 1023 символов + нуль-терминатор - BUFFER OVERRUN! Почему это вызывает проблему с Tamriel Rebuilt, либо сложными скриптами, они: Переполняют buf[1024] в GameCommandLine Вызывают buffer overrun Ломают стек вызовов Приводят к Runtime Error Что я буду делать? Как уже описал выше - (сначала поищу есть ли лучшие решения) потом исправлю эти строки, А ТАК ЖЕ, подумаю на сколько можно увеличить буфер....если взять примеры скриптов Пирата (if-if-if-if-if....и так далее if через каждую строчку x15), то в тестовом режиме можно увеличить буфер до 2-4кб вместо 1 КБ который установил давным давно Angel Death. Я всё ещё нге знаю память игры и эксперименты с этим могут повлечь самые разные последствия. Если всё будет гладко, то ещё увеличу буфер до 8КБ (чтобы на века). Вот такой анализ, и чем я буду заниматься дальше, но это уже будет после того как вернусь с работы, всем хорошего дня! 😃