ConsoleManager.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using System;
  2. using System.ComponentModel;
  3. using System.IO;
  4. using System.Text;
  5. using BepInEx.Configuration;
  6. using BepInEx.Unix;
  7. using MonoMod.Utils;
  8. namespace BepInEx
  9. {
  10. public static class ConsoleManager
  11. {
  12. private const uint SHIFT_JIS_CP = 932;
  13. internal static IConsoleDriver Driver { get; set; }
  14. /// <summary>
  15. /// True if an external console has been started, false otherwise.
  16. /// </summary>
  17. public static bool ConsoleActive => Driver?.ConsoleActive ?? false;
  18. /// <summary>
  19. /// The stream that writes to the standard out stream of the process. Should never be null.
  20. /// </summary>
  21. public static TextWriter StandardOutStream => Driver?.StandardOut;
  22. /// <summary>
  23. /// The stream that writes to an external console. Null if no such console exists
  24. /// </summary>
  25. public static TextWriter ConsoleStream => Driver?.ConsoleOut;
  26. public static void Initialize(bool alreadyActive)
  27. {
  28. switch (Utility.CurrentPlatform)
  29. {
  30. case Platform.MacOS:
  31. case Platform.Linux:
  32. {
  33. Driver = new LinuxConsoleDriver();
  34. break;
  35. }
  36. case Platform.Windows:
  37. {
  38. Driver = new WindowsConsoleDriver();
  39. break;
  40. }
  41. }
  42. Driver.Initialize(alreadyActive);
  43. }
  44. private static void DriverCheck()
  45. {
  46. if (Driver == null)
  47. throw new InvalidOperationException("Driver has not been initialized");
  48. }
  49. public static void CreateConsole()
  50. {
  51. if (ConsoleActive)
  52. return;
  53. DriverCheck();
  54. // Apparently some versions of Mono throw a "Encoding name 'xxx' not supported"
  55. // if you use Encoding.GetEncoding
  56. // That's why we use of codepages directly and handle then in console drivers separately
  57. var codepage = ConfigConsoleShiftJis.Value ? SHIFT_JIS_CP: (uint)Encoding.UTF8.CodePage;
  58. Driver.CreateConsole(codepage);
  59. }
  60. public static void DetachConsole()
  61. {
  62. if (!ConsoleActive)
  63. return;
  64. DriverCheck();
  65. Driver.DetachConsole();
  66. }
  67. public static void SetConsoleTitle(string title)
  68. {
  69. DriverCheck();
  70. Driver.SetConsoleTitle(title);
  71. }
  72. public static void SetConsoleColor(ConsoleColor color)
  73. {
  74. DriverCheck();
  75. Driver.SetConsoleColor(color);
  76. }
  77. public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind(
  78. "Logging.Console", "Enabled",
  79. false,
  80. "Enables showing a console for log output.");
  81. public static readonly ConfigEntry<bool> ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind(
  82. "Logging.Console", "ShiftJisEncoding",
  83. false,
  84. "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.");
  85. public static readonly ConfigEntry<ConsoleOutRedirectType> ConfigConsoleOutRedirectType = ConfigFile.CoreConfig.Bind(
  86. "Logging.Console", "StandardOutType",
  87. ConsoleOutRedirectType.Auto,
  88. new StringBuilder()
  89. .AppendLine("Hints console manager on what handle to assign as StandardOut. Possible values:")
  90. .AppendLine("Auto - lets BepInEx decide how to redirect console output")
  91. .AppendLine("ConsoleOut - prefer redirecting to console output; if possible, closes original standard output")
  92. .AppendLine("StandardOut - prefer redirecting to standard output; if possible, closes console out")
  93. .ToString()
  94. );
  95. public enum ConsoleOutRedirectType
  96. {
  97. [Description("Auto")] Auto = 0,
  98. [Description("Console Out")] ConsoleOut,
  99. [Description("Standard Out")] StandardOut,
  100. }
  101. }
  102. }