Several improvements and enhacements

This commit is contained in:
Joseph Ferano 2022-02-08 23:33:30 +07:00
parent b12dfe6788
commit 8f8aebd6ac
7 changed files with 63 additions and 34 deletions

View File

@ -21,9 +21,11 @@ let storeConfig = DiscordConfiguration()
//let configs = [| hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
let configs = [ hackerBattleConfig ; storeConfig ]
for conf in configs do
conf.TokenType <- TokenType.Bot
conf.Intents <- DiscordIntents.All
hackerBattleConfig.TokenType <- TokenType.Bot
hackerBattleConfig.Intents <- DiscordIntents.All
storeConfig.TokenType <- TokenType.Bot
storeConfig.Intents <- DiscordIntents.All
hackerBattleConfig.Token <- GuildEnvironment.tokenHackerBattle
storeConfig.Token <- GuildEnvironment.tokenStore
@ -34,8 +36,6 @@ let storeBot = new DiscordClient(storeConfig)
//let slotMachineBot = new DiscordClient(slotMachineConfig)
//let clients = [| hackerBattleBot ; storeBot ; slotMachineBot |]
let clients = [ hackerBattleBot ; storeBot ]
let sc1 = hackerBattleBot.UseSlashCommands()
let sc2 = storeBot.UseSlashCommands()
//let sc3 = slotMachineBot.UseSlashCommands()
@ -63,12 +63,27 @@ let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEven
:> Task
//hackerBattleBot.add_InteractionCreated(AsyncEventHandler(asdf))
if guild <> 922419263275425832uL then
Trainer.sendInitialEmbed hackerBattleBot
let run (client : DiscordClient) =
async {
do! client.ConnectAsync () |> Async.AwaitTask
}
Trainer.sendInitialEmbed hackerBattleBot
let clients =
if guild = 922419263275425832uL then
let interactionsConfig = DiscordConfiguration()
interactionsConfig.TokenType <- TokenType.Bot
interactionsConfig.Intents <- DiscordIntents.All
interactionsConfig.Token <- GuildEnvironment.tokenPlayerInteractions
let interactionsBot = new DiscordClient(interactionsConfig)
let commands = interactionsBot.UseSlashCommands()
commands.RegisterCommands<PlayerInteractions.PlayerInteractions>(guild)
[ hackerBattleBot ; storeBot ; interactionsBot ]
else
[ hackerBattleBot ; storeBot ]
clients
|> List.map run

View File

@ -1,6 +1,7 @@
module Degenz.Embeds
open System
open DSharpPlus
open DSharpPlus.EventArgs
open Degenz.Types
open DSharpPlus.Entities
@ -32,13 +33,16 @@ let getShieldGif = function
| ShieldId.Cypher -> "https://s10.gifyu.com/images/Cypher-Smaller.gif"
| _ -> shieldGif
let constructButtons (actionType: string) (playerInfo: string) (items: BattleItem array) =
let constructButtons (actionType: string) (player: PlayerData) (buttonId : string) (items: BattleItem array) =
items
|> Array.map (fun item -> DiscordButtonComponent(Game.getClassButtonColor item.Class, $"{actionType}-{item.Id}-{playerInfo}", $"{item.Name}"))
|> Array.map (fun item ->
match player.Actions |> Array.exists (fun i -> i.ActionId = item.Id) with
| true -> DiscordButtonComponent(Game.getClassButtonColor item.Class, $"{actionType}-{item.Id}", $"{item.Name} (on cooldown)", true)
| false -> DiscordButtonComponent(Game.getClassButtonColor item.Class, $"{actionType}-{item.Id}-{buttonId}", $"{item.Name}"))
let pickDefense actionId player =
let buttons =
constructButtons actionId (string player.DiscordId) (Player.shields player)
constructButtons actionId player (string player.DiscordId) (Player.shields player)
|> Seq.cast<DiscordComponent>
let embed =
@ -55,7 +59,7 @@ let pickDefense actionId player =
let pickHack actionId attacker defender =
let buttons =
let hacks = Player.hacks attacker
constructButtons actionId $"{defender.DiscordId}-{defender.Name}" hacks
constructButtons actionId attacker $"{defender.DiscordId}-{defender.Name}" hacks
|> Seq.cast<DiscordComponent>
let embed =
@ -69,12 +73,12 @@ let pickHack actionId attacker defender =
.AddEmbed(embed.Build())
.AsEphemeral true
let responseSuccessfulHack (targetId : uint64) (hack : BattleItem) =
let responseSuccessfulHack (targetName : string) (hack : BattleItem) =
let embed = DiscordEmbedBuilder()
embed.ImageUrl <- getHackGif (enum<HackId>(hack.Id))
DiscordFollowupMessageBuilder()
.WithContent($"You successfully hacked <@{targetId}> using {hack.Name}, and stole 💰$GBT {Game.HackPrize} from them!")
.WithContent($"You successfully hacked {targetName} using {hack.Name}, and stole 💰$GBT {Game.HackPrize} from them!")
.AddEmbed(embed.Build())
.AsEphemeral(true)
@ -90,20 +94,20 @@ let responseCreatedShieldTrainer (shield : BattleItem) =
.AsEphemeral(true)
.WithContent($"Mounted a {shield.Name} defense for {TimeSpan.FromMinutes(int shield.Cooldown).Hours} hours")
let eventSuccessfulHack (event : ComponentInteractionCreateEventArgs) targetId prize =
let eventSuccessfulHack (event : ComponentInteractionCreateEventArgs) target prize =
DiscordMessageBuilder()
.WithContent($"{event.User.Username} successfully hacked <@{targetId}> for a total of {prize} GoodBoyTokenz")
.WithContent($"{event.User.Username} successfully hacked {target.Name} for a total of {prize} GoodBoyTokenz")
let eventFailedHack (event : ComponentInteractionCreateEventArgs) targetId prize =
let eventFailedHack (event : ComponentInteractionCreateEventArgs) target prize =
DiscordMessageBuilder()
.WithContent($"{event.User.Username} successfully hacked <@{targetId}> for a total of {prize} GoodBoyTokenz")
.WithContent($"{event.User.Username} successfully hacked {target.Name} for a total of {prize} GoodBoyTokenz")
let getGoodAgainst = function
| BattleClass.Network -> ( ShieldId.Firewall , HackId.Virus )
| BattleClass.Penetration -> ( ShieldId.Cypher , HackId.RemoteAccess )
| BattleClass.Exploit -> ( ShieldId.Encryption , HackId.Worm )
let getBuyItemsEmbed (itemType : ItemType) (store : BattleItem array) =
let getBuyItemsEmbed (player : PlayerData) (itemType : ItemType) (store : BattleItem array) =
let embeds , buttons =
store
|> Array.filter (fun i -> i.Type = itemType)
@ -127,7 +131,10 @@ let getBuyItemsEmbed (itemType : ItemType) (store : BattleItem array) =
.WithColor(Game.getClassEmbedColor item.Class)
.WithTitle($"{item.Name}")
|> ignore
let button = DiscordButtonComponent(Game.getClassButtonColor item.Class, $"Buy-{item.Id}", $"Buy {item.Name}")
let button =
if player.Arsenal |> Array.exists (fun i -> i.Id = item.Id)
then DiscordButtonComponent(Game.getClassButtonColor item.Class, $"Buy-{item.Id}", $"Own {item.Name}", true)
else DiscordButtonComponent(Game.getClassButtonColor item.Class, $"Buy-{item.Id}", $"Buy {item.Name}")
embed.Build() , button :> DiscordComponent)
|> Array.unzip

View File

@ -33,11 +33,11 @@ module Game =
let! playerResult = tryFindPlayer ctx.Member.Id
match playerResult with
| Some player -> do! dispatch player
| None -> do! Messaging.sendSimpleResponse ctx "You are currently not a hacker, first use the /redpill command to become one"
| None -> do! Messaging.sendFollowUpMessageFromCtx ctx "You are currently not a hacker, first use the /redpill command to become one"
} |> Async.StartAsTask
:> Task
// TODO: Create an abstraction for these two helper functions
// TODO J: Create an abstraction for these two helper functions
let executePlayerEvent (event : ComponentInteractionCreateEventArgs) (dispatch : PlayerData -> Async<unit>) =
async {
let builder = DiscordInteractionResponseBuilder()

View File

@ -9,6 +9,8 @@ open DSharpPlus.SlashCommands
open Degenz
open Degenz.Messaging
// TODO: Do not allow any attacks until the user has completed training
// TODO: Introduce second round of weapons, more expensive and with better stats
let checkPlayerIsAttackingThemselves defender attacker =
match attacker.DiscordId = defender.DiscordId with
| true -> Error "You think you're clever? You can't hack yourself, pal."
@ -77,12 +79,12 @@ let successfulHack (event : ComponentInteractionCreateEventArgs) attacker defend
async {
do! updateCombatants attacker defender hack Game.HackPrize
let embed = Embeds.responseSuccessfulHack (defender.DiscordId) (Armory.getItem (int hack))
let embed = Embeds.responseSuccessfulHack (defender.Name) (Armory.getItem (int hack))
do! event.Interaction.CreateFollowupMessageAsync(embed)
|> Async.AwaitTask
|> Async.Ignore
let builder = Embeds.eventSuccessfulHack event defender.DiscordId Game.HackPrize
let builder = Embeds.eventSuccessfulHack event defender Game.HackPrize
let channel = event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle)
do! channel.SendMessageAsync(builder)
|> Async.AwaitTask
@ -97,7 +99,7 @@ let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender h
do! updateCombatants attacker defender hack -Game.ShieldPrize
let builder = DiscordMessageBuilder()
builder.WithContent($"Hacking attempt failed! <@{defender.DiscordId}> defended hack from {event.User.Username} and stole {Game.ShieldPrize} $GBT from them! ") |> ignore
builder.WithContent($"Hacking attempt failed! {defender.Name} defended hack from {event.User.Username} and stole {Game.ShieldPrize} $GBT from them! ") |> ignore
let channel = (event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle))
do! channel.SendMessageAsync(builder)
|> Async.AwaitTask
@ -122,7 +124,11 @@ let attack (target : DiscordUser) (ctx : InteractionContext) =
|> Async.AwaitTask
|> Async.Ignore
| Error msg -> sendFollowUpMessageFromCtx ctx msg
| None -> do! sendFollowUpMessageFromCtx ctx "Your target is not connected to the network, they must join first by using the /redpill command"
| None ->
if target.IsBot
then do! sendFollowUpMessageFromCtx ctx $"{target.Username} is a bot, pick a real human to hack"
else do! sendFollowUpMessageFromCtx ctx "Your target is not connected to the network, they must join first by using the /redpill command"
})
let handleAttack (event : ComponentInteractionCreateEventArgs) =

View File

@ -61,7 +61,7 @@ let arsenal (ctx : InteractionContext) =
let buy itemType (ctx : InteractionContext) =
Game.executePlayerInteraction ctx (fun player -> async {
let itemStore = Embeds.getBuyItemsEmbed itemType Armory.battleItems
let itemStore = Embeds.getBuyItemsEmbed player itemType Armory.battleItems
do! ctx.Interaction.CreateFollowupMessageAsync(itemStore)
|> Async.AwaitTask
|> Async.Ignore
@ -133,8 +133,7 @@ type Store() =
let enforceChannel (ctx : InteractionContext) (storeFn : InteractionContext -> Task) =
match ctx.Channel.Id with
| id when id = GuildEnvironment.channelArmory ->
storeFn ctx
| id when id = GuildEnvironment.channelArmory -> storeFn ctx
| _ ->
task {
let msg = $"You must go to <#{GuildEnvironment.channelArmory}> channel to buy/sell or check your arsenal"

View File

@ -8,6 +8,9 @@ open DSharpPlus.SlashCommands
open Degenz.Types
open Degenz.Messaging
// TODO: We should either gift the weapons to the player during training, or have them buy it
// TODO: We should tell the user to type out /arsenal during the training
// TODO: How do we handle the money being generated here? It's fake but fake is confusing
let defaultHack = Armory.battleItems |> Array.find (fun i -> i.Id = int HackId.Virus)
let defaultShield = Armory.battleItems |> Array.find (fun i -> i.Id = int ShieldId.Encryption)
@ -136,7 +139,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
let sendMessage' = sendFollowUpMessage event
do! Async.Sleep 1000
let hack = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultHack
let embed = Embeds.responseSuccessfulHack GuildEnvironment.botHackerBattle hack
let embed = Embeds.responseSuccessfulHack "Sensei" hack
do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore
do! Async.Sleep 5000
do! sendMessage'

View File

@ -99,7 +99,7 @@ module Messaging =
let plural amount = if amount = 1 then "" else "s"
let ``and`` = if remaining.Hours > 0 then "and " else ""
let hours = if remaining.Hours > 0 then $"{remaining.Hours} hour{plural remaining.Hours} {``and``}" else String.Empty
let totalMins = remaining.Minutes + 1
let totalMins = remaining.Minutes
let minutes = if totalMins > 0 then $"{totalMins} minute{plural totalMins}" else "1 minute"
$"{hours}{minutes}"
@ -114,12 +114,11 @@ module Messaging =
| _ ->
actions
|> Array.map (fun act ->
let item = Armory.getItem act.ActionId
let cooldown = getTimeTillCooldownFinishes (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
match act.Type with
| Attack atk -> $"Hacked {atk.Target.Name} at {act.Timestamp.ToShortTimeString()}"
| Defense ->
let item = Armory.getItem act.ActionId
let cooldown = getTimeTillCooldownFinishes (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
$"{item.Name} active for {cooldown}")
| Attack atk -> $"Hacked {atk.Target.Name} {cooldown} ago"
| Defense -> $"{item.Name} Shield active for {cooldown}")
|> String.concat "\n"
let sendSimpleResponse (ctx: InteractionContext) msg =