2020-04-29 01:56:34 +00:00
|
|
|
|
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;
|
2020-05-03 19:31:09 +00:00
|
|
|
|
using HarmonyLib;
|
2020-04-29 01:56:34 +00:00
|
|
|
|
|
|
|
|
|
namespace GamecraftModdingAPI.Persistence
|
|
|
|
|
{
|
2021-04-12 15:37:51 +00:00
|
|
|
|
//[HarmonyPatch] - TODO
|
2020-04-29 01:56:34 +00:00
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|