Итак поколупал я компиляторы и декомпиляторы из пакета modderspack 3.1.7z. Там обновленные скрипты от Noid, sslc int2ssl.
Тестировал всё на скриптах killap. В начале скрипты были декомпилированы, а затем собраны вновь. Две версии int файлов сравнил по md5. Всего скриптов 1315.
Первым был набор от Noid. Он успешно декомпилировал всё. Но один скрипт собрать назад не смог. После лёгкой правки полученного ssl все собралось успешно. Проблема была с процедурой, которая внезапно была создана как принимающая параметры. Хотя они никогда не используются. Причём именно в таком виде она присутствует в оригинальных исходниках F2. Видно Noid не предвидел такого поворота событий
Это похоже единственная процедура с параметрами.
Не сошлось контрольных сумм 322.
Далее тоже самое было проделано с int2ss и sslc. int2ssl успешно декомпилировал всё. Но не собралось назад 3 файла. В одном получился перл вида if (foo --100 > 0). В других были ошибки связанные с неверными расстановками ";". собрать не удалось.
Не сошлось контрольных сумм 128. Неплохой результат.
Далее я сделал дампы оригинальных и пересобранных скриптов и продолжил анализ уже на уровне опткодов.
Сразу нашлась отличительная черта обоих компиляторов. Они размещают стоки используемые в скрипте в порядке из встречи в скрипте. А компилятор которым собирал Киллап размещает их в обратном. o_O Соответственно по крайней мере часть скриптов он собирал явно не этой парочкой. Но это не баг, так как все смещения на строки указываются верно.
Далее я продолжил анализ Niod. Сразу повезло. Нашёлся скрипт, в котором адрес перехода для if был равен _нулю_. Это происходит если встречается пустой блок if.
CODE |
if (foo > 0) Begin End
|
sslc корректно вставляет адрес следующей за O_IF инструкции, а вот нойдовский вставляет ноль. Что-то мне подсказывает, что если проверка не выполнится, то будет вылет при такой конструкции. Такая пустая проверка присутствует в хедерах от оригинального F2. Видно и такого поворота событий Noid не предвидел
На этом я закончил его анализировать.
Далее перешёл к sslc. У него обнаружилось очень неприятная особенность. Он иногда добавляет O_POP в самый конец процедуры. Я не знаю насколько опасна эта особенность, но она сильно затрудняет анализ кода. Так как меняются все смещения и diff получается почти на весь файл. Слудующая особенность так же связана с O_IF. Если встречается вложенный if, причём после это ифа кода больше нет. В опткодах в оригинале это будет выглядеть как:
CODE |
адрес на "дальнейший код". (1) аргументы O_IF адрес на "дальнейший код" (2) аргументы O_IF полезный код безусловный переход на следующую строку дальнейший код
|
sslc же в случае (2) ставит адрес на "безусловный переход на следующую строку"
Вроди не сильно критично, но не приятно, md5 от этого не сходится.
Следующее выявленное различие было в использовании импортируемой переменной. скрипт bcgengrd импортирует i_Guard_Count. Её использование в опткодах везде выглядит как
CODE |
O_STRINGOP(0x0000037e) O_FETCH_EXTERNAL
|
но вот когда к ней добавляют 1 в оригинале используется O_INTOP(0x0000037e).
sslc по прежнему использует O_STRINGOP. Опять же не знаю насколько это безопасно. На этом остановился, так как дальше в основном были O_POP и нужно было прилагать много усилий для анализа. Может ещё продолжу очистив дампы от адресов. тогда различия будут видны лучше.
Можно сделать вывод, что всё отстой и тлен. Даже корректный скрипт может привести к вылету после компиляции.
Но ничего лучше у нас нет. Так что для модификации Лучше использовать сырцы Киллапа и уточнить у него чем он собирал.
QUOTE |
Когда у меня будут сорсы может мы объединимся и ты поможешь мне исправить скрипты для женского населения?
|
Вновь глянул в правки 1C. Наверное лучше согласится с Wasteland Ghost. Все проверки на пол 1C делает у избранного (op_dude_obj), а значит _сильно_ проще иметь два комплекта msg. Для мужского и для женского персонажа. Так как в F2 сейчас будут играть тока олдфаги, то им не составит труда установить нужную версию диалоговых скриптов. Ведь каждый, кто садится переигрывать уже зарание создал план. Кто-то будет мужиком, а кто-то сразу станет Баффи ради халявных гранат.
Могу скриптом сделать два вида msg вставив сообщения добавленный 1C в места которые они заменяют. Получится два варианта перевода М и Ж.
Из того что можно взять у 1C и в этом я готов помочь:
1. Правка охранника у входа в город убежище.
Тут перепутаны местами фразы о том что нельзя заходить в город с гулями и мутантами. 1c правили это в скрипте но это нужно исправить в диалоге! Причём в двух местах. (Тут 1c зафейлили не заметив.). Файл vcgatgrd.msg. Нужно поменять местами строки 109 и 110, 111 и 112. Опционально 129 и 130, но они хоть и присутствуют но процедуры их использующие не задействованы.
2. Локализация отсчёта времени до взрыва вышки и Сиерра.
3. Посмотреть, что можно сделать с проверкой op_msg_string(403, 100) == "You see one of the Reno townsfolk."
С этим условием мне вообще не ясно, оно правда может не выполниться ? Это похоже на бред!
в любом случае sslc отлично реагирует даже на юникод в переменных
Если бисовкий компилятор не осилит ничего кроме ASCII то можно отредактировать бинарник. Главное чтобы длина строк в байтах совпадала. Ну и конечно неясно как поведёт себя движок...
Drobovik, я вижу, что ты пишешь на nma. Не мог бы ты написать Киллапу о баге vcgatgrd.msg. Я вижу, что у него нет этого исправления.
Давно не заглядывал туда, Киллап согласился дать исходники?
Это сообщение отредактировано nicknn - 6 декабря 2013 | 20:48