Exemple #1
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 BinaryVdfFileNode Load(BinaryReader stream)
        {
            BinaryVdfFileNode thisLevel = new BinaryVdfFileNode();

            bool endOfStream = false;

            while (!endOfStream)
            {
                //SkipWhitespace( stream );
                byte nextByte;
                try
                {
                    nextByte = stream.ReadByte();
                }
                catch (EndOfStreamException e)
                {
                    endOfStream = true;
                    nextByte    = 8;
                }
                // Get key
                string key = null;
                if (endOfStream || nextByte == 8)
                {
                    break;
                }
                else if (nextByte == 0)
                {
                    key = GetStringToken(stream);
                    BinaryVdfFileNode newNode;
                    newNode        = Load(stream);
                    thisLevel[key] = newNode;
                }
                else if (nextByte == 1)
                {
                    key            = GetStringToken(stream);
                    thisLevel[key] = new BinaryVdfFileNode(GetStringToken(stream));
                }
                else
                {
                    throw new ParseException(string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextByte.ToString()));
                }
            }
            return(thisLevel);
        }
        /// <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 BinaryVdfFileNode Load( BinaryReader stream )
        {
            BinaryVdfFileNode thisLevel = new BinaryVdfFileNode();

            bool endOfStream = false;

            while( !endOfStream ) {

                //SkipWhitespace( stream );
                byte nextByte;
                try {
                    nextByte = stream.ReadByte();
                } catch( EndOfStreamException ) {
                    endOfStream = true;
                    nextByte = 8;
                }
                // Get key
                string key = null;
                if( endOfStream || nextByte == 8 ) {
                    break;
                } else if( nextByte == 0 ) {
                    key = GetStringToken( stream );
                    BinaryVdfFileNode newNode;
                    newNode = Load( stream );
                    thisLevel[key] = newNode;
                } else if( nextByte == 1 ) {
                    key = GetStringToken( stream );
                    thisLevel[key] = new BinaryVdfFileNode( GetStringToken( stream ) );
                } else if( nextByte == 2 ) {
                    key = GetStringToken( stream );
                    int val = stream.ReadInt32();
                    thisLevel[key] = new BinaryVdfFileNode( val );
                } else {
                    throw new ParseException( string.Format( GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextByte.ToString() ) );
                }
            }
            return thisLevel;
        }
        /// <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;
            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<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 BinaryVdfFileNode( c.Name );
                            index++;
                        }

                        nodeGame["hidden"] = new BinaryVdfFileNode( 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.Save( 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 );
                    }
                }
            }
        }
        /// <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);
        }
        /// <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);
                        }
                    }
                }
            }
        }
        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);
        }