madden-franchise 3.2.6 → 3.3.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/FranchiseFile.js CHANGED
@@ -1,19 +1,31 @@
1
- const fs = require('fs');
2
- const zlib = require('zlib');
3
- const Constants = require('./Constants');
1
+ const fs = require("fs");
2
+ const zlib = require("zlib");
3
+ const Constants = require("./Constants");
4
4
  // const debug = require('debug')('madden-franchise');
5
- const EventEmitter = require('events').EventEmitter;
6
- const FranchiseSchema = require('./FranchiseSchema');
7
- const utilService = require('./services/utilService');
8
- const FranchiseFileTable = require('./FranchiseFileTable');
9
- const StrategyPicker = require('./strategies/StrategyPicker');
10
- const FranchiseFileSettings = require('./FranchiseFileSettings');
11
- const schemaPickerService = require('./services/schemaPicker');
12
-
13
- const COMPRESSED_FILE_LENGTH = 2936094;
5
+ const EventEmitter = require("events").EventEmitter;
6
+ const FranchiseSchema = require("./FranchiseSchema");
7
+ const utilService = require("./services/utilService");
8
+ const FranchiseFileTable = require("./FranchiseFileTable");
9
+ const StrategyPicker = require("./strategies/StrategyPicker");
10
+ const FranchiseFileSettings = require("./FranchiseFileSettings");
11
+ const schemaPickerService = require("./services/schemaPicker");
12
+
14
13
  const COMPRESSED_DATA_OFFSET = 0x52;
15
14
 
16
15
  class FranchiseFile extends EventEmitter {
16
+ static create(filePath, settings) {
17
+ return new Promise((resolve, reject) => {
18
+ const file = new FranchiseFile(filePath, settings);
19
+
20
+ if (file.settings.autoParse) {
21
+ file.on('ready', () => resolve(file))
22
+ file.on('error', () => reject(err))
23
+ } else {
24
+ resolve(file);
25
+ }
26
+ });
27
+ }
28
+
17
29
  constructor(filePath, settings) {
18
30
  super();
19
31
  this._settings = new FranchiseFileSettings(settings);
@@ -24,11 +36,14 @@ class FranchiseFile extends EventEmitter {
24
36
  } else {
25
37
  this._filePath = filePath;
26
38
  }
27
-
39
+
28
40
  this._rawContents = fs.readFileSync(filePath);
29
41
  this._type = getFileType(this._rawContents);
30
42
  this._gameYear = this._type.year;
31
- this._expectedSchemaVersion = getSchemaMetadata(this.rawContents, this._type);
43
+ this._expectedSchemaVersion = getSchemaMetadata(
44
+ this.rawContents,
45
+ this._type
46
+ );
32
47
 
33
48
  if (this._type.compressed) {
34
49
  this.packedFileContents = this._rawContents;
@@ -38,37 +53,47 @@ class FranchiseFile extends EventEmitter {
38
53
  const newType = getFileType(this.unpackedFileContents);
39
54
  this._type.year = newType.year;
40
55
  this._gameYear = this._type.year;
41
- this._expectedSchemaVersion = getSchemaMetadata(this.unpackedFileContents, newType);
56
+ this._expectedSchemaVersion = getSchemaMetadata(
57
+ this.unpackedFileContents,
58
+ newType
59
+ );
42
60
  }
43
- }
44
- else {
61
+ } else {
45
62
  this.unpackedFileContents = this._rawContents;
46
63
  }
47
64
 
48
65
  if (this._settings.autoParse) {
49
66
  this.parse();
50
67
  }
51
- };
68
+ }
52
69
 
53
70
  parse() {
54
71
  const that = this;
55
72
  this.strategy = StrategyPicker.pick(this.type);
56
73
 
57
74
  let schemaPromise = new Promise((resolve, reject) => {
58
- const schemaMeta = this.settings.schemaOverride ? this.settings.schemaOverride : this.expectedSchemaVersion;
59
-
60
- const schemaPath = this.settings.schemaOverride && this.settings.schemaOverride.path ?
61
- this.settings.schemaOverride.path : schemaPickerService.pick(this._gameYear, schemaMeta.major, schemaMeta.minor, this.settings).path;
75
+ const schemaMeta = this.settings.schemaOverride
76
+ ? this.settings.schemaOverride
77
+ : this.expectedSchemaVersion;
78
+
79
+ const schemaPath =
80
+ this.settings.schemaOverride && this.settings.schemaOverride.path
81
+ ? this.settings.schemaOverride.path
82
+ : schemaPickerService.pick(
83
+ this._gameYear,
84
+ schemaMeta.major,
85
+ schemaMeta.minor,
86
+ this.settings
87
+ ).path;
62
88
 
63
89
  try {
64
90
  this.schemaList = new FranchiseSchema(schemaPath);
65
- this.schemaList.on('schemas:done', () => {
91
+ this.schemaList.on("schemas:done", () => {
66
92
  resolve();
67
93
  });
68
94
 
69
95
  this.schemaList.evaluate();
70
- }
71
- catch (err) {
96
+ } catch (err) {
72
97
  reject(err);
73
98
  }
74
99
  });
@@ -82,7 +107,7 @@ class FranchiseFile extends EventEmitter {
82
107
  const altFirstCheck = 0x41;
83
108
  const altSecondCheck = 0x53;
84
109
  const altThirdCheck = 0x54;
85
- const altFourthCheck = 0x4F;
110
+ const altFourthCheck = 0x4f;
86
111
 
87
112
  const alt2FirstCheck = 0x53;
88
113
  const alt2SecondCheck = 0x50;
@@ -91,44 +116,58 @@ class FranchiseFile extends EventEmitter {
91
116
 
92
117
  const tableIndicies = [];
93
118
 
94
- for (let i = 0; i <= this.unpackedFileContents.length - 4; i+=1) {
95
- if ((this.unpackedFileContents[i] === firstCheck
96
- && this.unpackedFileContents[i+1] === secondCheck
97
- && this.unpackedFileContents[i+2] === thirdCheck
98
- && this.unpackedFileContents[i+3] === fourthCheck) ||
99
- (this.unpackedFileContents[i] === altFirstCheck
100
- && this.unpackedFileContents[i+1] === altSecondCheck
101
- && this.unpackedFileContents[i+2] === altThirdCheck
102
- && this.unpackedFileContents[i+3] === altFourthCheck) ||
103
- (this.unpackedFileContents[i] === alt2FirstCheck
104
- && this.unpackedFileContents[i+1] === alt2SecondCheck
105
- && this.unpackedFileContents[i+2] === alt2ThirdCheck
106
- && this.unpackedFileContents[i+3] === alt2FourthCheck)) {
107
- const tableStart = i - getTableStartOffsetByGameYear(this._gameYear);
108
- tableIndicies.push(tableStart);
109
- }
119
+ for (let i = 0; i <= this.unpackedFileContents.length - 4; i += 1) {
120
+ if (
121
+ (this.unpackedFileContents[i] === firstCheck &&
122
+ this.unpackedFileContents[i + 1] === secondCheck &&
123
+ this.unpackedFileContents[i + 2] === thirdCheck &&
124
+ this.unpackedFileContents[i + 3] === fourthCheck) ||
125
+ (this.unpackedFileContents[i] === altFirstCheck &&
126
+ this.unpackedFileContents[i + 1] === altSecondCheck &&
127
+ this.unpackedFileContents[i + 2] === altThirdCheck &&
128
+ this.unpackedFileContents[i + 3] === altFourthCheck) ||
129
+ (this.unpackedFileContents[i] === alt2FirstCheck &&
130
+ this.unpackedFileContents[i + 1] === alt2SecondCheck &&
131
+ this.unpackedFileContents[i + 2] === alt2ThirdCheck &&
132
+ this.unpackedFileContents[i + 3] === alt2FourthCheck)
133
+ ) {
134
+ const tableStart = i - getTableStartOffsetByGameYear(this._gameYear);
135
+ tableIndicies.push(tableStart);
136
+ }
110
137
  }
111
138
 
112
139
  this.tables = [];
113
140
 
114
141
  for (let i = 0; i < tableIndicies.length; i++) {
115
142
  const currentTable = tableIndicies[i];
116
- const nextTable = tableIndicies.length > i+1 ? tableIndicies[i+1] : this.unpackedFileContents.length - 8; // Ignore trailing 8 bytes on last table
117
-
118
- const tableData = this.unpackedFileContents.slice(currentTable, nextTable);
119
-
120
- const newFranchiseTable = new FranchiseFileTable(tableData, currentTable, this._gameYear, this.strategy, this.settings);
143
+ const nextTable =
144
+ tableIndicies.length > i + 1
145
+ ? tableIndicies[i + 1]
146
+ : this.unpackedFileContents.length - 8; // Ignore trailing 8 bytes on last table
147
+
148
+ const tableData = this.unpackedFileContents.slice(
149
+ currentTable,
150
+ nextTable
151
+ );
152
+
153
+ const newFranchiseTable = new FranchiseFileTable(
154
+ tableData,
155
+ currentTable,
156
+ this._gameYear,
157
+ this.strategy,
158
+ this.settings
159
+ );
121
160
  newFranchiseTable.index = i;
122
161
  this.tables.push(newFranchiseTable);
123
162
 
124
- newFranchiseTable.on('change', function () {
163
+ newFranchiseTable.on("change", function () {
125
164
  this.isChanged = true;
126
165
 
127
166
  if (that.settings.saveOnChange) {
128
167
  that.packFile();
129
168
  }
130
169
 
131
- that.emit('change', newFranchiseTable);
170
+ that.emit("change", newFranchiseTable);
132
171
  });
133
172
  }
134
173
 
@@ -142,60 +181,69 @@ class FranchiseFile extends EventEmitter {
142
181
  const assetTableEntries = this.unpackedFileContents.readUInt32BE(36);
143
182
 
144
183
  let currentOffset = assetTableOffset;
145
-
184
+
146
185
  for (let i = 0; i < assetTableEntries; i++) {
147
186
  const assetId = this.unpackedFileContents.readUInt32BE(currentOffset);
148
- const reference = this.unpackedFileContents.readUInt32BE(currentOffset + 4);
187
+ const reference = this.unpackedFileContents.readUInt32BE(
188
+ currentOffset + 4
189
+ );
149
190
 
150
191
  this.assetTable.push({
151
- 'assetId': assetId,
152
- 'reference': reference
192
+ assetId: assetId,
193
+ reference: reference,
153
194
  });
154
195
 
155
196
  currentOffset += 8;
156
- }
197
+ }
157
198
 
158
199
  resolve();
159
200
  });
160
201
 
161
- Promise.all([schemaPromise, tablePromise, assetTablePromise]).then(() => {
162
- that.tables.forEach((table, index) => {
163
- const schema = that.schemaList.getSchema(table.name);
202
+ Promise.all([schemaPromise, tablePromise, assetTablePromise])
203
+ .then(() => {
204
+ that.tables.forEach((table, index) => {
205
+ const schema = that.schemaList.getSchema(table.name);
164
206
 
165
- if (schema) {
166
- table.schema = schema;
167
- }
168
- });
207
+ if (schema) {
208
+ table.schema = schema;
209
+ }
210
+ });
169
211
 
170
- that.isLoaded = true;
171
- that.emit('ready');
172
- }).catch((err) => {
173
- console.log(err);
174
- that.emit('error', err);
175
- });
176
- };
212
+ that.isLoaded = true;
213
+ that.emit("ready");
214
+ })
215
+ .catch((err) => {
216
+ console.log(err);
217
+ that.emit("error", err);
218
+ });
219
+ }
177
220
 
178
221
  save(outputFilePath, options) {
179
222
  return this.packFile(outputFilePath, options);
180
- };
223
+ }
181
224
 
182
225
  packFile(outputFilePath, options) {
183
226
  const that = this;
184
- this.emit('saving');
227
+ this.emit("saving");
185
228
 
186
229
  return new Promise((resolve, reject) => {
187
- this.unpackedFileContents = this.strategy.file.generateUnpackedContents(this.tables, this.unpackedFileContents);
230
+ this.unpackedFileContents = this.strategy.file.generateUnpackedContents(
231
+ this.tables,
232
+ this.unpackedFileContents
233
+ );
188
234
 
189
235
  let destination = outputFilePath ? outputFilePath : this.filePath;
190
-
236
+
191
237
  _packFile(this.unpackedFileContents, options).then((data) => {
192
- const dataToSave = this.strategy.file.postPackFile(this.packedFileContents, data);
238
+ const dataToSave = this.strategy.file.postPackFile(
239
+ this.packedFileContents,
240
+ data
241
+ );
193
242
 
194
243
  if (options && options.sync) {
195
244
  _saveSync(destination, dataToSave);
196
245
  postSaveActions();
197
- }
198
- else {
246
+ } else {
199
247
  _save(destination, dataToSave, (err) => {
200
248
  postSaveActions(err);
201
249
  });
@@ -204,130 +252,153 @@ class FranchiseFile extends EventEmitter {
204
252
  function postSaveActions(err) {
205
253
  if (err) {
206
254
  reject(err);
207
- that.emit('save-error');
255
+ that.emit("save-error");
208
256
  }
209
257
 
210
- resolve('saved');
211
- that.emit('saved');
258
+ resolve("saved");
259
+ that.emit("saved");
212
260
  }
213
261
  });
214
262
  });
215
- };
263
+ }
216
264
 
217
- get rawContents () {
265
+ get rawContents() {
218
266
  return this._rawContents;
219
- };
267
+ }
220
268
 
221
- get openedFranchiseFile () {
269
+ get openedFranchiseFile() {
222
270
  return this._openedFranchiseFile;
223
- };
271
+ }
224
272
 
225
- get filePath () {
273
+ get filePath() {
226
274
  return this._filePath;
227
- };
275
+ }
228
276
 
229
- get schema () {
277
+ get schema() {
230
278
  return this.schemaList;
231
- };
279
+ }
232
280
 
233
- get expectedSchemaVersion () {
281
+ get expectedSchemaVersion() {
234
282
  return this._expectedSchemaVersion;
235
- };
283
+ }
236
284
 
237
- get settings () {
285
+ get settings() {
238
286
  return this._settings;
239
- };
287
+ }
240
288
 
241
- get gameYear () {
289
+ get gameYear() {
242
290
  return this._gameYear;
243
- };
291
+ }
244
292
 
245
- get type () {
293
+ get type() {
246
294
  return this._type;
247
- };
295
+ }
248
296
 
249
- set filePath (path) {
297
+ set filePath(path) {
250
298
  this._filePath = path;
251
- };
299
+ }
252
300
 
253
- set settings (settings) {
301
+ set settings(settings) {
254
302
  this._settings = new FranchiseFileSettings(settings);
255
- };
303
+ }
256
304
 
257
- getTableByName (name) {
258
- return this.tables.find((table) => { return table.name === name; });
259
- };
305
+ getTableByName(name) {
306
+ return this.tables.find((table) => {
307
+ return table.name === name;
308
+ });
309
+ }
260
310
 
261
- getAllTablesByName (name) {
262
- return this.tables.filter((table) => { return table.name === name; });
263
- };
311
+ getAllTablesByName(name) {
312
+ return this.tables.filter((table) => {
313
+ return table.name === name;
314
+ });
315
+ }
264
316
 
265
- getTableById (id) {
266
- return this.tables.find((table) => { return table.header && table.header.tableId === id; });
267
- };
317
+ getTableById(id) {
318
+ return this.tables.find((table) => {
319
+ return table.header && table.header.tableId === id;
320
+ });
321
+ }
268
322
 
269
- getTableByIndex (index) {
323
+ getTableByIndex(index) {
270
324
  return this.tables[index];
271
- };
325
+ }
272
326
 
273
- getTableByUniqueId (id) {
274
- return this.tables.find((table) => { return table.header && table.header.uniqueId === id; });
275
- };
327
+ getTableByUniqueId(id) {
328
+ return this.tables.find((table) => {
329
+ return table.header && table.header.uniqueId === id;
330
+ });
331
+ }
276
332
 
277
- getReferencedRecord (referenceValue) {
333
+ getReferencedRecord(referenceValue) {
278
334
  const reference = utilService.getReferenceData(referenceValue);
279
335
  return this.getTableById(reference.tableId)?.records[reference.rowNumber];
280
- };
336
+ }
281
337
 
282
- getReferenceFromAssetId (assetId) {
338
+ getReferenceFromAssetId(assetId) {
283
339
  const assetEntry = this.assetTable.find((assetEntry) => {
284
340
  return assetEntry.assetId === assetId;
285
341
  });
286
342
 
287
343
  if (assetEntry) {
288
- const referenceBinaryString = assetEntry.reference.toString(2).padStart(32);
344
+ const referenceBinaryString = assetEntry.reference
345
+ .toString(2)
346
+ .padStart(32);
289
347
  return utilService.getReferenceData(referenceBinaryString);
290
- }
291
- else {
348
+ } else {
292
349
  return null;
293
350
  }
294
- };
351
+ }
295
352
 
296
353
  getReferencesToRecord(tableId, recordIndex) {
297
354
  const referencedTable = this.getTableById(tableId);
298
355
 
299
356
  if (referencedTable) {
300
- const fullBinary = utilService.getBinaryReferenceData(tableId, recordIndex);
301
- const hex = utilService.bin2hex(fullBinary).padStart(8, '0');
302
-
303
- return this.tables.filter((table) => {
304
- if (table.schema) {
305
- return table.schema && table.schema.attributes.find((attribute) => {
306
- return attribute.type === referencedTable.name;
307
- });
308
- }
309
- else if (table.isArray && referencedTable.schema) {
310
- // If the referenced table has a schema, we can check its base name.
311
- // Some array table names are by the base name like EnumTable[] can contain AwardTypeEnumTableEntry
312
-
313
- return table.name.slice(0, table.name.length - 2) === referencedTable.name
314
- || table.name.slice(0, table.name.length - 2) === referencedTable.schema.base;
315
- }
316
- else if (table.isArray) {
317
- return table.name.slice(0, table.name.length - 2) === referencedTable.name;
318
- }
319
- }).filter((table) => {
320
- return table.data.indexOf(hex, 0, 'hex') !== -1;
321
- }).map((table) => {
322
- return {
323
- tableId: table.header.tableId,
324
- name: table.name,
325
- table: table
326
- }
327
- });
357
+ const fullBinary = utilService.getBinaryReferenceData(
358
+ tableId,
359
+ recordIndex
360
+ );
361
+ const hex = utilService.bin2hex(fullBinary).padStart(8, "0");
362
+
363
+ return this.tables
364
+ .filter((table) => {
365
+ if (table.schema) {
366
+ return (
367
+ table.schema &&
368
+ table.schema.attributes.find((attribute) => {
369
+ return attribute.type === referencedTable.name;
370
+ })
371
+ );
372
+ } else if (table.isArray && referencedTable.schema) {
373
+ // If the referenced table has a schema, we can check its base name.
374
+ // Some array table names are by the base name like EnumTable[] can contain AwardTypeEnumTableEntry
375
+
376
+ return (
377
+ table.name.slice(0, table.name.length - 2) ===
378
+ referencedTable.name ||
379
+ table.name.slice(0, table.name.length - 2) ===
380
+ referencedTable.schema.base
381
+ );
382
+ } else if (table.isArray) {
383
+ return (
384
+ table.name.slice(0, table.name.length - 2) ===
385
+ referencedTable.name
386
+ );
387
+ }
388
+ })
389
+ .filter((table) => {
390
+ return table.data.indexOf(hex, 0, "hex") !== -1;
391
+ })
392
+ .map((table) => {
393
+ return {
394
+ tableId: table.header.tableId,
395
+ name: table.name,
396
+ table: table,
397
+ };
398
+ });
328
399
  }
329
- };
330
- };
400
+ }
401
+ }
331
402
 
332
403
  module.exports = FranchiseFile;
333
404
 
@@ -340,9 +411,9 @@ function getTableStartOffsetByGameYear(gameYear) {
340
411
  default:
341
412
  return 0x94;
342
413
  }
343
- };
414
+ }
344
415
 
345
- function unpackFile (data, type) {
416
+ function unpackFile(data, type) {
346
417
  let offset = 0;
347
418
 
348
419
  if (type.format === Constants.FORMAT.FRANCHISE) {
@@ -350,36 +421,39 @@ function unpackFile (data, type) {
350
421
  }
351
422
 
352
423
  return zlib.inflateSync(data.slice(offset));
353
- };
424
+ }
354
425
 
355
- function _packFile (data, options) {
426
+ function _packFile(data, options) {
356
427
  return new Promise((resolve, reject) => {
357
428
  if (options && options.sync) {
358
429
  const newData = zlib.deflateSync(data, {
359
- windowBits: 15
430
+ windowBits: 15,
360
431
  });
361
-
432
+
362
433
  resolve(newData);
363
- }
364
- else {
365
- zlib.deflate(data, {
366
- windowBits: 15
367
- }, function (err, newData) {
368
- if (err) reject(err);
369
-
370
- resolve(newData);
371
- });
434
+ } else {
435
+ zlib.deflate(
436
+ data,
437
+ {
438
+ windowBits: 15,
439
+ },
440
+ function (err, newData) {
441
+ if (err) reject(err);
442
+
443
+ resolve(newData);
444
+ }
445
+ );
372
446
  }
373
447
  });
374
- };
448
+ }
375
449
 
376
- function _save (destination, packedContents, callback) {
450
+ function _save(destination, packedContents, callback) {
377
451
  fs.writeFile(destination, packedContents, callback);
378
- };
452
+ }
379
453
 
380
- function _saveSync (destination, packedContents) {
454
+ function _saveSync(destination, packedContents) {
381
455
  fs.writeFileSync(destination, packedContents);
382
- };
456
+ }
383
457
 
384
458
  function getFileType(data) {
385
459
  const isDataCompressed = isCompressed(data);
@@ -387,59 +461,56 @@ function getFileType(data) {
387
461
  const year = getGameYear(data, isDataCompressed, format);
388
462
 
389
463
  return {
390
- 'format': format,
391
- 'compressed': isDataCompressed,
392
- 'year': year
464
+ format: format,
465
+ compressed: isDataCompressed,
466
+ year: year,
393
467
  };
394
- };
468
+ }
395
469
 
396
470
  function isCompressed(data) {
397
- const DECOMPRESSED_HEADER = Buffer.from([0x46, 0x72, 0x54, 0x6B]); // FrTk
471
+ const DECOMPRESSED_HEADER = Buffer.from([0x46, 0x72, 0x54, 0x6b]); // FrTk
398
472
 
399
473
  if (Buffer.compare(data.slice(0, 4), DECOMPRESSED_HEADER) === 0) {
400
474
  return false;
401
475
  }
402
476
 
403
477
  return true;
404
- };
478
+ }
405
479
 
406
480
  function getFormat(data, isCompressed) {
407
481
  if (isCompressed) {
408
- const ZLIB_HEADER = Buffer.from([0x78, 0x9C]);
482
+ const ZLIB_HEADER = Buffer.from([0x78, 0x9c]);
409
483
 
410
484
  if (Buffer.compare(data.slice(0, 2), ZLIB_HEADER) === 0) {
411
- return 'franchise-common';
412
- }
413
- else {
414
- return 'franchise';
485
+ return "franchise-common";
486
+ } else {
487
+ return "franchise";
415
488
  }
416
- }
417
- else {
489
+ } else {
418
490
  // very simple check based on file length.
419
491
  // This assumes the common files are smaller than 9,000 KB.
420
492
  if (data.length > 0x895440) {
421
- return 'franchise';
422
- }
423
- else {
424
- return 'franchise-common';
493
+ return "franchise";
494
+ } else {
495
+ return "franchise-common";
425
496
  }
426
497
  }
427
- };
498
+ }
428
499
 
429
500
  function getGameYear(data, isCompressed, format) {
430
501
  const schemaMax = [
431
502
  {
432
- 'year': 19,
433
- 'max': 95
503
+ year: 19,
504
+ max: 95,
434
505
  },
435
506
  {
436
- 'year': 24,
437
- 'max': 999
438
- }
507
+ year: 24,
508
+ max: 999,
509
+ },
439
510
  ];
440
511
 
441
- if(isCompressed) {
442
- // look at the max schemas per year. M19 schemas will be less than or equal to 95,
512
+ if (isCompressed) {
513
+ // look at the max schemas per year. M19 schemas will be less than or equal to 95,
443
514
  // while M20 schemas can be anywhere from 96 to 999 because the last schema hasn't been made yet.
444
515
  // Once M21 releases, the M20 schema max will be updated with the final number.
445
516
 
@@ -455,51 +526,43 @@ function getGameYear(data, isCompressed, format) {
455
526
 
456
527
  if (yearIdentifier[0] === 0x52) {
457
528
  return 19;
458
- }
459
- else if (yearIdentifier[2] === 0x30) {
529
+ } else if (yearIdentifier[2] === 0x30) {
460
530
  return 20;
461
- }
462
- else if (yearIdentifier[2] === 0x31) {
531
+ } else if (yearIdentifier[2] === 0x31) {
463
532
  return 21;
464
- }
465
- else if (yearIdentifier[2] === 0x32) {
533
+ } else if (yearIdentifier[2] === 0x32) {
466
534
  return 22;
467
- }
468
- else if (yearIdentifier[2] === 0x33) {
535
+ } else if (yearIdentifier[2] === 0x33) {
469
536
  return 23;
470
- }
471
- else if (yearIdentifier[2] === 0x34 || yearIdentifier[2] === 'd') {
537
+ } else if (yearIdentifier[2] === 0x34 || yearIdentifier[2] === "d") {
472
538
  return 24;
473
- }
474
- else {
539
+ } else {
475
540
  const schemaMajor = getCompressedSchema(data).major;
476
- const year = schemaMax.find((schema) => { return schema.max >= schemaMajor; }).year;
541
+ const year = schemaMax.find((schema) => {
542
+ return schema.max >= schemaMajor;
543
+ }).year;
477
544
  return year;
478
545
  }
479
-
480
- }
481
- else {
546
+ } else {
482
547
  const schemaMajor = getDecompressedM20Schema(data).major;
483
-
548
+
484
549
  if (schemaMajor === 0) {
485
550
  // M19 did not include schema info in uncompressed files.
486
551
  return 19;
487
- }
488
- else {
552
+ } else {
489
553
  // M21 and M20 have very similar formats. We can tell M21 because it has a table with 'M21' in the name.
490
- if (data.indexOf('M21') > -1) {
554
+ if (data.indexOf("M21") > -1) {
491
555
  return 21;
492
- }
493
- else {
556
+ } else {
494
557
  return null;
495
558
  }
496
559
  }
497
560
  }
498
- };
561
+ }
499
562
 
500
563
  function getSchemaMetadata(data, type) {
501
564
  let schemaMeta = {
502
- 'gameYear': type.year
565
+ gameYear: type.year,
503
566
  };
504
567
 
505
568
  if (type.compressed) {
@@ -512,14 +575,12 @@ function getSchemaMetadata(data, type) {
512
575
  const schemaData = getCompressedSchema(data);
513
576
  schemaMeta.major = schemaData.major;
514
577
  schemaMeta.minor = schemaData.minor;
515
- }
516
- else {
578
+ } else {
517
579
  if (type.year === 19) {
518
580
  // M19 did not include schema info in uncompressed files.
519
581
  schemaMeta.major = 0;
520
582
  schemaMeta.minor = 0;
521
- }
522
- else {
583
+ } else {
523
584
  const schemaData = getDecompressedM20Schema(data);
524
585
  schemaMeta.major = schemaData.major;
525
586
  schemaMeta.minor = schemaData.minor;
@@ -527,18 +588,18 @@ function getSchemaMetadata(data, type) {
527
588
  }
528
589
 
529
590
  return schemaMeta;
530
- };
591
+ }
531
592
 
532
593
  function getCompressedSchema(data) {
533
594
  return {
534
- 'major': data.readUInt32LE(0x3E),
535
- 'minor': data.readUInt32LE(0x42)
595
+ major: data.readUInt32LE(0x3e),
596
+ minor: data.readUInt32LE(0x42),
536
597
  };
537
- };
598
+ }
538
599
 
539
600
  function getDecompressedM20Schema(data) {
540
601
  return {
541
- 'major': data.readUInt32BE(0x2C),
542
- 'minor': data.readUInt32BE(0x28)
602
+ major: data.readUInt32BE(0x2c),
603
+ minor: data.readUInt32BE(0x28),
543
604
  };
544
- };
605
+ }