@etothepii/satisfactory-file-parser 0.0.15 → 0.0.16
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 +10 -8
- package/build/index.js +10 -12
- package/build/parser/byte/byte-reader.class.d.ts +1 -38
- package/build/parser/byte/byte-reader.class.js +0 -11
- package/build/parser/byte/byte-writer.class.d.ts +1 -38
- package/build/parser/byte/byte-writer.class.js +0 -10
- package/build/parser/file.types.d.ts +9 -0
- package/build/parser/file.types.js +2 -0
- package/build/parser/parser.d.ts +12 -40
- package/build/parser/parser.js +51 -47
- package/build/parser/satisfactory/blueprint/blueprint-reader.d.ts +18 -0
- package/build/parser/satisfactory/blueprint/blueprint-reader.js +124 -0
- package/build/parser/satisfactory/blueprint/blueprint-writer.d.ts +15 -0
- package/build/parser/satisfactory/blueprint/blueprint-writer.js +63 -0
- package/build/parser/satisfactory/blueprint/blueprint.types.d.ts +20 -0
- package/build/parser/satisfactory/blueprint/blueprint.types.js +2 -0
- package/build/parser/satisfactory/objects/DataFields.d.ts +1 -1
- package/build/parser/satisfactory/objects/DataFields.js +0 -25
- package/build/parser/satisfactory/objects/Property.d.ts +1 -1
- package/build/parser/satisfactory/objects/Property.js +10 -159
- package/build/parser/satisfactory/save/level.class.d.ts +21 -0
- package/build/parser/satisfactory/save/level.class.js +138 -0
- package/build/parser/satisfactory/save/satisfactory-save.d.ts +11 -0
- package/build/parser/satisfactory/save/satisfactory-save.js +11 -0
- package/build/parser/satisfactory/save/save-reader.d.ts +44 -0
- package/build/parser/satisfactory/save/save-reader.js +233 -0
- package/build/parser/satisfactory/save/save-writer.d.ts +12 -0
- package/build/parser/satisfactory/save/save-writer.js +112 -0
- package/build/parser/satisfactory/save/save.types.d.ts +49 -0
- package/build/parser/satisfactory/save/save.types.js +2 -0
- package/package.json +6 -2
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BlueprintConfigWriter = exports.BlueprintWriter = void 0;
|
|
4
|
+
const alignment_enum_1 = require("../../byte/alignment.enum");
|
|
5
|
+
const byte_writer_class_1 = require("../../byte/byte-writer.class");
|
|
6
|
+
const parser_error_1 = require("../../error/parser.error");
|
|
7
|
+
const level_class_1 = require("../save/level.class");
|
|
8
|
+
const save_writer_1 = require("../save/save-writer");
|
|
9
|
+
const util_types_1 = require("../structs/util.types");
|
|
10
|
+
class BlueprintWriter extends byte_writer_class_1.ByteWriter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(alignment_enum_1.Alignment.LITTLE_ENDIAN);
|
|
13
|
+
}
|
|
14
|
+
static SerializeHeader(writer, header) {
|
|
15
|
+
writer.writeInt32(2);
|
|
16
|
+
writer.writeInt32(36);
|
|
17
|
+
writer.writeInt32(211839);
|
|
18
|
+
writer.writeInt32(4);
|
|
19
|
+
writer.writeInt32(4);
|
|
20
|
+
writer.writeInt32(4);
|
|
21
|
+
writer.writeInt32(header.itemCosts.length);
|
|
22
|
+
for (const itemCost of header.itemCosts) {
|
|
23
|
+
writer.writeInt32(0);
|
|
24
|
+
writer.writeString(itemCost[0]);
|
|
25
|
+
writer.writeInt32(itemCost[1]);
|
|
26
|
+
}
|
|
27
|
+
writer.writeInt32(header.recipeReferences.length);
|
|
28
|
+
for (const recipeReference of header.recipeReferences) {
|
|
29
|
+
writer.writeInt32(0);
|
|
30
|
+
writer.writeString(recipeReference);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
generateChunks(compressionInfo, posAfterHeader, onBinaryBeforeCompressing, onHeader, onChunk) {
|
|
34
|
+
if (posAfterHeader <= 0) {
|
|
35
|
+
throw new parser_error_1.ParserError('ParserError', 'seems like this buffer has no header. Please write the header first before you can generate chunks.');
|
|
36
|
+
}
|
|
37
|
+
const header = new Uint8Array(this.bufferArray.slice(0, posAfterHeader));
|
|
38
|
+
onHeader(header);
|
|
39
|
+
this.bufferArray = this.bufferArray.slice(posAfterHeader);
|
|
40
|
+
const chunkSummary = save_writer_1.SaveWriter.GenerateCompressedChunksFromData(this.bufferArray, compressionInfo, onBinaryBeforeCompressing, onChunk, this.alignment);
|
|
41
|
+
return chunkSummary;
|
|
42
|
+
}
|
|
43
|
+
static SerializeObjects(writer, objects) {
|
|
44
|
+
const headersLenIndicator = writer.getBufferPosition();
|
|
45
|
+
writer.writeInt32(0);
|
|
46
|
+
level_class_1.Level.SerializeObjectHeaders(writer, objects);
|
|
47
|
+
writer.writeBinarySizeFromPosition(headersLenIndicator, headersLenIndicator + 4);
|
|
48
|
+
level_class_1.Level.SerializeObjectContents(writer, objects, 0);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.BlueprintWriter = BlueprintWriter;
|
|
52
|
+
class BlueprintConfigWriter extends byte_writer_class_1.ByteWriter {
|
|
53
|
+
constructor() {
|
|
54
|
+
super(alignment_enum_1.Alignment.LITTLE_ENDIAN);
|
|
55
|
+
}
|
|
56
|
+
static SerializeConfig(writer, config) {
|
|
57
|
+
writer.writeInt32(2);
|
|
58
|
+
writer.writeString(config.description);
|
|
59
|
+
writer.writeInt32(config.iconID);
|
|
60
|
+
(0, util_types_1.SerializeCol4RGBA)(writer, config.color);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.BlueprintConfigWriter = BlueprintConfigWriter;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ChunkCompressionInfo } from "../../file.types";
|
|
2
|
+
import { SaveComponent } from "../objects/SaveComponent";
|
|
3
|
+
import { SaveEntity } from "../objects/SaveEntity";
|
|
4
|
+
import { col4 } from "../structs/util.types";
|
|
5
|
+
export interface BlueprintConfig {
|
|
6
|
+
description: string;
|
|
7
|
+
color: col4;
|
|
8
|
+
iconID: number;
|
|
9
|
+
}
|
|
10
|
+
export type BlueprintHeader = {
|
|
11
|
+
itemCosts: [string, number][];
|
|
12
|
+
recipeReferences: string[];
|
|
13
|
+
};
|
|
14
|
+
export interface Blueprint {
|
|
15
|
+
name: string;
|
|
16
|
+
compressionInfo: ChunkCompressionInfo;
|
|
17
|
+
header: BlueprintHeader;
|
|
18
|
+
config: BlueprintConfig;
|
|
19
|
+
objects: (SaveEntity | SaveComponent)[];
|
|
20
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ByteReader } from "../../byte/byte-reader.class";
|
|
2
|
-
import { SaveWriter } from "
|
|
2
|
+
import { SaveWriter } from "../save/save-writer";
|
|
3
3
|
import { AbstractBaseProperty } from "./Property";
|
|
4
4
|
export declare class DataFields {
|
|
5
5
|
properties: any[];
|
|
@@ -12,7 +12,6 @@ class DataFields {
|
|
|
12
12
|
const start = reader.getBufferPosition();
|
|
13
13
|
const fields = new DataFields();
|
|
14
14
|
if (length === 0) {
|
|
15
|
-
//WARNING
|
|
16
15
|
fields.shouldBeNulled = true;
|
|
17
16
|
return fields;
|
|
18
17
|
}
|
|
@@ -24,7 +23,6 @@ class DataFields {
|
|
|
24
23
|
}
|
|
25
24
|
let int1 = reader.readInt32();
|
|
26
25
|
if (int1 !== 0) {
|
|
27
|
-
//WARNING
|
|
28
26
|
}
|
|
29
27
|
const end = reader.getBufferPosition();
|
|
30
28
|
let remainingBytes = start + length - end;
|
|
@@ -36,18 +34,6 @@ class DataFields {
|
|
|
36
34
|
if (currentProperty.name === 'None') {
|
|
37
35
|
return null;
|
|
38
36
|
}
|
|
39
|
-
//TODO: What is this extra byte that is appearing sometime?
|
|
40
|
-
// i dont think there is an extra byte.
|
|
41
|
-
/*
|
|
42
|
-
let extraByteTest = reader.readByte();
|
|
43
|
-
if (extraByteTest !== 0) {
|
|
44
|
-
reader.currentByte -= 1;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
console.log('Property extra byte', currentProperty);
|
|
48
|
-
}
|
|
49
|
-
*/
|
|
50
|
-
//TODO assign type and index after parsing.
|
|
51
37
|
const propertyType = reader.readString();
|
|
52
38
|
const binarySize = reader.readInt32();
|
|
53
39
|
const index = reader.readInt32();
|
|
@@ -83,12 +69,6 @@ class DataFields {
|
|
|
83
69
|
currentProperty = Property_1.Int64Property.Parse(reader, propertyType, index);
|
|
84
70
|
overhead = Property_1.Int64Property.CalcOverhead(currentProperty);
|
|
85
71
|
break;
|
|
86
|
-
// TODO
|
|
87
|
-
/*
|
|
88
|
-
case 'UInt64Property':
|
|
89
|
-
currentProperty = Int64Property.Parse(reader, propertyType, index);
|
|
90
|
-
break;
|
|
91
|
-
*/
|
|
92
72
|
case 'SingleProperty':
|
|
93
73
|
case 'FloatProperty':
|
|
94
74
|
currentProperty = Property_1.FloatProperty.Parse(reader, propertyType, index);
|
|
@@ -121,7 +101,6 @@ class DataFields {
|
|
|
121
101
|
overhead = Property_1.ArrayProperty.CalcOverhead(currentProperty);
|
|
122
102
|
break;
|
|
123
103
|
case 'MapProperty':
|
|
124
|
-
//currentProperty = reader.readMapProperty(currentProperty, '');
|
|
125
104
|
currentProperty = Property_1.MapProperty.Parse(reader, propertyName, buildVersion, binarySize);
|
|
126
105
|
overhead = Property_1.MapProperty.CalcOverhead(currentProperty);
|
|
127
106
|
break;
|
|
@@ -154,10 +133,8 @@ class DataFields {
|
|
|
154
133
|
}
|
|
155
134
|
static SerializeProperty(writer, property, propertyName, buildVersion) {
|
|
156
135
|
writer.writeString(property.ueType);
|
|
157
|
-
// binary length indicator
|
|
158
136
|
const lenIndicator = writer.getBufferPosition();
|
|
159
137
|
writer.writeInt32(0);
|
|
160
|
-
// write index if it is not 0. Since it normally is.
|
|
161
138
|
writer.writeInt32(property.index ?? 0);
|
|
162
139
|
const start = writer.getBufferPosition();
|
|
163
140
|
let overhead = 0;
|
|
@@ -191,7 +168,6 @@ class DataFields {
|
|
|
191
168
|
overhead = Property_1.Int64Property.CalcOverhead(property);
|
|
192
169
|
Property_1.Int64Property.Serialize(writer, property);
|
|
193
170
|
break;
|
|
194
|
-
// TODO: uint64Property
|
|
195
171
|
case 'SingleProperty':
|
|
196
172
|
case 'FloatProperty':
|
|
197
173
|
overhead = Property_1.FloatProperty.CalcOverhead(property);
|
|
@@ -242,7 +218,6 @@ class DataFields {
|
|
|
242
218
|
default:
|
|
243
219
|
throw new Error(`Unimplemented type ${property.type}`);
|
|
244
220
|
}
|
|
245
|
-
// replace len indicator.
|
|
246
221
|
writer.writeBinarySizeFromPosition(lenIndicator, start + overhead);
|
|
247
222
|
}
|
|
248
223
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ByteReader } from "../../byte/byte-reader.class";
|
|
2
|
-
import { SaveWriter } from "
|
|
2
|
+
import { SaveWriter } from "../save/save-writer";
|
|
3
3
|
import { col4, vec3, vec4 } from "../structs/util.types";
|
|
4
4
|
import { ObjectReference } from "./ObjectReference";
|
|
5
5
|
export type Properties = {
|
|
@@ -12,7 +12,6 @@ class AbstractProperty {
|
|
|
12
12
|
}
|
|
13
13
|
exports.AbstractProperty = AbstractProperty;
|
|
14
14
|
class AbstractBaseProperty extends AbstractProperty {
|
|
15
|
-
// overhead like Guid is not calculated into property size
|
|
16
15
|
constructor(type, ueType, index) {
|
|
17
16
|
super(type, index && index !== 0 ? index : undefined);
|
|
18
17
|
this.ueType = ueType;
|
|
@@ -32,7 +31,7 @@ const ParseGUID = (reader) => {
|
|
|
32
31
|
let guid;
|
|
33
32
|
if (hasGuid) {
|
|
34
33
|
throw new Error('Unexpected!');
|
|
35
|
-
guid = reader.readBytes(16);
|
|
34
|
+
guid = reader.readBytes(16);
|
|
36
35
|
}
|
|
37
36
|
return guid;
|
|
38
37
|
};
|
|
@@ -378,7 +377,6 @@ class TextProperty extends BasicProperty {
|
|
|
378
377
|
this.value = value;
|
|
379
378
|
}
|
|
380
379
|
static Parse(reader, ueType, index = 0) {
|
|
381
|
-
//let name = reader.readString();
|
|
382
380
|
const guidInfo = (0, exports.ParseGUID)(reader);
|
|
383
381
|
const value = TextProperty.ParseValue(reader);
|
|
384
382
|
return new TextProperty(value, ueType, guidInfo, index);
|
|
@@ -389,15 +387,12 @@ class TextProperty extends BasicProperty {
|
|
|
389
387
|
historyType: reader.readByte()
|
|
390
388
|
};
|
|
391
389
|
switch (prop.historyType) {
|
|
392
|
-
// HISTORYTYPE_BASE
|
|
393
390
|
case 0:
|
|
394
391
|
prop.namespace = reader.readString();
|
|
395
392
|
prop.key = reader.readString();
|
|
396
393
|
prop.value = reader.readString();
|
|
397
394
|
break;
|
|
398
|
-
// HISTORYTYPE_NAMEDFORMAT
|
|
399
395
|
case 1:
|
|
400
|
-
// HISTORYTYPE_ARGUMENTFORMAT
|
|
401
396
|
case 3:
|
|
402
397
|
prop.sourceFmt = TextProperty.ParseValue(reader);
|
|
403
398
|
const argumentsCount = reader.readInt32();
|
|
@@ -416,22 +411,15 @@ class TextProperty extends BasicProperty {
|
|
|
416
411
|
prop.arguments.push(currentArgumentsData);
|
|
417
412
|
}
|
|
418
413
|
break;
|
|
419
|
-
// see https://github.com/EpicGames/UnrealEngine/blob/4.25/Engine/Source/Runtime/Core/Private/Internationalization/TextHistory.cpp#L2268
|
|
420
|
-
// HISTORYTYPE_TRANSFORM
|
|
421
414
|
case 10:
|
|
422
415
|
prop.sourceText = TextProperty.ParseValue(reader);
|
|
423
416
|
prop.transformType = reader.readByte();
|
|
424
417
|
break;
|
|
425
|
-
// HISTORYTYPE_NONE
|
|
426
418
|
case 255:
|
|
427
|
-
// See: https://github.com/EpicGames/UnrealEngine/blob/4.25/Engine/Source/Runtime/Core/Private/Internationalization/Text.cpp#L894
|
|
428
|
-
// TODO: do i need that? check with goz3rr
|
|
429
|
-
//if (this.header!.buildVersion >= 140822) {
|
|
430
419
|
prop.hasCultureInvariantString = reader.readInt32() === 1;
|
|
431
420
|
if (prop.hasCultureInvariantString) {
|
|
432
421
|
prop.value = reader.readString();
|
|
433
422
|
}
|
|
434
|
-
//}
|
|
435
423
|
break;
|
|
436
424
|
default:
|
|
437
425
|
throw new Error('Unimplemented historyType `' + prop.historyType);
|
|
@@ -449,15 +437,12 @@ class TextProperty extends BasicProperty {
|
|
|
449
437
|
writer.writeInt32(value.flags);
|
|
450
438
|
writer.writeByte(value.historyType);
|
|
451
439
|
switch (value.historyType) {
|
|
452
|
-
// HISTORYTYPE_BASE
|
|
453
440
|
case 0:
|
|
454
441
|
writer.writeString(value.namespace);
|
|
455
442
|
writer.writeString(value.key);
|
|
456
443
|
writer.writeString(value.value);
|
|
457
444
|
break;
|
|
458
|
-
// HISTORYTYPE_NAMEDFORMAT
|
|
459
445
|
case 1:
|
|
460
|
-
// HISTORYTYPE_ARGUMENTFORMAT
|
|
461
446
|
case 3:
|
|
462
447
|
TextProperty.SerializeValue(writer, value.sourceFmt);
|
|
463
448
|
writer.writeInt32(value.arguments.length);
|
|
@@ -474,22 +459,15 @@ class TextProperty extends BasicProperty {
|
|
|
474
459
|
}
|
|
475
460
|
}
|
|
476
461
|
break;
|
|
477
|
-
// see https://github.com/EpicGames/UnrealEngine/blob/4.25/Engine/Source/Runtime/Core/Private/Internationalization/TextHistory.cpp#L2268
|
|
478
|
-
// HISTORYTYPE_TRANSFORM
|
|
479
462
|
case 10:
|
|
480
463
|
TextProperty.SerializeValue(writer, value.sourceText);
|
|
481
464
|
writer.writeByte(value.transformType);
|
|
482
465
|
break;
|
|
483
|
-
// HISTORYTYPE_NONE
|
|
484
466
|
case 255:
|
|
485
|
-
// See: https://github.com/EpicGames/UnrealEngine/blob/4.25/Engine/Source/Runtime/Core/Private/Internationalization/Text.cpp#L894
|
|
486
|
-
// TODO: do i need that? check with goz3rr
|
|
487
|
-
//if (this.header!.buildVersion >= 140822) {
|
|
488
467
|
writer.writeInt32(value.hasCultureInvariantString ? 1 : 0);
|
|
489
468
|
if (value.hasCultureInvariantString) {
|
|
490
469
|
writer.writeString(value.value);
|
|
491
470
|
}
|
|
492
|
-
//}
|
|
493
471
|
break;
|
|
494
472
|
default:
|
|
495
473
|
throw new Error('Unimplemented historyType `' + value.historyType);
|
|
@@ -578,7 +556,6 @@ class StructProperty extends AbstractBaseProperty {
|
|
|
578
556
|
unk3: reader.readString(),
|
|
579
557
|
properties: [],
|
|
580
558
|
};
|
|
581
|
-
//TODO - what is this? currentProperty.value.properties.push(reader.readProperty());
|
|
582
559
|
break;
|
|
583
560
|
case 'FluidBox':
|
|
584
561
|
value = {
|
|
@@ -591,7 +568,6 @@ class StructProperty extends AbstractBaseProperty {
|
|
|
591
568
|
case 'DateTime':
|
|
592
569
|
value = reader.readLong().toString();
|
|
593
570
|
break;
|
|
594
|
-
// MODS
|
|
595
571
|
case 'FINNetworkTrace':
|
|
596
572
|
value = (0, exports.ReadFINNetworkTrace)(reader);
|
|
597
573
|
break;
|
|
@@ -600,14 +576,13 @@ class StructProperty extends AbstractBaseProperty {
|
|
|
600
576
|
values: (0, exports.ReadFINLuaProcessorStateStorage)(reader, size)
|
|
601
577
|
};
|
|
602
578
|
break;
|
|
603
|
-
case 'FICFrameRange':
|
|
579
|
+
case 'FICFrameRange':
|
|
604
580
|
value = {
|
|
605
581
|
begin: reader.readLong().toString(),
|
|
606
582
|
end: reader.readLong().toString(),
|
|
607
583
|
};
|
|
608
584
|
break;
|
|
609
585
|
default:
|
|
610
|
-
//TODO: use buildversion
|
|
611
586
|
value = (0, exports.ParseDynamicStructData)(reader, 0, subtype);
|
|
612
587
|
}
|
|
613
588
|
return value;
|
|
@@ -673,7 +648,6 @@ class StructProperty extends AbstractBaseProperty {
|
|
|
673
648
|
writer.writeString(value.itemName);
|
|
674
649
|
writer.writeString(value.unk2);
|
|
675
650
|
writer.writeString(value.unk3);
|
|
676
|
-
//TODO - how to write properties?
|
|
677
651
|
break;
|
|
678
652
|
case 'FluidBox':
|
|
679
653
|
value = value;
|
|
@@ -687,7 +661,6 @@ class StructProperty extends AbstractBaseProperty {
|
|
|
687
661
|
value = value;
|
|
688
662
|
writer.writeInt64(BigInt(value));
|
|
689
663
|
break;
|
|
690
|
-
// MODS
|
|
691
664
|
case 'FINNetworkTrace':
|
|
692
665
|
value = value;
|
|
693
666
|
(0, exports.SerializeFINNetworkTrace)(writer, value);
|
|
@@ -696,13 +669,12 @@ class StructProperty extends AbstractBaseProperty {
|
|
|
696
669
|
value = value;
|
|
697
670
|
(0, exports.SerializeFINLuaProcessorStateStorage)(writer, value.values);
|
|
698
671
|
break;
|
|
699
|
-
case 'FICFrameRange':
|
|
672
|
+
case 'FICFrameRange':
|
|
700
673
|
value = value;
|
|
701
674
|
writer.writeInt64(BigInt(value.begin));
|
|
702
675
|
writer.writeInt64(BigInt(value.end));
|
|
703
676
|
break;
|
|
704
677
|
default:
|
|
705
|
-
//TODO: use buildversion
|
|
706
678
|
value = value;
|
|
707
679
|
(0, exports.SerializeDynamicStructData)(writer, 0, value);
|
|
708
680
|
}
|
|
@@ -718,7 +690,7 @@ class ArrayProperty extends BasicProperty {
|
|
|
718
690
|
}
|
|
719
691
|
static Parse(reader, ueType, index, propertyName) {
|
|
720
692
|
const subtype = reader.readString();
|
|
721
|
-
reader.skipBytes();
|
|
693
|
+
reader.skipBytes();
|
|
722
694
|
let property;
|
|
723
695
|
const elementCount = reader.readInt32();
|
|
724
696
|
switch (subtype) {
|
|
@@ -754,10 +726,10 @@ class ArrayProperty extends BasicProperty {
|
|
|
754
726
|
property = new ArrayProperty(subtype, new Array(elementCount).fill(0).map(e => ObjectProperty.ReadValue(reader)), ueType, index);
|
|
755
727
|
break;
|
|
756
728
|
case "StructProperty":
|
|
757
|
-
const name = reader.readString();
|
|
758
|
-
const type = reader.readString();
|
|
759
|
-
const binarySize = reader.readInt32();
|
|
760
|
-
const allIndex = reader.readInt32();
|
|
729
|
+
const name = reader.readString();
|
|
730
|
+
const type = reader.readString();
|
|
731
|
+
const binarySize = reader.readInt32();
|
|
732
|
+
const allIndex = reader.readInt32();
|
|
761
733
|
const allStructType = reader.readString();
|
|
762
734
|
const allGuid = reader.readInt32();
|
|
763
735
|
const allUnk1 = reader.readInt32();
|
|
@@ -780,11 +752,6 @@ class ArrayProperty extends BasicProperty {
|
|
|
780
752
|
const before = reader.getBufferPosition();
|
|
781
753
|
const maArr = new Array(elementCount).fill(0).map(e => {
|
|
782
754
|
const struct = new StructProperty(allStructType, type, allIndex, allGuid);
|
|
783
|
-
// we do NOT assign individual unk's here. Since they are only serialized always on ArrayProperty's Level once for all elements.
|
|
784
|
-
//struct.unk1 = allUnk1;
|
|
785
|
-
//struct.unk2 = allUnk2;
|
|
786
|
-
//struct.unk3 = allUnk3;
|
|
787
|
-
//struct.unk4 = allUnk4;
|
|
788
755
|
struct.value = StructProperty.ParseValue(reader, allStructType, binarySize);
|
|
789
756
|
return struct;
|
|
790
757
|
});
|
|
@@ -792,7 +759,6 @@ class ArrayProperty extends BasicProperty {
|
|
|
792
759
|
if (readBytees !== binarySize) {
|
|
793
760
|
throw new Error('possibly corrupt in array of struct.');
|
|
794
761
|
}
|
|
795
|
-
// Array Properties with struct values have some more properties.
|
|
796
762
|
property = new ArrayProperty(subtype, maArr, ueType, index, innerStructValueFields);
|
|
797
763
|
break;
|
|
798
764
|
default:
|
|
@@ -871,8 +837,8 @@ class SetProperty extends BasicProperty {
|
|
|
871
837
|
}
|
|
872
838
|
static Parse(reader, ueType, index, propertyName) {
|
|
873
839
|
const subtype = reader.readString();
|
|
874
|
-
reader.skipBytes(1);
|
|
875
|
-
reader.skipBytes(4);
|
|
840
|
+
reader.skipBytes(1);
|
|
841
|
+
reader.skipBytes(4);
|
|
876
842
|
const elementCount = reader.readInt32();
|
|
877
843
|
let property;
|
|
878
844
|
switch (subtype) {
|
|
@@ -900,7 +866,6 @@ class SetProperty extends BasicProperty {
|
|
|
900
866
|
}
|
|
901
867
|
static Serialize(writer, property) {
|
|
902
868
|
writer.writeString(property.subtype);
|
|
903
|
-
//TODO: what is that
|
|
904
869
|
writer.writeByte(0);
|
|
905
870
|
writer.writeInt32(0);
|
|
906
871
|
writer.writeInt32(property.values.length);
|
|
@@ -915,7 +880,6 @@ class SetProperty extends BasicProperty {
|
|
|
915
880
|
property.values.forEach(v => StrProperty.SerializeValue(writer, v));
|
|
916
881
|
break;
|
|
917
882
|
case "StructProperty":
|
|
918
|
-
//TODO: this would only work for mRemovalLocations. Get a way to check for propertyname at least.
|
|
919
883
|
property.values.forEach(v => (0, util_types_1.SerializeVec3)(writer, v));
|
|
920
884
|
break;
|
|
921
885
|
default:
|
|
@@ -940,119 +904,7 @@ class MapProperty extends BasicProperty {
|
|
|
940
904
|
const property = new MapProperty(reader.readString(), reader.readString(), ueType, index);
|
|
941
905
|
reader.skipBytes(1);
|
|
942
906
|
property.modeType = reader.readInt32();
|
|
943
|
-
//property.remainingData = reader.readBytes(size - (reader.getBufferPosition() - start));
|
|
944
907
|
property.remainingData = Array.from(reader.readBytes(size - 4));
|
|
945
|
-
// TODO
|
|
946
|
-
/*
|
|
947
|
-
|
|
948
|
-
if (property.modeType === 2) {
|
|
949
|
-
property.modeUnk2 = reader.readString();
|
|
950
|
-
property.modeUnk3 = reader.readString();
|
|
951
|
-
} else if (property.modeType === 3) {
|
|
952
|
-
property.modeUnk1 = reader.readHex(9);
|
|
953
|
-
property.modeUnk2 = reader.readString();
|
|
954
|
-
property.modeUnk3 = reader.readString();
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
let elementCount = reader.readInt32();
|
|
958
|
-
for (let i = 0; i < elementCount; i++) {
|
|
959
|
-
let key: number | string | ObjectReferenceV2 | vec3 | any[] | boolean;
|
|
960
|
-
let value: number | string | ObjectReferenceV2 | any[] | boolean;
|
|
961
|
-
|
|
962
|
-
switch (property.keyType) {
|
|
963
|
-
case 'IntProperty':
|
|
964
|
-
key = Int32Property.ReadValue(reader);
|
|
965
|
-
break;
|
|
966
|
-
case 'Int64Property':
|
|
967
|
-
key = Int64Property.ReadValue(reader);
|
|
968
|
-
break;
|
|
969
|
-
case 'NameProperty':
|
|
970
|
-
case 'StrProperty':
|
|
971
|
-
key = StrProperty.ReadValue(reader);
|
|
972
|
-
break;
|
|
973
|
-
case 'ObjectProperty':
|
|
974
|
-
key = ObjectProperty.ReadValue(reader);
|
|
975
|
-
break;
|
|
976
|
-
case 'EnumProperty':
|
|
977
|
-
key = EnumProperty.ReadValue(reader);
|
|
978
|
-
break;
|
|
979
|
-
case 'StructProperty':
|
|
980
|
-
if (propertyName === 'Destroyed_Foliage_Transform' || parentType === '/BuildGunUtilities/BGU_Subsystem.BGU_Subsystem_C') // Mod: Universal Destroyer/Factory Statistics
|
|
981
|
-
{
|
|
982
|
-
key = ParseVec3(reader);
|
|
983
|
-
break;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
key = [];
|
|
987
|
-
while (true) {
|
|
988
|
-
let singleValueProperty = DataFieldsV2.ParseProperty(reader, buildVersion, propertyName);
|
|
989
|
-
if (singleValueProperty === null) {
|
|
990
|
-
break;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
key.push(singleValueProperty);
|
|
994
|
-
}
|
|
995
|
-
break;
|
|
996
|
-
default:
|
|
997
|
-
throw new Error(`not implemented type ${property.keyType}`);
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
switch (property.valueType) {
|
|
1002
|
-
case 'ByteProperty':
|
|
1003
|
-
if (property.keyType === 'StrProperty') {
|
|
1004
|
-
value = reader.readString();
|
|
1005
|
-
}
|
|
1006
|
-
else {
|
|
1007
|
-
value = reader.readByte();
|
|
1008
|
-
}
|
|
1009
|
-
break;
|
|
1010
|
-
case 'BoolProperty':
|
|
1011
|
-
value = BoolProperty.ReadValue(reader);
|
|
1012
|
-
break;
|
|
1013
|
-
case 'IntProperty':
|
|
1014
|
-
value = Int32Property.ReadValue(reader);
|
|
1015
|
-
break;
|
|
1016
|
-
case 'FloatProperty':
|
|
1017
|
-
value = FloatProperty.ReadValue(reader);
|
|
1018
|
-
break;
|
|
1019
|
-
case 'StrProperty':
|
|
1020
|
-
value = StrProperty.ReadValue(reader);
|
|
1021
|
-
break;
|
|
1022
|
-
case 'ObjectProperty':
|
|
1023
|
-
value = ObjectProperty.ReadValue(reader);
|
|
1024
|
-
break;
|
|
1025
|
-
case 'StructProperty':
|
|
1026
|
-
// TODO: what is this
|
|
1027
|
-
/*
|
|
1028
|
-
if (parentType === 'LBBalancerData') {
|
|
1029
|
-
mapPropertySubProperties.mNormalIndex = this.readInt32();
|
|
1030
|
-
mapPropertySubProperties.mOverflowIndex = this.readInt32();
|
|
1031
|
-
mapPropertySubProperties.mFilterIndex = this.readInt32();
|
|
1032
|
-
}
|
|
1033
|
-
else { }
|
|
1034
|
-
*/
|
|
1035
|
-
/*
|
|
1036
|
-
|
|
1037
|
-
value = [];
|
|
1038
|
-
while (true) {
|
|
1039
|
-
let singleValueProperty = DataFieldsV2.ParseProperty(reader, buildVersion, propertyName);
|
|
1040
|
-
if (singleValueProperty === null) {
|
|
1041
|
-
break;
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
value.push(singleValueProperty);
|
|
1045
|
-
}
|
|
1046
|
-
break;
|
|
1047
|
-
default:
|
|
1048
|
-
throw new Error(`not implemented type ${property.valueType}`);
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
property.values.push({
|
|
1052
|
-
key, value
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
*/
|
|
1056
908
|
return property;
|
|
1057
909
|
}
|
|
1058
910
|
static CalcOverhead(property) {
|
|
@@ -1064,7 +916,6 @@ property.values.push({
|
|
|
1064
916
|
writer.writeByte(0);
|
|
1065
917
|
writer.writeInt32(property.modeType);
|
|
1066
918
|
writer.writeBytesArray(property.remainingData);
|
|
1067
|
-
//TODO: do the actual serialization.
|
|
1068
919
|
}
|
|
1069
920
|
}
|
|
1070
921
|
exports.MapProperty = MapProperty;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ByteReader } from "../../byte/byte-reader.class";
|
|
2
|
+
import { ByteWriter } from "../../byte/byte-writer.class";
|
|
3
|
+
import { ObjectReference } from "../objects/ObjectReference";
|
|
4
|
+
import { SaveComponent } from "../objects/SaveComponent";
|
|
5
|
+
import { SaveEntity } from "../objects/SaveEntity";
|
|
6
|
+
import { SaveObject } from "../objects/SaveObject";
|
|
7
|
+
import { SaveReader } from "./save-reader";
|
|
8
|
+
export declare class Level {
|
|
9
|
+
name: string;
|
|
10
|
+
objects: (SaveEntity | SaveComponent)[];
|
|
11
|
+
collectables: ObjectReference[];
|
|
12
|
+
constructor(name: string);
|
|
13
|
+
static SerializeObjectHeaders(writer: ByteWriter, objects: (SaveEntity | SaveComponent)[]): void;
|
|
14
|
+
static WriteLevel(writer: ByteWriter, level: Level, buildVersion: number): void;
|
|
15
|
+
static SerializeObjectContents(writer: ByteWriter, objects: (SaveEntity | SaveComponent)[], buildVersion: number): void;
|
|
16
|
+
static ReadObjectHeaders(reader: ByteReader, objectsList: SaveObject[], onProgressCallback: (progress: number, msg?: string) => void): void;
|
|
17
|
+
static ReadObjectContents(reader: ByteReader, objectsList: SaveObject[], buildVersion: number, onProgressCallback: (progress: number, msg?: string) => void): void;
|
|
18
|
+
static ReadLevel(reader: SaveReader, levelName: string, buildVersion: number): Level;
|
|
19
|
+
static SerializeCollectablesList(writer: ByteWriter, collectables: ObjectReference[]): void;
|
|
20
|
+
static ReadCollectablesList(reader: SaveReader): ObjectReference[];
|
|
21
|
+
}
|