@etothepii/satisfactory-file-parser 0.4.12 → 0.4.14
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/CHANGELOG.md +12 -0
- package/README.md +43 -22
- package/build/parser/byte/binary-readable.interface.d.ts +0 -3
- package/build/parser/byte/binary-writable.interface.d.ts +20 -0
- package/build/parser/byte/binary-writable.interface.js +2 -0
- package/build/parser/byte/byte-reader.class.d.ts +0 -3
- package/build/parser/byte/byte-reader.class.js +0 -8
- package/build/parser/byte/byte-writer.class.d.ts +6 -3
- package/build/parser/byte/byte-writer.class.js +3 -1
- package/build/parser/satisfactory/blueprint/blueprint-reader.js +10 -10
- package/build/parser/satisfactory/edit/edit-constants.d.ts +157 -3
- package/build/parser/satisfactory/edit/edit-constants.js +237 -161
- package/build/parser/satisfactory/objects/DataFields.js +9 -9
- package/build/parser/satisfactory/objects/SaveObject.d.ts +1 -1
- package/build/parser/satisfactory/objects/SaveObject.js +1 -1
- package/build/parser/satisfactory/objects/property/generic/FloatProperty.js +1 -1
- package/build/parser/satisfactory/objects/property/generic/SetProperty.js +5 -2
- package/build/parser/satisfactory/objects/property/generic/StructProperty.js +13 -5
- package/build/parser/satisfactory/save/level.class.d.ts +1 -2
- package/build/parser/satisfactory/save/level.class.js +10 -15
- package/build/parser/satisfactory/save/save-reader.js +8 -4
- package/build/parser/satisfactory/save/save.types.d.ts +0 -25
- package/build/parser/satisfactory/structs/util.types.js +8 -8
- package/build/parser/stream/reworked/readable-stream-parser.d.ts +1 -0
- package/build/parser/stream/reworked/readable-stream-parser.js +28 -3
- package/package.json +1 -1
- package/build/parser/satisfactory/objects/ObjectReference.d.ts +0 -10
- package/build/parser/satisfactory/objects/ObjectReference.js +0 -17
- package/build/parser/satisfactory/objects/Property.d.ts +0 -272
- package/build/parser/satisfactory/objects/Property.js +0 -1177
- package/build/parser/satisfactory/objects/ue/FMD5Hash.d.ts +0 -7
- package/build/parser/satisfactory/objects/ue/FMD5Hash.js +0 -19
- package/build/parser/satisfactory/objects/ue/GUID.d.ts +0 -6
- package/build/parser/satisfactory/objects/ue/GUID.js +0 -21
- package/build/parser/satisfactory/save/asynchronous-level.class.d.ts +0 -9
- package/build/parser/satisfactory/save/asynchronous-level.class.js +0 -66
- package/build/parser/stream/byte-stream-reader.class.d.ts +0 -57
- package/build/parser/stream/byte-stream-reader.class.js +0 -241
- package/build/parser/stream/json-stream-state-writer.d.ts +0 -12
- package/build/parser/stream/json-stream-state-writer.js +0 -18
- package/build/parser/stream/json-stream-writable.d.ts +0 -20
- package/build/parser/stream/json-stream-writable.js +0 -83
- package/build/parser/stream/json-stream-writer.d.ts +0 -22
- package/build/parser/stream/json-stream-writer.js +0 -127
- package/build/parser/stream/reworked/stream-parser.d.ts +0 -6
- package/build/parser/stream/reworked/stream-parser.js +0 -31
- package/build/parser/stream/save-stream-json-stringifier.d.ts +0 -6
- package/build/parser/stream/save-stream-json-stringifier.js +0 -35
- package/build/parser/stream/save-stream-reader.class.d.ts +0 -15
- package/build/parser/stream/save-stream-reader.class.js +0 -121
- package/build/parser/stream/save-stream-writer.class.d.ts +0 -25
- package/build/parser/stream/save-stream-writer.class.js +0 -119
- package/build/parser/stream/stream-level.class.d.ts +0 -12
- package/build/parser/stream/stream-level.class.js +0 -103
- package/build/parser/stream/stream-parser.d.ts +0 -40
- package/build/parser/stream/stream-parser.js +0 -225
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DataFields = void 0;
|
|
4
|
+
const parser_error_1 = require("../../error/parser.error");
|
|
4
5
|
const util_types_1 = require("../structs/util.types");
|
|
5
6
|
const ArrayProperty_1 = require("./property/generic/ArrayProperty");
|
|
6
7
|
const BoolProperty_1 = require("./property/generic/BoolProperty");
|
|
@@ -29,6 +30,7 @@ class DataFields {
|
|
|
29
30
|
const start = reader.getBufferPosition();
|
|
30
31
|
obj.properties = {};
|
|
31
32
|
if (length === 0) {
|
|
33
|
+
console.warn(`properties length for object ${obj.instanceName} was indicated as 0. Which is suspicious. Skipping object properties.`);
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
36
|
let propertyName = reader.readString();
|
|
@@ -45,18 +47,16 @@ class DataFields {
|
|
|
45
47
|
}
|
|
46
48
|
propertyName = reader.readString();
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
if (padding !== 0) {
|
|
50
|
-
}
|
|
50
|
+
reader.readInt32();
|
|
51
51
|
const remainingLen = length - (reader.getBufferPosition() - start);
|
|
52
52
|
obj.specialProperties = DataFields.ParseAdditionalSpecialProperties(reader, typePath, remainingLen);
|
|
53
53
|
const end = reader.getBufferPosition();
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
obj.trailingData = Array.from(reader.readBytes(
|
|
54
|
+
const remainingSize = length - (end - start);
|
|
55
|
+
if (remainingSize > 0) {
|
|
56
|
+
obj.trailingData = Array.from(reader.readBytes(remainingSize));
|
|
57
57
|
}
|
|
58
|
-
else if (
|
|
59
|
-
throw new
|
|
58
|
+
else if (remainingSize < 0) {
|
|
59
|
+
throw new parser_error_1.ParserError('ParserError', `Unexpected. Read more bytes than are indicated for entity ${obj.instanceName}. bytes left to read is ${remainingSize}`);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
static ParseAdditionalSpecialProperties(reader, typePath, remainingLen) {
|
|
@@ -290,7 +290,7 @@ class DataFields {
|
|
|
290
290
|
const readBytes = reader.getBufferPosition() - before - overhead;
|
|
291
291
|
if (readBytes !== binarySize) {
|
|
292
292
|
console.warn(`possibly corrupt. Read ${readBytes} for ${propertyType} ${propertyName}, but ${binarySize} were indicated.`);
|
|
293
|
-
throw new
|
|
293
|
+
throw new parser_error_1.ParserError('ParserError', `possibly corrupt. Read ${readBytes} bytes for ${propertyType} ${propertyName}, but ${binarySize} bytes were indicated.`);
|
|
294
294
|
}
|
|
295
295
|
return currentProperty;
|
|
296
296
|
}
|
|
@@ -14,7 +14,7 @@ export declare abstract class SaveObject implements SaveObjectHeader {
|
|
|
14
14
|
properties: PropertiesMap;
|
|
15
15
|
specialProperties: SpecialAnyProperty;
|
|
16
16
|
trailingData: number[];
|
|
17
|
-
|
|
17
|
+
objectVersion: number;
|
|
18
18
|
unknownType2: number;
|
|
19
19
|
constructor(typePath: string, rootObject: string, instanceName: string);
|
|
20
20
|
protected static ParseHeader(reader: BinaryReadable, obj: SaveObject): void;
|
|
@@ -24,7 +24,7 @@ class FloatProperty extends BasicProperty_1.BasicProperty {
|
|
|
24
24
|
FloatProperty.SerializeValue(writer, property.value);
|
|
25
25
|
}
|
|
26
26
|
static SerializeValue(writer, value) {
|
|
27
|
-
writer.
|
|
27
|
+
writer.writeFloat32(value);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
exports.FloatProperty = FloatProperty;
|
|
@@ -34,7 +34,10 @@ class SetProperty extends BasicProperty_1.BasicProperty {
|
|
|
34
34
|
property = new SetProperty(subtype, new Array(elementCount).fill(0).map(() => StrProperty_1.StrProperty.ReadValue(reader)), ueType, index);
|
|
35
35
|
break;
|
|
36
36
|
case "StructProperty":
|
|
37
|
-
if (propertyName === '
|
|
37
|
+
if (propertyName === 'mRemovalLocations') {
|
|
38
|
+
property = new SetProperty(subtype, new Array(elementCount).fill(0).map(() => util_types_1.vec3.ParseF(reader)), ueType, index);
|
|
39
|
+
}
|
|
40
|
+
if (propertyName === 'mDestroyedPickups' || propertyName === 'mLootedDropPods') {
|
|
38
41
|
property = new SetProperty(subtype, new Array(elementCount).fill(0).map(() => GUID_1.GUID.read(reader)), ueType, index);
|
|
39
42
|
}
|
|
40
43
|
else {
|
|
@@ -74,7 +77,7 @@ class SetProperty extends BasicProperty_1.BasicProperty {
|
|
|
74
77
|
console.warn('serializing mRemovalLocations, this is still under investigation.');
|
|
75
78
|
property.values.forEach(v => util_types_1.vec3.SerializeF(writer, v));
|
|
76
79
|
}
|
|
77
|
-
else if (property.name === 'mDestroyedPickups') {
|
|
80
|
+
else if (property.name === 'mDestroyedPickups' || property.name === 'mLootedDropPods') {
|
|
78
81
|
property.values.forEach(v => GUID_1.GUID.write(writer, v));
|
|
79
82
|
}
|
|
80
83
|
else {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SerializeFINLuaProcessorStateStorage = exports.ReadFINLuaProcessorStateStorage = exports.SerializeFINNetworkTrace = exports.ReadFINNetworkTrace = exports.SerializeDynamicStructData = exports.ParseDynamicStructData = exports.StructProperty = void 0;
|
|
4
|
+
const parser_error_1 = require("../../../../error/parser.error");
|
|
4
5
|
const util_types_1 = require("../../../structs/util.types");
|
|
5
6
|
const DataFields_1 = require("../../DataFields");
|
|
6
7
|
const ObjectReference_1 = require("../../values/ObjectReference");
|
|
@@ -34,7 +35,8 @@ class StructProperty extends BasicProperty_1.AbstractBaseProperty {
|
|
|
34
35
|
struct.value = StructProperty.ParseValue(reader, struct.subtype, size);
|
|
35
36
|
const readBytes = reader.getBufferPosition() - before;
|
|
36
37
|
if (readBytes !== size) {
|
|
37
|
-
if (size - readBytes === 4
|
|
38
|
+
if (size - readBytes === 4 || struct.subtype === 'ClientIdentityInfo') {
|
|
39
|
+
reader.skipBytes(size - readBytes);
|
|
38
40
|
}
|
|
39
41
|
else {
|
|
40
42
|
throw new Error(`possibly corrupt. Read ${readBytes} for StructProperty Content of ${struct.subtype}, but ${size} were indicated.`);
|
|
@@ -95,6 +97,7 @@ class StructProperty extends BasicProperty_1.AbstractBaseProperty {
|
|
|
95
97
|
value = { id, clientUnk1, clientUnk2, clientHashSize, someClientHash };
|
|
96
98
|
break;
|
|
97
99
|
case 'InventoryItem':
|
|
100
|
+
const before = reader.getBufferPosition();
|
|
98
101
|
value = {
|
|
99
102
|
unk1: reader.readInt32(),
|
|
100
103
|
itemName: reader.readString(),
|
|
@@ -112,6 +115,12 @@ class StructProperty extends BasicProperty_1.AbstractBaseProperty {
|
|
|
112
115
|
itemStateRaw: itemStateRaw
|
|
113
116
|
};
|
|
114
117
|
}
|
|
118
|
+
const bytesLeft = size - (reader.getBufferPosition() - before);
|
|
119
|
+
if (bytesLeft === 0 || (bytesLeft === 4 && reader.readInt32() === 0)) {
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
throw new parser_error_1.CorruptSaveError(`save may be corrupt. InventoryItem has weird format that was not seen so far and therefore not implemented. Could be that the save is ported from way before U8.`);
|
|
123
|
+
}
|
|
115
124
|
break;
|
|
116
125
|
case 'FluidBox':
|
|
117
126
|
value = {
|
|
@@ -187,8 +196,8 @@ class StructProperty extends BasicProperty_1.AbstractBaseProperty {
|
|
|
187
196
|
value = value;
|
|
188
197
|
writer.writeString(value.root);
|
|
189
198
|
writer.writeString(value.instanceName);
|
|
190
|
-
writer.
|
|
191
|
-
writer.
|
|
199
|
+
writer.writeFloat32(value.offset);
|
|
200
|
+
writer.writeFloat32(value.forward);
|
|
192
201
|
break;
|
|
193
202
|
case 'TimerHandle':
|
|
194
203
|
value = value;
|
|
@@ -218,10 +227,9 @@ class StructProperty extends BasicProperty_1.AbstractBaseProperty {
|
|
|
218
227
|
writer.writeBytesArray(value.itemState.itemStateRaw);
|
|
219
228
|
}
|
|
220
229
|
break;
|
|
221
|
-
break;
|
|
222
230
|
case 'FluidBox':
|
|
223
231
|
value = value;
|
|
224
|
-
writer.
|
|
232
|
+
writer.writeFloat32(value.value);
|
|
225
233
|
break;
|
|
226
234
|
case 'SlateBrush':
|
|
227
235
|
value = value;
|
|
@@ -9,7 +9,6 @@ export declare class Level {
|
|
|
9
9
|
name: string;
|
|
10
10
|
objects: (SaveEntity | SaveComponent)[];
|
|
11
11
|
collectables: ObjectReference[];
|
|
12
|
-
remainingStuffAfterHeaders: Uint8Array;
|
|
13
12
|
constructor(name: string);
|
|
14
13
|
static SerializeObjectHeaders(writer: ByteWriter, objects: (SaveEntity | SaveComponent)[]): void;
|
|
15
14
|
static WriteLevel(writer: ByteWriter, level: Level, buildVersion: number): void;
|
|
@@ -18,5 +17,5 @@ export declare class Level {
|
|
|
18
17
|
static ReadObjectContents(levelName: string, reader: BinaryReadable, objectsList: SaveObject[], buildVersion: number, onProgressCallback: (progress: number, msg?: string) => void): Promise<void>;
|
|
19
18
|
static ReadLevel(reader: SaveReader, levelName: string, buildVersion: number): Level;
|
|
20
19
|
static SerializeCollectablesList(writer: ByteWriter, collectables: ObjectReference[]): void;
|
|
21
|
-
static ReadCollectablesList(reader: BinaryReadable
|
|
20
|
+
static ReadCollectablesList(reader: BinaryReadable): ObjectReference[];
|
|
22
21
|
}
|
|
@@ -9,7 +9,6 @@ class Level {
|
|
|
9
9
|
this.name = name;
|
|
10
10
|
this.objects = [];
|
|
11
11
|
this.collectables = [];
|
|
12
|
-
this.remainingStuffAfterHeaders = new Uint8Array();
|
|
13
12
|
}
|
|
14
13
|
static SerializeObjectHeaders(writer, objects) {
|
|
15
14
|
writer.writeInt32(objects.length);
|
|
@@ -30,12 +29,11 @@ class Level {
|
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
static WriteLevel(writer, level, buildVersion) {
|
|
33
|
-
const
|
|
32
|
+
const lenIndicatorHeaderAndDestroyedEntitiesSize = writer.getBufferPosition();
|
|
34
33
|
writer.writeInt32(0);
|
|
35
34
|
writer.writeInt32(0);
|
|
36
35
|
Level.SerializeObjectHeaders(writer, level.objects);
|
|
37
|
-
|
|
38
|
-
writer.writeBinarySizeFromPosition(lenIndicatorHeaderAndCollectableSize, lenIndicatorHeaderAndCollectableSize + 8);
|
|
36
|
+
writer.writeBinarySizeFromPosition(lenIndicatorHeaderAndDestroyedEntitiesSize, lenIndicatorHeaderAndDestroyedEntitiesSize + 8);
|
|
39
37
|
Level.SerializeObjectContents(writer, level.objects, buildVersion, level.name);
|
|
40
38
|
Level.SerializeCollectablesList(writer, level.collectables);
|
|
41
39
|
}
|
|
@@ -45,7 +43,7 @@ class Level {
|
|
|
45
43
|
writer.writeInt32(0);
|
|
46
44
|
writer.writeInt32(objects.length);
|
|
47
45
|
for (const obj of objects) {
|
|
48
|
-
writer.writeInt32(obj.
|
|
46
|
+
writer.writeInt32(obj.objectVersion);
|
|
49
47
|
writer.writeInt32(obj.unknownType2);
|
|
50
48
|
const lenReplacementPosition = writer.getBufferPosition();
|
|
51
49
|
writer.writeInt32(0);
|
|
@@ -93,7 +91,7 @@ class Level {
|
|
|
93
91
|
onProgressCallback(reader.getBufferProgress(), `read object count [${(i + 1)}/${(countEntities + 1)}] in level ${levelName}`);
|
|
94
92
|
}
|
|
95
93
|
const obj = objectsList[i];
|
|
96
|
-
obj.
|
|
94
|
+
obj.objectVersion = reader.readInt32();
|
|
97
95
|
obj.unknownType2 = reader.readInt32();
|
|
98
96
|
const binarySize = reader.readInt32();
|
|
99
97
|
const before = reader.getBufferPosition();
|
|
@@ -117,7 +115,7 @@ class Level {
|
|
|
117
115
|
Level.ReadObjectHeaders(reader, level.objects, reader.onProgressCallback);
|
|
118
116
|
let remainingSize = headersBinLen - (reader.getBufferPosition() - posBeforeHeaders);
|
|
119
117
|
if (remainingSize > 0) {
|
|
120
|
-
const doubledCollectablesIgnored = Level.ReadCollectablesList(reader
|
|
118
|
+
const doubledCollectablesIgnored = Level.ReadCollectablesList(reader);
|
|
121
119
|
}
|
|
122
120
|
else {
|
|
123
121
|
}
|
|
@@ -135,7 +133,7 @@ class Level {
|
|
|
135
133
|
console.warn('save seems corrupt.', this.name);
|
|
136
134
|
}
|
|
137
135
|
reader.onProgressCallback(reader.getBufferProgress());
|
|
138
|
-
level.collectables = Level.ReadCollectablesList(reader
|
|
136
|
+
level.collectables = Level.ReadCollectablesList(reader);
|
|
139
137
|
return level;
|
|
140
138
|
}
|
|
141
139
|
static SerializeCollectablesList(writer, collectables) {
|
|
@@ -144,14 +142,11 @@ class Level {
|
|
|
144
142
|
ObjectReference_1.ObjectReference.write(writer, collectable);
|
|
145
143
|
}
|
|
146
144
|
}
|
|
147
|
-
static ReadCollectablesList(reader
|
|
145
|
+
static ReadCollectablesList(reader) {
|
|
148
146
|
const collected = [];
|
|
149
|
-
let
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const collectable = ObjectReference_1.ObjectReference.read(reader);
|
|
153
|
-
collected.push(collectable);
|
|
154
|
-
}
|
|
147
|
+
let count = reader.readInt32();
|
|
148
|
+
for (let i = 0; i < count; i++) {
|
|
149
|
+
collected.push(ObjectReference_1.ObjectReference.read(reader));
|
|
155
150
|
}
|
|
156
151
|
return collected;
|
|
157
152
|
}
|
|
@@ -167,11 +167,15 @@ class SaveReader extends byte_reader_class_1.ByteReader {
|
|
|
167
167
|
if (!this.header) {
|
|
168
168
|
throw new parser_error_1.ParserError('ParserError', 'Header must be set before objects can be read.');
|
|
169
169
|
}
|
|
170
|
-
|
|
170
|
+
const roughSaveVersion = SaveReader.getRoughSaveVersion(this.header.saveVersion, this.header.saveHeaderType);
|
|
171
|
+
if (roughSaveVersion === '<U6') {
|
|
171
172
|
throw new parser_error_1.UnsupportedVersionError('Game Version < U6 is not supported.');
|
|
172
173
|
}
|
|
173
|
-
if (
|
|
174
|
-
throw new parser_error_1.UnsupportedVersionError('Game Version
|
|
174
|
+
else if (roughSaveVersion === 'U6/U7') {
|
|
175
|
+
throw new parser_error_1.UnsupportedVersionError('Game Version U6/U7 is not supported in this package version. Consider downgrading to the latest package version supporting it, which is 0.0.34');
|
|
176
|
+
}
|
|
177
|
+
else if (roughSaveVersion === 'U8') {
|
|
178
|
+
throw new parser_error_1.UnsupportedVersionError('Game Version U8 is not supported in this package version. Consider downgrading to the latest package version supporting it, which is 0.3.7');
|
|
175
179
|
}
|
|
176
180
|
const levels = [];
|
|
177
181
|
const levelCount = this.readInt32();
|
|
@@ -184,7 +188,7 @@ class SaveReader extends byte_reader_class_1.ByteReader {
|
|
|
184
188
|
levels.push(level_class_1.Level.ReadLevel(this, levelSingleName, this.header.buildVersion));
|
|
185
189
|
}
|
|
186
190
|
levels.push(level_class_1.Level.ReadLevel(this, this.header.mapName, this.header.buildVersion));
|
|
187
|
-
const trailingStuffToIgnore = level_class_1.Level.ReadCollectablesList(this
|
|
191
|
+
const trailingStuffToIgnore = level_class_1.Level.ReadCollectablesList(this);
|
|
188
192
|
this.onProgressCallback(this.getBufferProgress(), 'finished parsing.');
|
|
189
193
|
return levels;
|
|
190
194
|
}
|
|
@@ -29,28 +29,3 @@ export interface SatisfactorySaveHeader {
|
|
|
29
29
|
creativeModeEnabled?: boolean;
|
|
30
30
|
}
|
|
31
31
|
export type RoughSaveVersion = '<U6' | 'U6/U7' | 'U8' | 'U1.0+';
|
|
32
|
-
export type ResourceNodeEntry = {
|
|
33
|
-
purity: string;
|
|
34
|
-
pathName: string;
|
|
35
|
-
position: {
|
|
36
|
-
x: number;
|
|
37
|
-
y: number;
|
|
38
|
-
z: number;
|
|
39
|
-
};
|
|
40
|
-
type: string;
|
|
41
|
-
};
|
|
42
|
-
export type CollectibleEntry = {
|
|
43
|
-
pathName: string;
|
|
44
|
-
position: {
|
|
45
|
-
x: number;
|
|
46
|
-
y: number;
|
|
47
|
-
z: number;
|
|
48
|
-
};
|
|
49
|
-
type: string;
|
|
50
|
-
};
|
|
51
|
-
export type StaticData = {
|
|
52
|
-
collectibles: CollectibleEntry[];
|
|
53
|
-
artifacts: CollectibleEntry[];
|
|
54
|
-
slugs: CollectibleEntry[];
|
|
55
|
-
resourceNodes: ResourceNodeEntry[];
|
|
56
|
-
};
|
|
@@ -4,10 +4,10 @@ exports.Transform = exports.vec2 = exports.vec3 = exports.vec4 = exports.col4 =
|
|
|
4
4
|
var col4;
|
|
5
5
|
(function (col4) {
|
|
6
6
|
col4.SerializeRGBA = (writer, value) => {
|
|
7
|
-
writer.
|
|
8
|
-
writer.
|
|
9
|
-
writer.
|
|
10
|
-
writer.
|
|
7
|
+
writer.writeFloat32(value.r);
|
|
8
|
+
writer.writeFloat32(value.g);
|
|
9
|
+
writer.writeFloat32(value.b);
|
|
10
|
+
writer.writeFloat32(value.a);
|
|
11
11
|
};
|
|
12
12
|
col4.ParseRGBA = (reader) => {
|
|
13
13
|
return {
|
|
@@ -52,7 +52,7 @@ var vec4;
|
|
|
52
52
|
};
|
|
53
53
|
vec4.SerializeF = (writer, vec) => {
|
|
54
54
|
vec3.SerializeF(writer, vec);
|
|
55
|
-
writer.
|
|
55
|
+
writer.writeFloat32(vec.w);
|
|
56
56
|
};
|
|
57
57
|
})(vec4 || (exports.vec4 = vec4 = {}));
|
|
58
58
|
var vec3;
|
|
@@ -87,7 +87,7 @@ var vec3;
|
|
|
87
87
|
};
|
|
88
88
|
vec3.SerializeF = (writer, vec) => {
|
|
89
89
|
vec2.SerializeF(writer, vec);
|
|
90
|
-
writer.
|
|
90
|
+
writer.writeFloat32(vec.z);
|
|
91
91
|
};
|
|
92
92
|
vec3.sub = (other, vec) => ({ x: other.x - vec.x, y: other.y - vec.y, z: other.z - vec.z });
|
|
93
93
|
vec3.add = (vec, other) => ({ x: vec.x + other.x, y: vec.y + other.y, z: vec.z + other.z });
|
|
@@ -114,8 +114,8 @@ var vec2;
|
|
|
114
114
|
};
|
|
115
115
|
};
|
|
116
116
|
vec2.SerializeF = (writer, vec) => {
|
|
117
|
-
writer.
|
|
118
|
-
writer.
|
|
117
|
+
writer.writeFloat32(vec.x);
|
|
118
|
+
writer.writeFloat32(vec.y);
|
|
119
119
|
};
|
|
120
120
|
})(vec2 || (exports.vec2 = vec2 = {}));
|
|
121
121
|
var Transform;
|
|
@@ -3,8 +3,10 @@ var _a;
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.ReadableStreamParser = void 0;
|
|
5
5
|
const web_1 = require("stream/web");
|
|
6
|
+
const parser_error_1 = require("../../error/parser.error");
|
|
6
7
|
const SaveComponent_1 = require("../../satisfactory/objects/SaveComponent");
|
|
7
8
|
const SaveEntity_1 = require("../../satisfactory/objects/SaveEntity");
|
|
9
|
+
const ObjectReference_1 = require("../../satisfactory/objects/values/ObjectReference");
|
|
8
10
|
const level_class_1 = require("../../satisfactory/save/level.class");
|
|
9
11
|
const satisfactory_save_1 = require("../../satisfactory/save/satisfactory-save");
|
|
10
12
|
const save_reader_1 = require("../../satisfactory/save/save-reader");
|
|
@@ -57,7 +59,7 @@ class ReadableStreamParser {
|
|
|
57
59
|
}
|
|
58
60
|
await write(`${j > 0 ? ', ' : ''}{"name": "${levelName}", "objects": [`, false);
|
|
59
61
|
const headersBinLen = reader.readInt32();
|
|
60
|
-
|
|
62
|
+
reader.readInt32();
|
|
61
63
|
const posBeforeHeaders = reader.getBufferPosition();
|
|
62
64
|
const afterAllHeaders = posBeforeHeaders + headersBinLen;
|
|
63
65
|
let countObjectHeaders = reader.readInt32();
|
|
@@ -152,6 +154,16 @@ ReadableStreamParser.CreateReadableStreamFromSaveToJson = (name, bytes, onDecomp
|
|
|
152
154
|
const reader = new save_reader_1.SaveReader(bytes.buffer, onProgress);
|
|
153
155
|
const header = reader.readHeader();
|
|
154
156
|
const save = new satisfactory_save_1.SatisfactorySave(name, header);
|
|
157
|
+
const roughSaveVersion = save_reader_1.SaveReader.getRoughSaveVersion(header.saveVersion, header.saveHeaderType);
|
|
158
|
+
if (roughSaveVersion === '<U6') {
|
|
159
|
+
throw new parser_error_1.UnsupportedVersionError('Game Version < U6 is not supported.');
|
|
160
|
+
}
|
|
161
|
+
else if (roughSaveVersion === 'U6/U7') {
|
|
162
|
+
throw new parser_error_1.UnsupportedVersionError('Game Version U6/U7 is not supported in this package version. Consider downgrading to the latest package version supporting it, which is 0.0.34');
|
|
163
|
+
}
|
|
164
|
+
else if (roughSaveVersion === 'U8') {
|
|
165
|
+
throw new parser_error_1.UnsupportedVersionError('Game Version U8 is not supported in this package version. Consider downgrading to the latest package version supporting it, which is 0.3.7');
|
|
166
|
+
}
|
|
155
167
|
const inflateResult = reader.inflateChunks();
|
|
156
168
|
onDecompressedSaveBody(reader.getBuffer());
|
|
157
169
|
const gridHash = reader.readSaveBodyHash();
|
|
@@ -166,6 +178,15 @@ ReadableStreamParser.CreateReadableStreamFromSaveToJson = (name, bytes, onDecomp
|
|
|
166
178
|
ReadableStreamParser.WriteHeaderAndGrids = async (write, compressionInfo, header, grids, gridHash) => {
|
|
167
179
|
return write(`{"header": ${JSON.stringify(header)}, "compressionInfo": ${JSON.stringify(compressionInfo)}, "gridHash": ${JSON.stringify(gridHash)}, "grids": ${JSON.stringify(grids)}, "levels": [`, false);
|
|
168
180
|
};
|
|
181
|
+
ReadableStreamParser.ReadDestroyedEntityReferences = (reader) => {
|
|
182
|
+
const destroyedEntitiesCount = reader.readInt32();
|
|
183
|
+
const destroyedEntities = [];
|
|
184
|
+
for (let i = 0; i < destroyedEntitiesCount; i++) {
|
|
185
|
+
const destroyed = ObjectReference_1.ObjectReference.read(reader);
|
|
186
|
+
destroyedEntities.push(destroyed);
|
|
187
|
+
}
|
|
188
|
+
return destroyedEntities;
|
|
189
|
+
};
|
|
169
190
|
ReadableStreamParser.ReadNObjectHeaders = (reader, count) => {
|
|
170
191
|
let objects = [];
|
|
171
192
|
let objectsRead = 0;
|
|
@@ -182,7 +203,7 @@ ReadableStreamParser.ReadNObjectHeaders = (reader, count) => {
|
|
|
182
203
|
SaveComponent_1.SaveComponent.ParseHeader(reader, obj);
|
|
183
204
|
break;
|
|
184
205
|
default:
|
|
185
|
-
throw new
|
|
206
|
+
throw new parser_error_1.CorruptSaveError('Unknown object type' + objectType);
|
|
186
207
|
}
|
|
187
208
|
objects.push(obj);
|
|
188
209
|
}
|
|
@@ -190,7 +211,7 @@ ReadableStreamParser.ReadNObjectHeaders = (reader, count) => {
|
|
|
190
211
|
};
|
|
191
212
|
ReadableStreamParser.ReadNObjects = (reader, count, objects, buildVersion) => {
|
|
192
213
|
for (let i = 0; i < count; i++) {
|
|
193
|
-
objects[i].
|
|
214
|
+
objects[i].objectVersion = reader.readInt32();
|
|
194
215
|
objects[i].unknownType2 = reader.readInt32();
|
|
195
216
|
const binarySize = reader.readInt32();
|
|
196
217
|
const before = reader.getBufferPosition();
|
|
@@ -200,5 +221,9 @@ ReadableStreamParser.ReadNObjects = (reader, count, objects, buildVersion) => {
|
|
|
200
221
|
else if ((0, SaveComponent_1.isSaveComponent)(objects[i])) {
|
|
201
222
|
SaveComponent_1.SaveComponent.ParseData(objects[i], binarySize, reader, buildVersion, objects[i].typePath);
|
|
202
223
|
}
|
|
224
|
+
const after = reader.getBufferPosition();
|
|
225
|
+
if (after - before !== binarySize) {
|
|
226
|
+
throw new parser_error_1.CorruptSaveError(`Could not read entity ${objects[i].instanceName}, as ${after - before} bytes were read, but ${binarySize} bytes were indicated.`);
|
|
227
|
+
}
|
|
203
228
|
}
|
|
204
229
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etothepii/satisfactory-file-parser",
|
|
3
3
|
"author": "etothepii",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.14",
|
|
5
5
|
"description": "A file parser for satisfactory files. Includes save files and blueprint files.",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
7
7
|
"main": "./build/index.js",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { BinaryReadable } from "../../byte/binary-readable.interface";
|
|
2
|
-
import { ByteWriter } from "../../byte/byte-writer.class";
|
|
3
|
-
export type ObjectReference = {
|
|
4
|
-
levelName: string;
|
|
5
|
-
pathName: string;
|
|
6
|
-
};
|
|
7
|
-
export declare namespace ObjectReference {
|
|
8
|
-
const read: (reader: BinaryReadable) => ObjectReference;
|
|
9
|
-
const write: (writer: ByteWriter, ref: ObjectReference) => void;
|
|
10
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ObjectReference = void 0;
|
|
4
|
-
var ObjectReference;
|
|
5
|
-
(function (ObjectReference) {
|
|
6
|
-
ObjectReference.read = (reader) => {
|
|
7
|
-
return {
|
|
8
|
-
levelName: reader.readString(),
|
|
9
|
-
pathName: reader.readString()
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
ObjectReference.write = (writer, ref) => {
|
|
13
|
-
writer.writeString(ref.levelName);
|
|
14
|
-
writer.writeString(ref.pathName);
|
|
15
|
-
};
|
|
16
|
-
})(ObjectReference = exports.ObjectReference || (exports.ObjectReference = {}));
|
|
17
|
-
;
|