hogepiyo

かつてはマイクラのModを作っていたがひざに矢を受けた

開発環境と実環境の検出とか

開発環境と実環境の違い

 開発環境と実環境は同じなようで違う. 1つは開発環境で操作するプレイヤーは, IDが適当(Player+数字)なことと, 実行時のクラス名, フィールド名, メソッド名が違うこと.

1.4まで

 1.4までは開発環境ではdeobfuscate, すなわち難読化解除状態でコードを書き, reobfuscate.batでバニラ側のクラス名などを難読化していた. そのためリフレクションを使うときに, フィールド名やメソッド名でアクセスするときに開発環境と実環境で名前が異なるために例外が投げられていた.

 これを解決するために, 開発環境ならリネーム名を, 実環境なら難読化名を使ってリフレクションするようにしていた. その違いを検出するために以下のようにしていた.

String methodName = !ObfuscationReflectionHelper.obfuscation ? "rename" : "a"; 

1.5から

 1.5から, 動的難読化解除の機能がFMLで追加され, 難読化テーブルが変わるマイナーアップデートに対応しなくてもModが動作するようになった. しかしこの機能によって上記の方法で環境の違いを検出できなくなった(そもそもobfuscationフィールドがなくなった).

結論

 色々調べた結果

ReflectionHelper.getPrivateValue(RelaunchLibraryManager.class, null, "deobfuscatedEnvironment");

RelaunchLibraryManagerに(privateだが)deobfuscatedEnviromentというbooleanフィールドがあったのでそれをリフレクションで取ってきたら環境の違いを検出できた.

 とはいえ今までと異なり実環境ではsrg名を使うようにしなければならないので, ややめんどうではある.