diff options
Diffstat (limited to 'src/SMAPI/Framework/Logging/LogManager.cs')
-rw-r--r-- | src/SMAPI/Framework/Logging/LogManager.cs | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 5a291d0a..a8a8b6ee 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -25,8 +25,11 @@ namespace StardewModdingAPI.Framework.Logging /// <summary>The log file to which to write messages.</summary> private readonly LogFileManager LogFile; + /// <summary>The text writer which intercepts console output.</summary> + private readonly InterceptingTextWriter ConsoleInterceptor; + /// <summary>Prefixing a low-level message with this character indicates that the console interceptor should write the string without intercepting it. (The character itself is not written.)</summary> - private readonly char IgnoreChar = '\u200B'; + private const char IgnoreChar = InterceptingTextWriter.IgnoreChar; /// <summary>Get a named monitor instance.</summary> private readonly Func<string, Monitor> GetMonitorImpl; @@ -34,22 +37,22 @@ namespace StardewModdingAPI.Framework.Logging /// <summary>Regex patterns which match console non-error messages to suppress from the console and log.</summary> private readonly Regex[] SuppressConsolePatterns = { - new Regex(@"^TextBox\.Selected is now '(?:True|False)'\.$", RegexOptions.Compiled | RegexOptions.CultureInvariant), - new Regex(@"^loadPreferences\(\); begin", RegexOptions.Compiled | RegexOptions.CultureInvariant), - new Regex(@"^savePreferences\(\); async=", RegexOptions.Compiled | RegexOptions.CultureInvariant), - new Regex(@"^DebugOutput:\s+(?:added cricket|dismount tile|Ping|playerPos)", RegexOptions.Compiled | RegexOptions.CultureInvariant), - new Regex(@"^Ignoring keys: ", RegexOptions.Compiled | RegexOptions.CultureInvariant) + new(@"^TextBox\.Selected is now '(?:True|False)'\.$", RegexOptions.Compiled | RegexOptions.CultureInvariant), + new(@"^loadPreferences\(\); begin", RegexOptions.Compiled | RegexOptions.CultureInvariant), + new(@"^savePreferences\(\); async=", RegexOptions.Compiled | RegexOptions.CultureInvariant), + new(@"^DebugOutput:\s+(?:added cricket|dismount tile|Ping|playerPos)", RegexOptions.Compiled | RegexOptions.CultureInvariant), + new(@"^Ignoring keys: ", RegexOptions.Compiled | RegexOptions.CultureInvariant) }; /// <summary>Regex patterns which match console messages to show a more friendly error for.</summary> private readonly ReplaceLogPattern[] ReplaceConsolePatterns = { // Steam not loaded - new ReplaceLogPattern( + new( search: new Regex(@"^System\.InvalidOperationException: Steamworks is not initialized\.[\s\S]+$", RegexOptions.Compiled | RegexOptions.CultureInvariant), replacement: #if SMAPI_FOR_WINDOWS - "Oops! Steam achievements won't work because Steam isn't loaded. See 'Launch SMAPI through Steam or GOG Galaxy' in the install guide for more info: https://smapi.io/install.", + "Oops! Steam achievements won't work because Steam isn't loaded. See 'Configure your game client' in the install guide for more info: https://smapi.io/install.", #else "Oops! Steam achievements won't work because Steam isn't loaded. You can launch the game through Steam to fix that.", #endif @@ -57,7 +60,7 @@ namespace StardewModdingAPI.Framework.Logging ), // save file not found error - new ReplaceLogPattern( + new( search: new Regex(@"^System\.IO\.FileNotFoundException: [^\n]+\n[^:]+: '[^\n]+[/\\]Saves[/\\]([^'\r\n]+)[/\\]([^'\r\n]+)'[\s\S]+LoadGameMenu\.FindSaveGames[\s\S]+$", RegexOptions.Compiled | RegexOptions.CultureInvariant), replacement: "The game can't find the '$2' file for your '$1' save. See https://stardewvalleywiki.com/Saves#Troubleshooting for help.", logLevel: LogLevel.Error @@ -91,7 +94,7 @@ namespace StardewModdingAPI.Framework.Logging public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, bool isVerbose, bool isDeveloperMode, Func<int?> getScreenIdForLog) { // init construction logic - this.GetMonitorImpl = name => new Monitor(name, this.IgnoreChar, this.LogFile, colorConfig, isVerbose, getScreenIdForLog) + this.GetMonitorImpl = name => new Monitor(name, LogManager.IgnoreChar, this.LogFile, colorConfig, isVerbose, getScreenIdForLog) { WriteToConsole = writeToConsole, ShowTraceInConsole = isDeveloperMode, @@ -104,10 +107,10 @@ namespace StardewModdingAPI.Framework.Logging this.MonitorForGame = this.GetMonitor("game"); // redirect direct console output - var output = new InterceptingTextWriter(Console.Out, this.IgnoreChar); + this.ConsoleInterceptor = new InterceptingTextWriter(Console.Out); if (writeToConsole) - output.OnMessageIntercepted += message => this.HandleConsoleMessage(this.MonitorForGame, message); - Console.SetOut(output); + this.ConsoleInterceptor.OnMessageIntercepted += message => this.HandleConsoleMessage(this.MonitorForGame, message); + Console.SetOut(this.ConsoleInterceptor); // enable Unicode handling on Windows // (the terminal defaults to UTF-8 on Linux/macOS) @@ -146,7 +149,7 @@ namespace StardewModdingAPI.Framework.Logging .Add(new ReloadI18nCommand(reloadTranslations), this.Monitor); // start handling command line input - Thread inputThread = new Thread(() => + Thread inputThread = new(() => { while (true) { @@ -262,7 +265,7 @@ namespace StardewModdingAPI.Framework.Logging public void LogIntro(string modsPath, IDictionary<string, object> customSettings) { // log platform - this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); + this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} (build {Constants.GetBuildVersionLabel()}) on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); // log basic info this.Monitor.Log($"Mods go here: {modsPath}", LogLevel.Info); @@ -363,7 +366,10 @@ namespace StardewModdingAPI.Framework.Logging // ignore suppressed message if (level != LogLevel.Error && this.SuppressConsolePatterns.Any(p => p.IsMatch(message))) + { + this.ConsoleInterceptor.IgnoreNextIfNewline = true; return; + } // show friendly error if applicable foreach (ReplaceLogPattern entry in this.ReplaceConsolePatterns) @@ -383,6 +389,7 @@ namespace StardewModdingAPI.Framework.Logging // forward to monitor gameMonitor.Log(message, level); + this.ConsoleInterceptor.IgnoreNextIfNewline = true; } /// <summary>Write a summary of mod warnings to the console and log.</summary> |