using System; using System.Collections.Generic; using System.Linq; using GameFinder.StoreHandlers.EGS; using GameFinder.StoreHandlers.GOG; using GameFinder.StoreHandlers.Origin; using GameFinder.StoreHandlers.Steam; using Microsoft.Extensions.Logging; using Wabbajack.DTOs; using Wabbajack.Paths; namespace Wabbajack.Installer { public class GameLocator : IGameLocator { private readonly Dictionary _locationCache; private readonly ILogger _logger; private readonly SteamHandler _steam; private readonly OriginHandler? _origin; private readonly GOGHandler _gog; private readonly EGSHandler _egs; public GameLocator(ILogger logger) { _logger = logger; _steam = new SteamHandler(logger); if (OperatingSystem.IsWindows()) { _origin = new OriginHandler(true, false, logger); } _gog = new GOGHandler(logger); _egs = new EGSHandler(logger); _locationCache = new Dictionary(); _steam.FindAllGames(); _origin?.FindAllGames(); _gog.FindAllGames(); _egs.FindAllGames(); } public AbsolutePath GameLocation(Game game) { if (TryFindLocation(game, out var path)) return path; throw new Exception($"Can't find game {game}"); } public bool IsInstalled(Game game) { return TryFindLocation(game, out _); } public bool TryFindLocation(Game game, out AbsolutePath path) { lock (_locationCache) { if (_locationCache.TryGetValue(game, out path)) return true; if (TryFindLocationInner(game, out path)) { _locationCache.Add(game, path); return true; } } return false; } private bool TryFindLocationInner(Game game, out AbsolutePath path) { var metaData = game.MetaData(); foreach (var steamGame in _steam.Games.Where(steamGame => metaData.SteamIDs.Contains(steamGame.ID))) { path = steamGame!.Path.ToAbsolutePath(); return true; } foreach (var gogGame in _gog.Games.Where(gogGame => metaData.GOGIDs.Contains(gogGame.GameID))) { path = gogGame!.Path.ToAbsolutePath(); return true; } foreach (var egsGame in _egs.Games.Where(egsGame => metaData.EpicGameStoreIDs.Contains(egsGame.CatalogItemId))) { path = egsGame!.Path.ToAbsolutePath(); return true; } if (_origin != null) { foreach (var originGame in _origin.Games.Where(originGame => metaData.EpicGameStoreIDs.Contains(originGame.Id))) { path = originGame.Path.ToAbsolutePath(); return true; } } path = default; return false; } } }