« Minecraft MOD開発 8 | トップページ | Minecraft MOD開発 10 »

2014年3月16日 (日)

Minecraft MOD開発 9

jarに含めたファイルをMODからアクセスしたい。

デフォルト値をソースコード中に記述するのは面倒なので、
1. .minecraft/config/下の設定ファイルを読みに行く
2. 見つからなければjar中の設定ファイルを読み、同内容を.minecraft/configにセーブする
という動作にしたい。

こちらを参考に、まずMODが呼ばれるときのカレントディレクトリを調べる。

PrintCWD.java

package nishina;
 
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
 
@Mod(modid="PrintCWD", name="PrintCWD", version="1.0")
public class PrintCWD
{
 @EventHandler
 public void init(FMLInitializationEvent event)
 {
  System.out.printf( "PrintCWD: CWD=%s\n", System.getProperty("user.dir"));
 }
}

開発環境でのカレントディレクトリはmcpの中のjarsへ向いているようだ。

C:\forge-1.6.4-9.11.1.965-src\forge\mcp>startclient
== MCP 8.09 (data: 8.11, client: 1.6.4, server: 1.6.4) ==
(中略)
[18:18:48] 2014-03-16 18:18:48 [情報] [STDOUT] PrintCWD: CWD=C:\forge-1.6.4-9.11.1.965-src\forge\mcp\jars

では本番環境へ持って行くためにreobfuscateする。

C:\forge-1.6.4-9.11.1.965-src\forge\mcp>reobfuscate.bat
== MCP 8.09 (data: 8.11, client: 1.6.4, server: 1.6.4) ==
"scalac" is not found on the PATH.  Scala files will not be recompiled
# found ff, ff patches, srgs, name csvs, doc csvs, param csvs, astyle, astyle config, rg, ss
> Creating Retroguard config files
== Reobfuscating client ==
> Cleaning reobf
> Generating md5s
> Packing jar
> Reobfuscating jar
> Extracting modified classes
> New class found      : nishina/pink_item_fuelhandler
> New class found      : nishina/pink_item
> New class found      : nishina/pink_item_core
> New class found      : nishina/pink_block
> New class found      : nishina/PrintCWD
> New class found      : mods/alchemy_sample
> New class found      : nishina/pink_block_core
> Outputted nishina/pink_item_fuelhandler       to reobf\minecraft as nishina/pink_item_fuelhandler.class
> Outputted nishina/pink_item                   to reobf\minecraft as nishina/pink_item.class
> Outputted nishina/pink_item_core              to reobf\minecraft as nishina/pink_item_core.class
> Outputted nishina/pink_block                  to reobf\minecraft as nishina/pink_block.class
> Outputted nishina/PrintCWD                    to reobf\minecraft as nishina/PrintCWD.class
> Outputted mods/alchemy_sample                 to reobf\minecraft as mods/alchemy_sample.class
> Outputted nishina/pink_block_core             to reobf\minecraft as nishina/pink_block_core.class
- Done in 3.66 seconds
!! Can not find server md5s !!
続行するには何かキーを押してください . . .
 
C:\forge-1.6.4-9.11.1.965-src\forge\mcp>

classファイルをjarへ入れる。

C:\forge-1.6.4-9.11.1.965-src\forge\mcp>cd reobf
 
C:\forge-1.6.4-9.11.1.965-src\forge\mcp\reobf>cd minecraft
 
C:\forge-1.6.4-9.11.1.965-src\forge\mcp\reobf\minecraft>jar cvf PrintCWD.jar nishina/PrintCWD.class
マニフェストが追加されました
nishina/PrintCWD.classを追加中です(入=1055)(出=580)(45%収縮されました)

本番環境で実行するとForgeModLoader-client-0.logに以下のログが出た。

2014-03-16 18:27:19 [情報] [STDOUT] PrintCWD: CWD=C:\Users\ユーザー\AppData\Roaming\.minecraft

こちらのページによると、JarFile.getJarEntryでjarファイル内を読めるようだ。

こういう内容を記述したhello.txtを用意する。

Hello world from JAR!.

/mods/ReadJAR.jarの中からnishina/hello.txtを見つけて1行表示するプログラムを書く。例外のキャッチがめんどくさい。JarFileがInputStreamしか返してくれないから、BufferedInputStream→InputStreamReader→BufferedReaderと変換していくのもめんどくさい。jarの中のテキストフィルを読む可能性を考えていなかったのだろうか。

ReadJAR.java

package nishina;
 
import java.io.*;
import java.util.jar.*;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
 
@Mod(modid="ReadJAR", name="ReadJAR", version="1.0")
public class ReadJAR
{
 @EventHandler
 public void init(FMLInitializationEvent event)
 {
  String CWD = System.getProperty("user.dir");
  System.out.printf( "ReadJAR: CWD=%s\n", CWD);
  String JarPath = CWD + "/mods/ReadJAR.jar";
  System.out.printf( "ReadJAR: JarPath=%s\n", JarPath);
  
  File f = new File( JarPath);
  
  JarFile jf;
  try
  {
   jf = new JarFile( f);
  }
  catch( Exception e)
  {
   System.out.printf( "ReadJAR: new JarFile failed.\n");
   return;
  }
  
  JarEntry entry = jf.getJarEntry("nishina/hello.txt");
  if( entry == null)
  {
   System.out.printf( "ReadJAR: jf.getJarEntry failed.\n");
   return;
  }
  
  
  BufferedInputStream in;
  try
  {
   in = new BufferedInputStream(jf.getInputStream(entry));
  }
  catch( Exception e)
  {
   System.out.printf( "ReadJAR: new BufferedInputStream(jf.getInputStream(entry)) failed.\n");
   return;
  }
  
  InputStreamReader re;
  try
  {
   re = new InputStreamReader( in, "UTF8");
  }
  catch( Exception e)
  {
   System.out.printf( "ReadJAR: new InputStreamReader( in, \"UTF8\") failed.\n");
   return;
  }
  
  BufferedReader br = new BufferedReader( re);
  
  String Content;
  try
  {
   Content = br.readLine();
  }
  catch( Exception e)
  {
   System.out.printf( "ReadJAR: br.readLine() failed.\n");
   return;
  }
  
  System.out.printf( "ReadJAR: Content=%s\n", Content);
 }
}

このMODはjarの中を読むため、開発環境でもjarファイルを必要とする。hello.txtとReadJAR.classを含むReadJAR.jarを作成する。

C:\forge-1.6.4-9.11.1.965-src\forge\mcp>cd bin/minecraft
 
C:\forge-1.6.4-9.11.1.965-src\forge\mcp\bin\minecraft>dir nishina
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 7422-11C4 です
 
 C:\forge-1.6.4-9.11.1.965-src\forge\mcp\bin\minecraft\nishina のディレクトリ
 
2014/03/16  19:34    〈DIR〉        .
2014/03/16  19:34    〈DIR〉        ..
2014/03/16  18:40                24 hello.txt
2014/03/16  19:34               803 pink_block.class
2014/03/16  19:34             1,832 pink_block_core.class
2014/03/16  19:34               758 pink_item.class
2014/03/16  19:34             1,802 pink_item_core.class
2014/03/16  19:34               687 pink_item_fuelhandler.class
2014/03/16  19:34             1,047 PrintCWD.class
2014/03/16  19:34             3,084 ReadJAR.class
               8 個のファイル              10,037 バイト
               2 個のディレクトリ  10,666,364,928 バイトの空き領域
 
C:\forge-1.6.4-9.11.1.965-src\forge\mcp\bin\minecraft>jar cvf ReadJAR.jar nishina/ReadJAR.class nishina/hello.txt
マニフェストが追加されました
nishina/ReadJAR.classを追加中です(入=3084)(出=1520)(50%収縮されました)
nishina/hello.txtを追加中です(入=24)(出=26)(-8%収縮されました)

できたReadJAR.jarをC:\forge-1.6.4-9.11.1.965-src\forge\mcp\jars\modsにコピーして、startclient.batでテストする。ForgeがReadJARが重複しているとエラーを出した。

開発環境のReadJAR.jarからはReadJAR.classを削除して、もう一度実行する。

ForgeModLoader-client-0.logにメッセージが表示された。

2014-03-16 19:43:47 [情報] [STDOUT] ReadJAR: Content=Hello world from JAR!.

これを本番環境へ持って行く。まずreobfuscateする。

C:\forge-1.6.4-9.11.1.965-src\forge\mcp>reobfuscate.bat
== MCP 8.09 (data: 8.11, client: 1.6.4, server: 1.6.4) ==
"scalac" is not found on the PATH.  Scala files will not be recompiled
# found ff, ff patches, srgs, name csvs, doc csvs, param csvs, astyle, astyle config, rg, ss
> Creating Retroguard config files
== Reobfuscating client ==
> Cleaning reobf
> Generating md5s
> Packing jar
> Reobfuscating jar
> Extracting modified classes
> New class found      : nishina/pink_item_fuelhandler
> New class found      : nishina/pink_item
> New class found      : nishina/pink_item_core
> New class found      : nishina/pink_block
> New class found      : nishina/ReadJAR
> New class found      : nishina/PrintCWD
> New class found      : mods/alchemy_sample
> New class found      : nishina/pink_block_core
> Outputted nishina/pink_item_fuelhandler       to reobf\minecraft as nishina/pink_item_fuelhandler.class
> Outputted nishina/pink_item                   to reobf\minecraft as nishina/pink_item.class
> Outputted nishina/pink_item_core              to reobf\minecraft as nishina/pink_item_core.class
> Outputted nishina/pink_block                  to reobf\minecraft as nishina/pink_block.class
> Outputted nishina/ReadJAR                     to reobf\minecraft as nishina/ReadJAR.class
> Outputted nishina/PrintCWD                    to reobf\minecraft as nishina/PrintCWD.class
> Outputted mods/alchemy_sample                 to reobf\minecraft as mods/alchemy_sample.class
> Outputted nishina/pink_block_core             to reobf\minecraft as nishina/pink_block_core.class
- Done in 3.87 seconds
!! Can not find server md5s !!
続行するには何かキーを押してください . . .

hello.txtをC:\forge-1.6.4-9.11.1.965-src\forge\mcp\reobf\minecraft\nishinaへコピーして、jarを作成する。

C:\forge-1.6.4-9.11.1.965-src\forge\mcp>cd reobf/minecraft
 
C:\forge-1.6.4-9.11.1.965-src\forge\mcp\reobf\minecraft>jar cvf ReadJAR.jar nishina/ReadJAR.class nishina/hello.txt
マニフェストが追加されました
nishina/ReadJAR.classを追加中です(入=3071)(出=1515)(50%収縮されました)
nishina/hello.txtを追加中です(入=24)(出=26)(-8%収縮されました)

本番環境のmodsフォルダへReadJAR.jarを置いて実行したら、ForgeModLoader-client-0.logにメッセージが表示され成功した。

2014-03-16 19:51:31 [情報] [STDOUT] ReadJAR: Content=Hello world from JAR!.

これでMODの設定ファイルをjar内から読み込む技術的めどが立った。面倒くさいけどね。

本番環境用のPrintCWD.jarReadJAR.jarです。Minecraft 1.6.4+Minecraft Forge-1.6.4-9.11.1.965用です。modsフォルダの中へ入れて使ってください。ForgeModLoader-client-0.logへメッセージを記録します。

« Minecraft MOD開発 8 | トップページ | Minecraft MOD開発 10 »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1499066/55394722

この記事へのトラックバック一覧です: Minecraft MOD開発 9:

« Minecraft MOD開発 8 | トップページ | Minecraft MOD開発 10 »