/// <summary> /// Attempts to add a found <see cref="GameFinderItemContainer"/> /// </summary> /// <param name="game">The game item to add</param> /// <param name="installDir">The found install directory</param> /// <param name="parameter">Optional parameter</param> /// <returns>True if the game item was added, otherwise false</returns> protected virtual async Task <bool> AddGameAsync(GameFinderItemContainer game, FileSystemPath installDir, object parameter = null) { RL.Logger?.LogInformationSource($"An install directory was found for {game.Game}"); // Make sure the game hasn't already been found if (FoundGames.Contains(game.Game)) { RL.Logger?.LogWarningSource($"{game.Game} could not be added. The game has already been found."); return(false); } // Make sure the install directory exists if (!installDir.DirectoryExists) { RL.Logger?.LogWarningSource($"{game.Game} could not be added. The install directory does not exist."); return(false); } // If available, run custom verification if (game.FinderItem.VerifyInstallDirectory != null) { var result = game.FinderItem.VerifyInstallDirectory?.Invoke(installDir); if (result == null) { RL.Logger?.LogInformationSource($"{game.Game} could not be added. The optional verification returned null."); return(false); } installDir = result.Value; } // Make sure that the game is valid if (!await game.Game.GetManager(game.GameType).IsValidAsync(installDir, parameter)) { RL.Logger?.LogInformationSource($"{game.Game} could not be added. The game default file was not found."); return(false); } // Add the game to found games Results.Add(new GameFinderResult(game.Game, installDir, game.GameType, game.FinderItem.FoundAction, parameter)); // Remove from games to find GamesToFind.Remove(game.Game); RL.Logger?.LogInformationSource($"The game {game.Game} was found"); return(true); }
/// <summary> /// Attempts to find the specified games, returning the found games and their install locations. This method can only be called once per class instance. /// </summary> /// <returns>The found games and their install locations</returns> public async Task <IReadOnlyList <BaseFinderResult> > FindGamesAsync() { if (HasRun) { throw new Exception("The FindGames method can only be called once per instance"); } HasRun = true; try { // Split finders into groups var ubiIniGameFinders = GameFinderItems.Where(x => !FoundGames.Contains(x.Game) && x.FinderItem.UbiIniSectionName != null).ToArray(); // Search the ubi.ini file if (ubiIniGameFinders.Any() && GamesToFind.Any()) { IDictionary <string, string> iniLocations = null; RL.Logger?.LogInformationSource("The game finder has ubi.ini finder"); try { // Make sure the file exists if (CommonPaths.UbiIniPath1.FileExists) { // Get the sections and the directory for each one iniLocations = GetUbiIniData(); RL.Logger?.LogInformationSource("The ubi.ini file data was parsed for the game finder"); } } catch (Exception ex) { ex.HandleUnexpected("Reading ubi.ini file for game finder"); } // If we retrieved ini data, search it if (iniLocations != null) { await SearchIniDataAsync(iniLocations, ubiIniGameFinders); } else { RL.Logger?.LogInformationSource("The ubi.ini file data was null"); } } // Split finders into groups var regUninstallGameFinders = GameFinderItems.Where(x => !FoundGames.Contains(x.Game) && x.FinderItem.PossibleWin32Names?.Any() == true).ToList(); var regUninstallFinders = FinderItems.Where(x => !FoundFinderItems.Contains(x) && x.PossibleWin32Names?.Any() == true).ToList(); var steamGameFinders = GameFinderItems.Where(x => !FoundGames.Contains(x.Game) && x.FinderItem.SteamID != null).ToList(); // Search Registry uninstall programs if ((regUninstallGameFinders.Any() || steamGameFinders.Any() || regUninstallFinders.Any()) && GamesToFind.Any()) { RL.Logger?.LogInformationSource("The Registry uninstall programs are being searched..."); try { // Get the enumerator for installed programs var installedPrograms = EnumerateRegistryUninstallPrograms(); // Search installed programs await SearchRegistryUninstallAsync(installedPrograms, regUninstallGameFinders, steamGameFinders, regUninstallFinders); } catch (Exception ex) { ex.HandleError("Searching Registry uninstall programs for game finder"); } } // Split finders into groups var programShortcutGameFinders = GameFinderItems.Where(x => !FoundGames.Contains(x.Game) && x.FinderItem.ShortcutName != null).ToList(); var programShortcutFinders = FinderItems.Where(x => !FoundFinderItems.Contains(x) && x.ShortcutName != null).ToList(); // Search Win32 shortcuts if ((programShortcutGameFinders.Any() || programShortcutFinders.Any()) && GamesToFind.Any()) { RL.Logger?.LogInformationSource("The program shortcuts are being searched..."); try { // Get the enumerator for the shortcuts var shortcuts = EnumerateProgramShortcuts(); // Search the shortcuts await SearchWin32ShortcutsAsync(shortcuts, programShortcutGameFinders, programShortcutFinders); } catch (Exception ex) { ex.HandleUnexpected("Searching program shortcuts for game finder"); } } // Run custom game finders foreach (var game in GameFinderItems.Where(x => !FoundGames.Contains(x.Game) && x.FinderItem.CustomFinderAction != null)) { // Run the custom action and get the result var result = game.FinderItem.CustomFinderAction(); // Make sure we got a result if (result == null) { continue; } // Add the game await AddGameAsync(game, result.InstallDir, result.Parameter); } // Run custom finders foreach (var item in FinderItems.Where(x => !FoundFinderItems.Contains(x) && x.CustomFinderAction != null)) { // Run the custom action and get the result var result = item.CustomFinderAction(); // Make sure we got a result if (result == null) { continue; } // Add the game AddItem(item, result.InstallDir, result.Parameter); } RL.Logger?.LogInformationSource($"The game finder found {Results.Count} games"); // Return the found games return(Results.AsReadOnly()); } catch (Exception ex) { ex.HandleError("Game finder"); throw; } }