178 lines
5.3 KiB
Forth
178 lines
5.3 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
|
|
| Ransom = 1
|
|
| Worm = 2
|
|
| DDos = 3
|
|
| Crack = 4
|
|
| Injection = 5
|
|
|
|
type ShieldId =
|
|
| Firewall = 6
|
|
| PortScan = 7
|
|
| Encryption = 8
|
|
| Hardening = 9
|
|
| Sanitation = 10
|
|
| Cypher = 11
|
|
|
|
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.Primary, $"{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)
|
|
|
|
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) 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
|
|
}
|
|
|