private static SteamGameInfo Parse(KeyValue kv, SteamLibrary library)
        {
            var gameName = kv.Key;

            if (gameName.Length == 0)
            {
                throw new SteamException("The name of the game is missing.");
            }

            var gameDir = (string)kv[GameDirKey];

            if (gameDir == null)
            {
                throw new SteamException("The path to the game directory of game \"" + gameName + "\" is missing.");
            }

            var executable = (string)kv[ExecutableKey];

            if (executable == null)
            {
                throw new SteamException("The path to the executable of game \"" + gameName + "\" is missing.");
            }

            var parser = new GameDirAndExecutableParser(gameName);

            if (!parser.Parse(gameDir, executable, library))
            {
                return(null);
            }

            var arguments = ((string)kv[ArgumentsKey])?.Replace("<steam>", library.InstallPath) ?? string.Empty;
            var appId     = (uint?)kv[AppIdKey] ?? 0;

            return(new SteamGameInfo(gameName, appId, parser.ValidatedGameDir, parser.ValidatedExecutable, arguments));
        }
        public static IReadOnlyList <SteamUserInfo> LocateUsers(SteamLibrary library)
        {
            if (library == null)
            {
                throw new ArgumentNullException(nameof(library));
            }

            try
            {
                var userdata = new DirectoryInfo(library.InstallPath + "\\userdata");

                if (!userdata.Exists)
                {
                    return(Array.Empty <SteamUserInfo>());
                }

                var users = new List <SteamUserInfo>();

                foreach (var dir in userdata.EnumerateDirectories())
                {
                    var userId = StringConverter.TryToUInt32(dir.Name);

                    if (!userId.HasValue || userId.Value == 0)
                    {
                        continue;
                    }

                    var localConfigPath = dir.FullName + "\\config\\localconfig.vdf";

                    if (!File.Exists(localConfigPath))
                    {
                        continue;
                    }

                    var name = (string)KeyValue.Load(localConfigPath)?["friends"]?["PersonaName"];

                    if (name != null)
                    {
                        users.Add(new SteamUserInfo(userId.Value, name, dir.FullName));
                    }
                }

                return(users.ToArray());
            }
            catch (Exception ex) when(ex is IOException ||
                                      ex is UnauthorizedAccessException ||
                                      ex is SecurityException ||
                                      ex is ParseException)
            {
                throw new SteamException("Unable to locate steam users: " + ex.Message, ex);
            }
        }
        public static IReadOnlyList <SteamGameInfo> LocateGames(KeyValue gameData, SteamLibrary library)
        {
            if (gameData == null)
            {
                throw new ArgumentNullException(nameof(gameData));
            }
            if (library == null)
            {
                throw new ArgumentNullException(nameof(library));
            }

            if (!gameData.HasChildren)
            {
                return(Array.Empty <SteamGameInfo>());
            }

            return(gameData.Select(kv => Parse(kv, library)).Where(game => game != null).ToArray());
        }
            public bool Parse(string gameDir, string executable, SteamLibrary library)
            {
                gameDir    = gameDir.Replace("<steam>", library.InstallPath);
                executable = executable.Replace("<steam>", library.InstallPath);

                if (!gameDir.Contains("<library>"))
                {
                    _validatedGameDir = ValidateGameDir(gameDir);
                }

                if (!executable.Contains("<library>"))
                {
                    _validatedExecutable = ValidateExecutable(executable);
                }

                if (_validatedGameDir != null && _validatedExecutable != null)
                {
                    return(true);
                }

                foreach (var folder in library.Folders)
                {
                    var newGameDir = _validatedGameDir ??
                                     ValidateGameDir(gameDir.Replace("<library>", folder));

                    var newExecutable = _validatedExecutable ??
                                        ValidateExecutable(executable.Replace("<library>", folder));

                    if (newGameDir != null && newExecutable != null)
                    {
                        _validatedGameDir    = newGameDir;
                        _validatedExecutable = newExecutable;
                        return(true);
                    }
                }

                return(false);
            }