Parcourir la source

Initial logging system rework

Bepis il y a 6 ans
Parent
commit
92f08deedc

+ 3 - 0
BepInEx/BepInEx.csproj

@@ -67,6 +67,9 @@
     <Compile Include="Bootstrap\Chainloader.cs" />
     <Compile Include="Contract\BaseUnityPlugin.cs" />
     <Compile Include="Logger.cs" />
+    <Compile Include="Logger\BaseLogger.cs" />
+    <Compile Include="Logger\LogLevel.cs" />
+    <Compile Include="Logger\PreloaderTextWriter.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Bootstrap\TypeLoader.cs" />
   </ItemGroup>

+ 1 - 1
BepInEx/Bootstrap/Chainloader.cs

@@ -55,7 +55,7 @@ namespace BepInEx.Bootstrap
 
 			try
 			{
-                BepInLogger.Log(Preloader.PreloaderLog);
+                BepInLogger.Log(Preloader.PreloaderLog.ToString());
 				BepInLogger.Log("Chainloader started");
 
 				UnityEngine.Object.DontDestroyOnLoad(ManagerObject);

+ 21 - 8
BepInEx/Bootstrap/Preloader.cs

@@ -5,6 +5,7 @@ using System.IO;
 using System.Linq;
 using System.Reflection;
 using BepInEx.Common;
+using BepInEx.Logger;
 using Mono.Cecil;
 using Mono.Cecil.Cil;
 using MethodAttributes = Mono.Cecil.MethodAttributes;
@@ -31,13 +32,13 @@ namespace BepInEx.Bootstrap
 
         public static string PatcherPluginPath => Utility.CombinePaths(GameRootPath, "BepInEx", "patchers");
 
-        public static string PreloaderLog { get; private set; } = $"BepInEx {Assembly.GetExecutingAssembly().GetName().Version}\r\n";
-
         #endregion
 
+        public static PreloaderTextWriter PreloaderLog { get; private set; }
 
         public static Dictionary<string, IList<AssemblyPatcherDelegate>> PatcherDictionary = new Dictionary<string, IList<AssemblyPatcherDelegate>>(StringComparer.OrdinalIgnoreCase);
 
+
         public static void AddPatcher(string dllName, AssemblyPatcherDelegate patcher)
         {
             if (PatcherDictionary.TryGetValue(dllName, out IList<AssemblyPatcherDelegate> patcherList))
@@ -56,7 +57,11 @@ namespace BepInEx.Bootstrap
         {
             try
             {
-                PreloaderLog += "Preloader started\r\n";
+                PreloaderLog = new PreloaderTextWriter();
+
+                PreloaderLog.WriteLine($"BepInEx {Assembly.GetExecutingAssembly().GetName().Version}");
+                PreloaderLog.Log(LogLevel.Message, "Preloader started");
+
 
                 ExecutablePath = args[0];
 
@@ -71,7 +76,7 @@ namespace BepInEx.Bootstrap
                     {
                         try
                         {
-                            var assembly = Assembly.LoadFrom(assemblyPath); 
+                            var assembly = Assembly.LoadFrom(assemblyPath);
 
                             foreach (var kv in GetPatcherMethods(assembly))
                                 foreach (var patcher in kv.Value)
@@ -85,7 +90,10 @@ namespace BepInEx.Bootstrap
             }
             catch (Exception ex)
             {
-                PreloaderLog += $"FATAL ERROR: COULD NOT LOAD PATCHER!\r\n{ex}";
+                PreloaderLog.Log(LogLevel.Fatal, "Could not run preloader!");
+                PreloaderLog.Log(LogLevel.Fatal, ex);
+
+                PreloaderLog.Disable();
 
                 try
                 {
@@ -94,9 +102,14 @@ namespace BepInEx.Bootstrap
                 }
                 finally
                 {
-                    File.WriteAllText(Path.Combine(CurrentExecutingAssemblyDirectoryPath, "fatalerror.log"), PreloaderLog);
+                    File.WriteAllText(Path.Combine(GameRootPath, $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"),
+                        PreloaderLog.ToString());
                 }
             }
+            finally
+            {
+                PreloaderLog.Disable();
+            }
         }
 
         internal static IDictionary<string, IList<AssemblyPatcherDelegate>> GetPatcherMethods(Assembly assembly)
@@ -147,11 +160,11 @@ namespace BepInEx.Bootstrap
                 }
                 catch (Exception ex)
                 {
-                    PreloaderLog += $"Could not load patcher methods from {assembly.GetName().Name}";
+                    PreloaderLog.Log(LogLevel.Warning, $"Could not load patcher methods from {assembly.GetName().Name}");
                 }
             }
 
-            PreloaderLog += $"Loaded {patcherMethods.SelectMany(x => x.Value).Distinct().Count()} patcher methods from {assembly.GetName().Name}";
+            PreloaderLog.Log(LogLevel.Info, $"Loaded {patcherMethods.SelectMany(x => x.Value).Distinct().Count()} patcher methods from {assembly.GetName().Name}");
 
             return patcherMethods;
         }

+ 23 - 0
BepInEx/Logger/BaseLogger.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace BepInEx.Logger
+{
+    public abstract class BaseLogger : TextWriter
+    {
+        public override Encoding Encoding { get; } = new UTF8Encoding(true);
+
+        public virtual void Log(LogLevel level, object entry)
+        {
+            WriteLine($"[{level}] {entry}");
+        }
+
+        public virtual void Log(object entry)
+        {
+            Log(LogLevel.Message, entry);
+        }
+    }
+}

+ 21 - 0
BepInEx/Logger/LogLevel.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BepInEx.Logger
+{
+    [Flags]
+    public enum LogLevel
+    {
+        None = 0,
+        Fatal = 1,
+        Error = 2,
+        Warning = 4,
+        Message = 8,
+        Info = 16,
+        Debug = 32,
+
+        All = Fatal | Error | Warning | Message | Info | Debug
+    }
+}

+ 78 - 0
BepInEx/Logger/PreloaderTextWriter.cs

@@ -0,0 +1,78 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+
+namespace BepInEx.Logger
+{
+    public class PreloaderTextWriter : BaseLogger
+    {
+        public override Encoding Encoding { get; } = new UTF8Encoding(true);
+
+        public StringBuilder StringBuilder = new StringBuilder();
+
+        protected TextWriter stdout;
+        protected TextWriterTraceListener traceListener;
+
+        private bool _enabled = false;
+        public bool Enabled {
+            get => _enabled;
+            set
+            {
+                if (value)
+                    Enable();
+                else
+                    Disable();
+            }
+        }
+
+        public PreloaderTextWriter()
+        {
+            stdout = Console.Out;
+            traceListener = new TextWriterTraceListener(this, "Preloader");
+        }
+
+        public void Enable()
+        {
+            if (Enabled)
+                return;
+
+            Console.SetOut(this);
+            Trace.Listeners.Add(traceListener);
+
+            _enabled = true;
+        }
+
+        public void Disable()
+        {
+            if (!Enabled)
+                return;
+
+            Console.SetOut(stdout);
+            Trace.Listeners.Remove(traceListener);
+
+            _enabled = false;
+        }
+
+        public override void Write(char value)
+        {
+            StringBuilder.Append(value);
+        }
+
+        public override void Write(string value)
+        {
+            StringBuilder.Append(value);
+        }
+
+        public override void Close()
+        {
+            Disable();
+            StringBuilder.Length = 0;
+        }
+
+        public override string ToString()
+        {
+            return StringBuilder.ToString().Trim();
+        }
+    }
+}