summaryrefslogtreecommitdiff
path: root/src/SMAPI.Toolkit/Framework/GameScanning
diff options
context:
space:
mode:
authorpizzaoverhead <pizzaoverhead@gmail.com>2022-09-29 13:33:45 +0100
committerpizzaoverhead <pizzaoverhead@gmail.com>2022-09-29 13:33:45 +0100
commitc6b3446e9cb1d1e02db9db86f143ecfe75e9908c (patch)
treeb93bf794a96b6086f6a0ca59f75a90c74729ecce /src/SMAPI.Toolkit/Framework/GameScanning
parentc0e31d17a6d3f235c8a251e851c446e00c804cdb (diff)
downloadSMAPI-c6b3446e9cb1d1e02db9db86f143ecfe75e9908c.tar.gz
SMAPI-c6b3446e9cb1d1e02db9db86f143ecfe75e9908c.tar.bz2
SMAPI-c6b3446e9cb1d1e02db9db86f143ecfe75e9908c.zip
Added checking for alternative Steam library install locations when looking for the Stardew Valley install.
Diffstat (limited to 'src/SMAPI.Toolkit/Framework/GameScanning')
-rw-r--r--src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs36
-rw-r--r--src/SMAPI.Toolkit/Framework/GameScanning/SteamLibraryCollection.cs47
2 files changed, 83 insertions, 0 deletions
diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs
index 8e1538a5..8e24dcdf 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
@@ -158,7 +159,14 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning
// 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");
+
+ // Check for Steam libraries in other locations
+ string? path = this.GetPathFromSteamLibrary(steamPath);
+ if (!string.IsNullOrWhiteSpace(path))
+ yield return path;
+ }
#endif
// default GOG/Steam paths
@@ -243,6 +251,34 @@ 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)
+ {
+ string stardewAppId = "413150";
+ if (steamPath != null)
+ {
+ string? libraryFoldersPath = Path.Combine(steamPath.Replace('/', '\\'), "steamapps\\libraryfolders.vdf");
+ using FileStream fs = File.OpenRead(libraryFoldersPath);
+ VdfDeserializer deserializer = new VdfDeserializer();
+ SteamLibraryCollection libraries = deserializer.Deserialize<SteamLibraryCollection>(fs);
+ if (libraries.libraryfolders != null)
+ {
+ var stardewLibrary = libraries.libraryfolders.FirstOrDefault(f =>
+ {
+ var apps = f.Value?.apps;
+ return apps != null && apps.Any(a => a.Key.Equals(stardewAppId));
+ });
+ if (stardewLibrary.Value?.path != null)
+ {
+ return Path.Combine(stardewLibrary.Value.path.Replace("\\\\", "\\"), @"steamapps\common\Stardew Valley");
+ }
+ }
+ }
+ return null;
+ }
#endif
}
}
diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/SteamLibraryCollection.cs b/src/SMAPI.Toolkit/Framework/GameScanning/SteamLibraryCollection.cs
new file mode 100644
index 00000000..7a186f69
--- /dev/null
+++ b/src/SMAPI.Toolkit/Framework/GameScanning/SteamLibraryCollection.cs
@@ -0,0 +1,47 @@
+#if SMAPI_FOR_WINDOWS
+using System.Collections.Generic;
+
+namespace StardewModdingAPI.Toolkit.Framework.GameScanning
+{
+#pragma warning disable IDE1006 // Model requires lowercase naming.
+#pragma warning disable CS8618 // Required for model.
+ /// <summary>Model for Steam's libraryfolders.vdf.</summary>
+ public class SteamLibraryCollection
+ {
+ /// <summary>Each entry identifies a different location that part of the Steam games library is installed to.</summary>
+ public LibraryFolders<int, LibraryFolder> libraryfolders { get; set; }
+ }
+
+ /// <summary>A collection of LibraryFolders. Like a dictionary, but has contentstatsid used as an index also.</summary>
+ /// <typeparam name="TKey"></typeparam>
+ /// <typeparam name="TValue"></typeparam>
+#pragma warning disable CS8714 // Required for model.
+ public class LibraryFolders<TKey, TValue> : Dictionary<TKey, TValue>
+#pragma warning restore CS8714
+ {
+ /// <summary>Index of the library, starting from "0".</summary>
+ public string contentstatsid { get; set; }
+ }
+
+ /// <summary>A Steam library folder, containing information on the location and size of games installed there.</summary>
+ public class LibraryFolder
+ {
+ /// <summary>The escaped path to this Steam library folder. There will be a steam.exe here, but this may not be the one the player generally launches.</summary>
+ public string path { get; set; }
+ /// <summary>Label for the library, or ""</summary>
+ public string label { get; set; }
+ /// <summary>~19-digit identifier.</summary>
+ public string contentid { get; set; }
+ /// <summary>Size of the library in bytes. May show 0 when size is non-zero.</summary>
+ public string totalsize { get; set; }
+ /// <summary>Used for downloads.</summary>
+ public string update_clean_bytes_tally { get; set; }
+ /// <summary>Normally "0".</summary>
+ public string time_last_update_corruption { get; set; }
+ /// <summary>List of Steam app IDs, and their current size in bytes.</summary>
+ public Dictionary<string, string> apps { get; set; }
+ }
+#pragma warning restore IDE1006
+#pragma warning restore CS8618
+}
+#endif