module Degenz.Shared open System open DSharpPlus open DSharpPlus.Entities open DSharpPlus.EventArgs open DSharpPlus.SlashCommands type ItemType = | Hack | Shield type ActionClass = | Network | Exploit | Penetration type Hack = | Virus = 0 | Ransom = 1 | Worm = 2 | DDos = 3 | Crack = 4 | Injection = 5 type Shield = | Firewall = 0 | PortScan = 1 | Encryption = 2 | Hardening = 4 | Sanitation = 5 | Cypher = 3 [] type Item = { Name : string ItemType : ItemType Cost : int } let weaponInventory = [| Hack.Virus ; Hack.Ransom ; Hack.DDos ; Hack.Worm ; Hack.Crack ; Hack.Injection |] let shieldInventory = [| Shield.Firewall ; Shield.PortScan ; Shield.Encryption ; Shield.Cypher ; Shield.Hardening ; Shield.Sanitation |] let getClass = function | 0 | 1 -> Network | 2 | 3 -> Exploit | 4 | _ -> Penetration type HackResult = | Strong | Weak [] type DiscordPlayer = { Id: uint64; Name: string } [] type Attack = { HackType: Hack Target: DiscordPlayer Timestamp: DateTime } [] type Defense = { DefenseType: Shield Timestamp: DateTime } [] type Player = { DiscordId: uint64 Name: string Weapons: Hack array Shields: Shield array Attacks: Attack array Defenses: Defense array Bank: int } let createSimpleResponseAsync msg (ctx: InteractionContext) = async { let builder = DiscordInteractionResponseBuilder() builder.Content <- msg builder.AsEphemeral true |> ignore do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask } let notYetAHackerMsg = createSimpleResponseAsync "You are currently not a hacker, first use the /redpill command to become one" let hackDescription = "" let statusFormat player = $"Hack Inventory: {player.Weapons |> Array.toList} Shield Inventory: {player.Shields |> Array.toList} Active Hacks: {player.Attacks |> Array.toList} Active Defenses: {player.Defenses |> Array.toList} Bank: {player.Bank}" let constructButtons (actionType: string) (playerInfo: string) (weapons: 'a array) = weapons |> Seq.map (fun hack -> DiscordButtonComponent(ButtonStyle.Primary, $"{actionType}-{hack}-{playerInfo}", $"{hack}")) let removeExpiredActions timespan (timestamp: 'a -> DateTime) actions = actions |> Array.filter (fun act -> DateTime.UtcNow - (timestamp act) < timespan) let modifyPlayerBank player amount = { player with Bank = Math.Max(player.Bank + amount, 0) } module Message = let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg = async { let builder = DiscordFollowupMessageBuilder() builder.IsEphemeral <- true builder.Content <- msg do! event.Interaction.CreateFollowupMessageAsync(builder) |> Async.AwaitTask |> Async.Ignore } let sendFollowUpMessageWithButton (event : ComponentInteractionCreateEventArgs) buttonId msg = async { let builder = DiscordFollowupMessageBuilder() let button = DiscordButtonComponent(ButtonStyle.Primary, buttonId, "Got it") :> DiscordComponent builder.AddComponents [| button |] |> ignore builder.IsEphemeral <- true builder.Content <- msg do! event.Interaction.CreateFollowupMessageAsync(builder) |> Async.AwaitTask |> Async.Ignore } let sendInteractionEvent (event : ComponentInteractionCreateEventArgs) msg = async { let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- msg do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask } let sendInteractionEventWithButton (event : ComponentInteractionCreateEventArgs) buttonId msg = async { let builder = DiscordInteractionResponseBuilder() let button = DiscordButtonComponent(ButtonStyle.Primary, buttonId, "Got it") :> DiscordComponent builder.AddComponents [| button |] |> ignore builder.IsEphemeral <- true builder.Content <- msg do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask }