A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SaveGameEnginePatch.cs 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System;
  2. using System.Text;
  3. using System.Reflection;
  4. using RobocraftX.Common;
  5. using RobocraftX.SaveAndLoad;
  6. using Svelto.DataStructures;
  7. using Svelto.ECS;
  8. using Svelto.ECS.Serialization;
  9. using GamecraftModdingAPI.Utility;
  10. using HarmonyLib;
  11. namespace GamecraftModdingAPI.Persistence
  12. {
  13. [HarmonyPatch]
  14. class SaveGameEnginePatch
  15. {
  16. private static readonly byte[] frameStart = Encoding.UTF8.GetBytes("\0\0\0GamecraftModdingAPI\0\0\0");
  17. public static void Postfix(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer)
  18. {
  19. Logging.MetaDebugLog("Running Postfix on SerializeGameToBuffer: serializing custom components...");
  20. if (SerializerManager.GetSerializersCount() == 0)
  21. {
  22. Logging.MetaDebugLog("Skipping component serialization: no serializers registered!");
  23. return;
  24. }
  25. serializationData.data.ExpandBy((uint)frameStart.Length);
  26. BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out uint buffLen), serializationData.dataPos);
  27. uint originalPos = serializationData.dataPos;
  28. Logging.MetaDebugLog($"dataPos: {originalPos}");
  29. // Add frame start so it's easier to find GamecraftModdingAPI-serialized components
  30. for (int i = 0; i < frameStart.Length; i++)
  31. {
  32. bbw.Write(frameStart[i]);
  33. }
  34. Logging.MetaDebugLog($"dataPos (after frame start): {bbw.Position}");
  35. serializationData.data.ExpandBy(4u);
  36. bbw.Write((uint)SerializerManager.GetSerializersCount());
  37. string[] serializerKeys = SerializerManager.GetSerializerNames();
  38. for (uint c = 0; c < serializerKeys.Length; c++)
  39. {
  40. Logging.MetaDebugLog($"dataPos (loop start): {bbw.Position}");
  41. // write component info
  42. serializationData.data.ExpandBy(4u + (uint)serializerKeys[c].Length);
  43. bbw.Write((uint)serializerKeys[c].Length);
  44. Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
  45. byte[] nameBytes = Encoding.UTF8.GetBytes(serializerKeys[c]);
  46. for (int i = 0; i < nameBytes.Length; i++)
  47. {
  48. bbw.Write(nameBytes[i]);
  49. }
  50. Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
  51. serializationData.data.ExpandBy(4u);
  52. serializationData.dataPos = bbw.Position + 4u;
  53. Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
  54. Logging.MetaDebugLog($"dataPos (appears to be): {serializationData.dataPos}");
  55. // serialize component
  56. IEntitySerializer serializer = SerializerManager.GetSerializer(serializerKeys[c]);
  57. if (!serializer.Serialize(ref serializationData, entitiesDB, entitySerializer))
  58. {
  59. Logging.MetaDebugLog("Component serialization failed!");
  60. }
  61. Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
  62. bbw.Write((uint)serializationData.dataPos);
  63. Logging.MetaDebugLog($"dataPos (now): {bbw.Position}");
  64. bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out buffLen), serializationData.dataPos);
  65. Logging.MetaDebugLog($"dataPos (loop end): {bbw.Position}");
  66. }
  67. serializationData.data.Trim();
  68. Logging.MetaDebugLog($"dataPos (end): {bbw.Position}");
  69. Logging.MetaDebugLog("Serialization complete");
  70. }
  71. public static MethodBase TargetMethod()
  72. {
  73. return typeof(SaveGameEngine).GetMethod("SerializeGameToBuffer");
  74. }
  75. }
  76. }