Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        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));
                            }
                        }
                    }
                }
            }
        }