summaryrefslogtreecommitdiff
path: root/src/SMAPI.Toolkit/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Toolkit/Framework')
-rw-r--r--src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs50
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
}
}