@etothepii/satisfactory-file-parser 0.0.30 → 0.0.31

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 (47) hide show
  1. package/build/index.d.ts +19 -0
  2. package/build/index.js +65 -0
  3. package/build/parser/byte/alignment.enum.d.ts +4 -0
  4. package/build/parser/byte/alignment.enum.js +18 -0
  5. package/build/parser/byte/byte-reader.class.d.ts +34 -0
  6. package/build/parser/byte/byte-reader.class.js +131 -0
  7. package/build/parser/byte/byte-writer.class.d.ts +33 -0
  8. package/build/parser/byte/byte-writer.class.js +149 -0
  9. package/build/parser/error/parser.error.d.ts +12 -0
  10. package/build/parser/error/parser.error.js +38 -0
  11. package/build/parser/file.types.d.ts +9 -0
  12. package/build/parser/file.types.js +12 -0
  13. package/build/parser/parser.d.ts +16 -0
  14. package/build/parser/parser.js +98 -0
  15. package/build/parser/satisfactory/blueprint/blueprint-reader.d.ts +18 -0
  16. package/build/parser/satisfactory/blueprint/blueprint-reader.js +134 -0
  17. package/build/parser/satisfactory/blueprint/blueprint-writer.d.ts +15 -0
  18. package/build/parser/satisfactory/blueprint/blueprint-writer.js +73 -0
  19. package/build/parser/satisfactory/blueprint/blueprint.types.d.ts +20 -0
  20. package/build/parser/satisfactory/blueprint/blueprint.types.js +12 -0
  21. package/build/parser/satisfactory/objects/DataFields.d.ts +13 -0
  22. package/build/parser/satisfactory/objects/DataFields.js +234 -0
  23. package/build/parser/satisfactory/objects/ObjectReference.d.ts +9 -0
  24. package/build/parser/satisfactory/objects/ObjectReference.js +27 -0
  25. package/build/parser/satisfactory/objects/Property.d.ts +270 -0
  26. package/build/parser/satisfactory/objects/Property.js +1011 -0
  27. package/build/parser/satisfactory/objects/SaveComponent.d.ts +16 -0
  28. package/build/parser/satisfactory/objects/SaveComponent.js +41 -0
  29. package/build/parser/satisfactory/objects/SaveEntity.d.ts +25 -0
  30. package/build/parser/satisfactory/objects/SaveEntity.js +80 -0
  31. package/build/parser/satisfactory/objects/SaveObject.d.ts +14 -0
  32. package/build/parser/satisfactory/objects/SaveObject.js +39 -0
  33. package/build/parser/satisfactory/save/level.class.d.ts +21 -0
  34. package/build/parser/satisfactory/save/level.class.js +148 -0
  35. package/build/parser/satisfactory/save/satisfactory-save.d.ts +11 -0
  36. package/build/parser/satisfactory/save/satisfactory-save.js +21 -0
  37. package/build/parser/satisfactory/save/save-reader.d.ts +44 -0
  38. package/build/parser/satisfactory/save/save-reader.js +243 -0
  39. package/build/parser/satisfactory/save/save-writer.d.ts +12 -0
  40. package/build/parser/satisfactory/save/save-writer.js +122 -0
  41. package/build/parser/satisfactory/save/save.types.d.ts +49 -0
  42. package/build/parser/satisfactory/save/save.types.js +12 -0
  43. package/build/parser/satisfactory/structs/util.types.d.ts +40 -0
  44. package/build/parser/satisfactory/structs/util.types.js +105 -0
  45. package/package.json +3 -3
  46. package/dist/index.d.ts +0 -610
  47. package/dist/index.js +0 -1
@@ -0,0 +1,243 @@
1
+ var __importDefault = (this && this.__importDefault) || function (mod) {
2
+ return (mod && mod.__esModule) ? mod : { "default": mod };
3
+ };
4
+ (function (factory) {
5
+ if (typeof module === "object" && typeof module.exports === "object") {
6
+ var v = factory(require, exports);
7
+ if (v !== undefined) module.exports = v;
8
+ }
9
+ else if (typeof define === "function" && define.amd) {
10
+ define(["require", "exports", "pako", "../../byte/alignment.enum", "../../byte/byte-reader.class", "../../error/parser.error", "../objects/SaveComponent", "../objects/SaveEntity", "./level.class"], factory);
11
+ }
12
+ })(function (require, exports) {
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.Conveyor = exports.SaveReader = exports.projectionFilterApplies = void 0;
16
+ const pako_1 = __importDefault(require("pako"));
17
+ const alignment_enum_1 = require("../../byte/alignment.enum");
18
+ const byte_reader_class_1 = require("../../byte/byte-reader.class");
19
+ const parser_error_1 = require("../../error/parser.error");
20
+ const SaveComponent_1 = require("../objects/SaveComponent");
21
+ const SaveEntity_1 = require("../objects/SaveEntity");
22
+ const level_class_1 = require("./level.class");
23
+ const projectionFilterApplies = (config, object) => {
24
+ let cond1 = false;
25
+ if ((0, SaveEntity_1.isSaveEntity)(object) || (config.includeComponents && (0, SaveComponent_1.isSaveComponent)(object))) {
26
+ cond1 = true;
27
+ }
28
+ let cond2 = true;
29
+ if ((0, SaveEntity_1.isSaveEntity)(object)) {
30
+ cond2 = false;
31
+ if (config.entityPathFilter.behavior === 'whitelist') {
32
+ cond2 = config.entityPathFilter.list.find(en => object.typePath.startsWith(en)) !== undefined;
33
+ }
34
+ else if (config.entityPathFilter.behavior === 'blacklist') {
35
+ cond2 = config.entityPathFilter.list.find(en => object.typePath.startsWith(en)) === undefined;
36
+ }
37
+ }
38
+ return cond1 && cond2;
39
+ };
40
+ exports.projectionFilterApplies = projectionFilterApplies;
41
+ class SaveReader extends byte_reader_class_1.ByteReader {
42
+ constructor(fileBuffer, onProgressCallback = () => { }) {
43
+ super(fileBuffer, alignment_enum_1.Alignment.LITTLE_ENDIAN);
44
+ this.onProgressCallback = onProgressCallback;
45
+ this.levels = [];
46
+ this.trailingCollectedObjects = [];
47
+ this.compressionInfo = {
48
+ packageFileTag: 0,
49
+ maxChunkContentSize: 0,
50
+ chunkHeaderSize: 48
51
+ };
52
+ }
53
+ readHeader() {
54
+ this.header = {
55
+ saveHeaderType: 0,
56
+ saveVersion: 0,
57
+ buildVersion: 0,
58
+ mapName: "DEFAULT",
59
+ mapOptions: "",
60
+ sessionName: "",
61
+ playDurationSeconds: 0,
62
+ saveDateTime: "0",
63
+ sessionVisibility: 0
64
+ };
65
+ this.header.saveHeaderType = this.readInt32();
66
+ this.header.saveVersion = this.readInt32();
67
+ this.header.buildVersion = this.readInt32();
68
+ this.header.mapName = this.readString();
69
+ this.header.mapOptions = this.readString();
70
+ this.header.sessionName = this.readString();
71
+ this.header.playDurationSeconds = this.readInt32();
72
+ const rawSaveDateTimeInTicks = this.readLong();
73
+ const unixMilliseconds = (rawSaveDateTimeInTicks - SaveReader.EPOCH_TICKS) / 10000n;
74
+ this.header.saveDateTime = unixMilliseconds.toString();
75
+ this.header.sessionVisibility = this.readByte();
76
+ if (this.header.saveHeaderType >= 7) {
77
+ this.header.fEditorObjectVersion = this.readInt32();
78
+ }
79
+ if (this.header.saveHeaderType >= 8) {
80
+ this.header.rawModMetadataString = this.readString();
81
+ try {
82
+ this.header.modMetadata = JSON.parse(this.header.rawModMetadataString);
83
+ }
84
+ catch (error) {
85
+ }
86
+ this.header.isModdedSave = this.readInt32();
87
+ }
88
+ if (this.header.saveHeaderType >= 10) {
89
+ this.header.saveIdentifier = this.readString();
90
+ }
91
+ if (this.header.saveVersion >= 21) {
92
+ }
93
+ else {
94
+ throw new parser_error_1.UnsupportedVersionError("The save version is too old to support encoding currently. Save in newer game version.");
95
+ }
96
+ return this.header;
97
+ }
98
+ inflateChunks() {
99
+ this.fileBuffer = this.fileBuffer.slice(this.currentByte);
100
+ this.handledByte = 0;
101
+ this.currentByte = 0;
102
+ this.maxByte = this.fileBuffer.byteLength;
103
+ let currentChunks = [];
104
+ let totalUncompressedBodySize = 0;
105
+ while (this.handledByte < this.maxByte) {
106
+ let chunkHeader = new DataView(this.fileBuffer.slice(0, this.compressionInfo.chunkHeaderSize));
107
+ this.currentByte = this.compressionInfo.chunkHeaderSize;
108
+ this.handledByte += this.compressionInfo.chunkHeaderSize;
109
+ if (this.compressionInfo.packageFileTag <= 0) {
110
+ this.compressionInfo.packageFileTag = chunkHeader.getInt32(0, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
111
+ }
112
+ if (this.compressionInfo.maxChunkContentSize <= 0) {
113
+ this.compressionInfo.maxChunkContentSize = chunkHeader.getInt32(8, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
114
+ }
115
+ const chunkCompressedLength = chunkHeader.getInt32(32, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
116
+ const chunkUncompressedLength = chunkHeader.getInt32(40, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
117
+ totalUncompressedBodySize += chunkUncompressedLength;
118
+ const currentChunkSize = chunkCompressedLength;
119
+ let currentChunk = this.fileBuffer.slice(this.currentByte, this.currentByte + currentChunkSize);
120
+ this.handledByte += currentChunkSize;
121
+ this.currentByte += currentChunkSize;
122
+ this.fileBuffer = this.fileBuffer.slice(this.currentByte);
123
+ this.currentByte = 0;
124
+ try {
125
+ let currentInflatedChunk = null;
126
+ currentInflatedChunk = pako_1.default.inflate(currentChunk);
127
+ currentChunks.push(currentInflatedChunk);
128
+ }
129
+ catch (err) {
130
+ throw new parser_error_1.CompressionLibraryError("Failed to inflate compressed save data. " + err);
131
+ }
132
+ }
133
+ let newChunkLength = currentChunks.map(cc => cc.length).reduce((prev, cur) => prev + cur);
134
+ const bigWholeChunk = new Uint8Array(newChunkLength);
135
+ let currentLength = 0;
136
+ for (let i = 0; i < currentChunks.length; i++) {
137
+ bigWholeChunk.set(currentChunks[i], currentLength);
138
+ currentLength += currentChunks[i].length;
139
+ }
140
+ this.currentByte = 0;
141
+ this.maxByte = bigWholeChunk.buffer.byteLength;
142
+ this.bufferView = new DataView(bigWholeChunk.buffer);
143
+ const dataLength = this.readInt32();
144
+ if (totalUncompressedBodySize !== dataLength + 4) {
145
+ throw new parser_error_1.CorruptSaveError(`Possibly corrupt. Indicated size of total save body (${dataLength}) does not match the uncompressed real size of ${totalUncompressedBodySize}.`);
146
+ }
147
+ return {
148
+ concatenatedChunkLength: newChunkLength,
149
+ numChunks: currentChunks.length
150
+ };
151
+ }
152
+ readLevels() {
153
+ if (!this.header) {
154
+ throw new parser_error_1.ParserError('ParserError', 'Header must be set before objects can be read.');
155
+ }
156
+ if (this.header.saveVersion < 29) {
157
+ throw new parser_error_1.UnsupportedVersionError('Support for < U6 is not yet implemented.');
158
+ }
159
+ const numSubLevels = this.readInt32();
160
+ this.levels = new Array(numSubLevels + 1);
161
+ for (let j = 0; j <= numSubLevels; j++) {
162
+ let levelName = (j === numSubLevels) ? '' + this.header.mapName : this.readString();
163
+ this.onProgressCallback(this.getBufferProgress(), `reading level [${(j + 1)}/${(numSubLevels + 1)}] ${levelName}`);
164
+ this.levels[j] = level_class_1.Level.ReadLevel(this, levelName, this.header.buildVersion);
165
+ }
166
+ if (this.getBufferPosition() < this.bufferView.byteLength) {
167
+ this.trailingCollectedObjects = level_class_1.Level.ReadCollectablesList(this);
168
+ }
169
+ return this.levels;
170
+ }
171
+ }
172
+ SaveReader.EPOCH_TICKS = 621355968000000000n;
173
+ exports.SaveReader = SaveReader;
174
+ class Conveyor {
175
+ static getConveyorBeltRegex() {
176
+ return /\/Game\/FactoryGame\/Buildable\/Factory\/(ConveyorBeltMk[0-9]+)\/Build_(\1)\.Build_(\1)_C/g;
177
+ }
178
+ ;
179
+ static getConveyorLiftRegex() {
180
+ return /\/Game\/FactoryGame\/Buildable\/Factory\/(ConveyorLiftMk[0-9]+)\/Build_(\1)\.Build_(\1)_C/g;
181
+ }
182
+ ;
183
+ static isAConveyorBelt(obj) {
184
+ return obj.typePath.match(this.getConveyorBeltRegex()) !== null;
185
+ }
186
+ static isAConveyorLift(obj) {
187
+ return obj.typePath.match(this.getConveyorLiftRegex()) !== null;
188
+ }
189
+ static get availableConnections() { return ['.ConveyorAny0', '.ConveyorAny1', '.Input0', '.Input1', '.Input2', '.Input3', '.InPut3', '.Input4', '.Input5', '.Input6', '.Output0', '.Output1', '.Output2', '.Output3']; }
190
+ static get availableConveyorBelts() {
191
+ return [
192
+ '/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk1/Build_ConveyorBeltMk1.Build_ConveyorBeltMk1_C',
193
+ '/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk2/Build_ConveyorBeltMk2.Build_ConveyorBeltMk2_C',
194
+ '/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk3/Build_ConveyorBeltMk3.Build_ConveyorBeltMk3_C',
195
+ '/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk4/Build_ConveyorBeltMk4.Build_ConveyorBeltMk4_C',
196
+ '/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk5/Build_ConveyorBeltMk5.Build_ConveyorBeltMk5_C'
197
+ ];
198
+ }
199
+ static get availableConveyorLifts() {
200
+ return [
201
+ '/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk1/Build_ConveyorLiftMk1.Build_ConveyorLiftMk1_C',
202
+ '/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk2/Build_ConveyorLiftMk2.Build_ConveyorLiftMk2_C',
203
+ '/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk3/Build_ConveyorLiftMk3.Build_ConveyorLiftMk3_C',
204
+ '/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk4/Build_ConveyorLiftMk4.Build_ConveyorLiftMk4_C',
205
+ '/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk5/Build_ConveyorLiftMk5.Build_ConveyorLiftMk5_C'
206
+ ];
207
+ }
208
+ static isConveyor(currentObject) {
209
+ return Conveyor.isConveyorBelt(currentObject) || Conveyor.isConveyorLift(currentObject);
210
+ }
211
+ static isConveyorBelt(currentObject) {
212
+ if (Conveyor.availableConveyorBelts.includes(currentObject.className)) {
213
+ return true;
214
+ }
215
+ if (currentObject.className.startsWith('/Conveyors_Mod/Build_BeltMk')
216
+ || currentObject.className.startsWith('/Game/Conveyors_Mod/Build_BeltMk')
217
+ || currentObject.className.startsWith('/UltraFastLogistics/Buildable/build_conveyorbeltMK')
218
+ || currentObject.className.startsWith('/FlexSplines/Conveyor/Build_Belt')
219
+ || currentObject.className.startsWith('/conveyorbeltmod/Belt/mk')
220
+ || currentObject.className.startsWith('/minerplus/content/buildable/Factory/belt_')
221
+ || currentObject.className.startsWith('/bamfp/content/buildable/Factory/belt_')) {
222
+ return true;
223
+ }
224
+ return false;
225
+ }
226
+ static isConveyorLift(currentObject) {
227
+ if (Conveyor.availableConveyorLifts.includes(currentObject.className)) {
228
+ return true;
229
+ }
230
+ if (currentObject.className.startsWith('/minerplus/content/buildable/Factory/lift')
231
+ || currentObject.className.startsWith('/bamfp/content/buildable/Factory/lift')
232
+ || currentObject.className.startsWith('/Game/Conveyors_Mod/Build_LiftMk')
233
+ || currentObject.className.startsWith('/Conveyors_Mod/Build_LiftMk')
234
+ || currentObject.className.startsWith('/Game/CoveredConveyor')
235
+ || currentObject.className.startsWith('/CoveredConveyor')
236
+ || currentObject.className.startsWith('/conveyorbeltmod/lift/')) {
237
+ return true;
238
+ }
239
+ return false;
240
+ }
241
+ }
242
+ exports.Conveyor = Conveyor;
243
+ });
@@ -0,0 +1,12 @@
1
+ import { Alignment } from "../../byte/alignment.enum";
2
+ import { ByteWriter } from "../../byte/byte-writer.class";
3
+ import { ChunkCompressionInfo, ChunkSummary } from "../../file.types";
4
+ import { SatisfactorySave } from "./satisfactory-save";
5
+ import { SatisfactorySaveHeader } from "./save.types";
6
+ export declare class SaveWriter extends ByteWriter {
7
+ constructor();
8
+ static WriteHeader(writer: ByteWriter, header: SatisfactorySaveHeader): void;
9
+ static WriteLevels(writer: ByteWriter, save: SatisfactorySave, buildVersion: number): void;
10
+ static GenerateCompressedChunksFromData(bufferArray: ArrayBuffer, compressionInfo: ChunkCompressionInfo, onBinaryBeforeCompressing: (binary: ArrayBuffer) => void, onChunk: (chunk: Uint8Array) => void, alignment?: Alignment): ChunkSummary[];
11
+ generateChunks(compressionInfo: ChunkCompressionInfo, posAfterHeader: number, onBinaryBeforeCompressing: (binary: ArrayBuffer) => void, onHeader: (header: Uint8Array) => void, onChunk: (chunk: Uint8Array) => void): ChunkSummary[];
12
+ }
@@ -0,0 +1,122 @@
1
+ var __importDefault = (this && this.__importDefault) || function (mod) {
2
+ return (mod && mod.__esModule) ? mod : { "default": mod };
3
+ };
4
+ (function (factory) {
5
+ if (typeof module === "object" && typeof module.exports === "object") {
6
+ var v = factory(require, exports);
7
+ if (v !== undefined) module.exports = v;
8
+ }
9
+ else if (typeof define === "function" && define.amd) {
10
+ define(["require", "exports", "pako", "../../byte/alignment.enum", "../../byte/byte-writer.class", "../../error/parser.error", "./level.class"], factory);
11
+ }
12
+ })(function (require, exports) {
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SaveWriter = void 0;
16
+ const pako_1 = __importDefault(require("pako"));
17
+ const alignment_enum_1 = require("../../byte/alignment.enum");
18
+ const byte_writer_class_1 = require("../../byte/byte-writer.class");
19
+ const parser_error_1 = require("../../error/parser.error");
20
+ const level_class_1 = require("./level.class");
21
+ class SaveWriter extends byte_writer_class_1.ByteWriter {
22
+ constructor() {
23
+ super(alignment_enum_1.Alignment.LITTLE_ENDIAN);
24
+ }
25
+ static WriteHeader(writer, header) {
26
+ writer.writeInt32(header.saveHeaderType);
27
+ writer.writeInt32(header.saveVersion);
28
+ writer.writeInt32(header.buildVersion);
29
+ writer.writeString(header.mapName);
30
+ writer.writeString(header.mapOptions);
31
+ writer.writeString(header.sessionName);
32
+ writer.writeInt32(header.playDurationSeconds);
33
+ writer.writeInt64(BigInt(header.saveDateTime));
34
+ writer.writeByte(header.sessionVisibility);
35
+ if (header.saveHeaderType >= 7) {
36
+ writer.writeInt32(header.fEditorObjectVersion);
37
+ }
38
+ if (header.saveHeaderType >= 8) {
39
+ if (header.modMetadata) {
40
+ writer.writeString(JSON.stringify(header.modMetadata));
41
+ }
42
+ else {
43
+ writer.writeString(header.rawModMetadataString);
44
+ }
45
+ writer.writeInt32(header.isModdedSave);
46
+ }
47
+ if (header.saveHeaderType >= 10) {
48
+ writer.writeString(header.saveIdentifier);
49
+ }
50
+ if (header.saveVersion >= 21) {
51
+ }
52
+ else {
53
+ throw new parser_error_1.UnsupportedVersionError("The save version is too old to be supported currently.");
54
+ }
55
+ }
56
+ static WriteLevels(writer, save, buildVersion) {
57
+ writer.writeInt32(save.levels.length - 1);
58
+ for (const level of save.levels) {
59
+ if (level.name !== save.header.mapName) {
60
+ writer.writeString(level.name);
61
+ }
62
+ level_class_1.Level.WriteLevel(writer, level, buildVersion);
63
+ }
64
+ level_class_1.Level.SerializeCollectablesList(writer, save.trailingCollectedObjects);
65
+ }
66
+ static GenerateCompressedChunksFromData(bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, alignment = alignment_enum_1.Alignment.LITTLE_ENDIAN) {
67
+ const errors = [];
68
+ const totalUncompressedSize = bufferArray.byteLength;
69
+ const saveBody = new Uint8Array(bufferArray.byteLength + 4);
70
+ saveBody.set(new Uint8Array(bufferArray), 4);
71
+ const miniView = new DataView(saveBody.buffer);
72
+ miniView.setInt32(0, totalUncompressedSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
73
+ onBinaryBeforeCompressing(saveBody.buffer);
74
+ let handledByte = 0;
75
+ const chunkSummary = [];
76
+ while (handledByte < saveBody.byteLength) {
77
+ const uncompressedContentSize = Math.min(compressionInfo.maxChunkContentSize, saveBody.byteLength - handledByte);
78
+ const uncompressedChunk = saveBody.buffer.slice(handledByte, handledByte + uncompressedContentSize);
79
+ let compressedChunk = new Uint8Array(0);
80
+ try {
81
+ compressedChunk = pako_1.default.deflate(uncompressedChunk);
82
+ }
83
+ catch (err) {
84
+ throw new parser_error_1.CompressionLibraryError("Could not compress save data. " + err);
85
+ }
86
+ const chunk = new Uint8Array(compressionInfo.chunkHeaderSize + compressedChunk.byteLength);
87
+ chunk.set(compressedChunk, compressionInfo.chunkHeaderSize);
88
+ const view = new DataView(chunk.buffer);
89
+ view.setInt32(0, compressionInfo.packageFileTag, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
90
+ view.setInt32(4, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
91
+ view.setInt32(8, compressionInfo.maxChunkContentSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
92
+ view.setInt32(12, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
93
+ view.setInt32(16, compressedChunk.byteLength, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
94
+ view.setInt32(20, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
95
+ view.setInt32(24, uncompressedContentSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
96
+ view.setInt32(28, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
97
+ view.setInt32(32, compressedChunk.byteLength, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
98
+ view.setInt32(36, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
99
+ view.setInt32(40, uncompressedContentSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
100
+ view.setInt32(44, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
101
+ onChunk(chunk);
102
+ chunkSummary.push({
103
+ uncompressedSize: uncompressedContentSize + compressionInfo.chunkHeaderSize,
104
+ compressedSize: compressedChunk.byteLength + compressionInfo.chunkHeaderSize
105
+ });
106
+ handledByte += uncompressedContentSize;
107
+ }
108
+ return chunkSummary;
109
+ }
110
+ generateChunks(compressionInfo, posAfterHeader, onBinaryBeforeCompressing, onHeader, onChunk) {
111
+ if (posAfterHeader <= 0) {
112
+ throw new parser_error_1.ParserError('ParserError', 'Seems like this buffer has no header. Please write the header first before you can generate chunks.');
113
+ }
114
+ const header = new Uint8Array(this.bufferArray.slice(0, posAfterHeader));
115
+ onHeader(header);
116
+ this.bufferArray = this.bufferArray.slice(posAfterHeader);
117
+ const chunkSummary = SaveWriter.GenerateCompressedChunksFromData(this.bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, this.alignment);
118
+ return chunkSummary;
119
+ }
120
+ }
121
+ exports.SaveWriter = SaveWriter;
122
+ });
@@ -0,0 +1,49 @@
1
+ export interface ModData {
2
+ Reference: string;
3
+ Name: string;
4
+ Version: string;
5
+ }
6
+ export interface SatisfactoryModMetadata {
7
+ Mods: ModData[];
8
+ }
9
+ export interface SatisfactorySaveHeader {
10
+ saveHeaderType: number;
11
+ saveVersion: number;
12
+ buildVersion: number;
13
+ mapName: string;
14
+ mapOptions: string;
15
+ sessionName: string;
16
+ playDurationSeconds: number;
17
+ saveDateTime: string;
18
+ sessionVisibility: number;
19
+ rawModMetadataString?: string;
20
+ modMetadata?: SatisfactoryModMetadata;
21
+ isModdedSave?: number;
22
+ saveIdentifier?: string;
23
+ fEditorObjectVersion?: number;
24
+ }
25
+ export type ResourceNodeEntry = {
26
+ purity: string;
27
+ pathName: string;
28
+ position: {
29
+ x: number;
30
+ y: number;
31
+ z: number;
32
+ };
33
+ type: string;
34
+ };
35
+ export type CollectibleEntry = {
36
+ pathName: string;
37
+ position: {
38
+ x: number;
39
+ y: number;
40
+ z: number;
41
+ };
42
+ type: string;
43
+ };
44
+ export type StaticData = {
45
+ collectibles: CollectibleEntry[];
46
+ artifacts: CollectibleEntry[];
47
+ slugs: CollectibleEntry[];
48
+ resourceNodes: ResourceNodeEntry[];
49
+ };
@@ -0,0 +1,12 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ });
@@ -0,0 +1,40 @@
1
+ import { ByteReader } from "../../byte/byte-reader.class";
2
+ import { ByteWriter } from "../../byte/byte-writer.class";
3
+ export type col4 = {
4
+ r: number;
5
+ g: number;
6
+ b: number;
7
+ a: number;
8
+ };
9
+ export declare const SerializeCol4RGBA: (writer: ByteWriter, value: col4) => void;
10
+ export declare const ParseCol4RGBA: (reader: ByteReader) => col4;
11
+ export declare const SerializeCol4BGRA: (writer: ByteWriter, value: col4) => void;
12
+ export declare const ParseCol4BGRA: (reader: ByteReader) => col4;
13
+ export type vec4 = vec3 & {
14
+ w: number;
15
+ };
16
+ export declare const ParseVec4: (reader: ByteReader) => vec4;
17
+ export declare const SerializeVec4: (writer: ByteWriter, vec: vec4) => void;
18
+ export declare const sub: (other: vec3, vec: vec3) => vec3;
19
+ export declare const add: (vec: vec3, other: vec3) => vec3;
20
+ export declare const length: (vec: vec3) => number;
21
+ export declare const mult: (vec: vec3, scale: number) => vec3;
22
+ export declare const norm: (vec: vec3) => vec3;
23
+ export type vec3 = vec2 & {
24
+ z: number;
25
+ };
26
+ export declare const ParseVec3: (reader: ByteReader) => vec3;
27
+ export declare const SerializeVec3: (writer: ByteWriter, vec: vec3) => void;
28
+ export type vec2 = {
29
+ x: number;
30
+ y: number;
31
+ };
32
+ export declare const ParseVec2: (reader: ByteReader) => vec2;
33
+ export declare const SerializeVec2: (writer: ByteWriter, vec: vec2) => void;
34
+ export type Transform = {
35
+ rotation: vec4;
36
+ translation: vec3;
37
+ scale3d: vec3;
38
+ };
39
+ export declare const ParseTransform: (reader: ByteReader) => Transform;
40
+ export declare const SerializeTransform: (writer: ByteWriter, transform: Transform) => void;
@@ -0,0 +1,105 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SerializeTransform = exports.ParseTransform = exports.SerializeVec2 = exports.ParseVec2 = exports.SerializeVec3 = exports.ParseVec3 = exports.norm = exports.mult = exports.length = exports.add = exports.sub = exports.SerializeVec4 = exports.ParseVec4 = exports.ParseCol4BGRA = exports.SerializeCol4BGRA = exports.ParseCol4RGBA = exports.SerializeCol4RGBA = void 0;
13
+ const SerializeCol4RGBA = (writer, value) => {
14
+ writer.writeFloat(value.r);
15
+ writer.writeFloat(value.g);
16
+ writer.writeFloat(value.b);
17
+ writer.writeFloat(value.a);
18
+ };
19
+ exports.SerializeCol4RGBA = SerializeCol4RGBA;
20
+ const ParseCol4RGBA = (reader) => {
21
+ return {
22
+ r: reader.readFloat(),
23
+ g: reader.readFloat(),
24
+ b: reader.readFloat(),
25
+ a: reader.readFloat(),
26
+ };
27
+ };
28
+ exports.ParseCol4RGBA = ParseCol4RGBA;
29
+ const SerializeCol4BGRA = (writer, value) => {
30
+ writer.writeByte(value.b);
31
+ writer.writeByte(value.g);
32
+ writer.writeByte(value.r);
33
+ writer.writeByte(value.a);
34
+ };
35
+ exports.SerializeCol4BGRA = SerializeCol4BGRA;
36
+ const ParseCol4BGRA = (reader) => {
37
+ return {
38
+ b: reader.readByte(),
39
+ g: reader.readByte(),
40
+ r: reader.readByte(),
41
+ a: reader.readByte(),
42
+ };
43
+ };
44
+ exports.ParseCol4BGRA = ParseCol4BGRA;
45
+ const ParseVec4 = (reader) => {
46
+ return {
47
+ ...(0, exports.ParseVec3)(reader),
48
+ w: reader.readFloat()
49
+ };
50
+ };
51
+ exports.ParseVec4 = ParseVec4;
52
+ const SerializeVec4 = (writer, vec) => {
53
+ (0, exports.SerializeVec3)(writer, vec);
54
+ writer.writeFloat(vec.w);
55
+ };
56
+ exports.SerializeVec4 = SerializeVec4;
57
+ const sub = (other, vec) => ({ x: other.x - vec.x, y: other.y - vec.y, z: other.z - vec.z });
58
+ exports.sub = sub;
59
+ const add = (vec, other) => ({ x: vec.x + other.x, y: vec.y + other.y, z: vec.z + other.z });
60
+ exports.add = add;
61
+ const length = (vec) => Math.sqrt(vec.x ** 2 + vec.y ** 2 + vec.z ** 2);
62
+ exports.length = length;
63
+ const mult = (vec, scale) => ({ x: vec.x * scale, y: vec.y * scale, z: vec.z * scale });
64
+ exports.mult = mult;
65
+ const norm = (vec) => (0, exports.mult)(vec, 1. / (0, exports.length)(vec));
66
+ exports.norm = norm;
67
+ const ParseVec3 = (reader) => {
68
+ return {
69
+ ...(0, exports.ParseVec2)(reader),
70
+ z: reader.readFloat()
71
+ };
72
+ };
73
+ exports.ParseVec3 = ParseVec3;
74
+ const SerializeVec3 = (writer, vec) => {
75
+ (0, exports.SerializeVec2)(writer, vec);
76
+ writer.writeFloat(vec.z);
77
+ };
78
+ exports.SerializeVec3 = SerializeVec3;
79
+ const ParseVec2 = (reader) => {
80
+ return {
81
+ x: reader.readFloat(),
82
+ y: reader.readFloat(),
83
+ };
84
+ };
85
+ exports.ParseVec2 = ParseVec2;
86
+ const SerializeVec2 = (writer, vec) => {
87
+ writer.writeFloat(vec.x);
88
+ writer.writeFloat(vec.y);
89
+ };
90
+ exports.SerializeVec2 = SerializeVec2;
91
+ const ParseTransform = (reader) => {
92
+ return {
93
+ rotation: (0, exports.ParseVec4)(reader),
94
+ translation: (0, exports.ParseVec3)(reader),
95
+ scale3d: (0, exports.ParseVec3)(reader),
96
+ };
97
+ };
98
+ exports.ParseTransform = ParseTransform;
99
+ const SerializeTransform = (writer, transform) => {
100
+ (0, exports.SerializeVec4)(writer, transform.rotation);
101
+ (0, exports.SerializeVec3)(writer, transform.translation);
102
+ (0, exports.SerializeVec3)(writer, transform.scale3d);
103
+ };
104
+ exports.SerializeTransform = SerializeTransform;
105
+ });
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@etothepii/satisfactory-file-parser",
3
3
  "author": "etothepii",
4
- "version": "0.0.30",
4
+ "version": "0.0.31",
5
5
  "description": "A file parser for satisfactory files. Includes save files and blueprint files.",
6
- "types": "./dist/index.d.ts",
7
- "main": "./dist/index.js",
6
+ "types": "./build/index.d.ts",
7
+ "main": "./build/index.js",
8
8
  "keywords": [
9
9
  "satisfactory",
10
10
  "save",