示例#1
0
        /// <summary>
        ///     Gets the node at the given address. May be used to build structure.
        /// </summary>
        /// <param name="args">An ordered list of keys, like a path</param>
        /// <param name="create">If true, will create any nodes it does not find along the path.</param>
        /// <param name="index">Start index of the arg array</param>
        /// <returns>The FileNode at the given location, or null if the location was not found / created</returns>
        public VdfFileNode GetNodeAt(string[] args, bool create = true, int index = 0)
        {
            if (index >= args.Length)
            {
                return(this);
            }

            if (NodeType == ValueType.Array)
            {
                Dictionary <string, VdfFileNode> data = (Dictionary <string, VdfFileNode>)NodeData;
                if (ContainsKey(args[index]))
                {
                    return(data[args[index]].GetNodeAt(args, create, index + 1));
                }

                if (create)
                {
                    VdfFileNode newNode = new VdfFileNode();
                    data.Add(args[index], newNode);

                    return(newNode.GetNodeAt(args, create, index + 1));
                }
            }

            return(null);
        }
示例#2
0
        public static Dictionary <int, AppInfo> LoadApps(string path)
        {
            Dictionary <int, AppInfo> result = new Dictionary <int, AppInfo>();
            BinaryReader bReader             = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read));
            long         fileLength          = bReader.BaseStream.Length;

            // seek to common: start of a new entry
            byte[] start = new byte[] { 0x00, 0x00, 0x63, 0x6F, 0x6D, 0x6D, 0x6F, 0x6E, 0x00 }; // 0x00 0x00 c o m m o n 0x00

            VdfFileNode.ReadBin_SeekTo(bReader, start, fileLength);

            VdfFileNode node = VdfFileNode.LoadFromBinary(bReader, fileLength);

            while (node != null)
            {
                AppInfo app = AppInfo.FromVdfNode(node);
                if (app != null)
                {
                    result.Add(app.Id, app);
                }
                VdfFileNode.ReadBin_SeekTo(bReader, start, fileLength);
                node = VdfFileNode.LoadFromBinary(bReader, fileLength);
            }
            bReader.Close();
            return(result);
        }
示例#3
0
        public static Dictionary <int, PackageInfo> LoadPackages(string path)
        {
            Dictionary <int, PackageInfo> result = new Dictionary <int, PackageInfo>();

            BinaryReader bReader = new BinaryReader(new FileStream(path, FileMode.Open), Encoding.ASCII);

            bReader.ReadBytes(38);

            VdfFileNode node = VdfFileNode.LoadFromBinary(bReader);

            while (node != null)
            {
                PackageInfo p = FromVdfNode(node);
                if (p != null)
                {
                    result.Add(p.Id, p);
                }
                bReader.ReadBytes(31);
                node = node = VdfFileNode.LoadFromBinary(bReader);
            }

            bReader.Close();

            return(result);
        }
示例#4
0
        /// <summary>
        /// Loads a FileNode from stream.
        /// </summary>
        /// <param name="stream">Stream to load from</param>
        /// <returns>FileNode representing the contents of the stream.</returns>
        public static VdfFileNode LoadFromBinary(BinaryReader stream, long streamLength = -1)
        {
            if (streamLength == -1)
            {
                streamLength = stream.BaseStream.Length;
            }
            if (stream.BaseStream.Position == streamLength)
            {
                return(null);
            }
            VdfFileNode thisLevel = new VdfFileNode();

            bool endOfStream = false;

            while (!endOfStream)
            {
                byte nextByte;
                try {
                    nextByte = stream.ReadByte();
                } catch (EndOfStreamException) {
                    endOfStream = true;
                    nextByte    = 8;
                }
                // Get key
                string key = null;
                if (endOfStream || nextByte == 8 || stream.BaseStream.Position == streamLength)
                {
                    break;
                }
                else if (nextByte == 0)
                {
                    key = ReadBin_GetStringToken(stream);
                    VdfFileNode newNode;
                    newNode        = LoadFromBinary(stream, streamLength);
                    thisLevel[key] = newNode;
                }
                else if (nextByte == 1)
                {
                    key            = ReadBin_GetStringToken(stream);
                    thisLevel[key] = new VdfFileNode(ReadBin_GetStringToken(stream));
                }
                else if (nextByte == 2)
                {
                    key = ReadBin_GetStringToken(stream);
                    int val = stream.ReadInt32();
                    thisLevel[key] = new VdfFileNode(val);
                }
                else if (nextByte == 0xFF)
                {
                    return(null);
                }
                else
                {
                    throw new ParseException(string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextByte.ToString()));
                }
            }
            return(thisLevel);
        }
示例#5
0
        public static PackageInfo FromVdfNode(VdfFileNode node)
        {
            VdfFileNode idNode = node.GetNodeAt(new string[] { "packageId" }, false);

            if ((idNode != null) && idNode.NodeType == ValueType.Int)
            {
                int id = idNode.NodeInt;

                string      name     = null;
                VdfFileNode nameNode = node.GetNodeAt(new string[] { "name" }, false);
                if (nameNode != null && nameNode.NodeType == ValueType.String)
                {
                    name = nameNode.NodeString;
                }

                PackageInfo package = new PackageInfo(id, name);

                VdfFileNode billingtypeNode = node["billingtype"];
                if (billingtypeNode != null && billingtypeNode.NodeType == ValueType.String || billingtypeNode.NodeType == ValueType.Int)
                {
                    int bType = billingtypeNode.NodeInt;

                    /*if( Enum.IsDefined( typeof(PackageBillingType), bType ) ) {
                     *
                     * } else {
                     *
                     * }*/
                    package.BillingType = (PackageBillingType)bType;
                }

                VdfFileNode appsNode = node["appids"];
                if (appsNode != null && appsNode.NodeType == ValueType.Array)
                {
                    foreach (VdfFileNode aNode in appsNode.NodeArray.Values)
                    {
                        if (aNode.NodeType == ValueType.Int)
                        {
                            package.AppIds.Add(aNode.NodeInt);
                        }
                    }
                }

                VdfFileNode expiryNode = node.GetNodeAt(new string[] { "extended", "ExpiryTime" }, false);
                if (expiryNode != null && expiryNode.NodeType == ValueType.Int)
                {
                    package.ExpiryTime = GetLocalDateTime(expiryNode.NodeInt);
                    package.Expires    = true;
                }
                else
                {
                    package.Expires = false;
                }

                return(package);
            }
            return(null);
        }
        /// <summary>
        /// Loads Apps from packageinfo.vdf.
        /// </summary>
        /// <param name="path">Path of packageinfo.vdf</param>
        public static Dictionary <int, PackageInfo> LoadPackages(string path)
        {
            Dictionary <int, PackageInfo> result = new Dictionary <int, PackageInfo>();

            /* packageinfo.vdf entry example format, sometimes has extra values. Line breaks are only for readability and not part of format.
             * we only care about *packageid*, *billingtype*, *appids*
             * *undeciphered*(24 bytes i haven't deciphered) *changenumber*(4 bytes, little endian)
             * 00 *packageid*(variable size, big endian, ascii) 00
             * 02 packageid 00 *packageid*(4 bytes, little endian)
             * 02 billingtype 00 *billingtype*(4 bytes, little endian)
             * 02 licensetype 00 *licensetype*(4 bytes, little endian)
             * 02 status 00 00 00 00 00 00 extended 00
             * 08 00 appids 00 02 *entrynumber*(variable size, number stored as string(ascii), starts at 0, random example: 31 38 39=189) 00 *appid*(4 bytes, little endian)
             * 08 00 depotids 00 02 *entrynumber* 00 *depotid*(4 bytes, little endian) 02 *entrynumber* 00 *depotid* 02 *entrynumber* 00 *depotid*
             * 08 00 appitems 00 08 08 08
             */

            BinaryReader bReader    = new BinaryReader(new FileStream(path, FileMode.Open), Encoding.ASCII);
            long         fileLength = bReader.BaseStream.Length;

            // seek to packageid: start of a new entry
            byte[] packageidBytes =
            {
                0x00, 0x02, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, 0x69, 0x64, 0x00
            }; // 0x00 0x02 p a c k a g e i d 0x00
            byte[] billingtypeBytes =
            {
                0x02, 0x62, 0x69, 0x6C, 0x6C, 0x69, 0x6E, 0x67, 0x74, 0x79, 0x70, 0x65, 0x00
            };                                                                             // 0x02 b i l l i n g t y p e 0x00
            byte[] appidsBytes = { 0x08, 0x00, 0x61, 0x70, 0x70, 0x69, 0x64, 0x73, 0x00 }; // 0x08 0x00 appids 0x00

            VdfFileNode.ReadBin_SeekTo(bReader, packageidBytes, fileLength);
            while (bReader.BaseStream.Position < fileLength)
            {
                int         id      = bReader.ReadInt32();
                PackageInfo package = new PackageInfo(id);

                VdfFileNode.ReadBin_SeekTo(bReader, billingtypeBytes, fileLength);
                package.BillingType = (PackageBillingType)bReader.ReadInt32();

                VdfFileNode.ReadBin_SeekTo(bReader, appidsBytes, fileLength);
                while (bReader.ReadByte() == 0x02)
                {
                    while (bReader.ReadByte() != 0x00)
                    {
                    }
                    package.AppIds.Add(bReader.ReadInt32());
                }

                result.Add(package.Id, package);
                VdfFileNode.ReadBin_SeekTo(bReader, packageidBytes, fileLength);
            }

            return(result);
        }
示例#7
0
        /// <summary>
        ///     Loads a FileNode from stream.
        /// </summary>
        /// <param name="stream">Stream to load from</param>
        /// <returns>FileNode representing the contents of the stream.</returns>
        public static VdfFileNode LoadFromText(StreamReader stream, bool useFirstAsRoot = false)
        {
            VdfFileNode thisLevel = useFirstAsRoot ? null : new VdfFileNode();

            ReadText_SkipWhitespace(stream);

            while (!stream.EndOfStream)
            {
                ReadText_SkipWhitespace(stream);
                // Get key
                char   nextChar = (char)stream.Read();
                string key      = null;
                if (stream.EndOfStream || (nextChar == '}'))
                {
                    break;
                }

                if (nextChar == '"')
                {
                    key = ReadText_GetStringToken(stream);
                }
                else
                {
                    throw new ParseException(string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextChar));
                }

                ReadText_SkipWhitespace(stream);

                // Get value
                nextChar = (char)stream.Read();
                VdfFileNode newNode;
                if (nextChar == '"')
                {
                    newNode = new VdfFileNode(ReadText_GetStringToken(stream));
                }
                else if (nextChar == '{')
                {
                    newNode = LoadFromText(stream);
                }
                else
                {
                    throw new ParseException(string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterValue, nextChar));
                }

                if (useFirstAsRoot)
                {
                    return(newNode);
                }

                thisLevel[key] = newNode;
            }

            return(thisLevel);
        }
示例#8
0
        public static PackageInfo FromVdfNode(VdfFileNode node)
        {
            VdfFileNode idNode = node.GetNodeAt(new[]
            {
                "packageId"
            }, false);

            if ((idNode != null) && (idNode.NodeType == ValueType.Int))
            {
                int id = idNode.NodeInt;

                string      name     = null;
                VdfFileNode nameNode = node.GetNodeAt(new[]
                {
                    "name"
                }, false);

                if ((nameNode != null) && (nameNode.NodeType == ValueType.String))
                {
                    name = nameNode.NodeString;
                }

                PackageInfo package = new PackageInfo(id, name);

                VdfFileNode billingtypeNode = node["billingtype"];
                if (((billingtypeNode != null) && (billingtypeNode.NodeType == ValueType.String)) || (billingtypeNode.NodeType == ValueType.Int))
                {
                    int bType = billingtypeNode.NodeInt;

                    /*if( Enum.IsDefined( typeof(PackageBillingType), bType ) ) {
                     *
                     * } else {
                     *
                     * }*/
                    package.BillingType = (PackageBillingType)bType;
                }

                VdfFileNode appsNode = node["appids"];
                if ((appsNode != null) && (appsNode.NodeType == ValueType.Array))
                {
                    foreach (VdfFileNode aNode in appsNode.NodeArray.Values)
                    {
                        if (aNode.NodeType == ValueType.Int)
                        {
                            package.AppIds.Add(aNode.NodeInt);
                        }
                    }
                }

                return(package);
            }

            return(null);
        }
        /// <summary>
        /// Load identifiers for external games from screenshots.vdf
        /// </summary>
        /// <param name="SteamId">Steam user identifier</param>
        /// <param name="shortcutGames">Found games listed as pairs of {gameName, gameId} </param>
        /// <returns></returns>
        private bool LoadShortcutGames(long SteamId, out Dictionary <string, int> shortcutGames)
        {
            bool   result   = false;
            string filePath = string.Format(Properties.Resources.ScreenshotsFilePath, Settings.Instance().SteamPath, Profile.ID64toDirName(SteamId));

            shortcutGames = new Dictionary <string, int>();

            StreamReader reader = null;

            try
            {
                reader = new StreamReader(filePath, false);
                TextVdfFileNode dataRoot = TextVdfFileNode.Load(reader, true);

                VdfFileNode appsNode = dataRoot.GetNodeAt(new string[] { "shortcutnames" }, false);

                foreach (KeyValuePair <string, VdfFileNode> shortcutPair in appsNode.NodeArray)
                {
                    string strId = shortcutPair.Key;

                    ulong ulongId;
                    if (ulong.TryParse(strId, out ulongId))
                    {
                        int    gameId   = (int)(ulongId >> 32);
                        string gameName = (string)shortcutPair.Value.NodeData;
                        shortcutGames.Add(gameName, gameId);
                    }
                    else
                    {
                        Program.Logger.Write(LoggerLevel.Warning, GlobalStrings.GameData_ErrorParsingScreenshots, (string)shortcutPair.Value.NodeData);
                    }
                }
                result = true;
            }
            catch (FileNotFoundException e)
            {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorOpeningConfigFileParam, e.ToString());
            }
            catch (IOException e)
            {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_LoadingErrorSteamConfig, e.ToString());
            }

            if (reader != null)
            {
                reader.Close();
            }

            return(result);
        }
示例#10
0
        public static PackageInfo FromVdfNode( VdfFileNode node ) {
            VdfFileNode idNode = node.GetNodeAt( new string[] { "packageId" }, false );
            if( (idNode != null ) && idNode.NodeType == ValueType.Int ) {
                int id = idNode.NodeInt;

                string name = null;
                VdfFileNode nameNode =  node.GetNodeAt( new string[] {"name"}, false );
                if( nameNode != null && nameNode.NodeType == ValueType.String ) {
                    name = nameNode.NodeString;
                }

                PackageInfo package = new PackageInfo(id, name);

                VdfFileNode billingtypeNode = node["billingtype"];
                if( billingtypeNode != null && billingtypeNode.NodeType == ValueType.String || billingtypeNode.NodeType == ValueType.Int ) {
                    int bType = billingtypeNode.NodeInt;
                    /*if( Enum.IsDefined( typeof(PackageBillingType), bType ) ) {

                    } else {

                    }*/
                    package.BillingType = (PackageBillingType)bType;
                }

                VdfFileNode appsNode = node["appids"];
                if( appsNode != null && appsNode.NodeType == ValueType.Array ) {
                    foreach( VdfFileNode aNode in appsNode.NodeArray.Values ) {
                        if( aNode.NodeType == ValueType.Int ) {
                            package.AppIds.Add( aNode.NodeInt );
                        }
                    }
                }

                VdfFileNode expiryNode = node.GetNodeAt( new string[] {"extended", "ExpiryTime"}, false);
                if( expiryNode != null && expiryNode.NodeType == ValueType.Int ) {
                    package.ExpiryTime = GetLocalDateTime( expiryNode.NodeInt );
                    package.Expires = true;
                } else {
                    package.Expires = false;
                }

                return package;

            }
            return null;
        }
示例#11
0
        /// <summary>
        /// Loads category info from the given steam config file.
        /// </summary>
        /// <param name="filePath">The path of the file to open</param>
        /// <returns>The number of game entries found</returns>
        public int ImportSteamFile(string filePath, SortedSet <int> ignore, bool ignoreDlc)
        {
            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_OpeningSteamConfigFile, filePath);
            TextVdfFileNode dataRoot;

            try {
                using (StreamReader reader = new StreamReader(filePath, false)) {
                    dataRoot = TextVdfFileNode.Load(reader, true);
                }
            } catch (ParseException e) {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorParsingConfigFileParam, e.Message);
                throw new ApplicationException(GlobalStrings.GameData_ErrorParsingSteamConfigFile + e.Message, e);
            } catch (IOException e) {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorOpeningConfigFileParam, e.Message);
                throw new ApplicationException(GlobalStrings.GameData_ErrorOpeningSteamConfigFile + e.Message, e);
            }

            VdfFileNode appsNode = dataRoot.GetNodeAt(new string[] { "Software", "Valve", "Steam", "apps" }, true);
            int         count    = GetDataFromVdf(appsNode, ignore, ignoreDlc);

            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_SteamConfigFileLoaded, count);
            return(count);
        }
示例#12
0
        /// <summary>
        /// Get LastPlayed date from a VDF node containing a list of games.
        /// Any games in the node not found in the game list will be added to the gamelist.
        /// </summary>
        /// <param name="appsNode">Node containing the game nodes</param>
        /// <param name="ignore">Set of games to ignore</param>
        /// <param name="forceInclude">Include games even if their type is not an included type</param>
        private void GetLastPlayedFromVdf(VdfFileNode appsNode, SortedSet<int> ignore, AppTypes includedTypes)
        {
            Dictionary<string, VdfFileNode> gameNodeArray = appsNode.NodeArray;
            if (gameNodeArray != null)
            {
                foreach (KeyValuePair<string, VdfFileNode> gameNodePair in gameNodeArray)
                {
                    int gameId;
                    if (int.TryParse(gameNodePair.Key, out gameId))
                    {
                        if ((ignore != null && ignore.Contains(gameId)) || !Program.GameDB.IncludeItemInGameList(gameId, includedTypes))
                        {
                            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_SkippedProcessingGame, gameId);
                        }
                        else if (gameNodePair.Value != null && gameNodePair.Value.NodeType == ValueType.Array)
                        {
                            GameInfo game = null;

                            // Add the game to the list if it doesn't exist already
                            if (!Games.ContainsKey(gameId))
                            {
                                game = new GameInfo(gameId, Program.GameDB.GetName(gameId), this);
                                Games.Add(gameId, game);
                                Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_AddedNewGame, gameId, game.Name);
                            }
                            else {
                                game = Games[gameId];
                            }

                            if (gameNodePair.Value.ContainsKey("LastPlayed") && gameNodePair.Value["LastPlayed"].NodeInt != 0)
                            {
                                DateTime dt = Utility.GetDTFromUTime(gameNodePair.Value["LastPlayed"].NodeInt);
                                if (dt > game.LastPlayed) game.LastPlayed = dt;
                                Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_ProcessedGame, gameId, game.LastPlayed.ToString());
                            }
                        }
                    }
                }
            }
        }
示例#13
0
        /// <summary>
        /// Loads in games from a VDF node containing a list of games.
        /// Any games in the node not found in the game list will be added to the gamelist.
        /// If a game in the node has a tags subnode, the "favorite" field will be overwritten.
        /// If a game in the node has a category set, it will overwrite any categories in the gamelist.
        /// If a game in the node does NOT have a category set, the category in the gamelist will NOT be cleared.
        /// </summary>
        /// <param name="appsNode">Node containing the game nodes</param>
        /// <param name="ignore">Set of games to ignore</param>
        /// <param name="forceInclude">Include games even if their type is not an included type</param>
        /// <returns>Number of games loaded</returns>
        private int IntegrateGamesFromVdf( VdfFileNode appsNode, SortedSet<int> ignore, AppTypes includedTypes )
        {
            int loadedGames = 0;

            Dictionary<string, VdfFileNode> gameNodeArray = appsNode.NodeArray;
            if( gameNodeArray != null ) {
                foreach( KeyValuePair<string, VdfFileNode> gameNodePair in gameNodeArray ) {
                    int gameId;
                    if( int.TryParse( gameNodePair.Key, out gameId ) ) {
                        if( ( ignore != null && ignore.Contains( gameId ) ) || !Program.GameDB.IncludeItemInGameList( gameId, includedTypes ) ) {
                            Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_SkippedProcessingGame, gameId );
                        } else if( gameNodePair.Value != null && gameNodePair.Value.NodeType == ValueType.Array ) {
                            GameInfo game = null;

                            // Add the game to the list if it doesn't exist already
                            if( !Games.ContainsKey( gameId ) ) {
                                game = new GameInfo( gameId, Program.GameDB.GetName( gameId ), this );
                                Games.Add( gameId, game );
                                Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_AddedNewGame, gameId, game.Name );
                            } else {
                                game = Games[gameId];
                            }

                            loadedGames++;

                            game.ApplySource( GameListingSource.SteamConfig );

                            game.Hidden = ( gameNodePair.Value.ContainsKey( "hidden" ) && gameNodePair.Value["hidden"].NodeInt != 0 );

                            VdfFileNode tagsNode = gameNodePair.Value["tags"];
                            if( tagsNode != null ) {
                                Dictionary<string, VdfFileNode> tagArray = tagsNode.NodeArray;
                                if( tagArray != null ) {
                                    List<Category> cats = new List<Category>( tagArray.Count );
                                    foreach( VdfFileNode tag in tagArray.Values ) {
                                        string tagName = tag.NodeString;
                                        if( tagName != null ) {
                                            Category c = GetCategory( tagName );
                                            if( c != null ) cats.Add( c );
                                        }
                                    }
                                    if( cats.Count > 0 ) {
                                        SetGameCategories( gameId, cats, false );
                                    }
                                }
                            }

                            Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_ProcessedGame, gameId, string.Join( ",", game.Categories ) );
                        }
                    }
                }
            }

            return loadedGames;
        }
示例#14
0
        /// <summary>
        /// Writes category information out to a steam config file. Also saves any other settings that had been loaded, to avoid setting loss.
        /// </summary>
        /// <param name="path">Full path of the steam config file to save</param>
        public void SaveSteamFile(string filePath, bool discardMissing)
        {
            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_SavingSteamConfigFile, filePath);

            TextVdfFileNode fileData = new TextVdfFileNode();

            try {
                using (StreamReader reader = new StreamReader(filePath, false)) {
                    fileData = TextVdfFileNode.Load(reader, true);
                }
            } catch (Exception e) {
                Program.Logger.Write(LoggerLevel.Warning, GlobalStrings.GameData_LoadingErrorSteamConfig, e.Message);
            }

            VdfFileNode appListNode = fileData.GetNodeAt(new string[] { "Software", "Valve", "Steam", "apps" }, true);

            if (discardMissing)
            {
                Dictionary <string, VdfFileNode> gameNodeArray = appListNode.NodeArray;
                if (gameNodeArray != null)
                {
                    foreach (KeyValuePair <string, VdfFileNode> pair in gameNodeArray)
                    {
                        int gameId;
                        if (!(int.TryParse(pair.Key, out gameId) && Games.ContainsKey(gameId)))
                        {
                            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_RemovingGameCategoryFromSteamConfig, gameId);
                            pair.Value.RemoveSubnode("tags");
                        }
                    }
                }
            }

            foreach (Game game in Games.Values)
            {
                if (game.Id > 0) // External games have negative identifier
                {
                    Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_AddingGameToConfigFile, game.Id);
                    VdfFileNode gameNode = (VdfFileNode)appListNode[game.Id.ToString()];
                    gameNode.RemoveSubnode("tags");
                    if (game.Category != null || game.Favorite)
                    {
                        VdfFileNode tagsNode = (VdfFileNode)gameNode["tags"];
                        int         key      = 0;
                        if (game.Category != null)
                        {
                            tagsNode[key.ToString()] = new TextVdfFileNode(game.Category.Name);
                            key++;
                        }
                        if (game.Favorite)
                        {
                            tagsNode[key.ToString()] = new TextVdfFileNode("favorite");
                        }
                    }
                }
            }

            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_CleaningUpSteamConfigTree);
            appListNode.CleanTree();

            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_WritingToDisk);
            TextVdfFileNode fullFile = new TextVdfFileNode();

            fullFile["UserLocalConfigStore"] = fileData;
            try {
                FileInfo f = new FileInfo(filePath);
                f.Directory.Create();
                FileStream fStream = f.Open(FileMode.Create, FileAccess.Write, FileShare.None);
                using (StreamWriter writer = new StreamWriter(fStream)) {
                    fullFile.Save(writer);
                }
                fStream.Close();
            } catch (ArgumentException e) {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString());
                throw new ApplicationException(GlobalStrings.GameData_FailedToSaveSteamConfigBadPath, e);
            } catch (IOException e) {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString());
                throw new ApplicationException(GlobalStrings.GameData_FailedToSaveSteamConfigFile + e.Message, e);
            } catch (UnauthorizedAccessException e) {
                Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString());
                throw new ApplicationException(GlobalStrings.GameData_AccessDeniedSteamConfigFile + e.Message, e);
            }
        }
示例#15
0
        /// <summary>
        /// Searches a list of games, looking for the one that matches the information in the shortcut node.
        /// Checks launch ID first, then checks a combination of name and ID, then just checks name.
        /// </summary>
        /// <param name="shortcutId">ID of the shortcut node</param>
        /// <param name="shortcutNode">Shotcut node itself</param>
        /// <param name="gamesToMatchAgainst">List of game objects to match against</param>
        /// <param name="shortcutLaunchIds">List of launch IDs referenced by name</param>
        /// <returns>The index of the matching game if found, -1 otherwise.</returns>
        private int FindMatchingShortcut( int shortcutId, VdfFileNode shortcutNode, List<GameInfo> gamesToMatchAgainst, StringDictionary shortcutLaunchIds )
        {
            VdfFileNode nodeName = shortcutNode.GetNodeAt( new string[] { "appname" }, false );
            string gameName = ( nodeName != null ) ? nodeName.NodeString : null;
            string launchId = shortcutLaunchIds[gameName];
            // First, look for games with matching launch IDs.
            for( int i = 0; i < gamesToMatchAgainst.Count; i++ ) {
                if( gamesToMatchAgainst[i].LaunchString == launchId ) return i;
            }
            // Second, look for games with matching names AND matching shortcut IDs.
            for( int i = 0; i < gamesToMatchAgainst.Count; i++ ) {
                if( gamesToMatchAgainst[i].Id == -( shortcutId + 1 ) && gamesToMatchAgainst[i].Name == gameName ) return i;
            }
            // Third, just look for name matches
            for( int i = 0; i < gamesToMatchAgainst.Count; i++ ) {
                if( gamesToMatchAgainst[i].Name == gameName ) return i;
            }

            return -1;
        }
示例#16
0
        public static AppInfo FromVdfNode(VdfFileNode commonNode)
        {
            if (commonNode == null || commonNode.NodeType != ValueType.Array)
            {
                return(null);
            }

            AppInfo result = null;

            VdfFileNode idNode = commonNode.GetNodeAt(new string[] { "gameid" }, false);
            int         id     = -1;

            if (idNode != null)
            {
                if (idNode.NodeType == ValueType.Int)
                {
                    id = idNode.NodeInt;
                }
                else if (idNode.NodeType == ValueType.String)
                {
                    if (!int.TryParse(idNode.NodeString, out id))
                    {
                        id = -1;
                    }
                }
            }

            if (id >= 0)
            {
                // Get name
                string      name     = null;
                VdfFileNode nameNode = commonNode.GetNodeAt(new string[] { "name" }, false);
                if (nameNode != null)
                {
                    name = nameNode.NodeData.ToString();
                }

                // Get type
                string      typeStr  = null;
                AppTypes    type     = AppTypes.Unknown;
                VdfFileNode typeNode = commonNode.GetNodeAt(new string[] { "type" }, false);
                if (typeNode != null)
                {
                    typeStr = typeNode.NodeData.ToString();
                }

                if (typeStr != null)
                {
                    if (!Enum.TryParse <AppTypes>(typeStr, true, out type))
                    {
                        type = AppTypes.Other;
                    }
                }

                // Get platforms
                string       oslist     = null;
                AppPlatforms platforms  = AppPlatforms.None;
                VdfFileNode  oslistNode = commonNode.GetNodeAt(new string[] { "oslist" }, false);
                if (oslistNode != null)
                {
                    oslist = oslistNode.NodeData.ToString();
                    if (oslist.IndexOf("windows", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        platforms |= AppPlatforms.Windows;
                    }
                    if (oslist.IndexOf("mac", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        platforms |= AppPlatforms.Mac;
                    }
                    if (oslist.IndexOf("linux", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        platforms |= AppPlatforms.Linux;
                    }
                }

                result = new AppInfo(id, name, type, platforms);

                // Get parent
                VdfFileNode parentNode = commonNode.GetNodeAt(new string[] { "parent" }, false);
                if (parentNode != null)
                {
                    result.Parent = parentNode.NodeInt;
                }
            }
            return(result);
        }
示例#17
0
        /// <summary>
        /// Loads in games from a VDF node containing a list of games.
        /// Any games in the node not found in the game list will be added to the gamelist.
        /// If a game in the node has a tags subnode, the "favorite" field will be overwritten.
        /// If a game in the node has a category set, it will overwrite any categories in the gamelist.
        /// If a game in the node does NOT have a category set, the category in the gamelist will NOT be cleared.
        /// </summary>
        /// <param name="appsNode">Node containing the game nodes</param>
        /// <param name="ignore">Set of games to ignore</param>
        /// <returns>Number of games loaded</returns>
        private int IntegrateGamesFromVdf( VdfFileNode appsNode, SortedSet<int> ignore, bool ignoreDlc )
        {
            int loadedGames = 0;

            Dictionary<string, VdfFileNode> gameNodeArray = appsNode.NodeArray;
            if( gameNodeArray != null ) {
                foreach( KeyValuePair<string, VdfFileNode> gameNodePair in gameNodeArray ) {
                    int gameId;
                    if( int.TryParse( gameNodePair.Key, out gameId ) ) {
                        if( ( ignore != null && ignore.Contains( gameId ) ) || ( ignoreDlc && Program.GameDB.IsDlc( gameId ) ) ) {
                            Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_SkippedProcessingGame, gameId );
                            continue;
                        }
                        if( gameNodePair.Value != null && gameNodePair.Value.ContainsKey( "tags" ) ) {
                            SortedSet<Category> cats = new SortedSet<Category>();

                            loadedGames++;

                            VdfFileNode tagsNode = gameNodePair.Value["tags"];
                            Dictionary<string, VdfFileNode> tagArray = tagsNode.NodeArray;
                            if( tagArray != null ) {
                                foreach( VdfFileNode tag in tagArray.Values ) {
                                    string tagName = tag.NodeString;
                                    if( tagName != null ) {
                                        Category c = GetCategory( tagName );
                                        if( c != null ) cats.Add( c );
                                    }
                                }
                            }

                            bool hidden = false;
                            if( gameNodePair.Value.ContainsKey( "hidden" ) ) {
                                VdfFileNode hiddenNode = gameNodePair.Value["hidden"];
                                hidden = ( hiddenNode.NodeString == "1" || hiddenNode.NodeInt == 1 );
                            }

                            // Add the game to the list if it doesn't exist already
                            if( !Games.ContainsKey( gameId ) ) {
                                GameInfo newGame = new GameInfo( gameId, string.Empty );
                                Games.Add( gameId, newGame );
                                newGame.Name = Program.GameDB.GetName( gameId );
                                Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_AddedNewGame, gameId, newGame.Name );
                            }

                            if( cats.Count > 0 ) {
                                this.SetGameCategories( gameId, cats, false );
                            }
                            Games[gameId].Hidden = hidden;

                            //TODO: Don't think SortedSet.ToString() does what I hope
                            Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_ProcessedGame, gameId, ( cats.Count == 0 ) ? "~" : cats.ToString() );
                        }
                    }
                }
            }

            return loadedGames;
        }
示例#18
0
        /// <summary>
        /// Adds a non-steam game to the gamelist.
        /// </summary>
        /// <param name="gameId">ID of the game in the steam config file</param>
        /// <param name="gameNode">Node for the game in the steam config file</param>
        /// <param name="oldShortcuts">List of un-matched non-steam games from the gamelist before the update</param>
        /// <param name="launchIds">Dictionary of launch ids (name:launchId)</param>
        /// <param name="newGames">Number of NEW games that have been added to the list</param>
        /// <param name="preferSteamCategories">If true, prefers to use the categories from the steam config if there is a conflict. If false, prefers to use the categories from the existing gamelist.</param>
        /// <returns>True if the game was successfully added</returns>
        private bool IntegrateShortcut( int gameId, VdfFileNode gameNode, List<Game> oldShortcuts, StringDictionary launchIds, ref int newGames, bool preferSteamCategories = true ) {
            VdfFileNode nodeName = gameNode.GetNodeAt( new string[] { "appname" }, false );
            string gameName = ( nodeName != null ) ? nodeName.NodeString : null;
            int newId = -gameId;

            if( Games.ContainsKey( newId ) ) {
                return false;
            }

            Game game = new Game( newId, gameName );
            Games.Add( newId, game );

            game.LaunchString = launchIds[gameName];

            int oldShortcutId = FindMatchingShortcut( gameId, gameNode, oldShortcuts, launchIds );
            bool oldCatSet = ( oldShortcutId != -1 ) && oldShortcuts[oldShortcutId].Category != null;
            if( oldShortcutId == -1 ) newGames++;
            
            VdfFileNode tagsNode = gameNode.GetNodeAt( new string[] { "tags" }, false );
            bool steamCatSet = ( tagsNode != null && tagsNode.NodeType == ValueType.Array && tagsNode.NodeArray.Count > 0 );
            
            //fill in categories
            if( steamCatSet && (preferSteamCategories || !oldCatSet) )  {
                foreach( KeyValuePair<string, VdfFileNode> tag in tagsNode.NodeArray) {
                    string tagName = tag.Value.NodeString;
                    if( tagName != null ) {
                        if( tagName == "favorite" ) {
                            game.Favorite = true;
                        } else {
                            game.Category = this.GetCategory( tagName );
                        }
                    }
                }

            } else {
                game.Category = oldShortcuts[oldShortcutId].Category;
                game.Favorite = oldShortcuts[oldShortcutId].Favorite;
            }

            if( oldShortcutId != -1 ) oldShortcuts.RemoveAt( oldShortcutId );
            return true;
        }
示例#19
0
        /// <summary>
        /// Writes category info for shortcut games to shortcuts.vdf config file for specified Steam user.
        /// Loads the shortcut config file, then tries to match each game in the file against one of the games in the gamelist. If it finds a match, it updates the config file with the new category info.
        /// </summary>
        /// <param name="SteamId">Identifier of Steam user to save information</param>
        /// <param name="discardMissing">If true, category information in shortcuts.vdf file is removed if game is not in Game list</param>
        public void ExportSteamShortcuts( long SteamId )
        {
            string filePath = string.Format( Properties.Resources.ShortCutsFilePath, Settings.Instance.SteamPath, Profile.ID64toDirName( SteamId ) );
            Program.Logger.Write( LoggerLevel.Info, GlobalStrings.GameData_SavingSteamConfigFile, filePath );
            FileStream fStream = null;
            BinaryReader binReader = null;
            VdfFileNode dataRoot = null;
            try {
                fStream = new FileStream( filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite );
                binReader = new BinaryReader( fStream );

                dataRoot = VdfFileNode.LoadFromBinary( binReader );
            } catch( FileNotFoundException e ) {
                Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorOpeningConfigFileParam, e.ToString() );
            } catch( IOException e ) {
                Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_LoadingErrorSteamConfig, e.ToString() );
            }
            if( binReader != null )
                binReader.Close();
            if( fStream != null )
                fStream.Close();
            if( dataRoot != null ) {

                List<GameInfo> gamesToSave = new List<GameInfo>();
                foreach( int id in Games.Keys ) {
                    if( id < 0 ) gamesToSave.Add( Games[id] );
                }

                StringDictionary launchIds = new StringDictionary();
                LoadShortcutLaunchIds( SteamId, out launchIds );

                VdfFileNode appsNode = dataRoot.GetNodeAt( new string[] { "shortcuts" }, false );
                foreach( KeyValuePair<string, VdfFileNode> shortcutPair in appsNode.NodeArray ) {
                    VdfFileNode nodeGame = shortcutPair.Value;
                    int nodeId = -1;
                    int.TryParse( shortcutPair.Key, out nodeId );

                    int matchingIndex = FindMatchingShortcut( nodeId, nodeGame, gamesToSave, launchIds );

                    if( matchingIndex >= 0 ) {
                        GameInfo game = gamesToSave[matchingIndex];
                        gamesToSave.RemoveAt( matchingIndex );

                        Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_AddingGameToConfigFile, game.Id );

                        VdfFileNode tagsNode = nodeGame.GetNodeAt( new string[] { "tags" }, true );
                        Dictionary<string, VdfFileNode> tags = tagsNode.NodeArray;
                        if( tags != null ) {
                            tags.Clear();
                        }

                        int index = 0;
                        foreach( Category c in game.Categories ) {
                            tagsNode[index.ToString()] = new VdfFileNode( c.Name );
                            index++;
                        }

                        nodeGame["hidden"] = new VdfFileNode( game.Hidden ? 1 : 0 );
                    }
                }
                if( dataRoot.NodeType == ValueType.Array ) {
                    Program.Logger.Write( LoggerLevel.Info, GlobalStrings.GameData_SavingShortcutConfigFile, filePath );
                    try {
                        Utility.BackupFile( filePath, Settings.Instance.ConfigBackupCount );
                    } catch( Exception e ) {
                        Program.Logger.Write( LoggerLevel.Error, GlobalStrings.Log_GameData_ShortcutBackupFailed, e.Message );
                    }
                    try {
                        string filePathTmp = filePath + ".tmp";
                        BinaryWriter binWriter;
                        fStream = new FileStream( filePathTmp, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite );
                        binWriter = new BinaryWriter( fStream );
                        dataRoot.SaveAsBinary( binWriter );
                        binWriter.Close();
                        fStream.Close();
                        File.Delete( filePath );
                        File.Move( filePathTmp, filePath );
                    } catch( ArgumentException e ) {
                        Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString() );
                        throw new ApplicationException( GlobalStrings.GameData_FailedToSaveSteamConfigBadPath, e );
                    } catch( IOException e ) {
                        Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString() );
                        throw new ApplicationException( GlobalStrings.GameData_FailedToSaveSteamConfigFile + e.Message, e );
                    } catch( UnauthorizedAccessException e ) {
                        Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString() );
                        throw new ApplicationException( GlobalStrings.GameData_AccessDeniedSteamConfigFile + e.Message, e );
                    }
                }
            }
        }
示例#20
0
        private int ImportNonSteamGames(long SteamId, SortedSet <int> ignore)
        {
            int    result   = 0;
            string filePath = string.Format(Properties.Resources.ShortCutsFilePath, Settings.Instance().SteamPath, Profile.ID64toDirName(SteamId));

            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_OpeningSteamConfigFile, filePath);

            Dictionary <string, int> shortcutgames;

            if (LoadShortcutGames(SteamId, out shortcutgames))
            {
                FileStream        fStream   = null;
                BinaryReader      binReader = null;
                BinaryVdfFileNode dataRoot  = null;
                try
                {
                    fStream   = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    binReader = new BinaryReader(fStream);
                    dataRoot  = BinaryVdfFileNode.Load(binReader);
                }
                finally
                {
                    if (binReader != null)
                    {
                        binReader.Close();
                    }
                    if (fStream != null)
                    {
                        fStream.Close();
                    }
                }
                if (dataRoot != null)
                {
                    VdfFileNode shortcutsNode = dataRoot.GetNodeAt(new string[] { "shortcuts" }, false);
                    foreach (KeyValuePair <string, VdfFileNode> shortcutPair in shortcutsNode.NodeArray)
                    {
                        string indexGame = shortcutPair.Key;

                        VdfFileNode attrGame = shortcutPair.Value;
                        VdfFileNode appGame  = attrGame.GetNodeAt(new string[] { "appname" }, false);

                        string gameName = appGame.NodeString;

                        // Check if external game has identifier in screenshots.vdf file (this happens only if game has been launched before from Steam client)
                        if (shortcutgames.ContainsKey(gameName))
                        {
                            int gameIdInDB = shortcutgames[gameName];
                            if (!ignore.Contains(gameIdInDB))
                            {
                                Game gameDB;
                                if (Games.ContainsKey(gameIdInDB))
                                {
                                    gameDB = Games[gameIdInDB];
                                }
                                else
                                {
                                    gameDB = new Game(gameIdInDB, gameName);
                                }

                                string      cat0 = null, cat1 = null;
                                VdfFileNode tagsGame = attrGame.GetNodeAt(new string[] { "tags" }, false);
                                if ((tagsGame != null) && (tagsGame.NodeType == ValueType.Array) &&
                                    (tagsGame.NodeArray.Count > 0) && (tagsGame.NodeArray.ContainsKey("0")))
                                {
                                    VdfFileNode vdfCat = tagsGame.NodeArray["0"];
                                    if (vdfCat.NodeType == ValueType.Value)
                                    {
                                        cat0 = vdfCat.NodeData.ToString();
                                    }
                                    if (tagsGame.NodeArray.ContainsKey("1"))
                                    {
                                        vdfCat = tagsGame.NodeArray["1"];
                                        if (vdfCat.NodeType == ValueType.Value)
                                        {
                                            cat1 = vdfCat.NodeData.ToString();
                                        }
                                    }
                                }
                                gameDB.Favorite = ((cat0 == "favorite") || (cat1 == "favorite"));
                                if (cat0 != "favorite")
                                {
                                    gameDB.Category = GetCategory(cat0);
                                }
                                else
                                {
                                    gameDB.Category = GetCategory(cat1);
                                }
                                result++;
                            }
                        }
                    }
                }
            }
            return(result);
        }
示例#21
0
        /// <summary>
        /// Loads a FileNode from stream.
        /// </summary>
        /// <param name="stream">Stream to load from</param>
        /// <returns>FileNode representing the contents of the stream.</returns>
        public static VdfFileNode LoadFromText( StreamReader stream, bool useFirstAsRoot = false ) {
            VdfFileNode thisLevel = useFirstAsRoot ? null : new VdfFileNode();

            ReadText_SkipWhitespace( stream );

            while( !stream.EndOfStream ) {

                ReadText_SkipWhitespace( stream );
                // Get key
                char nextChar = (char)stream.Read();
                string key = null;
                if( stream.EndOfStream || nextChar == '}' ) {
                    break;
                } else if( nextChar == '"' ) {
                    key = ReadText_GetStringToken( stream );
                } else {
                    throw new ParseException( string.Format( GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextChar ) );
                }
                ReadText_SkipWhitespace( stream );

                // Get value
                nextChar = (char)stream.Read();
                VdfFileNode newNode;
                if( nextChar == '"' ) {
                    newNode = new VdfFileNode( ReadText_GetStringToken( stream ) );
                } else if( nextChar == '{' ) {
                    newNode = LoadFromText( stream );
                } else {
                    throw new ParseException( string.Format( GlobalStrings.TextVdfFile_UnexpectedCharacterValue, nextChar ) );
                }

                if( useFirstAsRoot ) {
                    return newNode;
                }

                thisLevel[key] = newNode;
            }
            return thisLevel;
        }
示例#22
0
 /// <summary>
 /// Gets the node at the given address. May be used to build structure.
 /// </summary>
 /// <param name="args">An ordered list of keys, like a path</param>
 /// <param name="create">If true, will create any nodes it does not find along the path.</param>
 /// <param name="index">Start index of the arg array</param>
 /// <returns>The FileNode at the given location, or null if the location was not found / created</returns>
 public VdfFileNode GetNodeAt( string[] args, bool create = true, int index = 0 ) {
     if( index >= args.Length ) {
         return this;
     }
     if( this.NodeType == ValueType.Array ) {
         Dictionary<String, VdfFileNode> data = (Dictionary<String, VdfFileNode>)NodeData;
         if( ContainsKey( args[index] ) ) {
             return data[args[index]].GetNodeAt( args, create, index + 1 );
         } else if( create ) {
             VdfFileNode newNode = new VdfFileNode();
             data.Add( args[index], newNode );
             return newNode.GetNodeAt( args, create, index + 1 );
         }
     }
     return null;
 }
示例#23
0
        /// <summary>
        /// Searches a list of games, looking for the one that matches the information in the shortcut node.
        /// Checks launch ID first, then checks a combination of name and ID, then just checks name.
        /// </summary>
        /// <param name="shortcutId">ID of the shortcut node</param>
        /// <param name="shortcutNode">Shotcut node itself</param>
        /// <param name="gamesToMatchAgainst">List of game objects to match against</param>
        /// <param name="shortcutLaunchIds">List of launch IDs referenced by name</param>
        /// <returns>The index of the matching game if found, -1 otherwise.</returns>
        private int FindMatchingShortcut( int shortcutId, VdfFileNode shortcutNode, List<Game> gamesToMatchAgainst, StringDictionary shortcutLaunchIds ) {
            VdfFileNode nodeName = shortcutNode.GetNodeAt( new string[] { "appname" }, false );
            string gameName = ( nodeName != null ) ? nodeName.NodeString : null;
            string launchId = shortcutLaunchIds[gameName];

            for( int i = 0; i < gamesToMatchAgainst.Count; i++ ) {
                if( gamesToMatchAgainst[i].LaunchString == launchId ) return i;
            }

            for( int i = 0; i < gamesToMatchAgainst.Count; i++ ) {
                if( gamesToMatchAgainst[i].Id == shortcutId && gamesToMatchAgainst[i].Name == gameName ) return i;
            }

            for( int i = 0; i < gamesToMatchAgainst.Count; i++ ) {
                if( gamesToMatchAgainst[i].Name == gameName ) return i;
            }

            return -1;
        }
示例#24
0
        /// <summary>
        /// Adds a non-steam game to the gamelist.
        /// </summary>
        /// <param name="gameId">ID of the game in the steam config file</param>
        /// <param name="gameNode">Node for the game in the steam config file</param>
        /// <param name="oldShortcuts">List of un-matched non-steam games from the gamelist before the update</param>
        /// <param name="launchIds">Dictionary of launch ids (name:launchId)</param>
        /// <param name="newGames">Number of NEW games that have been added to the list</param>
        /// <param name="preferSteamCategories">If true, prefers to use the categories from the steam config if there is a conflict. If false, prefers to use the categories from the existing gamelist.</param>
        /// <returns>True if the game was successfully added</returns>
        private bool IntegrateShortcut( int gameId, VdfFileNode gameNode, List<GameInfo> oldShortcuts, StringDictionary launchIds, ref int newGames, bool preferSteamCategories = true )
        {
            VdfFileNode nodeName = gameNode.GetNodeAt( new string[] { "appname" }, false );
            string gameName = ( nodeName != null ) ? nodeName.NodeString : null;
            // The ID of the created game must be negative
            int newId = -( gameId + 1 );

            // This should never happen, but just in case
            if( Games.ContainsKey( newId ) ) {
                return false;
            }

            GameInfo game = new GameInfo( newId, gameName );
            Games.Add( newId, game );

            game.LaunchString = launchIds[gameName];

            int oldShortcutId = FindMatchingShortcut( gameId, gameNode, oldShortcuts, launchIds );
            bool oldCatSet = ( oldShortcutId != -1 ) && oldShortcuts[oldShortcutId].Categories.Count > 0;
            if( oldShortcutId == -1 ) newGames++;

            VdfFileNode tagsNode = gameNode.GetNodeAt( new string[] { "tags" }, false );
            bool steamCatSet = ( tagsNode != null && tagsNode.NodeType == ValueType.Array && tagsNode.NodeArray.Count > 0 );

            //fill in categories
            if( steamCatSet && ( preferSteamCategories || !oldCatSet ) ) {
                // Fill in categories from the Steam shortcut file
                foreach( KeyValuePair<string, VdfFileNode> tag in tagsNode.NodeArray ) {
                    string tagName = tag.Value.NodeString;
                    game.AddCategory( this.GetCategory( tagName ) );
                }

            } else if( oldShortcutId >= 0 && oldShortcutId < oldShortcuts.Count ) {
                // Fill in categories from the game list
                game.SetCategories( oldShortcuts[oldShortcutId].Categories );
            }

            game.Hidden = false;
            if( gameNode.ContainsKey( "hidden" ) ) {
                VdfFileNode hiddenNode = gameNode["hidden"];
                game.Hidden = ( hiddenNode.NodeString == "1" || hiddenNode.NodeInt == 1 );
            }

            if( oldShortcutId != -1 ) oldShortcuts.RemoveAt( oldShortcutId );
            return true;
        }
示例#25
0
        /// <summary>
        /// Adds a non-steam game to the gamelist.
        /// </summary>
        /// <param name="gameId">ID of the game in the steam config file</param>
        /// <param name="gameNode">Node for the game in the steam config file</param>
        /// <param name="launchIds">Dictionary of launch ids (name:launchId)</param>
        /// <param name="newGames">Number of NEW games that have been added to the list</param>
        /// <param name="preferSteamCategories">If true, prefers to use the categories from the steam config if there is a conflict. If false, prefers to use the categories from the existing gamelist.</param>
        /// <returns>True if the game was successfully added</returns>
        private bool IntegrateShortcut( int gameId, VdfFileNode gameNode, StringDictionary launchIds )
        {
            VdfFileNode nodeName = gameNode.GetNodeAt( new string[] { "appname" }, false );
            string gameName = ( nodeName != null ) ? nodeName.NodeString : null;
            // The ID of the created game must be negative
            int newId = -( gameId + 1 );

            // This should never happen, but just in case
            if( Games.ContainsKey( newId ) ) {
                return false;
            }

            //Create the new GameInfo
            GameInfo game = new GameInfo( newId, gameName, this );
            Games.Add( newId, game );

            // Fill in the LaunchString
            game.LaunchString = launchIds[gameName];

            // Fill in categories
            VdfFileNode tagsNode = gameNode.GetNodeAt( new string[] { "tags" }, false );
            foreach( KeyValuePair<string, VdfFileNode> tag in tagsNode.NodeArray ) {
                string tagName = tag.Value.NodeString;
                game.AddCategory( this.GetCategory( tagName ) );
            }

            // Fill in Hidden
            game.Hidden = false;
            if( gameNode.ContainsKey( "hidden" ) ) {
                VdfFileNode hiddenNode = gameNode["hidden"];
                game.Hidden = ( hiddenNode.NodeString == "1" || hiddenNode.NodeInt == 1 );
            }

            return true;
        }
示例#26
0
        public static AppInfo FromVdfNode( VdfFileNode commonNode ) {
            if( commonNode == null || commonNode.NodeType != ValueType.Array ) return null;

            AppInfo result = null;

            VdfFileNode idNode = commonNode.GetNodeAt( new string[] { "gameid" }, false );
            int id = -1;
            if( idNode != null ) {
                if( idNode.NodeType == ValueType.Int ) {
                    id = idNode.NodeInt;
                } else if( idNode.NodeType == ValueType.String ) {
                    if( !int.TryParse( idNode.NodeString, out id ) ) {
                        id = -1;
                    }
                }
            }

            if( id >= 0 ) {
                // Get name
                string name = null;
                VdfFileNode nameNode = commonNode.GetNodeAt( new string[] { "name" }, false );
                if( nameNode != null ) name = nameNode.NodeData.ToString();

                // Get type
                string typeStr = null;
                AppTypes type = AppTypes.Unknown;
                VdfFileNode typeNode = commonNode.GetNodeAt( new string[] { "type" }, false );
                if( typeNode != null ) typeStr = typeNode.NodeData.ToString();

                if( typeStr != null ) {
                    if( !Enum.TryParse<AppTypes>( typeStr, true, out type ) ) {
                        type = AppTypes.Other;
                    }
                }

                // Get platforms
                string oslist = null;
                AppPlatforms platforms = AppPlatforms.None;
                VdfFileNode oslistNode = commonNode.GetNodeAt( new string[] { "oslist" }, false );
                if( oslistNode != null ) {
                    oslist = oslistNode.NodeData.ToString();
                    if( oslist.IndexOf( "windows", StringComparison.OrdinalIgnoreCase ) != -1 ) {
                        platforms |= AppPlatforms.Windows;
                    }
                    if( oslist.IndexOf( "mac", StringComparison.OrdinalIgnoreCase ) != -1 ) {
                        platforms |= AppPlatforms.Mac;
                    }
                    if( oslist.IndexOf( "linux", StringComparison.OrdinalIgnoreCase ) != -1 ) {
                        platforms |= AppPlatforms.Linux;
                    }
                }

                result = new AppInfo( id, name, type, platforms );

                // Get parent
                VdfFileNode parentNode = commonNode.GetNodeAt( new string[] { "parent" }, false );
                if( parentNode != null ) {
                    result.Parent = parentNode.NodeInt;
                }

            }
            return result;
        }
示例#27
0
        /// <summary>
        /// Writes Steam game category information to Steam user config file.
        /// </summary>
        /// <param name="filePath">Full path of the steam config file to save</param>
        /// <param name="discardMissing">If true, any pre-existing game entries in the file that do not have corresponding entries in the GameList are removed</param>
        public void ExportSteamConfigFile( string filePath, bool discardMissing )
        {
            Program.Logger.Write( LoggerLevel.Info, GlobalStrings.GameData_SavingSteamConfigFile, filePath );

            VdfFileNode fileData = new VdfFileNode();
            try {
                using( StreamReader reader = new StreamReader( filePath, false ) ) {
                    fileData = VdfFileNode.LoadFromText( reader, true );
                }
            } catch( Exception e ) {
                Program.Logger.Write( LoggerLevel.Warning, GlobalStrings.GameData_LoadingErrorSteamConfig, e.Message );
            }

            VdfFileNode appListNode = fileData.GetNodeAt( new string[] { "Software", "Valve", "Steam", "apps" }, true );

            // Run through all Delete category data for any games not found in the GameList
            if( discardMissing ) {
                Dictionary<string, VdfFileNode> gameNodeArray = appListNode.NodeArray;
                if( gameNodeArray != null ) {
                    foreach( KeyValuePair<string, VdfFileNode> pair in gameNodeArray ) {
                        int gameId;
                        if( !( int.TryParse( pair.Key, out gameId ) && Games.ContainsKey( gameId ) ) ) {
                            Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_RemovingGameCategoryFromSteamConfig, gameId );
                            pair.Value.RemoveSubnode( "tags" );
                        }
                    }
                }
            }

            // Force appListNode to be an array, we can't do anything if it's a value
            appListNode.MakeArray();

            foreach( GameInfo game in Games.Values ) {
                if( game.Id > 0 ) { // External games have negative identifier
                    Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_AddingGameToConfigFile, game.Id );
                    VdfFileNode gameNode = (VdfFileNode)appListNode[game.Id.ToString()];
                    gameNode.MakeArray();

                    VdfFileNode tagsNode = (VdfFileNode)gameNode["tags"];
                    tagsNode.MakeArray();

                    Dictionary<string, VdfFileNode> tags = tagsNode.NodeArray;
                    if( tags != null ) tags.Clear();

                    int key = 0;
                    foreach( Category c in game.Categories ) {
                        string name = c.Name;
                        if (name == FAVORITE_NEW_CONFIG_VALUE) name = FAVORITE_CONFIG_VALUE;
                        tagsNode[key.ToString()] = new VdfFileNode( name );
                        key++;
                    }

                    if( game.Hidden ) {
                        gameNode["hidden"] = new VdfFileNode( "1" );
                    } else {
                        gameNode.RemoveSubnode( "hidden" );
                    }
                }
            }

            Program.Logger.Write( LoggerLevel.Verbose, GlobalStrings.GameData_CleaningUpSteamConfigTree );
            appListNode.CleanTree();

            Program.Logger.Write( LoggerLevel.Info, GlobalStrings.GameData_WritingToDisk );
            VdfFileNode fullFile = new VdfFileNode();
            fullFile["UserLocalConfigStore"] = fileData;
            try {
                Utility.BackupFile( filePath, Settings.Instance.ConfigBackupCount );
            } catch( Exception e ) {
                Program.Logger.Write( LoggerLevel.Error, GlobalStrings.Log_GameData_ConfigBackupFailed, e.Message );
            }
            try {
                string filePathTmp = filePath + ".tmp";
                FileInfo f = new FileInfo( filePathTmp );
                f.Directory.Create();
                FileStream fStream = f.Open( FileMode.Create, FileAccess.Write, FileShare.None );
                using( StreamWriter writer = new StreamWriter( fStream ) ) {
                    fullFile.SaveAsText( writer );
                }
                fStream.Close();
                File.Delete( filePath );
                File.Move( filePathTmp, filePath );
            } catch( ArgumentException e ) {
                Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString() );
                throw new ApplicationException( GlobalStrings.GameData_FailedToSaveSteamConfigBadPath, e );
            } catch( IOException e ) {
                Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString() );
                throw new ApplicationException( GlobalStrings.GameData_FailedToSaveSteamConfigFile + e.Message, e );
            } catch( UnauthorizedAccessException e ) {
                Program.Logger.Write( LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString() );
                throw new ApplicationException( GlobalStrings.GameData_AccessDeniedSteamConfigFile + e.Message, e );
            }
        }
示例#28
0
        /// <summary>
        /// Integrate external games defined by Steam user. Only external games with identifier in screenshot.vdf file are included in game DB.
        /// </summary>
        /// <param name="SteamId">Identifier of Steam user</param>
        /// <param name="overWrite">Overwrite actual contents of game DB</param>
        /// <param name="ignore">List of identifiers of games to be ignored</param>
        /// <param name="newItems">Returns number of new games integrated</param>
        /// <returns>Returns number of external games located</returns>
        public int IntegrateNonSteamGameList(long SteamId, bool overWrite, SortedSet <int> ignore, out int newItems, out int removedItems)
        {
            newItems     = 0;
            removedItems = 0;
            if (SteamId <= 0)
            {
                return(0);
            }
            int loadedGames = 0;

            Dictionary <string, int> shortcutgames;

            if (LoadShortcutGames(SteamId, out shortcutgames))
            {
                string       filePath  = string.Format(Properties.Resources.ShortCutsFilePath, Settings.Instance().SteamPath, Profile.ID64toDirName(SteamId));
                FileStream   fStream   = null;
                BinaryReader binReader = null;
                try
                {
                    fStream   = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    binReader = new BinaryReader(fStream);

                    BinaryVdfFileNode dataRoot = BinaryVdfFileNode.Load(binReader);

                    VdfFileNode shortcutsNode = dataRoot.GetNodeAt(new string[] { "shortcuts" }, false);

                    if (shortcutsNode != null)
                    {
                        foreach (KeyValuePair <string, VdfFileNode> shortcutPair in shortcutsNode.NodeArray)
                        {
                            //string indexGame = shortcutPair.Key;

                            VdfFileNode attrGame = shortcutPair.Value;
                            VdfFileNode appGame  = attrGame.GetNodeAt(new string[] { "appname" }, false);

                            string gameName = appGame.NodeString;

                            // Check if external game has identifier in screenshots.vdf file (this happens only if game has been launched before from Steam client)
                            if (shortcutgames.ContainsKey(gameName))
                            {
                                bool isNew;
                                if (IntegrateGame(shortcutgames[gameName], gameName, overWrite, ignore, false, out isNew))
                                {
                                    loadedGames++;
                                    if (isNew)
                                    {
                                        newItems++;
                                    }
                                }
                                shortcutgames.Remove(gameName);
                            }
                        }
                    }
                    // Remove external games which have been deleted from Steam client
                    foreach (KeyValuePair <string, int> shortcutpair in shortcutgames)
                    {
                        if (RemoveGame(shortcutpair.Value))
                        {
                            removedItems++;
                        }
                    }
                }
                catch (FileNotFoundException e)
                {
                    Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorOpeningConfigFileParam, e.ToString());
                    //throw new ApplicationException(string.Format(GlobalStrings.GameData_ErrorOpeningConfigFileParam, filePath) + e.Message, e);
                }
                catch (IOException e)
                {
                    Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_LoadingErrorSteamConfig, e.ToString());
                }
                catch (ParseException e)
                {
                    Program.Logger.Write(LoggerLevel.Error, e.ToString());
                }
                finally
                {
                    if (binReader != null)
                    {
                        binReader.Close();
                    }
                    if (fStream != null)
                    {
                        fStream.Close();
                    }
                }
            }

            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_IntegratedShortCuts, loadedGames, newItems, removedItems);

            return(loadedGames);
        }
示例#29
0
        /// <summary>
        /// Loads in games from an node containing a list of games.
        /// </summary>
        /// <param name="appsNode">Node containing the game nodes</param>
        /// <param name="ignore">Set of games to ignore</param>
        /// <returns>Number of games loaded</returns>
        private int GetDataFromVdf(VdfFileNode appsNode, SortedSet <int> ignore, bool ignoreDlc)
        {
            int loadedGames = 0;

            Dictionary <string, VdfFileNode> gameNodeArray = appsNode.NodeArray;

            if (gameNodeArray != null)
            {
                foreach (KeyValuePair <string, VdfFileNode> gameNodePair in gameNodeArray)
                {
                    int gameId;
                    if (int.TryParse(gameNodePair.Key, out gameId))
                    {
                        if ((ignore != null && ignore.Contains(gameId)) || (ignoreDlc && Program.GameDB.IsDlc(gameId)))
                        {
                            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_SkippedProcessingGame, gameId);
                            continue;
                        }
                        if (gameNodePair.Value != null && gameNodePair.Value.ContainsKey("tags"))
                        {
                            Category cat = null;
                            bool     fav = false;
                            loadedGames++;
                            VdfFileNode tagsNode = gameNodePair.Value["tags"];
                            Dictionary <string, VdfFileNode> tagArray = tagsNode.NodeArray;
                            if (tagArray != null)
                            {
                                foreach (VdfFileNode tag in tagArray.Values)
                                {
                                    string tagName = tag.NodeString;
                                    if (tagName != null)
                                    {
                                        if (tagName == "favorite")
                                        {
                                            fav = true;
                                        }
                                        else
                                        {
                                            cat = GetCategory(tagName);
                                        }
                                    }
                                }
                            }

                            if (!Games.ContainsKey(gameId))
                            {
                                Game newGame = new Game(gameId, string.Empty);
                                Games.Add(gameId, newGame);
                                newGame.Name = Program.GameDB.GetName(gameId);
                                Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_AddedNewGame, gameId, newGame.Name);
                            }
                            Games[gameId].Category = cat;
                            Games[gameId].Favorite = fav;
                            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_ProcessedGame, gameId, (cat == null) ? "~none~" : cat.ToString(), fav);
                        }
                    }
                }
            }

            return(loadedGames);
        }
示例#30
0
        /// <summary>
        /// Writes category info for shortcut games to shortcuts.vdf config file for specified Steam user.
        /// </summary>
        /// <param name="SteamId">Identifier of Steam user to save information</param>
        /// <param name="discardMissing">If true, category information in shortcuts.vdf file is removed if game is not in Game list</param>
        private void SaveShortcutGames(long SteamId, bool discardMissing)
        {
            string screenshotsFilePath = string.Format(Properties.Resources.ScreenshotsFilePath, Settings.Instance().SteamPath, Profile.ID64toDirName(SteamId));

            Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_SavingSteamConfigFile, screenshotsFilePath);

            Dictionary <string, int> shortcutgames;

            if (LoadShortcutGames(SteamId, out shortcutgames))
            {
                string            filePath  = string.Format(Properties.Resources.ShortCutsFilePath, Settings.Instance().SteamPath, Profile.ID64toDirName(SteamId));
                FileStream        fStream   = null;
                BinaryReader      binReader = null;
                BinaryVdfFileNode dataRoot  = null;
                try
                {
                    fStream   = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    binReader = new BinaryReader(fStream);

                    dataRoot = BinaryVdfFileNode.Load(binReader);
                }
                catch (FileNotFoundException e)
                {
                    Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorOpeningConfigFileParam, e.ToString());
                }
                catch (IOException e)
                {
                    Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_LoadingErrorSteamConfig, e.ToString());
                }
                if (binReader != null)
                {
                    binReader.Close();
                }
                if (fStream != null)
                {
                    fStream.Close();
                }
                if (dataRoot != null)
                {
                    List <KeyValuePair <string, int>?> listShortCutGames = new List <KeyValuePair <string, int>?>();
                    VdfFileNode appsNode = dataRoot.GetNodeAt(new string[] { "shortcuts" }, false);
                    foreach (KeyValuePair <string, VdfFileNode> shortcutPair in appsNode.NodeArray)
                    {
                        VdfFileNode attrGame = shortcutPair.Value;
                        VdfFileNode appGame  = attrGame.GetNodeAt(new string[] { "appname" }, false);

                        string gameName = appGame.NodeString;
                        // Check if external game has identifier in screenshots.vdf file (this happens only if game has been launched before from Steam client)
                        if (shortcutgames.ContainsKey(gameName))
                        {
                            VdfFileNode tagsNode = attrGame.GetNodeAt(new string[] { "tags" }, false);
                            int         idGame   = shortcutgames[gameName];
                            if (Games.ContainsKey(idGame))
                            {
                                Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_AddingGameToConfigFile, idGame);
                                tagsNode.NodeArray.Clear();
                                Game game = Games[idGame];
                                if ((game.Category != null) || (game.Favorite))
                                {
                                    int index = 0;
                                    if (game.Category != null)
                                    {
                                        tagsNode.NodeArray.Add(index.ToString(), new BinaryVdfFileNode(game.Category.Name));
                                        index++;
                                    }
                                    if (game.Favorite)
                                    {
                                        tagsNode.NodeArray.Add(index.ToString(), new BinaryVdfFileNode("favorite"));
                                    }
                                }
                            }
                            else if (discardMissing)
                            {
                                Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_RemovingGameCategoryFromSteamConfig, idGame);
                                tagsNode.NodeArray.Clear();
                            }
                        }
                    }
                    if (dataRoot.NodeType == ValueType.Array)
                    {
                        Program.Logger.Write(LoggerLevel.Info, GlobalStrings.GameData_SavingShortcutConfigFile, filePath);
                        BinaryWriter binWriter;
                        try
                        {
                            fStream   = new FileStream(filePath, FileMode.Truncate, FileAccess.ReadWrite, FileShare.ReadWrite);
                            binWriter = new BinaryWriter(fStream);
                            dataRoot.Save(binWriter);
                            binWriter.Close();
                            fStream.Close();
                        }
                        catch (ArgumentException e)
                        {
                            Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString());
                            throw new ApplicationException(GlobalStrings.GameData_FailedToSaveSteamConfigBadPath, e);
                        }
                        catch (IOException e)
                        {
                            Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString());
                            throw new ApplicationException(GlobalStrings.GameData_FailedToSaveSteamConfigFile + e.Message, e);
                        }
                        catch (UnauthorizedAccessException e)
                        {
                            Program.Logger.Write(LoggerLevel.Error, GlobalStrings.GameData_ErrorSavingSteamConfigFile, e.ToString());
                            throw new ApplicationException(GlobalStrings.GameData_AccessDeniedSteamConfigFile + e.Message, e);
                        }
                    }
                }
            }
        }
示例#31
0
        /// <summary>
        /// Loads a FileNode from stream.
        /// </summary>
        /// <param name="stream">Stream to load from</param>
        /// <returns>FileNode representing the contents of the stream.</returns>
        public static VdfFileNode LoadFromBinary( BinaryReader stream, long streamLength = -1 ) {
            if( streamLength == -1 ) streamLength = stream.BaseStream.Length;
            if( stream.BaseStream.Position == streamLength ) return null;
            VdfFileNode thisLevel = new VdfFileNode();

            bool endOfStream = false;

            while( !endOfStream ) {
                byte nextByte;
                try {
                    nextByte = stream.ReadByte();
                } catch( EndOfStreamException ) {
                    endOfStream = true;
                    nextByte = 8;
                }
                // Get key
                string key = null;
                if( endOfStream || nextByte == 8 || stream.BaseStream.Position == streamLength ) {
                    break;
                } else if( nextByte == 0 ) {
                    key = ReadBin_GetStringToken( stream );
                    VdfFileNode newNode;
                    newNode = LoadFromBinary( stream, streamLength );
                    thisLevel[key] = newNode;
                } else if( nextByte == 1 ) {
                    key = ReadBin_GetStringToken( stream );
                    thisLevel[key] = new VdfFileNode( ReadBin_GetStringToken( stream ) );
                } else if( nextByte == 2 ) {
                    key = ReadBin_GetStringToken( stream );
                    int val = stream.ReadInt32();
                    thisLevel[key] = new VdfFileNode( val );
                } else if( nextByte == 7 ) {
                    key = ReadBin_GetStringToken( stream );
                    ulong val = stream.ReadUInt64();
                    thisLevel[key] = new VdfFileNode( val );
                } else if( nextByte == 0xFF ) {
                    return null;
                } else {
                    throw new ParseException( string.Format( GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextByte.ToString() ) );
                }
            }
            return thisLevel;
        }
示例#32
0
        /// <summary>
        /// Loads in games from an node containing a list of games.
        /// </summary>
        /// <param name="appsNode">Node containing the game nodes</param>
        /// <param name="ignore">Set of games to ignore</param>
        /// <returns>Number of games loaded</returns>
        private int GetDataFromVdf(VdfFileNode appsNode, SortedSet<int> ignore, bool ignoreDlc )
        {
            int loadedGames = 0;

            Dictionary<string, VdfFileNode> gameNodeArray = appsNode.NodeArray;
            if( gameNodeArray != null ) {
                foreach( KeyValuePair<string, VdfFileNode> gameNodePair in gameNodeArray ) {
                    int gameId;
                    if( int.TryParse( gameNodePair.Key, out gameId ) ) {
                        if( ( ignore != null && ignore.Contains( gameId ) ) || ( ignoreDlc && Program.GameDB.IsDlc( gameId ) ) ) {
                            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_SkippedProcessingGame, gameId);
                            continue;
                        }
                        if( gameNodePair.Value != null && gameNodePair.Value.ContainsKey( "tags" ) ) {
                            Category cat = null;
                            bool fav = false;
                            loadedGames++;
                            VdfFileNode tagsNode = gameNodePair.Value["tags"];
                            Dictionary<string, VdfFileNode> tagArray = tagsNode.NodeArray;
                            if( tagArray != null ) {
                                foreach( VdfFileNode tag in tagArray.Values ) {
                                    string tagName = tag.NodeString;
                                    if( tagName != null ) {
                                        if( tagName == "favorite" ) {
                                            fav = true;
                                        } else {
                                            cat = GetCategory( tagName );
                                        }
                                    }
                                }
                            }

                            if( !Games.ContainsKey( gameId ) ) {
                                Game newGame = new Game( gameId, string.Empty );
                                Games.Add( gameId, newGame );
                                newGame.Name = Program.GameDB.GetName( gameId );
                                Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_AddedNewGame, gameId, newGame.Name);
                            }
                            Games[gameId].Category = cat;
                            Games[gameId].Favorite = fav;
                            Program.Logger.Write(LoggerLevel.Verbose, GlobalStrings.GameData_ProcessedGame, gameId, (cat == null) ? "~none~" : cat.ToString(), fav);
                        }
                    }
                }
            }

            return loadedGames;
        }