madden-franchise 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FranchiseEnum.js +13 -0
- package/FranchiseEnumValue.js +7 -0
- package/FranchiseFile.js +172 -1
- package/FranchiseFileField.js +22 -0
- package/FranchiseFileRecord.js +19 -0
- package/FranchiseFileSettings.js +15 -0
- package/FranchiseFileTable.js +105 -0
- package/FranchiseFileTable2Field.js +11 -0
- package/FranchiseFileTable3Field.js +11 -0
- package/FranchiseSchema.js +24 -0
- package/dist/Constants.d.ts +5 -0
- package/dist/Constants.d.ts.map +1 -0
- package/dist/FranchiseEnum.d.ts +33 -0
- package/dist/FranchiseEnum.d.ts.map +1 -0
- package/dist/FranchiseEnumValue.d.ts +21 -0
- package/dist/FranchiseEnumValue.d.ts.map +1 -0
- package/dist/FranchiseFile.d.ts +177 -0
- package/dist/FranchiseFile.d.ts.map +1 -0
- package/dist/FranchiseFileField.d.ts +56 -0
- package/dist/FranchiseFileField.d.ts.map +1 -0
- package/dist/FranchiseFileRecord.d.ts +48 -0
- package/dist/FranchiseFileRecord.d.ts.map +1 -0
- package/dist/FranchiseFileSettings.d.ts +28 -0
- package/dist/FranchiseFileSettings.d.ts.map +1 -0
- package/dist/FranchiseFileTable.d.ts +177 -0
- package/dist/FranchiseFileTable.d.ts.map +1 -0
- package/dist/FranchiseFileTable2Field.d.ts +38 -0
- package/dist/FranchiseFileTable2Field.d.ts.map +1 -0
- package/dist/FranchiseFileTable3Field.d.ts +38 -0
- package/dist/FranchiseFileTable3Field.d.ts.map +1 -0
- package/dist/FranchiseSchema.d.ts +43 -0
- package/dist/FranchiseSchema.d.ts.map +1 -0
- package/dist/services/schemaGenerator.d.ts +10 -0
- package/dist/services/schemaGenerator.d.ts.map +1 -0
- package/dist/services/schemaPicker.d.ts +5 -0
- package/dist/services/schemaPicker.d.ts.map +1 -0
- package/dist/services/utilService.d.ts +38 -0
- package/dist/services/utilService.d.ts.map +1 -0
- package/dist/strategies/GameStrategy.d.ts +80 -0
- package/dist/strategies/StrategyPicker.d.ts +5 -0
- package/dist/strategies/StrategyPicker.d.ts.map +1 -0
- package/dist/strategies/common/CommonAlgorithms.d.ts +2 -0
- package/dist/strategies/common/CommonAlgorithms.d.ts.map +1 -0
- package/dist/strategies/common/file/CommonFileStrategy.d.ts +2 -0
- package/dist/strategies/common/file/CommonFileStrategy.d.ts.map +1 -0
- package/dist/strategies/common/file/FTCFileStrategy.d.ts +3 -0
- package/dist/strategies/common/file/FTCFileStrategy.d.ts.map +1 -0
- package/dist/strategies/common/file/FranchiseFileStrategy.d.ts +3 -0
- package/dist/strategies/common/file/FranchiseFileStrategy.d.ts.map +1 -0
- package/dist/strategies/common/header/m19/M19TableHeaderStrategy.d.ts +50 -0
- package/dist/strategies/common/header/m19/M19TableHeaderStrategy.d.ts.map +1 -0
- package/dist/strategies/common/header/m20/M20TableHeaderStrategy.d.ts +50 -0
- package/dist/strategies/common/header/m20/M20TableHeaderStrategy.d.ts.map +1 -0
- package/dist/strategies/common/header/m24/M24TableHeaderStrategy.d.ts +44 -0
- package/dist/strategies/common/header/m24/M24TableHeaderStrategy.d.ts.map +1 -0
- package/dist/strategies/common/table/FTCTableStrategy.d.ts +3 -0
- package/dist/strategies/common/table/FTCTableStrategy.d.ts.map +1 -0
- package/dist/strategies/common/table/FranchiseTableStrategy.d.ts +5 -0
- package/dist/strategies/common/table/FranchiseTableStrategy.d.ts.map +1 -0
- package/dist/strategies/common/table2Field/FTCTable2FieldStrategy.d.ts +3 -0
- package/dist/strategies/common/table2Field/FTCTable2FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/common/table2Field/FranchiseTable2FieldStrategy.d.ts +3 -0
- package/dist/strategies/common/table2Field/FranchiseTable2FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/common/table3Field/FranchiseTable3FieldStrategy.d.ts +5 -0
- package/dist/strategies/common/table3Field/FranchiseTable3FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m19/M19FileStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m19/M19FileStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m19/M19Strategy.d.ts +3 -0
- package/dist/strategies/franchise/m19/M19Strategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m19/M19Table2FieldStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m19/M19Table2FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m19/M19TableStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m19/M19TableStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m20/M20FileStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m20/M20FileStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m20/M20Strategy.d.ts +3 -0
- package/dist/strategies/franchise/m20/M20Strategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m20/M20Table2FieldStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m20/M20Table2FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m20/M20TableStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m20/M20TableStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m24/M24Strategy.d.ts +3 -0
- package/dist/strategies/franchise/m24/M24Strategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m24/M24Table3FieldStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m24/M24Table3FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise/m24/M24TableStrategy.d.ts +6 -0
- package/dist/strategies/franchise/m24/M24TableStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m19/M19FTCFileStrategy.d.ts +6 -0
- package/dist/strategies/franchise-common/m19/M19FTCFileStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m19/M19FTCStrategy.d.ts +3 -0
- package/dist/strategies/franchise-common/m19/M19FTCStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m19/M19FTCTable2FieldStrategy.d.ts +6 -0
- package/dist/strategies/franchise-common/m19/M19FTCTable2FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m19/M19FTCTableStrategy.d.ts +6 -0
- package/dist/strategies/franchise-common/m19/M19FTCTableStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m20/M20FTCFileStrategy.d.ts +6 -0
- package/dist/strategies/franchise-common/m20/M20FTCFileStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m20/M20FTCStrategy.d.ts +3 -0
- package/dist/strategies/franchise-common/m20/M20FTCStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m20/M20FTCTable2FieldStrategy.d.ts +6 -0
- package/dist/strategies/franchise-common/m20/M20FTCTable2FieldStrategy.d.ts.map +1 -0
- package/dist/strategies/franchise-common/m20/M20FTCTableStrategy.d.ts +6 -0
- package/dist/strategies/franchise-common/m20/M20FTCTableStrategy.d.ts.map +1 -0
- package/package.json +5 -3
- package/{schema-generator-script.js → scripts/schema-generator-script.js} +1 -1
- package/services/schemaGenerator.js +4 -0
- package/services/schemaPicker.js +2 -0
- package/strategies/StrategyPicker.js +3 -0
- package/strategies/franchise/m19/M19FileStrategy.js +3 -0
- package/strategies/franchise/m19/M19Strategy.js +3 -0
- package/strategies/franchise/m19/M19Table2FieldStrategy.js +3 -0
- package/strategies/franchise/m19/M19TableStrategy.js +3 -0
- package/strategies/franchise/m20/M20FileStrategy.js +3 -0
- package/strategies/franchise/m20/M20Strategy.js +3 -0
- package/strategies/franchise/m20/M20Table2FieldStrategy.js +3 -0
- package/strategies/franchise/m20/M20TableStrategy.js +3 -0
- package/strategies/franchise/m24/M24Strategy.js +3 -0
- package/strategies/franchise/m24/M24Table3FieldStrategy.js +3 -0
- package/strategies/franchise/m24/M24TableStrategy.js +3 -0
- package/strategies/franchise-common/m19/M19FTCFileStrategy.js +3 -0
- package/strategies/franchise-common/m19/M19FTCStrategy.js +3 -0
- package/strategies/franchise-common/m19/M19FTCTable2FieldStrategy.js +3 -0
- package/strategies/franchise-common/m19/M19FTCTableStrategy.js +3 -0
- package/strategies/franchise-common/m20/M20FTCFileStrategy.js +3 -0
- package/strategies/franchise-common/m20/M20FTCStrategy.js +3 -0
- package/strategies/franchise-common/m20/M20FTCTable2FieldStrategy.js +3 -0
- package/strategies/franchise-common/m20/M20FTCTableStrategy.js +3 -0
- package/tsconfig.json +21 -0
- package/.vscode/launch.json +0 -17
- package/scripts/data/PlayerSchema.json +0 -1
- package/scripts/data/SeasonScheduleManager.SeasonScheduleTunableDataOffsetTable.json +0 -1
- package/scripts/data/SeasonScheduleManager.SeasonScheduleTunableDataSchema.json +0 -1
- package/scripts/data/playerOffsetTable.json +0 -1
- package/scripts/deflate.js +0 -37
- package/scripts/deflateFRT.js +0 -37
- package/scripts/getTableId.js +0 -18
- package/scripts/inflate.js +0 -42
- package/scripts/schemaOutput.js +0 -25
- package/scripts/scratchpad.js +0 -59
- package/scripts/sinthros-table3.js +0 -30
package/FranchiseEnum.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
const FranchiseEnumValue = require('./FranchiseEnumValue');
|
|
2
2
|
|
|
3
3
|
class FranchiseEnum {
|
|
4
|
+
/** @param {string | FranchiseEnum} name @param {number} assetId @param {boolean} isRecordPersistent */
|
|
4
5
|
constructor(name, assetId, isRecordPersistent) {
|
|
5
6
|
if (typeof name === 'object') {
|
|
6
7
|
const theEnum = name;
|
|
8
|
+
/** @private */
|
|
7
9
|
this._name = theEnum._name;
|
|
10
|
+
/** @private */
|
|
8
11
|
this._assetId = theEnum._assetId;
|
|
12
|
+
/** @private */
|
|
9
13
|
this._isRecordPersistent = theEnum._isRecordPersistent;
|
|
14
|
+
/** @private */
|
|
10
15
|
this._members = [];
|
|
11
16
|
|
|
12
17
|
for (let i = 0; i < theEnum._members.length; i++) {
|
|
@@ -24,26 +29,32 @@ class FranchiseEnum {
|
|
|
24
29
|
}
|
|
25
30
|
};
|
|
26
31
|
|
|
32
|
+
/** @returns {string} */
|
|
27
33
|
get name () {
|
|
28
34
|
return this._name;
|
|
29
35
|
};
|
|
30
36
|
|
|
37
|
+
/** @returns {number} */
|
|
31
38
|
get assetId () {
|
|
32
39
|
return this._assetId;
|
|
33
40
|
};
|
|
34
41
|
|
|
42
|
+
/** @returns {boolean} */
|
|
35
43
|
get isRecordPersistent () {
|
|
36
44
|
return this._isRecordPersistent;
|
|
37
45
|
};
|
|
38
46
|
|
|
47
|
+
/** @returns {Array<FranchiseEnumValue>} */
|
|
39
48
|
get members () {
|
|
40
49
|
return this._members;
|
|
41
50
|
}
|
|
42
51
|
|
|
52
|
+
/** @param {string} name @param {number} index @param {string} value @param {string?} [unformattedValue] */
|
|
43
53
|
addMember(name, index, value, unformattedValue) {
|
|
44
54
|
this._members.push(new FranchiseEnumValue(name, index, value, unformattedValue));
|
|
45
55
|
};
|
|
46
56
|
|
|
57
|
+
/** @param {string} value @returns {FranchiseEnumValue?} */
|
|
47
58
|
getMemberByValue(value) {
|
|
48
59
|
const matches = this._members.filter((member) => { return member.name !== 'First_' && member.name !== 'Last_' && member.value === value; });
|
|
49
60
|
if (matches.length === 0) { throw new Error(`Argument is not a valid enum value for this field. You passed in ${value}. Field name: ${this.name}`); }
|
|
@@ -52,6 +63,7 @@ class FranchiseEnum {
|
|
|
52
63
|
return matchesNoUnderscore ? matchesNoUnderscore : matches[0];
|
|
53
64
|
};
|
|
54
65
|
|
|
66
|
+
/** @param {string} value @returns {FranchiseEnumValue?} */
|
|
55
67
|
getMemberByUnformattedValue(value) {
|
|
56
68
|
if (value.length > this._maxLength) {
|
|
57
69
|
const valueToCutOff = value.substring(0, value.length - this._maxLength);
|
|
@@ -72,6 +84,7 @@ class FranchiseEnum {
|
|
|
72
84
|
return matchesNoUnderscore ? matchesNoUnderscore : matches[0];
|
|
73
85
|
};
|
|
74
86
|
|
|
87
|
+
/** @param {string} name @returns {FranchiseEnumValue?} */
|
|
75
88
|
getMemberByName(name) {
|
|
76
89
|
return this._members.find((member) => { return member.name.toLowerCase() === name.toLowerCase(); });
|
|
77
90
|
};
|
package/FranchiseEnumValue.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
const utilService = require('./services/utilService');
|
|
2
2
|
|
|
3
3
|
class FranchiseEnumValue {
|
|
4
|
+
/** @param {string} name @param {number} index @param {string} value @param {string?} [unformattedValue] */
|
|
4
5
|
constructor(name, index, value, unformattedValue) {
|
|
6
|
+
/** @private */
|
|
5
7
|
this._name = name;
|
|
8
|
+
/** @private */
|
|
6
9
|
this._index = typeof(index) === 'number' ? index : parseInt(index);
|
|
10
|
+
/** @private */
|
|
7
11
|
this._value = typeof(value) === 'number' ? value : parseInt(value);
|
|
12
|
+
/** @private */
|
|
8
13
|
this._unformattedValue = unformattedValue ? unformattedValue : parseFormattedValue(parseInt(value));
|
|
9
14
|
};
|
|
10
15
|
|
|
@@ -20,10 +25,12 @@ class FranchiseEnumValue {
|
|
|
20
25
|
return this._value;
|
|
21
26
|
};
|
|
22
27
|
|
|
28
|
+
/** @returns {string?} */
|
|
23
29
|
get unformattedValue () {
|
|
24
30
|
return this._unformattedValue;
|
|
25
31
|
};
|
|
26
32
|
|
|
33
|
+
/** @param {number} length */
|
|
27
34
|
setMemberLength(length) {
|
|
28
35
|
if (this.value < 0) {
|
|
29
36
|
this._unformattedValue = '1' + this._unformattedValue.padStart(length - 1, '0');
|
package/FranchiseFile.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const zlib = require("zlib");
|
|
3
3
|
const Constants = require("./Constants");
|
|
4
|
-
// const debug = require('debug')('madden-franchise');
|
|
5
4
|
const EventEmitter = require("events").EventEmitter;
|
|
6
5
|
const FranchiseSchema = require("./FranchiseSchema");
|
|
7
6
|
const utilService = require("./services/utilService");
|
|
@@ -11,8 +10,24 @@ const FranchiseFileSettings = require("./FranchiseFileSettings");
|
|
|
11
10
|
const schemaPickerService = require("./services/schemaPicker");
|
|
12
11
|
|
|
13
12
|
const COMPRESSED_DATA_OFFSET = 0x52;
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} AssetTable
|
|
15
|
+
* @param {number} assetId
|
|
16
|
+
* @param {number} reference
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {Object} RecordReference
|
|
20
|
+
* @param {number} tableId
|
|
21
|
+
* @param {number} rowNumber
|
|
22
|
+
*/
|
|
14
23
|
|
|
15
24
|
class FranchiseFile extends EventEmitter {
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {string} filePath
|
|
28
|
+
* @param {FranchiseFileSettings?} [settings]
|
|
29
|
+
* @returns {Promise<FranchiseFile>}
|
|
30
|
+
*/
|
|
16
31
|
static create(filePath, settings) {
|
|
17
32
|
return new Promise((resolve, reject) => {
|
|
18
33
|
const file = new FranchiseFile(filePath, settings);
|
|
@@ -26,27 +41,43 @@ class FranchiseFile extends EventEmitter {
|
|
|
26
41
|
});
|
|
27
42
|
}
|
|
28
43
|
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param {string} filePath
|
|
47
|
+
* @param {FranchiseFileSettings} settings
|
|
48
|
+
*/
|
|
29
49
|
constructor(filePath, settings) {
|
|
30
50
|
super();
|
|
51
|
+
/** @private @type {FranchiseFileSettings} */
|
|
31
52
|
this._settings = new FranchiseFileSettings(settings);
|
|
32
53
|
this.isLoaded = false;
|
|
33
54
|
|
|
34
55
|
if (Array.isArray(filePath)) {
|
|
56
|
+
/** @private @type {string} */
|
|
35
57
|
this._filePath = filePath[0];
|
|
36
58
|
} else {
|
|
37
59
|
this._filePath = filePath;
|
|
38
60
|
}
|
|
39
61
|
|
|
62
|
+
/** @private @type {Buffer} */
|
|
40
63
|
this._rawContents = fs.readFileSync(filePath);
|
|
64
|
+
|
|
65
|
+
/** @private @type {FileType} */
|
|
41
66
|
this._type = getFileType(this._rawContents);
|
|
67
|
+
|
|
68
|
+
/** @private @type {string} */
|
|
42
69
|
this._gameYear = this._type.year;
|
|
70
|
+
|
|
71
|
+
/** @private @type {SchemaMetadata} */
|
|
43
72
|
this._expectedSchemaVersion = getSchemaMetadata(
|
|
44
73
|
this.rawContents,
|
|
45
74
|
this._type
|
|
46
75
|
);
|
|
47
76
|
|
|
48
77
|
if (this._type.compressed) {
|
|
78
|
+
/** @type {Buffer} */
|
|
49
79
|
this.packedFileContents = this._rawContents;
|
|
80
|
+
/** @type {Buffer} */
|
|
50
81
|
this.unpackedFileContents = unpackFile(this._rawContents, this._type);
|
|
51
82
|
|
|
52
83
|
if (this._type.format === Constants.FORMAT.FRANCHISE_COMMON) {
|
|
@@ -67,6 +98,9 @@ class FranchiseFile extends EventEmitter {
|
|
|
67
98
|
}
|
|
68
99
|
}
|
|
69
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @returns {Promise<void>}
|
|
103
|
+
*/
|
|
70
104
|
parse() {
|
|
71
105
|
const that = this;
|
|
72
106
|
this.strategy = StrategyPicker.pick(this.type);
|
|
@@ -136,6 +170,7 @@ class FranchiseFile extends EventEmitter {
|
|
|
136
170
|
}
|
|
137
171
|
}
|
|
138
172
|
|
|
173
|
+
/** @type {Array<FranchiseFileTable>} */
|
|
139
174
|
this.tables = [];
|
|
140
175
|
|
|
141
176
|
for (let i = 0; i < tableIndicies.length; i++) {
|
|
@@ -175,6 +210,7 @@ class FranchiseFile extends EventEmitter {
|
|
|
175
210
|
});
|
|
176
211
|
|
|
177
212
|
let assetTablePromise = new Promise((resolve, reject) => {
|
|
213
|
+
/** @type {Array<AssetTable>} */
|
|
178
214
|
this.assetTable = [];
|
|
179
215
|
|
|
180
216
|
const assetTableOffset = this.unpackedFileContents.readUInt32BE(4);
|
|
@@ -218,10 +254,22 @@ class FranchiseFile extends EventEmitter {
|
|
|
218
254
|
});
|
|
219
255
|
}
|
|
220
256
|
|
|
257
|
+
/**
|
|
258
|
+
*
|
|
259
|
+
* @param {string} outputFilePath
|
|
260
|
+
* @param {object} options
|
|
261
|
+
* @returns {Promise<string>}
|
|
262
|
+
*/
|
|
221
263
|
save(outputFilePath, options) {
|
|
222
264
|
return this.packFile(outputFilePath, options);
|
|
223
265
|
}
|
|
224
266
|
|
|
267
|
+
/**
|
|
268
|
+
*
|
|
269
|
+
* @param {string} outputFilePath
|
|
270
|
+
* @param {object} options
|
|
271
|
+
* @returns {Promise<string>}
|
|
272
|
+
*/
|
|
225
273
|
packFile(outputFilePath, options) {
|
|
226
274
|
const that = this;
|
|
227
275
|
this.emit("saving");
|
|
@@ -262,6 +310,9 @@ class FranchiseFile extends EventEmitter {
|
|
|
262
310
|
});
|
|
263
311
|
}
|
|
264
312
|
|
|
313
|
+
/**
|
|
314
|
+
* @returns {Buffer}
|
|
315
|
+
*/
|
|
265
316
|
get rawContents() {
|
|
266
317
|
return this._rawContents;
|
|
267
318
|
}
|
|
@@ -270,26 +321,44 @@ class FranchiseFile extends EventEmitter {
|
|
|
270
321
|
return this._openedFranchiseFile;
|
|
271
322
|
}
|
|
272
323
|
|
|
324
|
+
/**
|
|
325
|
+
* @returns {string}
|
|
326
|
+
*/
|
|
273
327
|
get filePath() {
|
|
274
328
|
return this._filePath;
|
|
275
329
|
}
|
|
276
330
|
|
|
331
|
+
/**
|
|
332
|
+
* @returns {FranchiseSchema}
|
|
333
|
+
*/
|
|
277
334
|
get schema() {
|
|
278
335
|
return this.schemaList;
|
|
279
336
|
}
|
|
280
337
|
|
|
338
|
+
/**
|
|
339
|
+
* @returns {SchemaMetadata}
|
|
340
|
+
*/
|
|
281
341
|
get expectedSchemaVersion() {
|
|
282
342
|
return this._expectedSchemaVersion;
|
|
283
343
|
}
|
|
284
344
|
|
|
345
|
+
/**
|
|
346
|
+
* @returns {FranchiseFileSettings}
|
|
347
|
+
*/
|
|
285
348
|
get settings() {
|
|
286
349
|
return this._settings;
|
|
287
350
|
}
|
|
288
351
|
|
|
352
|
+
/**
|
|
353
|
+
* @returns {string}
|
|
354
|
+
*/
|
|
289
355
|
get gameYear() {
|
|
290
356
|
return this._gameYear;
|
|
291
357
|
}
|
|
292
358
|
|
|
359
|
+
/**
|
|
360
|
+
* @returns {FileType}
|
|
361
|
+
*/
|
|
293
362
|
get type() {
|
|
294
363
|
return this._type;
|
|
295
364
|
}
|
|
@@ -302,39 +371,74 @@ class FranchiseFile extends EventEmitter {
|
|
|
302
371
|
this._settings = new FranchiseFileSettings(settings);
|
|
303
372
|
}
|
|
304
373
|
|
|
374
|
+
/**
|
|
375
|
+
*
|
|
376
|
+
* @param {string} name
|
|
377
|
+
* @returns {FranchiseFileTable?}
|
|
378
|
+
*/
|
|
305
379
|
getTableByName(name) {
|
|
306
380
|
return this.tables.find((table) => {
|
|
307
381
|
return table.name === name;
|
|
308
382
|
});
|
|
309
383
|
}
|
|
310
384
|
|
|
385
|
+
/**
|
|
386
|
+
*
|
|
387
|
+
* @param {string} name
|
|
388
|
+
* @returns {Array<FranchiseFileTable>}
|
|
389
|
+
*/
|
|
311
390
|
getAllTablesByName(name) {
|
|
312
391
|
return this.tables.filter((table) => {
|
|
313
392
|
return table.name === name;
|
|
314
393
|
});
|
|
315
394
|
}
|
|
316
395
|
|
|
396
|
+
/**
|
|
397
|
+
*
|
|
398
|
+
* @param {number} id
|
|
399
|
+
* @returns {FranchiseFileTable?}
|
|
400
|
+
*/
|
|
317
401
|
getTableById(id) {
|
|
318
402
|
return this.tables.find((table) => {
|
|
319
403
|
return table.header && table.header.tableId === id;
|
|
320
404
|
});
|
|
321
405
|
}
|
|
322
406
|
|
|
407
|
+
/**
|
|
408
|
+
*
|
|
409
|
+
* @param {number} index
|
|
410
|
+
* @returns {FranchiseFileTable?}
|
|
411
|
+
*/
|
|
323
412
|
getTableByIndex(index) {
|
|
324
413
|
return this.tables[index];
|
|
325
414
|
}
|
|
326
415
|
|
|
416
|
+
/**
|
|
417
|
+
*
|
|
418
|
+
* @param {number} id
|
|
419
|
+
* @returns {FranchiseFileTable?}
|
|
420
|
+
*/
|
|
327
421
|
getTableByUniqueId(id) {
|
|
328
422
|
return this.tables.find((table) => {
|
|
329
423
|
return table.header && table.header.uniqueId === id;
|
|
330
424
|
});
|
|
331
425
|
}
|
|
332
426
|
|
|
427
|
+
/**
|
|
428
|
+
*
|
|
429
|
+
* @param {string} referenceValue
|
|
430
|
+
* @returns {RecordReference}
|
|
431
|
+
*/
|
|
333
432
|
getReferencedRecord(referenceValue) {
|
|
334
433
|
const reference = utilService.getReferenceData(referenceValue);
|
|
335
434
|
return this.getTableById(reference.tableId)?.records[reference.rowNumber];
|
|
336
435
|
}
|
|
337
436
|
|
|
437
|
+
/**
|
|
438
|
+
*
|
|
439
|
+
* @param {number} assetId
|
|
440
|
+
* @returns {RecordReference?}
|
|
441
|
+
*/
|
|
338
442
|
getReferenceFromAssetId(assetId) {
|
|
339
443
|
const assetEntry = this.assetTable.find((assetEntry) => {
|
|
340
444
|
return assetEntry.assetId === assetId;
|
|
@@ -350,6 +454,18 @@ class FranchiseFile extends EventEmitter {
|
|
|
350
454
|
}
|
|
351
455
|
}
|
|
352
456
|
|
|
457
|
+
/**
|
|
458
|
+
* @typedef {Object} TableRecordReference
|
|
459
|
+
* @param {number} tableId
|
|
460
|
+
* @param {string} name
|
|
461
|
+
* @param {FranchiseFileTable} table
|
|
462
|
+
*/
|
|
463
|
+
/**
|
|
464
|
+
*
|
|
465
|
+
* @param {number} tableId
|
|
466
|
+
* @param {number} recordIndex
|
|
467
|
+
* @returns {Array<TableRecordReference>}
|
|
468
|
+
*/
|
|
353
469
|
getReferencesToRecord(tableId, recordIndex) {
|
|
354
470
|
const referencedTable = this.getTableById(tableId);
|
|
355
471
|
|
|
@@ -455,6 +571,18 @@ function _saveSync(destination, packedContents) {
|
|
|
455
571
|
fs.writeFileSync(destination, packedContents);
|
|
456
572
|
}
|
|
457
573
|
|
|
574
|
+
/**
|
|
575
|
+
* @typedef {Object} FileType
|
|
576
|
+
* @property {string} format
|
|
577
|
+
* @property {number} year
|
|
578
|
+
* @property {boolean} compressed
|
|
579
|
+
*/
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
*
|
|
583
|
+
* @param {Buffer} data
|
|
584
|
+
* @returns {FileType}
|
|
585
|
+
*/
|
|
458
586
|
function getFileType(data) {
|
|
459
587
|
const isDataCompressed = isCompressed(data);
|
|
460
588
|
const format = getFormat(data, isDataCompressed);
|
|
@@ -467,6 +595,11 @@ function getFileType(data) {
|
|
|
467
595
|
};
|
|
468
596
|
}
|
|
469
597
|
|
|
598
|
+
/**
|
|
599
|
+
*
|
|
600
|
+
* @param {Buffer} data
|
|
601
|
+
* @returns {Boolean}
|
|
602
|
+
*/
|
|
470
603
|
function isCompressed(data) {
|
|
471
604
|
const DECOMPRESSED_HEADER = Buffer.from([0x46, 0x72, 0x54, 0x6b]); // FrTk
|
|
472
605
|
|
|
@@ -477,6 +610,12 @@ function isCompressed(data) {
|
|
|
477
610
|
return true;
|
|
478
611
|
}
|
|
479
612
|
|
|
613
|
+
/**
|
|
614
|
+
*
|
|
615
|
+
* @param {Buffer} data
|
|
616
|
+
* @param {Boolean} isCompressed
|
|
617
|
+
* @returns {string}
|
|
618
|
+
*/
|
|
480
619
|
function getFormat(data, isCompressed) {
|
|
481
620
|
if (isCompressed) {
|
|
482
621
|
const ZLIB_HEADER = Buffer.from([0x78, 0x9c]);
|
|
@@ -497,6 +636,13 @@ function getFormat(data, isCompressed) {
|
|
|
497
636
|
}
|
|
498
637
|
}
|
|
499
638
|
|
|
639
|
+
/**
|
|
640
|
+
*
|
|
641
|
+
* @param {Buffer} data
|
|
642
|
+
* @param {Boolean} isCompressed
|
|
643
|
+
* @param {string} format
|
|
644
|
+
* @returns {number}
|
|
645
|
+
*/
|
|
500
646
|
function getGameYear(data, isCompressed, format) {
|
|
501
647
|
const schemaMax = [
|
|
502
648
|
{
|
|
@@ -560,6 +706,20 @@ function getGameYear(data, isCompressed, format) {
|
|
|
560
706
|
}
|
|
561
707
|
}
|
|
562
708
|
|
|
709
|
+
/**
|
|
710
|
+
* @typedef {Object} SchemaMetadata
|
|
711
|
+
* @property {string?} gameYear
|
|
712
|
+
* @property {number?} major
|
|
713
|
+
* @property {number?} minor
|
|
714
|
+
* @property {string?} path
|
|
715
|
+
*/
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
*
|
|
719
|
+
* @param {Buffer} data
|
|
720
|
+
* @param {FileType} type
|
|
721
|
+
* @returns {SchemaMetadata}
|
|
722
|
+
*/
|
|
563
723
|
function getSchemaMetadata(data, type) {
|
|
564
724
|
let schemaMeta = {
|
|
565
725
|
gameYear: type.year,
|
|
@@ -590,6 +750,17 @@ function getSchemaMetadata(data, type) {
|
|
|
590
750
|
return schemaMeta;
|
|
591
751
|
}
|
|
592
752
|
|
|
753
|
+
/**
|
|
754
|
+
* @typedef PartialSchemaMetadata
|
|
755
|
+
* @property {number} major
|
|
756
|
+
* @property {number} minor
|
|
757
|
+
*/
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
*
|
|
761
|
+
* @param {Buffer} data
|
|
762
|
+
* @returns {PartialSchemaMetadata}
|
|
763
|
+
*/
|
|
593
764
|
function getCompressedSchema(data) {
|
|
594
765
|
return {
|
|
595
766
|
major: data.readUInt32LE(0x3e),
|
package/FranchiseFileField.js
CHANGED
|
@@ -5,33 +5,45 @@ const FranchiseFileTable2Field = require('./FranchiseFileTable2Field');
|
|
|
5
5
|
const FranchiseFileTable3Field = require('./FranchiseFileTable3Field');
|
|
6
6
|
|
|
7
7
|
class FranchiseFileField {
|
|
8
|
+
/** @param {string} key @param {Buffer} value @param {OffsetTableEntry} offset @param {FranchiseFileRecord} parent */
|
|
8
9
|
constructor(key, value, offset, parent) {
|
|
10
|
+
/** @private */
|
|
9
11
|
this._key = key;
|
|
12
|
+
/** @private */
|
|
10
13
|
this._recordBuffer = value;
|
|
14
|
+
/** @private */
|
|
11
15
|
this._unformattedValue = null;
|
|
16
|
+
/** @private */
|
|
12
17
|
this._offset = offset;
|
|
18
|
+
/** @private */
|
|
13
19
|
this._parent = parent;
|
|
20
|
+
/** @private */
|
|
14
21
|
this._isChanged = false;
|
|
15
22
|
|
|
16
23
|
if (offset.valueInSecondTable) {
|
|
24
|
+
/** @type {FranchiseFileTable2Field?} */
|
|
17
25
|
this.secondTableField = new FranchiseFileTable2Field(this._recordBuffer.readUInt32BE(offset.offset / 8), offset.maxLength);
|
|
18
26
|
this.secondTableField.fieldReference = this;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
if (offset.valueInThirdTable) {
|
|
30
|
+
/** @type {FranchiseFileTable3Field?} */
|
|
22
31
|
this.thirdTableField = new FranchiseFileTable3Field(this._recordBuffer.readUInt32BE(offset.offset / 8), offset.maxLength);
|
|
23
32
|
this.thirdTableField.fieldReference = this;
|
|
24
33
|
}
|
|
25
34
|
};
|
|
26
35
|
|
|
36
|
+
/** @returns {string} */
|
|
27
37
|
get key() {
|
|
28
38
|
return this._key;
|
|
29
39
|
};
|
|
30
40
|
|
|
41
|
+
/** @returns {OffsetTableEntry} */
|
|
31
42
|
get offset() {
|
|
32
43
|
return this._offset;
|
|
33
44
|
};
|
|
34
45
|
|
|
46
|
+
/** @returns {*} */
|
|
35
47
|
get value() {
|
|
36
48
|
if (this._unformattedValue === null) {
|
|
37
49
|
this._setUnformattedValueIfEmpty();
|
|
@@ -44,10 +56,12 @@ class FranchiseFileField {
|
|
|
44
56
|
return this._value;
|
|
45
57
|
};
|
|
46
58
|
|
|
59
|
+
/** @returns {boolean} */
|
|
47
60
|
get isReference() {
|
|
48
61
|
return this._offset.isReference;
|
|
49
62
|
};
|
|
50
63
|
|
|
64
|
+
/** @returns {RecordReference?} */
|
|
51
65
|
get referenceData() {
|
|
52
66
|
if (this._unformattedValue === null) {
|
|
53
67
|
this._setUnformattedValueIfEmpty();
|
|
@@ -151,6 +165,7 @@ class FranchiseFileField {
|
|
|
151
165
|
}
|
|
152
166
|
};
|
|
153
167
|
|
|
168
|
+
/** @returns {BitView} */
|
|
154
169
|
get unformattedValue() {
|
|
155
170
|
if (this._unformattedValue === null) {
|
|
156
171
|
this._setUnformattedValueIfEmpty();
|
|
@@ -159,20 +174,24 @@ class FranchiseFileField {
|
|
|
159
174
|
return this._unformattedValue;
|
|
160
175
|
};
|
|
161
176
|
|
|
177
|
+
/** @param {BitView} unformattedValue */
|
|
162
178
|
set unformattedValue(unformattedValue) {
|
|
163
179
|
this.setUnformattedValueWithoutChangeEvent(unformattedValue);
|
|
164
180
|
this._value = null;
|
|
165
181
|
this._parent.onEvent('change', this);
|
|
166
182
|
};
|
|
167
183
|
|
|
184
|
+
/** @returns {boolean} */
|
|
168
185
|
get isChanged() {
|
|
169
186
|
return this._isChanged;
|
|
170
187
|
};
|
|
171
188
|
|
|
189
|
+
/** @param {boolean} changed */
|
|
172
190
|
set isChanged(changed) {
|
|
173
191
|
this._isChanged = changed;
|
|
174
192
|
};
|
|
175
193
|
|
|
194
|
+
/** @param {OffsetTableEntry} offset */
|
|
176
195
|
getValueAs(offset) {
|
|
177
196
|
if (this._unformattedValue === null) {
|
|
178
197
|
this._setUnformattedValueIfEmpty();
|
|
@@ -196,6 +215,7 @@ class FranchiseFileField {
|
|
|
196
215
|
this._unformattedValue.bigEndian = true;
|
|
197
216
|
};
|
|
198
217
|
|
|
218
|
+
/** @param {BitView} unformattedValue @param {boolean} suppressErrors */
|
|
199
219
|
setUnformattedValueWithoutChangeEvent(unformattedValue, suppressErrors) {
|
|
200
220
|
if (!(unformattedValue instanceof BitView)) {
|
|
201
221
|
throw new Error(`Argument must be of type BitView. You passed in a(n) ${typeof unformattedValue}.`);
|
|
@@ -205,6 +225,7 @@ class FranchiseFileField {
|
|
|
205
225
|
}
|
|
206
226
|
}
|
|
207
227
|
|
|
228
|
+
/** @returns {FranchiseEnumValue?} */
|
|
208
229
|
_getEnumFromValue(value) {
|
|
209
230
|
const enumName = this.offset.enum.getMemberByName(value);
|
|
210
231
|
|
|
@@ -227,6 +248,7 @@ class FranchiseFileField {
|
|
|
227
248
|
}
|
|
228
249
|
};
|
|
229
250
|
|
|
251
|
+
/** @param {BitView} unformatted, @param {OffsetTableEntry} offset */
|
|
230
252
|
_parseFieldValue(unformatted, offset) {
|
|
231
253
|
if (offset.valueInSecondTable) {
|
|
232
254
|
return this.secondTableField.value;
|
package/FranchiseFileRecord.js
CHANGED
|
@@ -2,15 +2,23 @@ const utilService = require('./services/utilService');
|
|
|
2
2
|
const FranchiseFileField = require('./FranchiseFileField');
|
|
3
3
|
|
|
4
4
|
class FranchiseFileRecord {
|
|
5
|
+
/** @param {Buffer} data @param {number} index @param {OffsetTableEntry} offsetTable, @param {FranchiseFileTable} parent */
|
|
5
6
|
constructor(data, index, offsetTable, parent) {
|
|
7
|
+
/** @type {Buffer} */
|
|
6
8
|
this._data = data;
|
|
9
|
+
/** @type {OffsetTableEntry} */
|
|
7
10
|
this._offsetTable = offsetTable;
|
|
11
|
+
/** @type {number} */
|
|
8
12
|
this.index = index;
|
|
13
|
+
/** @private @type {Array<FranchiseFileField>} */
|
|
9
14
|
this._fieldsArray = [];
|
|
15
|
+
/** @private @type {Record<string, FranchiseFileField>} */
|
|
10
16
|
this._fields = this.parseRecordFields();
|
|
11
17
|
this._isChanged = false;
|
|
18
|
+
/** @type {number} */
|
|
12
19
|
this.arraySize = null;
|
|
13
20
|
this.isEmpty = false;
|
|
21
|
+
/** @type {FranchiseFileTable} */
|
|
14
22
|
this._parent = parent;
|
|
15
23
|
|
|
16
24
|
return new Proxy(this, {
|
|
@@ -30,22 +38,27 @@ class FranchiseFileRecord {
|
|
|
30
38
|
})
|
|
31
39
|
};
|
|
32
40
|
|
|
41
|
+
/** @returns {Buffer} */
|
|
33
42
|
get hexData () {
|
|
34
43
|
return this._data;
|
|
35
44
|
};
|
|
36
45
|
|
|
46
|
+
/** @returns {Record<string, FranchiseFileField>} */
|
|
37
47
|
get fields () {
|
|
38
48
|
return this._fields;
|
|
39
49
|
};
|
|
40
50
|
|
|
51
|
+
/** @returns {Array<FranchiseFileField>} */
|
|
41
52
|
get fieldsArray () {
|
|
42
53
|
return this._fieldsArray;
|
|
43
54
|
};
|
|
44
55
|
|
|
56
|
+
/** @returns {Buffer} */
|
|
45
57
|
get data() {
|
|
46
58
|
return this._data;
|
|
47
59
|
};
|
|
48
60
|
|
|
61
|
+
/** @param {Buffer} data */
|
|
49
62
|
set data (data) {
|
|
50
63
|
this._data = data;
|
|
51
64
|
|
|
@@ -59,6 +72,7 @@ class FranchiseFileRecord {
|
|
|
59
72
|
return this._isChanged;
|
|
60
73
|
};
|
|
61
74
|
|
|
75
|
+
/** @param {boolean} changed */
|
|
62
76
|
set isChanged(changed) {
|
|
63
77
|
this._isChanged = changed;
|
|
64
78
|
|
|
@@ -69,20 +83,24 @@ class FranchiseFileRecord {
|
|
|
69
83
|
}
|
|
70
84
|
}
|
|
71
85
|
|
|
86
|
+
/** @param {string} key @returns {FranchiseFileField?} */
|
|
72
87
|
getFieldByKey(key) {
|
|
73
88
|
return this._fields[key];
|
|
74
89
|
};
|
|
75
90
|
|
|
91
|
+
/** @param {string} key @returns {*?} */
|
|
76
92
|
getValueByKey(key) {
|
|
77
93
|
let field = this.getFieldByKey(key);
|
|
78
94
|
return field ? field.value : null;
|
|
79
95
|
};
|
|
80
96
|
|
|
97
|
+
/** @param {string} key @returns {RecordReference?} */
|
|
81
98
|
getReferenceDataByKey(key) {
|
|
82
99
|
let field = this.getFieldByKey(key);
|
|
83
100
|
return field ? field.referenceData : null;
|
|
84
101
|
};
|
|
85
102
|
|
|
103
|
+
/** @returns {Record<string, FranchiseFileField>} */
|
|
86
104
|
parseRecordFields() {
|
|
87
105
|
let fields = {};
|
|
88
106
|
this._fieldsArray = [];
|
|
@@ -105,6 +123,7 @@ class FranchiseFileRecord {
|
|
|
105
123
|
this.isEmpty = true;
|
|
106
124
|
};
|
|
107
125
|
|
|
126
|
+
/** @param {string} name @param {FranchiseFileField} field */
|
|
108
127
|
onEvent(name, field) {
|
|
109
128
|
if (name === 'change') {
|
|
110
129
|
// this._data = utilService.replaceAt(this._data, field.offset.offset, field.unformattedValue);
|
package/FranchiseFileSettings.js
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} SettingsParam
|
|
3
|
+
* @param {boolean?} [saveOnChange]
|
|
4
|
+
* @param {SchemaMetadata?} [schemaOverride]
|
|
5
|
+
* @param {string?} [schemaDirectory]
|
|
6
|
+
* @param {boolean?} [autoParse]
|
|
7
|
+
* @param {boolean?} [autoUnempty]
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
class FranchiseFileSettings {
|
|
11
|
+
/** @param {SettingsParam} settings */
|
|
2
12
|
constructor(settings) {
|
|
13
|
+
/** @type {boolean} */
|
|
3
14
|
this.saveOnChange = settings && settings.saveOnChange ? settings.saveOnChange : false;
|
|
15
|
+
/** @type {SchemaMetadata | false} */
|
|
4
16
|
this.schemaOverride = settings && settings.schemaOverride ? settings.schemaOverride: false;
|
|
17
|
+
/** @type {string | false} */
|
|
5
18
|
this.schemaDirectory = settings && settings.schemaDirectory ? settings.schemaDirectory : false;
|
|
19
|
+
/** @type {boolean} */
|
|
6
20
|
this.autoParse = settings && (settings.autoParse !== null && settings.autoParse !== undefined) ? settings.autoParse : true;
|
|
21
|
+
/** @type {boolean} */
|
|
7
22
|
this.autoUnempty = settings && (settings.autoUnempty !== null && settings.autoUnempty !== undefined) ? settings.autoUnempty : false;
|
|
8
23
|
}
|
|
9
24
|
};
|