diff options
Diffstat (limited to 'src/SMAPI.Toolkit/Framework')
-rw-r--r-- | src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index 8e1538a5..66465ffe 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -9,6 +9,7 @@ using StardewModdingAPI.Toolkit.Utilities; using System.Reflection; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; +using VdfParser; #endif namespace StardewModdingAPI.Toolkit.Framework.GameScanning @@ -23,6 +24,9 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning /// <summary>The current OS.</summary> private readonly Platform Platform; + /// <summary>The Steam app ID for Stardew Valley.</summary> + private const string SteamAppId = "413150"; + /********* ** Public methods @@ -145,7 +149,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning #if SMAPI_FOR_WINDOWS IDictionary<string, string> registryKeys = new Dictionary<string, string> { - [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150"] = "InstallLocation", // Steam + [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App " + GameScanner.SteamAppId] = "InstallLocation", // Steam [@"SOFTWARE\WOW6432Node\GOG.com\Games\1453375253"] = "PATH", // GOG on 64-bit Windows }; foreach (var pair in registryKeys) @@ -158,7 +162,15 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning // via Steam library path string? steamPath = this.GetCurrentUserRegistryValue(@"Software\Valve\Steam", "SteamPath"); if (steamPath != null) + { + // conventional path yield return Path.Combine(steamPath.Replace('/', '\\'), @"steamapps\common\Stardew Valley"); + + // from Steam's .vdf file + string? path = this.GetPathFromSteamLibrary(steamPath); + if (!string.IsNullOrWhiteSpace(path)) + yield return path; + } #endif // default GOG/Steam paths @@ -243,6 +255,42 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning using (openKey) return (string?)openKey.GetValue(name); } + + /// <summary>Get the game directory path from alternative Steam library locations.</summary> + /// <param name="steamPath">The full path to the directory containing steam.exe.</param> + /// <returns>The game directory, if found.</returns> + private string? GetPathFromSteamLibrary(string? steamPath) + { + if (steamPath == null) + return null; + + // get raw .vdf data + string libraryFoldersPath = Path.Combine(steamPath.Replace('/', '\\'), "steamapps\\libraryfolders.vdf"); + using FileStream fileStream = File.OpenRead(libraryFoldersPath); + VdfDeserializer deserializer = new(); + dynamic libraries = deserializer.Deserialize(fileStream); + if (libraries?.libraryfolders is null) + return null; + + // get path from Stardew Valley app (if any) + foreach (dynamic pair in libraries.libraryfolders) + { + dynamic library = pair.Value; + + foreach (dynamic app in library.apps) + { + string key = app.Key; + if (key == GameScanner.SteamAppId) + { + string path = library.path; + + return Path.Combine(path.Replace("\\\\", "\\"), "steamapps", "common", "Stardew Valley"); + } + } + } + + return null; + } #endif } } |