madden-franchise 3.0.4 → 3.0.6
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 +5 -2
- package/FranchiseFileField.js +25 -3
- package/FranchiseFileRecord.js +21 -6
- package/FranchiseFileTable.js +16 -2
- package/data/schemas/23/M23_158_18.gz +0 -0
- package/data/schemas/24/M24_155_8.gz +0 -0
- package/package.json +1 -1
- package/scripts/scratchpad.js +38 -0
- package/data/schemas/23/M23_156_2.gz +0 -0
package/FranchiseFile.js
CHANGED
|
@@ -276,7 +276,7 @@ class FranchiseFile extends EventEmitter {
|
|
|
276
276
|
|
|
277
277
|
getReferencedRecord (referenceValue) {
|
|
278
278
|
const reference = utilService.getReferenceData(referenceValue);
|
|
279
|
-
return this.getTableById(reference.tableId)
|
|
279
|
+
return this.getTableById(reference.tableId)?.records[reference.rowNumber];
|
|
280
280
|
};
|
|
281
281
|
|
|
282
282
|
getReferenceFromAssetId (assetId) {
|
|
@@ -433,7 +433,7 @@ function getGameYear(data, isCompressed, format) {
|
|
|
433
433
|
'max': 95
|
|
434
434
|
},
|
|
435
435
|
{
|
|
436
|
-
'year':
|
|
436
|
+
'year': 24,
|
|
437
437
|
'max': 999
|
|
438
438
|
}
|
|
439
439
|
];
|
|
@@ -468,6 +468,9 @@ function getGameYear(data, isCompressed, format) {
|
|
|
468
468
|
else if (yearIdentifier[2] === 0x33) {
|
|
469
469
|
return 23;
|
|
470
470
|
}
|
|
471
|
+
else if (yearIdentifier[2] === 0x34 || yearIdentifier[2] === 'd') {
|
|
472
|
+
return 24;
|
|
473
|
+
}
|
|
471
474
|
else {
|
|
472
475
|
const schemaMajor = getCompressedSchema(data).major;
|
|
473
476
|
const year = schemaMax.find((schema) => { return schema.max >= schemaMajor; }).year;
|
package/FranchiseFileField.js
CHANGED
|
@@ -10,6 +10,7 @@ class FranchiseFileField {
|
|
|
10
10
|
this._unformattedValue = null;
|
|
11
11
|
this._offset = offset;
|
|
12
12
|
this._parent = parent;
|
|
13
|
+
this._isChanged = false;
|
|
13
14
|
|
|
14
15
|
if (offset.valueInSecondTable) {
|
|
15
16
|
this.secondTableField = new FranchiseFileTable2Field(this._recordBuffer.readUInt32BE(offset.offset / 8), offset.maxLength);
|
|
@@ -53,12 +54,13 @@ class FranchiseFileField {
|
|
|
53
54
|
return null;
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
set value (value) {
|
|
57
|
+
set value (value) {
|
|
57
58
|
if (this._unformattedValue === null) {
|
|
58
59
|
this._setUnformattedValueIfEmpty();
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
this._value = value;
|
|
63
|
+
this.isChanged = true;
|
|
62
64
|
|
|
63
65
|
if (this.offset.valueInSecondTable) {
|
|
64
66
|
this.secondTableField.value = value.toString();
|
|
@@ -83,8 +85,15 @@ class FranchiseFileField {
|
|
|
83
85
|
this._value = theEnum.name;
|
|
84
86
|
}
|
|
85
87
|
catch (err) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
// if user tries entering an invalid enum value, check if it's an empty record reference (will be binary)
|
|
89
|
+
if (utilService.stringOnlyContainsBinaryDigits(value)) {
|
|
90
|
+
this._value = value;
|
|
91
|
+
this._unformattedValue.setBits(this.offset.offset, value, this.offset.length);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this._value = null;
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
88
97
|
}
|
|
89
98
|
}
|
|
90
99
|
else {
|
|
@@ -149,6 +158,19 @@ class FranchiseFileField {
|
|
|
149
158
|
this._parent.onEvent('change', this);
|
|
150
159
|
};
|
|
151
160
|
|
|
161
|
+
get isChanged() {
|
|
162
|
+
return this._isChanged;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
set isChanged(changed) {
|
|
166
|
+
this._isChanged = changed;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
clearCachedValues() {
|
|
170
|
+
this._value = null;
|
|
171
|
+
this._unformattedValue = null;
|
|
172
|
+
};
|
|
173
|
+
|
|
152
174
|
_setUnformattedValueIfEmpty() {
|
|
153
175
|
this._value = null;
|
|
154
176
|
this._unformattedValue = new BitView(this._recordBuffer, this._recordBuffer.byteOffset);
|
package/FranchiseFileRecord.js
CHANGED
|
@@ -7,8 +7,8 @@ class FranchiseFileRecord {
|
|
|
7
7
|
this._offsetTable = offsetTable;
|
|
8
8
|
this.index = index;
|
|
9
9
|
this._fieldsArray = [];
|
|
10
|
-
this._fields = this.parseRecordFields(
|
|
11
|
-
this.
|
|
10
|
+
this._fields = this.parseRecordFields();
|
|
11
|
+
this._isChanged = false;
|
|
12
12
|
this.arraySize = null;
|
|
13
13
|
this.isEmpty = false;
|
|
14
14
|
this._parent = parent;
|
|
@@ -55,6 +55,20 @@ class FranchiseFileRecord {
|
|
|
55
55
|
});
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
get isChanged() {
|
|
59
|
+
return this._isChanged;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
set isChanged(changed) {
|
|
63
|
+
this._isChanged = changed;
|
|
64
|
+
|
|
65
|
+
if (changed === false) {
|
|
66
|
+
this.fieldsArray.forEach((field) => {
|
|
67
|
+
field.isChanged = false;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
getFieldByKey(key) {
|
|
59
73
|
return this._fields[key];
|
|
60
74
|
};
|
|
@@ -69,15 +83,16 @@ class FranchiseFileRecord {
|
|
|
69
83
|
return field ? field.referenceData : null;
|
|
70
84
|
};
|
|
71
85
|
|
|
72
|
-
parseRecordFields(
|
|
86
|
+
parseRecordFields() {
|
|
73
87
|
let fields = {};
|
|
88
|
+
this._fieldsArray = [];
|
|
74
89
|
|
|
75
|
-
for (let j = 0; j <
|
|
76
|
-
const offset =
|
|
90
|
+
for (let j = 0; j < this._offsetTable.length; j++) {
|
|
91
|
+
const offset = this._offsetTable[j];
|
|
77
92
|
|
|
78
93
|
// Push the entire record buffer to the field. No need to perform a calculation
|
|
79
94
|
// to subarray the buffer, BitView will take care of it in the Field.
|
|
80
|
-
fields[offset.name] = new FranchiseFileField(offset.name,
|
|
95
|
+
fields[offset.name] = new FranchiseFileField(offset.name, this._data, offset, this);
|
|
81
96
|
|
|
82
97
|
this._fieldsArray.push(fields[offset.name]);
|
|
83
98
|
}
|
package/FranchiseFileTable.js
CHANGED
|
@@ -145,7 +145,7 @@ class FranchiseFileTable extends EventEmitter {
|
|
|
145
145
|
const firstOffset = this.offsetTable[0];
|
|
146
146
|
if (firstOffset.type !== 'string') {
|
|
147
147
|
isEmptyReference = true;
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
// Save the row number that this record points to.
|
|
150
150
|
emptyRecordReferenceIndicies.push(firstFourBytesReference.rowNumber);
|
|
151
151
|
}
|
|
@@ -154,7 +154,6 @@ class FranchiseFileTable extends EventEmitter {
|
|
|
154
154
|
record.isEmpty = isEmptyReference;
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
-
|
|
158
157
|
// We need to determine the starting node.
|
|
159
158
|
// To do that, we need to find the empty record which no other empty record points to.
|
|
160
159
|
const unreachableRecords = this.records.filter((record) => { return record.isEmpty; }).filter((record) => {
|
|
@@ -439,6 +438,21 @@ class FranchiseFileTable extends EventEmitter {
|
|
|
439
438
|
// const referenceData = utilService.getReferenceDataFromBuffer(object.data.slice(0, 4));
|
|
440
439
|
// if (referenceData.tableId !== 0 || referenceData.rowNumber > this.header.recordCapacity) {
|
|
441
440
|
|
|
441
|
+
|
|
442
|
+
// if the changed field isn't included in the first 32 bits, zero out the first 32 bits.
|
|
443
|
+
// Otherwise, it's not necessary to zero out.
|
|
444
|
+
const changedFieldsInFirst4Bytes = object.fieldsArray.filter((field) => { return field.isChanged && field.offset.indexOffset < 32; });
|
|
445
|
+
if (changedFieldsInFirst4Bytes.length === 0) {
|
|
446
|
+
// set first 4 bytes to 0
|
|
447
|
+
this._changeRecordBuffers(object.index, 0);
|
|
448
|
+
|
|
449
|
+
// invalidate the cached values since we set the buffer directly
|
|
450
|
+
const fieldsInFirst4Bytes = object.fieldsArray.filter((field) => { return field.offset.indexOffset < 32; });
|
|
451
|
+
fieldsInFirst4Bytes.forEach((field) => {
|
|
452
|
+
field.clearCachedValues();
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
442
456
|
// if the record contains any string values, point the string values to
|
|
443
457
|
// their correct offsets
|
|
444
458
|
this.strategy.recalculateStringOffsets(this, object);
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const FranchiseFile = require('../FranchiseFile');
|
|
2
|
+
const utilService = require('../services/utilService');
|
|
3
|
+
|
|
4
|
+
const franchisePath = 'C:\\Users\\Matt\\Downloads\\CAREER-COACHTEST';
|
|
5
|
+
const ftcPath = 'D:\\Projects\\Madden 24\\FTCs\\franchise-league-binary.FTC';
|
|
6
|
+
const schemaPath = 'C:\\Users\\Matt\\AppData\\Roaming\\madden-franchise-editor\\schemas\\M24_144_6.gz';
|
|
7
|
+
|
|
8
|
+
(async () => {
|
|
9
|
+
function franchiseFileLoadPromise(file) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
file.on('ready', () => {
|
|
12
|
+
resolve();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const file = new FranchiseFile(franchisePath, {
|
|
18
|
+
schemaOverride: {
|
|
19
|
+
path: schemaPath
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const ftc = new FranchiseFile(ftcPath, {
|
|
24
|
+
schemaOverride: {
|
|
25
|
+
path: schemaPath
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await Promise.all([franchiseFileLoadPromise(file), franchiseFileLoadPromise(ftc)]);
|
|
30
|
+
|
|
31
|
+
const tableToFind = file.getTableById(4227);
|
|
32
|
+
await tableToFind.readRecords();
|
|
33
|
+
|
|
34
|
+
const college = tableToFind.records[2].getFieldByKey('College');
|
|
35
|
+
const collegeVal = utilService.bin2dec(college.value);
|
|
36
|
+
const ref = ftc.getReferenceFromAssetId(collegeVal);
|
|
37
|
+
console.log(ref);
|
|
38
|
+
})();
|
|
Binary file
|