ProjectArcade
291 строка · 10.4 Кб
1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.IO;6using Microsoft.Win32;7using Steam_Library_Manager.Framework;8using EmulatorLauncher.Common.Launchers.Steam;9
10namespace EmulatorLauncher.Common.Launchers11{
12public static class SteamLibrary13{14// https://cdn.cloudflare.steamstatic.com/steam/apps/1515950/header.jpg15
16const string GameLaunchUrl = @"steam://rungameid/{0}";17const string HeaderImageUrl = @"https://cdn.cloudflare.steamstatic.com/steam/apps/{0}/header.jpg";18
19public static LauncherGameInfo[] GetInstalledGames()20{21var games = new List<LauncherGameInfo>();22
23string libraryfoldersPath = Path.Combine(GetInstallPath(), "config", "libraryfolders.vdf");24
25try26{27var libraryfolders = new KeyValue();28libraryfolders.ReadFileAsText(libraryfoldersPath);29
30var folders = GetLibraryFolders(libraryfolders);31
32foreach (var folder in folders)33{34var libFolder = Path.Combine(folder, "steamapps");35if (Directory.Exists(libFolder))36{37foreach(var game in GetInstalledGamesFromFolder(libFolder))38{39if (game.Id == "228980")40continue;41
42games.Add(game);43}44}45}46}47catch { }48
49return games.ToArray();50}51
52public static string GetSteamGameExecutableName(Uri uri)53{54string shorturl = uri.AbsolutePath.Substring(1);55int steamAppId = shorturl.ToInteger();56
57string exe = FindExecutableName(steamAppId);58
59if (string.IsNullOrEmpty(exe))60{61SimpleLogger.Instance.Info("[WARNING] Cannot find STEAM game executable");62return null;63}64
65return Path.GetFileNameWithoutExtension(exe);66}67
68static string FindExecutableName(int steamAppId)69{70string path = GetInstallPath();71if (string.IsNullOrEmpty(path))72throw new ApplicationException("Can not find Steam installation folder in registry.");73
74string appinfoPath = Path.Combine(path, "appcache", "appinfo.vdf");75if (!File.Exists(appinfoPath))76SimpleLogger.Instance.Info("[WARNING] Missing file " + appinfoPath);77
78try79{80var reader = new SteamAppInfoReader();81reader.Read(appinfoPath);82
83SimpleLogger.Instance.Info("[INFO] Reading Steam file 'appinfo.vdf'");84
85var app = reader.Apps.FirstOrDefault(a => a.AppID == steamAppId);86if (app == null)87return null;88
89SimpleLogger.Instance.Info("[INFO] Found Game \"" + steamAppId + "\" in 'appinfo.vdf'");90
91string executable;92
93var executables = app.Data.Traverse(d => d.Children).Where(d => d.Children.Any(c => c.Name == "executable")).ToArray();94foreach (var exe in executables)95{96var config = exe.Children.Where(c => c.Name == "config").SelectMany(c => c.Children).Where(c => c.Name == "oslist" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();97if ("windows".Equals(config))98{99var type = exe.Children.Where(c => c.Name == "type" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();100if (type != "default")101SimpleLogger.Instance.Info("[INFO] No default 'type' found, using first executable found.");102
103executable = exe.Children.Where(c => c.Name == "executable" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();104if (!string.IsNullOrEmpty(executable))105{106SimpleLogger.Instance.Info("[INFO] Game executable " + executable + " found.");107return executable;108}109}110else111{112SimpleLogger.Instance.Info("[INFO] No 'windows' specific config found, using first executable found.");113
114var type = exe.Children.Where(c => c.Name == "type" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();115if (type != "default")116SimpleLogger.Instance.Info("[INFO] No default 'type' found, using first executable found.");117
118executable = exe.Children.Where(c => c.Name == "executable" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();119if (!string.IsNullOrEmpty(executable))120{121SimpleLogger.Instance.Info("[INFO] Game executable " + executable + " found.");122return executable;123}124}125
126SimpleLogger.Instance.Info("[WARNING] No game executable found, cannot put ES in Wait-mode.");127}128}129catch { }130
131return null;132}133
134static List<LauncherGameInfo> GetInstalledGamesFromFolder(string path)135{136var games = new List<LauncherGameInfo>();137
138foreach (var file in Directory.GetFiles(path, @"appmanifest*"))139{140if (file.EndsWith("tmp", StringComparison.OrdinalIgnoreCase))141continue;142
143try144{145var game = GetInstalledGameFromFile(Path.Combine(path, file));146if (game == null)147continue;148
149if (string.IsNullOrEmpty(game.InstallDirectory) || game.InstallDirectory.Contains(@"steamapps\music"))150continue;151
152games.Add(game);153}154catch (Exception ex)155{156
157}158}159
160return games;161}162
163static LauncherGameInfo GetInstalledGameFromFile(string path)164{165var kv = new KeyValue();166
167using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))168kv.ReadAsText(fs);169
170SteamAppStateFlags appState;171if (!string.IsNullOrEmpty(kv["StateFlags"].Value) && Enum.TryParse<SteamAppStateFlags>(kv["StateFlags"].Value, out appState))172{173if (!appState.HasFlag(SteamAppStateFlags.FullyInstalled))174return null;175}176else177return null;178
179var name = string.Empty;180if (string.IsNullOrEmpty(kv["name"].Value))181{182if (kv["UserConfig"]["name"].Value != null)183{184name = kv["UserConfig"]["name"].Value; // StringExtensions.NormalizeGameName();185}186}187else188name = kv["name"].Value; // StringExtensions.NormalizeGameName();189
190var gameId = kv["appID"].Value;191if (gameId == "228980")192return null;193
194var installDir = Path.Combine((new FileInfo(path)).Directory.FullName, "common", kv["installDir"].Value);195if (!Directory.Exists(installDir))196{197installDir = Path.Combine((new FileInfo(path)).Directory.FullName, "music", kv["installDir"].Value);198if (!Directory.Exists(installDir))199{200installDir = string.Empty;201}202}203
204var game = new LauncherGameInfo()205{206Id = gameId,207Name = name,208InstallDirectory = installDir,209LauncherUrl = string.Format(GameLaunchUrl, gameId),210PreviewImageUrl = string.Format(HeaderImageUrl, gameId),211ExecutableName = FindExecutableName(gameId.ToInteger()),212Launcher = GameLauncherType.Steam213};214
215return game;216}217
218static List<string> GetLibraryFolders(KeyValue foldersData)219{220var dbs = new List<string>();221foreach (var child in foldersData.Children)222{223int val;224if (int.TryParse(child.Name, out val))225{226if (!string.IsNullOrEmpty(child.Value) && Directory.Exists(child.Value))227dbs.Add(child.Value);228else if (child.Children != null && child.Children.Count > 0)229{230var path = child.Children.FirstOrDefault(a => a.Name != null && a.Name.Equals("path", StringComparison.OrdinalIgnoreCase) == true);231if (!string.IsNullOrEmpty(path.Value) && Directory.Exists(path.Value))232dbs.Add(path.Value);233}234}235}236
237return dbs;238}239
240static string GetInstallPath()241{242try243{244using (var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Valve\\Steam"))245{246if (key != null)247{248var o = key.GetValue("InstallPath");249if (o != null)250return o as string;251}252}253}254catch { }255
256return null;257}258}259
260}
261
262
263namespace EmulatorLauncher.Common.Launchers.Steam264{
265[Flags]266public enum SteamAppStateFlags267{268Invalid = 0,269Uninstalled = 1,270UpdateRequired = 2,271FullyInstalled = 4,272Encrypted = 8,273Locked = 16,274FilesMissing = 32,275AppRunning = 64,276FilesCorrupt = 128,277UpdateRunning = 256,278UpdatePaused = 512,279UpdateStarted = 1024,280Uninstalling = 2048,281BackupRunning = 4096,282Reconfiguring = 65536,283Validating = 131072,284AddingFiles = 262144,285Preallocating = 524288,286Downloading = 1048576,287Staging = 2097152,288Committing = 4194304,289UpdateStopping = 8388608290}291}