示例#1
0
        private string GetInstallPath(string steamInstallPath)
        {
            string installPath = string.Empty;
            string basePath    = string.Format(@"{0}\{1}", steamInstallPath, "steamapps");

            string[] files = Directory.GetFiles(basePath, "*.acf");

            foreach (var file in files)
            {
                var reader = new AcfReader(file);
                if (reader.CheckIntegrity())
                {
                    var        manifestObject = reader.ACFFileToStruct();
                    ACF_Struct appState       = null;
                    manifestObject.SubACF.TryGetValue("AppState", out appState);
                    if (appState != null)
                    {
                        string gameName = null;
                        appState.SubItems.TryGetValue("name", out gameName);
                        if (gameName != null && gameName == ReflexNameInSteam)
                        {
                            installPath = string.Format(@"{0}\steamapps\common\{1}", steamInstallPath, manifestObject.SubACF["AppState"].SubItems["installdir"]);
                            break;
                        }
                    }
                }
            }

            return(installPath);
        }
        //
        //  Load ACF files from a given directory and return the ACFs' data
        //
        static List <AppInfo> ReadSteamManifestsFromDir(string directory)
        {
            List <AppInfo> apps = new List <AppInfo>();

            Console.WriteLine("Scanning for games in " + directory);
            if (Directory.Exists(directory))
            {
                string[]      files    = Directory.GetFiles(directory);
                List <string> acfFiles = new List <string>();
                foreach (string file in files)
                {
                    if (file.Substring(file.Length - 4) == ".acf")
                    {
                        acfFiles.Add(file);
                    }
                }
                foreach (string file in acfFiles)
                {
                    AcfReader  acfReader = new AcfReader(file);
                    ACF_Struct acf       = acfReader.ACFFileToStruct();

                    AppInfo app = new AppInfo();
                    app.name       = acf.SubACF["AppState"].SubItems["name"];
                    app.id         = acf.SubACF["AppState"].SubItems["appid"];
                    app.source     = "Steam";
                    app.fileSource = file;

                    apps.Add(app);

                    //Console.WriteLine("Added " + app.name + " (" + app.id + ") to the database");
                }
            }
            return(apps);
        }
示例#3
0
文件: Steam.cs 项目: Solaire/GLC
        private ACF_Struct ACFFileToStruct(string RegionToReadIn)
        {
            ACF_Struct ACF            = new();
            int        LengthOfRegion = RegionToReadIn.Length;
            int        CurrentPos     = 0;

            while (LengthOfRegion > CurrentPos)
            {
                int FirstItemStart = RegionToReadIn.IndexOf('"', CurrentPos);
                if (FirstItemStart == -1)
                {
                    break;
                }
                int FirstItemEnd = RegionToReadIn.IndexOf('"', FirstItemStart + 1);
                CurrentPos = FirstItemEnd + 1;
                string FirstItem = "";
                if (FirstItemEnd - FirstItemStart - 1 >= 0)
                {
                    FirstItem = RegionToReadIn.Substring(FirstItemStart + 1, FirstItemEnd - FirstItemStart - 1);
                }

                int SecondItemStartQuote     = RegionToReadIn.IndexOf('"', CurrentPos);
                int SecondItemStartBraceleft = RegionToReadIn.IndexOf('{', CurrentPos);
                if (SecondItemStartBraceleft == -1 || SecondItemStartQuote < SecondItemStartBraceleft)
                {
                    int    SecondItemEndQuote = RegionToReadIn.IndexOf('"', SecondItemStartQuote + 1);
                    string SecondItem         = "";
                    if (SecondItemEndQuote - SecondItemStartQuote - 1 >= 0)
                    {
                        SecondItem = RegionToReadIn.Substring(SecondItemStartQuote + 1, SecondItemEndQuote - SecondItemStartQuote - 1);
                    }
                    CurrentPos = SecondItemEndQuote + 1;
                    if (!ACF.SubItems.ContainsKey(FirstItem))
                    {
                        ACF.SubItems.Add(FirstItem, SecondItem);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    int        SecondItemEndBraceright = RegionToReadIn.NextEndOf('{', '}', SecondItemStartBraceleft + 1);
                    ACF_Struct ACFS = null;
                    if (SecondItemEndBraceright - SecondItemStartBraceleft - 1 >= 0)
                    {
                        ACFS = ACFFileToStruct(RegionToReadIn.Substring(SecondItemStartBraceleft + 1, SecondItemEndBraceright - SecondItemStartBraceleft - 1));
                    }
                    CurrentPos = SecondItemEndBraceright + 1;
                    if (!ACF.SubACF.ContainsKey(FirstItem))
                    {
                        ACF.SubACF.Add(FirstItem, ACFS);
                    }
                }
            }

            return(ACF);
        }
        //
        //  Find extra Steam libraries
        //
        static string[] GetSteamLibraryFolders(string SteamAppsLocation)
        {
            List <string> outList = new List <string>();

            if (Directory.Exists(SteamAppsLocation) && File.Exists(SteamAppsLocation + "/libraryfolders.vdf"))
            {
                AcfReader  acfReader = new AcfReader(SteamAppsLocation + "/libraryfolders.vdf");
                ACF_Struct acf       = acfReader.ACFFileToStruct();

                foreach (string key in acf.SubACF["LibraryFolders"].SubItems.Keys)
                {
                    if (Regex.IsMatch(key, @"^\d+$"))
                    {
                        outList.Add(acf.SubACF["LibraryFolders"].SubItems[key] + "/steamapps");
                        Console.WriteLine("Found Steam library at " + acf.SubACF["LibraryFolders"].SubItems[key] + "/steamapps");
                    }
                }
            }
            return(outList.ToArray());
        }
示例#5
0
        public void GetGames(List <ImportGameData> gameDataList, bool expensiveIcons = false)
        {
            string strInstallPath = "";
            string strClientPath  = "";

            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(STEAM_REG, RegistryKeyPermissionCheck.ReadSubTree))             // HKLM32
            {
                if (key == null)
                {
                    CLogger.LogInfo("{0} client not found in the registry.", _name.ToUpper());
                    return;
                }

                strInstallPath = GetRegStrVal(key, GAME_INSTALL_PATH);
                strClientPath  = Path.Combine(strInstallPath, STEAM_PATH);
            }

            if (!Directory.Exists(strClientPath))
            {
                CLogger.LogInfo("{0} library not found: {1}", _name.ToUpper(), strClientPath);
                return;
            }

            string        libFile = Path.Combine(strClientPath, STEAM_LIBFILE);
            List <string> libs    = new()
            {
                strClientPath
            };
            int nLibs = 1;

            try
            {
                if (File.Exists(libFile))
                {
                    SteamWrapper document     = new(libFile);
                    ACF_Struct   documentData = document.ACFFileToStruct();
                    ACF_Struct   folders      = new();
                    if (documentData.SubACF.ContainsKey(STEAM_LIBARR))
                    {
                        folders = documentData.SubACF[STEAM_LIBARR];
                    }
                    else if (documentData.SubACF.ContainsKey(STEAM_LIBARR.ToLower()))
                    {
                        folders = documentData.SubACF[STEAM_LIBARR.ToLower()];
                    }
                    for (; nLibs <= STEAM_MAX_LIBS; ++nLibs)
                    {
                        folders.SubItems.TryGetValue(nLibs.ToString(), out string library);
                        if (string.IsNullOrEmpty(library))
                        {
                            if (folders.SubACF.ContainsKey(nLibs.ToString()))
                            {
                                folders.SubACF[nLibs.ToString()].SubItems.TryGetValue("path", out library);
                            }
                            if (string.IsNullOrEmpty(library))
                            {
                                nLibs--;
                                break;
                            }
                        }
                        library = Path.Combine(library, STEAM_PATH);
                        if (!library.Equals(strClientPath) && Directory.Exists(library))
                        {
                            libs.Add(library);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                CLogger.LogError(e, string.Format("Malformed {0} file: {1}", _name.ToUpper(), libFile));
                nLibs--;
            }

            int           i        = 0;
            List <string> allFiles = new();

            foreach (string lib in libs)
            {
                List <string> libFiles = new();
                try
                {
                    libFiles = Directory.GetFiles(lib, "appmanifest_*.acf", SearchOption.TopDirectoryOnly).ToList();
                    allFiles.AddRange(libFiles);
                    CLogger.LogInfo("{0} {1} games found in library {2}", libFiles.Count, _name.ToUpper(), lib);
                }
                catch (Exception e)
                {
                    CLogger.LogError(e, string.Format("{0} directory read error: {1}", _name.ToUpper(), lib));
                    continue;
                }

                foreach (string file in libFiles)
                {
                    try
                    {
                        SteamWrapper document     = new(file);
                        ACF_Struct   documentData = document.ACFFileToStruct();
                        ACF_Struct   app          = documentData.SubACF["AppState"];

                        string id = app.SubItems["appid"];
                        if (id.Equals("228980"))                          // Steamworks Common Redistributables
                        {
                            continue;
                        }

                        string strID    = Path.GetFileName(file);
                        string strTitle = app.SubItems["name"];
                        CLogger.LogDebug($"- {strTitle}");
                        string strLaunch    = START_GAME + "/" + id;
                        string strIconPath  = "";
                        string strUninstall = "";
                        string strAlias     = "";
                        string strPlatform  = GetPlatformString(ENUM);

                        strAlias = GetAlias(strTitle);
                        if (!string.IsNullOrEmpty(strLaunch))
                        {
                            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(Path.Combine(NODE64_REG, STEAM_GAME_PREFIX + id), RegistryKeyPermissionCheck.ReadSubTree),                              // HKLM64
                                   key2 = Registry.LocalMachine.OpenSubKey(Path.Combine(NODE32_REG, STEAM_GAME_PREFIX + id), RegistryKeyPermissionCheck.ReadSubTree))                                         // HKLM32
                            {
                                if (key != null)
                                {
                                    strIconPath = GetRegStrVal(key, GAME_DISPLAY_ICON).Trim(new char[] { ' ', '"' });
                                }
                                else if (key2 != null)
                                {
                                    strIconPath = GetRegStrVal(key2, GAME_DISPLAY_ICON).Trim(new char[] { ' ', '"' });
                                }
                            }
                            if (string.IsNullOrEmpty(strIconPath) && expensiveIcons)
                            {
                                bool success = false;

                                // Search for an .exe to use as icon
                                strIconPath = CGameFinder.FindGameBinaryFile(Path.Combine(lib, "common", app.SubItems["installdir"]), strTitle);
                                if (!string.IsNullOrEmpty(strIconPath))
                                {
                                    success  = true;
                                    strAlias = GetAlias(Path.GetFileNameWithoutExtension(strIconPath));
                                    if (strAlias.Length > strTitle.Length)
                                    {
                                        strAlias = GetAlias(strTitle);
                                    }
                                }

                                if (!success && !(bool)(CConfig.GetConfigBool(CConfig.CFG_IMGDOWN)))
                                {
                                    // Download missing icons
                                    string iconUrl = $"https://cdn.cloudflare.steamstatic.com/steam/apps/{id}/capsule_184x69.jpg";
                                    if (CDock.DownloadCustomImage(strTitle, iconUrl))
                                    {
                                        success = true;
                                    }
                                }
                            }
                            if (strAlias.Equals(strTitle, CDock.IGNORE_CASE))
                            {
                                strAlias = "";
                            }
                            strUninstall = UNINST_GAME + "/" + id;
                            gameDataList.Add(new ImportGameData(strID, strTitle, strLaunch, strIconPath, strUninstall, strAlias, true, strPlatform));
                        }
                    }
                    catch (Exception e)
                    {
                        CLogger.LogError(e, string.Format("Malformed {0} file: {1}", _name.ToUpper(), file));
                    }
                }
                i++;

                /*
                 * if (i > nLibs)
                 *      CLogger.LogDebug("---------------------");
                 */
            }

            // Get not-installed games
            if (!(bool)CConfig.GetConfigBool(CConfig.CFG_INSTONLY))
            {
                // First get Steam user ID
                ulong userId = (ulong)CConfig.GetConfigULong(CConfig.CFG_STEAMID);

                if (userId < 1)
                {
                    try
                    {
                        ulong  userIdTmp     = 0;
                        string userName      = "";
                        string userNameTmp   = "";
                        string strConfigPath = Path.Combine(strInstallPath, "config");
                        string appFile       = Path.Combine(strConfigPath, STEAM_APPFILE);

                        if (File.Exists(appFile))
                        {
                            SteamWrapper appDoc     = new(appFile);
                            ACF_Struct   appDocData = appDoc.ACFFileToStruct();
                            ACF_Struct   appData    = appDocData.SubACF["SteamAppData"];

                            appData.SubItems.TryGetValue("AutoLoginUser", out userName);

                            SteamWrapper usrDoc     = new(Path.Combine(strConfigPath, STEAM_USRFILE));
                            ACF_Struct   usrDocData = usrDoc.ACFFileToStruct();
                            ACF_Struct   usrData    = usrDocData.SubACF["users"];

                            foreach (KeyValuePair <string, ACF_Struct> user in usrData.SubACF)
                            {
                                if (!ulong.TryParse(user.Key, out userIdTmp))
                                {
                                    userIdTmp = 0;
                                }

                                foreach (KeyValuePair <string, string> userVal in user.Value.SubItems)
                                {
                                    if (userVal.Key.Equals("AccountName"))
                                    {
                                        userNameTmp = userVal.Value;
                                        if (userNameTmp.Equals(userName))
                                        {
                                            if (!ulong.TryParse(user.Key, out userId))
                                            {
                                                userId = 0;
                                            }
                                        }
                                    }
                                    if (userVal.Key.Equals("MostRecent") && userVal.Value.Equals("1") && string.IsNullOrEmpty(userName))
                                    {
                                        userId   = userIdTmp;
                                        userName = userNameTmp;
                                        break;
                                    }
                                }
                            }
                            if (userId < 1)
                            {
                                userId   = userIdTmp;
                                userName = userNameTmp;
                            }
                        }
                        if (userId > 0)
                        {
                            CLogger.LogInfo("Setting default {0} user to {1} #{2}", _name.ToUpper(), userName, userId);
                            CConfig.SetConfigValue(CConfig.CFG_STEAMID, userId);
                            ExportConfig();
                        }
                    }
                    catch (Exception e)
                    {
                        CLogger.LogError(e, string.Format("Malformed {0} file: {1} or {2}", _name.ToUpper(), STEAM_APPFILE, STEAM_USRFILE));
                    }
                }

                if (userId > 0)
                {
                    // Download game list from public user profile
                    try
                    {
                        string url = string.Format("https://steamcommunity.com/profiles/{0}/games/?tab=all", userId);

                        /*
                         #if DEBUG
                         * // Don't re-download if file exists
                         * string tmpfile = $"tmp_{NAME}.html";
                         * if (!File.Exists(tmpfile))
                         * {
                         *      using (var client = new WebClient());
                         *      client.DownloadFile(url, tmpfile);
                         * }
                         * HtmlDocument doc = new HtmlDocument
                         * {
                         *      OptionUseIdAttribute = true
                         * };
                         * doc.Load(tmpfile);
                         #else
                         */
                        HtmlWeb web = new()
                        {
                            UseCookies = true
                        };
                        HtmlDocument doc = web.Load(url);
                        doc.OptionUseIdAttribute = true;
//#endif
                        HtmlNode gameList = doc.DocumentNode.SelectSingleNode("//script[@language='javascript']");
                        if (gameList != null)
                        {
                            CLogger.LogDebug("{0} not-installed games (user #{1}):", _name.ToUpper(), userId);

                            var options = new JsonDocumentOptions
                            {
                                AllowTrailingCommas = true
                            };
                            string rgGames = gameList.InnerText.Remove(0, gameList.InnerText.IndexOf('['));
                            rgGames = rgGames.Remove(rgGames.IndexOf(';'));

                            using JsonDocument document = JsonDocument.Parse(@rgGames, options);
                            foreach (JsonElement game in document.RootElement.EnumerateArray())
                            {
                                ulong id = GetULongProperty(game, "appid");
                                if (id > 0)
                                {
                                    // Check if game is already installed
                                    string strID = $"appmanifest_{id}.acf";
                                    bool   found = false;
                                    foreach (string file in allFiles)
                                    {
                                        if (file.EndsWith(strID))
                                        {
                                            found = true;
                                        }
                                    }
                                    if (!found)
                                    {
                                        string strTitle    = GetStringProperty(game, "name");
                                        string strPlatform = GetPlatformString(ENUM);

                                        // Add not-installed games
                                        CLogger.LogDebug($"- *{strTitle}");
                                        gameDataList.Add(new ImportGameData(strID, strTitle, "", "", "", "", false, strPlatform));

                                        // Use logo to download not-installed icons
                                        if (!(bool)(CConfig.GetConfigBool(CConfig.CFG_IMGDOWN)))
                                        {
                                            string iconUrl = GetStringProperty(game, "logo");
                                            CDock.DownloadCustomImage(strTitle, iconUrl);
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            CLogger.LogInfo("Can't get not-installed {0} games. Profile may not be public.\n" +
                                            "To change this, go to <https://steamcommunity.com/my/edit/settings>.",
                                            _name.ToUpper());
                        }

                        /*
                         #if DEBUG
                         *      File.Delete(tmpfile);
                         #endif
                         */
                    }
                    catch (Exception e)
                    {
                        CLogger.LogError(e);
                    }
                    CLogger.LogDebug("---------------------");
                }
            }
        }