193 lines
8.2 KiB
Forth

open System
open System.Threading.Tasks
open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.EventArgs
open DSharpPlus.SlashCommands
open DegenzGame
open DegenzGame.Shared
open Emzi0767.Utilities
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
type Trainer() =
inherit ApplicationCommandModule ()
[<SlashCommand("defend", "Create a passive defense that will last 24 hours")>]
member this.DefendCommand (ctx : InteractionContext) =
async {
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
match playerResult with
| Some player ->
let builder = DiscordInteractionResponseBuilder()
builder.AddEmbed (constructEmbed "Pick a defense to mount for 24 hours") |> ignore
constructButtons "Defend" (string player.DiscordId) player.Shields
|> Seq.cast<DiscordComponent>
|> builder.AddComponents
|> ignore
builder.AsEphemeral true |> ignore
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> 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
[<SlashCommand("hack", "Send a hack attack to another player")>]
member this.Attack (ctx : InteractionContext) =
async {
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
match playerResult with
| Some player ->
let builder = DiscordInteractionResponseBuilder()
builder.AddEmbed (constructEmbed "Pick an attack to use on your target") |> ignore
constructButtons "Attack" (string player.DiscordId) player.Weapons
|> Seq.cast<DiscordComponent>
|> builder.AddComponents
|> ignore
builder.AsEphemeral true |> ignore
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> 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 config = DiscordConfiguration()
config.Token <- "OTMzMDg4MTQyNDM5ODk5MTg4.YeccDQ.AbysjlHICgbNQVyduG6aGIHNpdE"
config.TokenType <- TokenType.Bot
config.Intents <- DiscordIntents.All
//config.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace
let client = new DiscordClient(config)
let slash = client.UseSlashCommands()
let sendMessage (event : ComponentInteractionCreateEventArgs) msg =
async {
let builder = DiscordFollowupMessageBuilder()
builder.IsEphemeral <- true
builder.Content <- msg
do! event.Interaction.CreateFollowupMessageAsync(builder)
|> Async.AwaitTask
|> Async.Ignore
do! Async.Sleep 4000
}
let handleInitialDialog (event : ComponentInteractionCreateEventArgs) =
let sendMessage' = sendMessage event
async {
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|> Async.AwaitTask
let! result = DbService.tryFindPlayer event.User.Id
match result with
| Some player ->
do! sendMessage' "The Degenz world is a dangerous place. I'm going to teach you how to protect yourself from other degenerates."
do! sendMessage' "And in the process, I'll also show you how to hack these sheeple, so you can earn some cash."
do! sendMessage' "First thing is first, let's get your system protected. Let's put up a shield."
let weaponName = player.Shields |> Array.tryHead |> Option.defaultValue Shield.Firewall
do! sendMessage' $"You currently have {weaponName} in your arsenal. To enable it and protect your system, run the `/defend` command and select '{weaponName}'"
| None ->
do! sendMessage' $"Something went wrong, please contact a moderator"
}
let handleDefense (event : ComponentInteractionCreateEventArgs) =
let sendMessage' = sendMessage event
async {
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|> Async.AwaitTask
let! result = DbService.tryFindPlayer event.User.Id
match result with
| Some player ->
let prize = 0.223f
do! sendMessage' $"{event.User.Username} has protected their system!"
do! sendMessage' "Ok, good, let me make sure that worked. I'll try to hack you now"
do! sendMessage' $"Hacking attempt failed! {player.Name} defended hack from Degenz-Trainer and took {prize} from them! "
do! sendMessage' "Great, I wasn't able to hack you. Great job! Because you had your system protected, when I tried to hack you, I lost some money and had to give it to you"
do! sendMessage' "But you can make even more by successfully hacking your target. Why don't you try hacking me?"
let weaponName = player.Weapons |> Array.tryHead |> Option.defaultValue Weapon.Virus
do! sendMessage' $"You currently have {weaponName} equipped. To attempt a hack, type the '/hack' command and select {weaponName}."
| None ->
do! sendMessage' $"Something went wrong, please contact a moderator"
}
let handleAttack (event : ComponentInteractionCreateEventArgs) =
let sendMessage' = sendMessage event
async {
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|> Async.AwaitTask
let! result = DbService.tryFindPlayer event.User.Id
match result with
| Some player ->
let prize = 1.337f // LEET
do! sendMessage' $"{player.Name} successfully hacked Degenz-Trainer for a total of {prize} GoodBoyTokenz"
do! sendMessage' "Looks like you got the hang of it. By successfully hacking other people you can earn some GoodBoyTokenz"
do! sendMessage' "I think we're done for now. If you wish to purchase more hacks or shields, you go to the store to purchase them."
do! sendMessage' "Alright you degenerate, off you go!"
| None ->
do! sendMessage' $"Something went wrong, please contact a moderator"
}
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
async {
match event.Id with
| id when id.StartsWith("Trainer") -> do! handleInitialDialog event
| id when id.StartsWith("Defend") -> do! handleDefense event
| id when id.StartsWith("Attack") -> do! handleAttack event
| _ -> do! sendMessage event "No action found"
}
|> Async.StartAsTask
:> Task
client.add_ComponentInteractionCreated(AsyncEventHandler(handleButtonEvent))
// My server
slash.RegisterCommands<Trainer>(922419263275425832uL);
// Degenz
//slash.RegisterCommands<HackerGame>(922414052708327494uL);
client.ConnectAsync ()
|> Async.AwaitTask
|> Async.RunSynchronously
async {
let! channel = client.GetChannelAsync(933298431521333258uL) |> Async.AwaitTask
let builder = DiscordMessageBuilder()
builder.Content <- "Welcome to the trainer bot, are you ready to get started?"
let button = DiscordButtonComponent(ButtonStyle.Success, $"Trainer-trainer-1", $"Get started") :> DiscordComponent
builder.AddComponents [| button |] |> ignore
do! channel.SendMessageAsync(builder)
|> Async.AwaitTask
|> Async.Ignore
} |> Async.RunSynchronously
Task.Delay(-1)
|> Async.AwaitTask
|> Async.RunSynchronously
client.DisconnectAsync ()
|> Async.AwaitTask
|> Async.RunSynchronously