Redoing trainer flow and adding GuildEnvironment module
This commit is contained in:
parent
5261713735
commit
ff513331c6
@ -4,64 +4,53 @@ open System
|
|||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
open DSharpPlus
|
open DSharpPlus
|
||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
|
open Degenz
|
||||||
open Degenz.PlayerInteractions
|
open Degenz.PlayerInteractions
|
||||||
open Degenz.SlotMachine
|
//open Degenz.SlotMachine
|
||||||
open Degenz.Trainer
|
|
||||||
open Degenz.HackerBattle
|
open Degenz.HackerBattle
|
||||||
open Degenz.Store
|
open Degenz.Store
|
||||||
open Emzi0767.Utilities
|
open Emzi0767.Utilities
|
||||||
open dotenv.net
|
|
||||||
|
|
||||||
|
|
||||||
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
|
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
|
||||||
|
|
||||||
let playerInteractionsConfig = DiscordConfiguration()
|
let playerInteractionsConfig = DiscordConfiguration()
|
||||||
let trainerConfig = DiscordConfiguration()
|
|
||||||
let hackerBattleConfig = DiscordConfiguration()
|
let hackerBattleConfig = DiscordConfiguration()
|
||||||
let storeConfig = DiscordConfiguration()
|
let storeConfig = DiscordConfiguration()
|
||||||
//let slotMachineConfig = DiscordConfiguration()
|
//let slotMachineConfig = DiscordConfiguration()
|
||||||
|
//config.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace
|
||||||
|
|
||||||
//let configs = [| playerInteractionsConfig ; trainerConfig ; hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
|
//let configs = [| playerInteractionsConfig ; hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
|
||||||
let configs = [| playerInteractionsConfig ; trainerConfig ; hackerBattleConfig ; storeConfig |]
|
let configs = [| playerInteractionsConfig ; hackerBattleConfig ; storeConfig |]
|
||||||
|
|
||||||
for conf in configs do
|
for conf in configs do
|
||||||
conf.TokenType <- TokenType.Bot
|
conf.TokenType <- TokenType.Bot
|
||||||
conf.Intents <- DiscordIntents.All
|
conf.Intents <- DiscordIntents.All
|
||||||
|
|
||||||
|
|
||||||
DotEnv.Load(DotEnvOptions(probeForEnv = true, probeLevelsToSearch = 5, overwriteExistingVars = false))
|
let guild = GuildEnvironment.guildId
|
||||||
|
|
||||||
let guild = Environment.GetEnvironmentVariable("DISCORD_GUILD") |> uint64
|
playerInteractionsConfig.Token <- GuildEnvironment.tokenPlayerInteractions
|
||||||
|
hackerBattleConfig.Token <- GuildEnvironment.tokenHackerBattle
|
||||||
playerInteractionsConfig.Token <- Environment.GetEnvironmentVariable("BOT_PLAYER_INTERACTIONS")
|
storeConfig.Token <- GuildEnvironment.tokenStore
|
||||||
trainerConfig.Token <- Environment.GetEnvironmentVariable("BOT_TRAINER")
|
|
||||||
hackerBattleConfig.Token <- Environment.GetEnvironmentVariable("BOT_HACKER_BATTLE")
|
|
||||||
storeConfig.Token <- Environment.GetEnvironmentVariable("BOT_STORE")
|
|
||||||
//slotMachineConfig.Token <- Environment.GetEnvironmentVariable("BOT_SLOT_MACHINE")
|
//slotMachineConfig.Token <- Environment.GetEnvironmentVariable("BOT_SLOT_MACHINE")
|
||||||
|
|
||||||
//config.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace
|
|
||||||
|
|
||||||
let playerInteractionsBot = new DiscordClient(playerInteractionsConfig)
|
let playerInteractionsBot = new DiscordClient(playerInteractionsConfig)
|
||||||
let trainerBot = new DiscordClient(trainerConfig)
|
|
||||||
let hackerBattleBot = new DiscordClient(hackerBattleConfig)
|
let hackerBattleBot = new DiscordClient(hackerBattleConfig)
|
||||||
let storeBot = new DiscordClient(storeConfig)
|
let storeBot = new DiscordClient(storeConfig)
|
||||||
//let slotMachineBot = new DiscordClient(slotMachineConfig)
|
//let slotMachineBot = new DiscordClient(slotMachineConfig)
|
||||||
|
|
||||||
hackerBattleBot.add_ComponentInteractionCreated(AsyncEventHandler(HackerBattle.handleButtonEvent))
|
hackerBattleBot.add_ComponentInteractionCreated(AsyncEventHandler(HackerBattle.handleButtonEvent))
|
||||||
trainerBot.add_ComponentInteractionCreated(AsyncEventHandler(Trainer.handleButtonEvent))
|
|
||||||
storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleSellButtonEvents))
|
storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleSellButtonEvents))
|
||||||
|
|
||||||
//let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot ; slotMachineBot |]
|
//let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot ; slotMachineBot |]
|
||||||
let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot |]
|
let clients = [| storeBot ; hackerBattleBot ; playerInteractionsBot |]
|
||||||
|
|
||||||
let sc1 = playerInteractionsBot.UseSlashCommands()
|
let sc1 = playerInteractionsBot.UseSlashCommands()
|
||||||
let sc2 = trainerBot.UseSlashCommands()
|
|
||||||
let sc3 = hackerBattleBot.UseSlashCommands()
|
let sc3 = hackerBattleBot.UseSlashCommands()
|
||||||
let sc4 = storeBot.UseSlashCommands()
|
let sc4 = storeBot.UseSlashCommands()
|
||||||
//let sc5 = slotMachineBot.UseSlashCommands()
|
//let sc5 = slotMachineBot.UseSlashCommands()
|
||||||
|
|
||||||
sc1.RegisterCommands<PlayerInteractions>(guild);
|
sc1.RegisterCommands<PlayerInteractions>(guild);
|
||||||
sc2.RegisterCommands<Trainer>(guild);
|
|
||||||
sc3.RegisterCommands<HackerGame>(guild);
|
sc3.RegisterCommands<HackerGame>(guild);
|
||||||
sc4.RegisterCommands<Store>(guild);
|
sc4.RegisterCommands<Store>(guild);
|
||||||
//sc5.RegisterCommands<SlotMachine>(guild);
|
//sc5.RegisterCommands<SlotMachine>(guild);
|
||||||
|
19
PlayerInteractions/GuildEnvironment.fs
Normal file
19
PlayerInteractions/GuildEnvironment.fs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[<Microsoft.FSharp.Core.RequireQualifiedAccess>]
|
||||||
|
module Degenz.GuildEnvironment
|
||||||
|
|
||||||
|
open System
|
||||||
|
open dotenv.net
|
||||||
|
|
||||||
|
DotEnv.Load(DotEnvOptions(probeForEnv = true, probeLevelsToSearch = 5, overwriteExistingVars = false))
|
||||||
|
|
||||||
|
let getVar str = Environment.GetEnvironmentVariable(str)
|
||||||
|
let getId str = getVar str |> uint64
|
||||||
|
|
||||||
|
let guildId = getId "DISCORD_GUILD"
|
||||||
|
let tokenPlayerInteractions = getVar "TOKEN_PLAYER_INTERACTIONS"
|
||||||
|
let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE"
|
||||||
|
let tokenStore = getVar "TOKEN_STORE"
|
||||||
|
let eventsChannelHackerBattle = getId "EVENTS_CHANNEL_HACKER_BATTLE"
|
||||||
|
let channelTraining = getId "CHANNEL_TRAINING"
|
||||||
|
let botHackerBattle = getId "BOT_HACKER_BATTLE"
|
||||||
|
let roleTrainee = getId "ROLE_TRAINEE"
|
@ -9,12 +9,6 @@ open DSharpPlus.SlashCommands
|
|||||||
open Degenz
|
open Degenz
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
|
|
||||||
[<Literal>]
|
|
||||||
// Degenz Server
|
|
||||||
//let battleChannel = 930363007781978142uL
|
|
||||||
// My server
|
|
||||||
let battleChannel = 927449884204867664uL
|
|
||||||
|
|
||||||
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||||
async {
|
async {
|
||||||
// TODO: We need to check if the player has any active embed hacks going, if not they can cheat
|
// TODO: We need to check if the player has any active embed hacks going, if not they can cheat
|
||||||
@ -133,7 +127,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
|||||||
|
|
||||||
let builder = DiscordMessageBuilder()
|
let builder = DiscordMessageBuilder()
|
||||||
builder.WithContent($"{event.User.Username} successfully hacked <@{targetId}> for a total of {prize} GoodBoyTokenz") |> ignore
|
builder.WithContent($"{event.User.Username} successfully hacked <@{targetId}> for a total of {prize} GoodBoyTokenz") |> ignore
|
||||||
let channel = (event.Guild.GetChannel(battleChannel))
|
let channel = (event.Guild.GetChannel(GuildEnvironment.eventsChannelHackerBattle))
|
||||||
do! channel.SendMessageAsync(builder)
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
@ -151,7 +145,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
|||||||
|
|
||||||
let builder = DiscordMessageBuilder()
|
let builder = DiscordMessageBuilder()
|
||||||
builder.WithContent($"Hacking attempt failed! <@{targetId}> defended hack from {event.User.Username} and took {prize} from them! ") |> ignore
|
builder.WithContent($"Hacking attempt failed! <@{targetId}> defended hack from {event.User.Username} and took {prize} from them! ") |> ignore
|
||||||
let channel = (event.Guild.GetChannel(battleChannel))
|
let channel = (event.Guild.GetChannel(GuildEnvironment.eventsChannelHackerBattle))
|
||||||
do! channel.SendMessageAsync(builder)
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
@ -194,18 +188,21 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
let task =
|
||||||
|
match event.Id with
|
||||||
|
| id when id.StartsWith("Attack") -> handleAttack event
|
||||||
|
| id when id.StartsWith("Defend") -> handleDefense event
|
||||||
|
| id when id.StartsWith("Trainer") -> Trainer.handleButtonEvent event
|
||||||
|
| _ ->
|
||||||
|
async {
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- $"Incorrect Action identifier {event.Id}"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
}
|
||||||
async {
|
async {
|
||||||
return! match event.Id with
|
return! task
|
||||||
| id when id.StartsWith("Attack") -> handleAttack event
|
|
||||||
| id when id.StartsWith("Defend") -> handleDefense event
|
|
||||||
| _ ->
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Incorrect Action identifier {event.Id}"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
}
|
|
||||||
} |> Async.StartAsTask
|
} |> Async.StartAsTask
|
||||||
:> Task
|
:> Task
|
||||||
|
|
||||||
@ -214,9 +211,18 @@ type HackerGame() =
|
|||||||
|
|
||||||
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
||||||
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
||||||
attack ctx target
|
let hasTraineeRole = Seq.exists (fun (r : DiscordRole) -> r.Name = "trainee") ctx.Member.Roles
|
||||||
|
if ctx.Channel.Name = "training-dojo" && hasTraineeRole then
|
||||||
|
Trainer.attack ctx target
|
||||||
|
else
|
||||||
|
attack ctx target
|
||||||
|
|
||||||
[<SlashCommand("defend", "Create a passive defense that will last 24 hours")>]
|
[<SlashCommand("defend", "Create a passive defense that will last 24 hours")>]
|
||||||
member this.DefendCommand (ctx : InteractionContext) = defend ctx
|
member this.DefendCommand (ctx : InteractionContext) =
|
||||||
|
let hasTraineeRole = Seq.exists (fun (r : DiscordRole) -> r.Name = "Trainee") ctx.Member.Roles
|
||||||
|
if ctx.Channel.Name = "training-dojo" && hasTraineeRole then
|
||||||
|
Trainer.defend ctx
|
||||||
|
else
|
||||||
|
defend ctx
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,16 +7,17 @@
|
|||||||
<RootNamespace>PlayerRegistration</RootNamespace>
|
<RootNamespace>PlayerRegistration</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="paket.references" />
|
|
||||||
<Compile Include="Store.fs" />
|
|
||||||
<Compile Include="HackerBattle.fs" />
|
|
||||||
<Compile Include="SlotMachine.fs" />
|
|
||||||
<Compile Include="Trainer.fs" />
|
|
||||||
<Compile Include="PlayerInteractions.fs" />
|
|
||||||
<Compile Include="Bot.fs" />
|
|
||||||
<Content Include="Items.json">
|
<Content Include="Items.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="paket.references" />
|
||||||
|
<Compile Include="GuildEnvironment.fs" />
|
||||||
|
<Compile Include="Store.fs" />
|
||||||
|
<Compile Include="Trainer.fs" />
|
||||||
|
<Compile Include="HackerBattle.fs" />
|
||||||
|
<Compile Include="SlotMachine.fs" />
|
||||||
|
<Compile Include="PlayerInteractions.fs" />
|
||||||
|
<Compile Include="Bot.fs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\DbService\DbService.fsproj" />
|
<ProjectReference Include="..\DbService\DbService.fsproj" />
|
||||||
|
@ -7,37 +7,114 @@ open DSharpPlus.EventArgs
|
|||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
|
|
||||||
let sendMessage (event : ComponentInteractionCreateEventArgs) msg =
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
let sendInitialEmbed (client : DiscordClient) =
|
||||||
async {
|
async {
|
||||||
let builder = DiscordFollowupMessageBuilder()
|
let! channel = client.GetChannelAsync(GuildEnvironment.channelTraining) |> Async.AwaitTask
|
||||||
builder.IsEphemeral <- true
|
let builder = DiscordMessageBuilder()
|
||||||
builder.Content <- msg
|
builder.Content <- "Welcome to the hacker dojo you degenerate, are you ready to get started?"
|
||||||
do! event.Interaction.CreateFollowupMessageAsync(builder)
|
let button = DiscordButtonComponent(ButtonStyle.Success, $"Trainer-1", $"Get started") :> DiscordComponent
|
||||||
|
builder.AddComponents [| button |] |> ignore
|
||||||
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
do! Async.Sleep 4000
|
} |> Async.RunSynchronously
|
||||||
|
|
||||||
|
let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
async {
|
||||||
|
let msg = "First time, eh? Beautopia is a dangerous place. I'm going to teach you how to protect yourself from other degenerates. "
|
||||||
|
+ "And in the process, I'll also show you how to hack some sheeple, so you can earn some cash."
|
||||||
|
do! Message.sendInteractionEventWithButton event "Trainer-2" msg
|
||||||
|
|
||||||
|
let! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask
|
||||||
|
let role = event.Guild.GetRole(GuildEnvironment.roleTrainee)
|
||||||
|
do! membr.GrantRoleAsync(role) |> Async.AwaitTask
|
||||||
}
|
}
|
||||||
|
|
||||||
let handleInitialDialog (event : ComponentInteractionCreateEventArgs) =
|
let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
|
||||||
let sendMessage' = sendMessage event
|
|
||||||
async {
|
async {
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
|
|
||||||
let! result = DbService.tryFindPlayer event.User.Id
|
let! result = DbService.tryFindPlayer event.User.Id
|
||||||
match result with
|
match result with
|
||||||
| Some player ->
|
| 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
|
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}'"
|
do! Message.sendFollowUpMessage event
|
||||||
|
($"First things first, let's get your system protected. Let's enable a shield to protect you from potential hackers. "
|
||||||
|
+ $"You currently have {weaponName} in your arsenal. To enable it and protect your system, you can use the `/defend` slash command to choose a shield."
|
||||||
|
+ $"\n\nRun the `/defend` command now and then select '{weaponName}'.")
|
||||||
| None ->
|
| None ->
|
||||||
do! sendMessage' $"Something went wrong, please contact a moderator"
|
do! Message.sendFollowUpMessage event $"Something went wrong, please contact a moderator"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let defend (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 8 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
|
||||||
|
|
||||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||||
let sendMessage' = sendMessage event
|
let sendMessage' = Message.sendFollowUpMessage event
|
||||||
async {
|
async {
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
@ -48,112 +125,102 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
|||||||
do! sendMessage' $"{event.User.Username} has protected their system!"
|
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' "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' $"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"
|
let msg = ("I wasn't able to hack you. Great job! Because you had your system protected when I tried to hack you, you took some money from me. "
|
||||||
do! sendMessage' "But you can make even more by successfully hacking your target. Why don't you try hacking me?"
|
+ "Shields only protect you for a certain amount of time, so remember to keep your system protected at all times.")
|
||||||
let weaponName = player.Weapons |> Array.tryHead |> Option.defaultValue Hack.Virus
|
do! Message.sendFollowUpMessageWithButton event "Trainer-3" msg
|
||||||
do! sendMessage' $"You currently have {weaponName} equipped. To attempt a hack, type the '/hack' command and select {weaponName}."
|
|
||||||
| None ->
|
| None ->
|
||||||
do! sendMessage' $"Something went wrong, please contact a moderator"
|
do! sendMessage' $"Something went wrong, please contact a moderator"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let handleTrainerStep3 (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
async {
|
||||||
|
let! result = DbService.tryFindPlayer event.User.Id
|
||||||
|
match result with
|
||||||
|
| Some player ->
|
||||||
|
// TODO: There's a potential bug here where if the player sold their weapons, they'll get stuck
|
||||||
|
let weaponName = player.Weapons |> Array.tryHead |> Option.defaultValue Hack.Virus
|
||||||
|
do! Message.sendFollowUpMessage event
|
||||||
|
($"Next why don't you try hacking me. You currently have {weaponName} equipped. To hack me and get some money, "
|
||||||
|
+ $" you can use the '/hack' slash command and select a user to hack, then choose the hack attack you wish to use."
|
||||||
|
+ $"\n\nRun the `/hack` command now and pick me as your target, then click on the '{weaponName}' button.")
|
||||||
|
| None ->
|
||||||
|
do! Message.sendFollowUpMessage event $"Something went wrong, please contact a moderator"
|
||||||
|
}
|
||||||
|
|
||||||
|
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||||
|
async {
|
||||||
|
let isRightTarget = target.Id = GuildEnvironment.botHackerBattle
|
||||||
|
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||||
|
match isRightTarget , playerResult with
|
||||||
|
| true , 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
|
||||||
|
| false , _ ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.Content <- "You picked the wrong target, you dufus. Try again, this time pick me!"
|
||||||
|
|
||||||
|
builder.AsEphemeral true |> ignore
|
||||||
|
|
||||||
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
| _ ->
|
||||||
|
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 handleAttack (event : ComponentInteractionCreateEventArgs) =
|
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||||
let sendMessage' = sendMessage event
|
let sendMessage' = Message.sendFollowUpMessage event
|
||||||
async {
|
async {
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
let! result = DbService.tryFindPlayer event.User.Id
|
let! result = DbService.tryFindPlayer event.User.Id
|
||||||
match result with
|
match result with
|
||||||
| Some player ->
|
| Some player ->
|
||||||
let prize = 1.337f // LEET
|
let prize = 2
|
||||||
do! sendMessage' $"{player.Name} successfully hacked Degenz-Trainer for a total of {prize} GoodBoyTokenz"
|
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' ("Look at that, you are now officially an elite haxor! By successfully hacking other people you can earn 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."
|
+ "Hacks take time to recover so check back in later once you've used all your hacks.")
|
||||||
do! sendMessage' "Alright you degenerate, off you go!"
|
let msg = ("I think we're done. You are going to need more hacks and shields if you want to survive in this crazy world. "
|
||||||
|
+ "Remember to go check out the store and purchase whatever you need to add to your arsenal."
|
||||||
|
+ "\n\nAlright you degenerate, off you go!")
|
||||||
|
do! Message.sendFollowUpMessageWithButton event "Trainer-4" msg
|
||||||
| None ->
|
| None ->
|
||||||
do! sendMessage' $"Something went wrong, please contact a moderator"
|
do! sendMessage' $"Something went wrong, please contact a moderator"
|
||||||
}
|
}
|
||||||
|
|
||||||
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
async {
|
||||||
|
let! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask
|
||||||
|
let role = event.Guild.GetRole(GuildEnvironment.roleTrainee)
|
||||||
|
do! membr.RevokeRoleAsync(role) |> Async.AwaitTask
|
||||||
|
}
|
||||||
|
|
||||||
|
let handleButtonEvent (event : ComponentInteractionCreateEventArgs) =
|
||||||
async {
|
async {
|
||||||
match event.Id with
|
match event.Id with
|
||||||
| id when id.StartsWith("Trainer") -> do! handleInitialDialog event
|
| id when id.StartsWith("Trainer") ->
|
||||||
| id when id.StartsWith("Defend") -> do! handleDefense event
|
let split = id.Split("-")
|
||||||
| id when id.StartsWith("Attack") -> do! handleAttack event
|
match int split.[1] with
|
||||||
| _ -> do! sendMessage event "No action found"
|
| 1 -> do! handleTrainerStep1 event
|
||||||
|
| 2 -> do! handleTrainerStep2 event
|
||||||
|
| 3 -> do! handleTrainerStep3 event
|
||||||
|
| _ -> do! Message.sendFollowUpMessage event "No action found"
|
||||||
|
| _ -> do! Message.sendFollowUpMessage event "No action found"
|
||||||
}
|
}
|
||||||
|> Async.StartAsTask
|
|
||||||
:> Task
|
|
||||||
|
|
||||||
let sendInitialEmbed (client : DiscordClient) =
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
FSharp.Core
|
FSharp.Core
|
||||||
DSharpPlus
|
DSharpPlus
|
||||||
|
DSharpPlus.Interactivity
|
||||||
DSharpPlus.SlashCommands
|
DSharpPlus.SlashCommands
|
||||||
dotenv.net
|
dotenv.net
|
||||||
DanielStout.AsciiTableFormatter
|
DanielStout.AsciiTableFormatter
|
||||||
|
@ -7,7 +7,8 @@ nuget FSharp.Core >= 6.0.0
|
|||||||
|
|
||||||
source https://nuget.emzi0767.com/api/v3/index.json
|
source https://nuget.emzi0767.com/api/v3/index.json
|
||||||
|
|
||||||
nuget DSharpPlus >= 4.2.0-nightly-01054
|
nuget DSharpPlus >= 4.2.0-nightly-01061
|
||||||
|
nuget DSharpPlus.Interactivity >= 4.2.0-nightly-01061
|
||||||
nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01061
|
nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01061
|
||||||
|
|
||||||
nuget MongoDB.Driver
|
nuget MongoDB.Driver
|
||||||
|
@ -2,6 +2,7 @@ STORAGE: NONE
|
|||||||
RESTRICTION: || (== net6.0) (== netstandard2.0) (== netstandard2.1)
|
RESTRICTION: || (== net6.0) (== netstandard2.0) (== netstandard2.1)
|
||||||
NUGET
|
NUGET
|
||||||
remote: https://api.nuget.org/v3/index.json
|
remote: https://api.nuget.org/v3/index.json
|
||||||
|
ConcurrentHashSet (1.3)
|
||||||
DanielStout.AsciiTableFormatter (1.1)
|
DanielStout.AsciiTableFormatter (1.1)
|
||||||
DnsClient (1.5)
|
DnsClient (1.5)
|
||||||
Microsoft.Win32.Registry (>= 5.0)
|
Microsoft.Win32.Registry (>= 5.0)
|
||||||
@ -481,6 +482,9 @@ NUGET
|
|||||||
System.Net.WebSockets.Client (>= 4.3.2)
|
System.Net.WebSockets.Client (>= 4.3.2)
|
||||||
System.Runtime.InteropServices.RuntimeInformation (>= 4.3)
|
System.Runtime.InteropServices.RuntimeInformation (>= 4.3)
|
||||||
System.Threading.Channels (>= 5.0)
|
System.Threading.Channels (>= 5.0)
|
||||||
|
DSharpPlus.Interactivity (4.2.0-nightly-01061)
|
||||||
|
ConcurrentHashSet (>= 1.1)
|
||||||
|
DSharpPlus (>= 4.2.0-nightly-01061)
|
||||||
DSharpPlus.SlashCommands (4.2.0-nightly-01061)
|
DSharpPlus.SlashCommands (4.2.0-nightly-01061)
|
||||||
DSharpPlus (>= 4.2.0-nightly-01061)
|
DSharpPlus (>= 4.2.0-nightly-01061)
|
||||||
Microsoft.Extensions.DependencyInjection (>= 5.0.1)
|
Microsoft.Extensions.DependencyInjection (>= 5.0.1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user