ProjectArcade

Форк
0
291 строка · 10.4 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.IO;
6
using Microsoft.Win32;
7
using Steam_Library_Manager.Framework;
8
using EmulatorLauncher.Common.Launchers.Steam;
9

10
namespace EmulatorLauncher.Common.Launchers
11
{
12
    public static class SteamLibrary
13
    {
14
        // https://cdn.cloudflare.steamstatic.com/steam/apps/1515950/header.jpg
15

16
        const string GameLaunchUrl = @"steam://rungameid/{0}";
17
        const string HeaderImageUrl = @"https://cdn.cloudflare.steamstatic.com/steam/apps/{0}/header.jpg";
18

19
        public static LauncherGameInfo[] GetInstalledGames()
20
        {
21
            var games = new List<LauncherGameInfo>();
22

23
            string libraryfoldersPath = Path.Combine(GetInstallPath(), "config", "libraryfolders.vdf");
24

25
            try
26
            {
27
                var libraryfolders = new KeyValue();
28
                libraryfolders.ReadFileAsText(libraryfoldersPath);
29

30
                var folders = GetLibraryFolders(libraryfolders);
31

32
                foreach (var folder in folders)
33
                {
34
                    var libFolder = Path.Combine(folder, "steamapps");
35
                    if (Directory.Exists(libFolder))
36
                    {
37
                        foreach(var game in GetInstalledGamesFromFolder(libFolder))
38
                        {
39
                            if (game.Id == "228980")
40
                                continue;
41

42
                            games.Add(game);
43
                        }
44
                    }
45
                }
46
            }
47
            catch { }
48

49
            return games.ToArray();
50
        }
51
        
52
        public static string GetSteamGameExecutableName(Uri uri)
53
        {
54
            string shorturl = uri.AbsolutePath.Substring(1);
55
            int steamAppId = shorturl.ToInteger();
56

57
            string exe = FindExecutableName(steamAppId);
58

59
            if (string.IsNullOrEmpty(exe))
60
            {
61
                SimpleLogger.Instance.Info("[WARNING] Cannot find STEAM game executable");
62
                return null;
63
            }
64

65
            return Path.GetFileNameWithoutExtension(exe);
66
        }
67

68
        static string FindExecutableName(int steamAppId)
69
        {
70
            string path = GetInstallPath();
71
            if (string.IsNullOrEmpty(path))
72
                throw new ApplicationException("Can not find Steam installation folder in registry.");
73
            
74
            string appinfoPath = Path.Combine(path, "appcache", "appinfo.vdf");
75
            if (!File.Exists(appinfoPath))
76
                SimpleLogger.Instance.Info("[WARNING] Missing file " + appinfoPath);
77

78
            try
79
            {
80
                var reader = new SteamAppInfoReader();
81
                reader.Read(appinfoPath);
82

83
                SimpleLogger.Instance.Info("[INFO] Reading Steam file 'appinfo.vdf'");
84

85
                var app = reader.Apps.FirstOrDefault(a => a.AppID == steamAppId);
86
                if (app == null)
87
                    return null;
88

89
                SimpleLogger.Instance.Info("[INFO] Found Game \"" + steamAppId + "\" in 'appinfo.vdf'");
90

91
                string executable;
92

93
                var executables = app.Data.Traverse(d => d.Children).Where(d => d.Children.Any(c => c.Name == "executable")).ToArray();
94
                foreach (var exe in executables)
95
                {
96
                    var 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();
97
                    if ("windows".Equals(config))
98
                    {
99
                        var type = exe.Children.Where(c => c.Name == "type" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();
100
                        if (type != "default")
101
                            SimpleLogger.Instance.Info("[INFO] No default 'type' found, using first executable found.");
102

103
                        executable = exe.Children.Where(c => c.Name == "executable" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();
104
                        if (!string.IsNullOrEmpty(executable))
105
                        {
106
                            SimpleLogger.Instance.Info("[INFO] Game executable " + executable + " found.");
107
                            return executable;
108
                        }
109
                    }
110
                    else
111
                    {
112
                        SimpleLogger.Instance.Info("[INFO] No 'windows' specific config found, using first executable found.");
113

114
                        var type = exe.Children.Where(c => c.Name == "type" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();
115
                        if (type != "default")
116
                            SimpleLogger.Instance.Info("[INFO] No default 'type' found, using first executable found.");
117

118
                        executable = exe.Children.Where(c => c.Name == "executable" && c.Value != null).Select(c => c.Value.ToString()).FirstOrDefault();
119
                        if (!string.IsNullOrEmpty(executable))
120
                        {
121
                            SimpleLogger.Instance.Info("[INFO] Game executable " + executable + " found.");
122
                            return executable;
123
                        }
124
                    }
125

126
                    SimpleLogger.Instance.Info("[WARNING] No game executable found, cannot put ES in Wait-mode.");
127
                }
128
            }
129
            catch { }
130

131
            return null;
132
        }
133

134
        static List<LauncherGameInfo> GetInstalledGamesFromFolder(string path)
135
        {
136
            var games = new List<LauncherGameInfo>();
137

138
            foreach (var file in Directory.GetFiles(path, @"appmanifest*"))
139
            {
140
                if (file.EndsWith("tmp", StringComparison.OrdinalIgnoreCase))
141
                    continue;
142

143
                try
144
                {
145
                    var game = GetInstalledGameFromFile(Path.Combine(path, file));
146
                    if (game == null)
147
                        continue;
148
                   
149
                    if (string.IsNullOrEmpty(game.InstallDirectory) || game.InstallDirectory.Contains(@"steamapps\music"))
150
                        continue;
151

152
                    games.Add(game);
153
                }
154
                catch (Exception ex)
155
                {
156

157
                }
158
            }
159

160
            return games;
161
        }
162

163
        static LauncherGameInfo GetInstalledGameFromFile(string path)
164
        {
165
            var kv = new KeyValue();
166

167
            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
168
                kv.ReadAsText(fs);
169

170
            SteamAppStateFlags appState;
171
            if (!string.IsNullOrEmpty(kv["StateFlags"].Value) && Enum.TryParse<SteamAppStateFlags>(kv["StateFlags"].Value, out appState))
172
            {
173
                if (!appState.HasFlag(SteamAppStateFlags.FullyInstalled))
174
                    return null;
175
            }
176
            else
177
                return null;
178

179
            var name = string.Empty;
180
            if (string.IsNullOrEmpty(kv["name"].Value))
181
            {
182
                if (kv["UserConfig"]["name"].Value != null)
183
                {
184
                    name = kv["UserConfig"]["name"].Value; //  StringExtensions.NormalizeGameName();
185
                }
186
            }
187
            else
188
                name = kv["name"].Value; // StringExtensions.NormalizeGameName();
189

190
            var gameId = kv["appID"].Value;
191
            if (gameId == "228980")
192
                return null;
193

194
            var installDir = Path.Combine((new FileInfo(path)).Directory.FullName, "common", kv["installDir"].Value);
195
            if (!Directory.Exists(installDir))
196
            {
197
                installDir = Path.Combine((new FileInfo(path)).Directory.FullName, "music", kv["installDir"].Value);
198
                if (!Directory.Exists(installDir))
199
                {
200
                    installDir = string.Empty;
201
                }
202
            }
203

204
            var game = new LauncherGameInfo()
205
            {
206
                Id = gameId,
207
                Name = name,
208
                InstallDirectory = installDir,
209
                LauncherUrl = string.Format(GameLaunchUrl, gameId),
210
                PreviewImageUrl = string.Format(HeaderImageUrl, gameId),
211
                ExecutableName = FindExecutableName(gameId.ToInteger()),
212
                Launcher = GameLauncherType.Steam
213
            };
214

215
            return game;
216
        }
217

218
        static List<string> GetLibraryFolders(KeyValue foldersData)
219
        {
220
            var dbs = new List<string>();
221
            foreach (var child in foldersData.Children)
222
            {
223
                int val;
224
                if (int.TryParse(child.Name, out val))
225
                {
226
                    if (!string.IsNullOrEmpty(child.Value) && Directory.Exists(child.Value))
227
                        dbs.Add(child.Value);
228
                    else if (child.Children != null && child.Children.Count > 0)
229
                    {
230
                        var path = child.Children.FirstOrDefault(a => a.Name != null && a.Name.Equals("path", StringComparison.OrdinalIgnoreCase) == true);
231
                        if (!string.IsNullOrEmpty(path.Value) && Directory.Exists(path.Value))
232
                            dbs.Add(path.Value);
233
                    }
234
                }
235
            }
236

237
            return dbs;
238
        }
239

240
        static string GetInstallPath()
241
        {
242
            try
243
            {
244
                using (var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Valve\\Steam"))
245
                {
246
                    if (key != null)
247
                    {
248
                        var o = key.GetValue("InstallPath");
249
                        if (o != null)
250
                            return o as string;
251
                    }
252
                }
253
            }
254
            catch { }
255

256
            return null;
257
        }
258
    }
259

260
}
261

262

263
namespace EmulatorLauncher.Common.Launchers.Steam
264
{
265
    [Flags]
266
    public enum SteamAppStateFlags
267
    {
268
        Invalid = 0,
269
        Uninstalled = 1,
270
        UpdateRequired = 2,
271
        FullyInstalled = 4,
272
        Encrypted = 8,
273
        Locked = 16,
274
        FilesMissing = 32,
275
        AppRunning = 64,
276
        FilesCorrupt = 128,
277
        UpdateRunning = 256,
278
        UpdatePaused = 512,
279
        UpdateStarted = 1024,
280
        Uninstalling = 2048,
281
        BackupRunning = 4096,
282
        Reconfiguring = 65536,
283
        Validating = 131072,
284
        AddingFiles = 262144,
285
        Preallocating = 524288,
286
        Downloading = 1048576,
287
        Staging = 2097152,
288
        Committing = 4194304,
289
        UpdateStopping = 8388608
290
    }
291
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.