2019年12月3日火曜日

Lua のデコンパイルとコンパイル

Renowned Explorers: International Society で使用されているコンパイル済み Lua ファイルからソースを復元する方法がわかりましたので、メモを残しておきます。
この記事は「お~るげーむず(仮)」さんから頂いた情報を元に作成しました。ありがとうございました。
「お~るげーむず(仮)」
https://agk.saloon.jp/



Renowned Explorers の日本語化については、以下のサイトを御覧ください。
「RE:IS 日本語化作業所」
https://docs.google.com/spreadsheets/d/1K_ystmDAq6fkRNPV7VMvSBWxqbqLpBSzZgti-ICaaV4/edit#gid=1501760049

この記事は書きかけのものです。
現在、手順通りに作業をしてもゲームが正しく動作しませんので、ご注意ください。


この例では、Sドライブに "LuaUtils" フォルダーを作成し作業を行うことにします。

1.Renowned Explorers Unpacker/Repacker


これは、ゲームの data フォルダーにある、"content.tim" を Unpack/Repack するツールです。今回は、ReisUnpack Version 0.3 を使用します。
ここから、ReisUnpack.0.3.zip をダウンロードします。
「AndrewSav/ReisUnpack: This is an unpacker for resource files of [Renowned Explorers: International Society] game」
https://github.com/AndrewSav/ReisUnpack

解凍した後、フォルダー "ReisUnpack.0.3" を "S:\LuaUtils" に移動します。


2.LuaJIT-Decompiler


2.1.ダウンロード


コンパイル済みの Lua ファイルをデコンパイルし、Lua のソースを出力するツールです。ここから、Python のソースをダウンロードします。
「Campbell Suter (ZNix) / luajit-decompiler · GitLab」
https://gitlab.com/znixian/luajit-decompiler
このツールを実行するためには Python 3 が必要です。必要に応じインストールしておいてください。この例では、Python 3.6 を使用しています。

解凍したフォルダー "luajit-decompiler-master" を "S:\LuaUtils" に移動します。


2.2.ソースの修正


今回使用したバージョンでは、文字列リテラルのブロック内("[[" で始まり "]]" で終わる)に、"[" や "]" があると正しくソースが出力されないので修正します。

"luajit-decompiler-master\ljd\lua\writer.py" を開き Python のソースを次の通り修正します。
840行目
変更前:self._write("[[")
変更後:self._write("[==[")
846行目
変更前:self._write("]]")
変更後:self._write("]==]")
これで、正しい Lua ソースが出力されるようになります。
【参考】
「Lua リファレンスマニュアル:2.1 - 字句の構成」
http://milkpot.sakura.ne.jp/lua/lua51_manual_ja.html#2.1


3.LuaJit


3.1.ダウンロード


Lua のソースをコンパイルするツールです。今回は、LuaJit Version 2.0.5 を使用します。ここから、LuaJit-2.0.5 をダウンロードします。
「LuaJIT - Download」
http://luajit.org/download.html

解凍したフォルダー "LuaJIT-2.0.5" を "S:\LuaUtils" に移動します。


3.2.コンパイル


次の手順でコンパイルします。コンパイルには Visual Studio 2017 を使用しました。
  • スタートメニューの "Visual Studio 2017" から "x86 Native Tools Command Prompt for VS 2017" を開く。
  • 解凍したフォルダー "S:\LuaUtils\LuaJIT-2.0.5\src" に移動する。
  • "msvcbuild.bat" を実行する。
エラーが出なければ、完了です。これで "S:\LuaUtils\LuaJIT-2.0.5\src" フォルダーに次のファイルが作成されます。
  • luajit.exe
  • lua51.dll

実行フォルダーの作成

"S:\LuaUtils\LuaJIT-2.0.5" フォルダーに "bin" フォルダーを作成し、上記 "luajit.exe" と "lua51.dll" を移動します。次に "S:\LuaUtils\LuaJIT-2.0.5\bin" フォルダーに "lua" フォルダーを作成し、"S:\LuaUtils\LuaJIT-2.0.5\src\jit" フォルダーをコピーします。

作業後のフォルダー構成:

S:\LuaUtils\LuaJIT-2.0.5
│  
├─bin
│  │  lua51.dll
│  │  luajit.exe
│  │  
│  └─lua
│      └─jit
│              bc.lua
│              bcsave.lua
│              dis_arm.lua
│              dis_mips.lua
│              dis_mipsel.lua
│              dis_ppc.lua
│              dis_x64.lua
│              dis_x86.lua
│              dump.lua
│              v.lua
│              vmdef.lua




4.Unpack


次のコマンドでゲームの "data" フォルダーにある "content.tim" を Unpack します。
ReisUnpack.exe unpack content.tim content
これで、content フォルダーに解凍されます。この処理は結構時間がかかります。一時間くらいかかったかもしれません。


5.デコンパイル


翻訳対象のファイル "lua\abbeybase\i18n.lua" をデコンパイルします。
コマンドの形式は、次のとおりです。
python main.py -f "i18n.lua" -o "i18n.decompiled.lua" --catch_asserts
ただ、このままでは上手く実行できません。太字部分のファイルはフルパスで指定してください。

これで、テキスト化された Lua ファイルが手に入ります。


6.コンパイル


LuaJIT を使用して、Luaファイルをコンパイルします。
コンパイルは次のコマンドで行います。
luajit.exe -b "i18n.decompiled.lua" "i18n.lua"


7.Repack


次のコマンドで Repack します。
ReisUnpack.exe repack (フォルダー名) jp_content.tim -m 0
"-m" は圧縮率です。"-m 0" は圧縮率は低いが速度が早いです。デフォルト値は "-m 4" で、圧縮率は高いが速度が遅いです。

Repackは全てのファイルをRepackする必要はなく、日本語化で必要なフォルダーとファイルのみを入れておきます。基本的には、"i18n.lua" と日本語フォントを入れておけばOKです。"*.tim" はアルファベット順に読み込まれ、後から読み込んだものが優先的に使用されるようです。

Repackするフォルダーの構成:
jp_content
│  arial.ttf
│  arialb.ttf
│  arialbi.ttf
│  ariali.ttf
│  default.ttf
│  defaultb.ttf
│  defaultbi.ttf
│  defaulti.ttf
│  header.ttf
│  headerb.ttf
│  headerbi.ttf
│  headeri.ttf
│  
└─lua
    └─abbeybase
            i18n.lua

Repackしたファイルをゲームのdataフォルダーにコピーします。
コピー後のゲームのdataフォルダー:

これで、一通りの作業は終わりですが、Repack した "jp_content.tim" を使用した場合、ゲームがクラッシュし起動できません。今の所原因不明です。日本語化MODの作業所で公開されている "i18n.lua" を使用した場合は正しく起動できるので LuaJIT のバージョンが問題なのかもしれません。
う~む、残念。

では・・・



0 件のコメント:

コメントを投稿

Raspberry Pi 3 Model A+ で広告ブロックサーバーを作る(その2)

前回作成した 広告ブロックサーバー の稼働状況をAmbientにアップロードするスクリプトを書いたのでメモを残しておきます。