From 864904ee03bacc5cbe847a3b885fab1ef9f9cdb7 Mon Sep 17 00:00:00 2001 From: Paul Hebble Date: Fri, 22 Mar 2024 16:52:55 -0500 Subject: [PATCH] Play game option for ConsoleUI --- ConsoleUI/ModListScreen.cs | 30 ++++++++++++++++ ConsoleUI/Properties/Resources.resx | 2 ++ ConsoleUI/Toolkit/ConsolePopupMenu.cs | 15 +++++--- ConsoleUI/Toolkit/Keys.cs | 7 ++++ Core/GameInstance.cs | 40 +++++++++++++++++++++ Core/Properties/Resources.fr-FR.resx | 5 ++- Core/Properties/Resources.it-IT.resx | 3 ++ Core/Properties/Resources.pl-PL.resx | 3 ++ Core/Properties/Resources.resx | 3 ++ Core/Properties/Resources.ru-RU.resx | 3 ++ Core/Properties/Resources.zh-CN.resx | 3 ++ GUI/Main/Main.cs | 50 ++------------------------- GUI/Properties/Resources.de-DE.resx | 5 --- GUI/Properties/Resources.fr-FR.resx | 5 --- GUI/Properties/Resources.it-IT.resx | 5 --- GUI/Properties/Resources.ja-JP.resx | 3 -- GUI/Properties/Resources.ko-KR.resx | 3 -- GUI/Properties/Resources.pl-PL.resx | 5 --- GUI/Properties/Resources.pt-BR.resx | 3 -- GUI/Properties/Resources.resx | 3 -- GUI/Properties/Resources.ru-RU.resx | 3 -- GUI/Properties/Resources.zh-CN.resx | 3 -- 22 files changed, 112 insertions(+), 90 deletions(-) diff --git a/ConsoleUI/ModListScreen.cs b/ConsoleUI/ModListScreen.cs index 2a2700aa30..cb85d56f1a 100644 --- a/ConsoleUI/ModListScreen.cs +++ b/ConsoleUI/ModListScreen.cs @@ -147,6 +147,7 @@ public ModListScreen(GameInstanceManager mgr, RepositoryDataManager repoData, Re AddObject(searchBox); AddObject(moduleList); + AddBinding(Keys.CtrlP, (object sender, ConsoleTheme theme) => PlayGame()); AddBinding(Keys.CtrlQ, (object sender, ConsoleTheme theme) => false); AddBinding(Keys.AltX, (object sender, ConsoleTheme theme) => false); AddBinding(Keys.F1, (object sender, ConsoleTheme theme) => Help(theme)); @@ -279,6 +280,22 @@ public ModListScreen(GameInstanceManager mgr, RepositoryDataManager repoData, Re )); List opts = new List() { + new ConsoleMenuOption(Properties.Resources.ModListPlayMenu, "", + Properties.Resources.ModListPlayMenuTip, + true, null, null, null, true, + () => new ConsolePopupMenu( + manager.CurrentInstance + .game + .DefaultCommandLines(manager.SteamLibrary, + new DirectoryInfo(manager.CurrentInstance.GameDir())) + .Select((cmd, i) => new ConsoleMenuOption( + cmd, + i == 0 ? $"{Properties.Resources.Ctrl}+P" + : "", + cmd, true, + th => PlayGame(cmd))) + .ToList())), + null, new ConsoleMenuOption(Properties.Resources.ModListSortMenu, "", Properties.Resources.ModListSortMenuTip, true, null, null, moduleList.SortMenu()), @@ -432,6 +449,19 @@ private int daysSinceUpdated(string filename) return (DateTime.Now - File.GetLastWriteTime(filename)).Days; } + private bool PlayGame() + => PlayGame(manager.CurrentInstance + .game + .DefaultCommandLines(manager.SteamLibrary, + new DirectoryInfo(manager.CurrentInstance.GameDir())) + .FirstOrDefault()); + + private bool PlayGame(string commandLine) + { + manager.CurrentInstance.PlayGame(commandLine); + return true; + } + private bool UpdateRegistry(ConsoleTheme theme, bool showNewModsPrompt = true) { ProgressScreen ps = new ProgressScreen( diff --git a/ConsoleUI/Properties/Resources.resx b/ConsoleUI/Properties/Resources.resx index 548629d549..6e62455557 100644 --- a/ConsoleUI/Properties/Resources.resx +++ b/ConsoleUI/Properties/Resources.resx @@ -319,6 +319,8 @@ If you uninstall it, CKAN will not be able to re-install it. Apply changes Updated at least {0} day ago Updated at least {0} days ago + Play game + Launch the game Sort... Change the sorting of the list of mods Refresh mod list diff --git a/ConsoleUI/Toolkit/ConsolePopupMenu.cs b/ConsoleUI/Toolkit/ConsolePopupMenu.cs index 3d8026d91e..effd81888e 100644 --- a/ConsoleUI/Toolkit/ConsolePopupMenu.cs +++ b/ConsoleUI/Toolkit/ConsolePopupMenu.cs @@ -21,7 +21,7 @@ public ConsolePopupMenu(List opts) int len = opt.Caption.Length + ( string.IsNullOrEmpty(opt.Key) ? 0 : 2 + opt.Key.Length ) + ( - opt.SubMenu != null ? 3 : + opt.SubMenu != null || opt.SubMenuFunc != null ? 3 : opt.RadioActive != null ? 4 : 0 ); @@ -66,7 +66,8 @@ public bool Run(ConsoleTheme theme, int right, int top) if (options[selectedOption].OnExec != null) { val = options[selectedOption].OnExec(theme); } - options[selectedOption].SubMenu?.Run( + (options[selectedOption].SubMenu ?? (options[selectedOption].SubMenuFunc?.Invoke())) + ?.Run( theme, right - 2, top + selectedOption + 2); @@ -153,7 +154,7 @@ private void DrawFooter(ConsoleTheme theme) } private string AnnotatedCaption(ConsoleMenuOption opt) - => opt.SubMenu != null + => opt.SubMenu != null || opt.SubMenuFunc != null ? opt.Caption.PadRight(longestLength - 1) + submenuIndicator : opt.RadioActive != null ? opt.RadioActive() @@ -184,9 +185,10 @@ public class ConsoleMenuOption { /// If set, this option is a radio button, and this function returns its value /// Submenu to open for this option /// true if this option should be drawn normally and allowed for selection, false to draw it grayed out and not allow selection + /// Function to generate submenu to open for this option public ConsoleMenuOption(string cap, string key, string tt, bool close, Func exec = null, Func radio = null, ConsolePopupMenu submenu = null, - bool enabled = true) + bool enabled = true, Func submenuFunc = null) { Caption = cap; Key = key; @@ -196,6 +198,7 @@ public ConsoleMenuOption(string cap, string key, string tt, bool close, SubMenu = submenu; RadioActive = radio; Enabled = enabled; + SubMenuFunc = submenuFunc; } /// @@ -227,6 +230,10 @@ public ConsoleMenuOption(string cap, string key, string tt, bool close, /// public readonly ConsolePopupMenu SubMenu; /// + /// Function to generate submenu to open for this option + /// + public readonly Func SubMenuFunc; + /// /// Function to call to check whether this option is enabled /// public readonly bool Enabled; diff --git a/ConsoleUI/Toolkit/Keys.cs b/ConsoleUI/Toolkit/Keys.cs index 51976202a6..bd5378fe4b 100644 --- a/ConsoleUI/Toolkit/Keys.cs +++ b/ConsoleUI/Toolkit/Keys.cs @@ -176,6 +176,13 @@ public static class Keys { (char)12, ConsoleKey.Clear, false, false, false ); + /// + /// Representation of Ctrl+P for key bindings + /// + public static readonly ConsoleKeyInfo CtrlP = new ConsoleKeyInfo( + (char)16, ConsoleKey.P, false, false, true + ); + /// /// Representation of Ctrl+Q for key bindings /// diff --git a/Core/GameInstance.cs b/Core/GameInstance.cs index 14ef203ed0..a99e3b67ee 100644 --- a/Core/GameInstance.cs +++ b/Core/GameInstance.cs @@ -371,6 +371,46 @@ public bool HasManagedFiles(Registry registry, string absPath) && Directory.EnumerateFileSystemEntries(absPath, "*", SearchOption.AllDirectories) .Any(f => registry.FileOwner(ToRelativeGameDir(f)) != null)); + public void PlayGame(string command, Action onExit = null) + { + var split = (command ?? "").Split(' '); + if (split.Length == 0) + { + return; + } + + split = game.AdjustCommandLine(split, Version()); + var binary = split[0]; + var args = string.Join(" ", split.Skip(1)); + + try + { + Directory.SetCurrentDirectory(GameDir()); + Process p = new Process() + { + StartInfo = new ProcessStartInfo() + { + FileName = binary, + Arguments = args + }, + EnableRaisingEvents = true + }; + + p.Exited += (sender, e) => + { + playTime.Stop(CkanDir()); + onExit?.Invoke(); + }; + + p.Start(); + playTime.Start(); + } + catch (Exception exception) + { + User.RaiseError(Properties.Resources.GameInstancePlayGameFailed, exception.Message); + } + } + public override string ToString() => string.Format(Properties.Resources.GameInstanceToString, game.ShortName, gameDir); diff --git a/Core/Properties/Resources.fr-FR.resx b/Core/Properties/Resources.fr-FR.resx index 2bca7f6e5b..af0db3aade 100644 --- a/Core/Properties/Resources.fr-FR.resx +++ b/Core/Properties/Resources.fr-FR.resx @@ -393,6 +393,9 @@ Installez le paquet `mono-complete` ou un équivalent pour votre système d'expl {0} n'existe pas + Impossible de lancer le jeu. + +{0} Téléchargement de {0} ... @@ -582,7 +585,7 @@ Pensez à ajouter un jeton d'authentification pour augmenter la limite avant bri Fichier verrou avec un ID de processus actif à {0} -Un autre processus CKAN est probablement déjà en train d'accéder à ce dossier de jeu. Si vous êtes sûr que ce fichier verrou est périmé, vous pouvez supprimer ce fichier pour continuer. Mais si ce n'est pas le cas, les deux CKAN risque de rentrer en conflit et corrompre votre registre de mods et votre dossier de jeu. +Un autre processus CKAN est probablement déjà en train d'accéder à ce dossier de jeu. Si vous êtes sûr que ce fichier verrou est périmé, vous pouvez supprimer ce fichier pour continuer. Mais si ce n'est pas le cas, les deux CKAN risque de rentrer en conflit et corrompre votre registre de mods et votre dossier de jeu. Voulez-vous supprimez ce fichier verrou pour forcer l'accès ? diff --git a/Core/Properties/Resources.it-IT.resx b/Core/Properties/Resources.it-IT.resx index 8bce7fcc45..6af7fed69c 100644 --- a/Core/Properties/Resources.it-IT.resx +++ b/Core/Properties/Resources.it-IT.resx @@ -390,6 +390,9 @@ Installa il pacchetto `mono-complete` o un pacchetto equivalente per il tuo sist {0} non esiste + Impossibile avviare il gioco. + +{0} Download di "{0}" diff --git a/Core/Properties/Resources.pl-PL.resx b/Core/Properties/Resources.pl-PL.resx index acf3f82d2f..7021335d12 100644 --- a/Core/Properties/Resources.pl-PL.resx +++ b/Core/Properties/Resources.pl-PL.resx @@ -380,6 +380,9 @@ Zainstaluj pakiet `mono-complete` lub pasujący do twojego systemu operacyjnego. {0} nie istnieje + Nie można uruchomić gry. + +{0} Pobieranie "{0}" diff --git a/Core/Properties/Resources.resx b/Core/Properties/Resources.resx index 846a619157..46a42c6bbe 100644 --- a/Core/Properties/Resources.resx +++ b/Core/Properties/Resources.resx @@ -210,6 +210,9 @@ Install the `mono-complete` package or equivalent for your operating system.Could not return a valid name for the new instance custom {0} does not exist + Couldn't start game. + +{0} Downloading {0} ... Nothing to install About to install: diff --git a/Core/Properties/Resources.ru-RU.resx b/Core/Properties/Resources.ru-RU.resx index ffee56b450..268c85b6a3 100644 --- a/Core/Properties/Resources.ru-RU.resx +++ b/Core/Properties/Resources.ru-RU.resx @@ -204,6 +204,9 @@ Не удалось вернуть корректное имя для новой сборки своя {0} не существует + Не удалось запустить игру. + +{0} Загружается «{0}» Нечего устанавливать Будут установлены: diff --git a/Core/Properties/Resources.zh-CN.resx b/Core/Properties/Resources.zh-CN.resx index 86c2e5321b..2176039dc7 100644 --- a/Core/Properties/Resources.zh-CN.resx +++ b/Core/Properties/Resources.zh-CN.resx @@ -393,6 +393,9 @@ {0} 不存在 + 无法启动游戏. + +{0} 正在下载 "{0}" diff --git a/GUI/Main/Main.cs b/GUI/Main/Main.cs index 54b7f2ca40..71edf32dee 100644 --- a/GUI/Main/Main.cs +++ b/GUI/Main/Main.cs @@ -979,25 +979,14 @@ private void openGameToolStripMenuItem_Click(object sender, EventArgs e) private void LaunchGame(string command = null) { - if (string.IsNullOrEmpty(command)) - { - command = configuration.CommandLines.First(); - } - var split = command.Split(' '); - if (split.Length == 0) - { - return; - } - var registry = RegistryManager.Instance(CurrentInstance, repoData).registry; - var suppressedIdentifiers = CurrentInstance.GetSuppressedCompatWarningIdentifiers; var incomp = registry.IncompatibleInstalled(CurrentInstance.VersionCriteria()) .Where(m => !m.Module.IsDLC && !suppressedIdentifiers.Contains(m.identifier)) .ToList(); if (incomp.Any()) { - // Warn that it might not be safe to run Game with incompatible modules installed + // Warn that it might not be safe to run game with incompatible modules installed string incompatDescrip = incomp .Select(m => $"{m.Module} ({m.Module.CompatibleGameVersions(CurrentInstance.game)})") .Aggregate((a, b) => $"{a}{Environment.NewLine}{b}"); @@ -1022,41 +1011,8 @@ private void LaunchGame(string command = null) } } - split = CurrentInstance.game.AdjustCommandLine(split, CurrentInstance.Version()); - var binary = split[0]; - var args = string.Join(" ", split.Skip(1)); - - try - { - - Directory.SetCurrentDirectory(CurrentInstance.GameDir()); - - Process p = new Process() - { - StartInfo = new ProcessStartInfo() - { - FileName = binary, - Arguments = args - }, - EnableRaisingEvents = true - }; - - GameInstance inst = CurrentInstance; - p.Exited += (sender, e) => GameExit(inst); - - p.Start(); - CurrentInstance.playTime.Start(); - } - catch (Exception exception) - { - currentUser.RaiseError(Properties.Resources.MainLaunchFailed, exception.Message); - } - } - - private void GameExit(GameInstance inst) - { - inst.playTime.Stop(inst.CkanDir()); - UpdateStatusBar(); + CurrentInstance.PlayGame(command ?? configuration.CommandLines.First(), + UpdateStatusBar); } // This is used by Reinstall diff --git a/GUI/Properties/Resources.de-DE.resx b/GUI/Properties/Resources.de-DE.resx index f0b8388dd8..c431083ee7 100644 --- a/GUI/Properties/Resources.de-DE.resx +++ b/GUI/Properties/Resources.de-DE.resx @@ -171,11 +171,6 @@ Versuche {2} aus {3} zu verschieben und CKAN neu zu starten. Starten Für diese Mods und {0} {1} nicht mehr anzeigen - - Das Spiel konnte nicht gestartet werden. - -{0} - CKAN Modpack (*.ckan) Klartext (*.txt) Nicht gefunden. diff --git a/GUI/Properties/Resources.fr-FR.resx b/GUI/Properties/Resources.fr-FR.resx index c52b049759..4fc12893ba 100644 --- a/GUI/Properties/Resources.fr-FR.resx +++ b/GUI/Properties/Resources.fr-FR.resx @@ -285,11 +285,6 @@ Quelle version souhaitez-vous utiliser ? Lancement - - Impossible de lancer le jeu. - -{0} - Modpack CKAN (*.ckan) diff --git a/GUI/Properties/Resources.it-IT.resx b/GUI/Properties/Resources.it-IT.resx index 9e994f6320..bce1450282 100644 --- a/GUI/Properties/Resources.it-IT.resx +++ b/GUI/Properties/Resources.it-IT.resx @@ -271,11 +271,6 @@ Prova a spostare {2} da {3} e a riavviare CKAN. Avvia - - Impossibile avviare il gioco. - -{0} - Modpack CKAN (*.ckan) diff --git a/GUI/Properties/Resources.ja-JP.resx b/GUI/Properties/Resources.ja-JP.resx index b74ddd79ec..4bdafdb381 100644 --- a/GUI/Properties/Resources.ja-JP.resx +++ b/GUI/Properties/Resources.ja-JP.resx @@ -170,9 +170,6 @@ Try to move {2} out of {3} and restart CKAN. {0} 起動 - 起動に失敗しました。 - -{0} CKAN Modパック (*.ckan) 平文 (*.txt) Markdown (*.md) diff --git a/GUI/Properties/Resources.ko-KR.resx b/GUI/Properties/Resources.ko-KR.resx index 6577a27a7a..93373400a2 100644 --- a/GUI/Properties/Resources.ko-KR.resx +++ b/GUI/Properties/Resources.ko-KR.resx @@ -171,9 +171,6 @@ {0} 이 모드들에 관해서는 다시 보여주지 않기 {0} {1} 실행 - 게임을 실행할 수 없었어요. - -{0} CKAN 모드팩 (*.ckan) 일반 텍스트(*.txt) 마크다운 (*.md) diff --git a/GUI/Properties/Resources.pl-PL.resx b/GUI/Properties/Resources.pl-PL.resx index e4f5537238..2db8273492 100644 --- a/GUI/Properties/Resources.pl-PL.resx +++ b/GUI/Properties/Resources.pl-PL.resx @@ -271,11 +271,6 @@ Spróbuj przenieść {2} z {3} i uruchomić ponownie CKAN. Uruchom - - Nie można uruchomić gry. - -{0} - CKAN modpack (*.ckan) diff --git a/GUI/Properties/Resources.pt-BR.resx b/GUI/Properties/Resources.pt-BR.resx index 093448fa37..001fbe2e7b 100644 --- a/GUI/Properties/Resources.pt-BR.resx +++ b/GUI/Properties/Resources.pt-BR.resx @@ -168,9 +168,6 @@ Tentando mover {2} de {3} e reiniciar o CKAN. {0} Inicializar - Não é possivel inicializar o jogo. - -{0} Lista de mods do CKAN (*.ckan) Texto plano (*.txt) Markdown (*.md) diff --git a/GUI/Properties/Resources.resx b/GUI/Properties/Resources.resx index 308d301e84..d502b0bb41 100644 --- a/GUI/Properties/Resources.resx +++ b/GUI/Properties/Resources.resx @@ -180,9 +180,6 @@ Which build would you like to use? {0} Don't show this again for these mods on {0} {1} Launch - Couldn't start game. - -{0} CKAN modpack (*.ckan) Plain text (*.txt) Markdown (*.md) diff --git a/GUI/Properties/Resources.ru-RU.resx b/GUI/Properties/Resources.ru-RU.resx index 534fc6609f..878aba48aa 100644 --- a/GUI/Properties/Resources.ru-RU.resx +++ b/GUI/Properties/Resources.ru-RU.resx @@ -168,9 +168,6 @@ {0} Запустить - Не удалось запустить игру. - -{0} Пакет модификаций CKAN (*.ckan) Текст (*.txt) Markdown (*.md) diff --git a/GUI/Properties/Resources.zh-CN.resx b/GUI/Properties/Resources.zh-CN.resx index d4fbd7aacf..3f1ee1a91b 100644 --- a/GUI/Properties/Resources.zh-CN.resx +++ b/GUI/Properties/Resources.zh-CN.resx @@ -169,9 +169,6 @@ {0} 启动 - 无法启动游戏. - -{0} CKAN modpack (*.ckan) Plain text (*.txt) Markdown (*.md)