89 lines
3.7 KiB
C#
89 lines
3.7 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
|
|
using RobocraftX.Common;
|
|
using Svelto.DataStructures;
|
|
using Svelto.ECS;
|
|
using Svelto.ECS.Serialization;
|
|
|
|
using HarmonyLib;
|
|
using GamecraftModdingAPI.Utility;
|
|
|
|
namespace GamecraftModdingAPI.Persistence
|
|
{
|
|
[HarmonyPatch]
|
|
class DeserializeFromDiskEntitiesEnginePatch
|
|
{
|
|
internal static EntitiesDB entitiesDB = null;
|
|
|
|
private static readonly byte[] frameStart = Encoding.UTF8.GetBytes("\0\0\0GamecraftModdingAPI\0\0\0");
|
|
|
|
public static void Prefix(ref ISerializationData ____serializationData, ref FasterList<byte> ____bytesStream, ref IEntitySerialization ____entitySerializer, bool ____spawnBlocksOnly)
|
|
{
|
|
if (____spawnBlocksOnly) return; // only run after second deserialization call (when all vanilla stuff is already deserialized)
|
|
if (SaveAndLoadCompositionRootPatch.currentEnginesRoot == null) return;
|
|
SerializerManager.RegisterSerializers(SaveAndLoadCompositionRootPatch.currentEnginesRoot);
|
|
uint originalPos = ____serializationData.dataPos;
|
|
Logging.MetaDebugLog($"dataPos: {originalPos}");
|
|
BinaryBufferReader bbr = new BinaryBufferReader(____bytesStream.ToArrayFast(out uint count), ____serializationData.dataPos);
|
|
byte[] frameBuffer = new byte[frameStart.Length];
|
|
Logging.MetaDebugLog($"serial data count: {____serializationData.data.count} capacity: {____serializationData.data.capacity}");
|
|
int i = 0;
|
|
// match frame start
|
|
while (frameBuffer != frameStart && bbr.Position < count-frameStart.Length)
|
|
{
|
|
i = 0;
|
|
frameBuffer[0] = bbr.ReadByte();
|
|
while (frameBuffer[i] == frameStart[i] && bbr.Position < count - frameStart.Length + i)
|
|
{
|
|
i++;
|
|
if (i == frameStart.Length) break;
|
|
frameBuffer[i] = bbr.ReadByte();
|
|
}
|
|
if (i == frameStart.Length) break;
|
|
}
|
|
// abort if at end of file
|
|
if (bbr.Position >= count - frameStart.Length)
|
|
{
|
|
Logging.MetaLog("Skipping deserialization (no frame found)");
|
|
return;
|
|
}
|
|
//____serializationData.dataPos = bbr.Position;
|
|
Logging.MetaDebugLog($"dataPos (after frame): {bbr.Position}");
|
|
uint customComponentsCount = bbr.ReadUint();
|
|
for (uint c = 0; c < customComponentsCount; c++)
|
|
{
|
|
// determine component from info
|
|
uint nameLength = bbr.ReadUint();
|
|
byte[] nameBytes = new byte[nameLength];
|
|
bbr.ReadBytes(nameBytes, nameLength);
|
|
string name = Encoding.UTF8.GetString(nameBytes);
|
|
Logging.MetaDebugLog($"Component name: {name} (len: {nameLength})");
|
|
uint componentEnd = bbr.ReadUint();
|
|
____serializationData.dataPos = bbr.Position;
|
|
if (SerializerManager.ExistsSerializer(name))
|
|
{
|
|
// deserialize component
|
|
IEntitySerializer serial = SerializerManager.GetSerializer(name);
|
|
if (!serial.Deserialize(ref ____serializationData, ____entitySerializer))
|
|
{
|
|
Logging.MetaDebugLog("Component deserialization failed!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logging.MetaDebugLog("Skipping component deserialization: not found!");
|
|
}
|
|
bbr = new BinaryBufferReader(____bytesStream.ToArrayFast(out count), componentEnd);
|
|
}
|
|
____serializationData.dataPos = originalPos; // change back to original end point (just in case)
|
|
Logging.MetaDebugLog("Deserialization complete");
|
|
}
|
|
|
|
public static MethodBase TargetMethod()
|
|
{
|
|
return AccessTools.Method("RobocraftX.SaveAndLoad.DeserializeFromDiskEntitiesEngine:LoadingFinished");//AccessTools.TypeByName("RobocraftX.SaveAndLoad.DeserializeFromDiskEntities")
|
|
}
|
|
}
|
|
}
|