using System; namespace StardewModdingAPI.Framework.Logging { /// Manages console output interception. internal class ConsoleInterceptionManager : IDisposable { /********* ** Properties *********/ /// The intercepting console writer. private readonly InterceptingTextWriter Output; /********* ** Accessors *********/ /// Whether the current console supports color formatting. public bool SupportsColor { get; } /// The event raised when a message is written to the console directly. public event Action OnMessageIntercepted; /********* ** Public methods *********/ /// Construct an instance. public ConsoleInterceptionManager() { // redirect output through interceptor this.Output = new InterceptingTextWriter(Console.Out); this.Output.OnMessageIntercepted += line => this.OnMessageIntercepted?.Invoke(line); Console.SetOut(this.Output); // test color support this.SupportsColor = this.TestColorSupport(); } /// Get an exclusive lock and write to the console output without interception. /// The action to perform within the exclusive write block. public void ExclusiveWriteWithoutInterception(Action action) { lock (Console.Out) { try { this.Output.ShouldIntercept = false; action(); } finally { this.Output.ShouldIntercept = true; } } } /// Release all resources. public void Dispose() { Console.SetOut(this.Output.Out); this.Output.Dispose(); } /********* ** private methods *********/ /// Test whether the current console supports color formatting. private bool TestColorSupport() { try { this.ExclusiveWriteWithoutInterception(() => { Console.ForegroundColor = Console.ForegroundColor; }); return true; } catch (Exception) { return false; // Mono bug } } } }