From c627348c25774600e83248182336bdc857feda0a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 23 Nov 2020 18:20:52 -0500 Subject: let players specify game path by running the installer from within it --- .../Framework/GameScanning/GameScanner.cs | 48 +++++++++++++++------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'src/SMAPI.Toolkit/Framework') diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index 825988a5..d4c82180 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -14,21 +14,34 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning /// Finds installed game folders. public class GameScanner { + /********* + ** Fields + *********/ + /// The current OS. + private readonly Platform Platform; + + /// The name of the Stardew Valley executable. + private readonly string ExecutableName; + + /********* ** Public methods *********/ + /// Construct an instance. + public GameScanner() + { + this.Platform = EnvironmentUtility.DetectPlatform(); + this.ExecutableName = EnvironmentUtility.GetExecutableName(this.Platform); + } + /// Find all valid Stardew Valley install folders. /// This checks default game locations, and on Windows checks the Windows registry for GOG/Steam install data. A folder is considered 'valid' if it contains the Stardew Valley executable for the current OS. public IEnumerable Scan() { - // get OS info - Platform platform = EnvironmentUtility.DetectPlatform(); - string executableFilename = EnvironmentUtility.GetExecutableName(platform); - // get install paths IEnumerable paths = this - .GetCustomInstallPaths(platform) - .Concat(this.GetDefaultInstallPaths(platform)) + .GetCustomInstallPaths() + .Concat(this.GetDefaultInstallPaths()) .Select(PathUtilities.NormalizePath) .Distinct(StringComparer.OrdinalIgnoreCase); @@ -36,21 +49,27 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning foreach (string path in paths) { DirectoryInfo folder = new DirectoryInfo(path); - if (folder.Exists && folder.EnumerateFiles(executableFilename).Any()) + if (this.LooksLikeGameFolder(folder)) yield return folder; } } + /// Get whether a folder seems to contain the game. + /// The folder to check. + public bool LooksLikeGameFolder(DirectoryInfo dir) + { + return dir.Exists && dir.EnumerateFiles(this.ExecutableName).Any(); + } + /********* ** Private methods *********/ /// The default file paths where Stardew Valley can be installed. - /// The target platform. - /// Derived from the crossplatform mod config: https://github.com/Pathoschild/Stardew.ModBuildConfig. - private IEnumerable GetDefaultInstallPaths(Platform platform) + /// Derived from the crossplatform mod config. + private IEnumerable GetDefaultInstallPaths() { - switch (platform) + switch (this.Platform) { case Platform.Linux: case Platform.Mac: @@ -102,16 +121,15 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning break; default: - throw new InvalidOperationException($"Unknown platform '{platform}'."); + throw new InvalidOperationException($"Unknown platform '{this.Platform}'."); } } /// Get the custom install path from the stardewvalley.targets file in the home directory, if any. - /// The target platform. - private IEnumerable GetCustomInstallPaths(Platform platform) + private IEnumerable GetCustomInstallPaths() { // get home path - string homePath = Environment.GetEnvironmentVariable(platform == Platform.Windows ? "USERPROFILE" : "HOME"); + string homePath = Environment.GetEnvironmentVariable(this.Platform == Platform.Windows ? "USERPROFILE" : "HOME"); if (string.IsNullOrWhiteSpace(homePath)) yield break; -- cgit From 1c70736c00e6e70f46f539cb26b5fd253f4eff3b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 8 Dec 2020 08:23:16 -0500 Subject: clarify not-a-mod error when SMAPI installer is in mods folder --- docs/release-notes.md | 1 + src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs | 10 ++++++++++ 2 files changed, 11 insertions(+) (limited to 'src/SMAPI.Toolkit/Framework') diff --git a/docs/release-notes.md b/docs/release-notes.md index 8043212e..0bbbeb58 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -10,6 +10,7 @@ ## Upcoming release * For players: * When the installer is run from within a game folder, it now installs SMAPI to that folder. That simplifies installation if you have multiple copies of the game or it can't otherwise auto-detect the game path. + * Clarified not-a-mod error when the SMAPI installer is in the `Mods` folder. ## 3.7.6 Released 21 November 2020 for Stardew Valley 1.4.1 or later. diff --git a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs index 6d6b6417..5eacee9e 100644 --- a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs +++ b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs @@ -112,10 +112,20 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning if (manifestFile == null) { FileInfo[] files = this.RecursivelyGetRelevantFiles(searchFolder).ToArray(); + + // empty folder if (!files.Any()) return new ModFolder(root, searchFolder, ModType.Invalid, null, ModParseError.EmptyFolder, "it's an empty folder."); + + // XNB mod if (files.All(this.IsPotentialXnbFile)) return new ModFolder(root, searchFolder, ModType.Xnb, null, ModParseError.XnbMod, "it's not a SMAPI mod (see https://smapi.io/xnb for info)."); + + // SMAPI installer + if (files.Any(p => p.Name == "install on Linux.sh" || p.Name == "install on Mac.command" || p.Name == "install on Windows.bat")) + return new ModFolder(root, searchFolder, ModType.Invalid, null, ModParseError.ManifestMissing, "the SMAPI installer isn't a mod (you can delete this folder after running the installer file)."); + + // not a mod? return new ModFolder(root, searchFolder, ModType.Invalid, null, ModParseError.ManifestMissing, "it contains files, but none of them are manifest.json."); } -- cgit