private void Controllers_Stopped(object sender, GameControllerEventArgs args) { var game = args.Controller.Game; logger.Info($"Game {game.Name} stopped after {args.EllapsedTime} seconds."); var dbGame = Database.Games.Get(game.Id); dbGame.IsRunning = false; dbGame.IsLaunching = false; dbGame.Playtime += args.EllapsedTime; Database.Games.Update(dbGame); controllers.RemoveController(args.Controller); gameStartups.TryRemove(game.Id, out _); if (Application.Mode == ApplicationMode.Desktop) { if (AppSettings.AfterGameClose == AfterGameCloseOptions.Restore) { Application.Restore(); } } else { Application.Restore(); } if (AppSettings.DiscordPresenceEnabled) { Application.Discord?.ClearPresence(); } if (!game.PostScript.IsNullOrWhiteSpace()) { try { var expanded = game.ExpandVariables(game.PostScript); ExecuteScriptAction(game.ActionsScriptLanguage, expanded, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { var message = exc.Message; if (exc is ScriptRuntimeException err) { message = err.Message + "\n\n" + err.ScriptStackTrace; } logger.Error(exc, "Failed to execute game's post-script action."); logger.Error(game.PostScript); Dialogs.ShowMessage( message, resources.GetString("LOCErrorGameScriptAction"), MessageBoxButton.OK, MessageBoxImage.Error); } } if (!AppSettings.PostScript.IsNullOrWhiteSpace() && game.UseGlobalPostScript) { try { var expanded = game.ExpandVariables(AppSettings.PostScript); ExecuteScriptAction(AppSettings.ActionsScriptLanguage, expanded, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { var message = exc.Message; if (exc is ScriptRuntimeException err) { message = err.Message + "\n\n" + err.ScriptStackTrace; } logger.Error(exc, "Failed to execute global post-script action."); logger.Error(AppSettings.PostScript); Dialogs.ShowMessage( message, resources.GetString("LOCErrorGlobalScriptAction"), MessageBoxButton.OK, MessageBoxImage.Error); } } if (AppSettings.ClientAutoShutdown.ShutdownClients && !game.IsCustomGame) { if (args.EllapsedTime <= AppSettings.ClientAutoShutdown.MinimalSessionTime) { logger.Debug("Game session was too short for client to be shutdown."); } else { var plugin = Extensions.GetLibraryPlugin(game.PluginId); if (plugin?.Capabilities?.CanShutdownClient == true && AppSettings.ClientAutoShutdown.ShutdownPlugins.Contains(plugin.Id)) { if (shutdownJobs.TryGetValue(game.PluginId, out var existingJob)) { existingJob.CancelToken.Cancel(); shutdownJobs.TryRemove(game.PluginId, out var _); } var newJob = new ClientShutdownJob { PluginId = plugin.Id, CancelToken = new CancellationTokenSource() }; var task = new Task(async() => { var ct = newJob.CancelToken; var libPlugin = plugin; var timeout = AppSettings.ClientAutoShutdown.GraceTimeout; var curTime = 0; logger.Info($"Scheduled {libPlugin.Name} to be closed after {timeout} seconds."); while (curTime < timeout) { if (ct.IsCancellationRequested) { logger.Debug($"Client {libPlugin.Name} shutdown canceled."); return; } await Task.Delay(1000); curTime++; } if (curTime >= timeout) { try { shutdownJobs.TryRemove(libPlugin.Id, out var _); libPlugin.Client.Shutdown(); } catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(e, $"Failed to shutdown {libPlugin.Name} client."); } } }); newJob.CancelTask = task; shutdownJobs.TryAdd(plugin.Id, newJob); newJob.CancelTask.Start(); } } } }
public void PlayGame(Game game) { if (!game.IsInstalled) { InstallGame(game); return; } logger.Info($"Starting {game.GetIdentifierInfo()}"); var dbGame = Database.Games.Get(game.Id); if (dbGame == null) { Dialogs.ShowMessage( string.Format(resources.GetString("LOCGameStartErrorNoGame"), game.Name), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); UpdateJumpList(); return; } IGameController controller = null; try { if (game.IsRunning) { logger.Warn("Failed to start the game, game is already running."); return; } if (game.PlayAction.IsHandledByPlugin) { logger.Info("Using library plugin to start the game."); controller = controllers.GetGameBasedController(game, Extensions); } else { logger.Info("Using generic controller start the game."); controller = controllers.GetGenericGameController(game); } if (controller == null) { Dialogs.ShowErrorMessage( resources.GetString("LOCErrorLibraryPluginNotFound"), resources.GetString("LOCGameError")); return; } controllers.RemoveController(game.Id); controllers.AddController(controller); UpdateGameState(game.Id, null, null, null, null, true); controller.Play(); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { if (controller != null) { controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); } logger.Error(exc, "Cannot start game: "); Dialogs.ShowMessage( string.Format(resources.GetString("LOCGameStartError"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); return; } try { UpdateJumpList(); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(exc, "Failed to set jump list data: "); } }
private void Controllers_Started(object sender, GameControllerEventArgs args) { var game = args.Controller.Game; logger.Info($"Started {game.Name} game."); UpdateGameState(game.Id, null, true, null, null, false); gameStartups.TryAdd(game.Id, DateTime.Now); if (!AppSettings.GameStartedScript.IsNullOrWhiteSpace() && game.UseGlobalGameStartedScript) { try { var expanded = game.ExpandVariables(AppSettings.GameStartedScript); ExecuteScriptAction(AppSettings.ActionsScriptLanguage, expanded, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { var message = exc.Message; if (exc is ScriptRuntimeException err) { message = err.Message + "\n\n" + err.ScriptStackTrace; } logger.Error(exc, "Failed to execute global game-started action."); logger.Error(AppSettings.GameStartedScript); Dialogs.ShowMessage( message, resources.GetString("LOCErrorGlobalScriptAction"), MessageBoxButton.OK, MessageBoxImage.Error); } } if (!game.GameStartedScript.IsNullOrWhiteSpace()) { try { var expanded = game.ExpandVariables(game.GameStartedScript); ExecuteScriptAction(game.ActionsScriptLanguage, expanded, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { var message = exc.Message; if (exc is ScriptRuntimeException err) { message = err.Message + "\n\n" + err.ScriptStackTrace; } logger.Error(exc, "Failed to execute game's game-started action."); logger.Error(game.GameStartedScript); Dialogs.ShowMessage( message, resources.GetString("LOCErrorGameScriptAction"), MessageBoxButton.OK, MessageBoxImage.Error); } } if (Application.Mode == ApplicationMode.Desktop) { if (AppSettings.AfterLaunch == AfterLaunchOptions.Close) { Application.Quit(); } else if (AppSettings.AfterLaunch == AfterLaunchOptions.Minimize) { Application.Minimize(); } } else { if (AppSettings.AfterLaunch == AfterLaunchOptions.Close) { Application.Quit(); } else { Application.Minimize(); } } if (AppSettings.DiscordPresenceEnabled) { Application.Discord?.SetPresence(game.Name); } }
public void RemoveGames(List <Game> games) { if (games.Exists(a => a.IsInstalling || a.IsRunning || a.IsLaunching || a.IsUninstalling)) { Dialogs.ShowMessage( "LOCGameRemoveRunningError", "LOCGameError", MessageBoxButton.OK, MessageBoxImage.Error); return; } var addToExclusionList = false; if (games.All(a => a.IsCustomGame)) { if (Dialogs.ShowMessage( string.Format(resources.GetString("LOCGamesRemoveAskMessage"), games.Count()), "LOCGameRemoveAskTitle", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return; } } else { var options = new List <MessageBoxOption> { new MessageBoxOption("LOCRemoveAskAddToExlusionListYesResponse"), new MessageBoxOption("LOCYesLabel", true), new MessageBoxOption("LOCNoLabel", false, true) }; var result = Dialogs.ShowMessage( string.Format(resources.GetString("LOCGamesRemoveAskMessageIgnoreOption"), games.Count()), "LOCGameRemoveAskTitle", MessageBoxImage.Question, options); if (result == options[0]) { addToExclusionList = true; } else if (result == options[2]) { return; } } foreach (var game in games.ToList()) { if (Database.Games[game.Id] == null) { logger.Warn($"Failed to remove game {game.Name} {game.Id}, game doesn't exists anymore."); games.Remove(game); } if (addToExclusionList && !game.IsCustomGame) { AppSettings.ImportExclusionList.Add(game.GameId, game.Name, game.PluginId, Extensions.GetLibraryPlugin(game.PluginId)?.Name); } } Database.Games.Remove(games); }
public void PlayGame(Game game) { if (!game.IsInstalled) { InstallGame(game); return; } logger.Info($"Starting {game.GetIdentifierInfo()}"); var dbGame = Database.Games.Get(game.Id); if (dbGame == null) { Dialogs.ShowMessage( string.Format(resources.GetString("LOCGameStartErrorNoGame"), game.Name), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); UpdateJumpList(); return; } IGameController controller = null; try { if (game.IsRunning || game.IsLaunching) { logger.Warn("Failed to start the game, game is already running/launching."); return; } if (game.PlayAction == null) { Dialogs.ShowErrorMessage( resources.GetString("LOCErrorNoPlayAction"), resources.GetString("LOCGameError")); return; } if (game.PlayAction.IsHandledByPlugin) { logger.Info("Using library plugin to start the game."); controller = controllers.GetGameBasedController(game, Extensions); } else { logger.Info("Using generic controller start the game."); controller = controllers.GetGenericGameController(game); } if (controller == null) { Dialogs.ShowErrorMessage( resources.GetString("LOCErrorLibraryPluginNotFound"), resources.GetString("LOCGameError")); return; } controllers.RemoveController(game.Id); controllers.AddController(controller); UpdateGameState(game.Id, null, null, null, null, true); if (!game.IsCustomGame && shutdownJobs.TryGetValue(game.PluginId, out var existingJob)) { logger.Debug($"Starting game with existing client shutdown job, canceling job {game.PluginId}."); existingJob.CancelToken.Cancel(); shutdownJobs.TryRemove(game.PluginId, out var _); } if (!AppSettings.PreScript.IsNullOrWhiteSpace() && game.UseGlobalPreScript) { try { var expanded = game.ExpandVariables(AppSettings.PreScript); ExecuteScriptAction(AppSettings.ActionsScriptLanguage, expanded, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { var message = exc.Message; if (exc is ScriptRuntimeException err) { message = err.Message + "\n\n" + err.ScriptStackTrace; } logger.Error(exc, "Failed to execute global pre-script action."); logger.Error(AppSettings.PreScript); Dialogs.ShowMessage( message, resources.GetString("LOCErrorGlobalScriptAction"), MessageBoxButton.OK, MessageBoxImage.Error); controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); return; } } if (!game.PreScript.IsNullOrWhiteSpace()) { try { var expanded = game.ExpandVariables(game.PreScript); ExecuteScriptAction(game.ActionsScriptLanguage, expanded, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { var message = exc.Message; if (exc is ScriptRuntimeException err) { message = err.Message + "\n\n" + err.ScriptStackTrace; } logger.Error(exc, "Failed to execute game's pre-script action."); logger.Error(game.PreScript); Dialogs.ShowMessage( message, resources.GetString("LOCErrorGameScriptAction"), MessageBoxButton.OK, MessageBoxImage.Error); controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); return; } } controller.Play(); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(exc, "Cannot start game: "); Dialogs.ShowMessage( string.Format(resources.GetString("LOCGameStartError"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); if (controller != null) { controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); } return; } UpdateJumpList(); }
public void PlayGame(Game game) { if (!game.IsInstalled) { InstallGame(game); return; } logger.Info($"Starting {game.GetIdentifierInfo()}"); var dbGame = Database.Games.Get(game.Id); if (dbGame == null) { Dialogs.ShowMessage( string.Format(resources.GetString("LOCGameStartErrorNoGame"), game.Name), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); UpdateJumpList(); return; } IGameController controller = null; try { if (game.IsRunning || game.IsLaunching) { logger.Warn("Failed to start the game, game is already running/launching."); return; } if (game.PlayAction == null) { Dialogs.ShowErrorMessage( resources.GetString("LOCErrorNoPlayAction"), resources.GetString("LOCGameError")); return; } if (game.PlayAction.IsHandledByPlugin) { logger.Info("Using library plugin to start the game."); controller = controllers.GetGameBasedController(game, Extensions); } else { logger.Info("Using generic controller start the game."); controller = controllers.GetGenericGameController(game); } if (controller == null) { Dialogs.ShowErrorMessage( resources.GetString("LOCErrorLibraryPluginNotFound"), resources.GetString("LOCGameError")); return; } controllers.RemoveController(game.Id); controllers.AddController(controller); UpdateGameState(game.Id, null, null, null, null, true); if (!AppSettings.PreScript.IsNullOrWhiteSpace()) { try { ExecuteScriptAction(AppSettings.ActionsScriptLanguage, AppSettings.PreScript, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(exc, "Failed to execute global pre-script action."); logger.Error(AppSettings.PreScript); Dialogs.ShowMessage( string.Format(resources.GetString("LOCErrorGlobalScriptAction"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); return; } } if (!game.PreScript.IsNullOrWhiteSpace()) { try { ExecuteScriptAction(game.ActionsScriptLanguage, game.PreScript, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(exc, "Failed to execute game's pre-script action."); logger.Error(game.PreScript); Dialogs.ShowMessage( string.Format(resources.GetString("LOCErrorGameScriptAction"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); return; } } controller.Play(); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { if (controller != null) { controllers.RemoveController(game.Id); UpdateGameState(game.Id, null, null, null, null, false); } logger.Error(exc, "Cannot start game: "); Dialogs.ShowMessage( string.Format(resources.GetString("LOCGameStartError"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); return; } UpdateJumpList(); }
private void Controllers_Stopped(object sender, GameControllerEventArgs args) { var game = args.Controller.Game; logger.Info($"Game {game.Name} stopped after {args.EllapsedTime} seconds."); var dbGame = Database.Games.Get(game.Id); dbGame.IsRunning = false; dbGame.IsLaunching = false; dbGame.Playtime += args.EllapsedTime; Database.Games.Update(dbGame); controllers.RemoveController(args.Controller); if (Application.Mode == ApplicationMode.Desktop) { if (AppSettings.AfterGameClose == AfterGameCloseOptions.Restore) { Application.Restore(); } } else { Application.Restore(); } if (!game.PostScript.IsNullOrWhiteSpace()) { try { ExecuteScriptAction(game.ActionsScriptLanguage, game.PostScript, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(exc, "Failed to execute game's post-script action."); logger.Error(game.PostScript); Dialogs.ShowMessage( string.Format(resources.GetString("LOCErrorGameScriptAction"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); } } if (!AppSettings.PostScript.IsNullOrWhiteSpace()) { try { ExecuteScriptAction(AppSettings.ActionsScriptLanguage, AppSettings.PostScript, game); } catch (Exception exc) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(exc, "Failed to execute global post-script action."); logger.Error(AppSettings.PostScript); Dialogs.ShowMessage( string.Format(resources.GetString("LOCErrorGlobalScriptAction"), exc.Message), resources.GetString("LOCGameError"), MessageBoxButton.OK, MessageBoxImage.Error); } } }