From ae60c43cfe6e108475314247af9109cfa82104ee Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 21 Feb 2022 01:15:18 +0100 Subject: [PATCH] Add warning on close, display whether online mode can be used --- TBMM/MainForm.Designer.cs | 2 + TBMM/MainForm.cs | 20 +++++++- TBMM/MainPatcher.cs | 96 +++++++++++++++++++++------------------ TBMM/MainUtils.cs | 2 +- TBMM/TBMM.csproj | 2 +- 5 files changed, 73 insertions(+), 49 deletions(-) diff --git a/TBMM/MainForm.Designer.cs b/TBMM/MainForm.Designer.cs index 0482305..dfb7b74 100644 --- a/TBMM/MainForm.Designer.cs +++ b/TBMM/MainForm.Designer.cs @@ -228,6 +228,8 @@ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "MainForm"; this.Text = "Techblox Mod Manager"; + this.Activated += new System.EventHandler(this.MainForm_Activated); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); this.Load += new System.EventHandler(this.Form1_Load); this.Shown += new System.EventHandler(this.MainForm_Shown); this.ResumeLayout(false); diff --git a/TBMM/MainForm.cs b/TBMM/MainForm.cs index 0913257..dc0e44f 100644 --- a/TBMM/MainForm.cs +++ b/TBMM/MainForm.cs @@ -19,7 +19,7 @@ namespace TBMM resources = new ResourceManager("TBMM.Localization", Assembly.GetExecutingAssembly()); Configuration = Configuration.Load(); } - + public Configuration Configuration { get; } private readonly ResourceManager resources; @@ -215,7 +215,7 @@ You may also want to verify the game's files in the launcher. private async Task RefreshEverything(bool evenMods) { - if (CheckIfPatched() == GameState.Patched) //Set from placeholder + if (CheckIfPatched() == GameState.Patched) //Set from placeholder & unpatch if game was patched HandleGameExit(null, EventArgs.Empty); lastGameUpdateTime = GetGameVersionAsDate(); var mods = GetInstalledMods(); @@ -229,5 +229,21 @@ You may also want to verify the game's files in the launcher. { Focus(); } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + if (e.Cancel) return; + if (CheckIfPatched() != GameState.InGame) return; + if (MessageBox.Show("The game is still running. The mod manager needs to be running until the game closes to restore the game files." + + " If you proceed you won't be able to play online until you start the mod manager again.\n\n" + + "Are you sure you want TBMM to exit before the game does?", "Game still running", + MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.No) + e.Cancel = true; + } + + private void MainForm_Activated(object sender, EventArgs e) + { + CheckIfPatched(); + } } } diff --git a/TBMM/MainPatcher.cs b/TBMM/MainPatcher.cs index 707da33..f858382 100644 --- a/TBMM/MainPatcher.cs +++ b/TBMM/MainPatcher.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO.Compression; using System.IO; @@ -13,67 +14,72 @@ namespace TBMM { public GameState CheckIfPatched() { - if (GetExe() == null) + Dictionary statusTexts = new() { - status.Text = "Status: Game not found"; - return GameState.NotFound; + { GameState.NotFound, ("Game not found", "Specify the game's location in settings", "") }, + { GameState.InGame, ("Game is running", "", "In-game") }, + { GameState.NoPatcher, ("Patcher missing", "Clicking Play will install it", "") }, + { GameState.OldPatcher, ("Patcher outdated", "nClicking play will update it", "") }, + { GameState.Unpatched, ("Unpatched", "", "") }, + { GameState.Patched, ("Patched", "", "")} + }; + void SetStatusText(GameState state, bool patched) + { + var (statusText, extra, play) = statusTexts[state]; + if (extra.Length == 0) extra = patched ? "Cannot join online mode" : "Online mode available"; + if (play.Length == 0) play = "Play modded"; + status.Text = $"Status: {statusText}\n{extra}"; + playbtn.Text = play; } - string pnp = "Play modded"; - if (!File.Exists(GamePath(@"\IPA.exe"))) + if (GetExe() == null) { - status.Text = "Status: Patcher missing\nClicking Play will install it"; - playbtn.Text = pnp; - return GameState.NoPatcher; + SetStatusText(GameState.NotFound, false); + return GameState.NotFound; } - if (CheckIfGameIsRunning()) + bool gameIsRunning = CheckIfGameIsRunning(); + if (gameIsRunning) { - status.Text = "Status: Game is running"; - playbtn.Text = "In-game"; UpdateButton(playbtn, false); //Don't allow (un)installing mods if game is running UpdateButton(installbtn, false); UpdateButton(uninstallbtn, false); modlist.Enabled = false; - return GameState.InGame; } - - if (!working) UpdateButton(playbtn, true); - modlist.Enabled = true; - if (gcipa.Updatable && !(gcipa.Version == new Version(1, 0, 0, 0) && gcipa.LatestVersion == new Version(4, 0, 0, 0))) + else { - status.Text = "Status: Patcher outdated\nClicking play will update it"; - playbtn.Text = pnp; - return GameState.OldPatcher; + if (!working) UpdateButton(playbtn, true); + modlist.Enabled = true; } - string nopatch = "Status: Unpatched"; - string gc = GetExe(withExtension: false); - string backups = GamePath(@"\IPA\Backups\" + gc); - if (!Directory.Exists(backups)) - { - status.Text = nopatch; - playbtn.Text = pnp; - return GameState.Unpatched; - } - string backup = Directory.EnumerateDirectories(backups).OrderByDescending(Directory.GetLastWriteTimeUtc).FirstOrDefault(); - if (backup == null) - { - status.Text = nopatch; - playbtn.Text = pnp; - return GameState.Unpatched; - } - if (File.GetLastWriteTime(GamePath($@"\{gc}_Data\Managed\Assembly-CSharp.dll")) - > //If the file was updated at least 2 minutes after patching - Directory.GetLastWriteTime(backup).AddMinutes(2) - || !File.Exists(GamePath($@"\{gc}_Data\Managed\IllusionInjector.dll"))) + + GameState GetPatchedState() { - status.Text = nopatch; - playbtn.Text = pnp; - return GameState.Unpatched; + if (!File.Exists(GamePath(@"\IPA.exe"))) + return GameState.NoPatcher; + + if (gcipa.Updatable && !(gcipa.Version == new Version(1, 0, 0, 0) && + gcipa.LatestVersion == new Version(4, 0, 0, 0)) + && !gameIsRunning) + return GameState.OldPatcher; + string gc = GetExe(withExtension: false); + string backups = GamePath(@"\IPA\Backups\" + gc); + if (!Directory.Exists(backups)) + return GameState.Unpatched; + string backup = Directory.EnumerateDirectories(backups) + .OrderByDescending(Directory.GetLastWriteTimeUtc).FirstOrDefault(); + if (backup == null) + return GameState.Unpatched; + if (File.GetLastWriteTime(GamePath($@"\{gc}_Data\Managed\Assembly-CSharp.dll")) + > //If the file was updated at least 2 minutes after patching + Directory.GetLastWriteTime(backup).AddMinutes(2) + || !File.Exists(GamePath($@"\{gc}_Data\Managed\IllusionInjector.dll"))) + return GameState.Unpatched; + return GameState.Patched; } - status.Text = "Status: Patched"; - playbtn.Text = "Play"; - return GameState.Patched; + var patchedState = GetPatchedState(); + var finalState = gameIsRunning ? GameState.InGame : patchedState; + SetStatusText(finalState, patchedState == GameState.Patched); + return finalState; } public async Task PatchStartGame(string command = null) diff --git a/TBMM/MainUtils.cs b/TBMM/MainUtils.cs index c939b26..975e2b0 100644 --- a/TBMM/MainUtils.cs +++ b/TBMM/MainUtils.cs @@ -112,7 +112,7 @@ namespace TBMM _gameProcess = null; if (InvokeMethod(CheckIfPatched) != GameState.Patched) return; - InvokeMethod(() => ExecutePatcher(false)).Exited += (o, args) => + InvokeMethod(() => ExecutePatcher(false)).Exited += (_, _) => { if (InvokeMethod(CheckIfPatched) == GameState.Patched) { diff --git a/TBMM/TBMM.csproj b/TBMM/TBMM.csproj index deb8382..9898069 100644 --- a/TBMM/TBMM.csproj +++ b/TBMM/TBMM.csproj @@ -11,7 +11,7 @@ ExMods A mod manager for Techblox. It automatically downloads and runs GCIPA and allows the user to install mods. true - 8 + 9