From 036a467bd0cd77c75b9f5d25f4e9361072bdfe06 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 Microsoft.Extensions.Logging; 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 @@ namespace SharedLibraryCore 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); + } + } + } } }