From d762991b49e7231e4cef3c6b90a8ec05cb879445 Mon Sep 17 00:00:00 2001 From: Rans4ckeR Date: Wed, 7 Dec 2022 10:45:11 +0100 Subject: [PATCH] Use Tasks instead of Threads --- ClientGUI/GameProcessLogic.cs | 6 +- .../DXGUI/Generic/CampaignSelector.cs | 23 ++---- .../DXGUI/Generic/GameLoadingWindow.cs | 10 ++- DXMainClient/DXGUI/Generic/MainMenu.cs | 25 +++--- .../CnCNet/CnCNetGameLoadingLobby.cs | 8 +- .../DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs | 7 +- .../DXGUI/Multiplayer/GameLoadingLobbyBase.cs | 4 +- .../Multiplayer/GameLobby/GameLobbyBase.cs | 6 +- .../DXGUI/Multiplayer/LANGameLoadingLobby.cs | 6 +- DXMainClient/Online/CnCNetGameCheck.cs | 76 +++++++------------ 10 files changed, 70 insertions(+), 101 deletions(-) diff --git a/ClientGUI/GameProcessLogic.cs b/ClientGUI/GameProcessLogic.cs index 8f3d6d692..191af0957 100644 --- a/ClientGUI/GameProcessLogic.cs +++ b/ClientGUI/GameProcessLogic.cs @@ -4,7 +4,7 @@ using ClientCore; using Rampastring.Tools; using ClientCore.INIProcessing; -using System.Threading; +using System.Threading.Tasks; using Rampastring.XNAUI; namespace ClientGUI @@ -26,7 +26,7 @@ public static class GameProcessLogic /// /// Starts the main game process. /// - public static void StartGameProcess(WindowManager windowManager) + public static async ValueTask StartGameProcessAsync(WindowManager windowManager) { Logger.Log("About to launch main game executable."); @@ -35,7 +35,7 @@ public static void StartGameProcess(WindowManager windowManager) int waitTimes = 0; while (PreprocessorBackgroundTask.Instance.IsRunning) { - Thread.Sleep(1000); + await Task.Delay(1000); waitTimes++; if (waitTimes > 10) { diff --git a/DXMainClient/DXGUI/Generic/CampaignSelector.cs b/DXMainClient/DXGUI/Generic/CampaignSelector.cs index 733151509..faa6b95c2 100644 --- a/DXMainClient/DXGUI/Generic/CampaignSelector.cs +++ b/DXMainClient/DXGUI/Generic/CampaignSelector.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using DTAClient.Domain; using System.IO; +using System.Threading.Tasks; +using ClientCore.Extensions; using ClientGUI; using Rampastring.XNAUI.XNAControls; using Rampastring.XNAUI; @@ -149,7 +151,7 @@ public override void Initialize() btnLaunch.ClientRectangle = new Rectangle(12, Height - 35, UIDesignConstants.BUTTON_WIDTH_133, UIDesignConstants.BUTTON_HEIGHT); btnLaunch.Text = "Launch".L10N("UI:Main:ButtonLaunch"); btnLaunch.AllowClick = false; - btnLaunch.LeftClick += BtnLaunch_LeftClick; + btnLaunch.LeftClick += (_, _) => BtnLaunch_LeftClickAsync().HandleTask(); var btnCancel = new XNAClientButton(WindowManager); btnCancel.Name = "btnCancel"; @@ -186,7 +188,7 @@ public override void Initialize() AddChild(dp); dp.CenterOnParent(); cheaterWindow.CenterOnParent(); - cheaterWindow.YesClicked += CheaterWindow_YesClicked; + cheaterWindow.YesClicked += (_, _) => LaunchMissionAsync(missionToLaunch).HandleTask(); cheaterWindow.Disable(); } @@ -224,7 +226,7 @@ private void BtnCancel_LeftClick(object sender, EventArgs e) Enabled = false; } - private void BtnLaunch_LeftClick(object sender, EventArgs e) + private async ValueTask BtnLaunch_LeftClickAsync() { int selectedMissionId = lbCampaignList.SelectedIndex; @@ -239,7 +241,7 @@ private void BtnLaunch_LeftClick(object sender, EventArgs e) return; } - LaunchMission(mission); + await LaunchMissionAsync(mission); } private bool AreFilesModified() @@ -253,19 +255,10 @@ private bool AreFilesModified() return false; } - /// - /// Called when the user wants to proceed to the mission despite having - /// being called a cheater. - /// - private void CheaterWindow_YesClicked(object sender, EventArgs e) - { - LaunchMission(missionToLaunch); - } - /// /// Starts a singleplayer mission. /// - private void LaunchMission(Mission mission) + private async ValueTask LaunchMissionAsync(Mission mission) { bool copyMapsToSpawnmapINI = ClientConfiguration.Instance.CopyMissionsToSpawnmapINI; @@ -318,7 +311,7 @@ private void LaunchMission(Mission mission) discordHandler.UpdatePresence(mission.GUIName, difficultyName, mission.IconPath, true); GameProcessLogic.GameProcessExited += GameProcessExited_Callback; - GameProcessLogic.StartGameProcess(WindowManager); + await GameProcessLogic.StartGameProcessAsync(WindowManager); } private int GetComputerDifficulty() => diff --git a/DXMainClient/DXGUI/Generic/GameLoadingWindow.cs b/DXMainClient/DXGUI/Generic/GameLoadingWindow.cs index 917a60bb1..95f987ef3 100644 --- a/DXMainClient/DXGUI/Generic/GameLoadingWindow.cs +++ b/DXMainClient/DXGUI/Generic/GameLoadingWindow.cs @@ -10,6 +10,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; +using ClientCore.Extensions; namespace DTAClient.DXGUI.Generic { @@ -55,7 +57,7 @@ public override void Initialize() btnLaunch.ClientRectangle = new Rectangle(125, 345, 110, 23); btnLaunch.Text = "Load".L10N("UI:Main:ButtonLoad"); btnLaunch.AllowClick = false; - btnLaunch.LeftClick += BtnLaunch_LeftClick; + btnLaunch.LeftClick += (_, _) => BtnLaunch_LeftClickAsync().HandleTask(); btnDelete = new XNAClientButton(WindowManager); btnDelete.Name = nameof(btnDelete); @@ -99,7 +101,7 @@ private void BtnCancel_LeftClick(object sender, EventArgs e) Enabled = false; } - private void BtnLaunch_LeftClick(object sender, EventArgs e) + private async ValueTask BtnLaunch_LeftClickAsync() { SavedGame sg = savedGames[lbSaveGameList.SelectedIndex]; Logger.Log("Loading saved game " + sg.FileName); @@ -137,7 +139,7 @@ private void BtnLaunch_LeftClick(object sender, EventArgs e) Enabled = false; GameProcessLogic.GameProcessExited += GameProcessExited_Callback; - GameProcessLogic.StartGameProcess(WindowManager); + await GameProcessLogic.StartGameProcessAsync(WindowManager); } private void BtnDelete_LeftClick(object sender, EventArgs e) @@ -219,4 +221,4 @@ private void ParseSaveGame(string fileName) savedGames.Add(sg); } } -} +} \ No newline at end of file diff --git a/DXMainClient/DXGUI/Generic/MainMenu.cs b/DXMainClient/DXGUI/Generic/MainMenu.cs index 6e8f82362..501763f3b 100644 --- a/DXMainClient/DXGUI/Generic/MainMenu.cs +++ b/DXMainClient/DXGUI/Generic/MainMenu.cs @@ -225,7 +225,7 @@ public override void Initialize() btnExit.IdleTexture = AssetLoader.LoadTexture("MainMenu/exitgame.png"); btnExit.HoverTexture = AssetLoader.LoadTexture("MainMenu/exitgame_c.png"); btnExit.HoverSoundEffect = new EnhancedSoundEffect("MainMenu/button.wav"); - btnExit.LeftClick += BtnExit_LeftClick; + btnExit.LeftClick += (_, _) => BtnExit_LeftClickAsync().HandleTask(); XNALabel lblCnCNetStatus = new XNALabel(WindowManager); lblCnCNetStatus.Name = nameof(lblCnCNetStatus); @@ -312,10 +312,8 @@ public override void Initialize() GameProcessLogic.GameProcessStarted += SharedUILogic_GameProcessStarted; GameProcessLogic.GameProcessStarting += SharedUILogic_GameProcessStarting; - UserINISettings.Instance.SettingsSaved += SettingsSaved; - - Updater.Restart += Updater_Restart; + Updater.Restart += (_, _) => WindowManager.AddCallback(() => ExitClientAsync().HandleTask()); SetButtonHotkeys(true); } @@ -379,9 +377,6 @@ private void SharedUILogic_GameProcessStarting() } } - private void Updater_Restart(object sender, EventArgs e) => - WindowManager.AddCallback(ExitClient); - /// /// Applies configuration changes (music playback and volume) /// when settings are saved. @@ -868,12 +863,12 @@ private void BtnCredits_LeftClick(object sender, EventArgs e) private void BtnExtras_LeftClick(object sender, EventArgs e) => innerPanel.Show(innerPanel.ExtrasWindow); - private void BtnExit_LeftClick(object sender, EventArgs e) + private ValueTask BtnExit_LeftClickAsync() { #if WINFORMS WindowManager.HideWindow(); #endif - FadeMusicExit(); + return FadeMusicExitAsync(); } private void SharedUILogic_GameProcessExited() => @@ -969,11 +964,11 @@ private void FadeMusic(GameTime gameTime) /// /// Exits the client. Quickly fades the music if it's playing. /// - private void FadeMusicExit() + private async ValueTask FadeMusicExitAsync() { if (!isMediaPlayerAvailable || themeSong == null) { - ExitClient(); + await ExitClientAsync(); return; } @@ -982,21 +977,21 @@ private void FadeMusicExit() if (MediaPlayer.Volume > step) { MediaPlayer.Volume -= step; - AddCallback(FadeMusicExit); + AddCallback(() => FadeMusicExitAsync().HandleTask()); } else { MediaPlayer.Stop(); - ExitClient(); + await ExitClientAsync(); } } - private void ExitClient() + private async ValueTask ExitClientAsync() { Logger.Log("Exiting."); WindowManager.CloseGame(); #if !XNA - Thread.Sleep(1000); + await Task.Delay(1000); Environment.Exit(0); #endif } diff --git a/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetGameLoadingLobby.cs b/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetGameLoadingLobby.cs index e362eefb7..f7d34a23c 100644 --- a/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetGameLoadingLobby.cs +++ b/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetGameLoadingLobby.cs @@ -53,7 +53,7 @@ public CnCNetGameLoadingLobby( new IntCommandHandler(CnCNetCommands.TUNNEL_PING, HandleTunnelPing), new StringCommandHandler(CnCNetCommands.OPTIONS, (sender, data) => HandleOptionsMessageAsync(sender, data).HandleTask()), new NoParamCommandHandler(CnCNetCommands.INVALID_SAVED_GAME_INDEX, HandleInvalidSaveIndexCommand), - new StringCommandHandler(CnCNetCommands.START_GAME, HandleStartGameCommand), + new StringCommandHandler(CnCNetCommands.START_GAME, (sender, data) => HandleStartGameCommandAsync(sender, data).HandleTask()), new IntCommandHandler(CnCNetCommands.PLAYER_READY, (sender, readyStatus) => HandlePlayerReadyRequestAsync(sender, readyStatus).HandleTask()), new StringCommandHandler(CnCNetCommands.CHANGE_TUNNEL_SERVER, HandleTunnelServerChangeMessage) }; @@ -489,7 +489,7 @@ private void HandleInvalidSaveIndexCommand(string sender) CopyPlayerDataToUI(); } - private void HandleStartGameCommand(string sender, string data) + private async ValueTask HandleStartGameCommandAsync(string sender, string data) { if (sender != hostName) return; @@ -523,7 +523,7 @@ private void HandleStartGameCommand(string sender, string data) pInfo.Port = port; } - LoadGame(); + await LoadGameAsync(); } private async ValueTask HandlePlayerReadyRequestAsync(string sender, int readyStatus) @@ -606,7 +606,7 @@ protected override async ValueTask HostStartGameAsync() started = true; - LoadGame(); + await LoadGameAsync(); } protected override void WriteSpawnIniAdditions(IniFile spawnIni) diff --git a/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs b/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs index 372fdabac..4ca386de3 100644 --- a/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs +++ b/DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs @@ -1111,8 +1111,8 @@ private void ConnectionManager_Disconnected(object sender, EventArgs e) ddCurrentChannel.SelectedIndex = gameIndex; } - if (gameCheckCancellation != null) - gameCheckCancellation.Cancel(); + gameCheckCancellation?.Cancel(); + gameCheckCancellation?.Dispose(); } private async ValueTask ConnectionManager_WelcomeMessageReceivedAsync() @@ -1147,8 +1147,7 @@ private async ValueTask ConnectionManager_WelcomeMessageReceivedAsync() } gameCheckCancellation = new CancellationTokenSource(); - CnCNetGameCheck gameCheck = new CnCNetGameCheck(); - gameCheck.InitializeService(gameCheckCancellation); + CnCNetGameCheck.RunServiceAsync(gameCheckCancellation.Token).HandleTask(); } private void ConnectionManager_PrivateCTCPReceived(object sender, PrivateCTCPEventArgs e) diff --git a/DXMainClient/DXGUI/Multiplayer/GameLoadingLobbyBase.cs b/DXMainClient/DXGUI/Multiplayer/GameLoadingLobbyBase.cs index a8e82dee1..9cb23cd03 100644 --- a/DXMainClient/DXGUI/Multiplayer/GameLoadingLobbyBase.cs +++ b/DXMainClient/DXGUI/Multiplayer/GameLoadingLobbyBase.cs @@ -286,7 +286,7 @@ protected virtual ValueTask NotAllPresentNotificationAsync() protected abstract ValueTask HostStartGameAsync(); - protected void LoadGame() + protected async ValueTask LoadGameAsync() { FileInfo spawnFileInfo = SafePath.GetFile(ProgramConstants.GamePath, ProgramConstants.SPAWNER_SETTINGS); @@ -340,7 +340,7 @@ protected void LoadGame() gameLoadTime = DateTime.Now; GameProcessLogic.GameProcessExited += SharedUILogic_GameProcessExited; - GameProcessLogic.StartGameProcess(WindowManager); + await GameProcessLogic.StartGameProcessAsync(WindowManager); fsw.EnableRaisingEvents = true; UpdateDiscordPresence(true); diff --git a/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs b/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs index 8d98cad07..642f4f36b 100644 --- a/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs +++ b/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs @@ -1640,7 +1640,7 @@ private void ManipulateStartingLocations(IniFile mapIni, PlayerHouseInfo[] house /// Writes spawn.ini, writes the map file, initializes statistics and /// starts the game process. /// - protected virtual ValueTask StartGameAsync() + protected virtual async ValueTask StartGameAsync() { PlayerHouseInfo[] houseInfos = WriteSpawnIni(); InitializeMatchStatistics(houseInfos); @@ -1648,10 +1648,8 @@ protected virtual ValueTask StartGameAsync() GameProcessLogic.GameProcessExited += GameProcessExited_Callback; - GameProcessLogic.StartGameProcess(WindowManager); + await GameProcessLogic.StartGameProcessAsync(WindowManager); UpdateDiscordPresence(true); - - return ValueTask.CompletedTask; } private void GameProcessExited_Callback() => AddCallback(() => GameProcessExitedAsync().HandleTask()); diff --git a/DXMainClient/DXGUI/Multiplayer/LANGameLoadingLobby.cs b/DXMainClient/DXGUI/Multiplayer/LANGameLoadingLobby.cs index a5ca4e881..465c64bec 100644 --- a/DXMainClient/DXGUI/Multiplayer/LANGameLoadingLobby.cs +++ b/DXMainClient/DXGUI/Multiplayer/LANGameLoadingLobby.cs @@ -50,7 +50,7 @@ public LANGameLoadingLobby( { new ClientStringCommandHandler(LANCommands.CHAT_GAME_LOADING_COMMAND, Client_HandleChatMessage), new ClientStringCommandHandler(LANCommands.OPTIONS, Client_HandleOptionsMessage), - new ClientNoParamCommandHandler(LANCommands.GAME_START, Client_HandleStartCommand) + new ClientNoParamCommandHandler(LANCommands.GAME_START, () => Client_HandleStartCommandAsync().HandleTask()) }; WindowManager.GameClosing += (_, _) => WindowManager_GameClosingAsync().HandleTask(); @@ -556,11 +556,11 @@ private void Client_HandleOptionsMessage(string data) CopyPlayerDataToUI(); } - private void Client_HandleStartCommand() + private ValueTask Client_HandleStartCommandAsync() { started = true; - LoadGame(); + return LoadGameAsync(); } #endregion diff --git a/DXMainClient/Online/CnCNetGameCheck.cs b/DXMainClient/Online/CnCNetGameCheck.cs index 952b69aec..f878b20d0 100644 --- a/DXMainClient/Online/CnCNetGameCheck.cs +++ b/DXMainClient/Online/CnCNetGameCheck.cs @@ -1,48 +1,43 @@ using System; using ClientCore; using System.Diagnostics; +using System.IO; using System.Threading; +using System.Threading.Tasks; namespace DTAClient.Online { - public class CnCNetGameCheck + internal static class CnCNetGameCheck { - private static int REFRESH_INTERVAL = 15000; // 15 seconds + private const int REFRESH_INTERVAL = 15000; // 15 seconds - public void InitializeService(CancellationTokenSource cts) + public static async ValueTask RunServiceAsync(CancellationToken cancellationToken) { - ThreadPool.QueueUserWorkItem(new WaitCallback(RunService), cts); - } - - private void RunService(object tokenObj) - { - var waitHandle = ((CancellationTokenSource)tokenObj).Token.WaitHandle; - - while (true) + while (!cancellationToken.IsCancellationRequested) { - if (waitHandle.WaitOne(REFRESH_INTERVAL)) + try { - // Cancellation signaled - return; + await Task.Delay(REFRESH_INTERVAL, cancellationToken); + + CheatEngineWatchEvent(); } - else + catch (OperationCanceledException) { - CheatEngineWatchEvent(); } } } - private void CheatEngineWatchEvent() + private static void CheatEngineWatchEvent() { Process[] processlist = Process.GetProcesses(); + foreach (Process process in processlist) { try { if (process.ProcessName.Contains("cheatengine") || process.MainWindowTitle.ToLower().Contains("cheat engine") || - process.MainWindowHandle.ToString().ToLower().Contains("cheat engine") - ) + process.MainWindowHandle.ToString().ToLower().Contains("cheat engine")) { KillGameInstance(); } @@ -56,38 +51,25 @@ private void CheatEngineWatchEvent() } } - private void KillGameInstance() + private static void KillGameInstance() { - try - { - string gameExecutableName = ClientConfiguration.Instance.GetOperatingSystemVersion() == OSVersion.UNIX ? - ClientConfiguration.Instance.UnixGameExecutableName : - ClientConfiguration.Instance.GetGameExecutableName(); + string gameExecutableName = ClientConfiguration.Instance.GetOperatingSystemVersion() == OSVersion.UNIX ? + ClientConfiguration.Instance.UnixGameExecutableName : + ClientConfiguration.Instance.GetGameExecutableName(); - gameExecutableName = gameExecutableName.Replace(".exe", ""); - - Process[] processlist = Process.GetProcesses(); - foreach (Process process in processlist) + foreach (Process process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(gameExecutableName))) + { + try { - try - { - if (process.ProcessName.Contains(gameExecutableName)) - { - process.Kill(); - } - } - catch (Exception ex) - { - ProgramConstants.LogException(ex); - } - - process.Dispose(); + process.Kill(); } - } - catch (Exception ex) - { - ProgramConstants.LogException(ex); + catch (Exception ex) + { + ProgramConstants.LogException(ex); + } + + process.Dispose(); } } } -} +} \ No newline at end of file