using LANCommander.Launcher.Data; using LANCommander.Launcher.Data.Models; using LANCommander.Launcher.Models; using LANCommander.SDK; using LANCommander.SDK.Extensions; using LANCommander.SDK.Helpers; using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using System.Diagnostics; namespace LANCommander.Launcher.Services { public class GameService : BaseDatabaseService { private readonly AuthenticationService AuthenticationService; private readonly PlaySessionService PlaySessionService; private readonly IServiceProvider ServiceProvider; private readonly SaveService SaveService; private readonly MessageBusService MessageBusService; public Dictionary RunningProcesses = new Dictionary(); private Settings Settings { get; set; } public delegate Task OnUninstallCompleteHandler(Game game); public event OnUninstallCompleteHandler OnUninstallComplete; public delegate Task OnUninstallHandler(Game game); public event OnUninstallHandler OnUninstall; public GameService( DatabaseContext dbContext, SDK.Client client, ILogger logger, AuthenticationService authenticationService, PlaySessionService playSessionService, IServiceProvider serviceProvider, SaveService saveService, MessageBusService messageBusService) : base(dbContext, client, logger) { Settings = SettingService.GetSettings(); AuthenticationService = authenticationService; PlaySessionService = playSessionService; ServiceProvider = serviceProvider; SaveService = saveService; MessageBusService = messageBusService; } public async Task UninstallAsync(Game game) { using (var operation = Logger.BeginOperation("Uninstalling game {GameTitle} ({GameId})", game.Title, game.Id)) { try { OnUninstall?.Invoke(game); await Client.Games.UninstallAsync(game.InstallDirectory, game.Id); if (game.BaseGameId.HasValue) { var libraryService = ServiceProvider.GetService(); var isInstalled = await libraryService!.IsInstalledAsync(game.BaseGameId.Value); if (!isInstalled) { var baseGame = await GetAsync(game.BaseGameId.Value); await Client.Games.UninstallAsync(game.InstallDirectory, baseGame?.Id ?? game.BaseGameId.Value); ClearGameState(baseGame!, skipAddons: true); } } ClearGameState(game); await UpdateAsync(game); OnUninstallComplete?.Invoke(game); operation.Complete(); } catch (Exception ex) { Logger?.LogError(ex, "Game {GameTitle} ({GameId}) could not be uninstalled", game.Title, game.Id); } } } public async Task Run(Game game, SDK.Models.Action action) { Guid userId; if (Client.IsConnected()) { var profile = await Client.Profile.GetAsync(); userId = profile.Id; } else { userId = AuthenticationService.GetUserId(); } try { var latestSession = await PlaySessionService.GetLatestSession(game.Id, userId); await PlaySessionService.StartSession(game.Id, userId); await Client.Games.RunAsync(game.InstallDirectory, game.Id, action, latestSession?.CreatedOn); } catch (Exception ex) { Logger?.LogError(ex, "Game failed to run"); } finally { await PlaySessionService.EndSession(game.Id, userId); } } protected void ClearGameState(Game game, bool skipAddons = false) { if (game == null) return; game.InstallDirectory = null; game.Installed = false; game.InstalledOn = null; game.InstalledVersion = null; if (!skipAddons) { foreach (var addon in (game.DependentGames ?? [])) { ClearGameState(addon); } } } } }