сайтец /dev/urandom

gxter, утилита для работы с файлами GXT

В недавнее время я разработал на языке Rust небольшую библиотеку и консольную утилиту для чтения и создания файлов в формате GXT из старых игр серии Grand Theft Auto. Файлы GXT (описание формата, на англ.) состоят из списка локализируемых текстовых строк, используемых как самим кодом игры, так и внутри игровых скриптов (включая миссии). Использование таких файлов было полезным для разработчиков, так как они с самого начала были готовы выпустить игру на множестве разных языков.

Программа поддерживает файлы из игр GTA III, Vice City и San Andreas, и была на этих файлах протестирована. Также возможна работа с играми из серии “Stories”, так как они обе основаны на “движке” Vice City.

Пакеты и установка

На данный момент, лучший способ установить библиотеку или утилиту – это использовать cargo, менеджер пакетов языка программирования Rust. Для установки библиотеки gxter в свой проект, запустите следующую команду в папке этого проекта:

cargo add gxter

А этой командой можно установить консольную утилиту в свою систему:

cargo install gxter-cli

Использование утилиты gxter-cli

Программа работает в двух режимах. По умолчанию она “компилирует” текстовый файл в файл GXT. Если указать параметр -d, то программа переходит в режим “декомпиляции” и вместо этого создаёт текстовый файл на основе существующего файла GXT. Текстовые файлы основаны на формате TOML и выглядят примерно так:

format = "Three"

[main_table]
1000 = "YOU ARE DEAD"
1001 = "YOU ARE DEAD"
1002 = "YOU ARE DEAD"
1003 = "YOU ARE DEAD"
1004 = "YOU ARE DEAD"
1005 = "BUSTED"
1006 = "BUSTED"
...

Первая строка задаёт формат файла GXT. Каждый формат имеет немного разную процедуру чтения и записи, а также меняются некоторые ограничения. Поддерживаются четыре формата.

После этого начинается секция [main_table], содержащая имена и значения строк. В форматах “Three” и “Vice” имя строки – это текст длиной до 8 байт (хотя на практике максимальная длина – 7 байт, и проверить, могут ли вообще игры читать имена строк длиной в 8 байт, ещё не удалось, но сам формат это позволяет).

Если используется формат “Vice”, “San8” или “San16”, то файл может содержать дополнительные таблицы, каждая из которых будет иметь секцию [aux_tables.NAME], где NAME заменяется на имя таблицы. Оно также ограничивается 8 (а на практике – 7) байтами.

Если используется формат “San8” или “San16”, то строки хранятся не по именам, а по контрольным суммам, полученным через алгоритм CRC32. При открытии файла GXT эти “хэши” будут записаны, как строки, начинающиеся с символа решётки и содержащие значение контрольной суммы в шестнадцатеричном виде (например, #01234567). Если получится, что у строки есть настоящее имя, которое действительно начинается со знака решётки, то он дублируется (например, ##NAME).

По умолчанию, при декомпиляции файла GXT строки выводятся в порядке их “ключей”, что на практике означает сортировку имён строк по ASCII (или контрольных сумм как чисел). Но также возможно использовать порядок по “адресам” (по расположению самих строк в файле), который выдаёт довольно интересные результаты. Создаётся ощущение, что строки были постепенно добавлены в процессе разработки или как-то упорядочены по категориям. Например, последние “адреса” строк в файлах GTA III все относятся к дополнительным функциям ПК-версии игры. А вот так выглядят самые первые строки “по адресам”:

format = "Three"

[main_table]
LETTER1 = """abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBF"""
DEFNAM = "Claude----------------------"
IN_VEH = "~g~Hey! Get back in the vehicle!"
IN_VEH2 = "~g~You need some wheels for this job!"
IN_BOAT = "~g~You need a boat for this job!"
HEY = "~g~Don't go solo, keep your posse together!"
HEY2 = "~g~Don't split up, keep the group together!"
HEY3 = "~g~You've dropped your main man, go back and get 8-Ball!"

(Стоит упомянуть, что строка DEFNAM не используется в финальной версии игры. Первая и вторая игры GTA обе позволяли игроку назвать своего персонажа, а GTA III – нет. Даже тот факт, что протагониста GTA III зовут Клод, стал официально известен только из GTA: San Andreas.)

gxter имеет встроенные таблицы символов для американско-европейских версий игр (на английском, немецком, французском, итальянском и испанском языках), но также поддерживает использование внешних таблиц для любых других переводов. Исходный код содержит уже собранные таблицы для двух популярных пиратских переводов GTA: Vice City и San Andreas на русский язык. Эти переводы переназначают некоторые символы с латиницы или западноевропейских алфавитов на кириллицу, чтобы было возможным писать текст на оригинально неподдерживаемом языке. Если кому-то понадобится перевести одну из игр GTA на ещё какой-то язык, то также будет необходимо составить новую таблицу символов (и изменить используемые шрифты, конечно). Вот так, например, при использовании соответствующей таблицы выглядит одна из самых известных строк из пиратского перевода GTA: San Andreas:

"#C0EBC586" = " ~z~ОНА - СО МНОЙ, УГЛЕПЛАСТИК. ТАК ОХЛАДИТЕ ТРАХАНИЕ. Я РАССМАТРИВАЮ ЕЕ ПОЛЬЗУ."

Также для работы с файлами форматов “San” программа умеет принимать “списки имён”. Имена строк, указанные в таком списке, сразу же используются для вычисления контрольных сумм, и после этого совпадающим строкам из файла GXT назначается соответствующее имя.

Использование библиотеки gxter

Документация для библиотеки gxter доступна на английском языке на сайте docs.rs. Самая важная структура библиотеки – это GXTFile, которая содержит все используемые строки. Эта структура поддерживает чтение из файлов GXT, запись в файлы GXT, а также работу с текстовыми файлами, формат которых был описан выше. После чтения файла данные структуры содержатся в легко-читаемом формате. Главная таблица, а также все дополнительные, хранятся в структурах типа [IndexMap](https://docs.rs/indexmap) (это вариант структуры HashMap, сохраняющий порядок значений) с индексами в виде строк.

Ссылки

Исходный код и подробные инструкции (англ.)