提供: Minecraft Modding Wiki
2012年8月21日 (火) 16:00時点におけるScalar (トーク | 投稿記録)による版 (ページの作成:「{{前提MOD|reqmod="ModLoader"}} ==mod の逆コンパイル Tips== このページでは mod がどのようにして動作しているのかを知るため、Java ...」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

この記事は"ModLoader"を前提MODとしています。

mod の逆コンパイル Tips

このページでは mod がどのようにして動作しているのかを知るため、Java ソースファイルに変換するための Tips を記述します。

もっとも簡単な方法

mcp で逆コンパイルを行う前に minecraft.jar に mod の class ファイルをいれておけば、一緒に逆コンパイルしてくれるそうです。
この方法ですと難読化も解除してくれるので楽に読みやすいソースファイルが手に入ります。

手作業で逆コンパイルをする場合

mcp での作業後に新たに mod を逆コンパイルする場合、手作業で難読化を解除することになります。
量が多いとかなり大変なので、大型の mod の場合は mcp で再度逆コンパイルすることをおすすめします。
ここでは小型・単機能の mod を手作業で難読化解除する方法について記述します。

jad で class ファイルをソースファイルに変換する。
eclipse で強制的に class ファイルを読ませても逆コンパイルできたような…。
mcp/conf の中にある client.srg を開きます。今回は mcp62(本体ver1.2.5用)を使います。
mcp は mod の対応バージョンをよく確認して選んでください。
本体ver1.2.5用の mod なのに、mcp72(ver1.3.2用)を使ったりすると悲惨なことになります。
このファイルはテキストエディタで開けます。
この中にクラス、フィールド、メソッドが記述されています。
行の先頭が CL ならクラス、FD がフィールド、MD がメソッドになります。
ソースを開き、クラスと思われる部分を置換していきます。
例)aan itemstack = ~~;
aan がクラス名になりますので client.srg から検索します("CL: aan" とかね)。
この例ですと変数名から類推可能ですが、「CL: aan net/minecraft/src/ItemStack」となります。
例)if (entity instanceof fq)
正規表現「^CL: fq 」で検索します。EntityItem ですね。
クラス名を解除できたら、次はフィールドです。
例)if(!entity.G)
entity は Entity クラスのインスタンスです。
今度はクラス名から難読化後の名称を調べます。
正規表現「^CL:.*/Entity$」で検索します。「CL: nn net/minecraft/src/Entity」が見つかります。
このクラスのフィールド G ですので、「^FD: nn/G 」を検索します。「FD: nn/G net/minecraft/src/Entity/field_646_aA」が見つかります。
mcp/conf/fields.csv を開きます。テキストエディタがいいかも?
「field_646_aA」を検索すれば、フィールド名が見つかります。「isDead」です。
結果)if(!entity.isDead)
同じようにして、メソッド名も methods.csv から探します。
メソッド名は場合によって、同一メソッド名が複数存在します。引数が異なることでオーバーロードできるためです。
その場合は引数や戻り値の型からどのメソッドかを調べてください。
例)MD: acb/a ()Z net/minecraft/src/BlockDoor/func_217_b ()Z
これは引数なし、戻り値 Z、つまり boolean のメソッドです。
カッコ内が引数の型、カッコの後ろについているのが戻り値の型です。
例)MD: acb/a (Lali;III)V net/minecraft/src/BlockDoor/func_238_a (Lnet/minecraft/src/IBlockAccess;III)V
「Lali;」は L とセミコロンの間にある ali がクラス名になります。後ろをみればわかりますが、これは IBlockAccess インターフェイスです。
I は int、V は void です。III だと int 型の引数を3つ持ちます。
よって void func_238_a(IBlockAccess b, int i, int j, int k) になります。
同様に F は float、D が double になります。