module Degenz.PlayerInteractions open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities open DSharpPlus.EventArgs open Degenz.Messaging open Degenz.DbService let executePlayerAction (ctx : IDiscordContext) (dispatch : PlayerData -> Async) = async { let builder = DiscordInteractionResponseBuilder().AsEphemeral(true) do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! playerResult = tryFindPlayer (ctx.GetDiscordMember().Id) match playerResult with | Some player -> do! dispatch player | None -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one" } |> Async.Start Task.CompletedTask let executePlayerActionNoMsg (ctx : IDiscordContext) (dispatch : PlayerData -> Async) = async { let eventCtx = ctx.GetContext() :?> ComponentInteractionCreateEventArgs let disabledButtons = eventCtx.Message.Components |> Seq.map (fun c -> c.Components |> Seq.cast) |> Seq.concat |> Seq.map (fun btn -> DiscordButtonComponent(btn.Style, btn.CustomId, btn.Label, disabled = true)) |> Seq.cast let builder = DiscordInteractionResponseBuilder() .AddEmbeds(eventCtx.Message.Embeds) .AddComponents(disabledButtons) do! ctx.Respond(InteractionResponseType.UpdateMessage, builder) |> Async.AwaitTask let! playerResult = tryFindPlayer (ctx.GetDiscordMember().Id) match playerResult with | Some player -> do! dispatch player | None -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one" } |> Async.Start Task.CompletedTask let executePlayerActionWithTarget (targetPlayer : DiscordUser) (ctx : IDiscordContext) (dispatch : PlayerData -> PlayerData -> Async) = async { let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- "Content" do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! players = [ tryFindPlayer (ctx.GetDiscordMember().Id) tryFindPlayer targetPlayer.Id ] |> Async.Parallel match players.[0] , players.[1] with | Some player , Some target -> do! dispatch player target | None , _ -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one" | _ , None -> if targetPlayer.IsBot then do! Messaging.sendFollowUpMessage ctx $"{targetPlayer.Username} is a bot, pick a real human to hack" else do! Messaging.sendFollowUpMessage ctx "Your target is not connected to the network, they must join first by using the /redpill command" } |> Async.Start Task.CompletedTask let executePlayerActionWithTargetId defer (targetId : uint64) (ctx : IDiscordContext) (dispatch : PlayerData -> PlayerData -> Async) = async { let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- "Content" if defer then do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! players = [ tryFindPlayer (ctx.GetDiscordMember().Id) tryFindPlayer targetId ] |> Async.Parallel match players.[0] , players.[1] with | Some player , Some target -> do! dispatch player target | None , _ -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one" | _ , None -> do! Messaging.sendFollowUpMessage ctx "Your target is not connected to the network, they must join first by using the /redpill command" } |> Async.StartAsTask :> Task let handleResultWithResponse ctx fn (player : Result) = match player with | Ok p -> fn p | Error e -> async { do! Messaging.sendFollowUpMessage ctx e } let handleResultWithEmbed<'a> (ctx : IDiscordContext) fn (player : Result<'a, DiscordFollowupMessageBuilder>) = match player with | Ok a -> fn a | Error e -> async { do! ctx.FollowUp e |> Async.AwaitTask}