@etothepii/satisfactory-file-parser 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +11 -0
- package/build/index.js +12 -0
- package/build/parser/blueprint-reader.d.ts +18 -0
- package/build/parser/blueprint-reader.js +128 -0
- package/build/parser/blueprint-writer.d.ts +21 -0
- package/build/parser/blueprint-writer.js +64 -0
- package/build/parser/byte/alignment.enum.d.ts +4 -0
- package/build/parser/byte/alignment.enum.js +5 -0
- package/build/parser/byte/byte-reader.class.d.ts +38 -0
- package/build/parser/byte/byte-reader.class.js +128 -0
- package/build/parser/byte/byte-writer.class.d.ts +38 -0
- package/build/parser/byte/byte-writer.class.js +146 -0
- package/build/parser/error/parser.error.d.ts +12 -0
- package/build/parser/error/parser.error.js +21 -0
- package/build/parser/parser.d.ts +44 -0
- package/build/parser/parser.js +81 -0
- package/build/parser/satisfactory/blueprint/blueprint.d.ts +20 -0
- package/build/parser/satisfactory/blueprint/blueprint.js +1 -0
- package/build/parser/satisfactory/level.class.d.ts +21 -0
- package/build/parser/satisfactory/level.class.js +144 -0
- package/build/parser/satisfactory/objects/DataFields.d.ts +13 -0
- package/build/parser/satisfactory/objects/DataFields.js +245 -0
- package/build/parser/satisfactory/objects/ObjectReference.d.ts +9 -0
- package/build/parser/satisfactory/objects/ObjectReference.js +13 -0
- package/build/parser/satisfactory/objects/Property.d.ts +270 -0
- package/build/parser/satisfactory/objects/Property.js +1119 -0
- package/build/parser/satisfactory/objects/SaveComponent.d.ts +16 -0
- package/build/parser/satisfactory/objects/SaveComponent.js +27 -0
- package/build/parser/satisfactory/objects/SaveEntity.d.ts +25 -0
- package/build/parser/satisfactory/objects/SaveEntity.js +66 -0
- package/build/parser/satisfactory/objects/SaveObject.d.ts +14 -0
- package/build/parser/satisfactory/objects/SaveObject.js +25 -0
- package/build/parser/satisfactory/satisfactory-save.d.ts +57 -0
- package/build/parser/satisfactory/satisfactory-save.js +7 -0
- package/build/parser/satisfactory/static-data.d.ts +7 -0
- package/build/parser/satisfactory/static-data.js +1 -0
- package/build/parser/satisfactory/structs/util.types.d.ts +40 -0
- package/build/parser/satisfactory/structs/util.types.js +75 -0
- package/build/parser/save-reader.d.ts +43 -0
- package/build/parser/save-reader.js +243 -0
- package/build/parser/save-writer.d.ts +22 -0
- package/build/parser/save-writer.js +114 -0
- package/package.json +4 -3
- package/index.d.ts +0 -2356
- package/index.js +0 -2364
- package/rollup.config.mjs +0 -11
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Alignment } from "./byte/alignment.enum";
|
|
2
|
+
import { ByteWriter } from "./byte/byte-writer.class";
|
|
3
|
+
import { ChunkCompressionInfo, SatisfactorySave, SatisfactorySaveHeader } from "./satisfactory/satisfactory-save";
|
|
4
|
+
export declare class SaveWriter extends ByteWriter {
|
|
5
|
+
constructor();
|
|
6
|
+
static WriteHeader(writer: ByteWriter, header: SatisfactorySaveHeader): void;
|
|
7
|
+
static WriteLevels(writer: ByteWriter, save: SatisfactorySave, buildVersion: number): void;
|
|
8
|
+
static GenerateCompressedChunksFromData(bufferArray: ArrayBuffer, compressionInfo: ChunkCompressionInfo, onBinaryBeforeCompressing: (binary: ArrayBuffer) => void, onChunk: (chunk: Uint8Array) => void, onFinish: (summary: {
|
|
9
|
+
errors: string[];
|
|
10
|
+
chunkSummary: {
|
|
11
|
+
uncompressedSize: number;
|
|
12
|
+
compressedSize: number;
|
|
13
|
+
}[];
|
|
14
|
+
}) => void, alignment?: Alignment): void;
|
|
15
|
+
generateChunks(compressionInfo: ChunkCompressionInfo, posAfterHeader: number, onBinaryBeforeCompressing: (binary: ArrayBuffer) => void, onHeader: (header: Uint8Array) => void, onChunk: (chunk: Uint8Array) => void, onFinish: (summary: {
|
|
16
|
+
errors: string[];
|
|
17
|
+
chunkSummary: {
|
|
18
|
+
uncompressedSize: number;
|
|
19
|
+
compressedSize: number;
|
|
20
|
+
}[];
|
|
21
|
+
}) => void): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import Pako from "pako";
|
|
2
|
+
import { Alignment } from "./byte/alignment.enum";
|
|
3
|
+
import { ByteWriter } from "./byte/byte-writer.class";
|
|
4
|
+
import { ParserError, UnsupportedVersionError } from "./error/parser.error";
|
|
5
|
+
import { Level } from "./satisfactory/level.class";
|
|
6
|
+
export class SaveWriter extends ByteWriter {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(Alignment.LITTLE_ENDIAN);
|
|
9
|
+
}
|
|
10
|
+
static WriteHeader(writer, header) {
|
|
11
|
+
writer.writeInt32(header.saveHeaderType);
|
|
12
|
+
writer.writeInt32(header.saveVersion);
|
|
13
|
+
writer.writeInt32(header.buildVersion);
|
|
14
|
+
writer.writeString(header.mapName);
|
|
15
|
+
writer.writeString(header.mapOptions);
|
|
16
|
+
writer.writeString(header.sessionName);
|
|
17
|
+
writer.writeInt32(header.playDurationSeconds);
|
|
18
|
+
writer.writeInt64(BigInt(header.saveDateTime));
|
|
19
|
+
writer.writeByte(header.sessionVisibility);
|
|
20
|
+
if (header.saveHeaderType >= 7) {
|
|
21
|
+
writer.writeInt32(header.fEditorObjectVersion);
|
|
22
|
+
}
|
|
23
|
+
if (header.saveHeaderType >= 8) {
|
|
24
|
+
if (header.modMetadata) {
|
|
25
|
+
writer.writeString(JSON.stringify(header.modMetadata));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
writer.writeString(header.rawModMetadataString);
|
|
29
|
+
}
|
|
30
|
+
writer.writeInt32(header.isModdedSave);
|
|
31
|
+
}
|
|
32
|
+
if (header.saveHeaderType >= 10) {
|
|
33
|
+
writer.writeString(header.saveIdentifier);
|
|
34
|
+
}
|
|
35
|
+
if (header.saveVersion >= 21) {
|
|
36
|
+
// ready to write levels now.
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new UnsupportedVersionError("The save version is too old to be supported currently.");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
static WriteLevels(writer, save, buildVersion) {
|
|
43
|
+
writer.writeInt32(save.levels.length - 1);
|
|
44
|
+
for (const level of save.levels) {
|
|
45
|
+
if (level.name !== save.header.mapName) {
|
|
46
|
+
writer.writeString(level.name);
|
|
47
|
+
}
|
|
48
|
+
Level.WriteLevel(writer, level, buildVersion);
|
|
49
|
+
}
|
|
50
|
+
Level.SerializeCollectablesList(writer, save.trailingCollectedObjects);
|
|
51
|
+
}
|
|
52
|
+
static GenerateCompressedChunksFromData(bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, onFinish, alignment = Alignment.LITTLE_ENDIAN) {
|
|
53
|
+
const errors = [];
|
|
54
|
+
const totalUncompressedSize = bufferArray.byteLength;
|
|
55
|
+
const saveBody = new Uint8Array(bufferArray.byteLength + 4);
|
|
56
|
+
saveBody.set(new Uint8Array(bufferArray), 4);
|
|
57
|
+
const miniView = new DataView(saveBody.buffer);
|
|
58
|
+
miniView.setInt32(0, totalUncompressedSize, alignment === Alignment.LITTLE_ENDIAN);
|
|
59
|
+
onBinaryBeforeCompressing(saveBody.buffer);
|
|
60
|
+
// collect slices of chunks with help of compression info for max chunk size
|
|
61
|
+
let handledByte = 0;
|
|
62
|
+
const chunkSummary = [];
|
|
63
|
+
while (handledByte < saveBody.byteLength) {
|
|
64
|
+
// create uncompressed chunk.
|
|
65
|
+
const uncompressedContentSize = Math.min(compressionInfo.maxChunkContentSize, saveBody.byteLength - handledByte);
|
|
66
|
+
const uncompressedChunk = saveBody.buffer.slice(handledByte, handledByte + uncompressedContentSize);
|
|
67
|
+
// deflate chunk while we're at it.
|
|
68
|
+
let compressedChunk = new Uint8Array(0);
|
|
69
|
+
try {
|
|
70
|
+
compressedChunk = Pako.deflate(uncompressedChunk);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
errors.push("An error occurred while calling pako deflate. -> " + err);
|
|
74
|
+
}
|
|
75
|
+
const chunk = new Uint8Array(compressionInfo.chunkHeaderSize + compressedChunk.byteLength);
|
|
76
|
+
chunk.set(compressedChunk, compressionInfo.chunkHeaderSize);
|
|
77
|
+
// write header
|
|
78
|
+
const view = new DataView(chunk.buffer);
|
|
79
|
+
view.setInt32(0, compressionInfo.packageFileTag, alignment === Alignment.LITTLE_ENDIAN);
|
|
80
|
+
view.setInt32(4, 0, alignment === Alignment.LITTLE_ENDIAN);
|
|
81
|
+
view.setInt32(8, compressionInfo.maxChunkContentSize, alignment === Alignment.LITTLE_ENDIAN);
|
|
82
|
+
view.setInt32(12, 0, alignment === Alignment.LITTLE_ENDIAN);
|
|
83
|
+
view.setInt32(16, compressedChunk.byteLength, alignment === Alignment.LITTLE_ENDIAN);
|
|
84
|
+
view.setInt32(20, 0, alignment === Alignment.LITTLE_ENDIAN);
|
|
85
|
+
view.setInt32(24, uncompressedContentSize, alignment === Alignment.LITTLE_ENDIAN);
|
|
86
|
+
view.setInt32(28, 0, alignment === Alignment.LITTLE_ENDIAN);
|
|
87
|
+
view.setInt32(32, compressedChunk.byteLength, alignment === Alignment.LITTLE_ENDIAN);
|
|
88
|
+
view.setInt32(36, 0, alignment === Alignment.LITTLE_ENDIAN);
|
|
89
|
+
view.setInt32(40, uncompressedContentSize, alignment === Alignment.LITTLE_ENDIAN);
|
|
90
|
+
view.setInt32(44, 0, alignment === Alignment.LITTLE_ENDIAN);
|
|
91
|
+
onChunk(chunk);
|
|
92
|
+
chunkSummary.push({
|
|
93
|
+
uncompressedSize: uncompressedContentSize + compressionInfo.chunkHeaderSize,
|
|
94
|
+
compressedSize: compressedChunk.byteLength + compressionInfo.chunkHeaderSize
|
|
95
|
+
});
|
|
96
|
+
handledByte += uncompressedContentSize;
|
|
97
|
+
}
|
|
98
|
+
onFinish({
|
|
99
|
+
errors,
|
|
100
|
+
chunkSummary
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
generateChunks(compressionInfo, posAfterHeader, onBinaryBeforeCompressing, onHeader, onChunk, onFinish) {
|
|
104
|
+
if (posAfterHeader <= 0) {
|
|
105
|
+
throw new ParserError('ParserError', 'Seems like this buffer has no header. Please write the header first before you can generate chunks.');
|
|
106
|
+
}
|
|
107
|
+
// send plain header first.
|
|
108
|
+
const header = new Uint8Array(this.bufferArray.slice(0, posAfterHeader));
|
|
109
|
+
onHeader(header);
|
|
110
|
+
// create save body
|
|
111
|
+
this.bufferArray = this.bufferArray.slice(posAfterHeader);
|
|
112
|
+
SaveWriter.GenerateCompressedChunksFromData(this.bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, onFinish, this.alignment);
|
|
113
|
+
}
|
|
114
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etothepii/satisfactory-file-parser",
|
|
3
3
|
"author": "etothepii",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"description": "A file parser for satisfactory files. Includes save files and blueprint files.",
|
|
6
|
-
"main": "index.js",
|
|
6
|
+
"main": "build/index.js",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"keywords": [
|
|
8
9
|
"satisfactory",
|
|
9
10
|
"save",
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
"scripts": {
|
|
16
17
|
"test": "jest --config=jest.config.json",
|
|
17
18
|
"build": "tsc",
|
|
18
|
-
"prepublish": "
|
|
19
|
+
"prepublish": "npm version patch"
|
|
19
20
|
},
|
|
20
21
|
"repository": {
|
|
21
22
|
"type": "git",
|