@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.
Files changed (56) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +43 -22
  3. package/build/parser/byte/binary-readable.interface.d.ts +0 -3
  4. package/build/parser/byte/binary-writable.interface.d.ts +20 -0
  5. package/build/parser/byte/binary-writable.interface.js +2 -0
  6. package/build/parser/byte/byte-reader.class.d.ts +0 -3
  7. package/build/parser/byte/byte-reader.class.js +0 -8
  8. package/build/parser/byte/byte-writer.class.d.ts +6 -3
  9. package/build/parser/byte/byte-writer.class.js +3 -1
  10. package/build/parser/satisfactory/blueprint/blueprint-reader.js +10 -10
  11. package/build/parser/satisfactory/edit/edit-constants.d.ts +157 -3
  12. package/build/parser/satisfactory/edit/edit-constants.js +237 -161
  13. package/build/parser/satisfactory/objects/DataFields.js +9 -9
  14. package/build/parser/satisfactory/objects/SaveObject.d.ts +1 -1
  15. package/build/parser/satisfactory/objects/SaveObject.js +1 -1
  16. package/build/parser/satisfactory/objects/property/generic/FloatProperty.js +1 -1
  17. package/build/parser/satisfactory/objects/property/generic/SetProperty.js +5 -2
  18. package/build/parser/satisfactory/objects/property/generic/StructProperty.js +13 -5
  19. package/build/parser/satisfactory/save/level.class.d.ts +1 -2
  20. package/build/parser/satisfactory/save/level.class.js +10 -15
  21. package/build/parser/satisfactory/save/save-reader.js +8 -4
  22. package/build/parser/satisfactory/save/save.types.d.ts +0 -25
  23. package/build/parser/satisfactory/structs/util.types.js +8 -8
  24. package/build/parser/stream/reworked/readable-stream-parser.d.ts +1 -0
  25. package/build/parser/stream/reworked/readable-stream-parser.js +28 -3
  26. package/package.json +1 -1
  27. package/build/parser/satisfactory/objects/ObjectReference.d.ts +0 -10
  28. package/build/parser/satisfactory/objects/ObjectReference.js +0 -17
  29. package/build/parser/satisfactory/objects/Property.d.ts +0 -272
  30. package/build/parser/satisfactory/objects/Property.js +0 -1177
  31. package/build/parser/satisfactory/objects/ue/FMD5Hash.d.ts +0 -7
  32. package/build/parser/satisfactory/objects/ue/FMD5Hash.js +0 -19
  33. package/build/parser/satisfactory/objects/ue/GUID.d.ts +0 -6
  34. package/build/parser/satisfactory/objects/ue/GUID.js +0 -21
  35. package/build/parser/satisfactory/save/asynchronous-level.class.d.ts +0 -9
  36. package/build/parser/satisfactory/save/asynchronous-level.class.js +0 -66
  37. package/build/parser/stream/byte-stream-reader.class.d.ts +0 -57
  38. package/build/parser/stream/byte-stream-reader.class.js +0 -241
  39. package/build/parser/stream/json-stream-state-writer.d.ts +0 -12
  40. package/build/parser/stream/json-stream-state-writer.js +0 -18
  41. package/build/parser/stream/json-stream-writable.d.ts +0 -20
  42. package/build/parser/stream/json-stream-writable.js +0 -83
  43. package/build/parser/stream/json-stream-writer.d.ts +0 -22
  44. package/build/parser/stream/json-stream-writer.js +0 -127
  45. package/build/parser/stream/reworked/stream-parser.d.ts +0 -6
  46. package/build/parser/stream/reworked/stream-parser.js +0 -31
  47. package/build/parser/stream/save-stream-json-stringifier.d.ts +0 -6
  48. package/build/parser/stream/save-stream-json-stringifier.js +0 -35
  49. package/build/parser/stream/save-stream-reader.class.d.ts +0 -15
  50. package/build/parser/stream/save-stream-reader.class.js +0 -121
  51. package/build/parser/stream/save-stream-writer.class.d.ts +0 -25
  52. package/build/parser/stream/save-stream-writer.class.js +0 -119
  53. package/build/parser/stream/stream-level.class.d.ts +0 -12
  54. package/build/parser/stream/stream-level.class.js +0 -103
  55. package/build/parser/stream/stream-parser.d.ts +0 -40
  56. 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
- let padding = reader.readInt32();
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 newWayOfCalculatingReminingSize = length - (end - start);
55
- if (newWayOfCalculatingReminingSize > 0) {
56
- obj.trailingData = Array.from(reader.readBytes(newWayOfCalculatingReminingSize));
54
+ const remainingSize = length - (end - start);
55
+ if (remainingSize > 0) {
56
+ obj.trailingData = Array.from(reader.readBytes(remainingSize));
57
57
  }
58
- else if (newWayOfCalculatingReminingSize < 0) {
59
- throw new Error(`Unexpected. Read more bytes than are indicated for this etity. bytes left to read is ${newWayOfCalculatingReminingSize}`);
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 Error(`possibly corrupt. Read ${readBytes} for ${propertyType} ${propertyName}, but ${binarySize} were indicated.`);
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
- saveOrBlueprintIndicator: number;
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;
@@ -10,7 +10,7 @@ class SaveObject {
10
10
  this.properties = {};
11
11
  this.specialProperties = {};
12
12
  this.trailingData = [];
13
- this.saveOrBlueprintIndicator = 0;
13
+ this.objectVersion = 0;
14
14
  this.unknownType2 = 0;
15
15
  }
16
16
  static ParseHeader(reader, obj) {
@@ -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.writeFloat(value);
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 === 'mDestroyedPickups') {
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 && reader.readInt32() === 0) {
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.writeFloat(value.offset);
191
- writer.writeFloat(value.forward);
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.writeFloat(value.value);
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, printSmthWhenItsCollectables?: string | undefined): ObjectReference[];
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 lenIndicatorHeaderAndCollectableSize = writer.getBufferPosition();
32
+ const lenIndicatorHeaderAndDestroyedEntitiesSize = writer.getBufferPosition();
34
33
  writer.writeInt32(0);
35
34
  writer.writeInt32(0);
36
35
  Level.SerializeObjectHeaders(writer, level.objects);
37
- Level.SerializeCollectablesList(writer, level.collectables);
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.saveOrBlueprintIndicator);
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.saveOrBlueprintIndicator = reader.readInt32();
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, 'collectables at the header section! ' + levelName);
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, 'collectables 2! ' + levelName);
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, printSmthWhenItsCollectables) {
145
+ static ReadCollectablesList(reader) {
148
146
  const collected = [];
149
- let countSmthing = reader.readInt32();
150
- if (countSmthing > 0) {
151
- for (let i = 0; i < countSmthing; i++) {
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
- if (this.header.saveVersion < 29) {
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 (this.header.saveHeaderType < 13) {
174
- 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.0.34');
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, 'collectables 6!');
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.writeFloat(value.r);
8
- writer.writeFloat(value.g);
9
- writer.writeFloat(value.b);
10
- writer.writeFloat(value.a);
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.writeFloat(vec.w);
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.writeFloat(vec.z);
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.writeFloat(vec.x);
118
- writer.writeFloat(vec.y);
117
+ writer.writeFloat32(vec.x);
118
+ writer.writeFloat32(vec.y);
119
119
  };
120
120
  })(vec2 || (exports.vec2 = vec2 = {}));
121
121
  var Transform;
@@ -7,6 +7,7 @@ export declare class ReadableStreamParser {
7
7
  };
8
8
  private static WriteHeaderAndGrids;
9
9
  private static WriteLevels;
10
+ private static ReadDestroyedEntityReferences;
10
11
  private static ReadNObjectHeaders;
11
12
  private static ReadNObjects;
12
13
  }
@@ -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
- const unk = reader.readInt32();
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 Error('Unknown object type' + objectType);
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].saveOrBlueprintIndicator = reader.readInt32();
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.12",
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
- ;