Several improvements and enhacements
This commit is contained in:
parent
b12dfe6788
commit
8f8aebd6ac
27
Bot/Bot.fs
27
Bot/Bot.fs
@ -21,9 +21,11 @@ let storeConfig = DiscordConfiguration()
|
|||||||
//let configs = [| hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
|
//let configs = [| hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
|
||||||
let configs = [ hackerBattleConfig ; storeConfig ]
|
let configs = [ hackerBattleConfig ; storeConfig ]
|
||||||
|
|
||||||
for conf in configs do
|
hackerBattleConfig.TokenType <- TokenType.Bot
|
||||||
conf.TokenType <- TokenType.Bot
|
hackerBattleConfig.Intents <- DiscordIntents.All
|
||||||
conf.Intents <- DiscordIntents.All
|
|
||||||
|
storeConfig.TokenType <- TokenType.Bot
|
||||||
|
storeConfig.Intents <- DiscordIntents.All
|
||||||
|
|
||||||
hackerBattleConfig.Token <- GuildEnvironment.tokenHackerBattle
|
hackerBattleConfig.Token <- GuildEnvironment.tokenHackerBattle
|
||||||
storeConfig.Token <- GuildEnvironment.tokenStore
|
storeConfig.Token <- GuildEnvironment.tokenStore
|
||||||
@ -34,8 +36,6 @@ let storeBot = new DiscordClient(storeConfig)
|
|||||||
//let slotMachineBot = new DiscordClient(slotMachineConfig)
|
//let slotMachineBot = new DiscordClient(slotMachineConfig)
|
||||||
|
|
||||||
//let clients = [| hackerBattleBot ; storeBot ; slotMachineBot |]
|
//let clients = [| hackerBattleBot ; storeBot ; slotMachineBot |]
|
||||||
let clients = [ hackerBattleBot ; storeBot ]
|
|
||||||
|
|
||||||
let sc1 = hackerBattleBot.UseSlashCommands()
|
let sc1 = hackerBattleBot.UseSlashCommands()
|
||||||
let sc2 = storeBot.UseSlashCommands()
|
let sc2 = storeBot.UseSlashCommands()
|
||||||
//let sc3 = slotMachineBot.UseSlashCommands()
|
//let sc3 = slotMachineBot.UseSlashCommands()
|
||||||
@ -63,12 +63,27 @@ let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEven
|
|||||||
:> Task
|
:> Task
|
||||||
//hackerBattleBot.add_InteractionCreated(AsyncEventHandler(asdf))
|
//hackerBattleBot.add_InteractionCreated(AsyncEventHandler(asdf))
|
||||||
|
|
||||||
|
if guild <> 922419263275425832uL then
|
||||||
|
Trainer.sendInitialEmbed hackerBattleBot
|
||||||
|
|
||||||
let run (client : DiscordClient) =
|
let run (client : DiscordClient) =
|
||||||
async {
|
async {
|
||||||
do! client.ConnectAsync () |> Async.AwaitTask
|
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
|
clients
|
||||||
|> List.map run
|
|> List.map run
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Degenz.Embeds
|
module Degenz.Embeds
|
||||||
|
|
||||||
open System
|
open System
|
||||||
|
open DSharpPlus
|
||||||
open DSharpPlus.EventArgs
|
open DSharpPlus.EventArgs
|
||||||
open Degenz.Types
|
open Degenz.Types
|
||||||
open DSharpPlus.Entities
|
open DSharpPlus.Entities
|
||||||
@ -32,13 +33,16 @@ let getShieldGif = function
|
|||||||
| ShieldId.Cypher -> "https://s10.gifyu.com/images/Cypher-Smaller.gif"
|
| ShieldId.Cypher -> "https://s10.gifyu.com/images/Cypher-Smaller.gif"
|
||||||
| _ -> shieldGif
|
| _ -> shieldGif
|
||||||
|
|
||||||
let constructButtons (actionType: string) (playerInfo: string) (items: BattleItem array) =
|
let constructButtons (actionType: string) (player: PlayerData) (buttonId : string) (items: BattleItem array) =
|
||||||
items
|
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 pickDefense actionId player =
|
||||||
let buttons =
|
let buttons =
|
||||||
constructButtons actionId (string player.DiscordId) (Player.shields player)
|
constructButtons actionId player (string player.DiscordId) (Player.shields player)
|
||||||
|> Seq.cast<DiscordComponent>
|
|> Seq.cast<DiscordComponent>
|
||||||
|
|
||||||
let embed =
|
let embed =
|
||||||
@ -55,7 +59,7 @@ let pickDefense actionId player =
|
|||||||
let pickHack actionId attacker defender =
|
let pickHack actionId attacker defender =
|
||||||
let buttons =
|
let buttons =
|
||||||
let hacks = Player.hacks attacker
|
let hacks = Player.hacks attacker
|
||||||
constructButtons actionId $"{defender.DiscordId}-{defender.Name}" hacks
|
constructButtons actionId attacker $"{defender.DiscordId}-{defender.Name}" hacks
|
||||||
|> Seq.cast<DiscordComponent>
|
|> Seq.cast<DiscordComponent>
|
||||||
|
|
||||||
let embed =
|
let embed =
|
||||||
@ -69,12 +73,12 @@ let pickHack actionId attacker defender =
|
|||||||
.AddEmbed(embed.Build())
|
.AddEmbed(embed.Build())
|
||||||
.AsEphemeral true
|
.AsEphemeral true
|
||||||
|
|
||||||
let responseSuccessfulHack (targetId : uint64) (hack : BattleItem) =
|
let responseSuccessfulHack (targetName : string) (hack : BattleItem) =
|
||||||
let embed = DiscordEmbedBuilder()
|
let embed = DiscordEmbedBuilder()
|
||||||
embed.ImageUrl <- getHackGif (enum<HackId>(hack.Id))
|
embed.ImageUrl <- getHackGif (enum<HackId>(hack.Id))
|
||||||
|
|
||||||
DiscordFollowupMessageBuilder()
|
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())
|
.AddEmbed(embed.Build())
|
||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
@ -90,20 +94,20 @@ let responseCreatedShieldTrainer (shield : BattleItem) =
|
|||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
.WithContent($"Mounted a {shield.Name} defense for {TimeSpan.FromMinutes(int shield.Cooldown).Hours} hours")
|
.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()
|
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()
|
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
|
let getGoodAgainst = function
|
||||||
| BattleClass.Network -> ( ShieldId.Firewall , HackId.Virus )
|
| BattleClass.Network -> ( ShieldId.Firewall , HackId.Virus )
|
||||||
| BattleClass.Penetration -> ( ShieldId.Cypher , HackId.RemoteAccess )
|
| BattleClass.Penetration -> ( ShieldId.Cypher , HackId.RemoteAccess )
|
||||||
| BattleClass.Exploit -> ( ShieldId.Encryption , HackId.Worm )
|
| 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 =
|
let embeds , buttons =
|
||||||
store
|
store
|
||||||
|> Array.filter (fun i -> i.Type = itemType)
|
|> Array.filter (fun i -> i.Type = itemType)
|
||||||
@ -127,7 +131,10 @@ let getBuyItemsEmbed (itemType : ItemType) (store : BattleItem array) =
|
|||||||
.WithColor(Game.getClassEmbedColor item.Class)
|
.WithColor(Game.getClassEmbedColor item.Class)
|
||||||
.WithTitle($"{item.Name}")
|
.WithTitle($"{item.Name}")
|
||||||
|> ignore
|
|> 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)
|
embed.Build() , button :> DiscordComponent)
|
||||||
|> Array.unzip
|
|> Array.unzip
|
||||||
|
|
||||||
|
@ -33,11 +33,11 @@ module Game =
|
|||||||
let! playerResult = tryFindPlayer ctx.Member.Id
|
let! playerResult = tryFindPlayer ctx.Member.Id
|
||||||
match playerResult with
|
match playerResult with
|
||||||
| Some player -> do! dispatch player
|
| 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
|
} |> Async.StartAsTask
|
||||||
:> Task
|
:> 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>) =
|
let executePlayerEvent (event : ComponentInteractionCreateEventArgs) (dispatch : PlayerData -> Async<unit>) =
|
||||||
async {
|
async {
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
@ -9,6 +9,8 @@ open DSharpPlus.SlashCommands
|
|||||||
open Degenz
|
open Degenz
|
||||||
open Degenz.Messaging
|
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 =
|
let checkPlayerIsAttackingThemselves defender attacker =
|
||||||
match attacker.DiscordId = defender.DiscordId with
|
match attacker.DiscordId = defender.DiscordId with
|
||||||
| true -> Error "You think you're clever? You can't hack yourself, pal."
|
| true -> Error "You think you're clever? You can't hack yourself, pal."
|
||||||
@ -77,12 +79,12 @@ let successfulHack (event : ComponentInteractionCreateEventArgs) attacker defend
|
|||||||
async {
|
async {
|
||||||
do! updateCombatants attacker defender hack Game.HackPrize
|
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)
|
do! event.Interaction.CreateFollowupMessageAsync(embed)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> 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)
|
let channel = event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle)
|
||||||
do! channel.SendMessageAsync(builder)
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
@ -97,7 +99,7 @@ let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender h
|
|||||||
do! updateCombatants attacker defender hack -Game.ShieldPrize
|
do! updateCombatants attacker defender hack -Game.ShieldPrize
|
||||||
|
|
||||||
let builder = DiscordMessageBuilder()
|
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))
|
let channel = (event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle))
|
||||||
do! channel.SendMessageAsync(builder)
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
@ -122,7 +124,11 @@ let attack (target : DiscordUser) (ctx : InteractionContext) =
|
|||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
| Error msg -> sendFollowUpMessageFromCtx ctx msg
|
| 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) =
|
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||||
|
@ -61,7 +61,7 @@ let arsenal (ctx : InteractionContext) =
|
|||||||
|
|
||||||
let buy itemType (ctx : InteractionContext) =
|
let buy itemType (ctx : InteractionContext) =
|
||||||
Game.executePlayerInteraction ctx (fun player -> async {
|
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)
|
do! ctx.Interaction.CreateFollowupMessageAsync(itemStore)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
@ -133,8 +133,7 @@ type Store() =
|
|||||||
|
|
||||||
let enforceChannel (ctx : InteractionContext) (storeFn : InteractionContext -> Task) =
|
let enforceChannel (ctx : InteractionContext) (storeFn : InteractionContext -> Task) =
|
||||||
match ctx.Channel.Id with
|
match ctx.Channel.Id with
|
||||||
| id when id = GuildEnvironment.channelArmory ->
|
| id when id = GuildEnvironment.channelArmory -> storeFn ctx
|
||||||
storeFn ctx
|
|
||||||
| _ ->
|
| _ ->
|
||||||
task {
|
task {
|
||||||
let msg = $"You must go to <#{GuildEnvironment.channelArmory}> channel to buy/sell or check your arsenal"
|
let msg = $"You must go to <#{GuildEnvironment.channelArmory}> channel to buy/sell or check your arsenal"
|
||||||
|
@ -8,6 +8,9 @@ open DSharpPlus.SlashCommands
|
|||||||
open Degenz.Types
|
open Degenz.Types
|
||||||
open Degenz.Messaging
|
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 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)
|
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
|
let sendMessage' = sendFollowUpMessage event
|
||||||
do! Async.Sleep 1000
|
do! Async.Sleep 1000
|
||||||
let hack = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultHack
|
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! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore
|
||||||
do! Async.Sleep 5000
|
do! Async.Sleep 5000
|
||||||
do! sendMessage'
|
do! sendMessage'
|
||||||
|
@ -99,7 +99,7 @@ module Messaging =
|
|||||||
let plural amount = if amount = 1 then "" else "s"
|
let plural amount = if amount = 1 then "" else "s"
|
||||||
let ``and`` = if remaining.Hours > 0 then "and " else ""
|
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 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"
|
let minutes = if totalMins > 0 then $"{totalMins} minute{plural totalMins}" else "1 minute"
|
||||||
$"{hours}{minutes}"
|
$"{hours}{minutes}"
|
||||||
|
|
||||||
@ -114,12 +114,11 @@ module Messaging =
|
|||||||
| _ ->
|
| _ ->
|
||||||
actions
|
actions
|
||||||
|> Array.map (fun act ->
|
|> Array.map (fun act ->
|
||||||
match act.Type with
|
|
||||||
| Attack atk -> $"Hacked {atk.Target.Name} at {act.Timestamp.ToShortTimeString()}"
|
|
||||||
| Defense ->
|
|
||||||
let item = Armory.getItem act.ActionId
|
let item = Armory.getItem act.ActionId
|
||||||
let cooldown = getTimeTillCooldownFinishes (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
|
let cooldown = getTimeTillCooldownFinishes (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
|
||||||
$"{item.Name} active for {cooldown}")
|
match act.Type with
|
||||||
|
| Attack atk -> $"Hacked {atk.Target.Name} {cooldown} ago"
|
||||||
|
| Defense -> $"{item.Name} Shield active for {cooldown}")
|
||||||
|> String.concat "\n"
|
|> String.concat "\n"
|
||||||
|
|
||||||
let sendSimpleResponse (ctx: InteractionContext) msg =
|
let sendSimpleResponse (ctx: InteractionContext) msg =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user