@etothepii/satisfactory-file-parser 0.0.33 → 0.1.1

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 (38) hide show
  1. package/README.md +12 -8
  2. package/build/index.js +41 -51
  3. package/build/parser/byte/alignment.enum.js +8 -18
  4. package/build/parser/byte/binary-operable.interface.js +2 -12
  5. package/build/parser/byte/binary-readable.interface.js +2 -12
  6. package/build/parser/byte/byte-reader.class.js +122 -132
  7. package/build/parser/byte/byte-writer.class.js +133 -143
  8. package/build/parser/error/parser.error.js +40 -50
  9. package/build/parser/file.types.js +2 -12
  10. package/build/parser/parser.js +84 -95
  11. package/build/parser/satisfactory/blueprint/blueprint-reader.js +109 -119
  12. package/build/parser/satisfactory/blueprint/blueprint-writer.js +56 -66
  13. package/build/parser/satisfactory/blueprint/blueprint.types.js +2 -12
  14. package/build/parser/satisfactory/objects/DataFields.js +306 -307
  15. package/build/parser/satisfactory/objects/ObjectReference.js +14 -24
  16. package/build/parser/satisfactory/objects/Property.js +974 -977
  17. package/build/parser/satisfactory/objects/SaveComponent.js +28 -38
  18. package/build/parser/satisfactory/objects/SaveEntity.js +69 -75
  19. package/build/parser/satisfactory/objects/SaveObject.js +26 -36
  20. package/build/parser/satisfactory/save/asynchronous-level.class.js +60 -70
  21. package/build/parser/satisfactory/save/level.class.d.ts +1 -1
  22. package/build/parser/satisfactory/save/level.class.js +147 -128
  23. package/build/parser/satisfactory/save/satisfactory-save.js +10 -20
  24. package/build/parser/satisfactory/save/save-reader.d.ts +2 -2
  25. package/build/parser/satisfactory/save/save-reader.js +209 -171
  26. package/build/parser/satisfactory/save/save-writer.js +97 -107
  27. package/build/parser/satisfactory/save/save.types.js +2 -12
  28. package/build/parser/satisfactory/structs/util.types.d.ts +6 -0
  29. package/build/parser/satisfactory/structs/util.types.js +122 -96
  30. package/build/parser/stream/byte-stream-reader.class.js +217 -227
  31. package/build/parser/stream/json-stream-state-writer.js +15 -25
  32. package/build/parser/stream/json-stream-writable.js +72 -82
  33. package/build/parser/stream/json-stream-writer.js +122 -132
  34. package/build/parser/stream/save-stream-json-stringifier.js +29 -39
  35. package/build/parser/stream/save-stream-reader.class.js +106 -116
  36. package/build/parser/stream/save-stream-writer.class.js +90 -100
  37. package/build/parser/stream/stream-level.class.js +93 -103
  38. package/package.json +2 -2
@@ -1,188 +1,226 @@
1
+ "use strict";
1
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
2
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
3
4
  };
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;
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SaveReader = exports.DEFAULT_SATISFACTORY_CHUNK_HEADER_SIZE = exports.projectionFilterApplies = void 0;
7
+ const pako_1 = __importDefault(require("pako"));
8
+ const alignment_enum_1 = require("../../byte/alignment.enum");
9
+ const byte_reader_class_1 = require("../../byte/byte-reader.class");
10
+ const parser_error_1 = require("../../error/parser.error");
11
+ const SaveComponent_1 = require("../objects/SaveComponent");
12
+ const SaveEntity_1 = require("../objects/SaveEntity");
13
+ const asynchronous_level_class_1 = require("./asynchronous-level.class");
14
+ const level_class_1 = require("./level.class");
15
+ const projectionFilterApplies = (config, object) => {
16
+ let cond1 = false;
17
+ if ((0, SaveEntity_1.isSaveEntity)(object) || (config.includeComponents && (0, SaveComponent_1.isSaveComponent)(object))) {
18
+ cond1 = true;
8
19
  }
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", "./asynchronous-level.class", "./level.class"], factory);
20
+ let cond2 = true;
21
+ if ((0, SaveEntity_1.isSaveEntity)(object)) {
22
+ cond2 = false;
23
+ if (config.entityPathFilter.behavior === 'whitelist') {
24
+ cond2 = config.entityPathFilter.list.find(en => object.typePath.startsWith(en)) !== undefined;
25
+ }
26
+ else if (config.entityPathFilter.behavior === 'blacklist') {
27
+ cond2 = config.entityPathFilter.list.find(en => object.typePath.startsWith(en)) === undefined;
28
+ }
11
29
  }
12
- })(function (require, exports) {
13
- "use strict";
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.SaveReader = exports.DEFAULT_SATISFACTORY_CHUNK_HEADER_SIZE = 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 asynchronous_level_class_1 = require("./asynchronous-level.class");
23
- const level_class_1 = require("./level.class");
24
- const projectionFilterApplies = (config, object) => {
25
- let cond1 = false;
26
- if ((0, SaveEntity_1.isSaveEntity)(object) || (config.includeComponents && (0, SaveComponent_1.isSaveComponent)(object))) {
27
- cond1 = true;
28
- }
29
- let cond2 = true;
30
- if ((0, SaveEntity_1.isSaveEntity)(object)) {
31
- cond2 = false;
32
- if (config.entityPathFilter.behavior === 'whitelist') {
33
- cond2 = config.entityPathFilter.list.find(en => object.typePath.startsWith(en)) !== undefined;
34
- }
35
- else if (config.entityPathFilter.behavior === 'blacklist') {
36
- cond2 = config.entityPathFilter.list.find(en => object.typePath.startsWith(en)) === undefined;
37
- }
30
+ return cond1 && cond2;
31
+ };
32
+ exports.projectionFilterApplies = projectionFilterApplies;
33
+ exports.DEFAULT_SATISFACTORY_CHUNK_HEADER_SIZE = 49;
34
+ class SaveReader extends byte_reader_class_1.ByteReader {
35
+ constructor(fileBuffer, onProgressCallback = () => { }) {
36
+ super(fileBuffer, alignment_enum_1.Alignment.LITTLE_ENDIAN);
37
+ this.onProgressCallback = onProgressCallback;
38
+ this.levels = [];
39
+ this.trailingCollectedObjects = [];
40
+ this.compressionInfo = {
41
+ packageFileTag: 0,
42
+ maxChunkContentSize: 0,
43
+ chunkHeaderSize: exports.DEFAULT_SATISFACTORY_CHUNK_HEADER_SIZE
44
+ };
45
+ }
46
+ readHeader() {
47
+ this.header = {
48
+ saveHeaderType: 0,
49
+ saveVersion: 0,
50
+ buildVersion: 0,
51
+ mapName: "DEFAULT",
52
+ mapOptions: "",
53
+ sessionName: "",
54
+ playDurationSeconds: 0,
55
+ saveDateTime: "0",
56
+ sessionVisibility: 0
57
+ };
58
+ this.header.saveHeaderType = this.readInt32();
59
+ this.header.saveVersion = this.readInt32();
60
+ this.header.buildVersion = this.readInt32();
61
+ this.header.mapName = this.readString();
62
+ this.header.mapOptions = this.readString();
63
+ this.header.sessionName = this.readString();
64
+ this.header.playDurationSeconds = this.readInt32();
65
+ const rawSaveDateTimeInTicks = this.readLong();
66
+ const unixMilliseconds = (rawSaveDateTimeInTicks - SaveReader.EPOCH_TICKS) / 10000n;
67
+ this.header.saveDateTime = unixMilliseconds.toString();
68
+ this.header.sessionVisibility = this.readByte();
69
+ if (this.header.saveHeaderType >= 7) {
70
+ this.header.fEditorObjectVersion = this.readInt32();
38
71
  }
39
- return cond1 && cond2;
40
- };
41
- exports.projectionFilterApplies = projectionFilterApplies;
42
- exports.DEFAULT_SATISFACTORY_CHUNK_HEADER_SIZE = 48;
43
- class SaveReader extends byte_reader_class_1.ByteReader {
44
- constructor(fileBuffer, onProgressCallback = () => { }) {
45
- super(fileBuffer, alignment_enum_1.Alignment.LITTLE_ENDIAN);
46
- this.onProgressCallback = onProgressCallback;
47
- this.levels = [];
48
- this.trailingCollectedObjects = [];
49
- this.compressionInfo = {
50
- packageFileTag: 0,
51
- maxChunkContentSize: 0,
52
- chunkHeaderSize: exports.DEFAULT_SATISFACTORY_CHUNK_HEADER_SIZE
53
- };
54
- }
55
- readHeader() {
56
- this.header = {
57
- saveHeaderType: 0,
58
- saveVersion: 0,
59
- buildVersion: 0,
60
- mapName: "DEFAULT",
61
- mapOptions: "",
62
- sessionName: "",
63
- playDurationSeconds: 0,
64
- saveDateTime: "0",
65
- sessionVisibility: 0
66
- };
67
- this.header.saveHeaderType = this.readInt32();
68
- this.header.saveVersion = this.readInt32();
69
- this.header.buildVersion = this.readInt32();
70
- this.header.mapName = this.readString();
71
- this.header.mapOptions = this.readString();
72
- this.header.sessionName = this.readString();
73
- this.header.playDurationSeconds = this.readInt32();
74
- const rawSaveDateTimeInTicks = this.readLong();
75
- const unixMilliseconds = (rawSaveDateTimeInTicks - SaveReader.EPOCH_TICKS) / 10000n;
76
- this.header.saveDateTime = unixMilliseconds.toString();
77
- this.header.sessionVisibility = this.readByte();
78
- if (this.header.saveHeaderType >= 7) {
79
- this.header.fEditorObjectVersion = this.readInt32();
80
- }
81
- if (this.header.saveHeaderType >= 8) {
82
- this.header.rawModMetadataString = this.readString();
83
- try {
84
- this.header.modMetadata = JSON.parse(this.header.rawModMetadataString);
85
- }
86
- catch (error) {
87
- }
88
- this.header.isModdedSave = this.readInt32();
89
- }
90
- if (this.header.saveHeaderType >= 10) {
91
- this.header.saveIdentifier = this.readString();
72
+ if (this.header.saveHeaderType >= 8) {
73
+ this.header.rawModMetadataString = this.readString();
74
+ try {
75
+ this.header.modMetadata = JSON.parse(this.header.rawModMetadataString);
92
76
  }
93
- if (this.header.saveVersion >= 21) {
77
+ catch (error) {
94
78
  }
95
- else {
96
- throw new parser_error_1.UnsupportedVersionError("The save version is too old to support encoding currently. Save in newer game version.");
97
- }
98
- return this.header;
79
+ this.header.isModdedSave = this.readInt32();
99
80
  }
100
- inflateChunks() {
101
- this.fileBuffer = this.fileBuffer.slice(this.currentByte);
102
- this.handledByte = 0;
103
- this.currentByte = 0;
104
- this.maxByte = this.fileBuffer.byteLength;
105
- let currentChunks = [];
106
- let totalUncompressedBodySize = 0;
107
- while (this.handledByte < this.maxByte) {
108
- let chunkHeader = new DataView(this.fileBuffer.slice(0, this.compressionInfo.chunkHeaderSize));
109
- this.currentByte = this.compressionInfo.chunkHeaderSize;
110
- this.handledByte += this.compressionInfo.chunkHeaderSize;
111
- if (this.compressionInfo.packageFileTag <= 0) {
112
- this.compressionInfo.packageFileTag = chunkHeader.getInt32(0, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
113
- }
114
- if (this.compressionInfo.maxChunkContentSize <= 0) {
115
- this.compressionInfo.maxChunkContentSize = chunkHeader.getInt32(8, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
116
- }
117
- const chunkCompressedLength = chunkHeader.getInt32(32, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
118
- const chunkUncompressedLength = chunkHeader.getInt32(40, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
119
- totalUncompressedBodySize += chunkUncompressedLength;
120
- const currentChunkSize = chunkCompressedLength;
121
- let currentChunk = this.fileBuffer.slice(this.currentByte, this.currentByte + currentChunkSize);
122
- this.handledByte += currentChunkSize;
123
- this.currentByte += currentChunkSize;
124
- this.fileBuffer = this.fileBuffer.slice(this.currentByte);
125
- this.currentByte = 0;
126
- try {
127
- let currentInflatedChunk = null;
128
- currentInflatedChunk = pako_1.default.inflate(currentChunk);
129
- currentChunks.push(currentInflatedChunk);
130
- }
131
- catch (err) {
132
- throw new parser_error_1.CompressionLibraryError("Failed to inflate compressed save data. " + err);
133
- }
81
+ if (this.header.saveHeaderType >= 10) {
82
+ this.header.saveIdentifier = this.readString();
83
+ }
84
+ if (this.header.saveHeaderType >= 13) {
85
+ const unk1 = this.readInt32();
86
+ const unk2 = this.readInt32();
87
+ const unk3 = this.readBytes(16);
88
+ const unk4 = this.readInt32();
89
+ }
90
+ if (this.header.saveVersion >= 21) {
91
+ }
92
+ else {
93
+ throw new parser_error_1.UnsupportedVersionError("The save version is too old to support encoding currently. Save in newer game version.");
94
+ }
95
+ return this.header;
96
+ }
97
+ inflateChunks() {
98
+ this.fileBuffer = this.fileBuffer.slice(this.currentByte);
99
+ this.handledByte = 0;
100
+ this.currentByte = 0;
101
+ this.maxByte = this.fileBuffer.byteLength;
102
+ let currentChunks = [];
103
+ let totalUncompressedBodySize = 0;
104
+ while (this.handledByte < this.maxByte) {
105
+ let chunkHeader = new DataView(this.fileBuffer.slice(0, this.compressionInfo.chunkHeaderSize));
106
+ this.currentByte = this.compressionInfo.chunkHeaderSize;
107
+ this.handledByte += this.compressionInfo.chunkHeaderSize;
108
+ if (this.compressionInfo.packageFileTag <= 0) {
109
+ this.compressionInfo.packageFileTag = chunkHeader.getInt32(0, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
134
110
  }
135
- let newChunkLength = currentChunks.map(cc => cc.length).reduce((prev, cur) => prev + cur);
136
- const bigWholeChunk = new Uint8Array(newChunkLength);
137
- let currentLength = 0;
138
- for (let i = 0; i < currentChunks.length; i++) {
139
- bigWholeChunk.set(currentChunks[i], currentLength);
140
- currentLength += currentChunks[i].length;
111
+ if (this.compressionInfo.maxChunkContentSize <= 0) {
112
+ this.compressionInfo.maxChunkContentSize = chunkHeader.getInt32(8, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
141
113
  }
114
+ const chunkCompressedLength = chunkHeader.getInt32(33, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
115
+ const chunkUncompressedLength = chunkHeader.getInt32(25, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
116
+ totalUncompressedBodySize += chunkUncompressedLength;
117
+ const currentChunkSize = chunkCompressedLength;
118
+ let currentChunk = this.fileBuffer.slice(this.currentByte, this.currentByte + currentChunkSize);
119
+ this.handledByte += currentChunkSize;
120
+ this.currentByte += currentChunkSize;
121
+ this.fileBuffer = this.fileBuffer.slice(this.currentByte);
142
122
  this.currentByte = 0;
143
- this.maxByte = bigWholeChunk.buffer.byteLength;
144
- this.bufferView = new DataView(bigWholeChunk.buffer);
145
- const dataLength = this.readInt32();
146
- if (totalUncompressedBodySize !== dataLength + 4) {
147
- throw new parser_error_1.CorruptSaveError(`Possibly corrupt. Indicated size of total save body (${dataLength}) does not match the uncompressed real size of ${totalUncompressedBodySize}.`);
148
- }
149
- return {
150
- concatenatedChunkLength: newChunkLength,
151
- numChunks: currentChunks.length
152
- };
153
- }
154
- readLevels() {
155
- if (!this.header) {
156
- throw new parser_error_1.ParserError('ParserError', 'Header must be set before objects can be read.');
123
+ try {
124
+ let currentInflatedChunk = null;
125
+ currentInflatedChunk = pako_1.default.inflate(currentChunk);
126
+ currentChunks.push(currentInflatedChunk);
157
127
  }
158
- if (this.header.saveVersion < 29) {
159
- throw new parser_error_1.UnsupportedVersionError('Support for < U6 is not yet implemented.');
128
+ catch (err) {
129
+ throw new parser_error_1.CompressionLibraryError("Failed to inflate compressed save data. " + err);
160
130
  }
161
- const numSubLevels = this.readInt32();
162
- this.levels = new Array(numSubLevels + 1);
163
- for (let j = 0; j <= numSubLevels; j++) {
164
- let levelName = (j === numSubLevels) ? '' + this.header.mapName : this.readString();
165
- this.onProgressCallback(this.getBufferProgress(), `reading level [${(j + 1)}/${(numSubLevels + 1)}] ${levelName}`);
166
- this.levels[j] = level_class_1.Level.ReadLevel(this, levelName, this.header.buildVersion);
167
- }
168
- if (this.getBufferPosition() < this.bufferView.byteLength) {
169
- this.trailingCollectedObjects = level_class_1.Level.ReadCollectablesList(this);
170
- }
171
- return this.levels;
172
- }
173
- async readLevelsAsynchronously(writer) {
174
- const numSubLevels = this.readInt32();
175
- this.levels = new Array(numSubLevels + 1);
176
- await writer.openLevels();
177
- for (let j = 0; j <= numSubLevels; j++) {
178
- let levelName = (j === numSubLevels) ? '' + this.header.mapName : this.readString();
179
- this.onProgressCallback(this.getBufferProgress(), `reading level [${(j + 1)}/${(numSubLevels + 1)}] ${levelName}`);
180
- this.levels[j] = await asynchronous_level_class_1.AsynchronousLevel.StreamReadLevel(this, levelName, this.header.buildVersion, writer);
131
+ }
132
+ let newChunkLength = currentChunks.map(cc => cc.length).reduce((prev, cur) => prev + cur);
133
+ const bigWholeChunk = new Uint8Array(newChunkLength);
134
+ let currentLength = 0;
135
+ for (let i = 0; i < currentChunks.length; i++) {
136
+ bigWholeChunk.set(currentChunks[i], currentLength);
137
+ currentLength += currentChunks[i].length;
138
+ }
139
+ this.currentByte = 0;
140
+ this.maxByte = bigWholeChunk.buffer.byteLength;
141
+ this.bufferView = new DataView(bigWholeChunk.buffer);
142
+ const dataLength = this.readInt32();
143
+ if (totalUncompressedBodySize !== dataLength + 8) {
144
+ throw new parser_error_1.CorruptSaveError(`Possibly corrupt. Indicated size of total save body (${dataLength + 8}) does not match the uncompressed real size of ${totalUncompressedBodySize}.`);
145
+ }
146
+ return {
147
+ concatenatedChunkLength: newChunkLength,
148
+ numChunks: currentChunks.length
149
+ };
150
+ }
151
+ readLevelsU8() {
152
+ if (!this.header) {
153
+ throw new parser_error_1.ParserError('ParserError', 'Header must be set before objects can be read.');
154
+ }
155
+ if (this.header.saveVersion < 29) {
156
+ throw new parser_error_1.UnsupportedVersionError('Game Version < U6 is not supported.');
157
+ }
158
+ if (this.header.saveHeaderType < 13) {
159
+ 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');
160
+ }
161
+ const unk = this.readInt32();
162
+ const cannotBeLevelCountWhatIsIt = this.readInt32();
163
+ const noneString = this.readString();
164
+ const unk2 = this.readInt32();
165
+ const hm1 = this.readInt32();
166
+ const unk3 = this.readInt32();
167
+ const noneString2 = this.readString();
168
+ const grids = {};
169
+ const readLevelsList = (childrenCount) => {
170
+ const hmm = this.readInt32();
171
+ const parentName = this.readString();
172
+ const whatever = this.readBytes(8);
173
+ grids[parentName] = {};
174
+ for (let i = 0; i < childrenCount; i++) {
175
+ const binaryLenIGuess = this.readInt32();
176
+ const levelInstanceName = this.readString();
177
+ const lod = /\_L([0-9]+)\_/.exec(levelInstanceName)[1];
178
+ const arr = grids[parentName][Number(lod)];
179
+ if (!arr) {
180
+ grids[parentName][Number(lod)] = [];
181
+ }
182
+ grids[parentName][Number(lod)].push(levelInstanceName);
181
183
  }
182
- await writer.endLevels();
183
- return this.levels;
184
+ };
185
+ readLevelsList(1379);
186
+ readLevelsList(0);
187
+ readLevelsList(972);
188
+ readLevelsList(0);
189
+ readLevelsList(0);
190
+ const unk5 = this.readInt32();
191
+ const levels = [];
192
+ const levelCount = this.readInt32();
193
+ this.onProgressCallback(this.getBufferProgress(), `reading pack of ${levelCount} levels.`);
194
+ for (let i = 0; i < levelCount; i++) {
195
+ let levelSingleName = this.readString();
196
+ levels.push(level_class_1.Level.ReadLevel(this, levelSingleName, this.header.buildVersion));
197
+ }
198
+ level_class_1.Level.ReadCollectablesList(this);
199
+ this.onProgressCallback(this.getBufferProgress(), `finished reading levels pack of ${levelCount}.`);
200
+ if (this.getBufferPosition() < this.getBufferLength()) {
201
+ const appendedLevel = new level_class_1.Level(this.header.mapName);
202
+ levels.push(appendedLevel);
203
+ level_class_1.Level.ReadObjectHeaders(this, appendedLevel.objects, this.onProgressCallback);
204
+ appendedLevel.collectables = level_class_1.Level.ReadCollectablesList(this);
205
+ level_class_1.Level.ReadObjectContents(appendedLevel.name, this, appendedLevel.objects, this.header.buildVersion, this.onProgressCallback);
206
+ level_class_1.Level.ReadCollectablesList(this);
207
+ level_class_1.Level.ReadCollectablesList(this);
208
+ }
209
+ this.onProgressCallback(this.getBufferProgress(), 'finished parsing.');
210
+ return levels;
211
+ }
212
+ async readLevelsAsynchronously(writer) {
213
+ const numSubLevels = this.readInt32();
214
+ this.levels = new Array(numSubLevels + 1);
215
+ await writer.openLevels();
216
+ for (let j = 0; j <= numSubLevels; j++) {
217
+ let levelName = (j === numSubLevels) ? '' + this.header.mapName : this.readString();
218
+ this.onProgressCallback(this.getBufferProgress(), `reading level [${(j + 1)}/${(numSubLevels + 1)}] ${levelName}`);
219
+ this.levels[j] = await asynchronous_level_class_1.AsynchronousLevel.StreamReadLevel(this, levelName, this.header.buildVersion, writer);
184
220
  }
221
+ await writer.endLevels();
222
+ return this.levels;
185
223
  }
186
- SaveReader.EPOCH_TICKS = 621355968000000000n;
187
- exports.SaveReader = SaveReader;
188
- });
224
+ }
225
+ SaveReader.EPOCH_TICKS = 621355968000000000n;
226
+ exports.SaveReader = SaveReader;
@@ -1,122 +1,112 @@
1
+ "use strict";
1
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
2
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
3
4
  };
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;
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SaveWriter = void 0;
7
+ const pako_1 = __importDefault(require("pako"));
8
+ const alignment_enum_1 = require("../../byte/alignment.enum");
9
+ const byte_writer_class_1 = require("../../byte/byte-writer.class");
10
+ const parser_error_1 = require("../../error/parser.error");
11
+ const level_class_1 = require("./level.class");
12
+ class SaveWriter extends byte_writer_class_1.ByteWriter {
13
+ constructor() {
14
+ super(alignment_enum_1.Alignment.LITTLE_ENDIAN);
8
15
  }
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);
16
+ static WriteHeader(writer, header) {
17
+ writer.writeInt32(header.saveHeaderType);
18
+ writer.writeInt32(header.saveVersion);
19
+ writer.writeInt32(header.buildVersion);
20
+ writer.writeString(header.mapName);
21
+ writer.writeString(header.mapOptions);
22
+ writer.writeString(header.sessionName);
23
+ writer.writeInt32(header.playDurationSeconds);
24
+ writer.writeInt64(BigInt(header.saveDateTime));
25
+ writer.writeByte(header.sessionVisibility);
26
+ if (header.saveHeaderType >= 7) {
27
+ writer.writeInt32(header.fEditorObjectVersion);
24
28
  }
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) {
29
+ if (header.saveHeaderType >= 8) {
30
+ if (header.modMetadata) {
31
+ writer.writeString(JSON.stringify(header.modMetadata));
51
32
  }
52
33
  else {
53
- throw new parser_error_1.UnsupportedVersionError("The save version is too old to be supported currently.");
34
+ writer.writeString(header.rawModMetadataString);
54
35
  }
36
+ writer.writeInt32(header.isModdedSave);
55
37
  }
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);
38
+ if (header.saveHeaderType >= 10) {
39
+ writer.writeString(header.saveIdentifier);
40
+ }
41
+ if (header.saveVersion >= 21) {
65
42
  }
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;
43
+ else {
44
+ throw new parser_error_1.UnsupportedVersionError("The save version is too old to be supported currently.");
45
+ }
46
+ }
47
+ static WriteLevels(writer, save, buildVersion) {
48
+ writer.writeInt32(save.levels.length - 1);
49
+ for (const level of save.levels) {
50
+ if (level.name !== save.header.mapName) {
51
+ writer.writeString(level.name);
107
52
  }
108
- return chunkSummary;
53
+ level_class_1.Level.WriteLevel(writer, level, buildVersion);
109
54
  }
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.');
55
+ level_class_1.Level.SerializeCollectablesList(writer, save.trailingCollectedObjects);
56
+ }
57
+ static GenerateCompressedChunksFromData(bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, alignment = alignment_enum_1.Alignment.LITTLE_ENDIAN) {
58
+ const errors = [];
59
+ const totalUncompressedSize = bufferArray.byteLength;
60
+ const saveBody = new Uint8Array(bufferArray.byteLength + 4);
61
+ saveBody.set(new Uint8Array(bufferArray), 4);
62
+ const miniView = new DataView(saveBody.buffer);
63
+ miniView.setInt32(0, totalUncompressedSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
64
+ onBinaryBeforeCompressing(saveBody.buffer);
65
+ let handledByte = 0;
66
+ const chunkSummary = [];
67
+ while (handledByte < saveBody.byteLength) {
68
+ const uncompressedContentSize = Math.min(compressionInfo.maxChunkContentSize, saveBody.byteLength - handledByte);
69
+ const uncompressedChunk = saveBody.buffer.slice(handledByte, handledByte + uncompressedContentSize);
70
+ let compressedChunk = new Uint8Array(0);
71
+ try {
72
+ compressedChunk = pako_1.default.deflate(uncompressedChunk);
113
73
  }
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;
74
+ catch (err) {
75
+ throw new parser_error_1.CompressionLibraryError("Could not compress save data. " + err);
76
+ }
77
+ const chunk = new Uint8Array(compressionInfo.chunkHeaderSize + compressedChunk.byteLength);
78
+ chunk.set(compressedChunk, compressionInfo.chunkHeaderSize);
79
+ const view = new DataView(chunk.buffer);
80
+ view.setInt32(0, compressionInfo.packageFileTag, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
81
+ view.setInt32(4, 572662306, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
82
+ view.setInt32(8, compressionInfo.maxChunkContentSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
83
+ view.setInt32(12, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
84
+ view.setInt32(16, compressedChunk.byteLength, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
85
+ view.setInt32(20, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
86
+ view.setInt32(24, uncompressedContentSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
87
+ view.setInt32(28, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
88
+ view.setInt32(32, compressedChunk.byteLength, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
89
+ view.setInt32(36, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
90
+ view.setInt32(40, uncompressedContentSize, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
91
+ view.setInt32(44, 0, alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
92
+ onChunk(chunk);
93
+ chunkSummary.push({
94
+ uncompressedSize: uncompressedContentSize + compressionInfo.chunkHeaderSize,
95
+ compressedSize: compressedChunk.byteLength + compressionInfo.chunkHeaderSize
96
+ });
97
+ handledByte += uncompressedContentSize;
98
+ }
99
+ return chunkSummary;
100
+ }
101
+ generateChunks(compressionInfo, posAfterHeader, onBinaryBeforeCompressing, onHeader, onChunk) {
102
+ if (posAfterHeader <= 0) {
103
+ throw new parser_error_1.ParserError('ParserError', 'Seems like this buffer has no header. Please write the header first before you can generate chunks.');
119
104
  }
105
+ const header = new Uint8Array(this.bufferArray.slice(0, posAfterHeader));
106
+ onHeader(header);
107
+ this.bufferArray = this.bufferArray.slice(posAfterHeader);
108
+ const chunkSummary = SaveWriter.GenerateCompressedChunksFromData(this.bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, this.alignment);
109
+ return chunkSummary;
120
110
  }
121
- exports.SaveWriter = SaveWriter;
122
- });
111
+ }
112
+ exports.SaveWriter = SaveWriter;
@@ -1,12 +1,2 @@
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
- });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });