madden-franchise 2.4.1 → 2.5.2

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
@@ -175,30 +175,20 @@ class FranchiseFile extends EventEmitter {
175
175
  });
176
176
  };
177
177
 
178
- save(outputFilePath) {
179
- return this.packFile(outputFilePath);
178
+ save(outputFilePath, options) {
179
+ return this.packFile(outputFilePath, options);
180
180
  };
181
181
 
182
- packFile(outputFilePath) {
182
+ packFile(outputFilePath, options) {
183
183
  const that = this;
184
184
  this.emit('saving');
185
185
 
186
186
  return new Promise((resolve, reject) => {
187
187
  this.unpackedFileContents = this.strategy.file.generateUnpackedContents(this.tables, this.unpackedFileContents);
188
- // const changedTables = this.tables.filter((table) => { return table.isChanged; });
189
-
190
- // for (let i = 0; i < changedTables.length; i++) {
191
- // let table = changedTables[i];
192
- // const header = that.unpackedFileContents.slice(0, table.offset);
193
- // const trailer = that.unpackedFileContents.slice(table.offset + table.data.length);
194
- // that.unpackedFileContents = Buffer.concat([header, table.hexData, trailer]);
195
-
196
- // table.isChanged = false;
197
- // }
198
188
 
199
189
  let destination = outputFilePath ? outputFilePath : this.filePath;
200
190
 
201
- _packFile(this.unpackedFileContents).then((data) => {
191
+ _packFile(this.unpackedFileContents, options).then((data) => {
202
192
  const dataToSave = this.strategy.file.postPackFile(this.packedFileContents, data);
203
193
  _save(destination, dataToSave, (err) => {
204
194
  if (err) {
@@ -292,7 +282,7 @@ class FranchiseFile extends EventEmitter {
292
282
 
293
283
  if (referencedTable) {
294
284
  const fullBinary = utilService.getBinaryReferenceData(tableId, recordIndex);
295
- const hex = utilService.bin2hex(fullBinary);
285
+ const hex = utilService.bin2hex(fullBinary).padStart(8, '0');
296
286
 
297
287
  return this.tables.filter((table) => {
298
288
  if (table.schema) {
@@ -300,6 +290,13 @@ class FranchiseFile extends EventEmitter {
300
290
  return attribute.type === referencedTable.name;
301
291
  });
302
292
  }
293
+ else if (table.isArray && referencedTable.schema) {
294
+ // If the referenced table has a schema, we can check its base name.
295
+ // Some array table names are by the base name like EnumTable[] can contain AwardTypeEnumTableEntry
296
+
297
+ return table.name.slice(0, table.name.length - 2) === referencedTable.name
298
+ || table.name.slice(0, table.name.length - 2) === referencedTable.schema.base;
299
+ }
303
300
  else if (table.isArray) {
304
301
  return table.name.slice(0, table.name.length - 2) === referencedTable.name;
305
302
  }
@@ -339,15 +336,24 @@ function unpackFile (data, type) {
339
336
  return zlib.inflateSync(data.slice(offset));
340
337
  };
341
338
 
342
- function _packFile (data) {
339
+ function _packFile (data, options) {
343
340
  return new Promise((resolve, reject) => {
344
- zlib.deflate(data, {
345
- windowBits: 15
346
- }, function (err, newData) {
347
- if (err) reject(err);
348
-
349
- resolve(newData);
350
- });
341
+ if (options && options.sync) {
342
+ const data = zlib.deflateSync(data, {
343
+ windowBits: 15
344
+ });
345
+
346
+ resolve(data);
347
+ }
348
+ else {
349
+ zlib.deflate(data, {
350
+ windowBits: 15
351
+ }, function (err, newData) {
352
+ if (err) reject(err);
353
+
354
+ resolve(newData);
355
+ });
356
+ }
351
357
  });
352
358
  };
353
359
 
@@ -46,6 +46,7 @@ class FranchiseSchema extends EventEmitter {
46
46
  this.meta = this.schema.meta;
47
47
  this.schemas = this.schema.schemas;
48
48
  this.schemaMap = {};
49
+ this.enumMap = {};
49
50
 
50
51
  for (let i = 0; i < this.schemas.length; i++) {
51
52
  const schema = this.schemas[i];
@@ -56,6 +57,7 @@ class FranchiseSchema extends EventEmitter {
56
57
 
57
58
  if (attribute.enum) {
58
59
  attribute.enum = new FranchiseEnum(attribute.enum);
60
+ this.enumMap[attribute.enum.name] = attribute.enum;
59
61
  }
60
62
  }
61
63
  }
@@ -64,6 +66,11 @@ class FranchiseSchema extends EventEmitter {
64
66
  const extraSchemas = schemaGenerator.getExtraSchemas();
65
67
  extraSchemas.forEach((schema) => {
66
68
  if (!this.schemaMap[schema.name]) {
69
+ schema.attributes.forEach((attrib) => {
70
+ if (attrib.enum) {
71
+ attrib.enum = new FranchiseEnum(this.enumMap[attrib.enum]);
72
+ }
73
+ })
67
74
  this.schemas.unshift(schema);
68
75
  this.schemaMap[schema.name] = schema;
69
76
  addedExtraSchema = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "madden-franchise",
3
- "version": "2.4.1",
3
+ "version": "2.5.2",
4
4
  "description": "Tools to read a madden franchise file and get data from it",
5
5
  "main": "FranchiseFile.js",
6
6
  "scripts": {
@@ -13,7 +13,7 @@
13
13
  "author": "matthewpanetta",
14
14
  "license": "MIT",
15
15
  "dependencies": {
16
- "xml-stream": "^0.4.5"
16
+ "node-xml-stream-parser": "^1.0.12"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
@@ -22,7 +22,7 @@
22
22
  "devDependencies": {
23
23
  "chai": "^4.2.0",
24
24
  "chai-eventemitter": "^1.1.1",
25
- "mocha": "^6.2.2",
25
+ "mocha": "^9.1.4",
26
26
  "proxyquire": "^2.1.3",
27
27
  "sinon": "^7.5.0"
28
28
  }
@@ -1,14 +1,11 @@
1
- // USAGE:
2
- // node schema-generator.js [input file path] [output file folder]
3
-
4
1
  const fs = require('fs');
5
2
  const path = require('path');
6
3
  const zlib = require('zlib');
7
- const XmlStream = require('xml-stream');
4
+ const { pipeline } = require('stream');
8
5
  const utilService = require('./utilService');
9
6
  const FranchiseEnum = require('../FranchiseEnum');
7
+ const XmlParser = require('node-xml-stream-parser');
10
8
  const EventEmitter = require('events').EventEmitter;
11
- const extraSchemas = require('../data/schemas/extra-schemas.json');
12
9
 
13
10
  let schemaGenerator = {};
14
11
  schemaGenerator.eventEmitter = new EventEmitter();
@@ -22,103 +19,147 @@ schemaGenerator.generateFromStream = (stream, showOutput, outputFile) => {
22
19
  schemaGenerator.root = {}
23
20
  schemaGenerator.schemas = [];
24
21
  schemaGenerator.schemaMap = {};
22
+ schemaGenerator.schemaMeta = {};
25
23
  schemaGenerator.enums = [];
24
+ const extraSchemas = schemaGenerator.getExtraSchemas();
26
25
 
27
- schemaGenerator.xml = new XmlStream(stream);
26
+ schemaGenerator.xml = new XmlParser();
28
27
 
29
- schemaGenerator.xml.collect('attribute');
28
+ pipeline(
29
+ stream,
30
+ schemaGenerator.xml,
31
+ (err) => {
32
+ if (err) {
33
+ console.error(err);
34
+ throw err;
35
+ }
36
+
37
+ schemaGenerator.enums.forEach((theEnum) => {
38
+ theEnum.setMemberLength();
39
+ });
30
40
 
31
- schemaGenerator.xml.on('endElement: FranTkData', function (data) {
32
- const majorVersion = data.$.dataMajorVersion;
33
- const minorVersion = data.$.dataMinorVersion;
34
- const databaseName = data.$.databaseName;
35
- const gameYear = /Madden(\d{2})/.exec(databaseName)[1];
41
+ const majorVersion = schemaGenerator.schemaMeta.dataMajorVersion;
42
+ const minorVersion = schemaGenerator.schemaMeta.dataMinorVersion;
43
+ const databaseName = schemaGenerator.schemaMeta.databaseName;
36
44
 
37
- addExtraSchemas();
38
- calculateInheritedSchemas();
45
+ const gameYear = /Madden(\d{2})/.exec(databaseName)[1];
39
46
 
40
- schemaGenerator.root = {
41
- 'meta': {
42
- 'major': parseInt(majorVersion),
43
- 'minor': parseInt(minorVersion),
44
- 'gameYear': parseInt(gameYear)
45
- },
46
- 'schemas': schemaGenerator.schemas,
47
- 'schemaMap': schemaGenerator.schemaMap
48
- };
47
+ addExtraSchemas();
48
+ calculateInheritedSchemas();
49
49
 
50
- if (outputFile) {
51
- zlib.gzip(JSON.stringify(schemaGenerator.root), function (_, data) {
52
- fs.writeFileSync(`${outputFile}\\${majorVersion}_${minorVersion}.gz`, data);
53
- });
50
+ schemaGenerator.root = {
51
+ 'meta': {
52
+ 'major': parseInt(majorVersion),
53
+ 'minor': parseInt(minorVersion),
54
+ 'gameYear': parseInt(gameYear)
55
+ },
56
+ 'schemas': schemaGenerator.schemas,
57
+ 'schemaMap': schemaGenerator.schemaMap
58
+ };
59
+
60
+ if (outputFile) {
61
+ zlib.gzip(JSON.stringify(schemaGenerator.root), function (_, data) {
62
+ fs.writeFileSync(`${outputFile}\\${majorVersion}_${minorVersion}.gz`, data);
63
+ });
64
+ }
65
+
66
+ schemaGenerator.eventEmitter.emit('schemas:done', schemaGenerator.root);
54
67
  }
68
+ );
55
69
 
56
- schemaGenerator.eventEmitter.emit('schemas:done', schemaGenerator.root);
57
- });
70
+ let currentParent = {
71
+ type: '',
72
+ ref: null
73
+ };
58
74
 
59
- schemaGenerator.xml.on('endElement: enum', function (theEnum) {
60
- if (showOutput) console.log(`Adding enum ${theEnum.$.name}`);
75
+ schemaGenerator.xml.on('opentag', (name, attrs) => {
76
+ if (name === 'FranTkData') {
77
+ schemaGenerator.schemaMeta.databaseName = attrs.databaseName;
78
+ schemaGenerator.schemaMeta.dataMajorVersion = attrs.dataMajorVersion;
79
+ schemaGenerator.schemaMeta.dataMinorVersion = attrs.dataMinorVersion;
80
+ }
61
81
 
62
- let newEnum = new FranchiseEnum(theEnum.$.name, theEnum.$.assetId, theEnum.$.isRecordPersistent);
82
+ else if (name === 'enum') {
83
+ let theEnum = parseEnum(attrs);
84
+ schemaGenerator.enums.push(theEnum);
63
85
 
64
- if (theEnum.attribute) {
65
- theEnum.attribute.forEach((attribute) => {
66
- newEnum.addMember(attribute.$.name, attribute.$.idx, attribute.$.value);
67
- });
86
+ currentParent = {
87
+ type: 'enum',
88
+ ref: theEnum
89
+ }
68
90
  }
69
91
 
70
- newEnum.setMemberLength();
71
- schemaGenerator.enums.push(newEnum);
72
- });
92
+ else if (name === 'schema') {
93
+ let schema = parseSchema(attrs);
94
+ schema.attributes = [];
73
95
 
74
- schemaGenerator.xml.on('endElement: schema', function (schema) {
75
- if (showOutput) console.log(`Adding schema ${schema.$.name}`);
76
- let attributes = [];
77
-
78
- if (schema.attribute) {
79
- attributes = schema.attribute.map((attribute) => {
80
- return {
81
- 'index': attribute.$.idx,
82
- 'name': attribute.$.name,
83
- 'type': attribute.$.type,
84
- 'minValue': attribute.$.minValue,
85
- 'maxValue': attribute.$.maxValue,
86
- 'maxLength': attribute.$.maxLen,
87
- 'default': attribute.$.default,
88
- 'final': attribute.$.final,
89
- 'enum': getEnum(attribute.$.type),
90
- 'const': attribute.$.const
91
- }
92
- });
96
+ schemaGenerator.schemas.push(schema);
97
+ schemaGenerator.schemaMap[schema.name] = schema;
98
+
99
+ currentParent = {
100
+ type: 'schema',
101
+ ref: schema
102
+ }
103
+ }
104
+
105
+ else if (name === 'attribute') {
106
+ if (currentParent.type === 'enum') {
107
+ currentParent.ref.addMember(attrs.name, attrs.idx, attrs.value);
108
+ }
109
+ else {
110
+ const attribute = parseAttribute(attrs);
111
+ currentParent.ref.attributes.push(attribute);
112
+ }
93
113
  }
114
+ });
94
115
 
95
- const element = {
96
- 'assetId': schema.$.assetId,
97
- 'ownerAssetId': schema.$.ownerAssetId,
98
- 'numMembers': schema.$.numMembers,
99
- 'name': schema.$.name,
100
- 'base': schema.$.base,
101
- 'attributes': attributes
116
+ function parseEnum(enumAttributes) {
117
+ return new FranchiseEnum(enumAttributes.name, enumAttributes.assetId, enumAttributes.isRecordPersistent);
118
+ };
119
+
120
+ function parseSchema(schemaAttributes) {
121
+ return {
122
+ 'assetId': schemaAttributes.assetId,
123
+ 'ownerAssetId': schemaAttributes.ownerAssetId,
124
+ 'numMembers': schemaAttributes.numMembers,
125
+ 'name': schemaAttributes.name,
126
+ 'base': schemaAttributes.base
102
127
  };
128
+ };
129
+
130
+ function parseAttribute(attributeAttributes) {
131
+ return {
132
+ 'index': attributeAttributes.idx,
133
+ 'name': attributeAttributes.name,
134
+ 'type': attributeAttributes.type,
135
+ 'minValue': attributeAttributes.minValue,
136
+ 'maxValue': attributeAttributes.maxValue,
137
+ 'maxLength': attributeAttributes.maxLen,
138
+ 'default': getDefaultValue(attributeAttributes.default),
139
+ 'final': attributeAttributes.final,
140
+ 'enum': getEnum(attributeAttributes.type),
141
+ 'const': attributeAttributes.const
142
+ }
103
143
 
104
- schemaGenerator.schemas.push(element);
105
- schemaGenerator.schemaMap[element.name] = element;
144
+ function getDefaultValue(defaultVal) {
145
+ if (!defaultVal) { return undefined; }
106
146
 
107
- if (element.name === 'WinLossStreakPlayerGoal') {
108
- // calculateInheritedSchemas();
109
- // // fs.writeFileSync(outputFile, JSON.stringify(schemaGenerator.schemas));
110
- // zlib.gzip(JSON.stringify(schemaGenerator.schemas), function (_, data) {
111
- // fs.writeFileSync(outputFile, data);
112
- // });
113
- // schemaGenerator.emit('schemas:done', schemaGenerator.schemas);
147
+ defaultVal = defaultVal
148
+ .replace(new RegExp('&#xD;', 'g'), '\r')
149
+ .replace(new RegExp('&#xA;', 'g'), '\n')
150
+ .replace(new RegExp('&amp;', 'g'), '&')
151
+ .replace(new RegExp('&gt;', 'g'), '>')
152
+ .replace(new RegExp('&lt;', 'g'), '<')
153
+ .replace(new RegExp('&quot;', 'g'), '\"')
154
+
155
+ return defaultVal;
114
156
  }
115
- });
157
+ };
116
158
 
117
159
  function addExtraSchemas() {
118
160
  extraSchemas.forEach((schema) => {
119
-
120
161
  if (!schemaGenerator.schemaMap[schema.name]) {
121
- schema.attributes.filter((attrib) => {
162
+ schema.attributes.filter((attrib) => {
122
163
  return attrib.enum && !(attrib.enum instanceof FranchiseEnum);
123
164
  }).forEach((attrib) => {
124
165
  attrib.enum = getEnum(attrib.enum);
@@ -143,19 +184,7 @@ schemaGenerator.generateFromStream = (stream, showOutput, outputFile) => {
143
184
  };
144
185
 
145
186
  schemaGenerator.getExtraSchemas = () => {
146
- let newSchemas = [];
147
-
148
- extraSchemas.forEach((schema) => {
149
- schema.attributes.filter((attrib) => {
150
- return attrib.enum && !(attrib.enum instanceof FranchiseEnum);
151
- }).forEach((attrib) => {
152
- attrib.enum = new FranchiseEnum(attrib.enum);
153
- });
154
-
155
- newSchemas.push(schema);
156
- });
157
-
158
- return newSchemas;
187
+ return JSON.parse(JSON.stringify(require(path.join(__dirname, '../data/schemas/extra-schemas.json'))));
159
188
  };
160
189
 
161
190
  schemaGenerator.calculateInheritedSchemas = (schemaList) => {