Move TraceFix to preloader runtime patches, and clean up Preloader folder structure

This commit is contained in:
Bepis committed 2019-02-09 14:04:53 +11:00
1 parent 69efae63ed
commit aba672acbc
8 files changed
+99 -93

No files matched your search

+6 -7
View File
@@ -38,13 +38,14 @@
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="Patcher\AssemblyPatcher.cs" />
<Compile Include="Patching\AssemblyPatcher.cs" />
<Compile Include="Entrypoint.cs" />
<Compile Include="Patcher\PatcherPlugin.cs" />
<Compile Include="Patching\PatcherPlugin.cs" />
<Compile Include="RuntimeFixes\TraceFix.cs" />
<Compile Include="Preloader.cs" />
<Compile Include="PreloaderLogWriter.cs" />
<Compile Include="Logger\PreloaderLogWriter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UnityPatches.cs" />
<Compile Include="RuntimeFixes\UnityPatches.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BepInEx\BepInEx.csproj">
@@ -60,8 +61,6 @@
<Name>Harmony</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Logger\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -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
{
@@ -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
{
/// <summary>
/// Delegate used in patching assemblies.
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace BepInEx.Preloader.Patcher
namespace BepInEx.Preloader.Patching
{
/// <summary>
/// A single assembly patcher.
+6 -1
View File
@@ -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)
{
@@ -0,0 +1,74 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Harmony;
namespace BepInEx.Preloader.RuntimeFixes
{
/// <summary>
/// This exists because the Mono implementation of <see cref="Trace"/> is/was broken, and would call Write directly instead of calling TraceEvent. This class fixes that with a <see cref="Harmony"/> hook.
/// </summary>
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;
}
}
}
@@ -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]
+1 -81
View File
@@ -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
/// <inheritdoc cref="TraceListener"/>
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}");
}
/// <summary>
/// This exists because the Mono implementation of <see cref="Trace"/> is/was broken, and would call Write directly instead of calling TraceEvent. This class fixes that with a <see cref="Harmony"/> hook.
/// </summary>
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;
}
}
}
}