From 403616b07c6da6479ce77fd45b41f622e9972915 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 28 Feb 2021 12:39:37 -0500 Subject: fix mods with suppressed warnings counted for showing the log section --- src/SMAPI/Framework/Logging/LogManager.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/SMAPI/Framework/Logging/LogManager.cs') diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 2c7be399..f3656886 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -505,7 +505,7 @@ namespace StardewModdingAPI.Framework.Logging { this.LogModWarningGroup( modsWithWarnings, - match: mod => mod.HasUnsuppressedWarnings(ModWarning.AccessesConsole, ModWarning.AccessesFilesystem, ModWarning.AccessesShell), + match: mod => mod.HasWarnings(ModWarning.AccessesConsole, ModWarning.AccessesFilesystem, ModWarning.AccessesShell), level: LogLevel.Debug, heading: "Direct system access", blurb: new[] @@ -517,11 +517,11 @@ namespace StardewModdingAPI.Framework.Logging modLabel: mod => { List labels = new List(); - if (mod.HasUnsuppressedWarnings(ModWarning.AccessesConsole)) + if (mod.HasWarnings(ModWarning.AccessesConsole)) labels.Add("console"); - if (mod.HasUnsuppressedWarnings(ModWarning.AccessesFilesystem)) + if (mod.HasWarnings(ModWarning.AccessesFilesystem)) labels.Add("files"); - if (mod.HasUnsuppressedWarnings(ModWarning.AccessesShell)) + if (mod.HasWarnings(ModWarning.AccessesShell)) labels.Add("shells/processes"); return $"{mod.DisplayName} ({string.Join(", ", labels)})"; @@ -582,7 +582,7 @@ namespace StardewModdingAPI.Framework.Logging /// A detailed explanation of the warning, split into lines. private void LogModWarningGroup(IModMetadata[] mods, ModWarning warning, LogLevel level, string heading, params string[] blurb) { - this.LogModWarningGroup(mods, mod => mod.HasUnsuppressedWarnings(warning), level, heading, blurb); + this.LogModWarningGroup(mods, mod => mod.HasWarnings(warning), level, heading, blurb); } -- cgit From 0ed46c09104b823a5784690fa50e7022efc12c8f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 7 Mar 2021 18:04:48 -0500 Subject: add descriptive error for PathTooLongException which crashes SMAPI or the installer --- docs/release-notes.md | 3 ++- src/SMAPI.Installer/InteractiveInstaller.cs | 12 ++++++++++++ src/SMAPI.Toolkit/Properties/AssemblyInfo.cs | 1 + src/SMAPI.Toolkit/Utilities/PathUtilities.cs | 25 +++++++++++++++++++++++++ src/SMAPI/Framework/Logging/LogManager.cs | 13 ++++++++++++- 5 files changed, 52 insertions(+), 2 deletions(-) (limited to 'src/SMAPI/Framework/Logging/LogManager.cs') diff --git a/docs/release-notes.md b/docs/release-notes.md index ebe44f09..39e33305 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -9,8 +9,9 @@ ## Upcoming release * For players: - * Fixed console showing _found 1 mod with warnings_ with no mods listed. * If the installer crashes, the window now stays open if possible so you can read the error and ask for help. + * Added descriptive error if possible when a `PathTooLongException` crashes SMAPI or the installer. + * Fixed console showing _found 1 mod with warnings_ with no mods listed. * For mod authors: * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index ff74a659..3d673719 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -279,6 +279,7 @@ namespace StardewModdingApi.Installer /********* ** Step 4: validate assumptions *********/ + // executable exists if (!File.Exists(paths.ExecutablePath)) { this.PrintError("The detected game install path doesn't contain a Stardew Valley executable."); @@ -286,6 +287,17 @@ namespace StardewModdingApi.Installer return; } + // game folder doesn't contain paths beyond the max limit + { + string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray(); + if (tooLongPaths.Any()) + { + this.PrintError($"SMAPI can't install to the detected game folder, because some of its files exceed the maximum {context.Platform} path length.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", tooLongPaths)}"); + Console.ReadLine(); + return; + } + } + /********* ** Step 5: ask what to do diff --git a/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs b/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs index 233e680b..eede4562 100644 --- a/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs +++ b/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("StardewModdingAPI")] +[assembly: InternalsVisibleTo("SMAPI.Installer")] [assembly: InternalsVisibleTo("SMAPI.Web")] diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index c9fb6213..a394edba 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.Contracts; using System.IO; using System.Linq; @@ -133,5 +134,29 @@ namespace StardewModdingAPI.Toolkit.Utilities { return !Regex.IsMatch(str, "[^a-z0-9_.-]", RegexOptions.IgnoreCase); } + + /// Get the paths which exceed the OS length limit. + /// The root path to search. + internal static IEnumerable GetTooLongPaths(string rootPath) + { + return Directory + .EnumerateFileSystemEntries(rootPath, "*.*", SearchOption.AllDirectories) + .Where(PathUtilities.IsPathTooLong); + } + + /// Get whether a file or directory path exceeds the OS path length limit. + /// The path to test. + internal static bool IsPathTooLong(string path) + { + try + { + _ = Path.GetFullPath(path); + return false; + } + catch (PathTooLongException) + { + return true; + } + } } } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index f3656886..0dd45355 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -252,11 +252,22 @@ namespace StardewModdingAPI.Framework.Logging break; // missing content folder exception - case FileNotFoundException ex when ex.Message == "Could not find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path + case FileNotFoundException ex when ex.Message == "Couldn't find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path this.Monitor.Log("The game can't find its Content\\XACT\\FarmerSounds.xgs file. You can usually fix this by resetting your content files (see https://smapi.io/troubleshoot#reset-content ), or by uninstalling and reinstalling the game.", LogLevel.Error); this.Monitor.Log($"Technical details: {ex.GetLogSummary()}"); break; + // path too long exception + case PathTooLongException: + { + string[] affectedPaths = PathUtilities.GetTooLongPaths(Constants.ModsPath).ToArray(); + string message = affectedPaths.Any() + ? $"SMAPI can't launch because some of your mod files exceed the maximum path length on {Constants.Platform}.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", affectedPaths)}" + : $"The game failed to launch: {exception.GetLogSummary()}"; + this.MonitorForGame.Log(message, LogLevel.Error); + } + break; + // generic exception default: this.MonitorForGame.Log($"The game failed to launch: {exception.GetLogSummary()}", LogLevel.Error); -- cgit