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(); } }
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 { // The delay should hopefully fix rare cases where Fullscreen mode doesn't get proper focus after restore. // https://www.reddit.com/r/playnite/comments/f6d73l/bug_full_screen_ui_wont_respond_to_left_stick/ Task.Delay(TimeSpan.FromSeconds(2)).ContinueWith(a => Application.Restore()); } 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()) { 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(); } } } }
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); } } }