mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Add runtime fix for console logging
This commit is contained in:
1 parent
f22e5836ca
commit
a00b095eae
8 files changed
+96
-98
No files matched your search
@@ -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" />
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user