Add runtime fix for console logging

This commit is contained in:
ghorsington committed 2020-06-18 00:15:03 +03:00
1 parent f22e5836ca
commit a00b095eae
8 files changed
+96 -98

No files matched your search

+2 -1
View File
@@ -54,9 +54,10 @@
<Compile Include="Patching\AssemblyPatcher.cs" /> <Compile Include="Patching\AssemblyPatcher.cs" />
<Compile Include="Entrypoint.cs" /> <Compile Include="Entrypoint.cs" />
<Compile Include="Patching\PatcherPlugin.cs" /> <Compile Include="Patching\PatcherPlugin.cs" />
<Compile Include="RuntimeFixes\ConsoleSetOutFix.cs" />
<Compile Include="RuntimeFixes\TraceFix.cs" /> <Compile Include="RuntimeFixes\TraceFix.cs" />
<Compile Include="Preloader.cs" /> <Compile Include="Preloader.cs" />
<Compile Include="Logger\PreloaderLogWriter.cs" /> <Compile Include="Logger\PreloaderConsoleListener.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RuntimeFixes\UnityPatches.cs" /> <Compile Include="RuntimeFixes\UnityPatches.cs" />
<Compile Include="RuntimeFixes\XTermFix.cs" /> <Compile Include="RuntimeFixes\XTermFix.cs" />
+3
View File
@@ -21,7 +21,10 @@ namespace BepInEx.Preloader
private static void PreloaderMain() private static void PreloaderMain()
{ {
if (Preloader.ConfigApplyRuntimePatches.Value) if (Preloader.ConfigApplyRuntimePatches.Value)
{
XTermFix.Apply(); XTermFix.Apply();
ConsoleSetOutFix.Apply();
}
Preloader.Run(); Preloader.Run();
} }
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using BepInEx.Configuration;
using BepInEx.Logging;
namespace BepInEx.Preloader
{
public class PreloaderConsoleListener : ILogListener
{
public static List<LogEventArgs> LogEvents { get; } = new List<LogEventArgs>();
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if ((eventArgs.Level & ConfigConsoleDisplayedLevel.Value) == 0)
return;
LogEvents.Add(eventArgs);
}
private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind(
"Logging.Console","LogLevels",
LogLevel.Fatal | LogLevel.Error | LogLevel.Message | LogLevel.Info,
"Which log levels to show in the console output.");
public void Dispose() { }
}
}
@@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BepInEx.Configuration;
using BepInEx.Logging;
namespace BepInEx.Preloader
{
public class PreloaderConsoleListener : ILogListener
{
public static List<LogEventArgs> LogEvents { get; } = new List<LogEventArgs>();
public static TextWriter StandardOut { get; set; }
protected PreloaderConsoleSource LoggerSource { get; set; }
public PreloaderConsoleListener(bool redirectConsole)
{
StandardOut = Console.Out;
if (redirectConsole)
{
LoggerSource = new PreloaderConsoleSource();
Logger.Sources.Add(LoggerSource);
Console.SetOut(LoggerSource);
}
}
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if ((eventArgs.Level & ConfigConsoleDisplayedLevel.Value) == 0)
return;
LogEvents.Add(eventArgs);
ConsoleManager.SetConsoleColor(eventArgs.Level.GetConsoleColor());
ConsoleDirectWrite(eventArgs.ToStringLine());
ConsoleManager.SetConsoleColor(ConsoleColor.Gray);
}
public void ConsoleDirectWrite(string value)
{
StandardOut.Write(value);
}
public void ConsoleDirectWriteLine(string value)
{
StandardOut.WriteLine(value);
}
public void Dispose()
{
if (LoggerSource != null)
{
Console.SetOut(StandardOut);
Logger.Sources.Remove(LoggerSource);
LoggerSource.Dispose();
LoggerSource = null;
}
}
private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind(
"Logging.Console","LogLevels",
LogLevel.Fatal | LogLevel.Error | LogLevel.Message | LogLevel.Info,
"Which log levels to show in the console output.");
}
public class PreloaderConsoleSource : TextWriter, ILogSource
{
public override Encoding Encoding { get; } = Console.OutputEncoding;
public string SourceName { get; } = "BepInEx Preloader";
public event EventHandler<LogEventArgs> LogEvent;
public override void Write(object value)
=> LogEvent?.Invoke(this, new LogEventArgs(value, LogLevel.Info, this));
public override void Write(string value)
=> Write((object)value);
public override void WriteLine() { }
public override void WriteLine(object value)
=> Write(value);
public override void WriteLine(string value)
=> Write(value);
}
}
+3 -4
View File
@@ -42,8 +42,9 @@ namespace BepInEx.Preloader
Logger.InitializeInternalLoggers(); Logger.InitializeInternalLoggers();
Logger.Sources.Add(TraceLogSource.CreateSource()); Logger.Sources.Add(TraceLogSource.CreateSource());
PreloaderLog = new PreloaderConsoleListener(ConfigPreloaderCOutLogging.Value); Logger.Listeners.Add(new ConsoleLogListener());
PreloaderLog = new PreloaderConsoleListener();
Logger.Listeners.Add(PreloaderLog); Logger.Listeners.Add(PreloaderLog);
string consoleTile = $"BepInEx {typeof(Paths).Assembly.GetName().Version} - {Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName)}"; string consoleTile = $"BepInEx {typeof(Paths).Assembly.GetName().Version} - {Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName)}";
@@ -85,11 +86,9 @@ namespace BepInEx.Preloader
AssemblyPatcher.PatchAndLoad(Paths.ManagedPath); AssemblyPatcher.PatchAndLoad(Paths.ManagedPath);
AssemblyPatcher.DisposePatchers(); AssemblyPatcher.DisposePatchers();
Logger.LogMessage("Preloader finished"); Logger.LogMessage("Preloader finished");
Logger.Listeners.Remove(PreloaderLog); Logger.Listeners.Remove(PreloaderLog);
Logger.Listeners.Add(new ConsoleLogListener());
PreloaderLog.Dispose(); PreloaderLog.Dispose();
} }
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using HarmonyLib;
namespace BepInEx.Preloader.RuntimeFixes
{
internal static class ConsoleSetOutFix
{
private static AggregatedTextWriter aggregatedTextWriter;
public static void Apply()
{
aggregatedTextWriter = new AggregatedTextWriter(Console.Out);
Console.SetOut(aggregatedTextWriter);
HarmonyLib.Harmony.CreateAndPatchAll(typeof(ConsoleSetOutFix));
}
[HarmonyPatch(typeof(Console), nameof(Console.SetOut))]
[HarmonyPrefix]
private static bool OnSetOut(TextWriter newOut)
{
aggregatedTextWriter.Add(newOut);
return false;
}
}
internal class AggregatedTextWriter : TextWriter
{
public override Encoding Encoding { get; } = Encoding.UTF8;
private List<TextWriter> writers = new List<TextWriter>();
public AggregatedTextWriter(params TextWriter[] initialWriters)
{
writers.AddRange(initialWriters.Where(w => w != null));
}
public void Add(TextWriter tw)
{
if (writers.Any(t => t == tw))
return;
writers.Add(tw);
}
public override void Flush() => writers.ForEach(w => w.Flush());
public override void Write(object value) => writers.ForEach(w => w.Write(value));
public override void Write(string value) => writers.ForEach(w => w.Write(value));
public override void Write(char value) => writers.ForEach(w => w.Write(value));
public override void WriteLine(object value) => writers.ForEach(w => w.WriteLine(value));
public override void WriteLine(string value) => writers.ForEach(w => w.WriteLine(value));
public override void WriteLine(char value) => writers.ForEach(w => w.WriteLine(value));
}
}
+1 -1
View File
@@ -13,7 +13,7 @@ namespace BepInEx.Logging
if ((eventArgs.Level & ConfigConsoleDisplayedLevel.Value) == 0) if ((eventArgs.Level & ConfigConsoleDisplayedLevel.Value) == 0)
return; return;
ConsoleManager.SetConsoleColor(eventArgs.Level.GetConsoleColor()); ConsoleManager.SetConsoleColor(eventArgs.Level.GetConsoleColor());
ConsoleManager.ConsoleStream?.Write(eventArgs.ToStringLine()); Console.Write(eventArgs.ToStringLine());
ConsoleManager.SetConsoleColor(ConsoleColor.Gray); ConsoleManager.SetConsoleColor(ConsoleColor.Gray);
} }
+3
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.IO;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
@@ -78,6 +79,8 @@ namespace BepInEx.Logging
if (type == LogType.Exception) if (type == LogType.Exception)
message += $"\nStack trace:\n{stackTrace}"; message += $"\nStack trace:\n{stackTrace}";
File.WriteAllText("unity.log", $"{message}\n");
InternalUnityLogMessage?.Invoke(null, new LogEventArgs(message, logLevel, null)); InternalUnityLogMessage?.Invoke(null, new LogEventArgs(message, logLevel, null));
} }