ConsoleManager.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using BepInEx.Configuration;
  5. using BepInEx.Unix;
  6. using BepInEx.ConsoleUtil;
  7. using HarmonyLib;
  8. using UnityInjector.ConsoleUtil;
  9. namespace BepInEx
  10. {
  11. public static class ConsoleManager
  12. {
  13. /// <summary>
  14. /// True if an external console has been started, false otherwise.
  15. /// </summary>
  16. public static bool ConsoleActive { get; private set; }
  17. /// <summary>
  18. /// The stream that writes to the standard out stream of the process. Should never be null.
  19. /// </summary>
  20. public static TextWriter StandardOutStream { get; internal set; }
  21. /// <summary>
  22. /// The stream that writes to an external console. Null if no such console exists
  23. /// </summary>
  24. public static TextWriter ConsoleStream { get; internal set; }
  25. public static void Initialize(bool active)
  26. {
  27. StandardOutStream = Console.Out;
  28. Console.SetOut(StandardOutStream);
  29. ConsoleActive = active;
  30. switch (Environment.OSVersion.Platform)
  31. {
  32. case PlatformID.MacOSX:
  33. case PlatformID.Unix:
  34. {
  35. ConsoleActive = true;
  36. var duplicateStream = UnixStreamHelper.CreateDuplicateStream(1);
  37. var writer = ConsoleWriter.CreateConsoleStreamWriter(duplicateStream, Console.Out.Encoding, true);
  38. StandardOutStream = TextWriter.Synchronized(writer);
  39. var driver = AccessTools.Field(AccessTools.TypeByName("System.ConsoleDriver"), "driver").GetValue(null);
  40. AccessTools.Field(AccessTools.TypeByName("System.TermInfoDriver"), "stdout").SetValue(driver, writer);
  41. Console.SetOut(StandardOutStream);
  42. break;
  43. }
  44. }
  45. }
  46. public static void CreateConsole()
  47. {
  48. if (ConsoleActive)
  49. return;
  50. switch (Environment.OSVersion.Platform)
  51. {
  52. case PlatformID.Win32NT:
  53. {
  54. ConsoleWindow.Attach();
  55. break;
  56. }
  57. default:
  58. throw new PlatformNotSupportedException("Spawning a console is not currently supported on this platform");
  59. }
  60. SetConsoleStreams();
  61. ConsoleActive = true;
  62. }
  63. public static void DetachConsole()
  64. {
  65. if (!ConsoleActive)
  66. return;
  67. switch (Environment.OSVersion.Platform)
  68. {
  69. case PlatformID.Win32NT:
  70. {
  71. ConsoleWindow.Detach();
  72. break;
  73. }
  74. default:
  75. throw new PlatformNotSupportedException("Spawning a console is not currently supported on this platform");
  76. }
  77. ConsoleActive = false;
  78. }
  79. public static void SetConsoleEncoding()
  80. {
  81. uint encoding = ConfigConsoleShiftJis.Value ? 932 : (uint)Encoding.UTF8.CodePage;
  82. SetConsoleEncoding(encoding);
  83. }
  84. public static void SetConsoleEncoding(uint encodingCodePage)
  85. {
  86. if (!ConsoleActive)
  87. throw new InvalidOperationException("Console is not currently active");
  88. switch (Environment.OSVersion.Platform)
  89. {
  90. case PlatformID.Win32NT:
  91. {
  92. ConsoleEncoding.ConsoleCodePage = encodingCodePage;
  93. Console.OutputEncoding = Encoding.GetEncoding((int)encodingCodePage);
  94. break;
  95. }
  96. case PlatformID.MacOSX:
  97. case PlatformID.Unix:
  98. {
  99. break;
  100. }
  101. }
  102. }
  103. public static void SetConsoleTitle(string title)
  104. {
  105. switch (Environment.OSVersion.Platform)
  106. {
  107. case PlatformID.Win32NT:
  108. {
  109. if (!ConsoleActive)
  110. return;
  111. ConsoleWindow.Title = title;
  112. break;
  113. }
  114. }
  115. }
  116. public static void SetConsoleColor(ConsoleColor color)
  117. {
  118. switch (Environment.OSVersion.Platform)
  119. {
  120. case PlatformID.Win32NT:
  121. {
  122. if (!ConsoleActive)
  123. return;
  124. Kon.ForegroundColor = color;
  125. break;
  126. }
  127. }
  128. SafeConsole.ForegroundColor = color;
  129. }
  130. internal static void SetConsoleStreams()
  131. {
  132. switch (Environment.OSVersion.Platform)
  133. {
  134. case PlatformID.Win32NT:
  135. {
  136. Console.SetOut(ConsoleStream);
  137. Console.SetError(ConsoleStream);
  138. break;
  139. }
  140. case PlatformID.MacOSX:
  141. case PlatformID.Unix:
  142. {
  143. // We do not have external consoles on Unix platforms.
  144. // Set the console output to standard output
  145. Console.SetOut(StandardOutStream);
  146. Console.SetError(StandardOutStream);
  147. break;
  148. }
  149. }
  150. }
  151. public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind(
  152. "Logging.Console", "Enabled",
  153. false,
  154. "Enables showing a console for log output.");
  155. public static readonly ConfigEntry<bool> ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind(
  156. "Logging.Console", "ShiftJisEncoding",
  157. false,
  158. "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.");
  159. }
  160. }