-
Постов
89 -
Зарегистрирован
-
Посещение
Тип контента
Профили
Форумы
Календарь
Весь контент ksteel
-
Уважаемые форумчане!!! Я выяснил что делает MCP с text.dll! Что я таки нашёл после патча text.dll от версии GFM 5.7 через MCP: Оригинальный файл: Пропатченный через MCP: Различие в байтах на лицо, итого имеем: В Hex Workshop побаловались, идём в декомпилятор/дизассемблер и ищем: в оригинальном text.dll последовательность CC CC CC CC 8B 44 24 04 56 8B 74 24 10 83 FE 08 F7 D0 0F 8C D4 00 в пропатченном text.dll последовательность CC CC CC CC B8 AF 88 56 38 C3 74 24 10 83 FE 08 F7 D0 0F 8C D4 00 По обоим-двум последовательностям В РАЗНЫХ text.dll мы находим: text:1000188C align 10h НО align 10h - это паддинг, а не код!!! Подозрительно так? Заменять столько информации, на паддинг? Прыгаем в адрес 1000188C в обеих dll и смотрим код вокруг него: оригинальный Text.dll: пропатченный через MCP text.dll: Ничего подозрительного не находите? В детстве играли в "найди различия на картинке"? Так вот они! (это не всё, я не буду сюда скидывать весь дизассемблер) На лицо явная замена функции. Что за функции? Смотрим вот в это место оригинала: sub_10001890 proc near mov eax, [esp+arg_0] push esi mov esi, [esp+4+arg_8] cmp esi, 8 not eax jl loc_10001978 А теперь в то же место патча: sub_10001890 proc near mov eax, 385688AFh retn всё. ТОЧКА. MCP заменил всю сложную функцию CRC32 на простой возврат хардкодного значения. Но вот как он это сделал...после значения retn идут случайные байты dw 2474h и повреждённый код. Грубо конечно, но для такого метода очень эффективно, хотя и не в полной мере. А теперь немного по шаманим с плагинами декомпилятора и сравним полностью эти два файлика, их код и глянем разницу, сначала в HEX, а затем и в дизассемблере: Первая вкладка: Вторая вкладка: Начнём со второй вкладки - HEX Разница: Знакомая в принципе картина, уже видели её в Hex Workshop. А теперь самое интересное - дизассемблер: БЫЛО: Сложный CRC32 алгоритм (50+ строк кода) СТАЛО: Всего 2 инструкции! Таким образом получается mov eax, 385688AFh + retn - это магическое число, которое подсовывает MCP вместо реальных вычислений. Выходит что: MCP обходит проверки целостности Возвращает фиксированный хеш вместо реального Это объясняет, почему пропатченный text.dll работает с модифицированным Morrowind.exe А теперь давайте посмотрим и найдём похожие функции, связанные с проверкой по crc ключу между text.dll и morrowind.exe...(кто следит за этой темой с самого начала и внимательно читал, наверное уже настальгирует сидит 😃 ) MCP ломает систему определения версии Morrowind в самом text.dll и САМ определяет её, вычисляя хэш Morrowind.exe! Всё оказалось просто: MCP эту функцию WORD crc = CalcExeCRC(); подменяет на пустышку и все дальнейшие проверки внутри text.dll уже бессмысленны. Вот почему MCP спокойно патчит Morrowind.exe и text.dll не ругается на изменение хэша исполняемого файла. Итог расследования: Я уже сам лично купировал эту crc проверку (как указано в шапке темы), мой text.dll универсально работает с ЛЮБЫМ Morrowind.exe, которому нужен ЛЮБОЙ другой text.dll!!! Всем спасибо за внимание!!!
-
пока сделал заметку. по поводу фикса аргониан (имею в виду починку самой функции и замену "название расы" на "ID расы"), начал разбираться что да как, чуть не заблудился 😄 А сейчас вот к этому молчаливому патчу: Что удалось выяснить: конкретно в FUN_0048b000 есть конкретная функция логирования: sub_477400 где Первый параметр — строка формата (наши сообщения об ошибках) Второй параметр — дополнительная информация Смотрим подробно структуру данного инструмента логирования: CHAR Buffer[1300]; // [esp+6Ah] [ebp-520h] BYREF Что собственно происходит? vsprintf(Buffer, a1, va); - форматирование строки в буфер 1300 байт. Находим этот "буфер": 00477419 FUN_00477400 SUB ESP,0x548 Немного математики: 0x548 в hex = 1352 байта в десятичной Текущий буфер: 1300 байт (как видно в коде) Разница: 52 байта - это (скорее всего) служебные данные/выравнивание Увы, это не расширение консоли, где я могу увидеть весь исходный код и впаять запросто динамический буфер (хотя я попробую). Потому Моё решение: меняем SUB ESP,0x548 (1352 байта) на SUB ESP,0x800 (2048 байт) итого +696 байт доп пространства, чего должно хватить для кириллицы (да и вообще любого языка). А т.к. я трогаю ТОЛЬКО размер буфера — нулевой риск, не затрагивающий основную логику поведения сообщений по звуковым ошибкам. Данный фикс должен покрывать все 5 найденных строк ошибок звуковой системы. К сожалению (как я уже неоднократно говорил) я не плагиностроитель или мододел, потому воспроизвести случай появления этих ошибок я не смогу (для проведения тестов). У кого есть время, прошу провести тесты. Прикладываю файлы собсно для теста. Условия для тестов - чистый MTB без MCP/MGE/MWSE патча - это очень важно. Мой файл по статичному увеличению буфера: angel.iniText.dll
-
ещё забавно, но факт что в стиме при скачивании En, Fr или De версий нет констракшн сета 😃 совсем безолаберность upd Construction Set и всякие источники показывают только строковое значение ID для расы = Argonian. Совершенно бесполезно. Надо искать числовое значение внутри движка и вновь погружаюсь в декомпиляторы) upd из строчек: 007af2a4 Unable to find race id "%s" in script %s. "Unable to find race id \"%s\" in script %s." и 004fde03 PUSH s_Unable_to_find_race_id_"%s"_in_s_007af2a4 DATA прихожу к выводу, что Race id в "скриптах" передаётся как строка ("%s") (что грустно), а не число, Construction Set говорит, что id аргониан = Argonian, которую нещадно переводит наша (да и вообще любая) локализация. Надежда на то, что Движок анимаций использует числа, а не строку, продолжаю поиски. Можно конечно задать параметр, чтобы пеередавалось не как строка.....но хз чем это будет грозить в рамках всего движка (тотальным ахтунгом, потому что все функции ждут строку, а не число int) upd (далее пойдёт немного хаотичное повествование, т.к. автор поста выпил вина 😄 ) что было выявлено посредством шаманства: 0x004C2B40 - 0x004C3090 - это ОДНА ФУНКЦИЯ выбора анимации MOV EAX - загрузка пути анимации в регистр PUSH EAX - передача пути в функцию загрузки base_animKnA.nif vs argonian_swimKnA.nif - два варианта анимации! Вывод в функции происходит ветвление: Если аргонианин → argonian_swimKnA.nif Если другая раса → base_animKnA.nif А ещё я нашёл ЧИСЛОВУЮ (ура) проверку: dec eax ; jz short loc_4C2B47 ; (Если EAX == 2 → зелёная ветка (аргониане)) Вывод EAX содержит числовой race_id. Теперь смотрим на код в декомпиляторе: из которого делаю выводы: if ( v20 ) { if ( v20 == 1 ) { v24 = aBaseAnimkna1st;} else if ( v20 == 2 ){ v24 = aArgonianSwimkn;} else { v24 = 0; } } v24 = aBaseAnimkna1st; // "base_animkna1st.nif" v24 = aArgonianSwimkn; // "argonian_swimKnA.nif" - аргониане получается переменная v20 v20 = 0 → base_animkna.nif (стандартная анимация) v20 = 1 → base_animkna1st.nif (анимация от первого лица) v20 = 2 → argonian_swimKnA.nif (специальная анимация аргониан) НО где же определяется эта переменная? Смотрим выше: v20 = 0; for ( m = 0; ; v20 = m ) {... огромный блок кода ... result = ++m; if ( m >= 3 ) break; } Вывод v20 (m) проходит значения 0, 1, 2, v20 = 2 соответствует аргонианам, Значит race_id аргониан = 2. Нам надо перехватить в момент проверки когда v20 = 2 и обеспечить загрузку правильной анимации.
-
хоть я уже и перенёс фикс по "названию расы в игре", ваша мысль просто бриллиантовая! я переделаю этот фикс, сделаю его изначально "универсальным" для всех языков, которые НЕ английские! тем более у нас есть уже явный пример от Angel Death в файле items_info.cpp. Он использует сравнение по ID типа предмета (0x4f4d4d41 = 'AMMO'), а не по строковому имени! Это именно тот подход, который нужен для аргониан!
-
и т.к. в Angel.ini будет прям очень много информации, соответственно скорее всего сам файл Angel.ini будет разделён на разные версии Angel_eng.ini Angel_rus.ini Angel_fr.ini и так далее. В каждом из инишников будет описание как на родном для локали языке, так и на английском. Где "особые" уникальные фиксы будут описываться подробнее (пример: почему его нет в другой локали, а в этой он есть). И сама структура инишников будет переделана - сначала будут идти общие фиксы, которые необходимы всем локалям, а потом будут идти уже узконаправленные фиксы для определённой локали.
-
Ох даже так? ну в любом случае этот фикс пока направлен на русскую локаль, пока в text.dll нет поддержки польского языка (хотя их Morrowind.exe очень близок к нашему, хоть и базируется на GOTY edition издании, алфавит сродни нашему ) Я добавлю этот алфавит тоже, после внедрения кодировки UTF-8. Будет добавлен блок для исправления польских багов в Angel.ini (если есть какие-то специфичные). А шаблон исправления будет взят с исправления русских фиксов. Сейчас фокусируюсь именно на русской локали, которая даст уже шаблоны на каждый похожий баг 😃 С китайскими иероглифами будет сложнее там вроде 80к иероглифов 😄 определенно нужна будет кодировка UTF-8 чтобы сие чудо внедрить. Сами образы китайской и польской версий у меня есть. Со стима можн овыдернуть Morrowind.exe FR и DE. Про другие версии я даже не знал. Но определенно если ест ькакая-то локализация морровинда - её словарь должен быть в text.dll Что касается De-FR да, в них присутствует этот баг по плаванию аргониан тоже (ох уж это наплевательское отношение беседки к другим языкам). Я добавлю отдельные фиксы позже, которые будут подключаться в соответствующей языковой локали, с выбором фикса вкл/выкл. Т.е. помимо EnableRussianLocalization=1 появятся ещё и EnableFranceLocalization=1, EnableDeutchLocalization=1 и прочие. Сначала надо разобраться с русской локалью, создать шаблоны для фиксов при других локалях. А так-же помимо [Rules_only_for_Russian_version] будут Rules_only_for_France_version и так далее. Работы много, но мы её сделаем 😃 upd перечитал ваше сообщение второй раз. Действительно, проверки должны идти не по названию насы в игре, а по ID расы. Вы открыли мне глаза) зачем плодить эти фиксы, если можно сделать один универсальный.
-
нашёл функцию в движке FUN_0048b000, которая отвечает за обработку всех следующих ошибок: "Invalid pointer found in TES 'lightSounds' list!" "Invalid REFR pointer found in TES 'lightSounds' list!" "Invalid REFR pointer found in TES 'tmpSounds' list!" "Invalid REFR pointer found in TES 'sounds' list!" "Trying to AddTmpSound with invalid reference!" буду препарировать данную функцию, увеличивать буфер, а точнее сделать динамический буфер, дабы не занимать места больше чем нужно.
-
Я обнаружил "молчаливый фикс" в MCP для русской локализации, о котором в принципе не пишется в логе, хотя этот фикс ОЧЕНЬ важен. Было: Стало: Фикс из категории БУФЕРОВ И БЕЗОПАСНОСТИ. Предположение: Фикс переполнения буферов в системе обработки ошибок звуковой подсистемы Morrowind. Я фиксил уже расширение консоли по переполнению буфера. Этот же фикс прорабатывает систему буферов по звукам. Проблема: Слишком длинные сообщения об ошибках в английской версии В русской локализации эти строки становятся еще длиннее из-за кириллицы Приводит к переполнению буферов и возможным сбоям Что делает MCP? Он укорачивает строки ошибок, чтобы избежать переполнения., заменяет list на l. 0x00 00 80 3F - скорее всего, padding или служебные данные. Это довольно важный фикс безопасности, предотвращающий потенциальные сбои при работе со звуковой системой в русской локализации. НО переносить его в таком виде - кощунство. Я буду "забивать гвозди микроскопом". Надо использовать text.dll в полной мере. Мы увеличим буфер для обработки такого типа ошибок (как я сделал фикс по переполнению буфера расширения консоли).
-
Фикс Анимации плавания успешно перенесён! Теперь он не просто меняет строку с Argonian на Аргонианин, а сама проверка расы должна работать с двумя названиями: как Argonian, так и Аргонианин ! 😊 Полный отчёт сделаю как только перенесу остальные фиксы для русской локализации: фикс меню создания заклинаний и фикс окошка при повышении уровня.
-
Я имею в виду, что я не хочу (да и не имею морального права) просто молчаливо переносить их патчи. В логах будут прописаны любые разработчики, чьи творения переносятся на уровень ядра. todo: Возможно чуть позже создам отдельный лог к логу первого вдоха (дабы не загружать второй), будет лог по разработчикам (чьи патчи были включены при запуске), где будут прописываться Имена разработчиков и ссылки на оригинальные творения. А пользователи, кто подкинул идею по модернизации будут упомянуты. Например Siberian Crab подсказал идею сделать клавишу смены раскладки не статичной, что считаю тоже немаловажным для упоминания.
-
СПАСИБО! 🤝🥳 А чтобы у пользователей не было путаницы, в логе первого вдоха 00_text_dll_first_light.log, при подключении фиксов, будет чётко прописано следующее (Сама надпись уже реализована, просто фикс настраиваю, чтобы он ничего лишнего не менял): Т.е. любые импортированные на уровень движка патчи из MCP будут иметь чёткое описание, что это патч из MCP от тех же разработчиков, просто на уровне ядра игры. 😃
-
Текущая подцель — не изменять рабочую версию исправления, а сделать так, чтобы text.dll (русская локализация в частности) в целом не ломала движок. В общей идеологии MCP и text.dll работают параллельно, создать систему, где все фиксы работают в гармонии, Заменить "сборную солянку" из утилит на "швейцарский армейский нож" (я не про фиксы по типу зачарования стрел, ношения перчаток вместе с наручами и так далее). Чинить не следствия неправильной работы text.dll, а саму неправильную работу text.dll и не снаружи меняя байты памяти, а изнутри, не изменяя morrowind.exe вообще, как часть игрового процесса. На примере фикса плавания аргониан он будет не просто менять строку, а интегрируется в систему локализации, как это было с фиксом по повышению уровня. Модульность и гибкость. Сейчас в MCP как - всё или ничего, либо 3 фикса разом, либо 0. Я же хочу сделать каждый из фиксов отдельно подключаемыми. Дать игрокам / плагиностроителям выбор - что им требуется, то и включают, что им мешает - отключают. Расширение в будущем: после внедрения lua на уровень движка, кодировки utf-8, вдруг кто-то захочет сделать мод (по типу преобразования Ё-Е (это совсем как пример))? Мододелу/плагиностроителю не надо будет читать 40ка страничный туториал как установить Морровинд 1с (сборку fullrest к примеру) в стим, чтобы работал оверлей, как потом накатить MCP, MGE XE почему одно без другого не работает, сверху ещё налепить mwse каким образом оно работает (по такой-же причине MGE с mwse объединены, если не ошибаюсь). А человек просто возьмет напишет скрипт и движок будет это поддерживать посредством text.dll (ядра) и его модулей, сможет вести нормальную отладку всего и вся и получать фидбек от пользователей. Сможет отключать оригинальные патчи и совершенствовать что-либо в Морровинде. Исключение каких-либо конфликтов в будущем. Я не изменяю MCP, его фиксы, я переношу его на уровень движка. Вместо чёрного ящика будет прозрачный аквариум, где всё будет видно что как работает и для чего, потому что исходные коды в доступности. И у всего этого будет единая точка конфигурации. Я хочу создать не просто патч, я хочу создать экосистему.
-
Новая вводная. Как выяснилось опытным путём и личными тестами — при отключении русской локали (И ДАЖЕ БЕЗ MCP патча) EnableRussianLocalization=0 в Angel.ini корректно работают: анимация плавания Аргониан работает корректно по умолчанию: меню заклинаний нормальное (не обрезанное), окно повышения уровня отображается корректно без обрезки . Соответственно в Angel.ini будет создан новый блок [rules_russian_fix], где будут находиться 4 фикса, которые будут работать ТОЛЬКО при включении русской локали! Т.к. в английской версии эти патчи ПРОСТО НАПРОСТО НЕ НУЖНЫ! fix_argonian_swim — fix_levelUp_messages fix_levelUp_window — fix_SpellCreation_window — Я не буду объединять патчи fix_levelUp_messages и fix_levelUp_window, да и вообще все патчи в одну строчку - для гибкости и возможности отключения какого-либо патча отдельно. Надо будет выяснить нужен ли fix_unarmored_bug=1 в английской версии. Т.е. присутствует ли баг бездоспешного боя в английской версии? Или это тоже только косяк русской версии. Если кто знает, прошу написать мне х) или в теме в общем.
-
в целом по Аргонианам я уже нашёл этот фикс Было до патча MCP: Стало после патча MCP: Что это за байты? Это замена слова Argonian на кириллические символы в кодировке cp1251. Предполагаю (хотя немного глупое предположение Argonian -> Аргонианин Немного сложно то, что все три патча ставятся одной галкой + 4 gb патч стаивтся по умолчанию. Итого 1 галочка=4 патча. Сейчас сделаю тестовый фикс и проверим 😃
-
Никоим образом нельзя этого делать с моей версией! По крайней мере с моей text.dll. Она постоянно меняется, меняется ХЭШ, байты постоянно сползают в сторону, от чего создателю MCP прийдётся чуть ли не каждую неделю выискивать эти смещенные байты в моей версии и выкатывать доп патч. Это бессмысленно пока идёт разработка ядра text.dll. Я потому и удалил свой форк MCP, потому что он мог ломать совершенно другие адреса в моём text.dll !!! MCP сначала проверяет хэш Morrowind.exe! И выбирает подходящие под него патчи (которые ставятся нормально). Потом он проверяет хэш text.dll и выбирает "непонятные патчи для него". Мой text.dll он не знает (и слава богу) иначе бы ломал его.
-
Значит явно надо смотреть механизм "загрузки" сейва, изучать этот механизм, внедрять как минимум следующие доп шаги (это я на вскидку): при обнаружении обновления параметров игрового движка (именно движка, а не esp | esm | скрипты) заставить делать бэкап этих самых параметров, после чего принимать новые заданные патчем параметры ввести проверку, что эти изменения всё ещё присутствуют в движке, при обнаружении их отсутствия (откате патча) - доставать старые параметры (делать автозагрузку из бэкапа) их. вывести меседж бокс через WarningPrn по обнаруженным изменениям в коде (байтах) движка Т.е. сразу лечить не следствие (поломка карты), а причину — ошибки. Даже так? я не смотрел конечно через tes eng и tes ru ID расы, но может проблема даже в том, что Ангел перевёл алфавит (сделал хук и вырвал 64 байта, внедрил кириллицу), а расу не перевёл должным образом. Но т.к. это конкретное отличие для уникальной расы, которые вшиты в движок - анимация и не подхватывалась. (опять же предположение) в любом случае решение уже есть, надо его просто перенести 😃 Можно попытаться нормально "перевести" название расы конечно, но возможно ограничение по байтам. И впихнуть невпихуемое будет невозможно argonian - 8 символов, аргонианин - 10 символов. Да, это видно в моем ролике, который я заливал, когда перенёс фикс при повышении уровня из версии dll GFM в свою версию. Там написано просто "привлекательность" без цифр. Я сначала подумал что дело в том, что я "забыл перенести" проверку версии "М-МТ-МТБ?" из оригинального dll из-за чего патч немного "съезжал" в сторону, но: а) её там попросту нет б) при отключении русской локализации нормально отображалось Personality 40 И дело просто в количестве символов Personality - 11 символов Привлекательность - 17 символов и цифры не обрезались, они просто выталкивались "за рамку". Т.е. опытным путём пришёл к тому, что фиксы русской локализации априори должны быть перенесены в text.dllю Подумаю создавать ли новые cpp или вшить "фикс рамки" по повышенгию уровня в фикс по сообщению при повышении уровня. Вынести эти строки в angel.ini в к фиксам по бездоспешному бою и фиксу при повышении уровня. А это я на скорую руку открыл случайно английскую версию. Локализованный МСР у меня есть, просто не тот открыл )
-
ДОБРЫЙ ДЕНЬ УВАЖАЕМЫЕ ФОРУМЧАНЕ! Не дождавшись выходных - спешу вас оповестить о новшествах и исправлениях! 1. БЫЛ ПРОВЕДЕН ФИКС. А именно — когда я починил два неконтролируемых лога из предыдущего обновления: eventstream_direct.log log_CoreScanner_cpp.txt И переименовал строчку в angel.ini, в секции [DeepScan] с Enable=1|0 на enableScan=1|0. Так вот, фикс коснулся последнего изменения. Вышло небольшая неполадка и... я переименовал строчку в angel.ini, перенёс условие проверки для мониторов в самое начало ...но в этом условии по старой памяти была записана проверка состояния строки Enable=1 😄 А именно, в файле CoreScanner.cpp: Строка была исправлена: Теперь всё работает нормально. --------------------------------------------------------------------------------------------------------------------------------------------- 2. Теперь о завершении обновления 3.01.3: При переключении EnableRussianLocalization=1/0 логи будут вестись на разных языках! Как было реализовано? 2.1 ГЛАВНЫЕ ИЗМЕНЕНИЯ Коротко: переведены вызовы DEEP_SCAN_LOG и LogAngel в билингвальный режим, чтобы посылать и соответственно принимать 2 аргумента format_ru и format_en А теперь к ЦИФРАМ! 2.2 Второе ключевое изменение в src/2HelperFunctions/AngelLogger.cpp Добавлен этап выбора языка через билингвик-макрос Console_Text: Как я говорил выше, теперь оба макроса действуют взаимосвязано, они дополняют друг друга. 2.3 Третье ключевое изменение в входной точке dll src\morr_text_dll.cpp Лог первого вдоха стал также билингвальным! НО он изначально работает(и должен работать) ОТДЕЛЬНО от LogAngel, т.е. функция CreateFirstLightLog была так-же переведена в билингвальную. Она работает отдельно от LogAngel, потому что это "первый вдох", который осуществляется ДО запуска основных процессов внутри text.dll В morr_text_dll.cpp все 16 вызовов CreateFirstLightLog были переведены в билингвальную систему. А ТАКЖЕ Функция WarningPrn была переведена в билингвальную систему (это то, что показывало ошибки в загрузчиках .top .mrk .cell). Я понимаю что сразу намечается....вопрос: "А, собсно, "натуя" ты перевел в билингвальную систему то, что работает только в русской локали?" Ответ: Во-первых, а вдруг кто-то из англоязычных "учит русский язык" в Морровинде.....? 😄 😄 😄(шутка). А во-вторых (на самом деле), это задел на будущее, вдруг надо будет засунуть эту функцию в файлик, который будет работать независимо от локали (ру/en). Там то и понадобится билингвизм 😃 Четвёртое ключевое изменение (вытекающее из предыдущего) все Message Boxes из дата - загрузчиков были также переведены в билингвальную систему. Все 17 вызовов WarningPrn были переведены в билингвальную систему! ОТМЕЧУ, ЧТО ЭТО ФИКС+ОКОНЧАНИЕ ОБНОВЛЕНИЯ v3.01.3, соответственно версию Я НЕ МЕНЯЛ! Файлы на странице загрузки обновлены! Прикладываю исходники и скомпилированный dll как обычно. (source code) text_dll_v_3.01.3 (final update for 3.01.3 version).zip text_dll_v_3.01.3 (final update for 3.01.3 version).zip
-
Сейв запарывает в каком случае? И каким образом багуется карта (немножко подробнее опишите х). У меня просто сейчас нет возможности самому зайти в игру и проверить порядок поломки. Если: включить фикс карты в MCP. зайти на сохранение. сохранить с включенным фиксом, выйти из игры. отключить фикс. Зайти опять в игру. Сохранение сломано? Второй вариант: включить фикс, зайти на сохранение в котором не было фикса сохранение сломано? Моя гипотеза: фикс карты от MCP (например как оригинальный фикс Angel Death по сообщениям при повышении уровня) не содержит никаких проверок. Т.е. Он грубо внедряет новые байты в Morrowind.exe без проверок на замену оригинальным. Пока единственная проверка, которую я увидел - внешняя по хэшу morrowind.exe и text.dll - т.е. внешня проверка. При откатывании патча — он также грубо вырывает сырые байты и ставит старые, которые там были, НО тут-то и происходит поломка (скорее всего). Т.к. MCP ставит оригинальные сырые байты назад, он не оставляет там никакой "проверки" или условий на тему было ли произведено сохранение с этими фиксами, что было ДО его внесения изменений, что изменилось ПОСЛЕ в этих сохранениях, и где сохраняется кэш(информация сохранения, из чего состоит этот кэш, и где там кэш по карте). Если в кэшэ было отведено определенное количество байтов под "карту", то после фикса — это место "уширилось или(что хуже) сузилось" и теперь в это "суженное" место игра пытается впихнуть невпихуемое (как я пытался впихнуть букву Ё (66 байт в 64 байта), от чего строка обрезалась и эффекта не было - это если в конец алфавита ))) а если вставить то самое "невпихуемое" (та же буква Ё) в середину алфавита, то весь перевод идёт по одному месту, игра вроде работает, но текст - сплошные наборы букв, а не слова. Так может быть и с картой. Объяснение на пальцах: МСP: тихо, (ночью) крадёт у морровинда карту, подменяя старую на новую. Морровинд проснувшись даже не в курсе, что у него что-то забрали. Он работает, как и раньше, но вот сохранение явно идёт запись (ага, новая карта, ошибок не вызывает (игра ведь не вылетает), значит с ней и работаем). (НО, досада, пользователю фикс не понравился, или стал не нужен, или стал мешать) MCP: под стелсом (вновь) забирает свою новую карту у Морровинда и возвращает старую дырявую карту. Морровинд её принимает (ведь он с ней нормально работал) и запускается как ни в чём ни бывало. Но вот механизм кэша в сохранении начинает истерить: всмысле карта другая? Я уже тут все: и ремонт в комнате сделал, и место на стене расчистил под новую карту, а у меня старая дырявая карта. Так не пойдёт, я против, мне это не нравится. Это похоже на механизм, если загрузить в игру плагины, сделать сейв, а потом удалить плагины и снова загрузить сейв — вылезет каскад ошибок из-за кэша. MCP забирает карту, не проверив — не забыл ли Механизм сохранений работу со старой картой, не запутается ли интерфейс в том, что это предыдущая карта. МСP не объяснил механизму сохранений, что делать, если вернется старая карта (возможность отката не оставил). И если моя гипотеза верна, то надо не переносить патч (хотя как доп вариант), а чинить расширять проверку rэша сейва, либо механизм загрузки (что более вероятно). Разработчиками явно "механизм кэширование сохранения" строился без учёта того, что будет модифицироваться сам движок, потому там только условие по ЕСП/есм файлам.