diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index cc80eed..f37e5c2 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -34,7 +34,7 @@ jobs:
with:
PROJECT_FILE_PATH: ./SatisfactorySaveNet.Abstracts/SatisfactorySaveNet.Abstracts.csproj
PACKAGE_NAME: SatisfactorySaveNet
- VERSION_STATIC: 0.0.12
+ VERSION_STATIC: 0.0.13
TAG_COMMIT: false
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
NUGET_SOURCE: https://api.nuget.org
@@ -45,7 +45,7 @@ jobs:
with:
PROJECT_FILE_PATH: ./SatisfactorySaveNet/SatisfactorySaveNet.csproj
PACKAGE_NAME: SatisfactorySaveNet
- VERSION_STATIC: 0.0.12
+ VERSION_STATIC: 0.0.13
TAG_COMMIT: false
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
NUGET_SOURCE: https://api.nuget.org
diff --git a/Directory.Build.props b/Directory.Build.props
index 10c7efc..235cdfd 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,7 +11,7 @@
false
false
- 0.0.12
+ 0.0.13
$(VersionPrefix)-$(VersionSuffix)
$(VersionPrefix)
diff --git a/SatisfactorySaveNet.Abstracts/Exceptions/BadReadException.cs b/SatisfactorySaveNet.Abstracts/Exceptions/BadReadException.cs
new file mode 100644
index 0000000..55e07fb
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Exceptions/BadReadException.cs
@@ -0,0 +1,24 @@
+using System.Runtime.Serialization;
+using System;
+
+namespace SatisfactorySaveNet.Abstracts.Exceptions;
+
+[Serializable]
+public class BadReadException : SatisFactoryException
+{
+ public BadReadException()
+ {
+ }
+
+ public BadReadException(string? message) : base(message)
+ {
+ }
+
+ public BadReadException(string? message, Exception? innerException) : base(message, innerException)
+ {
+ }
+
+ protected BadReadException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/BlueprintData.cs b/SatisfactorySaveNet.Abstracts/Extra/BlueprintData.cs
new file mode 100644
index 0000000..cb9c55e
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/BlueprintData.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Model.Extra;
+
+public class BlueprintData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.BlueprintData;
+
+ public int Count { get; set; }
+ public required ICollection Objects { get; set; }
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Extra/CargoObject.cs b/SatisfactorySaveNet.Abstracts/Extra/CargoObject.cs
new file mode 100644
index 0000000..a1b79e9
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/CargoObject.cs
@@ -0,0 +1,7 @@
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class CargoObject
+{
+ public string Name { get; set; } = string.Empty;
+ public string Unknown { get; set; } = string.Empty;
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/Circuit.cs b/SatisfactorySaveNet.Abstracts/Extra/Circuit.cs
new file mode 100644
index 0000000..30acbaf
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/Circuit.cs
@@ -0,0 +1,9 @@
+using SatisfactorySaveNet.Abstracts.Model;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class Circuit
+{
+ public int CircuitId { get; set; }
+ public required ObjectReference ObjectReference { get; set; }
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/CircuitData.cs b/SatisfactorySaveNet.Abstracts/Extra/CircuitData.cs
new file mode 100644
index 0000000..4b97c18
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/CircuitData.cs
@@ -0,0 +1,12 @@
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class CircuitData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.CircuitData;
+
+ public int Count { get; set; }
+ public required ICollection Circuits { get; set; }
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/ConveyorData.cs b/SatisfactorySaveNet.Abstracts/Extra/ConveyorData.cs
new file mode 100644
index 0000000..f2a1d11
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/ConveyorData.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Model.Extra;
+
+public class ConveyorData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.Conveyor;
+
+ public int Count { get; set; }
+ public required ICollection- Items { get; set; }
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Extra/DroneStationAction.cs b/SatisfactorySaveNet.Abstracts/Extra/DroneStationAction.cs
new file mode 100644
index 0000000..b14e587
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/DroneStationAction.cs
@@ -0,0 +1,10 @@
+using SatisfactorySaveNet.Abstracts.Model.Properties;
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class DroneStationAction
+{
+ public string Name { get; set; } = string.Empty;
+ public required ICollection Properties { get; set; }
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/DroneStationData.cs b/SatisfactorySaveNet.Abstracts/Extra/DroneStationData.cs
new file mode 100644
index 0000000..d2adb56
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/DroneStationData.cs
@@ -0,0 +1,21 @@
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class DroneStationData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.DroneStationData;
+
+ public int Unknown1 { get; set; }
+ public int Unknown2 { get; set; }
+ ///
+ /// Should only be null if Missing is filled, which indicates that there were unparseable data
+ ///
+ public ICollection? ActiveActions { get; set; }
+ ///
+ /// Should only be null if Missing is filled, which indicates that there were unparseable data
+ ///
+ public ICollection? ActionQueue { get; set; }
+ public string? Missing { get; set; }
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/ExtraData.cs b/SatisfactorySaveNet.Abstracts/Extra/ExtraData.cs
new file mode 100644
index 0000000..70f5897
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/ExtraData.cs
@@ -0,0 +1,6 @@
+namespace SatisfactorySaveNet.Abstracts.Model.Extra;
+
+public abstract class ExtraData
+{
+ public abstract ExtraDataConstraint Type { get; }
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Extra/ExtraDataConstraint.cs b/SatisfactorySaveNet.Abstracts/Extra/ExtraDataConstraint.cs
new file mode 100644
index 0000000..25b52bb
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/ExtraDataConstraint.cs
@@ -0,0 +1,14 @@
+namespace SatisfactorySaveNet.Abstracts.Model.Extra;
+
+public enum ExtraDataConstraint
+{
+ Conveyor,
+ BlueprintData,
+ PlayerData,
+ PowerLineData,
+ VehicleData,
+ LocomotiveData,
+ DroneStationData,
+ CircuitData,
+ UnknownExtraData
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Extra/LocomotiveData.cs b/SatisfactorySaveNet.Abstracts/Extra/LocomotiveData.cs
new file mode 100644
index 0000000..27a3a80
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/LocomotiveData.cs
@@ -0,0 +1,15 @@
+using SatisfactorySaveNet.Abstracts.Model;
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class LocomotiveData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.LocomotiveData;
+
+ public int Count { get; set; }
+ public required ICollection CargoObjects { get; set; }
+ public required ObjectReference Previous { get; set; }
+ public required ObjectReference Next { get; set; }
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/PlayerData.cs b/SatisfactorySaveNet.Abstracts/Extra/PlayerData.cs
new file mode 100644
index 0000000..1532d0b
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/PlayerData.cs
@@ -0,0 +1,12 @@
+namespace SatisfactorySaveNet.Abstracts.Model.Extra;
+
+public class PlayerData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.PlayerData;
+
+ public string? Missing { get; set; }
+ public byte PlayerType { get; set; }
+ public string? EpicOnlineServicesId { get; set; }
+ public string? SteamId { get; set; }
+ public string? PlatformId { get; set; }
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Extra/PowerLineData.cs b/SatisfactorySaveNet.Abstracts/Extra/PowerLineData.cs
new file mode 100644
index 0000000..07b184c
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/PowerLineData.cs
@@ -0,0 +1,16 @@
+using SatisfactorySaveNet.Abstracts.Maths.Vector;
+using SatisfactorySaveNet.Abstracts.Model;
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class PowerLineData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.PowerLineData;
+
+ public int Count { get; set; }
+ public required ObjectReference Source { get; set; }
+ public required ObjectReference Target { get; set; }
+ public Vector3? SourceTranslation { get; set; }
+ public Vector3? TargetTranslation { get; set;}
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/UnknownExtraData.cs b/SatisfactorySaveNet.Abstracts/Extra/UnknownExtraData.cs
new file mode 100644
index 0000000..bc5172a
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/UnknownExtraData.cs
@@ -0,0 +1,10 @@
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class UnknownExtraData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.UnknownExtraData;
+
+ public string Missing { get; set; } = string.Empty;
+}
diff --git a/SatisfactorySaveNet.Abstracts/Extra/VehicleData.cs b/SatisfactorySaveNet.Abstracts/Extra/VehicleData.cs
new file mode 100644
index 0000000..2756313
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Extra/VehicleData.cs
@@ -0,0 +1,12 @@
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+using System.Collections.Generic;
+
+namespace SatisfactorySaveNet.Abstracts.Extra;
+
+public class VehicleData : ExtraData
+{
+ public override ExtraDataConstraint Type => ExtraDataConstraint.VehicleData;
+
+ public int Count { get; set; }
+ public required ICollection CargoObjects { get; set; }
+}
diff --git a/SatisfactorySaveNet.Abstracts/IExtraDataSerializer.cs b/SatisfactorySaveNet.Abstracts/IExtraDataSerializer.cs
new file mode 100644
index 0000000..46b272b
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/IExtraDataSerializer.cs
@@ -0,0 +1,10 @@
+using SatisfactorySaveNet.Abstracts.Model;
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+using System.IO;
+
+namespace SatisfactorySaveNet.Abstracts;
+
+public interface IExtraDataSerializer
+{
+ public ExtraData? Deserialize(BinaryReader reader, string typePath, Header header, long expectedPosition);
+}
diff --git a/SatisfactorySaveNet.Abstracts/IPropertySerializer.cs b/SatisfactorySaveNet.Abstracts/IPropertySerializer.cs
index b5d6756..251da14 100644
--- a/SatisfactorySaveNet.Abstracts/IPropertySerializer.cs
+++ b/SatisfactorySaveNet.Abstracts/IPropertySerializer.cs
@@ -7,6 +7,6 @@ namespace SatisfactorySaveNet.Abstracts;
public interface IPropertySerializer
{
- public IEnumerable DeserializeProperties(BinaryReader reader, Header? header = null, string? type = null);
+ public IEnumerable DeserializeProperties(BinaryReader reader, Header? header = null, string? type = null, long? expectedPosition = null);
public Property? DeserializeProperty(BinaryReader reader, Header? header = null, string? type = null);
}
diff --git a/SatisfactorySaveNet.Abstracts/ITypedDataSerializer.cs b/SatisfactorySaveNet.Abstracts/ITypedDataSerializer.cs
index 0f04895..4ad00be 100644
--- a/SatisfactorySaveNet.Abstracts/ITypedDataSerializer.cs
+++ b/SatisfactorySaveNet.Abstracts/ITypedDataSerializer.cs
@@ -6,5 +6,5 @@ namespace SatisfactorySaveNet.Abstracts;
public interface ITypedDataSerializer
{
- public TypedData Deserialize(BinaryReader reader, Header header, string type);
+ public TypedData Deserialize(BinaryReader reader, Header header, string type, bool isArrayProperty);
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/ActorObject.cs b/SatisfactorySaveNet.Abstracts/Model/ActorObject.cs
index 755f9a9..123e97b 100644
--- a/SatisfactorySaveNet.Abstracts/Model/ActorObject.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/ActorObject.cs
@@ -22,5 +22,5 @@ public class ActorObject : ComponentObject
public string ParentObjectRoot { get; set; } = string.Empty;
public string ParentObjectName { get; set; } = string.Empty;
- public IList Components { get; set; } = [];
+ public ICollection Components { get; set; } = [];
}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Model/Body.cs b/SatisfactorySaveNet.Abstracts/Model/Body.cs
index a596edc..3e995a9 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Body.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Body.cs
@@ -8,7 +8,7 @@ public class Body
///
/// Levels and the persistent level. There is one more level than the level count above, the last entry being the persistent level (See SCIM). For the format of one level
///
- public IList Levels { get; set; } = [];
+ public ICollection Levels { get; set; } = [];
///
/// Unknown grid related data
@@ -19,5 +19,5 @@ public class Body
/// A list of object references, can also be ignored. for the format of one such ObjectReference
///
[Obsolete("These information seem to be obsolete")]
- public IList? ObjectReferences { get; set; }
+ public ICollection? ObjectReferences { get; set; }
}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Model/ComponentObject.cs b/SatisfactorySaveNet.Abstracts/Model/ComponentObject.cs
index 496e5d4..9e0f5ff 100644
--- a/SatisfactorySaveNet.Abstracts/Model/ComponentObject.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/ComponentObject.cs
@@ -1,3 +1,4 @@
+using SatisfactorySaveNet.Abstracts.Model.Extra;
using SatisfactorySaveNet.Abstracts.Model.Properties;
using System.Collections.Generic;
@@ -14,6 +15,7 @@ public class ComponentObject
public string ParentActorName { get; set; } = string.Empty;
- public IList Properties { get; set; } = [];
+ public ICollection Properties { get; set; } = [];
+ public ExtraData? ExtraData { get; set; }
public int? EntitySaveVersion { get; set; }
}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Model/Grid.cs b/SatisfactorySaveNet.Abstracts/Model/Grid.cs
index 09a95ce..ff09170 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Grid.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Grid.cs
@@ -9,5 +9,5 @@ public class Grid
public int Unknown3 { get; set; }
public string Unknown4 { get; set; } = string.Empty;
public int Unknown5 { get; set; }
- public IList Data { get; set; } = [];
+ public ICollection Data { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/GridData.cs b/SatisfactorySaveNet.Abstracts/Model/GridData.cs
index c2f234e..12c7394 100644
--- a/SatisfactorySaveNet.Abstracts/Model/GridData.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/GridData.cs
@@ -7,5 +7,5 @@ public class GridData
public string Unknown1 { get; set; } = string.Empty;
public int Unknown2 { get; set; }
public int Unknown3 { get; set; }
- public IList Levels { get; set; } = [];
+ public ICollection Levels { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Item.cs b/SatisfactorySaveNet.Abstracts/Model/Item.cs
new file mode 100644
index 0000000..fba650b
--- /dev/null
+++ b/SatisfactorySaveNet.Abstracts/Model/Item.cs
@@ -0,0 +1,14 @@
+using SatisfactorySaveNet.Abstracts.Maths.Vector;
+
+namespace SatisfactorySaveNet.Abstracts.Model;
+
+public class Item
+{
+ public string Name { get; set; } = string.Empty;
+ public required ObjectReference ObjectReference { get; set; }
+ ///
+ /// Supposed to be a float, but Vec4 seems to be logical?
+ ///
+ public Vector4I Position { get; set; }
+ public int Length { get; set; }
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Model/Level.cs b/SatisfactorySaveNet.Abstracts/Model/Level.cs
index 129ab6d..03c2288 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Level.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Level.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model;
@@ -6,8 +6,8 @@ namespace SatisfactorySaveNet.Abstracts.Model;
public class Level
{
public string Name { get; set; } = string.Empty;
- public IList Collectables { get; set; } = [];
- public IList Objects { get; set; } = [];
+ public ICollection Collectables { get; set; } = [];
+ public ICollection Objects { get; set; } = [];
[Obsolete("These information seem to be obsolete")]
- public IList? SecondCollectables { get; set; } = [];
+ public ICollection? SecondCollectables { get; set; } = [];
}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayBoolProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayBoolProperty.cs
index c89cba0..42e75bc 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayBoolProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayBoolProperty.cs
@@ -7,5 +7,5 @@ public class ArrayBoolProperty : IArrayProperty
///
/// Values[x] != 0 <=> True
///
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayByteProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayByteProperty.cs
index 7e14d10..e24ddef 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayByteProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayByteProperty.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayByteProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayDoubleProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayDoubleProperty.cs
index a252f05..17c9d63 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayDoubleProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayDoubleProperty.cs
@@ -3,5 +3,5 @@ namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayDoubleProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayEnumProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayEnumProperty.cs
index 01f915b..b9336bb 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayEnumProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayEnumProperty.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayEnumProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayFloatProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayFloatProperty.cs
index cb581cb..b3b6bf6 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayFloatProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayFloatProperty.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayFloatProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInt64Property.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInt64Property.cs
index a3760c0..aba5474 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInt64Property.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInt64Property.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayInt64Property : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayIntProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayIntProperty.cs
index 52c7bf9..afbe3a1 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayIntProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayIntProperty.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayIntProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInterfaceProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInterfaceProperty.cs
index 5851ee7..c107ed1 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInterfaceProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayInterfaceProperty.cs
@@ -3,5 +3,5 @@ namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayInterfaceProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayObjectProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayObjectProperty.cs
index 46da97b..5ed3913 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayObjectProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayObjectProperty.cs
@@ -1,8 +1,8 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayObjectProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArraySoftObjectProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArraySoftObjectProperty.cs
index 7d70666..a163930 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArraySoftObjectProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArraySoftObjectProperty.cs
@@ -4,5 +4,5 @@ namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArraySoftObjectProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStrProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStrProperty.cs
index 142a6cc..771fb07 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStrProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStrProperty.cs
@@ -1,7 +1,7 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayStrProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStructProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStructProperty.cs
index 030a396..346135f 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStructProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayStructProperty.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace SatisfactorySaveNet.Abstracts.Model.Properties;
@@ -8,5 +8,5 @@ public class ArrayStructProperty : IArrayProperty
public string PropertyType { get; set; } = string.Empty;
public (int, int, int, int) UUID { get; set; } = new(0, 0, 0, 0);
public string ElementType { get; set; } = string.Empty;
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayTextProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayTextProperty.cs
index 86ad673..4cc7e4c 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayTextProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/ArrayTextProperty.cs
@@ -4,5 +4,5 @@ namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class ArrayTextProperty : IArrayProperty
{
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/FINNetworkProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/FINNetworkProperty.cs
index 1f753b4..a551593 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/FINNetworkProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/FINNetworkProperty.cs
@@ -2,8 +2,7 @@ namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class FINNetworkProperty : Property
{
- public string LevelName { get; set; } = string.Empty; //ToDo: ObjectReference
- public string PathName { get; set; } = string.Empty;
+ public required ObjectReference ObjectReference { get; set; }
public FINNetworkProperty? Previous { get; set; }
public string? Step { get; set; }
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Properties/SetProperty.cs b/SatisfactorySaveNet.Abstracts/Model/Properties/SetProperty.cs
index dbba4d4..44be587 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Properties/SetProperty.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Properties/SetProperty.cs
@@ -6,5 +6,5 @@ namespace SatisfactorySaveNet.Abstracts.Model.Properties;
public class SetProperty : Property
{
public string Type { get; set; } = string.Empty;
- public IList Elements { get; set; } = [];
+ public ICollection Elements { get; set; } = [];
}
\ No newline at end of file
diff --git a/SatisfactorySaveNet.Abstracts/Model/TypedData/ArrayProperties.cs b/SatisfactorySaveNet.Abstracts/Model/TypedData/ArrayProperties.cs
index 42087f5..10064a7 100644
--- a/SatisfactorySaveNet.Abstracts/Model/TypedData/ArrayProperties.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/TypedData/ArrayProperties.cs
@@ -7,6 +7,6 @@ public class ArrayProperties : TypedData
{
public override TypedDataConstraint Type => TypedDataConstraint.ArrayProperties;
- public IList Values { get; set; } = [];
+ public ICollection Values { get; set; } = [];
public string TypeName { get; set; } = string.Empty;
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/TypedData/FINGPUT1Buffer.cs b/SatisfactorySaveNet.Abstracts/Model/TypedData/FINGPUT1Buffer.cs
index 802588f..0c15963 100644
--- a/SatisfactorySaveNet.Abstracts/Model/TypedData/FINGPUT1Buffer.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/TypedData/FINGPUT1Buffer.cs
@@ -11,6 +11,6 @@ public class FINGPUT1Buffer : TypedData
public string Name { get; set; } = string.Empty;
public string TypeName { get; set; } = string.Empty;
public int Length { get; set; }
- public IList Buffer { get; set; } = [];
+ public ICollection Buffer { get; set; } = [];
public string Unknown { get; set; } = string.Empty;
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/TypedData/FINLuaProcessorStateStorage.cs b/SatisfactorySaveNet.Abstracts/Model/TypedData/FINLuaProcessorStateStorage.cs
index c34fe7b..5d77c79 100644
--- a/SatisfactorySaveNet.Abstracts/Model/TypedData/FINLuaProcessorStateStorage.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/TypedData/FINLuaProcessorStateStorage.cs
@@ -6,9 +6,9 @@ public class FINLuaProcessorStateStorage : TypedData
{
public override TypedDataConstraint Type => TypedDataConstraint.FINLuaProcessorStateStorage;
- public IList Traces { get; set; } = [];
- public IList ObjectReferences { get; set; } = [];
+ public ICollection Traces { get; set; } = [];
+ public ICollection ObjectReferences { get; set; } = [];
public string Thread { get; set; } = string.Empty;
public string Globals { get; set; } = string.Empty;
- public IList TypedData { get; set; } = [];
+ public ICollection TypedData { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/TypedData/FactoryCustomizationColorSlot.cs b/SatisfactorySaveNet.Abstracts/Model/TypedData/FactoryCustomizationColorSlot.cs
index 1fb1ede..152b28c 100644
--- a/SatisfactorySaveNet.Abstracts/Model/TypedData/FactoryCustomizationColorSlot.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/TypedData/FactoryCustomizationColorSlot.cs
@@ -7,5 +7,5 @@ public class FactoryCustomizationColorSlot : TypedData
{
public override TypedDataConstraint Type => TypedDataConstraint.FactoryCustomizationColorSlot;
- public IList Properties { get; set; } = [];
+ public ICollection Properties { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/TypedData/SpawnData.cs b/SatisfactorySaveNet.Abstracts/Model/TypedData/SpawnData.cs
index 23e4619..10efa32 100644
--- a/SatisfactorySaveNet.Abstracts/Model/TypedData/SpawnData.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/TypedData/SpawnData.cs
@@ -7,5 +7,5 @@ public class SpawnData : TypedData
{
public override TypedDataConstraint Type => TypedDataConstraint.SpawnData;
- public IList Properties { get; set; } = [];
+ public ICollection Properties { get; set; } = [];
}
diff --git a/SatisfactorySaveNet.Abstracts/Model/Union/FINNetworkUnion.cs b/SatisfactorySaveNet.Abstracts/Model/Union/FINNetworkUnion.cs
index ff36adf..b22be4f 100644
--- a/SatisfactorySaveNet.Abstracts/Model/Union/FINNetworkUnion.cs
+++ b/SatisfactorySaveNet.Abstracts/Model/Union/FINNetworkUnion.cs
@@ -5,5 +5,5 @@ namespace SatisfactorySaveNet.Abstracts.Model.Union;
public class FINNetworkUnion : UnionBase
{
public override UnionConstraint Type => UnionConstraint.FINNetwork;
- public FINNetworkProperty Value { get; set; } = new();
+ public required FINNetworkProperty Value { get; set; }
}
diff --git a/SatisfactorySaveNet/BodySerializer.cs b/SatisfactorySaveNet/BodySerializer.cs
index 3d91187..7f7fef8 100644
--- a/SatisfactorySaveNet/BodySerializer.cs
+++ b/SatisfactorySaveNet/BodySerializer.cs
@@ -129,6 +129,7 @@ public BodySerializer(IStringSerializer stringSerializer, IObjectHeaderSerialize
}
var binarySizeObjects = header.SaveVersion >= 41 ? reader.ReadInt64() : reader.ReadInt32();
+ var positionStart = reader.BaseStream.Position;
var nrObjects = reader.ReadInt32();
if (nrObjects != nrObjectHeaders)
@@ -139,6 +140,10 @@ public BodySerializer(IStringSerializer stringSerializer, IObjectHeaderSerialize
objects[j] = _objectSerializer.Deserialize(reader, header, objects[j]);
}
+ var expectedPosition = positionStart + binarySizeObjects;
+ if (expectedPosition != reader.BaseStream.Position)
+ throw new BadReadException("Expected stream position does not match actual position");
+
var nrSecondCollectables = reader.ReadInt32();
var secondCollectables = new List(nrSecondCollectables);
diff --git a/SatisfactorySaveNet/ExtraDataSerializer.cs b/SatisfactorySaveNet/ExtraDataSerializer.cs
new file mode 100644
index 0000000..e29b206
--- /dev/null
+++ b/SatisfactorySaveNet/ExtraDataSerializer.cs
@@ -0,0 +1,363 @@
+using SatisfactorySaveNet.Abstracts;
+using SatisfactorySaveNet.Abstracts.Extra;
+using SatisfactorySaveNet.Abstracts.Maths.Vector;
+using SatisfactorySaveNet.Abstracts.Model;
+using SatisfactorySaveNet.Abstracts.Model.Extra;
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace SatisfactorySaveNet;
+
+public class ExtraDataSerializer : IExtraDataSerializer
+{
+ public static readonly IExtraDataSerializer Instance = new ExtraDataSerializer(StringSerializer.Instance, ObjectReferenceSerializer.Instance, VectorSerializer.Instance, HexSerializer.Instance, PropertySerializer.Instance);
+
+ private readonly IStringSerializer _stringSerializer;
+ private readonly IObjectReferenceSerializer _objectReferenceSerializer;
+ private readonly IVectorSerializer _vectorSerializer;
+ private readonly IHexSerializer _hexSerializer;
+ private readonly IPropertySerializer _propertySerializer;
+
+ public ExtraDataSerializer(IStringSerializer stringSerializer, IObjectReferenceSerializer objectReferenceSerializer, IVectorSerializer vectorSerializer, IHexSerializer hexSerializer, IPropertySerializer propertySerializer)
+ {
+ _stringSerializer = stringSerializer;
+ _objectReferenceSerializer = objectReferenceSerializer;
+ _vectorSerializer = vectorSerializer;
+ _hexSerializer = hexSerializer;
+ _propertySerializer = propertySerializer;
+ }
+
+ public ExtraData? Deserialize(BinaryReader reader, string typePath, Header header, long expectedPosition)
+ {
+ if (KnownConstants.IsConveyor(typePath))
+ return DeserializeConveyor(reader);
+ if (KnownConstants.IsPowerLine(typePath))
+ return DeserializePowerLine(reader, header);
+ if (KnownConstants.IsVehicle(typePath))
+ return DeserializeVehicle(reader, header);
+ if (KnownConstants.IsLocomotive(typePath) || KnownConstants.IsFreightWagon(typePath))
+ return DeserializeLocomotiveData(reader, header);
+
+ return typePath switch
+ {
+ "/Game/FactoryGame/-Shared/Blueprint/BP_GameState.BP_GameState_C" or "/Game/FactoryGame/-Shared/Blueprint/BP_GameMode.BP_GameMode_C" => DeserializeBlueprint(reader),
+ "/Game/FactoryGame/Character/Player/BP_PlayerState.BP_PlayerState_C" => DeserializePlayerData(reader, expectedPosition),
+ "/Game/FactoryGame/Buildable/Factory/DroneStation/BP_DroneTransport.BP_DroneTransport_C" => DeserializeDroneStation(reader, header, expectedPosition),
+ "/Game/FactoryGame/-Shared/Blueprint/BP_CircuitSubsystem.BP_CircuitSubsystem_C" => DeserializeCircuitData(reader),
+ _ => DeserializeUnknownData(reader, header, typePath, expectedPosition),
+ };
+ }
+
+ private UnknownExtraData? DeserializeUnknownData(BinaryReader reader, Header header, string typePath, long expectedPosition)
+ {
+ var bytesCount = expectedPosition - reader.BaseStream.Position;
+
+ if (bytesCount > 4)
+ {
+ if (header.SaveVersion >= 41 && typePath.StartsWith("/Script/FactoryGame.FG", StringComparison.Ordinal))
+ reader.BaseStream.Seek(8, SeekOrigin.Current);
+ else
+ {
+ var missing = _hexSerializer.Deserialize(reader, (int) bytesCount);
+
+ return new UnknownExtraData
+ {
+ Missing = missing,
+ };
+ }
+ }
+ else
+ {
+ reader.BaseStream.Seek(4, SeekOrigin.Current);
+ }
+
+ return null;
+ }
+
+ private CircuitData DeserializeCircuitData(BinaryReader reader)
+ {
+ var count = reader.ReadInt32();
+ var nrElements = reader.ReadInt32();
+ var circuits = new Circuit[nrElements];
+
+ for (var x = 0; x < nrElements; x++)
+ {
+ var circuitId = reader.ReadInt32();
+ var objectReference = _objectReferenceSerializer.Deserialize(reader);
+
+ circuits[x] = new Circuit
+ {
+ CircuitId = circuitId,
+ ObjectReference = objectReference
+ };
+ }
+
+ return new CircuitData
+ {
+ Count = count,
+ Circuits = circuits
+ };
+ }
+
+ private DroneStationData DeserializeDroneStation(BinaryReader reader, Header header, long expectedPosition)
+ {
+ if (header.SaveVersion >= 41)
+ {
+ var unknown1 = reader.ReadInt32();
+ var unknown2 = reader.ReadInt32();
+
+ var nrActiveActions = reader.ReadInt32();
+ var activeActions = new DroneStationAction[nrActiveActions];
+
+ for (var x = 0; x < nrActiveActions; x++)
+ {
+ var name = _stringSerializer.Deserialize(reader);
+ var properties = _propertySerializer.DeserializeProperties(reader, header).ToArray();
+
+ activeActions[x] = new DroneStationAction
+ {
+ Properties = properties,
+ Name = name
+ };
+ }
+
+ var nrQueuedActions = reader.ReadInt32();
+ var queuedActions = new DroneStationAction[nrQueuedActions];
+
+ for (var x = 0; x < nrQueuedActions; x++)
+ {
+ var name = _stringSerializer.Deserialize(reader);
+ var properties = _propertySerializer.DeserializeProperties(reader, header).ToArray();
+
+ queuedActions[x] = new DroneStationAction
+ {
+ Properties = properties,
+ Name = name
+ };
+ }
+
+ return new DroneStationData
+ {
+ ActionQueue = queuedActions,
+ ActiveActions = activeActions,
+ Unknown1 = unknown1,
+ Unknown2 = unknown2,
+ };
+ }
+
+ var bytesCount = expectedPosition - reader.BaseStream.Position;
+ var missing = _hexSerializer.Deserialize(reader, (int)bytesCount);
+
+ return new DroneStationData
+ {
+ Missing = missing
+ };
+ }
+
+ private PlayerData? DeserializePlayerData(BinaryReader reader, long expectedPosition)
+ {
+ var bytesCount = expectedPosition - reader.BaseStream.Position;
+ var playerData = new PlayerData();
+
+ if (bytesCount > 0)
+ {
+ var missing = _hexSerializer.Deserialize(reader, (int)bytesCount);
+ reader.BaseStream.Seek(-bytesCount, SeekOrigin.Current);
+ _ = reader.ReadInt32();
+ var mode = reader.ReadByte();
+
+ playerData.PlayerType = mode;
+
+ switch (mode)
+ {
+ case 241:
+ _ = reader.ReadByte();
+
+ var nrElements1 = reader.ReadInt32();
+ var sb1 = new StringBuilder();
+
+ for (var x = 0; x < nrElements1; x++)
+ {
+ sb1.Append(reader.ReadByte().ToString("X2"));
+ }
+
+ playerData.EpicOnlineServicesId = sb1.ToString().TrimStart('0'); //.Substring(1, 32);
+ return playerData;
+ case 248:
+ var value = _stringSerializer.Deserialize(reader);
+ playerData.EpicOnlineServicesId = value.Split("|")[0];
+ return playerData;
+ case 249:
+ _ = _stringSerializer.Deserialize(reader);
+ break;
+ case 17:
+ var nrElements2 = reader.ReadByte();
+ var sb2 = new StringBuilder();
+
+ for (var x = 0; x < nrElements2; x++)
+ {
+ sb2.Append(reader.ReadByte().ToString("X2"));
+ }
+
+ playerData.EpicOnlineServicesId = sb2.ToString().TrimStart('0');
+ return playerData;
+ case 25:
+ case 29:
+ var nrElements3 = reader.ReadByte();
+ var sb3 = new StringBuilder();
+
+ for (var x = 0; x < nrElements3; x++)
+ {
+ sb3.Append(reader.ReadByte().ToString("X2"));
+ }
+
+ playerData.SteamId = sb3.ToString().TrimStart('0');
+ return playerData;
+ case 8:
+ playerData.PlatformId = _stringSerializer.Deserialize(reader);
+ return playerData;
+ default:
+ playerData.Missing = missing;
+ reader.BaseStream.Seek(-5, SeekOrigin.Current);
+ break;
+ }
+
+ return playerData;
+ }
+
+ return null;
+ }
+
+ private BlueprintData DeserializeBlueprint(BinaryReader reader)
+ {
+ var count = reader.ReadInt32();
+ var nrElements = reader.ReadInt32();
+ var objectReferences = new ObjectReference[nrElements];
+
+ for (var x = 0; x < nrElements; x++)
+ {
+ objectReferences[x] = _objectReferenceSerializer.Deserialize(reader);
+ }
+
+ return new BlueprintData
+ {
+ Count = count,
+ Objects = objectReferences
+ };
+ }
+
+ private ConveyorData DeserializeConveyor(BinaryReader reader)
+ {
+ var count = reader.ReadInt32();
+ var nrElements = reader.ReadInt32();
+
+ var items = new Item[nrElements];
+
+ for (var x = 0; x < nrElements; x++)
+ {
+ var length = reader.ReadInt32();
+ var name = _stringSerializer.Deserialize(reader);
+ var objectReference = _objectReferenceSerializer.Deserialize(reader);
+ var position = VectorSerializer.Instance.DeserializeVec4B(reader);
+
+ items[x] = new Item
+ {
+ Name = name,
+ ObjectReference = objectReference,
+ Position = position,
+ Length = length
+ };
+ }
+
+ return new ConveyorData
+ {
+ Items = items,
+ Count = count
+ };
+ }
+
+ private LocomotiveData DeserializeLocomotiveData(BinaryReader reader, Header header)
+ {
+ var count = reader.ReadInt32();
+ var nrElements = reader.ReadInt32();
+ var vehicleObjects = new CargoObject[nrElements];
+
+ var unknownSize = header.SaveVersion >= 41 ? 105 : 53;
+
+ for (var x = 0; x < nrElements; x++)
+ {
+ var name = _stringSerializer.Deserialize(reader);
+ var unknown = _hexSerializer.Deserialize(reader, unknownSize);
+
+ vehicleObjects[x] = new CargoObject
+ {
+ Name = name,
+ Unknown = unknown,
+ };
+ }
+
+ var previous = _objectReferenceSerializer.Deserialize(reader);
+ var next = _objectReferenceSerializer.Deserialize(reader);
+
+ return new LocomotiveData
+ {
+ Count = count,
+ CargoObjects = vehicleObjects,
+ Previous = previous,
+ Next = next
+ };
+ }
+
+ private PowerLineData DeserializePowerLine(BinaryReader reader, Header header)
+ {
+ var count = reader.ReadInt32();
+ var source = _objectReferenceSerializer.Deserialize(reader);
+ var target = _objectReferenceSerializer.Deserialize(reader);
+ Vector3? sourceTranslation = null;
+ Vector3? targetTranslation = null;
+
+ if (header.SaveVersion >= 33 && header.SaveVersion < 41)
+ {
+ sourceTranslation = _vectorSerializer.DeserializeVec3(reader);
+ targetTranslation = _vectorSerializer.DeserializeVec3(reader);
+ }
+
+ return new PowerLineData
+ {
+ Count = count,
+ Source = source,
+ Target = target,
+ SourceTranslation = sourceTranslation,
+ TargetTranslation = targetTranslation
+ };
+ }
+
+ private VehicleData DeserializeVehicle(BinaryReader reader, Header header)
+ {
+ var count = reader.ReadInt32();
+ var nrElements = reader.ReadInt32();
+ var vehicleObjects = new CargoObject[nrElements];
+
+ var unknownSize = header.SaveVersion >= 41 ? 105 : 53;
+
+ for (var x = 0; x < nrElements; x++)
+ {
+ var name = _stringSerializer.Deserialize(reader);
+ var unknown = _hexSerializer.Deserialize(reader, unknownSize);
+
+ vehicleObjects[x] = new CargoObject
+ {
+ Name = name,
+ Unknown = unknown,
+ };
+ }
+
+ return new VehicleData
+ {
+ Count = count,
+ CargoObjects = vehicleObjects
+ };
+ }
+}
\ No newline at end of file
diff --git a/SatisfactorySaveNet/KnownConstants.cs b/SatisfactorySaveNet/KnownConstants.cs
index c8e223e..51b76f5 100644
--- a/SatisfactorySaveNet/KnownConstants.cs
+++ b/SatisfactorySaveNet/KnownConstants.cs
@@ -1,17 +1,22 @@
-using System;
-using System.Collections.Generic;
+using System;
+using System.Collections.Frozen;
+using System.Linq;
namespace SatisfactorySaveNet;
public static class KnownConstants
{
- public static readonly IReadOnlySet ConveyorBelts = new HashSet(StringComparer.Ordinal)
+ public static readonly FrozenSet ConveyorBelts = new[]
{
"/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk1/Build_ConveyorBeltMk1.Build_ConveyorBeltMk1_C",
"/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk2/Build_ConveyorBeltMk2.Build_ConveyorBeltMk2_C",
"/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk3/Build_ConveyorBeltMk3.Build_ConveyorBeltMk3_C",
"/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk4/Build_ConveyorBeltMk4.Build_ConveyorBeltMk4_C",
- "/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk5/Build_ConveyorBeltMk5.Build_ConveyorBeltMk5_C",
+ "/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk5/Build_ConveyorBeltMk5.Build_ConveyorBeltMk5_C"
+ }.ToFrozenSet(StringComparer.Ordinal);
+
+ public static readonly string[] ModConveyorBelts =
+ [
"/Conveyors_Mod/Build_BeltMk",
"/Game/Conveyors_Mod/Build_BeltMk",
"/UltraFastLogistics/Buildable/build_conveyorbeltMK",
@@ -19,15 +24,19 @@ public static class KnownConstants
"/conveyorbeltmod/Belt/mk",
"/minerplus/content/buildable/Factory/belt_",
"/bamfp/content/buildable/Factory/belt_"
- };
+ ];
- public static readonly IReadOnlySet ConveyorLifts = new HashSet(StringComparer.Ordinal)
+ public static readonly FrozenSet ConveyorLifts = new[]
{
"/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk1/Build_ConveyorLiftMk1.Build_ConveyorLiftMk1_C",
"/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk2/Build_ConveyorLiftMk2.Build_ConveyorLiftMk2_C",
"/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk3/Build_ConveyorLiftMk3.Build_ConveyorLiftMk3_C",
"/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk4/Build_ConveyorLiftMk4.Build_ConveyorLiftMk4_C",
- "/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk5/Build_ConveyorLiftMk5.Build_ConveyorLiftMk5_C",
+ "/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk5/Build_ConveyorLiftMk5.Build_ConveyorLiftMk5_C"
+ }.ToFrozenSet(StringComparer.Ordinal);
+
+ public static readonly string[] ModConveyorLifts =
+ [
"/minerplus/content/buildable/Factory/lift",
"/bamfp/content/buildable/Factory/lift",
"/Game/Conveyors_Mod/Build_LiftMk",
@@ -35,20 +44,97 @@ public static class KnownConstants
"/Game/CoveredConveyor",
"/CoveredConveyor",
"/conveyorbeltmod/lift/"
- };
+ ];
+
+ public static readonly FrozenSet PowerLines = new[]
+ {
+ "/Game/FactoryGame/Buildable/Factory/PowerLine/Build_PowerLine.Build_PowerLine_C",
+ "/Game/FactoryGame/Events/Christmas/Buildings/PowerLineLights/Build_XmassLightsLine.Build_XmassLightsLine_C"
+ }.ToFrozenSet(StringComparer.Ordinal);
+
+ public static readonly string[] ModPowerLines =
+ [
+ "/FlexSplines/PowerLine/Build_FlexPowerline.Build_FlexPowerline_C",
+ "/AB_CableMod/Visuals1/Build_AB-PLCopper.Build_AB-PLCopper_C",
+ "/AB_CableMod/Visuals1/Build_AB-PLCaterium.Build_AB-PLCaterium_C",
+ "/AB_CableMod/Visuals3/Build_AB-PLHeavy.Build_AB-PLHeavy_C",
+ "/AB_CableMod/Visuals4/Build_AB-SPLight.Build_AB-SPLight_C",
+ "/AB_CableMod/Visuals3/Build_AB-PLPaintable.Build_AB-PLPaintable_C",
+ "/AB_CableMod/Cables_Heavy/Build_AB-PLHeavy-Cu.Build_AB-PLHeavy-Cu_C",
+ "/AB_CableMod/Cables_Standard/Build_AB-PLStandard-Cu.Build_AB-PLStandard-Cu_C",
+ "/AB_CableMod/Cables_Wire/Build_AB-PLWire-Si.Build_AB-PLWire-Si_C",
+ "/AB_CableMod/Cables_Wire/Build_AB-PLWire-Au.Build_AB-PLWire-Au_C"
+ ];
+
+ public static readonly FrozenSet Vehicles = new[]
+ {
+ "/Game/FactoryGame/Buildable/Vehicle/Tractor/BP_Tractor.BP_Tractor_C",
+ "/Game/FactoryGame/Buildable/Vehicle/Truck/BP_Truck.BP_Truck_C",
+ "/Game/FactoryGame/Buildable/Vehicle/Explorer/BP_Explorer.BP_Explorer_C",
+ "/Game/FactoryGame/Buildable/Vehicle/Cyberwagon/Testa_BP_WB.Testa_BP_WB_C",
+ "/Game/FactoryGame/Buildable/Vehicle/Golfcart/BP_Golfcart.BP_Golfcart_C",
+ "/Game/FactoryGame/Buildable/Vehicle/Golfcart/BP_GolfcartGold.BP_GolfcartGold_C"
+ }.ToFrozenSet(StringComparer.Ordinal);
+
+ public static readonly string[] ModVehicles =
+ [
+ "/x3_mavegrag/Vehicles/Trucks/TruckMk1/BP_X3Truck_Mk1.BP_X3Truck_Mk1_C"
+ ];
+
+ public static readonly FrozenSet Locomotives = new[]
+ {
+ "/Game/FactoryGame/Buildable/Vehicle/Train/Locomotive/BP_Locomotive.BP_Locomotive_C"
+ }.ToFrozenSet(StringComparer.Ordinal);
+
+ public static readonly string[] ModLocomotives =
+ [
+ "/x3_mavegrag/Vehicles/Trains/Locomotive_Mk1/BP_X3Locomotive_Mk1.BP_X3Locomotive_Mk1_C",
+ "/DI_Transportation_Darkplate/Trains/Locomotive/DI_Locomotive_400/Build_DI_Locomotive_400.Build_DI_Locomotive_400_C"
+ ];
+
+ public static readonly FrozenSet FreightWagon = new[]
+ {
+ "/Game/FactoryGame/Buildable/Vehicle/Train/Wagon/BP_FreightWagon.BP_FreightWagon_C"
+ }.ToFrozenSet(StringComparer.Ordinal);
+
+ public static readonly string[] ModFreightWagon =
+ [
+ "/x3_mavegrag/Vehicles/Trains/CargoWagon_Mk1/BP_X3CargoWagon_Mk1.BP_X3CargoWagon_Mk1_C",
+ "/DI_Transportation_Darkplate/Trains/Wagon/DI_Wagon_512/Build_DI_FrieghtWagon512.Build_DI_FrieghtWagon512_C"
+ ];
public static bool IsConveyorLift(string path)
{
- return ConveyorLifts.Contains(path);
+ return ConveyorLifts.Contains(path) || ModConveyorLifts.Any(x => x.StartsWith(path, StringComparison.Ordinal));
}
public static bool IsConveyorBelt(string path)
{
- return ConveyorBelts.Contains(path);
+ return ConveyorBelts.Contains(path) || ModConveyorBelts.Any(x => x.StartsWith(path, StringComparison.Ordinal));
}
public static bool IsConveyor(string path)
{
return IsConveyorLift(path) || IsConveyorBelt(path);
}
+
+ public static bool IsPowerLine(string path)
+ {
+ return PowerLines.Contains(path) || ModPowerLines.Any(x => x.StartsWith(path, StringComparison.Ordinal));
+ }
+
+ public static bool IsVehicle(string path)
+ {
+ return Vehicles.Contains(path) || ModVehicles.Any(x => x.StartsWith(path, StringComparison.Ordinal));
+ }
+
+ public static bool IsLocomotive(string path)
+ {
+ return Locomotives.Contains(path) || ModLocomotives.Any(x => x.StartsWith(path, StringComparison.Ordinal));
+ }
+
+ public static bool IsFreightWagon(string path)
+ {
+ return FreightWagon.Contains(path) || ModFreightWagon.Any(x => x.StartsWith(path, StringComparison.Ordinal));
+ }
}
\ No newline at end of file
diff --git a/SatisfactorySaveNet/ObjectSerializer.cs b/SatisfactorySaveNet/ObjectSerializer.cs
index b58f83c..4c0ed22 100644
--- a/SatisfactorySaveNet/ObjectSerializer.cs
+++ b/SatisfactorySaveNet/ObjectSerializer.cs
@@ -10,17 +10,19 @@ namespace SatisfactorySaveNet;
public class ObjectSerializer : IObjectSerializer
{
- public static readonly IObjectSerializer Instance = new ObjectSerializer(StringSerializer.Instance, ObjectReferenceSerializer.Instance, PropertySerializer.Instance);
+ public static readonly IObjectSerializer Instance = new ObjectSerializer(StringSerializer.Instance, ObjectReferenceSerializer.Instance, PropertySerializer.Instance, ExtraDataSerializer.Instance);
private readonly IStringSerializer _stringSerializer;
private readonly IObjectReferenceSerializer _objectReferenceSerializer;
private readonly IPropertySerializer _propertySerializer;
+ private readonly IExtraDataSerializer _extraDataSerializer;
- public ObjectSerializer(IStringSerializer stringSerializer, IObjectReferenceSerializer objectReferenceSerializer, IPropertySerializer propertySerializer)
+ public ObjectSerializer(IStringSerializer stringSerializer, IObjectReferenceSerializer objectReferenceSerializer, IPropertySerializer propertySerializer, IExtraDataSerializer extraDataSerializer)
{
_stringSerializer = stringSerializer;
_objectReferenceSerializer = objectReferenceSerializer;
_propertySerializer = propertySerializer;
+ _extraDataSerializer = extraDataSerializer;
}
public ComponentObject Deserialize(BinaryReader reader, Header header, ComponentObject componentObject)
@@ -62,24 +64,25 @@ private ActorObject DeserializeActor(BinaryReader reader, Header header, ActorOb
actorObject.ParentObjectName = parentObjectName;
var expectedPosition = positionStart + binarySize;
+ actorObject.Components = components;
if (expectedPosition == reader.BaseStream.Position)
return actorObject;
- var properties = _propertySerializer.DeserializeProperties(reader, header).ToList();
+ var properties = _propertySerializer.DeserializeProperties(reader, header, expectedPosition: expectedPosition).ToList();
- actorObject.Components = components;
actorObject.Properties = properties;
+ actorObject.ExtraData = _extraDataSerializer.Deserialize(reader, actorObject.TypePath, header, expectedPosition);
var missingBytes = expectedPosition - reader.BaseStream.Position;
if (missingBytes > 4)
{
var binary = reader.ReadBytes(Cast(missingBytes));
- //var hex = new string(binary.Select(Convert.ToChar).ToArray());
+ var hex = new string(binary.Select(Convert.ToChar).ToArray());
}
else
- reader.BaseStream.Seek(4, SeekOrigin.Current);
+ reader.BaseStream.Seek(missingBytes, SeekOrigin.Current);
return actorObject;
}
@@ -113,10 +116,10 @@ private ComponentObject DeserializeComponent(BinaryReader reader, Header header,
if (missingBytes > 4)
{
var binary = reader.ReadBytes(Cast(missingBytes));
- //var hex = new string(binary.Select(Convert.ToChar).ToArray());
+ var hex = new string(binary.Select(Convert.ToChar).ToArray());
}
else
- reader.BaseStream.Seek(4, SeekOrigin.Current);
+ reader.BaseStream.Seek(missingBytes, SeekOrigin.Current);
return componentObject;
}
diff --git a/SatisfactorySaveNet/PropertySerializer.cs b/SatisfactorySaveNet/PropertySerializer.cs
index e757136..be0d41d 100644
--- a/SatisfactorySaveNet/PropertySerializer.cs
+++ b/SatisfactorySaveNet/PropertySerializer.cs
@@ -5,6 +5,7 @@
using SatisfactorySaveNet.Abstracts.Model.Union;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
@@ -42,11 +43,19 @@ public PropertySerializer(IStringSerializer stringSerializer, IObjectReferenceSe
_softObjectReferenceSerializer = softObjectReferenceSerializer;
}
- public IEnumerable DeserializeProperties(BinaryReader reader, Header? header = null, string? type = null)
+ public IEnumerable DeserializeProperties(BinaryReader reader, Header? header = null, string? type = null, long? expectedPosition = null)
{
+ if (expectedPosition != null && expectedPosition < reader.BaseStream.Position)
+ yield break;
+
Property? property;
while ((property = DeserializeProperty(reader, header, type)) != null)
+ {
yield return property;
+
+ if (expectedPosition != null && expectedPosition < reader.BaseStream.Position)
+ yield break;
+ }
}
[return: NotNullIfNotNull(nameof(type))]
@@ -58,11 +67,9 @@ public IEnumerable DeserializeProperties(BinaryReader reader, Header?
{
propertyName = _stringSerializer.Deserialize(reader);
- if (string.Equals(propertyName, "None", StringComparison.Ordinal))
+ if (string.Equals(propertyName, "None", StringComparison.Ordinal) || string.IsNullOrWhiteSpace(propertyName))
return null;
- //if (reader.ReadByte() != 0) reader.BaseStream.Seek(-1, SeekOrigin.Current); //ToDo: Dead code?
-
type = _stringSerializer.Deserialize(reader);
}
@@ -332,23 +339,6 @@ private ArrayProperty DeserializeArrayProperty(BinaryReader reader, Header heade
private TextProperty DeserializeTextProperty(BinaryReader reader, Header header)
{
- //var binarySize = reader.ReadInt32();
- //var index = reader.ReadInt32();
- //var padding = reader.ReadSByte();
- //var flags = reader.ReadInt32();
- //var historyType = reader.ReadSByte();
- //var isCultureInvariant = reader.ReadInt32() != 0;
- //var value = _stringSerializer.Deserialize(reader);
- //
- //return new TextProperty
- //{
- // Index = index,
- // Flags = flags,
- // HistoryType = historyType,
- // IsCultureInvariant = isCultureInvariant,
- // Value = value,
- //};
-
var binarySize = reader.ReadInt32();
var index = reader.ReadInt32();
var padding = reader.ReadSByte();
@@ -436,7 +426,6 @@ private ArrayStructProperty DeserializeArrayStructProperty(BinaryReader reader,
var propertyType = _stringSerializer.Deserialize(reader);
var binarySize = reader.ReadInt32();
- var startPosition = reader.BaseStream.Position;
var padding1 = reader.ReadInt32();
var elementType = _stringSerializer.Deserialize(reader);
@@ -446,13 +435,11 @@ private ArrayStructProperty DeserializeArrayStructProperty(BinaryReader reader,
var uuid4 = reader.ReadInt32();
var padding2 = reader.ReadSByte();
- var endPosition = startPosition + binarySize;
-
var values = new TypedData[length];
for (var x = 0; x < length; x++)
{
- values[x] = _typedDataSerializer.Deserialize(reader, header, elementType);
+ values[x] = _typedDataSerializer.Deserialize(reader, header, elementType, true);
}
var property = new ArrayStructProperty
@@ -866,8 +853,7 @@ private SetProperty DeserializeSetProperty(BinaryReader reader, string propertyN
private FINNetworkProperty DeserializeFINNetworkProperty(BinaryReader reader)
{
- var levelName = _stringSerializer.Deserialize(reader); //ToDo: ObjectReference
- var pathName = _stringSerializer.Deserialize(reader);
+ var objectReference = _objectReferenceSerializer.Deserialize(reader);
FINNetworkProperty? previous = null;
string? step = null;
if (reader.ReadInt32() == 1)
@@ -875,7 +861,7 @@ private FINNetworkProperty DeserializeFINNetworkProperty(BinaryReader reader)
if (reader.ReadInt32() == 1)
step = _stringSerializer.Deserialize(reader);
- return new FINNetworkProperty { LevelName = levelName, PathName = pathName, Previous = previous, Step = step };
+ return new FINNetworkProperty { ObjectReference = objectReference, Previous = previous, Step = step };
}
private StrProperty DeserializeStrProperty(BinaryReader reader)
@@ -897,13 +883,12 @@ private StrProperty DeserializeStrProperty(BinaryReader reader)
private StructProperty DeserializeStructProperty(BinaryReader reader, Header header)
{
var binarySize = reader.ReadInt32();
- var startPosition = reader.BaseStream.Position;
var index = reader.ReadInt32();
var type = _stringSerializer.Deserialize(reader);
var padding1 = reader.ReadInt64();
var padding2 = reader.ReadInt64();
var padding3 = reader.ReadSByte();
- var typedData = _typedDataSerializer.Deserialize(reader, header, type);
+ var typedData = _typedDataSerializer.Deserialize(reader, header, type, false);
var property = new StructProperty
{
diff --git a/SatisfactorySaveNet/TypedDataSerializer.cs b/SatisfactorySaveNet/TypedDataSerializer.cs
index d2e24f1..8417586 100644
--- a/SatisfactorySaveNet/TypedDataSerializer.cs
+++ b/SatisfactorySaveNet/TypedDataSerializer.cs
@@ -38,7 +38,7 @@ public TypedDataSerializer(IVectorSerializer vectorSerializer, IStringSerializer
_objectReferenceSerializer = objectReferenceSerializer;
}
- public TypedData Deserialize(BinaryReader reader, Header header, string type)
+ public TypedData Deserialize(BinaryReader reader, Header header, string type, bool isArrayProperty)
{
return type switch
{
@@ -53,7 +53,7 @@ public TypedData Deserialize(BinaryReader reader, Header header, string type)
nameof(RailroadTrackPosition) => DeserializeRailroadTrackPosition(reader),
nameof(TimerHandle) => DeserializeTimerHandle(reader),
nameof(Guid) => DeserializeGuid(reader),
- nameof(InventoryItem) => DeserializeInventoryItem(reader, header),
+ nameof(InventoryItem) => DeserializeInventoryItem(reader, header, isArrayProperty),
nameof(FluidBox) => DeserializeFluidBox(reader),
nameof(SlateBrush) => DeserializeSlateBrush(reader),
nameof(DateTime) => DeserializeDateTime(reader),
@@ -386,6 +386,7 @@ private LinearColor DeserializeLinearColor(BinaryReader reader)
};
}
+ //Seems to be dead code
private TypedData DeserializeInventoryStack(BinaryReader reader, Header header)
{
if (header.SaveVersion >= 42)
@@ -426,7 +427,7 @@ private TypedData DeserializeInventoryStack(BinaryReader reader, Header header)
}
}
- private InventoryItem DeserializeInventoryItem(BinaryReader reader, Header header)
+ private InventoryItem DeserializeInventoryItem(BinaryReader reader, Header header, bool isArrayProperty)
{
var padding = reader.ReadInt32();
var itemType = _stringSerializer.Deserialize(reader);
@@ -438,7 +439,10 @@ private InventoryItem DeserializeInventoryItem(BinaryReader reader, Header heade
else
unknown1 = _stringSerializer.Deserialize(reader);
- var property = _propertySerializer.DeserializeProperty(reader, header);
+ Property? property = null;
+
+ if (!isArrayProperty)
+ property = _propertySerializer.DeserializeProperty(reader, header);
return new InventoryItem
{