summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/Logging
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-01 18:16:09 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-01 18:16:09 -0400
commitc8ad50dad1d706a1901798f9396f6becfea36c0e (patch)
tree28bd818a5db39ec5ece1bd141a28de955950463b /src/SMAPI/Framework/Logging
parent451b70953ff4c0b1b27ae0de203ad99379b45b2a (diff)
parentf78093bdb58d477b400cde3f19b70ffd6ddf833d (diff)
downloadSMAPI-c8ad50dad1d706a1901798f9396f6becfea36c0e.tar.gz
SMAPI-c8ad50dad1d706a1901798f9396f6becfea36c0e.tar.bz2
SMAPI-c8ad50dad1d706a1901798f9396f6becfea36c0e.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework/Logging')
-rw-r--r--src/SMAPI/Framework/Logging/InterceptingTextWriter.cs22
-rw-r--r--src/SMAPI/Framework/Logging/LogFileManager.cs2
-rw-r--r--src/SMAPI/Framework/Logging/LogManager.cs32
3 files changed, 30 insertions, 26 deletions
diff --git a/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs b/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs
index bad69a2a..9ecc1626 100644
--- a/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs
+++ b/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs
@@ -8,6 +8,13 @@ namespace StardewModdingAPI.Framework.Logging
internal class InterceptingTextWriter : TextWriter
{
/*********
+ ** Fields
+ *********/
+ /// <summary>The event raised when a message is written to the console directly.</summary>
+ private readonly Action<string> OnMessageIntercepted;
+
+
+ /*********
** Accessors
*********/
/// <summary>Prefixing a message with this character indicates that the console interceptor should write the string without intercepting it. (The character itself is not written.)</summary>
@@ -19,9 +26,6 @@ namespace StardewModdingAPI.Framework.Logging
/// <inheritdoc />
public override Encoding Encoding => this.Out.Encoding;
- /// <summary>The event raised when a message is written to the console directly.</summary>
- public event Action<string> OnMessageIntercepted;
-
/// <summary>Whether the text writer should ignore the next input if it's a newline.</summary>
/// <remarks>This is used when log output is suppressed from the console, since <c>Console.WriteLine</c> writes the trailing newline as a separate call.</remarks>
public bool IgnoreNextIfNewline { get; set; }
@@ -32,9 +36,11 @@ namespace StardewModdingAPI.Framework.Logging
*********/
/// <summary>Construct an instance.</summary>
/// <param name="output">The underlying output writer.</param>
- public InterceptingTextWriter(TextWriter output)
+ /// <param name="onMessageIntercepted">The event raised when a message is written to the console directly.</param>
+ public InterceptingTextWriter(TextWriter output, Action<string> onMessageIntercepted)
{
this.Out = output;
+ this.OnMessageIntercepted = onMessageIntercepted;
}
/// <inheritdoc />
@@ -63,7 +69,7 @@ namespace StardewModdingAPI.Framework.Logging
this.Out.Write(buffer, index, count);
}
else
- this.OnMessageIntercepted?.Invoke(new string(buffer, index, count));
+ this.OnMessageIntercepted(new string(buffer, index, count));
}
/// <inheritdoc />
@@ -72,12 +78,6 @@ namespace StardewModdingAPI.Framework.Logging
this.Out.Write(ch);
}
- /// <inheritdoc />
- protected override void Dispose(bool disposing)
- {
- this.OnMessageIntercepted = null;
- }
-
/*********
** Private methods
diff --git a/src/SMAPI/Framework/Logging/LogFileManager.cs b/src/SMAPI/Framework/Logging/LogFileManager.cs
index 6ab2bdfb..b396091a 100644
--- a/src/SMAPI/Framework/Logging/LogFileManager.cs
+++ b/src/SMAPI/Framework/Logging/LogFileManager.cs
@@ -30,7 +30,7 @@ namespace StardewModdingAPI.Framework.Logging
this.Path = path;
// create log directory if needed
- string logDir = System.IO.Path.GetDirectoryName(path);
+ string? logDir = System.IO.Path.GetDirectoryName(path);
if (logDir == null)
throw new ArgumentException($"The log path '{path}' is not valid.");
Directory.CreateDirectory(logDir);
diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs
index a8a8b6ee..b94807b5 100644
--- a/src/SMAPI/Framework/Logging/LogManager.cs
+++ b/src/SMAPI/Framework/Logging/LogManager.cs
@@ -93,23 +93,26 @@ namespace StardewModdingAPI.Framework.Logging
/// <param name="getScreenIdForLog">Get the screen ID that should be logged to distinguish between players in split-screen mode, if any.</param>
public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, bool isVerbose, bool isDeveloperMode, Func<int?> getScreenIdForLog)
{
- // init construction logic
+ // init log file
+ this.LogFile = new LogFileManager(logPath);
+
+ // init monitor
this.GetMonitorImpl = name => new Monitor(name, LogManager.IgnoreChar, this.LogFile, colorConfig, isVerbose, getScreenIdForLog)
{
WriteToConsole = writeToConsole,
ShowTraceInConsole = isDeveloperMode,
ShowFullStampInConsole = isDeveloperMode
};
-
- // init fields
- this.LogFile = new LogFileManager(logPath);
this.Monitor = this.GetMonitor("SMAPI");
this.MonitorForGame = this.GetMonitor("game");
// redirect direct console output
- this.ConsoleInterceptor = new InterceptingTextWriter(Console.Out);
- if (writeToConsole)
- this.ConsoleInterceptor.OnMessageIntercepted += message => this.HandleConsoleMessage(this.MonitorForGame, message);
+ this.ConsoleInterceptor = new InterceptingTextWriter(
+ output: Console.Out,
+ onMessageIntercepted: writeToConsole
+ ? message => this.HandleConsoleMessage(this.MonitorForGame, message)
+ : _ => { }
+ );
Console.SetOut(this.ConsoleInterceptor);
// enable Unicode handling on Windows
@@ -154,7 +157,7 @@ namespace StardewModdingAPI.Framework.Logging
while (true)
{
// get input
- string input = Console.ReadLine();
+ string? input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
continue;
@@ -220,7 +223,7 @@ namespace StardewModdingAPI.Framework.Logging
if (File.Exists(Constants.UpdateMarker))
{
string[] rawUpdateFound = File.ReadAllText(Constants.UpdateMarker).Split(new[] { '|' }, 2);
- if (SemanticVersion.TryParse(rawUpdateFound[0], out ISemanticVersion updateFound))
+ if (SemanticVersion.TryParse(rawUpdateFound[0], out ISemanticVersion? updateFound))
{
if (Constants.ApiVersion.IsPrerelease() && updateFound.IsNewerThan(Constants.ApiVersion))
{
@@ -262,7 +265,7 @@ namespace StardewModdingAPI.Framework.Logging
/// <summary>Log the initial header with general SMAPI and system details.</summary>
/// <param name="modsPath">The path from which mods will be loaded.</param>
/// <param name="customSettings">The custom SMAPI settings.</param>
- public void LogIntro(string modsPath, IDictionary<string, object> customSettings)
+ public void LogIntro(string modsPath, IDictionary<string, object?> customSettings)
{
// log platform
this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} (build {Constants.GetBuildVersionLabel()}) on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info);
@@ -324,7 +327,7 @@ namespace StardewModdingAPI.Framework.Logging
// log loaded content packs
if (loadedContentPacks.Any())
{
- string GetModDisplayName(string id) => loadedMods.FirstOrDefault(p => p.HasID(id))?.DisplayName;
+ string? GetModDisplayName(string id) => loadedMods.FirstOrDefault(p => p.HasID(id))?.DisplayName;
this.Monitor.Log($"Loaded {loadedContentPacks.Length} content packs:", LogLevel.Info);
foreach (IModMetadata metadata in loadedContentPacks.OrderBy(p => p.DisplayName))
@@ -333,7 +336,7 @@ namespace StardewModdingAPI.Framework.Logging
this.Monitor.Log(
$" {metadata.DisplayName} {manifest.Version}"
+ (!string.IsNullOrWhiteSpace(manifest.Author) ? $" by {manifest.Author}" : "")
- + $" | for {GetModDisplayName(metadata.Manifest.ContentPackFor.UniqueID)}"
+ + $" | for {GetModDisplayName(metadata.Manifest.ContentPackFor!.UniqueID)}"
+ (!string.IsNullOrWhiteSpace(manifest.Description) ? $" | {manifest.Description}" : ""),
LogLevel.Info
);
@@ -396,6 +399,7 @@ namespace StardewModdingAPI.Framework.Logging
/// <param name="mods">The loaded mods.</param>
/// <param name="skippedMods">The mods which could not be loaded.</param>
/// <param name="logParanoidWarnings">Whether to log issues for mods which directly use potentially sensitive .NET APIs like file or shell access.</param>
+ [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "Manifests aren't guaranteed non-null at this point in the loading process.")]
private void LogModWarnings(IEnumerable<IModMetadata> mods, IModMetadata[] skippedMods, bool logParanoidWarnings)
{
// get mods with warnings
@@ -429,7 +433,7 @@ namespace StardewModdingAPI.Framework.Logging
// duplicate mod: log first one only, don't show redundant version
if (mod.FailReason == ModFailReason.Duplicate && mod.HasManifest())
{
- if (loggedDuplicateIds.Add(mod.Manifest.UniqueID))
+ if (loggedDuplicateIds.Add(mod.Manifest!.UniqueID))
continue; // already logged
message = $" - {mod.DisplayName} because {mod.Error}";
@@ -608,7 +612,7 @@ namespace StardewModdingAPI.Framework.Logging
/// <param name="heading">A brief heading label for the group.</param>
/// <param name="blurb">A detailed explanation of the warning, split into lines.</param>
/// <param name="modLabel">Formats the mod label, or <c>null</c> to use the <see cref="IModMetadata.DisplayName"/>.</param>
- private void LogModWarningGroup(IModMetadata[] mods, Func<IModMetadata, bool> match, LogLevel level, string heading, string[] blurb, Func<IModMetadata, string> modLabel = null)
+ private void LogModWarningGroup(IModMetadata[] mods, Func<IModMetadata, bool> match, LogLevel level, string heading, string[] blurb, Func<IModMetadata, string>? modLabel = null)
{
// get matching mods
string[] modLabels = mods