TechbloxModdingAPI/GamecraftModdingAPI/Persistence/SaveGameEnginePatch.cs
2020-05-15 17:42:04 -04:00

82 lines
3.2 KiB
C#

using System;
using System.Text;
using System.Reflection;
using RobocraftX.Common;
using RobocraftX.SaveAndLoad;
using Svelto.DataStructures;
using Svelto.ECS;
using Svelto.ECS.Serialization;
using GamecraftModdingAPI.Utility;
using HarmonyLib;
namespace GamecraftModdingAPI.Persistence
{
[HarmonyPatch]
class SaveGameEnginePatch
{
private static readonly byte[] frameStart = Encoding.UTF8.GetBytes("\0\0\0GamecraftModdingAPI\0\0\0");
public static void Postfix(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer)
{
Logging.MetaDebugLog("Running Postfix on SerializeGameToBuffer: serializing custom components...");
if (SerializerManager.GetSerializersCount() == 0)
{
Logging.MetaDebugLog("Skipping component serialization: no serializers registered!");
return;
}
serializationData.data.ExpandBy((uint)frameStart.Length);
BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out uint buffLen), serializationData.dataPos);
uint originalPos = serializationData.dataPos;
Logging.MetaDebugLog($"dataPos: {originalPos}");
// Add frame start so it's easier to find GamecraftModdingAPI-serialized components
for (int i = 0; i < frameStart.Length; i++)
{
bbw.Write(frameStart[i]);
}
Logging.MetaDebugLog($"dataPos (after frame start): {bbw.Position}");
serializationData.data.ExpandBy(4u);
bbw.Write((uint)SerializerManager.GetSerializersCount());
string[] serializerKeys = SerializerManager.GetSerializerNames();
for (uint c = 0; c < serializerKeys.Length; c++)
{
Logging.MetaDebugLog($"dataPos (loop start): {bbw.Position}");
// write component info
serializationData.data.ExpandBy(4u + (uint)serializerKeys[c].Length);
bbw.Write((uint)serializerKeys[c].Length);
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
byte[] nameBytes = Encoding.UTF8.GetBytes(serializerKeys[c]);
for (int i = 0; i < nameBytes.Length; i++)
{
bbw.Write(nameBytes[i]);
}
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
serializationData.data.ExpandBy(4u);
serializationData.dataPos = bbw.Position + 4u;
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
Logging.MetaDebugLog($"dataPos (appears to be): {serializationData.dataPos}");
// serialize component
IEntitySerializer serializer = SerializerManager.GetSerializer(serializerKeys[c]);
if (!serializer.Serialize(ref serializationData, entitiesDB, entitySerializer))
{
Logging.MetaDebugLog("Component serialization failed!");
}
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
bbw.Write((uint)serializationData.dataPos);
Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out buffLen), serializationData.dataPos);
Logging.MetaDebugLog($"dataPos (loop end): {bbw.Position}");
}
serializationData.data.Trim();
Logging.MetaDebugLog($"dataPos (end): {bbw.Position}");
Logging.MetaDebugLog("Serialization complete");
}
public static MethodBase TargetMethod()
{
return typeof(SaveGameEngine).GetMethod("SerializeGameToBuffer");
}
}
}