-
Notifications
You must be signed in to change notification settings - Fork 65
Extend with JavaScript
航海日誌拡張版1.6.0から外部スクリプトによる拡張が実装されました。同時に艦娘一覧などの一部のテーブルはスクリプトによる実装になりました。航海日誌拡張版はJavaScriptで拡張できます。
- テーブルの項目を増やす
- テーブルのデザインを変える
- データ受信時に処理をする
logbook.jarと同じフォルダにあるscriptフォルダの下にスクリプトを置くと自動的に読み込まれます。スクリプトのファイル名は、どこに対する拡張かによって決まっています。
艦娘一覧テーブルなどは、ほぼすべての表示項目がスクリプトで生成されています。また、テーブル項目の色などのデザインもスクリプトで制御されています。デフォルトで用意されているスクリプトを見ればだいたい分かると思います。
注意点をいくつか
-
スクリプトファイルはUTF-8で保存してください。UTF-8でないと
java.nio.charset.MalformedInputExceptionが発生します。 -
航海日誌拡張版に同梱してあるスクリプトは今後のアップデートで変更される可能性があります。新しく列を追加するような場合は、なるべく新しくjsファイルを作るようにしてください。
-
例外を吐く場合は、
logs/script.logに例外情報が出力されるのでそれを見てください。JavaScript中で例外が発生した場合はスタックトレースに<eval>:62のように行数が表示されます。ちなみに、このファイルは航海日誌拡張版を起動する度に前のログが削除されます。
スクリプトのファイル名は以下のようになります。各スクリプトについては下の方に解説があります。
-
テーブルプリフィックス_*.js: テーブルの項目を増やすスクリプト
例: ship_hoge.js, drop_hage.js, ... -
テーブルプリフィックスstyle.js: テーブルのデザインを変えるスクリプト
例: shipstyle.js, dropstyle.js, ... -
update_*.js: データ受信時に処理をするスクリプト
例: update_hoge.js, update_bar.js, ...
テーブルプリフィックスは例えば艦娘一覧テーブルだったらship、ドロップ報告書だったらdropのようにテーブルごとに決まっています。*は任意の文字列です。
| テーブル名 | テーブルプリフィックス |
|---|---|
| ドロップ報告書 | drop |
| 艦娘一覧 | ship |
| 装備一覧 | item |
| 遠征一覧 | mission |
| グループエディタ | shipgroup |
| 開発報告書 | createitem |
| 建造報告書 | createship |
| 遠征報告書 | missionresult |
| 任務一覧 | quest |
| 資材チャート | resource |
航海日誌拡張版はJava8に実装されているJavaScriptエンジンNashornを使って実行します。 JavaScriptからJavaへのアクセス方法は、The Nashorn Java APIによくまとまっています。(日本語は知らん)
スクリプトでテーブルのカラムを増やすことができます。
現在対応しているテーブルと、スクリプトが実装すべきインターフェースは以下の通り
| テーブル | スクリプトが実装すべきインターフェース |
|---|---|
| ドロップ報告書 | logbook.scripting.BattleLogListener |
| 艦娘一覧 | logbook.scripting.ShipItemListener |
| 装備一覧 | logbook.scripting.ItemInfoListener |
| 遠征一覧 | logbook.scripting.MissionListener |
| 任務一覧 | logbook.scripting.QuestListener |
航海日誌拡張版に付属のスクリプト ship_remodel.js を例に説明します。このスクリプトは艦娘が改造可能かどうかの列を艦娘一覧テーブルに追加します。以下、このスクリプトの全文です。コメントは説明のために追加しました。
load("script/utils.js");
function header() {
return [ "改造可能" ];
}
function begin(specdiff) { }
function body(ship) {
var afterlv = ship.shipInfo.afterlv; // ※1
var canRemodel = (afterlv > 0) && (ship.lv >= afterlv);
return toComparable([ canRemodel ? "可能" : null ]);
}
function end() { }
JavaのインターフェースをJavaScriptで実装するにはそのインターフェースの全てのメソッドをグローバルスコープの関数として定義します。ShipItemListenerインターフェースには4つのメソッド(header(),begin(),body(),end())があるので、スクリプトにはこの全てのメソッドを定義する必要があります。ただし、本当に重要なのはテーブルの列ヘッダーを返すheader()と、各レコードに対する表示内容を返すbody()の2つで、begin(),end()は特にやることがなければ空でOKです。
header()は、追加する列のヘッダーを配列で返します。body()はShipDtoを引数に取り、その艦娘が改造可能かを計算して、返しています。
渡されたオブジェクトからのデータの取り出し方法は、大きく以下の2つの方法があります。
- 航海日誌がJSONから取得済みのデータをオブジェクト(ここでは
ShipDtoなど)から取り出す - JSONを取り出して自分で見に行く
上記例は1の方法で取得しています。どんなデータが取り出せるかなどはJavadocを参照してください。
上記例では使っていませんが、航海日誌が取得していないデータなどはJSONから取り出す必要があります。ship.getJson()でJSONに直接触れます。艦これのJSONの仕様はAndanteさんのドキュメントを参照してください。ship.getJson()で取得できるJSONは、api_port/portのapi_shipです。
※1の行で、ship.shipInfo.afterlvとありますが、これはship.getShipInfo().getAfterlv()と同じです(NashornのJava APIにより短縮形が書けるようになっています。)。同じように、JSONにアクセスするときはjson.getJsonObject("hoge")などとする必要はなく、json.hogeで直接アクセスできます。
-
注意点1:
body()の戻り値はComparable[]です。上のスクリプトではtoComparable()(script/utils.jsで定義されています)でJavaScriptの配列からJavaの配列に変換していますが、実はJavaScriptの配列をそのまま返しても動きます。ただし、現在のNashornエンジンだとJavaScriptの配列をそのまま返すと型変換によりかなり遅くなることが分かっています。toComparable()を使ってJavaの配列に変換してから返すようにしてください。 -
注意点2: JavaScriptによる実装はJavaに比べてかなり遅いです。特にJavaScriptの配列とJavaの配列の相互変換(
Java.to()など)はかなり遅いようです。遅いコードを走らせてしまうと、GUIがもっさりするようになったり、戦闘履歴のロードが終わらなくなってしまうので(マジで!)、気をつけてください。
ドロップ報告書に対空カットインを追加するサンプルが templates\samples\drop_taiku_cutin.js にあります。
ユーザのゲーム情報のほとんどはGlobalContextから取得できます。引数で渡されたデータだけでなく、GlobalContextからもデータを取得して表示することができます。
スクリプトは航海日誌動作中に動的に読み込まれるので、スクリプトを変更した場合、次にテーブルの再読み込みが走った時に反映されます。ただし、起動中のヘッダーの変更には対応していないため、航海日誌が起動後最初に読み込んだヘッダーは、航海日誌が再起動するまで変更できません。
また、ドロップ報告書だけは、戦闘履歴のデータ量が多いため起動時のデータベースロード時にスクリプトが実行されます。動作中にスクリプトの変更を反映したい場合は、ドロップ報告書の操作→データベースを再読み込みでデータベースをロードしなおしてください。
テーブル列の初期位置はスクリプトの実行順で決まります。スクリプトの実行順はスクリプトの名前順になります。例えば、ship_a.js, ship_b.js, ship_c.jsがあった場合、ship_a.js→ship_b.js→ship_c.jsの順に実行されます。航海日誌拡張版付属の艦娘一覧テーブル用スクリプトは以下のようになっています。
| 実行順 | スクリプト名 | 内容 |
|---|---|---|
| 1 | ship__1basic.js | ソート順やレベルなどの基本項目 |
| 2 | ship__2slot.js | 装備や搭載数 |
| 3 | ship__3status.js | 能力値 |
| 4 | ship_power.js | 夜戦火力など |
| 5 | ship_remodel.js | 改造可能か |
上の3つはアンダーバー(_)を2つ重ねていますが、これは追加したスクリプトの項目が基本項目に割り込まないようにするためです。
航海日誌拡張版はテーブルの列幅や列の順番などを記憶しています。このとき、列ヘッダーをキーとして使っています。なので、同じヘッダーの列が複数あると正しく記憶できません。これを回避するために、明示的にその列のキーを指定することができます。例えば、ship__1basic.jsのheader()にある"燃料#現在の燃料"は、表示されるヘッダーは"燃料"ですが、列情報を保存するためのキーは"現在の燃料"です。このようにヘッダーを"表示名#キー"とすることでキーを明示的に指定できます。重複のありそうな列はキーを明示的に指定してください。
TableItemCreatorをスクリプトで実装することで、テーブルのデザインを変えることができます。書き方はscript\shipstyle.jsを参照してください。create()でテーブルの1行分に相当するTableItemを作って返します。dataで渡されるのは1行分の表示内容(Comparable[])ですが、data[0].get()でその行に対応するデータオブジェクトを取得できることがあります。
対応するテーブルと取得可能なデータオブジェクトについては以下の通り
| テーブル名 | data[0].get()で取得できるデータ |
|---|---|
| ドロップ報告書 | BattleResultDto |
| 艦娘一覧 | ShipDto |
| 装備一覧 | ItemInfo |
| 遠征一覧 | MissionDto |
| 任務一覧 | QuestDto |
| 建造報告書 | GetShipDto |
| 開発報告書 | CreateItemDto |
| 遠征報告書 | MissionResultDto |
航海日誌本家に実装されている機能です。使い方は本家のマニュアルを参照してください。ただし、以下の様な違いがあります。
- スクリプトの指定方法が本家だと設定画面からファイルを直接指定できますが、拡張版は上記のように規則に沿ったファイル名でスクリプト置くという方式を取っていて、本家の方法はサポートしていません。
- 拡張版が対応しているのはJavaScriptのみです。
ScriptDataクラスにkey-value形式でデータを保持できます。
データ受信時にScriptData.setData()でデータを入れると、テーブルスクリプトからScriptData.getData()で入れたデータを取得して表示というようなことが可能です。ただし、航海日誌拡張版が想定していないデータからの更新だと自動更新が反応しないので、テーブルが更新されません。テーブルの更新を発動させるには、ApplicationMain.main.get*で対象のテーブルを取得して、update()メソッドを呼び出してください。
// 任務一覧を更新させる
ApplicationMain = Java.type("logbook.gui.ApplicationMain");
ApplicationMain.main.getQuestTable().update();
(ver1.8.1から)
スクリプトはscriptフォルダから読み込まれますが、航海日誌拡張版起動時にtemplates/scriptフォルダから更新のあったスクリプトをコピーして上書きします。同梱スクリプトを独自に変更したなどでこのアップデートを抑制したい場合は、script/ignore_update.txtにアップデートしないスクリプトの名前を書いてください。このファイルは航海日誌を一度でも起動すると空ファイルが作られます。
例) ignore_update.txt
ship_remodel.js
quest__basic.js
正しく読み込まれれば航海日誌を起動するとlogs/script.logに以下のようにログ出力されます。
XXX INFO script [XXX] 除外されているためアップデートされません: XXX\quest__basic.js
XXX INFO script [XXX] 除外されているためアップデートされません: XXX\ship_remodel.js
(一部長いのでXXXで省略)
※ver1.8.0以前の航海日誌拡張版を起動するとignore_update.txtが無視されて上書きされるので注意