using System; using System.ComponentModel; using System.IO; using System.Text; using BepInEx.Configuration; using BepInEx.Unix; using MonoMod.Utils; namespace BepInEx { public static class ConsoleManager { private const uint SHIFT_JIS_CP = 932; internal static IConsoleDriver Driver { get; set; } /// /// True if an external console has been started, false otherwise. /// public static bool ConsoleActive => Driver?.ConsoleActive ?? false; /// /// The stream that writes to the standard out stream of the process. Should never be null. /// public static TextWriter StandardOutStream => Driver?.StandardOut; /// /// The stream that writes to an external console. Null if no such console exists /// public static TextWriter ConsoleStream => Driver?.ConsoleOut; public static void Initialize(bool alreadyActive) { if (PlatformHelper.Is(Platform.MacOS) || PlatformHelper.Is(Platform.Linux)) { Driver = new LinuxConsoleDriver(); } else if (PlatformHelper.Is(Platform.Windows)) { Driver = new WindowsConsoleDriver(); } else { throw new PlatformNotSupportedException("Was unable to determine console driver for platform " + PlatformHelper.Current); } Driver.Initialize(alreadyActive); } private static void DriverCheck() { if (Driver == null) throw new InvalidOperationException("Driver has not been initialized"); } public static void CreateConsole() { if (ConsoleActive) return; DriverCheck(); // Apparently some versions of Mono throw a "Encoding name 'xxx' not supported" // if you use Encoding.GetEncoding // That's why we use of codepages directly and handle then in console drivers separately var codepage = ConfigConsoleShiftJis.Value ? SHIFT_JIS_CP: (uint)Encoding.UTF8.CodePage; Driver.CreateConsole(codepage); Console.SetOut(ConsoleStream); } public static void DetachConsole() { if (!ConsoleActive) return; DriverCheck(); Driver.DetachConsole(); } public static void SetConsoleTitle(string title) { DriverCheck(); Driver.SetConsoleTitle(title); } public static void SetConsoleColor(ConsoleColor color) { DriverCheck(); Driver.SetConsoleColor(color); } public static readonly ConfigEntry ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind( "Logging.Console", "Enabled", false, "Enables showing a console for log output."); public static readonly ConfigEntry ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind( "Logging.Console", "ShiftJisEncoding", false, "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding."); public static readonly ConfigEntry ConfigConsoleOutRedirectType = ConfigFile.CoreConfig.Bind( "Logging.Console", "StandardOutType", ConsoleOutRedirectType.Auto, new StringBuilder() .AppendLine("Hints console manager on what handle to assign as StandardOut. Possible values:") .AppendLine("Auto - lets BepInEx decide how to redirect console output") .AppendLine("ConsoleOut - prefer redirecting to console output; if possible, closes original standard output") .AppendLine("StandardOut - prefer redirecting to standard output; if possible, closes console out") .ToString() ); public enum ConsoleOutRedirectType { [Description("Auto")] Auto = 0, [Description("Console Out")] ConsoleOut, [Description("Standard Out")] StandardOut, } } }