Browse Source

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.
pull/86/head
Anairkoen Schno 1 year ago
parent
commit
7d385709db
No known key found for this signature in database GPG Key ID: 40F6F33603F1772D
4 changed files with 201 additions and 155 deletions
  1. +8
    -0
      IPA.Loader/Config/SelfConfig.cs
  2. +39
    -38
      IPA.Loader/Logging/LogPrinter.cs
  3. +153
    -116
      IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs
  4. +1
    -1
      IPA.Loader/Logging/StdoutInterceptor.cs

+ 8
- 0
IPA.Loader/Config/SelfConfig.cs View File

@ -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


+ 39
- 38
IPA.Loader/Logging/LogPrinter.cs View File

@ -1,39 +1,40 @@
using System;
namespace IPA.Logging
{
/// <summary>
/// The log printer's base class.
/// </summary>
public abstract class LogPrinter
{
/// <summary>
/// Provides a filter for which log levels to allow through.
/// </summary>
/// <value>the level to filter to</value>
public abstract Logger.LogLevel Filter { get; set; }
/// <summary>
/// Prints a provided message from a given log at the specified time.
/// </summary>
/// <param name="level">the log level</param>
/// <param name="time">the time the message was composed</param>
/// <param name="logName">the name of the log that created this message</param>
/// <param name="message">the message</param>
public abstract void Print(Logger.Level level, DateTime time, string logName, string message);
/// <summary>
/// Called before the first print in a group. May be called multiple times.
/// Use this to create file handles and the like.
/// </summary>
public virtual void StartPrint() { }
/// <summary>
/// Called after the last print in a group. May be called multiple times.
/// Use this to dispose file handles and the like.
/// </summary>
public virtual void EndPrint() { }
internal DateTime LastUse { get; set; }
}
#nullable enable
using System;
namespace IPA.Logging
{
/// <summary>
/// The log printer's base class.
/// </summary>
public abstract class LogPrinter
{
/// <summary>
/// Provides a filter for which log levels to allow through.
/// </summary>
/// <value>the level to filter to</value>
public abstract Logger.LogLevel Filter { get; set; }
/// <summary>
/// Prints a provided message from a given log at the specified time.
/// </summary>
/// <param name="level">the log level</param>
/// <param name="time">the time the message was composed</param>
/// <param name="logName">the name of the log that created this message</param>
/// <param name="message">the message</param>
public abstract void Print(Logger.Level level, DateTime time, string logName, string message);
/// <summary>
/// Called before the first print in a group. May be called multiple times.
/// Use this to create file handles and the like.
/// </summary>
public virtual void StartPrint() { }
/// <summary>
/// Called after the last print in a group. May be called multiple times.
/// Use this to dispose file handles and the like.
/// </summary>
public virtual void EndPrint() { }
internal DateTime LastUse { get; set; }
}
}

+ 153
- 116
IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs View File

@ -1,116 +1,153 @@
using System;
using System.Runtime.InteropServices;
namespace IPA.Logging.Printers
{
/// <summary>
/// Prints a pretty message to the console.
/// </summary>
public class ColoredConsolePrinter : LogPrinter
{
private Logger.LogLevel filter = Logger.LogLevel.All;
/// <summary>
/// A filter for this specific printer.
/// </summary>
/// <value>the filter to apply to this printer</value>
public override Logger.LogLevel Filter { get => filter; set => filter = value; }
/// <summary>
/// The color to print messages as.
/// </summary>
/// <value>the color to print this message as</value>
// 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);
/// <summary>
/// Prints an entry to the console window.
/// </summary>
/// <param name="level">the <see cref="Logger.Level"/> of the message</param>
/// <param name="time">the <see cref="DateTime"/> the message was recorded at</param>
/// <param name="logName">the name of the log that sent the message</param>
/// <param name="message">the message to print</param>
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
{
/// <summary>
/// Prints a pretty message to the console.
/// </summary>
public class ColoredConsolePrinter : LogPrinter
{
private Logger.LogLevel filter = Logger.LogLevel.All;
/// <summary>
/// A filter for this specific printer.
/// </summary>
/// <value>the filter to apply to this printer</value>
public override Logger.LogLevel Filter { get => filter; set => filter = value; }
/// <summary>
/// The color to print messages as.
/// </summary>
/// <value>the color to print this message as</value>
// 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;
}
/// <summary>
/// Prints an entry to the console window.
/// </summary>
/// <param name="level">the <see cref="Logger.Level"/> of the message</param>
/// <param name="time">the <see cref="DateTime"/> the message was recorded at</param>
/// <param name="logName">the name of the log that sent the message</param>
/// <param name="message">the message to print</param>
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);
}
}

+ 1
- 1
IPA.Loader/Logging/StdoutInterceptor.cs View File

@ -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


Loading…
Cancel
Save