Finishing new trainer flow

This commit is contained in:
Joseph Ferano 2022-01-22 14:13:24 +07:00
parent ff513331c6
commit a4d9926cfa
11 changed files with 47 additions and 33 deletions

View File

@ -17,7 +17,7 @@ let playerInteractionsConfig = 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 //hackerBattleConfig.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace
//let configs = [| playerInteractionsConfig ; hackerBattleConfig ; storeConfig ; slotMachineConfig ; |] //let configs = [| playerInteractionsConfig ; hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
let configs = [| playerInteractionsConfig ; hackerBattleConfig ; storeConfig |] let configs = [| playerInteractionsConfig ; hackerBattleConfig ; storeConfig |]
@ -39,9 +39,6 @@ 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))
storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleSellButtonEvents))
//let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot ; slotMachineBot |] //let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot ; slotMachineBot |]
let clients = [| storeBot ; hackerBattleBot ; playerInteractionsBot |] let clients = [| storeBot ; hackerBattleBot ; playerInteractionsBot |]
@ -55,11 +52,16 @@ sc3.RegisterCommands<HackerGame>(guild);
sc4.RegisterCommands<Store>(guild); sc4.RegisterCommands<Store>(guild);
//sc5.RegisterCommands<SlotMachine>(guild); //sc5.RegisterCommands<SlotMachine>(guild);
hackerBattleBot.add_ComponentInteractionCreated(AsyncEventHandler(HackerBattle.handleButtonEvent))
storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleSellButtonEvents))
let run (client : DiscordClient) = let run (client : DiscordClient) =
async { async {
do! client.ConnectAsync () |> Async.AwaitTask do! client.ConnectAsync () |> Async.AwaitTask
} }
Trainer.sendInitialEmbed hackerBattleBot
clients clients
|> Array.map run |> Array.map run
|> Array.toSeq |> Array.toSeq

View File

@ -13,7 +13,7 @@ let guildId = getId "DISCORD_GUILD"
let tokenPlayerInteractions = getVar "TOKEN_PLAYER_INTERACTIONS" let tokenPlayerInteractions = getVar "TOKEN_PLAYER_INTERACTIONS"
let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE" let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE"
let tokenStore = getVar "TOKEN_STORE" let tokenStore = getVar "TOKEN_STORE"
let eventsChannelHackerBattle = getId "EVENTS_CHANNEL_HACKER_BATTLE" let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE"
let channelTraining = getId "CHANNEL_TRAINING" let channelTraining = getId "CHANNEL_TRAINING"
let botHackerBattle = getId "BOT_HACKER_BATTLE" let botHackerBattle = getId "BOT_HACKER_BATTLE"
let roleTrainee = getId "ROLE_TRAINEE" let roleTrainee = getId "ROLE_TRAINEE"

View File

@ -127,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(GuildEnvironment.eventsChannelHackerBattle)) let channel = (event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle))
do! channel.SendMessageAsync(builder) do! channel.SendMessageAsync(builder)
|> Async.AwaitTask |> Async.AwaitTask
|> Async.Ignore |> Async.Ignore
@ -145,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(GuildEnvironment.eventsChannelHackerBattle)) let channel = (event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle))
do! channel.SendMessageAsync(builder) do! channel.SendMessageAsync(builder)
|> Async.AwaitTask |> Async.AwaitTask
|> Async.Ignore |> Async.Ignore
@ -211,16 +211,16 @@ 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) =
let hasTraineeRole = Seq.exists (fun (r : DiscordRole) -> r.Name = "trainee") ctx.Member.Roles let hasTraineeRole = Seq.exists (fun (r : DiscordRole) -> r.Id = GuildEnvironment.roleTrainee) ctx.Member.Roles
if ctx.Channel.Name = "training-dojo" && hasTraineeRole then if ctx.Channel.Id = GuildEnvironment.channelTraining && hasTraineeRole then
Trainer.attack ctx target Trainer.attack ctx target
else else
attack ctx target 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) = member this.DefendCommand (ctx : InteractionContext) =
let hasTraineeRole = Seq.exists (fun (r : DiscordRole) -> r.Name = "Trainee") ctx.Member.Roles let hasTraineeRole = Seq.exists (fun (r : DiscordRole) -> r.Id = GuildEnvironment.roleTrainee) ctx.Member.Roles
if ctx.Channel.Name = "training-dojo" && hasTraineeRole then if ctx.Channel.Id = GuildEnvironment.channelTraining && hasTraineeRole then
Trainer.defend ctx Trainer.defend ctx
else else
defend ctx defend ctx

View File

@ -62,13 +62,15 @@ let sendInitialEmbed (client : DiscordClient) =
let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) = let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) =
async { 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! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask
let role = event.Guild.GetRole(GuildEnvironment.roleTrainee) let role = event.Guild.GetRole(GuildEnvironment.roleTrainee)
do! membr.GrantRoleAsync(role) |> Async.AwaitTask do! membr.GrantRoleAsync(role) |> Async.AwaitTask
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|> Async.AwaitTask
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.sendFollowUpMessageWithButton event "Trainer-2" msg
} }
let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) = let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
@ -77,7 +79,7 @@ let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
match result with match result with
| Some player -> | Some player ->
let weaponName = player.Shields |> Array.tryHead |> Option.defaultValue Shield.Firewall let weaponName = player.Shields |> Array.tryHead |> Option.defaultValue Shield.Firewall
do! Message.sendFollowUpMessage event do! Message.sendInteractionEvent event
($"First things first, let's get your system protected. Let's enable a shield to protect you from potential hackers. " ($"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." + $"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}'.") + $"\n\nRun the `/defend` command now and then select '{weaponName}'.")
@ -93,7 +95,7 @@ let defend (ctx : InteractionContext) =
let builder = DiscordInteractionResponseBuilder() let builder = DiscordInteractionResponseBuilder()
builder.AddEmbed (constructEmbed "Pick a defense to mount for 8 hours") |> ignore builder.AddEmbed (constructEmbed "Pick a defense to mount for 8 hours") |> ignore
constructButtons "Defend" (string player.DiscordId) player.Shields constructButtons "Trainer-3" (string player.DiscordId) player.Shields
|> Seq.cast<DiscordComponent> |> Seq.cast<DiscordComponent>
|> builder.AddComponents |> builder.AddComponents
|> ignore |> ignore
@ -123,28 +125,31 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
| Some player -> | Some player ->
let prize = 0.223f let prize = 0.223f
do! sendMessage' $"{event.User.Username} has protected their system!" do! sendMessage' $"{event.User.Username} has protected their system!"
do! Async.Sleep 3000
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! Async.Sleep 4000
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! Async.Sleep 3000
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. " 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. "
+ "Shields only protect you for a certain amount of time, so remember to keep your system protected at all times.") + "Shields only protect you for a certain amount of time, so remember to keep your system protected at all times.")
do! Message.sendFollowUpMessageWithButton event "Trainer-3" msg 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 handleTrainerStep3 (event : ComponentInteractionCreateEventArgs) = let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) =
async { async {
let! result = DbService.tryFindPlayer event.User.Id let! result = DbService.tryFindPlayer event.User.Id
match result with match result with
| Some player -> | Some player ->
// TODO: There's a potential bug here where if the player sold their weapons, they'll get stuck // 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 let weaponName = player.Weapons |> Array.tryHead |> Option.defaultValue Hack.Virus
do! Message.sendFollowUpMessage event do! Message.sendInteractionEvent event
($"Next why don't you try hacking me. You currently have {weaponName} equipped. To hack me and get some money, " ($"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." + $" 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.") + $"\n\nRun the `/hack` command now and pick me as your target, then click on the '{weaponName}' button.")
| None -> | None ->
do! Message.sendFollowUpMessage event $"Something went wrong, please contact a moderator" do! Message.sendInteractionEvent event $"Something went wrong, please contact a moderator"
} }
let attack (ctx : InteractionContext) (target : DiscordUser) = let attack (ctx : InteractionContext) (target : DiscordUser) =
@ -156,7 +161,7 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
let builder = DiscordInteractionResponseBuilder() let builder = DiscordInteractionResponseBuilder()
builder.AddEmbed (constructEmbed "Pick an attack to use on your target") |> ignore builder.AddEmbed (constructEmbed "Pick an attack to use on your target") |> ignore
constructButtons "Attack" (string player.DiscordId) player.Weapons constructButtons "Trainer-5" (string player.DiscordId) player.Weapons
|> Seq.cast<DiscordComponent> |> Seq.cast<DiscordComponent>
|> builder.AddComponents |> builder.AddComponents
|> ignore |> ignore
@ -194,33 +199,40 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
| Some player -> | Some player ->
let prize = 2 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! Async.Sleep 3000
do! sendMessage' ("Look at that, you are now officially an elite haxor! By successfully hacking other people you can earn GoodBoyTokenz. " do! sendMessage' ("Look at that, you are now officially an elite haxor! By successfully hacking other people you can earn GoodBoyTokenz. "
+ "Hacks take time to recover so check back in later once you've used all your hacks.") + "Hacks take time to recover so check back in later once you've used all your hacks.")
do! Async.Sleep 6000
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. " 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." + "Remember to go check out the store and purchase whatever you need to add to your arsenal."
+ "\n\nAlright you degenerate, off you go!") + "\n\nAlright you degenerate, off you go!")
do! Message.sendFollowUpMessageWithButton event "Trainer-4" msg do! Message.sendFollowUpMessageWithButton event "Trainer-6" msg
| None -> | None ->
do! sendMessage' $"Something went wrong, please contact a moderator" do! sendMessage' $"Something went wrong, please contact a moderator"
} }
let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) = let handleTrainerStep6 (event : ComponentInteractionCreateEventArgs) =
async { async {
let! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask let! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask
let role = event.Guild.GetRole(GuildEnvironment.roleTrainee) let role = event.Guild.GetRole(GuildEnvironment.roleTrainee)
do! membr.RevokeRoleAsync(role) |> Async.AwaitTask do! membr.RevokeRoleAsync(role) |> Async.AwaitTask
let builder = DiscordInteractionResponseBuilder()
builder.Content <- "Get out of here!"
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|> Async.AwaitTask
} }
let handleButtonEvent (event : ComponentInteractionCreateEventArgs) = let handleButtonEvent (event : ComponentInteractionCreateEventArgs) =
async { async {
match event.Id with let split = event.Id.Split("-")
| id when id.StartsWith("Trainer") ->
let split = id.Split("-")
match int split.[1] with match int split.[1] with
| 1 -> do! handleTrainerStep1 event | 1 -> do! handleTrainerStep1 event
| 2 -> do! handleTrainerStep2 event | 2 -> do! handleTrainerStep2 event
| 3 -> do! handleTrainerStep3 event | 3 -> do! handleDefense event
| _ -> do! Message.sendFollowUpMessage event "No action found" | 4 -> do! handleTrainerStep4 event
| 5 -> do! handleAttack event
| 6 -> do! handleTrainerStep6 event
| _ -> do! Message.sendFollowUpMessage event "No action found" | _ -> do! Message.sendFollowUpMessage event "No action found"
} }

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105 VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "PlayerInteractions", "PlayerInteractions\PlayerInteractions.fsproj", "{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}" Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Bot", "Bot\Bot.fsproj", "{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}"
EndProject EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "DbService", "DbService\DbService.fsproj", "{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}" Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "DbService", "DbService\DbService.fsproj", "{B1D3E1CC-451C-42D4-B054-D64E75E1A3B9}"
EndProject EndProject