From aba672acbc1b9458ea78ee39f5abd7424b1757db Mon Sep 17 00:00:00 2001 From: Bepis <36346617+bbepis@users.noreply.github.com> Date: Sat, 9 Feb 2019 14:04:53 +1100 Subject: [PATCH] Move TraceFix to preloader runtime patches, and clean up Preloader folder structure --- BepInEx.Preloader/BepInEx.Preloader.csproj | 13 ++- .../{ => Logger}/PreloaderLogWriter.cs | 3 +- .../{Patcher => Patching}/AssemblyPatcher.cs | 3 +- .../{Patcher => Patching}/PatcherPlugin.cs | 2 +- BepInEx.Preloader/Preloader.cs | 7 +- BepInEx.Preloader/RuntimeFixes/TraceFix.cs | 74 +++++++++++++++++ .../{ => RuntimeFixes}/UnityPatches.cs | 8 +- BepInEx/Logging/TraceLogSource.cs | 82 +------------------ 8 files changed, 99 insertions(+), 93 deletions(-) rename BepInEx.Preloader/{ => Logger}/PreloaderLogWriter.cs (97%) rename BepInEx.Preloader/{Patcher => Patching}/AssemblyPatcher.cs (98%) rename BepInEx.Preloader/{Patcher => Patching}/PatcherPlugin.cs (96%) create mode 100644 BepInEx.Preloader/RuntimeFixes/TraceFix.cs rename BepInEx.Preloader/{ => RuntimeFixes}/UnityPatches.cs (88%) diff --git a/BepInEx.Preloader/BepInEx.Preloader.csproj b/BepInEx.Preloader/BepInEx.Preloader.csproj index 61a623a..c387545 100644 --- a/BepInEx.Preloader/BepInEx.Preloader.csproj +++ b/BepInEx.Preloader/BepInEx.Preloader.csproj @@ -38,13 +38,14 @@ - + - + + - + - + @@ -60,8 +61,6 @@ Harmony - - - + \ No newline at end of file diff --git a/BepInEx.Preloader/PreloaderLogWriter.cs b/BepInEx.Preloader/Logger/PreloaderLogWriter.cs similarity index 97% rename from BepInEx.Preloader/PreloaderLogWriter.cs rename to BepInEx.Preloader/Logger/PreloaderLogWriter.cs index de8ac98..9ac9235 100644 --- a/BepInEx.Preloader/PreloaderLogWriter.cs +++ b/BepInEx.Preloader/Logger/PreloaderLogWriter.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Text; using BepInEx.ConsoleUtil; +using BepInEx.Logging; -namespace BepInEx.Logging +namespace BepInEx.Preloader { public class PreloaderConsoleListener : ILogListener { diff --git a/BepInEx.Preloader/Patcher/AssemblyPatcher.cs b/BepInEx.Preloader/Patching/AssemblyPatcher.cs similarity index 98% rename from BepInEx.Preloader/Patcher/AssemblyPatcher.cs rename to BepInEx.Preloader/Patching/AssemblyPatcher.cs index a812b7f..a2916c5 100644 --- a/BepInEx.Preloader/Patcher/AssemblyPatcher.cs +++ b/BepInEx.Preloader/Patching/AssemblyPatcher.cs @@ -3,9 +3,10 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using BepInEx.Logging; +using BepInEx.Preloader.RuntimeFixes; using Mono.Cecil; -namespace BepInEx.Preloader.Patcher +namespace BepInEx.Preloader.Patching { /// /// Delegate used in patching assemblies. diff --git a/BepInEx.Preloader/Patcher/PatcherPlugin.cs b/BepInEx.Preloader/Patching/PatcherPlugin.cs similarity index 96% rename from BepInEx.Preloader/Patcher/PatcherPlugin.cs rename to BepInEx.Preloader/Patching/PatcherPlugin.cs index 8d0a72b..b602d4b 100644 --- a/BepInEx.Preloader/Patcher/PatcherPlugin.cs +++ b/BepInEx.Preloader/Patching/PatcherPlugin.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace BepInEx.Preloader.Patcher +namespace BepInEx.Preloader.Patching { /// /// A single assembly patcher. diff --git a/BepInEx.Preloader/Preloader.cs b/BepInEx.Preloader/Preloader.cs index 0ac94ef..9c4cd80 100644 --- a/BepInEx.Preloader/Preloader.cs +++ b/BepInEx.Preloader/Preloader.cs @@ -6,7 +6,8 @@ using System.Linq; using System.Reflection; using System.Text; using BepInEx.Logging; -using BepInEx.Preloader.Patcher; +using BepInEx.Preloader.Patching; +using BepInEx.Preloader.RuntimeFixes; using Mono.Cecil; using Mono.Cecil.Cil; using UnityInjector.ConsoleUtil; @@ -56,6 +57,8 @@ namespace BepInEx.Preloader Logger.LogMessage(attribute.Info); } + Logger.LogMessage($"Running under unity version {Process.GetCurrentProcess().MainModule.FileVersionInfo.FileVersion}"); + Logger.LogMessage("Preloader started"); string entrypointAssembly = Config.GetEntry("entrypoint-assembly", "UnityEngine.dll", "Preloader"); @@ -76,6 +79,8 @@ namespace BepInEx.Preloader Logger.Listeners.Add(new ConsoleLogListener()); PreloaderLog.Dispose(); + + Trace.TraceError("This should be an error"); } catch (Exception ex) { diff --git a/BepInEx.Preloader/RuntimeFixes/TraceFix.cs b/BepInEx.Preloader/RuntimeFixes/TraceFix.cs new file mode 100644 index 0000000..fd9b559 --- /dev/null +++ b/BepInEx.Preloader/RuntimeFixes/TraceFix.cs @@ -0,0 +1,74 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using Harmony; + +namespace BepInEx.Preloader.RuntimeFixes +{ + /// + /// This exists because the Mono implementation of is/was broken, and would call Write directly instead of calling TraceEvent. This class fixes that with a hook. + /// + internal static class TraceFix + { + 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), + prefix: new HarmonyMethod(typeof(TraceFix).GetMethod(nameof(DoTraceReplacement), BindingFlags.Static | BindingFlags.NonPublic))); + } + + + private 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; + } + } +} \ No newline at end of file diff --git a/BepInEx.Preloader/UnityPatches.cs b/BepInEx.Preloader/RuntimeFixes/UnityPatches.cs similarity index 88% rename from BepInEx.Preloader/UnityPatches.cs rename to BepInEx.Preloader/RuntimeFixes/UnityPatches.cs index b843f76..c6f919e 100644 --- a/BepInEx.Preloader/UnityPatches.cs +++ b/BepInEx.Preloader/RuntimeFixes/UnityPatches.cs @@ -4,7 +4,7 @@ using System.Reflection; using BepInEx.Harmony; using Harmony; -namespace BepInEx.Preloader +namespace BepInEx.Preloader.RuntimeFixes { internal static class UnityPatches { @@ -16,6 +16,12 @@ namespace BepInEx.Preloader public static void Apply() { HarmonyWrapper.PatchAll(typeof(UnityPatches), HarmonyInstance); + + try + { + TraceFix.ApplyFix(); + } + catch { } //ignore everything, if it's thrown an exception, we're using an assembly that has already fixed this } [HarmonyPostfix] diff --git a/BepInEx/Logging/TraceLogSource.cs b/BepInEx/Logging/TraceLogSource.cs index 5d78884..cc24f62 100644 --- a/BepInEx/Logging/TraceLogSource.cs +++ b/BepInEx/Logging/TraceLogSource.cs @@ -1,9 +1,4 @@ -using System; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using Harmony; -using UnityEngineInternal; +using System.Diagnostics; namespace BepInEx.Logging { @@ -13,15 +8,6 @@ namespace BepInEx.Logging /// public class TraceLogSource : TraceListener { - static TraceLogSource() - { - try - { - TraceFixer.ApplyFix(); - } - catch { } //ignore everything, if it's thrown an exception, we're using an assembly that has already fixed this - } - public static bool IsListening { get; protected set; } = false; private static TraceLogSource traceListener; @@ -93,71 +79,5 @@ namespace BepInEx.Logging LogSource.Log(level, $"{source} : {message}"); } - - /// - /// This exists because the Mono implementation of is/was broken, and would call Write directly instead of calling TraceEvent. This class fixes that with a hook. - /// - 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), - prefix: new HarmonyMethod(typeof(TraceFixer).GetMethod(nameof(DoTraceReplacement), BindingFlags.Static | BindingFlags.NonPublic))); - } - - - private 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; - } - } } } \ No newline at end of file