В помощь переводчику - дизассемблирование скриптов что делать, если автор не дал psc файлы

К комментариям (4)
17.03.2013 — 00:01
Автор: gkalian

Статья «В помощь переводчику - дизассемблирование скриптов что делать, если автор не дал psc файлы» специально для TESALL.RU

...В помощь переводчику...

Перевод - это великое дело, но что делать, если переводимый текст записан в функции MessageBox "ля ля - фа фа", а исходника (.psc файла) этого скрипта злобный автор не предоставил.
Не унываем - выход есть: Bethesda снабдила нас возможностью дезассемблировать скрипты, просто не сказала нам об этом.
Итак, как это сделать:

  • Ну это в принципе ясно - ставим "конструктор"
  • Находим папку %gamedir%\Papyrus Compiler и обращаем в ней внимание на файл PapyrusAssembler.exe - это и есть ассемблер скриптов, а он-же и дезассемблер, если задать соответствующий ключ.

Как им пользоватся? А всё просто:

  • Устанавливаем рабочую папку в папку с .pex файлом, который нужно дезассемлбировать

Ну, это сделать так, чтоб в утилите cmd перед курсором писалось например e:\Skyrim\data\Scripts, короче путь к интересующей нас папке. Это можно сделать набором команд cd или перейти в файлменеджере (напр. Total commander) в нужную папку и в командной строке набрать cmd и нажать "ввод".
В командной строке (можно, даже лучше, создать .bat файл) пишем:

"%gamedir%\Papyrus Compiler\PapyrusAssembler" <имя интересующего нас pex файла, только без расширения> -D

  • Жмём ввод.
  • Итого, если всё написано правильно т. е. если программа написала:

0 error(s), 0 warning(s)
Disassembly succeeded

  • То ищем в папке с .pex файлом файл формата "имя нашего pex файла.disassemble.pas" - это и есть дезассемблированный файл, который хоть и имеет специфический формат, сильно отличающийся от формата psc файла, но уже являющийся текстовым и его можно редактировать.

Итак. Редактировать. А что редактировать? А то же (названия функций принципиально не изменены т. е. забивай в поиск название функции напр. MessageBox (или Message), находи строку, в которой она встречается и редактируй текст в "кавычках".

Пример:
[spoiler="исходный скрипт: (psc)"]

Scriptname _test_testscript extendsObjectReference  
{Тестовыйскрипт
"Привет мир!"}

EventOnActivate(ObjectReference akActionRef)
                Debug.MessageBox("Привет, мир!")
endEvent

[/spoiler]
 
[spoiler=" Дизассемблированый скрипт (pas)"]

Дааа. Многовато..... но не бойся.
        .info
        .source "_test_testscript.psc"
        .modifyTime 1336688266;FriMay1101:17:462012Local
        .compileTime 1336688290;FriMay1101:18:102012Local
        .user "Администратор"
        .computer "USER-B390813CF2"
.endInfo
.userFlagsRef
        .flag hidden 0  ;0x00000000
        .flag conditional 1     ;0x00000001
.endUserFlagsRef
.objectTable
        .object _test_testscript ObjectReference
                .userFlags 0    ;Flags:0x00000000
                .docString "Тестовый скрипт\n\"Привет мир!\""
                .autoState 
                .variableTable
                .endVariableTable
                .propertyTable
                .endPropertyTable
                .stateTable
                        .state 
                                .functionOnActivate
                                        .userFlags 0    ;Flags:0x00000000
                                        .docString ""
                                        .return NONE
                                        .paramTable
                                                .param akActionRef ObjectReference
                                        .endParamTable
                                        .localTable
                                                .local::nonevar NONE
                                        .endLocalTable
                                        .code
                                                CallStatic debug MessageBox::nonevar "Привет, мир!"  ;@line6
                                        .endCode
                                .endFunction
                                .functionGotoState
                                        .userFlags 0    ;Flags:0x00000000
                                        .docString "Function that switches this object to the specified state"
                                        .return NONE
                                        .paramTable
                                                .param newState String
                                        .endParamTable
                                        .localTable
                                                .local::nonevar NONE
                                        .endLocalTable
                                        .code
                                                CallMethod onEndState self::nonevar                     ;@line??
                                                Assign::state newState                                  ;@line??
                                                CallMethod onBeginState self::nonevar                   ;@line??
                                        .endCode
                                .endFunction
                                .functionGetState
                                        .userFlags 0    ;Flags:0x00000000
                                        .docString "Function that returns the current state"
                                        .returnString
                                        .paramTable
                                        .endParamTable
                                        .localTable
                                        .endLocalTable
                                        .code
                                                Return::state                                           ;@line??
                                        .endCode
                                .endFunction
                        .endState
                .endStateTable
        .endObject
.[/size][/size][size=NaN]endObjectTable   [/size]

[/spoiler]
Просмотрел? Увидел строку
CallStatic debug MessageBox ::nonevar "Привет, мир!" ;@line 6
Это и есть интересующее нас место. что тут менять - это и ежу понятно: "Привет мир!" (кавычки сохраняем - они - техническая часть текста)

Ну поменяли. А что дальше? Да всё просто - ассемблируем!
- стираем из имени файла участок .disassemble
- и пишем всё то же, что и при дезассемблировании, только без ключа -D :

"%gamedir%\Papyrus Compiler\PapyrusAssembler" <имя интересующего нас pex файла, только без расширения>

Если всё введено правильно то программа выдаст:

0 error(s), 0 warning(s)
Assembly succeeded

И создаст вожделенный .pex файл, который, ну, используем по назначению.

Всё!
Скачать описание: в помощь переводчику.zip

И ещё по одной...


  PapyrusAssembler

Использование: PapyrusAssembler файл [-D] [-V] [-Q] [-A] [-S] [-?]

Файл имя файла (путь берётся только из "рабочей папки", больше никак), который будет скомпилирован или декомпилирован. файл должен указыватся без расширения! Компилятор ищет файл с расширением ".pas". Декомпилятор ищет расширение ".pex". Внимание! декомпиляция не происходит, если имя файла скрипта не совпадает со стокой, начинающейся с байта 0Х12h в теле скрипта! (в нормальном состоянии строка дублирует имя файла)

  • -D Дезассемблировать объект, если не указан - ассемблирует его.
  • -V Включить подробный режим. (выводит туеву хучу всякой техинфы)
  • -Q Включает тихий режим. (выводятся только сообжения об ошибках)
  • -A Только анализ. Ассемблирование/дезассемблирование не производится.
  • -S Удаляет отладочную информацию из скомпилированного (.pex) файла. Нельзя использовать с -A или -D
  • -? Выводит справочную информацию

 

PapyrusCompiler

Использование: PapyrusCompiler <файл или папка> [<аргументы>]

Объект
Файл Указывает файл для компиляции. (-all не указан)
папка Указвыает папку для компиляции. (-all указан)

Аргументы Один или несколько из следующих:

  • -debug -d Включает режим отладки компилятора, на экран выводится техническая информация.
  • -optimize -op Включает режим оптимизации кода скрипта.
  • -output -o=<путь к каталогу> Указвает каталог для записи скомпилированных скриптов.
  • -import -i=<путь к каталогу> Указвыает папки для импорта библиотек (тоже psc файлы) компилятором, разделённые ";". Обязателен для указания. Путь по умолчанию %gamedir%\data\scripts\source\
  • -flags -f=<путь к файлу> Указывает путь к файлу с флагами, определёнными пользователем. Обязателен для указания. "дефолтный" файл флагов лежит по пути %gamedir%\data\scripts\source\TESV_Papyrus_Flags.flg
  • -all -a Задаёт компилятору скомпилировать все psc файлы в заданной папке. (в качестве объекта должна быть заданна папка).
  • -quiet -q Тихий режим. Отображаются сообжения только об ошибках.
  • -noasm Ассемблер не вызывается и не производится ассемблирование скрипта. (короче только анализ)
  • -keepasm Сохраняет ассемблер файл после завершения работы ассембера. (сохраняет pas файл)
  • -asmonly Создаёт ассемблер файл, но не вызывает ассемблер. (создаёт pas файл, но не создаёт pex файл)
  • -? Выводит справочную информацию.

Файл TESV_Papyrus_Flags.flg (по умолчанию лежит в %gamedir%\data\scripts\source\TESV_Papyrus_Flags.flg
Начинка по умолчанию и её описание:


/*
Формат строк задаётся следующим образом (пробелы игнорируются, index должен содержать 0 - 31 символов):
Flag <name> <index> // Флаг применяется для всех типов
или:
Flag <name> <index> { <список скриптов, параметров, переменных или функций> } // флаг применяется только для указанных типов
*/

// Список флагов для TESV - НЕ РЕДАКТИРОВАТЬ

// Флаг прячет скрипт или параметр от игрового редактора. (ну небось типа в редакторе не отображается)
Flag Hidden 0
{
Script
Property
}

// Флаг на объекте определяет его как скрипт, который будет рассматривать система состояний.
// Флаг на переменоой определяет переменную скрипта как исследуемую системой состояний.
// Сам нихера не полнял, что это значит, но самый близкий перевод.
Flag Conditional 1
{
Script
Variable
}

Скачать описание: папирус-справка.zip
 
® Кащей tesall.ru

Автор: Пакость