diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-06-17 18:51:12 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-09-14 18:05:18 -0400 |
commit | a7544e5afb4ba7f12d248503106cc8d407c2bad1 (patch) | |
tree | 986ee649e5144de93ea03749ea6b041437c899a7 /src/SMAPI.Toolkit/Framework/GameScanning | |
parent | 46a0dd6236a39175e85c11eac44a710db1c07847 (diff) | |
download | SMAPI-a7544e5afb4ba7f12d248503106cc8d407c2bad1.tar.gz SMAPI-a7544e5afb4ba7f12d248503106cc8d407c2bad1.tar.bz2 SMAPI-a7544e5afb4ba7f12d248503106cc8d407c2bad1.zip |
move game detection into toolkit for reuse
Diffstat (limited to 'src/SMAPI.Toolkit/Framework/GameScanning')
-rw-r--r-- | src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs new file mode 100644 index 00000000..1755a7db --- /dev/null +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using StardewModdingAPI.Toolkit.Utilities; +#if SMAPI_FOR_WINDOWS +using Microsoft.Win32; +#endif + +namespace StardewModdingAPI.Toolkit.Framework.GameScanning +{ + /// <summary>Finds installed game folders.</summary> + public class GameScanner + { + /********* + ** Public methods + *********/ + /// <summary>Find all valid Stardew Valley install folders.</summary> + /// <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 + Platform platform = EnvironmentUtility.DetectPlatform(); + string executableFilename = EnvironmentUtility.GetExecutableName(platform); + IEnumerable<string> paths = this.GetDefaultInstallPaths(platform).Select(PathUtilities.NormalisePathSeparators).Distinct(StringComparer.InvariantCultureIgnoreCase); + + // get valid folders + foreach (string path in paths) + { + DirectoryInfo folder = new DirectoryInfo(path); + if (folder.Exists && folder.EnumerateFiles(executableFilename).Any()) + yield return folder; + } + } + + + /********* + ** Private methods + *********/ + /// <summary>The default file paths where Stardew Valley can be installed.</summary> + /// <param name="platform">The target platform.</param> + /// <remarks>Derived from the crossplatform mod config: https://github.com/Pathoschild/Stardew.ModBuildConfig. </remarks> + private IEnumerable<string> GetDefaultInstallPaths(Platform platform) + { + switch (platform) + { + case Platform.Linux: + case Platform.Mac: + { + string home = Environment.GetEnvironmentVariable("HOME"); + + // Linux + yield return $"{home}/GOG Games/Stardew Valley/game"; + yield return Directory.Exists($"{home}/.steam/steam/steamapps/common/Stardew Valley") + ? $"{home}/.steam/steam/steamapps/common/Stardew Valley" + : $"{home}/.local/share/Steam/steamapps/common/Stardew Valley"; + + // Mac + yield return "/Applications/Stardew Valley.app/Contents/MacOS"; + yield return $"{home}/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS"; + } + break; + + case Platform.Windows: + { + // Windows + foreach (string programFiles in new[] { @"C:\Program Files", @"C:\Program Files (x86)" }) + { + yield return $@"{programFiles}\GalaxyClient\Games\Stardew Valley"; + yield return $@"{programFiles}\GOG Galaxy\Games\Stardew Valley"; + yield return $@"{programFiles}\Steam\steamapps\common\Stardew Valley"; + } + + // Windows registry +#if SMAPI_FOR_WINDOWS + IDictionary<string, string> registryKeys = new Dictionary<string, string> + { + [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150"] = "InstallLocation", // Steam + [@"SOFTWARE\WOW6432Node\GOG.com\Games\1453375253"] = "PATH", // GOG on 64-bit Windows + }; + foreach (var pair in registryKeys) + { + string path = this.GetLocalMachineRegistryValue(pair.Key, pair.Value); + if (!string.IsNullOrWhiteSpace(path)) + yield return path; + } + + // via Steam library path + string steampath = this.GetCurrentUserRegistryValue(@"Software\Valve\Steam", "SteamPath"); + if (steampath != null) + yield return Path.Combine(steampath.Replace('/', '\\'), @"steamapps\common\Stardew Valley"); +#endif + } + break; + + default: + throw new InvalidOperationException($"Unknown platform '{platform}'."); + } + } + +#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> + /// <param name="name">The name of the value.</param> + private string GetLocalMachineRegistryValue(string key, string name) + { + RegistryKey localMachine = Environment.Is64BitOperatingSystem ? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) : Registry.LocalMachine; + RegistryKey openKey = localMachine.OpenSubKey(key); + if (openKey == null) + return null; + using (openKey) + return (string)openKey.GetValue(name); + } + + /// <summary>Get the value of a key in the Windows HKCU registry.</summary> + /// <param name="key">The full path of the registry key relative to HKCU.</param> + /// <param name="name">The name of the value.</param> + private string GetCurrentUserRegistryValue(string key, string name) + { + RegistryKey currentuser = Environment.Is64BitOperatingSystem ? RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64) : Registry.CurrentUser; + RegistryKey openKey = currentuser.OpenSubKey(key); + if (openKey == null) + return null; + using (openKey) + return (string)openKey.GetValue(name); + } +#endif + } +} |