From 91568ce9d280456d3429b35ed13a978730663d37 Mon Sep 17 00:00:00 2001 From: Amos Date: Sat, 6 Jul 2024 22:41:59 +0100 Subject: [PATCH] Add PromptClientInput method in Utilities.cs A new utility method named 'PromptClientInput' has been added in the Utilities.cs file. This method accepts client, prompt, and validator as inputs and allows taking action based on client responses. Included subscription and unsubscription to the 'ClientMessaged' game event, and handling of cancellation token to control the execution flow. --- SharedLibraryCore/Utilities.cs | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index d8e72a48..f7e2a322 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -19,10 +19,12 @@ using SharedLibraryCore.Configuration; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos.Meta; +using SharedLibraryCore.Events.Game; using SharedLibraryCore.Events.Server; using SharedLibraryCore.Exceptions; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; +using SharedLibraryCore.Interfaces.Events; using SharedLibraryCore.Localization; using SharedLibraryCore.RCon; using static System.Threading.Tasks.Task; @@ -1372,5 +1374,48 @@ public static void ExecuteAfterDelay(int delayMs, Func public static void ExecuteAfterDelay(this Func action, int delayMs, CancellationToken token = default) => ExecuteAfterDelay(delayMs, action, token); + + public static async Task PromptClientInput(this EFClient client, string prompt, Func> validator, + CancellationToken token = default) + { + var clientResponse = new ManualResetEventSlim(false); + string response = null; + + try + { + IGameEventSubscriptions.ClientMessaged += OnResponse; + await client.TellAsync([prompt], token); + + var tokenSource = new CancellationTokenSource(DefaultCommandTimeout); + using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(tokenSource.Token, token); + + clientResponse.Wait(linkedTokenSource.Token); + + return response; + } + finally + { + IGameEventSubscriptions.ClientMessaged -= OnResponse; + } + + async Task OnResponse(ClientMessageEvent messageEvent, CancellationToken cancellationToken) + { + if (!messageEvent.Origin.ClientId.Equals(client.ClientId) || cancellationToken.IsCancellationRequested) + { + return; + } + + response = messageEvent.Message; + + if (await validator(response)) + { + clientResponse.Set(); + } + else + { + await client.TellAsync([prompt], cancellationToken); + } + } + } } }