diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index 1755a7db..60c7a682 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Xml.Linq; +using System.Xml.XPath; using StardewModdingAPI.Toolkit.Utilities; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; @@ -19,12 +21,18 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning /// <remarks>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.</remarks> public IEnumerable<DirectoryInfo> Scan() { - // get unique candidate paths + // get OS info Platform platform = EnvironmentUtility.DetectPlatform(); string executableFilename = EnvironmentUtility.GetExecutableName(platform); - IEnumerable<string> paths = this.GetDefaultInstallPaths(platform).Select(PathUtilities.NormalisePathSeparators).Distinct(StringComparer.InvariantCultureIgnoreCase); - // get valid folders + // get install paths + IEnumerable<string> paths = this + .GetCustomInstallPaths(platform) + .Concat(this.GetDefaultInstallPaths(platform)) + .Select(PathUtilities.NormalisePathSeparators) + .Distinct(StringComparer.InvariantCultureIgnoreCase); + + // yield valid folders foreach (string path in paths) { DirectoryInfo folder = new DirectoryInfo(path); @@ -98,6 +106,38 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning } } + /// <summary>Get the custom install path from the <c>stardewvalley.targets</c> file in the home directory, if any.</summary> + /// <param name="platform">The target platform.</param> + private IEnumerable<string> GetCustomInstallPaths(Platform platform) + { + // get home path + string homePath = Environment.GetEnvironmentVariable(platform == Platform.Windows ? "USERPROFILE" : "HOME"); + if (string.IsNullOrWhiteSpace(homePath)) + yield break; + + // get targets file + FileInfo file = new FileInfo(Path.Combine(homePath, "stardewvalley.targets")); + if (!file.Exists) + yield break; + + // parse file + XElement root; + try + { + using (FileStream stream = file.OpenRead()) + root = XElement.Load(stream); + } + catch + { + yield break; + } + + // get install path + XElement element = root.XPathSelectElement("//*[local-name() = 'GamePath']"); // can't use '//GamePath' due to the default namespace + if (!string.IsNullOrWhiteSpace(element?.Value)) + yield return element.Value.Trim(); + } + #if SMAPI_FOR_WINDOWS /// <summary>Get the value of a key in the Windows HKLM registry.</summary> /// <param name="key">The full path of the registry key relative to HKLM.</param> |