forked from triacontane/RPGMakerMV
-
Notifications
You must be signed in to change notification settings - Fork 2
/
DatabaseConverter.js
1491 lines (1364 loc) · 56.4 KB
/
DatabaseConverter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//=============================================================================
// DatabaseConverter.js
// ----------------------------------------------------------------------------
// (C)2015-2018 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.2 2019/11/03 1.1.0の修正によりマップおよびコモンイベントが出力できなくなっていた問題を修正
// 1.1.1 2019/10/12 自動インポートがうまく動作していなかった問題を修正
// 1.1.0 2019/09/23 オリジナルデータベースでIDが重複する行を配列としてエクスポート、インポートできる機能を追加
// 1.0.3 2019/06/23 変換実行時、まれにメモ欄や説明欄の改行が増幅してしまう問題を修正
// 1.0.2 2018/05/30 移動ルートの設定のコマンドをインポートした際、一部の数値がundefinedとなってしまう問題を修正
// 1.0.1 2018/05/20 オリジナルデータの作成方法をヘルプに追加
// 1.0.0 2018/05/20 正式版リファクタリング
// 0.3.0 2018/05/17 オートインポート機能がパラメータ設定に拘わらず有効になっていた問題を修正
// マップIDに歯抜けがあった場合、出力エラーになる問題を修正
// イベントテストの実行内容を出力する機能を追加
// 0.2.0 2018/05/14 ヘルプ修正
// 0.1.0 2018/05/13 テスト版
// ----------------------------------------------------------------------------
// [Blog] : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================
/*:
* @plugindesc データベース変換プラグイン
* @author トリアコンタン
*
* @param excelDataPath
* @text シートデータファイルパス
* @desc シートデータファイルが出力されるパスです。相対パス、絶対パスが入力できます。
* @default excelData
*
* @param ExportPrefix
* @text 出力ファイル接頭辞
* @desc エクスポートファイルに付与される接頭辞です。インポートファイルと分けて保持したい場合に指定してください。
* @default
*
* @param targetDatabase
* @text 対象データベース
* @desc 入出力の対象になるデータベースの一覧です。独自に定義したデータファイルを追加できます。
* @default ["{\"JsonName\":\"Actors\",\"VariableName\":\"\"}","{\"JsonName\":\"Classes\",\"VariableName\":\"\"}","{\"JsonName\":\"Skills\",\"VariableName\":\"\"}","{\"JsonName\":\"Items\",\"VariableName\":\"\"}","{\"JsonName\":\"Weapons\",\"VariableName\":\"\"}","{\"JsonName\":\"Armors\",\"VariableName\":\"\"}","{\"JsonName\":\"Enemies\",\"VariableName\":\"\"}","{\"JsonName\":\"Troops\",\"VariableName\":\"\"}","{\"JsonName\":\"States\",\"VariableName\":\"\"}","{\"JsonName\":\"MapInfos\",\"VariableName\":\"\"}"]
* @type struct<DatabaseInfo>[]
*
* @param fileFormat
* @text 出力ファイル形式
* @desc 出力データのファイル形式です。
* @default xlsx
* @type select
* @option xlsx : Excel 2007+ XML Format
* @value xlsx
* @option xlsm : Excel 2007+ Macro XML Format
* @value xlsm
* @option xlsb : Excel 2007+ Binary Format
* @value xlsb
* @option ods : OpenDocument Spreadsheet
* @value ods
* @option fods : Flat OpenDocument Spreadsheet
* @value fods
* @option csv : Comma Separated Values
* @value csv
* @option txt : UTF-16 Unicode Text (TSV)
* @value txt
*
* @param originalDataLoad
* @text オリジナルデータ読み込み
* @desc 作成済みのオリジナルJSONデータの読み込み処理を実行します。データファイルがないとエラーになります。
* @default false
* @type boolean
*
* @param autoImport
* @text 自動インポート
* @desc インポート処理を実行してからゲーム開始します。テストプレー時のみ有効です。
* @default false
* @type boolean
*
* @param exportEventTest
* @text イベントテスト出力
* @desc イベントテスト実行時に実行内容を出力します。ただし本プラグインのコマンドを実行した場合は出力されません。
* @default true
* @type boolean
*
* @param originalDatabaseStack
* @text データベースの配列化
* @desc オリジナルデータベースのエクスポート、インポートでIDが同一の行を配列として格納します。
* @default false
* @type boolean
*
* @param commandPrefix
* @text メモ欄接頭辞
* @desc 他のプラグインとメモ欄もしくはプラグインコマンドの名称が被ったときに指定する接頭辞です。通常は指定不要です。
* @default
*
* @help DatabaseConverter.js
* ツクールMVのデータベースをExcelなどのシートデータ(以下シートファイル)に
* 書き出し、読み込みします。
*
* イベントテスト(イベントエディタ上で右クリック→テスト)から所定の
* プラグインコマンド(後述)を実行すると書き出しおよび読み込みができます。
*
* --------------------------------------
* 書き出し手順
* --------------------------------------
* 1. 本プラグインを管理画面からONにする。
* 2.「プロジェクトの保存」を実行する。(初回実行時のみ)
* 3. イベントテストから所定のプラグインコマンドを実行する。
* 4. 所定のフォルダにシートファイルが出力される。
*
* --------------------------------------
* 読み込み手順
* --------------------------------------
* 1.「プロジェクトの保存」を実行する。
* 2. Dataフォルダをバックアップしておく。
* 3. イベントテストから所定のプラグインコマンドを実行する。
* 4.「プロジェクトを開く」を実行して、プロジェクトを開き直す。
* 開き直すとき、プロジェクトの保存はしないでください。
*
* ※プラグインコマンドは1つずつ実行してください。
* 一度に複数のコマンドを実行することはできません。
*
* --------------------------------------
* オリジナルデータベース作成手順(上級者向け)
* --------------------------------------
* 1. パラメータ「オリジナルデータ読み込み」をOFFにする。
* 2. パラメータ「対象データベース」にオリジナルデータを追加
* 3. データベースをエクスポート
* 4. オリジナルデータのシートが追加されるので自由に編集
* 5. データベースをインポート
* 6. パラメータ「オリジナルデータ読み込み」をONにする。
* 7. スクリプトからオリジナルデータの内容を参照できる。
*
* --------------------------------------
* 出力対象データ
* --------------------------------------
* ・データベース
* 既存のデータベースを入出力します。ファイル名は「Database」です。
* 出力フォーマットに合わせた拡張子が付与されます。(以降も同様)
* タイルセットおよびコモンイベントは対象外です。
* さらに独自に定義したデータ(スクリプトから参照)も入出力可能です。
*
* ・コモンイベント
* コモンイベントの実行内容を入出力します。ファイル名は「CommonEvents」です。
* パラメータの詳細は以下のスプレッドシートが参考になります。
* https://docs.google.com/spreadsheets/d/1rOIzDuhLC6IqJPEFciYOmXWL_O7X9-hMValMs7DpWCk/edit#gid=1266374350
*
* ・マップイベント
* マップイベントの実行内容を入出力します。ファイル名は「MapXXX」です。
* シート名に「イベントID」および「イベントページ」が出力されます。
*
* ・イベントテスト
* イベントテストで選択した実行内容を出力します。
* ファイル名は「Test_Event」です。出力のみに対応しています。
*
* --------------------------------------
* 出力対象フォーマット
* --------------------------------------
* Excelファイル以外にもCSVやOpenDocument Spreadsheetなど
* 以下のフォーマットに対応しています。プラグインパラメータから変更可能です。
*
* xlsx : Excel2007以降の一般的な形式です。
* xlsm : Excel2007以降のマクロ付き形式です。
* xlsb : Excel2007以降のバイナリ形式です。容量や速度面で優れています。
* ods : 特定のベンダに依存しないオープンなファイル形式です。
* fods : 特定のベンダに依存しないオープンなXMLテキストファイル形式です。
* csv : カンマ区切りのテキストファイル形式です。
* txt : タブ区切りのテキストファイル形式です。
*
* --------------------------------------
* 出力ファイル詳細
* --------------------------------------
* 1. 出力時に同名のファイルが存在した場合は上書きされます。(※1)
* 2. シート名にはデータ種別が出力されるので編集しないでください。
* 3. 出力ファイルの1行目には入出力に必須な情報(プロパティ名)が出力されます。
* ここも編集しないでください。
* 4. 2行目には項目の日本語名が出力されます。読み込み時は無視されます。
* 5. 配列項目(特徴など)は一部除きjson文字列で出力されます。編集は非推奨です。
* 6. 数値や文字列は編集できますが、整合性のない値の入力には注意してください。
* 7. Excel計算式は計算結果がデータベースの値として読み込まれます。
* 8. 書式設定や行列の設定、マクロの追加などは自由です。
* 9. データベースは読み込み時にID列でソートされます。重複はエラーになります。
*
* ※1 同名ファイルを開いているとエラーになるのでファイルを閉じてください。
* --------------------------------------
* 注意事項
* --------------------------------------
* 当プラグインの機能を使用する前にプロジェクト以下の「data」フォルダの
* バックアップを「必ず」取得してください。
*
* 「data」フォルダの内容を自動でバックアップするプラグインも配布しています。
* こちらのご利用もご検討ください。
* https://raw.githubusercontent.com/triacontane/RPGMakerMV/master/BackUpDatabase.js
*
* いかなる場合も破損したプロジェクトの復元には応じられませんのでご注意ください。
*
* エクスポートしたExcelファイルを開いたときに何らかのエラーメッセージが
* 表示された場合は、そのまま編集およびインポートしないでください。
*
* 本プラグインの機能は「イベントテスト」から実行した場合のみ有効です。
* 通常のテストプレーおよび製品版には影響を与えません。
* (独自データの読み込み機能は例外)
*
* --------------------------------------
* プラグインコマンド詳細
* --------------------------------------
* イベントコマンド「プラグインコマンド」から実行。
* (パラメータの間は半角スペースで区切る)
*
* EXPORT_DATABASE
* データベースの内容を指定したフォーマットで出力します。
*
* IMPORT_DATABASE
* シートファイルを読み込んでデータベースファイルを書き換えます。
* エディタに反映させるためには、プロジェクトを開き直す必要があります。
*
* EXPORT_COMMON_EVENT 2
* ID[2]のコモンイベントの実行内容を出力します。IDは複数指定可能です。
* IDを指定しなかった場合は全てのコモンイベントを出力します。
*
* IMPORT_COMMON_EVENT 3
* シートファイルを読み込んでID[3]のコモンイベントを書き換えます。
* IDを指定しなかった場合は全てのコモンイベントを書き換えます。
*
* EXPORT_MAP_EVENT 6 20
* ID[6]のマップにあるID[20]のイベントの実行内容を出力します。
* イベントIDは複数指定可能で省略した場合、全イベントを出力します。
* マップIDは省略できません。
*
* IMPORT_MAP_EVENT 6 20
* シートファイルを読み込んでID[6]のマップにあるID[20]のイベントの
* 実行内容を書き換えます。
* イベントIDは複数指定可能で省略した場合、全イベントを書き換えます。
* マップIDは省略できません。
*
* --------------------------------------
* 使用ライブラリ
* --------------------------------------
* Excelデータの解析にはSheetJSのCommunity Editionを使用しています。
* http://sheetjs.com/
* Copyright (C) 2012-present SheetJS LLC
* Licensed under the Apache License, Version 2.0
*
* SheetJSはCDNを通じて提供されるため、プラグイン利用者は別途ライブラリを
* 導入する必要はありませんが、オフラインで作業する場合やダウンロードできない
* 場合は、以下の手順に従ってダウンロードしプラグインとして適用してください。
*
* 1. 以下のサイトのdist/xlsx.full.min.jsをダウンロードする。
* https://github.com/sheetjs/js-xlsx
*
* 2. ファイル名を任意の英字に変更する。
* (ファイル名に「.」が含まれているとプラグインとして取り込めないため)
*
* 3. プラグイン管理画面から有効にする。
*
* ExcelはMicrosoftの登録商標です。
*
* 利用規約:
* 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等)
* についても制限はありません。
* このプラグインはもうあなたのものです。
*/
/*~struct~DatabaseInfo:
*
* @param JsonName
* @text データファイル名称
* @desc データベースファイルのJSON名称です。(拡張子不要) 独自に定義したJSONファイルを読み込む場合は直接入力してください。
* @default
* @type combo
* @option Actors
* @option Classes
* @option Skills
* @option Items
* @option Weapons
* @option Armors
* @option Enemies
* @option Troops
* @option States
* @option MapInfos
*
* @param VariableName
* @text グローバル変数名称
* @desc データベースが格納されるグローバル変数の名称です。既存データベースの場合は入力不要です。
* @default
*/
/**
* ConverterManager
* コンバータを管理します。
* @constructor
*/
function ConverterManager() {
this.initialize.apply(this, arguments);
}
(function() {
'use strict';
let param = {};
const pluginCommandMap = new Map();
const paramReplacer = function(key, value) {
if (value === 'null' || value === null) {
return value;
}
if (value[0] === '"' && value[value.length - 1] === '"') {
return value;
}
if (value === String(value)) {
if (value.toLowerCase() === 'true') {
return true;
}
if (value.toLowerCase() === 'false') {
return false;
}
}
try {
return JSON.parse(value);
} catch (e) {
return value;
}
};
if (typeof Utils !== 'undefined' && Utils.RPGMAKER_NAME === 'MV') {
/**
* Convert escape characters.(require any window object)
* @param text Target text
* @returns {String} Converted text
*/
const convertEscapeCharacters = function(text) {
const windowLayer = SceneManager._scene._windowLayer;
return windowLayer ? windowLayer.children[0].convertEscapeCharacters(text.toString()) : text;
};
/**
* Convert escape characters.(for text array)
* @param texts Target text array
* @returns {Array<String>} Converted text array
*/
const convertEscapeCharactersAll = function(texts) {
return texts.map(function(text) {
return convertEscapeCharacters(text);
});
};
/**
* Set plugin command to method
* @param commandName plugin command name
* @param methodName execute method(Game_Interpreter)
*/
const setPluginCommand = function(commandName, methodName) {
pluginCommandMap.set(param.commandPrefix + commandName, methodName);
};
/**
* Create plugin parameter. param[paramName] ex. param.commandPrefix
* @param pluginName plugin name(ExcelDataConverter)
* @returns {Object} Created parameter
*/
const createPluginParameter = function(pluginName) {
const parameter = JSON.parse(JSON.stringify(PluginManager.parameters(pluginName), paramReplacer));
PluginManager.setParameters(pluginName, parameter);
return parameter;
};
param = createPluginParameter('DatabaseConverter');
if (param.originalDataLoad && !DataManager.isEventTest()) {
param.targetDatabase.forEach(function(databaseInfo) {
const srcName = `${databaseInfo.JsonName}.json`;
const exist = DataManager._databaseFiles.some(function(fileInfo) {
return fileInfo.src === srcName;
});
if (!exist) {
DataManager._databaseFiles.push({name: databaseInfo.VariableName, src: srcName});
}
});
}
if (!Utils.isOptionValid('test') && !DataManager.isEventTest()) {
return;
}
setPluginCommand('EXPORT_DATABASE', 'exportDatabase');
setPluginCommand('IMPORT_DATABASE', 'importDatabase');
setPluginCommand('EXPORT_COMMON_EVENT', 'exportCommonEvent');
setPluginCommand('IMPORT_COMMON_EVENT', 'importCommonEvent');
setPluginCommand('EXPORT_MAP_EVENT', 'exportMapEvent');
setPluginCommand('IMPORT_MAP_EVENT', 'importMapEvent');
//=============================================================================
// Game_Interpreter
//=============================================================================
const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_Game_Interpreter_pluginCommand.apply(this, arguments);
const pluginCommandMethod = pluginCommandMap.get(command.toUpperCase());
if (pluginCommandMethod) {
this[pluginCommandMethod](convertEscapeCharactersAll(args));
}
};
Game_Interpreter.prototype.exportDatabase = function() {
ConverterManager.executeDataExport(new ConvertTargetDatabase(false));
};
Game_Interpreter.prototype.importDatabase = function() {
ConverterManager.executeDataImport(new ConvertTargetDatabase(false));
};
Game_Interpreter.prototype.exportCommonEvent = function(args) {
ConverterManager.executeDataExport(new ConvertTargetCommonEvent(args));
};
Game_Interpreter.prototype.importCommonEvent = function(args) {
ConverterManager.executeDataImport(new ConvertTargetCommonEvent(args));
};
Game_Interpreter.prototype.exportMapEvent = function(args) {
const mapId = parseInt(args.shift());
ConverterManager.executeDataExport(new ConvertTargetMapEvent(args, mapId));
};
Game_Interpreter.prototype.importMapEvent = function(args) {
const mapId = parseInt(args.shift());
ConverterManager.executeDataImport(new ConvertTargetMapEvent(args, mapId));
};
const _Game_Interpreter_terminate = Game_Interpreter.prototype.terminate;
Game_Interpreter.prototype.terminate = function() {
_Game_Interpreter_terminate.apply(this, arguments);
if (DataManager.isEventTest() && this._depth === 0 && param.exportEventTest) {
ConverterManager.executeDataExport(new ConvertTargetTestEvent());
}
};
//=============================================================================
// SceneManager
// コンバータマネージャーを追加定義します。
//=============================================================================
const _SceneManager_initialize = SceneManager.initialize;
SceneManager.initialize = function() {
_SceneManager_initialize.apply(this, arguments);
ConverterManager.initialize();
};
//=============================================================================
// DataManager
// 起動時の自動読み込みを追加します。
//=============================================================================
var _DataManager_loadDatabase = DataManager.loadDatabase;
DataManager.loadDatabase = function() {
if (!this.isEventTest() && !this._databaseImport && param.autoImport) {
ConverterManager.executeDataImportSync(function() {
_DataManager_loadDatabase.apply(this, arguments);
ConverterManager.createConverter();
}.bind(this));
this._databaseImport = true;
} else {
_DataManager_loadDatabase.apply(this, arguments);
}
};
//=============================================================================
// Scene_Boot
// 変換オブジェクトの準備完了を待ちます。
//=============================================================================
const _Scene_Boot_isReady = Scene_Boot.prototype.isReady;
Scene_Boot.prototype.isReady = function() {
return _Scene_Boot_isReady.apply(this, arguments) && ConverterManager.isSheetDataConverterReady();
};
}
//=============================================================================
// ConverterManager
// シート変換オブジェクトを生成、管理します。
//=============================================================================
ConverterManager.initialize = function() {
this.createConverter();
this._sheetJs = new SheetJsCreator();
};
ConverterManager.createConverter = function() {
this._sheetDataConverter = AbstractSheetConverter.getInstance(param.fileFormat);
};
ConverterManager.isSheetDataConverterReady = function() {
return this._sheetJs.isReady() && this._sheetDataConverter.isReady();
};
ConverterManager.executeDataImportSync = function(callBack) {
this._sheetJs.addLoadListener(function() {
this._sheetDataConverter.executeImport(new ConvertTargetDatabase(true));
callBack();
}.bind(this));
};
ConverterManager.executeDataExport = function(target) {
this._executeDataConvert('executeExport', target);
};
ConverterManager.executeDataImport = function(target) {
this._executeDataConvert('executeImport', target);
};
ConverterManager._executeDataConvert = function(process, target) {
if (!this.isSheetDataConverterReady()) {
return;
}
var nwWin = require('nw.gui').Window.get();
nwWin.showDevTools();
console.log(`----- ${process} Process Start -----`);
this._sheetDataConverter[process](target);
console.log(`----- ${process} Process End -----`);
setTimeout(function() {
nwWin.focus();
}, 500);
this._pause();
};
ConverterManager._pause = function() {
console.log('Press or Click any key to shutdown....');
setInterval(function() {
if (Object.keys(Input._currentState).length > 0 || TouchInput.isPressed()) SceneManager.terminate();
}, 10);
};
ConverterManager.getDatabasePath = function() {
return this.getRelativePath('data/');
};
ConverterManager.getRelativePath = function(subPath) {
const path = require('path');
const base = path.dirname(process.mainModule.filename);
return path.join(base, subPath);
};
ConverterManager.setParameter = function(name, value) {
param[name] = value;
};
/**
* SheetJsCreator
* SheetJsライブラリをダウンロードして保持します。
*/
class SheetJsCreator {
constructor() {
this._loaded = false;
this._loadListener = [];
this._urlIndex = 0;
this._loadSheetJs();
}
isReady() {
return this._loaded;
}
addLoadListener(callBack) {
if (this._loaded) {
callBack();
} else {
this._loadListener.push(callBack);
}
}
_loadSheetJs() {
if (typeof XLSX !== 'undefined') {
this._onLoadScript();
return;
}
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = this._getSheetJsUrl();
script.onerror = this._onLoadScriptError.bind(this);
script.onload = this._onLoadScript.bind(this);
document.body.appendChild(script);
}
_getSheetJsUrl() {
return AbstractSheetConverter.CDN_SERVER_URL_LIST[this._urlIndex];
}
_onLoadScript() {
if (typeof XLSX === 'undefined') {
this._onLoadScriptError();
return;
}
this._loaded = true;
this._loadListener.forEach(function(callBack) {
callBack();
});
this._loadListener = null;
}
_onLoadScriptError() {
this._urlIndex++;
if (this._getSheetJsUrl()) {
this._loadSheetJs();
} else {
throw new Error('CDNサーバからのライブラリダウンロードに失敗しました。マニュアルダウンロードをお試しください。');
}
}
}
/**
* ConverterStorage
* データファイルのロード・セーブを行います。
*/
class ConverterStorage {
loadDataBaseFileSync(fileName) {
try {
const filePath = this.getDatabaseFullPath(fileName);
return JSON.parse(require('fs').readFileSync(filePath, {encoding: 'utf8'}));
} catch (e) {
console.error('Fail to Load ' + fileName);
return [null, {id: 1, name: ' '}];
}
}
saveDataBaseFile(fileName, data, sync) {
try {
const filePath = this.getDatabaseFullPath(fileName);
const fs = require('fs');
const writeFunc = sync ? fs.writeFileSync : fs.writeFile;
writeFunc(filePath, JSON.stringify(data), {encoding: 'utf8'});
} catch (e) {
console.error('Fail to Save ' + fileName);
throw e;
}
}
getDatabaseFullPath(fileName) {
return ConverterManager.getDatabasePath() + fileName + '.json';
}
}
/**
* AbstractSheetConverter
* データベースとシートファイルの相互変換を行う抽象クラスです。
*/
class AbstractSheetConverter {
constructor(format) {
const directory = this._getTargetDirectory();
if (!this._makeSheetDirectoryIfNeed(directory)) {
throw new Error(`シート出力ディレクトリ[${directory}]が見付かりませんでした。`);
}
this._format = format;
this._directory = directory;
this._serializer = null;
this._target = null;
}
_makeSheetDirectoryIfNeed(filePath) {
const fs = require('fs');
if (!fs.existsSync(filePath)) {
try {
fs.mkdirSync(filePath);
} catch (e) {
console.error(e);
return false;
}
}
return fs.existsSync(filePath);
}
isReady() {
return !this._serializer;
}
executeExport(target) {
this._target = target;
this._workBook = this._createWorkBook();
this._serializer = new DataSerializer(target);
this._target.execute(this._exportItem.bind(this));
this.writeAllWorkbook();
}
_createWorkBook() {
return {SheetNames: [], Sheets: {}};
}
_exportItem(dataName) {
console.log('Export ' + dataName);
const data = this._target.load(dataName);
if (!data) {
return;
}
this._workBook.SheetNames.push(dataName);
this._workBook.Sheets[dataName] = this._serializer.serializeData(data, dataName);
}
/**
* writeAllWorkbook
* @abstract
*/
writeAllWorkbook() {}
writeWorkbookFile(dataBaseName, workbookData) {
const writeOption = {bookType: this._format};
const path = this._getTargetFilePath(this._target.getFileName() + param.ExportPrefix, dataBaseName);
try {
XLSX.writeFile(workbookData, path, writeOption);
} catch (e) {
if (e.code === 'EBUSY') {
throw new Error(`ファイル[${path}]の書き出しに失敗しました。ファイルを開いている可能性があります。`);
} else {
throw e;
}
}
}
executeImport(target) {
this._target = target;
this._workBook = this.readAllWorkbook();
this._serializer = new DataSerializer(target);
this._target.execute(this._importItem.bind(this));
}
_importItem(dataName) {
const sheetData = this._workBook.Sheets[dataName];
if (!sheetData) {
console.warn('Skip Import ' + dataName);
return;
} else {
console.log('Import ' + dataName);
}
const data = this._serializer.deserializeData(sheetData, dataName);
this._target.save(dataName, data);
}
/**
* readAllWorkbook
* @abstract
*/
readAllWorkbook() {}
readWorkbookFile(dataBaseName) {
const readOption = {};
const path = this._getTargetFilePath(this._target.getFileName(), dataBaseName);
try {
return XLSX.readFile(path, readOption);
} catch (e) {
if (e.code === 'ENOENT') {
throw new Error(`ファイル[${path}]が見付かりませんでした。`);
} else {
throw e;
}
}
}
_getTargetDirectory() {
const path = param.excelDataPath;
return (!path.match(/^[A-Z]:/) ? ConverterManager.getRelativePath(path) : path);
}
_getTargetFilePath(baseName, dataName) {
return `${this._directory}/${baseName}${dataName}.${this._format}`;
}
static getInstance(format) {
if (AbstractSheetConverter.SINGLE_FORMATS.contains(format)) {
return new SingleSheetConverter(format);
} else {
return new MultiSheetConverter(format);
}
}
static get SINGLE_FORMATS() {
return ['csv', 'txt'];
}
static get CDN_SERVER_URL_LIST() {
return [
'https://unpkg.com/xlsx/dist/xlsx.full.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.11.19/xlsx.full.min.js',
'https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js'
];
}
}
/**
* MultiSheetConverter
* マルチチート用の変換クラスです。
*/
class MultiSheetConverter extends AbstractSheetConverter {
writeAllWorkbook() {
this.writeWorkbookFile('', this._workBook);
}
readAllWorkbook() {
return this.readWorkbookFile('');
}
}
/**
* SingleSheetConverter
* シングルシート用の変換クラスです。
*/
class SingleSheetConverter extends AbstractSheetConverter {
writeAllWorkbook() {
this._target.execute(function(databaseName) {
var workbook = this._createWorkBook();
workbook.SheetNames.push(databaseName);
workbook.Sheets[databaseName] = this._workBook.Sheets[databaseName];
this.writeWorkbookFile(databaseName, workbook);
}.bind(this));
}
readAllWorkbook() {
const workbook = this._createWorkBook();
this._target.execute(function(databaseName) {
const singleWork = this.readWorkbookFile(databaseName);
if (singleWork) {
workbook.SheetNames.push(databaseName);
workbook.Sheets[databaseName] = singleWork.Sheets['Sheet1'];
}
}.bind(this));
return workbook;
}
}
/**
* InterfaceConvertTarget
* 変換対象インタフェース
*/
class InterfaceConvertTarget {
static METHODS() {
return ['execute', 'getFileName', 'load', 'save', 'getColumnDescriptions', 'getArrayProperties', 'appendData', 'isStackDatabase'];
}
constructor() {
InterfaceConvertTarget.METHODS().forEach(function(method) {
if (!this[method] || typeof this[method] !== 'function') {
throw new Error(`Require method ${method} not found.`);
}
}, this);
}
}
/**
* ConvertTargetDatabase
* データベース用の変換対象クラス
*/
class ConvertTargetDatabase extends InterfaceConvertTarget {
constructor(sync) {
super();
this._sync = sync;
this._storage = new ConverterStorage();
}
execute(process) {
param.targetDatabase.map(function(databaseInfo) {
return databaseInfo.JsonName;
}).forEach(process, this);
}
getFileName() {
return 'Database';
}
load(name) {
const data = this._storage.loadDataBaseFileSync(name);
data.shift(0);
return data;
}
save(name, data) {
data[0] = null;
data.forEach(function(item) {
if (!item) {
return;
}
ConvertTargetDatabase.replaceWrongReturnCode(item, 'note');
ConvertTargetDatabase.replaceWrongReturnCode(item, 'description');
ConvertTargetDatabase.replaceWrongReturnCode(item, 'profile');
});
this._storage.saveDataBaseFile(name, data, this._sync);
}
appendData(database, dataItem, dataName) {
if (database[dataItem.id] && !this.isStackDatabase(dataName)) {
throw new Error(`データ内のID[${dataItem.id}]が重複しています。`);
}
if (!dataItem.hasOwnProperty('name')) {
dataItem.name = '';
}
if (!dataItem.hasOwnProperty('note')) {
dataItem.note = '';
}
if (this.isStackDatabase(dataName)) {
if (!database[dataItem.id]) {
database[dataItem.id] = [];
}
database[dataItem.id].push(dataItem);
} else {
database[dataItem.id] = dataItem;
}
}
getColumnDescriptions() {
return ConvertTargetDatabase._commonDescriptions;
}
getArrayProperties() {
return ConvertTargetDatabase._arrayProperties;
}
getSplitProperties() {
return ConvertTargetDatabase._splitProperties;
}
getObjectProperties() {
return ConvertTargetDatabase._objectProperties;
}
isStackDatabase(name) {
return !ConvertTargetDatabase._systemDatabaseList.contains(name) && param.originalDatabaseStack;
}
static replaceWrongReturnCode(item, propName) {
if (item[propName]) {
item[propName] = item[propName].replace(/\r\r\n/g, '\n');
}
}
}
ConvertTargetDatabase._systemDatabaseList = [
'Actors',
'Classes',
'Skills',
'Items',
'Weapons',
'Armors',
'Enemies',
'Troops',
'States',
'MapInfos'
];
ConvertTargetDatabase._commonDescriptions = {
id : 'ID',
name : '名前',
description : '説明',
traits : '特徴',
effects : '効果',
note : 'メモ',
actions : '行動',
dropItems : 'ドロップアイテム',
members : 'メンバー',
animationId : 'アニメーション',
hitType : '命中タイプ',
iconIndex : 'アイコン',
occasion : '使用可能時',
repeats : '連続回数',
scope : '範囲',
speed : '速度補正',
successRate : '成功率',
tpCost : '消費TP',
tpGain : '得TP',
mpCost : '消費MP',
damage_elementId : '属性',
damage_type : 'タイプ',
damage_variance : '分散度',
damage_critical : '会心',
damage_formula : '計算式',
price : '価格',
params0 : '最大HP',
params1 : '最大MP',
params2 : '攻撃力',
params3 : '防御力',
params4 : '魔法力',
params5 : '魔法防御',
params6 : '敏捷性',
params7 : '運',
stypeId : 'スキルタイプ',
requiredWtypeId1 : '武器タイプ1',
requiredWtypeId2 : '武器タイプ2',
itypeId : 'アイテムタイプ',
consumable : '消耗',
wtypeId : '武器タイプ',
atypeId : '防具タイプ',
etypeId : '装備タイプ',
battlerHue : '色相',
exp : '経験値',
gold : '所持金',
autoRemovalTiming : '自動解除のタイミング',
chanceByDamage : 'ダメージで解除_ダメージ',
maxTurns : '継続ターン数_最大',
minTurns : '継続ターン数_最小',
motion : '[SV] モーション',
overlay : '[SV] 重ね合わせ',
priority : '優先度',
removeAtBattleEnd : '戦闘終了時に解除',
removeByDamage : 'ダメージで解除',
removeByRestriction: '行動制約で解除',
removeByWalking : '歩数で解除',
restriction : '行動制約',
stepsToRemove : '歩数で解除_歩数',
battlerName : '[SV] 戦闘キャラ',
characterIndex : '歩行キャラ_インデックス',