えいまぼJEブログ

Minecraft Java Editionに関していろいろ書きます

Minecraftを逆コンパイル(+難読化解除)してソースコードを編集・コンパイルする方法 [Java 1.17]

注意

コンパイルしたコードは公開できません。 後ほど紹介するMCP-Rebornのライセンスで禁止されています。 その他の禁止事項についてはMCP-RebornのMCP-Licenseにあります。 これらの点を注意して逆コンパイル・編集・コンパイルをしましょう。

はじめに

Minecraftの詳しい動作を知りたいとき、ソースコードをただ見るだけよりも、ソースコードにログを吐くコードを追加して挙動を見たほうが理解しやすかったりします。そこで、ソースコードが編集されたMinecraftを作る方法を紹介します。

コンパイルコンパイル

各種ツールのダウンロード

まずは、IntelliJ IDEAMCP-Rebornをダウンロードします。

IntelliJ IDEA

以下のリンクから「ダウンロード」をクリックします。

https://www.jetbrains.com/ja-jp/idea/

f:id:rslatch:20211021124526p:plain

そうするとこのようなページに飛ぶので、Communityのほうをダウンロードします。

ダウンロードできたら、exeなら実行、zipなら展開して適当な場所に置いてください。

MCP-Reborn

以下のリンクからお好みのバージョンのzipファイル(Source codeではないほう)をダウンロードしてください。

https://github.com/Hexeption/MCP-Reborn/releases

f:id:rslatch:20211021124736p:plain

ダウンロードできたら展開して適当な場所に置いてください。

IntelliJ IDEAの操作

ダウンロードできたら、IntelliJ IDEAを開きます。規約の同意と匿名の情報送信について選択したあと、ウィンドウが出ます。そのウィンドウの「Open」をクリックします。

f:id:rslatch:20211021125039p:plain

ファイルの選択ダイアログが出るので、展開したMCP-Rebornの中にあるbuild.gradleを選択して「OK」をクリックします。

f:id:rslatch:20211021125312p:plain

そのファイルをどのように開くか聞かれるので、「Open as Project」をクリックします。

f:id:rslatch:20211021125424p:plain

更に、そのプロジェクトを信頼するか聞かれるので、「Trust Project」をクリックします。

f:id:rslatch:20211021125703p:plain

そうすると自動でプロジェクトのビルドが開始されるので、しばらく待ちます。

f:id:rslatch:20211021125817p:plain

左下に「finished」、右下に「BUILD SUCCESSFUL」などと書かれていれば、ビルドが完了しています。

f:id:rslatch:20211021130053p:plain

ビルドが完了したら、次はセットアップをします。

右端に縦書きで「🍃Gradle」と書いてある部分をクリックします。右上にメニューが出てくるので、mcp-reborn/Tasks/mcpの中のsetupをダブルクリックします。

f:id:rslatch:20211021213344p:plain

これで逆コンパイル(+難読化解除)を含めたセットアップが始まります。左下に「successful」、右下に「BUILD SUCCESSFUL」などと書かれていれば、セットアップが完了しています。

f:id:rslatch:20211021230219p:plain

ここまで来れば、あとはコンパイルしてゲームを起動するだけです。setupの上にあるrunclientをダブルクリックします。

f:id:rslatch:20211021230341p:plain

コンパイルのあと、ゲームが起動します。

f:id:rslatch:20211021230419p:plain

ゲームの起動が確認できたら、この節は終了です。

編集する

さて、次はソースコードを編集します。

今回は、TNTが爆発した瞬間のTNT座標をログファイルに出力するプログラムを挿入します。 Minecraftでは「複数のTNTが近くで同一tickで爆発するとき、先に爆発したTNTの影響を受けて、後に爆発するTNTが爆発直前に移動」します。これをソース編集によって体感します。

では、まずはエンティティのTNTの挙動を記述したファイルを探します。ここでCtrl+Shift+Nキーを押します。

f:id:rslatch:20211023010350p:plain

検索画面が出たので、「tnt」と入力します。

f:id:rslatch:20211023010401p:plain

いろいろなファイルが引っかかりますが、エンティティのTNTPrimedTnt.java*1に記述されているので、それを選択します。

PrimedTnt.javaが開かれるので、このファイルの82行目あたり*2にあるexplosion関数*3の中に以下のコードを挿入します。

System.out.println("(x, y, z) = (" + this.getX() + ", " + this.getY() + ", " + this.getZ() + ")");

場所はどこでも良いですが、とりあえず関数の最初にします。

f:id:rslatch:20211023010453p:plain

挿入したら、runclientをしてゲームを実行します。

そして、以下の動画と同じことをします。TNTを(x, z) = (0.5, 0.5)と(0.5, 2.5)に置き、同時に着火します。y座標は見ないので適当に。

爆発したので、そのログが吐かれています。

ログはrun/logs/latest.logにあります。

f:id:rslatch:20211023012039p:plain

latest.logを開くと、ファイルの末尾に座標が書き込まれているはずです。

f:id:rslatch:20211023012212p:plain
着色が違いますが内容は同じです

このように、爆発した瞬間の座標や爆発の順番がわかります。 爆発の順番は(x, z) = (0.5, 0.5)→(0.5, 2.5)のようです*4。 よく見るとz = 2.5付近で爆発するはずのTNTはz = 3.259で爆発しています。 これは先に爆発したTNTの爆発力で、後に爆発するTNTが飛んだ現象です。 これで「後に爆発するTNTが爆発直前に移動する」ことを体感できたかなと思います。 お疲れさまでした。

その他の編集のヒント

その他のファイルを編集してログを吐かせる場合も、以上と同じ手順でできます。

Tips : 関数の元を見つける

TNTの例では、explosion関数の中にthis.level.explosionという関数が書かれていました。 この関数は何をやっているのか?を追うために、便利なショートカットキーがあります。

this.level.explosionexplosionにカーソルを合わせてCtrl+Alt+Bキーを押します。 これでこの関数が実装されている位置まで飛んでくれます。

このショートカットキーを使って奥深くまで追うことができます。

日本語でコメントできるようにする

このままだと、日本語でコメントするとエラーが出ます。

これは、文字コードを指定すれば解決します。

左のメニューからbuild.gradleを開きます。 開いたファイルの末尾に以下の2行を追記します。

compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'

f:id:rslatch:20211023015801p:plain

これで日本語のコメントを打てるようになります。

(おまけ1) IntelliJ IDEAの日本語化

IntelliJ IDEAの日本語化の方法を紹介します。

左上の「File」から「Settings」をクリックします。

f:id:rslatch:20211023003433p:plain

設定ウィンドウが出ます。左側の「Plugin」をクリックし、検索欄に「japan」と入力します。そうすると日本語化プラグインが出てくるので、それを選択してインストールします。

f:id:rslatch:20211023003453p:plain

インストールができたら「Restart IDE」をクリックしてIntelliJ IDEAを再起動します。

f:id:rslatch:20211023003634p:plain

これで日本語化ができました。

f:id:rslatch:20211023003724p:plain

(おまけ2) Assetsのコピー

何もしない状態では、実行したゲームから音が鳴りません。また、日本語化もできません。 このような音や言語ファイル(Assets)が欲しい場合は、右上のGradleメニューのmcp-reborn/Tasks/mcpからcopyAssetsを実行します。

f:id:rslatch:20211023000237p:plain

実行したあと、左下に「successful」、右下に「BUILD SUCCESSFUL」などと書かれていれば、Assetsのコピーが完了しています。

このままrunclientでゲームを実行すれば、音が出てくるはずです。

(余談) yarnについて

yarnというツールがあります。 これは逆コンパイルと難読化解除までをしてくれるツールです。 編集とコンパイルはできません。 特徴としては、難読化解除後の名前がMCP-Rebornと違う点です。 MCP-Rebornよりわかりやすい命名なこともあるので、見比べると理解が早くなるかもしれません。 yarnの使い方についてはこちらを参照ください。ただし、バージョン1.17以降はJava16のパスを通す必要があり、手順が増えることに注意してください。

参考動画

*1:バージョンによって名前が異なる場合があります

*2:バージョンによって場所が異なる場合があります

*3:バージョンによって名前が異なる場合があります

*4:この順番はおそらく方角や座標に依存します