module Degenz.Trainer open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities open DSharpPlus.EventArgs open DSharpPlus.SlashCommands open Degenz.Shared open Degenz.Store let defaultHack = armoury |> Array.find (fun i -> i.Id = int HackId.Virus) let defaultShield = armoury |> Array.find (fun i -> i.Id = int ShieldId.Firewall) let sendInitialEmbed (client : DiscordClient) = async { let! channel = client.GetChannelAsync(GuildEnvironment.channelTraining) |> Async.AwaitTask let builder = DiscordMessageBuilder() let embed = DiscordEmbedBuilder() embed.ImageUrl <- "https://s10.gifyu.com/images/MasterTraining_Degenz.gif" builder.AddEmbed embed |> ignore builder.Content <- "Welcome to the hacker dojo you degenerate, are you ready to get started?" let button = DiscordButtonComponent(ButtonStyle.Success, $"Trainer-1", $"Get started") :> DiscordComponent builder.AddComponents [| button |] |> ignore do! channel.SendMessageAsync(builder) |> Async.AwaitTask |> Async.Ignore } |> Async.RunSynchronously let step1Msg = { ButtonId = "Trainer-2" ButtonText = "Show me" Message = "First time, eh? Beautopia is a dangerous place. I'm going to teach you how to protect yourself from other degenerates. " + "And in the process, I'll also show you how to hack some sheeple, so you can earn some cash." } let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) = async { let! maybePlayer = DbService.tryFindPlayer event.User.Id do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate) |> Async.AwaitTask match maybePlayer with | Some _ -> do! Message.sendFollowUpMessageWithButton event step1Msg | None -> let msg = "Looks like an error occurred, you're not a registered degenerate. Please contact a moderator." do! Message.sendFollowUpMessage event msg } let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) = async { let! result = DbService.tryFindPlayer event.User.Id match result with | Some player -> let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name do! Message.updateMessageWithGreyedOutButtons event step1Msg let shieldMessage = if Player.shields player |> Array.isEmpty then $"You do not have any Shields in your arsenal, here's a {defaultShield.Name} you can use for now" else $"You currently have {weaponName} in your arsenal" do! Message.sendFollowUpMessage event ($"First things first, let's get your system protected. Let's enable a shield to protect you from potential hackers. " + $"{shieldMessage}. To enable it and protect your system, you can use the `/defend` slash command to choose a shield." + $"\n\nRun the `/defend` command now and then select '{weaponName}'.") | None -> do! Message.sendFollowUpMessage event $"Something went wrong, please contact a moderator" } let defend (ctx : InteractionContext) = async { let! playerResult = DbService.tryFindPlayer ctx.Member.Id match playerResult with | Some player -> let playerWithShields = match player.Arsenal with | [||] -> { player with Arsenal = [| defaultShield |] } | _ -> player let embed = Embeds.pickDefense "Trainer-3" playerWithShields do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) |> Async.AwaitTask | None -> let builder = DiscordInteractionResponseBuilder() builder.Content <- "Error, please contact a moderator" builder.AsEphemeral true |> ignore do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask } |> Async.StartAsTask :> Task let handleDefenseMsg = { ButtonId = "Trainer-4" ButtonText = "Got it" Message = "I wasn't able to hack you. Great job! Because you had your system protected when I tried to hack you, you took some money from me. " + "Shields only protect you for a certain amount of time, so remember to keep your system protected at all times." } let handleDefense (event : ComponentInteractionCreateEventArgs) = let sendMessage' = Message.sendFollowUpMessage event async { do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate) |> Async.AwaitTask let! maybePlayer = DbService.tryFindPlayer event.User.Id match maybePlayer with | Some player -> let prize = 0.223f let shield = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield let embed = Embeds.responseCreatedShieldTrainer shield do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore do! Async.Sleep 2000 do! sendMessage' "Ok, good, let me make sure that worked. I'll try to hack you now" do! Async.Sleep 4000 do! sendMessage' $"Hacking attempt failed! {player.Name} defended hack from Degenz-Trainer and took {prize} from them! " do! Async.Sleep 3000 do! Message.sendFollowUpMessageWithButton event handleDefenseMsg | None -> do! sendMessage' $"Something went wrong, please contact a moderator" } let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) = async { let! result = DbService.tryFindPlayer event.User.Id match result with | Some player -> let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name do! Message.updateMessageWithGreyedOutButtons event handleDefenseMsg let hackMessage = if Player.shields player |> Array.isEmpty then $"You do not have any Hacks in your arsenal, here's a {defaultHack.Name} you can use for now" else $"You currently have {weaponName} in your arsenal" do! Message.sendFollowUpMessage event ($"Next why don't you try hacking me. {hackMessage}. To hack me and get some money, " + $" you can use the '/hack' slash command and select a user to hack, then choose the hack attack you wish to use." + $"\n\nRun the `/hack` command now and pick me as your target, then click on the '{weaponName}' button.") | None -> do! Message.sendInteractionEvent event $"Something went wrong, please contact a moderator" } let attack (ctx : InteractionContext) (target : DiscordUser) = async { let isRightTarget = target.Id = GuildEnvironment.botHackerBattle let! playerResult = DbService.tryFindPlayer ctx.Member.Id match isRightTarget , playerResult with | true , Some player -> let playerWithAttacks = match player.Arsenal with | [||] -> { player with Arsenal = [| defaultHack |] } | _ -> player let embed = Embeds.pickHack "Trainer-5" playerWithAttacks player do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) |> Async.AwaitTask | false , _ -> let builder = DiscordInteractionResponseBuilder() builder.Content <- "You picked the wrong target, you dufus. Try again, this time pick me!" builder.IsEphemeral <- true do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask | _ -> let builder = DiscordInteractionResponseBuilder() builder.Content <- "Error, please contact a moderator" builder.AsEphemeral true |> ignore do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask } |> Async.StartAsTask :> Task let handleAttackMsg = { ButtonId = "Trainer-6" ButtonText = "Hell yeah" Message = "I think we're done. You are going to need more hacks and shields if you want to survive in this crazy world. " + "Remember to go check out the store and purchase whatever you need to add to your arsenal." + "\n\nAlright you degenerate, off you go!" } let handleAttack (event : ComponentInteractionCreateEventArgs) = let sendMessage' = Message.sendFollowUpMessage event async { do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate) |> Async.AwaitTask let! result = DbService.tryFindPlayer event.User.Id match result with | Some player -> let prize = 2 do! Async.Sleep 1000 let hack = player.Arsenal |> Array.tryHead |> Option.defaultValue defaultHack let embed = Embeds.responseSuccessfulHackTrainer $"<@{GuildEnvironment.botHackerBattle}>" hack prize do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore do! Async.Sleep 3000 do! sendMessage' ("Look at that, you are now officially an elite haxor! By successfully hacking other people you can earn GoodBoyTokenz. " + "Hacks take time to recover so check back in later once you've used all your hacks.") do! Async.Sleep 7000 do! Message.sendFollowUpMessageWithButton event handleAttackMsg | None -> do! sendMessage' $"Something went wrong, please contact a moderator" } let handleTrainerStep6 (event : ComponentInteractionCreateEventArgs) = async { // let! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask // let role = event.Guild.GetRole(GuildEnvironment.roleTrainee) // do! membr.RevokeRoleAsync(role) |> Async.AwaitTask let builder = DiscordFollowupMessageBuilder() builder.IsEphemeral <- true builder.Content <- "Get out of here!" do! Message.updateMessageWithGreyedOutButtons event handleAttackMsg do! event.Interaction.CreateFollowupMessageAsync(builder) |> Async.AwaitTask |> Async.Ignore } let handleButtonEvent (event : ComponentInteractionCreateEventArgs) = async { let split = event.Id.Split("-") match int split.[1] with | 1 -> do! handleTrainerStep1 event | 2 -> do! handleTrainerStep2 event | 3 -> do! handleDefense event | 4 -> do! handleTrainerStep4 event | 5 -> do! handleAttack event | 6 -> do! handleTrainerStep6 event | _ -> do! Message.sendFollowUpMessage event "No action found" }