|
@@ -1,4 +1,8 @@
|
|
|
-using System.Diagnostics;
|
|
|
+using System;
|
|
|
+using System.Diagnostics;
|
|
|
+using System.Linq;
|
|
|
+using System.Reflection;
|
|
|
+using Harmony;
|
|
|
|
|
|
namespace BepInEx.Logger
|
|
|
{
|
|
@@ -6,6 +10,15 @@ namespace BepInEx.Logger
|
|
|
{
|
|
|
public BaseLogger Logger;
|
|
|
|
|
|
+ static LoggerTraceListener()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ TraceFixer.ApplyFix();
|
|
|
+ }
|
|
|
+ catch { } //ignore everything, if it's thrown an exception, we're using an assembly that has already fixed this
|
|
|
+ }
|
|
|
+
|
|
|
public LoggerTraceListener(BaseLogger logger)
|
|
|
{
|
|
|
Logger = logger;
|
|
@@ -50,5 +63,70 @@ namespace BepInEx.Logger
|
|
|
|
|
|
Logger.Log(level, $"{source} : {message}");
|
|
|
}
|
|
|
+
|
|
|
+ private static class TraceFixer
|
|
|
+ {
|
|
|
+ private static Type TraceImplType;
|
|
|
+
|
|
|
+ private static object ListenersSyncRoot;
|
|
|
+ private static TraceListenerCollection Listeners;
|
|
|
+ private static PropertyInfo prop_AutoFlush;
|
|
|
+
|
|
|
+ private static bool AutoFlush => (bool)prop_AutoFlush.GetValue(null, null);
|
|
|
+
|
|
|
+
|
|
|
+ public static void ApplyFix()
|
|
|
+ {
|
|
|
+ TraceImplType = AppDomain.CurrentDomain.GetAssemblies()
|
|
|
+ .First(x => x.GetName().Name == "System")
|
|
|
+ .GetTypes()
|
|
|
+ .First(x => x.Name == "TraceImpl");
|
|
|
+
|
|
|
+
|
|
|
+ ListenersSyncRoot = AccessTools.Property(TraceImplType, "ListenersSyncRoot").GetValue(null, null);
|
|
|
+
|
|
|
+ Listeners = (TraceListenerCollection)AccessTools.Property(TraceImplType, "Listeners").GetValue(null, null);
|
|
|
+
|
|
|
+ prop_AutoFlush = AccessTools.Property(TraceImplType, "AutoFlush");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ HarmonyInstance instance = HarmonyInstance.Create("com.bepis.bepinex.tracefix");
|
|
|
+
|
|
|
+ instance.Patch(
|
|
|
+ typeof(Trace).GetMethod("DoTrace", BindingFlags.Static | BindingFlags.NonPublic),
|
|
|
+ new HarmonyMethod(typeof(TraceFixer).GetMethod("DoTraceReplacement", BindingFlags.Static | BindingFlags.Public)),
|
|
|
+ null);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static bool DoTraceReplacement(string kind, Assembly report, string message)
|
|
|
+ {
|
|
|
+ string arg = string.Empty;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ arg = report.GetName().Name;
|
|
|
+ }
|
|
|
+ catch (MethodAccessException) { }
|
|
|
+
|
|
|
+ TraceEventType type = (TraceEventType)Enum.Parse(typeof(TraceEventType), kind);
|
|
|
+
|
|
|
+ lock (ListenersSyncRoot)
|
|
|
+ {
|
|
|
+ foreach (object obj in Listeners)
|
|
|
+ {
|
|
|
+ TraceListener traceListener = (TraceListener)obj;
|
|
|
+ traceListener.TraceEvent(new TraceEventCache(), arg, type, 0, message);
|
|
|
+
|
|
|
+ if (AutoFlush)
|
|
|
+ {
|
|
|
+ traceListener.Flush();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|