Getting defense command to work. Fixes and improvements
This commit is contained in:
parent
97bf07e7ec
commit
2f3a9fd1f9
91
Program.fs
91
Program.fs
@ -1,5 +1,4 @@
|
||||
open System
|
||||
open System.IO
|
||||
open System.Threading.Tasks
|
||||
open DSharpPlus
|
||||
open DSharpPlus.Entities
|
||||
@ -23,13 +22,19 @@ type Protection =
|
||||
| Hardening = 4
|
||||
| Sanitation = 5
|
||||
|
||||
type DiscordPlayer = {
|
||||
Id : uint64
|
||||
Name : string
|
||||
}
|
||||
|
||||
type Attack = {
|
||||
HackType : Hack
|
||||
Target : DiscordPlayer
|
||||
Timestamp : DateTime
|
||||
}
|
||||
|
||||
type Defense = {
|
||||
DefenseType : Hack
|
||||
DefenseType : Protection
|
||||
Timestamp : DateTime
|
||||
}
|
||||
|
||||
@ -62,13 +67,12 @@ let newPlayer (membr : uint64) =
|
||||
Bank = 0L
|
||||
Defenses = [] }
|
||||
|
||||
let constructButtons (actionType : string) (playerId : uint64) (weapons : 'a list) =
|
||||
let constructButtons (actionType : string) (playerInfo : string) (weapons : 'a list) =
|
||||
weapons
|
||||
|> Seq.map (fun hack ->
|
||||
// TODO:L Button ID should be a GUID and we should keep an in-memory store of the buttons we're waiting for
|
||||
DiscordButtonComponent(
|
||||
ButtonStyle.Primary,
|
||||
$"{actionType}-{hack}-{playerId}",
|
||||
$"{actionType}-{hack}-{playerInfo}",
|
||||
$"{hack}"))
|
||||
|
||||
let notRegisteredYetMessage (ctx : InteractionContext) =
|
||||
@ -91,6 +95,17 @@ let removeExpiredActions timespan (timestamp : 'a -> DateTime) actions =
|
||||
then true
|
||||
else false)
|
||||
|
||||
let constructEmbed message =
|
||||
let builder = DiscordEmbedBuilder()
|
||||
builder.Color <- Optional(DiscordColor.PhthaloGreen)
|
||||
builder.Description <- message
|
||||
let author = DiscordEmbedBuilder.EmbedAuthor()
|
||||
author.Name <- "Joebot Pro"
|
||||
author.Url <- "https://ferano.io"
|
||||
author.IconUrl <- "https://i.kym-cdn.com/entries/icons/original/000/028/861/cover3.jpg"
|
||||
builder.Author <- author
|
||||
builder.Build()
|
||||
|
||||
type JoeBot() =
|
||||
inherit ApplicationCommandModule ()
|
||||
|
||||
@ -132,18 +147,23 @@ type JoeBot() =
|
||||
:> Task
|
||||
|
||||
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
||||
member this.Attack (ctx : InteractionContext, [<Option("player", "The player you want to hack")>] player : DiscordUser) =
|
||||
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
||||
// TODO: We need to check if the player has any active hacks going, if not they can cheat
|
||||
players
|
||||
|> List.tryFind (fun p -> p.DiscordId = ctx.Member.Id)
|
||||
|> function
|
||||
| Some player ->
|
||||
let updatedAttacks = removeExpiredActions (TimeSpan.FromMinutes(5)) (fun (atk : Attack) -> atk.Timestamp) player.Attacks
|
||||
if updatedAttacks.Length <= 3 then
|
||||
let updatedAttacks = removeExpiredActions (TimeSpan.FromMinutes(15)) (fun (atk : Attack) -> atk.Timestamp) player.Attacks
|
||||
players <-
|
||||
players
|
||||
|> List.map (fun p -> if p.DiscordId = player.DiscordId then { p with Attacks = updatedAttacks } else p)
|
||||
if updatedAttacks.Length < 1 then
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.AddEmbed (this.Embed("Pick the hack you wish to use. ")) |> ignore
|
||||
builder.AddEmbed (constructEmbed "Pick the hack you wish to use.") |> ignore
|
||||
|
||||
constructButtons "Attack" player.DiscordId player.Hacks
|
||||
let targetInfo = $"{target.Id}-{target.Username}"
|
||||
constructButtons "Attack" targetInfo player.Hacks
|
||||
|> Seq.cast<DiscordComponent>
|
||||
|> builder.AddComponents
|
||||
|> ignore
|
||||
@ -158,7 +178,8 @@ type JoeBot() =
|
||||
else
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.Content <- "You have no more hacks available, please wait for another hack to cooldown"
|
||||
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - updatedAttacks.Head.Timestamp)
|
||||
builder.Content <- $"You already hacked, please wait {timeRemaining.Minutes} minutes and {timeRemaining.Seconds} seconds to attempt another hack"
|
||||
|
||||
builder.AsEphemeral true |> ignore
|
||||
|
||||
@ -171,16 +192,20 @@ type JoeBot() =
|
||||
|
||||
|
||||
[<SlashCommand("defend", "Create a passive defense that will last a certain amount of time")>]
|
||||
member this.Defend (ctx : InteractionContext) =
|
||||
member this.DefendCommand (ctx : InteractionContext) =
|
||||
players
|
||||
|> List.tryFind (fun p -> p.DiscordId = ctx.Member.Id)
|
||||
|> function
|
||||
| Some player ->
|
||||
async {
|
||||
let updatedDefenses = removeExpiredActions (TimeSpan.FromMinutes(60)) (fun (pro : Defense) -> pro.Timestamp) player.Defenses
|
||||
players <-
|
||||
players
|
||||
|> List.map (fun p -> if p.DiscordId = player.DiscordId then { p with Defenses = updatedDefenses } else p)
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.AddEmbed (this.Embed("Pick a defense to mount for a duration of time")) |> ignore
|
||||
builder.AddEmbed (constructEmbed "Pick a defense to mount for a duration of time") |> ignore
|
||||
|
||||
constructButtons "Defense" player.DiscordId player.Protections
|
||||
constructButtons "Defense" (string player.DiscordId) player.Protections
|
||||
|> Seq.cast<DiscordComponent>
|
||||
|> builder.AddComponents
|
||||
|> ignore
|
||||
@ -194,36 +219,27 @@ type JoeBot() =
|
||||
:> Task
|
||||
| None -> notRegisteredYetMessage ctx
|
||||
|
||||
member _.Embed message =
|
||||
let builder = DiscordEmbedBuilder()
|
||||
builder.Color <- Optional(DiscordColor.PhthaloGreen)
|
||||
builder.Description <- message
|
||||
let author = DiscordEmbedBuilder.EmbedAuthor()
|
||||
author.Name <- "Joebot Pro"
|
||||
author.Url <- "https://ferano.io"
|
||||
author.IconUrl <- "https://i.kym-cdn.com/entries/icons/original/000/028/861/cover3.jpg"
|
||||
builder.Author <- author
|
||||
builder.Build()
|
||||
|
||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
let split = event.Id.Split("-")
|
||||
let ( resultHack , hackType ) = Enum.TryParse(typedefof<Hack>, split.[1])
|
||||
let ( resultId , target ) = UInt64.TryParse split.[2]
|
||||
let ( resultId , targetId ) = UInt64.TryParse split.[2]
|
||||
match resultHack , resultId with
|
||||
| true , true ->
|
||||
let hackType = hackType :?> Hack
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- $"Hack has been sent to {target}!"
|
||||
builder.Content <- $"Sent {hackType} to {split.[3]}!"
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let attack = { HackType = hackType ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||
players <-
|
||||
players
|
||||
|> List.map (fun p -> { p with Attacks = { HackType = hackType :?> Hack ; Timestamp = DateTime.UtcNow }::p.Attacks })
|
||||
|> List.map (fun p -> if p.DiscordId = event.User.Id then { p with Attacks = attack::p.Attacks } else p)
|
||||
|
||||
let builder = DiscordMessageBuilder()
|
||||
builder.WithContent($"{event.User.Username} has sent a hack to <@{target}>") |> ignore
|
||||
builder.WithContent($"{event.User.Username} has sent a hack to <@{targetId}>") |> ignore
|
||||
let battleChannel = (event.Guild.GetChannel(927449884204867664uL))
|
||||
do! battleChannel.SendMessageAsync(builder)
|
||||
|> Async.AwaitTask
|
||||
@ -239,16 +255,21 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
let split = event.Id.Split("-")
|
||||
let ( resultHack , hackType ) = Enum.TryParse(typedefof<Hack>, split.[1])
|
||||
let ( resultId , target ) = UInt64.TryParse split.[2]
|
||||
match resultHack , resultId with
|
||||
| true , true ->
|
||||
let ( resultHack , protectionType ) = Enum.TryParse(typedefof<Protection>, split.[1])
|
||||
match resultHack with
|
||||
| true ->
|
||||
let protectionType = protectionType :?> Protection
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- $"Hack has been sent to your target!"
|
||||
builder.Content <- $"Mounted a {protectionType} defense for 1 hour"
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let defense = { DefenseType = protectionType ; Timestamp = DateTime.UtcNow }
|
||||
players <-
|
||||
players
|
||||
|> List.map (fun p -> { p with Defenses = defense::p.Defenses })
|
||||
|
||||
let builder = DiscordMessageBuilder()
|
||||
builder.WithContent($"{event.User.Username} has protected their system!") |> ignore
|
||||
let battleChannel = (event.Guild.GetChannel(927449884204867664uL))
|
||||
@ -265,7 +286,7 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
|
||||
let handleButtonEvent (client : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
return match event.Id with
|
||||
return! match event.Id with
|
||||
| id when id.StartsWith("Attack") -> handleAttack event
|
||||
| id when id.StartsWith("Defend") -> handleDefense event
|
||||
| _ -> async { return () }
|
||||
|
Loading…
x
Reference in New Issue
Block a user