CLre/CLre_server/Fixes/InitLogSooner.cs

84 lines
3 KiB
C#

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using HarmonyLib;
namespace CLre_server.Fixes
{
[Bugfix(name = "InitLogSooner",
description = "Start the logger slightly sooner than Cardlife does",
component = BugfixType.Initialiser, id = 0)]
public static class InitLogSooner
{
public static int millisecondsTimeout = 5000;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Init()
{
try
{
CustomLoggerThread_CreateGameObject_Patch.allowed = true;
CustomLoggerThread.CreateGameObject();
CustomLoggerThread_CreateGameObject_Patch.allowed = false;
API.Utility.Logging.Log($"Completed early log init, hello!");
//System.IO.File.WriteAllText("InitLogSooner.log", $"Done at " + System.DateTime.Now.ToString());
}
catch (Exception e)
{
API.Utility.Logging.Log($"Failed to initialise log sooner, reason:\n" + e);
System.IO.File.WriteAllText("InitLogSooner.log", e.ToString());
}
}
[Bugfix(name = "InitLogSooner",
target = typeof(CustomLoggerThread),
component = BugfixType.HarmonyPatch, id = 0)]
[HarmonyPatch(typeof(CustomLoggerThread), "CreateGameObject")]
class CustomLoggerThread_CreateGameObject_Patch
{
internal static bool allowed = false;
public static bool Prefix()
{
return allowed;
}
}
[Bugfix(name = "InitLogSooner",
component = BugfixType.HarmonyPatch, id = 0)]
[HarmonyPatch(typeof(CustomLoggerThread), "StartQueue")]
class CustomLoggerThread_StartQueue_Patch
{
internal static volatile bool IsLogStarted = false;
private delegate void Flusher();
public static bool Prefix()
{
// setup thru reflection
FieldInfo quitThreadField = AccessTools.Field(typeof(CustomLoggerThread), "_quitThread");
MethodInfo flushLoggerMethod = AccessTools.Method(typeof(CustomLoggerThread), "FlushLogger");
Flusher flushLogger = (Flusher) Delegate.CreateDelegate(typeof(Action), null, flushLoggerMethod);
MethodInfo forceFlushMethod = AccessTools.Method("CustomLogger:ForceFlush");
Flusher forceFlush = (Flusher) Delegate.CreateDelegate(typeof(Action), null, forceFlushMethod);
Thread.MemoryBarrier();
IsLogStarted = true;
while (!(bool) quitThreadField.GetValue(null))
{
flushLogger();
forceFlush();
Thread.Sleep(millisecondsTimeout);
}
IsLogStarted = false;
return false;
}
}
}
}