/// <summary> /// Populate this instance from the given <see cref="Stream"/> as a binary <see cref="KeyValue"/>. /// </summary> /// <param name="input">The input <see cref="Stream"/> to read from.</param> /// <returns><c>true</c> if the read was successful; otherwise, <c>false</c>.</returns> public bool ReadAsBinary(Stream input) { this.Children = new List <KeyValue>(); while (true) { var type = (Type)input.ReadByte(); if (type == Type.End) { break; } var current = new KeyValue { Name = input.ReadNullTermString(Encoding.UTF8) }; try { switch (type) { case Type.None: { current.ReadAsBinary(input); break; } case Type.String: { current.Value = input.ReadNullTermString(Encoding.UTF8); break; } case Type.WideString: { throw new InvalidDataException("wstring is unsupported"); } case Type.Int32: case Type.Color: case Type.Pointer: { current.Value = Convert.ToString(input.ReadInt32()); break; } case Type.UInt64: { current.Value = Convert.ToString(input.ReadUInt64()); break; } case Type.Float32: { current.Value = Convert.ToString(input.ReadFloat(), CultureInfo.InvariantCulture); break; } default: { throw new InvalidDataException("Unknown KV type encountered."); } } } catch (InvalidDataException ex) { throw new InvalidDataException($"An exception ocurred while reading KV '{current.Name}'", ex); } this.Children.Add(current); } return(input.Position == input.Length); }
public IEnumerable <GameDescriptor> CollectInstalledGames() { if (!File.Exists(libraryFoldersPath)) { yield break; } var steamAppsPath = PathUtils.Combine(steamInstallationDir, "steamapps"); var libraryFolders = new HashSet <string> { steamAppsPath }; var librabyFoldersKv = KeyValue.LoadAsText(libraryFoldersPath); if (librabyFoldersKv.Name == "LibraryFolders") { foreach (var child in librabyFoldersKv.Children) { if (uint.TryParse(child.Name, out _)) { libraryFolders.Add(PathUtils.Combine(child.Value, "steamapps")); } } } foreach (var libraryFolder in libraryFolders) { if (!Directory.Exists(libraryFolder)) { continue; } var appmanifestFilePaths = Directory.GetFiles(libraryFolder, "appmanifest_*.acf"); foreach (var appmanifestFilePath in appmanifestFilePaths) { var appmanifestKv = KeyValue.LoadAsText(appmanifestFilePath); if (appmanifestKv.Name == "AppState") { string gameName = null; string gameId = null; foreach (var child in appmanifestKv.Children) { switch (child.Name) { case "appid": gameId = child.Value; break; case "name": gameName = StringExtensions.NormalizeGameName(child.Value); break; } } if (!string.IsNullOrEmpty(gameId) && !string.IsNullOrEmpty(gameName)) { // "228980" corresponds to "Steamworks Common Redistributables" and should be skipped if (gameId != "228980") { yield return(new GameDescriptor(gameName, gameId)); } } } } } }