/// <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); }