190 lines
6.0 KiB
Forth

module Degenz.Shared
open System
open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.EventArgs
open DSharpPlus.SlashCommands
open Newtonsoft.Json
[<Measure>]
type mins
[<Measure>]
type GBT
type BattleClass =
| Network
| Exploit
| Penetration
type HackId =
| Virus = 0
| RemoteAccess = 1
| Worm = 2
type ShieldId =
| Firewall = 6
| Encryption = 7
| Cypher = 8
type ItemType =
| Hack
| Shield
type BattleItem = {
Id : int
Name : string
Cost : int<GBT>
Type : ItemType
Class : BattleClass
Power : int
Cooldown : int<mins>
}
type HackResult =
| Strong
| Weak
[<CLIMutable>]
type DiscordPlayer = { Id: uint64; Name: string }
[<CLIMutable>]
type AttackResult = {
Result : bool
Target : DiscordPlayer
}
type ActionType =
| Attack of AttackResult
| Defense
[<CLIMutable>]
type Action =
{ ActionId : int
Type : ActionType
Timestamp : DateTime }
[<CLIMutable>]
type PlayerData =
{ DiscordId : uint64
Name : string
Arsenal : BattleItem array
Actions : Action array
Bank : int<GBT> }
module Player =
let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield)
let attacks player =
player.Actions
|> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense _ -> true | _ -> false)
let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
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 p =
$"Hacks: {Player.hacks p |> Array.toList}
Shields: {Player.shields p |> Array.toList}
Hack Attacks: {Player.attacks p |> Array.toList}
Active Defenses: {Player.defenses p |> Array.toList}
Bank: {p.Bank}"
let constructButtons (actionType: string) (playerInfo: string) (weapons: BattleItem array) =
weapons
|> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Success, $"{actionType}-{w.Id}-{playerInfo}", $"{w.Name}"))
let modifyPlayerBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
let armoury =
let file = System.IO.File.ReadAllText("Items.json")
JsonConvert.DeserializeObject<BattleItem array>(file)
type InteractiveMessage = {
ButtonId : string
ButtonText : string
Message : string
}
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 sendFollowUpMessageWithEmbed (event : ComponentInteractionCreateEventArgs) (embed : DiscordEmbed) msg =
async {
let builder =
DiscordFollowupMessageBuilder()
.AsEphemeral(true)
.WithContent(msg)
.AddEmbed(embed)
do! event.Interaction.CreateFollowupMessageAsync(builder)
|> Async.AwaitTask
|> Async.Ignore
}
let sendFollowUpMessageWithButton (event : ComponentInteractionCreateEventArgs) interactiveMessage =
async {
let builder = DiscordFollowupMessageBuilder()
let button = DiscordButtonComponent(ButtonStyle.Success, interactiveMessage.ButtonId, interactiveMessage.ButtonText) :> DiscordComponent
builder.AddComponents [| button |] |> ignore
builder.IsEphemeral <- true
builder.Content <- interactiveMessage.Message
do! event.Interaction.CreateFollowupMessageAsync(builder)
|> Async.AwaitTask
|> Async.Ignore
}
let updateMessageWithGreyedOutButtons (event : ComponentInteractionCreateEventArgs) interactiveMessage =
async {
let builder = DiscordInteractionResponseBuilder()
let button = DiscordButtonComponent(ButtonStyle.Success, interactiveMessage.ButtonId, interactiveMessage.ButtonText, true) :> DiscordComponent
builder.AddComponents [| button |] |> ignore
builder.IsEphemeral <- true
builder.Content <- interactiveMessage.Message
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, 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.Success, buttonId, "Got it") :> DiscordComponent
builder.AddComponents [| button |] |> ignore
builder.IsEphemeral <- true
builder.Content <- msg
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask
}