From 7d385709db3c4740abfc9b7cbffe985ed4160d3e Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Thu, 21 Jul 2022 02:16:44 -0500 Subject: [PATCH] Implement #40, finally The current implementation follows a flag in the config which globally darkens the message part of a log entry by 1 shade. --- IPA.Loader/Config/SelfConfig.cs | 8 + IPA.Loader/Logging/LogPrinter.cs | 77 ++--- .../Logging/Printers/ColoredConsolePrinter.cs | 269 ++++++++++-------- IPA.Loader/Logging/StdoutInterceptor.cs | 2 +- 4 files changed, 201 insertions(+), 155 deletions(-) diff --git a/IPA.Loader/Config/SelfConfig.cs b/IPA.Loader/Config/SelfConfig.cs index 0bfefb92..6118a475 100644 --- a/IPA.Loader/Config/SelfConfig.cs +++ b/IPA.Loader/Config/SelfConfig.cs @@ -56,6 +56,9 @@ namespace IPA.Config case "--no-logs": CommandLineValues.WriteLogs = false; break; + case "--darken-message": + CommandLineValues.Debug.DarkenMessages = true; + break; case "--condense-logs": CommandLineValues.Debug.CondenseModLogs = true; break; @@ -159,6 +162,11 @@ namespace IPA.Config public virtual bool SyncLogging { get; set; } = false; // LINE: ignore public static bool SyncLogging_ => Instance?.Debug?.SyncLogging ?? false; + + public virtual bool DarkenMessages { get; set; } = false; + // LINE: ignore 2 + public static bool DarkenMessages_ => (Instance?.Debug?.DarkenMessages ?? false) + || CommandLineValues.Debug.DarkenMessages; } // LINE: ignore diff --git a/IPA.Loader/Logging/LogPrinter.cs b/IPA.Loader/Logging/LogPrinter.cs index 57a58f4f..bd241e3d 100644 --- a/IPA.Loader/Logging/LogPrinter.cs +++ b/IPA.Loader/Logging/LogPrinter.cs @@ -1,39 +1,40 @@ -using System; - -namespace IPA.Logging -{ - /// - /// The log printer's base class. - /// - public abstract class LogPrinter - { - /// - /// Provides a filter for which log levels to allow through. - /// - /// the level to filter to - public abstract Logger.LogLevel Filter { get; set; } - - /// - /// Prints a provided message from a given log at the specified time. - /// - /// the log level - /// the time the message was composed - /// the name of the log that created this message - /// the message - public abstract void Print(Logger.Level level, DateTime time, string logName, string message); - - /// - /// Called before the first print in a group. May be called multiple times. - /// Use this to create file handles and the like. - /// - public virtual void StartPrint() { } - - /// - /// Called after the last print in a group. May be called multiple times. - /// Use this to dispose file handles and the like. - /// - public virtual void EndPrint() { } - - internal DateTime LastUse { get; set; } - } +#nullable enable +using System; + +namespace IPA.Logging +{ + /// + /// The log printer's base class. + /// + public abstract class LogPrinter + { + /// + /// Provides a filter for which log levels to allow through. + /// + /// the level to filter to + public abstract Logger.LogLevel Filter { get; set; } + + /// + /// Prints a provided message from a given log at the specified time. + /// + /// the log level + /// the time the message was composed + /// the name of the log that created this message + /// the message + public abstract void Print(Logger.Level level, DateTime time, string logName, string message); + + /// + /// Called before the first print in a group. May be called multiple times. + /// Use this to create file handles and the like. + /// + public virtual void StartPrint() { } + + /// + /// Called after the last print in a group. May be called multiple times. + /// Use this to dispose file handles and the like. + /// + public virtual void EndPrint() { } + + internal DateTime LastUse { get; set; } + } } \ No newline at end of file diff --git a/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs b/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs index 1c069a94..e6415018 100644 --- a/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs +++ b/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs @@ -1,116 +1,153 @@ -using System; -using System.Runtime.InteropServices; - -namespace IPA.Logging.Printers -{ - /// - /// Prints a pretty message to the console. - /// - public class ColoredConsolePrinter : LogPrinter - { - private Logger.LogLevel filter = Logger.LogLevel.All; - - /// - /// A filter for this specific printer. - /// - /// the filter to apply to this printer - public override Logger.LogLevel Filter { get => filter; set => filter = value; } - /// - /// The color to print messages as. - /// - /// the color to print this message as - // Initializer calls this function because Unity's .NET 3.5 doesn't have the color properties on Console - public ConsoleColor Color { get; set; } = GetConsoleColor(WinConsole.OutHandle); - - /// - /// Prints an entry to the console window. - /// - /// the of the message - /// the the message was recorded at - /// the name of the log that sent the message - /// the message to print - public override void Print(Logger.Level level, DateTime time, string logName, string message) - { - if (((byte)level & (byte)StandardLogger.PrintFilter) == 0) return; - EnsureDefaultsPopulated(WinConsole.OutHandle); - SetColor(Color, WinConsole.OutHandle); - foreach (var line in message.Split(new[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) - WinConsole.ConOut.WriteLine(Logger.LogFormat, line, logName, time, level.ToString().ToUpper()); - ResetColor(WinConsole.OutHandle); - } - - private static bool _haveReadDefaultColors; - private static short _defaultColors; - - private void EnsureDefaultsPopulated(IntPtr handle, bool force = false) - { - if (!_haveReadDefaultColors | force) - { - GetConsoleScreenBufferInfo(handle, out var info); - _defaultColors = (short)(info.Attribute & ~15); - _haveReadDefaultColors = true; - } - } - - private void ResetColor(IntPtr handle) - { - GetConsoleScreenBufferInfo(handle, out var info); - var otherAttrs = (short)(info.Attribute & ~15); - SetConsoleTextAttribute(handle, (short)(otherAttrs | _defaultColors)); - } - - private void SetColor(ConsoleColor col, IntPtr handle) - { - GetConsoleScreenBufferInfo(handle, out var info); - var attr = GetAttrForeground(info.Attribute, col); - SetConsoleTextAttribute(handle, attr); - } - - private static short GetAttrForeground(int attr, ConsoleColor color) - { - attr &= ~15; - return (short)(attr | (int)color); - } - - private static ConsoleColor GetConsoleColor(IntPtr handle) - { - GetConsoleScreenBufferInfo(handle, out var info); - return (ConsoleColor)(info.Attribute & 15); - } - - - // ReSharper disable NotAccessedField.Local -#pragma warning disable 649 - private struct Coordinate - { - public short X; - public short Y; - } - - private struct SmallRect - { - public short Left; - public short Top; - public short Right; - public short Bottom; - } - - private struct ConsoleScreenBufferInfo - { - public Coordinate Size; - public Coordinate CursorPosition; - public short Attribute; - public SmallRect Window; - public Coordinate MaxWindowSize; - } - #pragma warning restore 649 - // ReSharper restore NotAccessedField.Local - - - [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool GetConsoleScreenBufferInfo(IntPtr handle, out ConsoleScreenBufferInfo info); - - [DllImport("kernel32.dll", EntryPoint = "SetConsoleTextAttribute", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool SetConsoleTextAttribute(IntPtr handle, short attribute); - } -} +#nullable enable +using System; +using System.Runtime.InteropServices; + +namespace IPA.Logging.Printers +{ + /// + /// Prints a pretty message to the console. + /// + public class ColoredConsolePrinter : LogPrinter + { + private Logger.LogLevel filter = Logger.LogLevel.All; + + /// + /// A filter for this specific printer. + /// + /// the filter to apply to this printer + public override Logger.LogLevel Filter { get => filter; set => filter = value; } + /// + /// The color to print messages as. + /// + /// the color to print this message as + // Initializer calls this function because Unity's .NET 3.5 doesn't have the color properties on Console + public ConsoleColor Color { get; set; } = GetConsoleColor(WinConsole.OutHandle); + + private static ConsoleColor GetDarkenedColor(ConsoleColor color) + => color switch + { + ConsoleColor.Gray => ConsoleColor.DarkGray, + ConsoleColor.Blue => ConsoleColor.DarkBlue, + ConsoleColor.Green => ConsoleColor.DarkGreen, + ConsoleColor.Cyan => ConsoleColor.DarkCyan, + ConsoleColor.Red => ConsoleColor.DarkRed, + ConsoleColor.Magenta => ConsoleColor.DarkMagenta, + ConsoleColor.Yellow => ConsoleColor.DarkYellow, + ConsoleColor.White => ConsoleColor.Gray, + _ => color, + }; + + private readonly bool darkenSetManually; + private readonly bool darkenMessages; + + + public ColoredConsolePrinter() : this(Config.SelfConfig.Debug_.DarkenMessages_) + { + darkenSetManually = false; + } + + public ColoredConsolePrinter(bool darkenMessages) + { + darkenSetManually = true; + this.darkenMessages = darkenMessages; + } + + /// + /// Prints an entry to the console window. + /// + /// the of the message + /// the the message was recorded at + /// the name of the log that sent the message + /// the message to print + public override void Print(Logger.Level level, DateTime time, string logName, string message) + { + if (((byte)level & (byte)StandardLogger.PrintFilter) == 0) return; + EnsureDefaultsPopulated(WinConsole.OutHandle); + SetColor(Color, WinConsole.OutHandle); + + var prefixStr = ""; + if ((darkenSetManually && darkenMessages) || (!darkenSetManually && Config.SelfConfig.Debug_.DarkenMessages_)) + { + prefixStr = StdoutInterceptor.ConsoleColorToForegroundSet(GetDarkenedColor(Color)); + } + + foreach (var line in message.Split(new[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) + WinConsole.ConOut.WriteLine(Logger.LogFormat, prefixStr + line, logName, time, level.ToString().ToUpperInvariant()); + ResetColor(WinConsole.OutHandle); + } + + private static bool _haveReadDefaultColors; + private static short _defaultColors; + + private static void EnsureDefaultsPopulated(IntPtr handle, bool force = false) + { + if (!_haveReadDefaultColors | force) + { + _ = GetConsoleScreenBufferInfo(handle, out var info); + _defaultColors = (short)(info.Attribute & ~15); + _haveReadDefaultColors = true; + } + } + + private static void ResetColor(IntPtr handle) + { + _ = GetConsoleScreenBufferInfo(handle, out var info); + var otherAttrs = (short)(info.Attribute & ~15); + _ = SetConsoleTextAttribute(handle, (short)(otherAttrs | _defaultColors)); + } + + private static void SetColor(ConsoleColor col, IntPtr handle) + { + _ = GetConsoleScreenBufferInfo(handle, out var info); + var attr = GetAttrForeground(info.Attribute, col); + _ = SetConsoleTextAttribute(handle, attr); + } + + private static short GetAttrForeground(int attr, ConsoleColor color) + { + attr &= ~15; + return (short)(attr | (int)color); + } + + private static ConsoleColor GetConsoleColor(IntPtr handle) + { + _ = GetConsoleScreenBufferInfo(handle, out var info); + return (ConsoleColor)(info.Attribute & 15); + } + + + // ReSharper disable NotAccessedField.Local +#pragma warning disable 649 + private struct Coordinate + { + public short X; + public short Y; + } + + private struct SmallRect + { + public short Left; + public short Top; + public short Right; + public short Bottom; + } + + private struct ConsoleScreenBufferInfo + { + public Coordinate Size; + public Coordinate CursorPosition; + public short Attribute; + public SmallRect Window; + public Coordinate MaxWindowSize; + } + #pragma warning restore 649 + // ReSharper restore NotAccessedField.Local + + + [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true, CharSet = CharSet.Unicode)] + private static extern bool GetConsoleScreenBufferInfo(IntPtr handle, out ConsoleScreenBufferInfo info); + + [DllImport("kernel32.dll", EntryPoint = "SetConsoleTextAttribute", SetLastError = true, CharSet = CharSet.Unicode)] + private static extern bool SetConsoleTextAttribute(IntPtr handle, short attribute); + } +} diff --git a/IPA.Loader/Logging/StdoutInterceptor.cs b/IPA.Loader/Logging/StdoutInterceptor.cs index c2bba24f..8ba05d24 100644 --- a/IPA.Loader/Logging/StdoutInterceptor.cs +++ b/IPA.Loader/Logging/StdoutInterceptor.cs @@ -54,7 +54,7 @@ namespace IPA.Logging private const ConsoleColor defaultColor = ConsoleColor.Gray; private ConsoleColor currentColor = defaultColor; - private static string ConsoleColorToForegroundSet(ConsoleColor col) + internal static string ConsoleColorToForegroundSet(ConsoleColor col) { if (!WinConsole.UseVTEscapes) return ""; string code = "0"; // reset