Add hacker gif when issuing a hack command. Disable slot machine
This commit is contained in:
parent
a007f55c55
commit
9af3f7ef9d
@ -19,9 +19,10 @@ let playerInteractionsConfig = DiscordConfiguration()
|
|||||||
let trainerConfig = DiscordConfiguration()
|
let trainerConfig = DiscordConfiguration()
|
||||||
let hackerBattleConfig = DiscordConfiguration()
|
let hackerBattleConfig = DiscordConfiguration()
|
||||||
let storeConfig = DiscordConfiguration()
|
let storeConfig = DiscordConfiguration()
|
||||||
let slotMachineConfig = DiscordConfiguration()
|
//let slotMachineConfig = DiscordConfiguration()
|
||||||
|
|
||||||
let configs = [| playerInteractionsConfig ; trainerConfig ; hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
|
//let configs = [| playerInteractionsConfig ; trainerConfig ; hackerBattleConfig ; storeConfig ; slotMachineConfig ; |]
|
||||||
|
let configs = [| playerInteractionsConfig ; trainerConfig ; hackerBattleConfig ; storeConfig |]
|
||||||
|
|
||||||
for conf in configs do
|
for conf in configs do
|
||||||
conf.TokenType <- TokenType.Bot
|
conf.TokenType <- TokenType.Bot
|
||||||
@ -36,7 +37,7 @@ playerInteractionsConfig.Token <- Environment.GetEnvironmentVariable("BOT_PLAYER
|
|||||||
trainerConfig.Token <- Environment.GetEnvironmentVariable("BOT_TRAINER")
|
trainerConfig.Token <- Environment.GetEnvironmentVariable("BOT_TRAINER")
|
||||||
hackerBattleConfig.Token <- Environment.GetEnvironmentVariable("BOT_HACKER_BATTLE")
|
hackerBattleConfig.Token <- Environment.GetEnvironmentVariable("BOT_HACKER_BATTLE")
|
||||||
storeConfig.Token <- Environment.GetEnvironmentVariable("BOT_STORE")
|
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
|
//config.MinimumLogLevel <- Microsoft.Extensions.Logging.LogLevel.Trace
|
||||||
|
|
||||||
@ -44,24 +45,26 @@ let playerInteractionsBot = new DiscordClient(playerInteractionsConfig)
|
|||||||
let trainerBot = new DiscordClient(trainerConfig)
|
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))
|
trainerBot.add_ComponentInteractionCreated(AsyncEventHandler(Trainer.handleButtonEvent))
|
||||||
|
storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleSellButtonEvents))
|
||||||
|
|
||||||
let clients = [| playerInteractionsBot ; trainerBot ; hackerBattleBot ; storeBot ; slotMachineBot |]
|
//let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot ; slotMachineBot |]
|
||||||
|
let clients = [| storeBot ; trainerBot ; hackerBattleBot ; playerInteractionsBot |]
|
||||||
|
|
||||||
let sc1 = playerInteractionsBot.UseSlashCommands()
|
let sc1 = playerInteractionsBot.UseSlashCommands()
|
||||||
let sc2 = trainerBot.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);
|
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);
|
||||||
|
|
||||||
let run (client : DiscordClient) =
|
let run (client : DiscordClient) =
|
||||||
async {
|
async {
|
||||||
|
@ -27,8 +27,13 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
|
|||||||
|> removeExpiredActions (TimeSpan.FromMinutes(15)) (fun (atk : Attack) -> atk.Timestamp)
|
|> removeExpiredActions (TimeSpan.FromMinutes(15)) (fun (atk : Attack) -> atk.Timestamp)
|
||||||
do! DbService.updatePlayer <| { attacker with Attacks = updatedAttacks }
|
do! DbService.updatePlayer <| { attacker with Attacks = updatedAttacks }
|
||||||
if updatedAttacks.Length < 2 then
|
if updatedAttacks.Length < 2 then
|
||||||
|
let embed = DiscordEmbedBuilder()
|
||||||
|
embed.Color <- Optional(DiscordColor.PhthaloGreen)
|
||||||
|
embed.Description <- "Pick the hack that you want to use"
|
||||||
|
embed.ImageUrl <- "https://s10.gifyu.com/images/Hacker-Degenz-V2.gif"
|
||||||
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
builder.AddEmbed (constructEmbed "Pick the hack you wish to use.") |> ignore
|
builder.AddEmbed (embed.Build()) |> ignore
|
||||||
|
|
||||||
let defenderInfo = $"{defender.DiscordId}-{target.Username}"
|
let defenderInfo = $"{defender.DiscordId}-{target.Username}"
|
||||||
constructButtons "Attack" defenderInfo attacker.Weapons
|
constructButtons "Attack" defenderInfo attacker.Weapons
|
||||||
@ -94,10 +99,10 @@ let defend (ctx : InteractionContext) =
|
|||||||
|
|
||||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||||
let updatePlayer amount attack p =
|
let updatePlayer amount attack p =
|
||||||
{ p with Attacks = Array.append [| attack |] p.Attacks ; Bank = MathF.Max(p.Bank + amount, 0f) }
|
{ p with Attacks = Array.append [| attack |] p.Attacks ; Bank = Math.Max(p.Bank + amount, 0) }
|
||||||
async {
|
async {
|
||||||
let split = event.Id.Split("-")
|
let split = event.Id.Split("-")
|
||||||
let weapon = Enum.Parse(typedefof<Weapon>, split.[1]) :?> Weapon
|
let weapon = Enum.Parse(typedefof<Hack>, split.[1]) :?> Hack
|
||||||
let ( resultId , targetId ) = UInt64.TryParse split.[2]
|
let ( resultId , targetId ) = UInt64.TryParse split.[2]
|
||||||
let! resultPlayer = DbService.tryFindPlayer event.User.Id
|
let! resultPlayer = DbService.tryFindPlayer event.User.Id
|
||||||
let! resultTarget = DbService.tryFindPlayer targetId
|
let! resultTarget = DbService.tryFindPlayer targetId
|
||||||
@ -114,7 +119,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
|||||||
match wasSuccessfulHack with
|
match wasSuccessfulHack with
|
||||||
| false ->
|
| false ->
|
||||||
let prize = 1.337f // LEET
|
let prize = 1.337f // LEET
|
||||||
let attack = { HackType = enum<Weapon>(int weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
let attack = { HackType = enum<Hack>(int weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||||
// TODO: Make a single update instead of two
|
// TODO: Make a single update instead of two
|
||||||
do! DbService.updatePlayer <| updatePlayer prize attack player
|
do! DbService.updatePlayer <| updatePlayer prize attack player
|
||||||
do! DbService.updatePlayer { target with Bank = MathF.Max(target.Bank - prize, 0f)}
|
do! DbService.updatePlayer { target with Bank = MathF.Max(target.Bank - prize, 0f)}
|
||||||
@ -139,7 +144,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
|||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|
|
||||||
let attack = { HackType = enum<Weapon>(int weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
let attack = { HackType = enum<Hack>(int weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||||
do! DbService.updatePlayer <| updatePlayer -prize attack player
|
do! DbService.updatePlayer <| updatePlayer -prize attack player
|
||||||
do! DbService.updatePlayer { target with Bank = target.Bank + prize }
|
do! DbService.updatePlayer { target with Bank = target.Bank + prize }
|
||||||
|
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"Name" : "Virus",
|
"Name" : "Virus",
|
||||||
"ItemType" : { "Case" : "Weapon" },
|
"ItemType" : { "Case" : "Hack" },
|
||||||
"Cost" : 5.0
|
"Cost" : 5.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name" : "Ransom",
|
"Name" : "Ransom",
|
||||||
"ItemType" : { "Case" : "Weapon" },
|
"ItemType" : { "Case" : "Hack" },
|
||||||
"Cost" : 10.0
|
"Cost" : 10.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name" : "Worm",
|
"Name" : "Worm",
|
||||||
"ItemType" : { "Case" : "Weapon" },
|
"ItemType" : { "Case" : "Hack" },
|
||||||
"Cost" : 5.0
|
"Cost" : 5.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name" : "DDos",
|
"Name" : "DDos",
|
||||||
"ItemType" : { "Case" : "Weapon" },
|
"ItemType" : { "Case" : "Hack" },
|
||||||
"Cost" : 10.0
|
"Cost" : 10.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name" : "Crack",
|
"Name" : "Crack",
|
||||||
"ItemType" : { "Case" : "Weapon" },
|
"ItemType" : { "Case" : "Hack" },
|
||||||
"Cost" : 5.0
|
"Cost" : 5.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name" : "Injection",
|
"Name" : "Injection",
|
||||||
"ItemType" : { "Case" : "Weapon" },
|
"ItemType" : { "Case" : "Hack" },
|
||||||
"Cost" : 10.0
|
"Cost" : 10.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -39,24 +39,24 @@
|
|||||||
"ItemType" : { "Case" : "Shield" },
|
"ItemType" : { "Case" : "Shield" },
|
||||||
"Cost" : 10.0
|
"Cost" : 10.0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Name" : "Cypher",
|
||||||
|
"ItemType" : { "Case" : "Shield" },
|
||||||
|
"Cost" : 5.0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Name" : "Encryption",
|
"Name" : "Encryption",
|
||||||
"ItemType" : { "Case" : "Shield" },
|
"ItemType" : { "Case" : "Shield" },
|
||||||
|
"Cost" : 10.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name" : "Sanitation",
|
||||||
|
"ItemType" : { "Case" : "Shield" },
|
||||||
"Cost" : 5.0
|
"Cost" : 5.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name" : "Hardening",
|
"Name" : "Hardening",
|
||||||
"ItemType" : { "Case" : "Shield" },
|
"ItemType" : { "Case" : "Shield" },
|
||||||
"Cost" : 10.0
|
"Cost" : 10.0
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name" : "Cypher",
|
|
||||||
"ItemType" : { "Case" : "Shield" },
|
|
||||||
"Cost" : 5.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name" : "Sanitation",
|
|
||||||
"ItemType" : { "Case" : "Shield" },
|
|
||||||
"Cost" : 10.0
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -75,6 +75,13 @@ module Commands =
|
|||||||
} |> Async.StartAsTask
|
} |> Async.StartAsTask
|
||||||
:> Task
|
:> Task
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type LeaderboardEntry = {
|
||||||
|
Position : string
|
||||||
|
Amount : string
|
||||||
|
Name : string
|
||||||
|
}
|
||||||
|
|
||||||
let leaderboard (ctx : InteractionContext) =
|
let leaderboard (ctx : InteractionContext) =
|
||||||
async {
|
async {
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
@ -82,12 +89,12 @@ module Commands =
|
|||||||
|
|
||||||
let! leaders = DbService.getTopPlayers 10
|
let! leaders = DbService.getTopPlayers 10
|
||||||
let content =
|
let content =
|
||||||
// TODO: There's a bug, it's not in the right order
|
|
||||||
leaders
|
leaders
|
||||||
|> Seq.toArray
|
|> Seq.toArray
|
||||||
|> Array.mapi (fun i p -> $"{i + 1}. {p.Bank} {p.Name}")
|
|> Array.sortByDescending (fun p -> p.Bank)
|
||||||
|> String.concat "\n"
|
|> Array.mapi (fun i p -> { Position = string (i + 1) ; Amount = string p.Bank ; Name = p.Name })
|
||||||
builder.Content <- if not <| String.IsNullOrEmpty content then content else "There are no active hackers"
|
|> Formatter.Format
|
||||||
|
builder.Content <- if not <| String.IsNullOrEmpty content then $"```{content}```" else "There are no active hackers"
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
} |> Async.StartAsTask
|
} |> Async.StartAsTask
|
||||||
|
@ -8,6 +8,7 @@ open DSharpPlus.SlashCommands
|
|||||||
open Degenz
|
open Degenz
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
open Newtonsoft.Json
|
open Newtonsoft.Json
|
||||||
|
open AsciiTableFormatter
|
||||||
|
|
||||||
let store =
|
let store =
|
||||||
try
|
try
|
||||||
@ -16,180 +17,209 @@ let store =
|
|||||||
|> Array.groupBy (fun (i : Item) -> i.ItemType)
|
|> Array.groupBy (fun (i : Item) -> i.ItemType)
|
||||||
with _ -> [||]
|
with _ -> [||]
|
||||||
|
|
||||||
|
//[<Sealed>]
|
||||||
|
//type Table() =
|
||||||
|
// member val Name = "" with get , set
|
||||||
|
// member val Cost = "" with get , set
|
||||||
|
// member val Class = "" with get , set
|
||||||
|
//
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type Table = {
|
||||||
|
Name : string
|
||||||
|
Cost : string
|
||||||
|
Class : string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let storeListing =
|
let storeListing =
|
||||||
store
|
store
|
||||||
|> Array.map (fun ( itemType , items ) ->
|
|> Array.map (fun ( itemType , items ) ->
|
||||||
let itemList = items |> Array.map (fun i -> $"{i.Name} - {i.Cost} GBT") |> String.concat "\n"
|
let itemsData =
|
||||||
(constructEmbed $"{itemType}:\n{itemList}"))
|
items
|
||||||
|
|> Array.map (fun (item : Item) ->
|
||||||
|
let itemClass =
|
||||||
|
if itemType = ItemType.Hack
|
||||||
|
then weaponInventory
|
||||||
|
|> Array.find (fun w -> item.Name = string w)
|
||||||
|
|> int
|
||||||
|
|> getClass
|
||||||
|
else shieldInventory
|
||||||
|
|> Array.find (fun w -> item.Name = string w)
|
||||||
|
|> int
|
||||||
|
|> getClass
|
||||||
|
{ Name = item.Name ; Cost = string item.Cost ; Class = string itemClass })
|
||||||
|
|
||||||
module Commands =
|
let table = Formatter.Format(ResizeArray(itemsData))
|
||||||
let viewStore (ctx : InteractionContext) =
|
|
||||||
async {
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
|
|
||||||
builder.AddEmbeds(storeListing)
|
(constructEmbed $"**{itemType}s**\n```{table}```"))
|
||||||
.AsEphemeral(true)
|
|
||||||
|> ignore
|
|
||||||
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
let viewStore (ctx : InteractionContext) =
|
||||||
|> Async.AwaitTask
|
async {
|
||||||
} |> Async.StartAsTask
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
:> Task
|
|
||||||
|
|
||||||
let getItems itemType = store |> Array.find (fun ( t , _ ) -> t = itemType) |> snd
|
builder.AddEmbeds(storeListing)
|
||||||
|
.AsEphemeral(true)
|
||||||
|
|> ignore
|
||||||
|
|
||||||
let buyHack (ctx : InteractionContext) hackId =
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
async {
|
|> Async.AwaitTask
|
||||||
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
} |> Async.StartAsTask
|
||||||
let weapons = getItems ItemType.Weapon
|
:> Task
|
||||||
let weaponResult = weapons |> Array.tryFind (fun w -> w.Name = string hackId)
|
|
||||||
return!
|
let getItems itemType = store |> Array.find (fun ( t , _ ) -> t = itemType) |> snd
|
||||||
match playerResult , weaponResult with
|
|
||||||
| Some player , Some item ->
|
let buyHack (ctx : InteractionContext) hackId =
|
||||||
async {
|
async {
|
||||||
let newBalance = player.Bank - item.Cost
|
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||||
if newBalance >= 0.0f then
|
let weapons = getItems ItemType.Hack
|
||||||
let playerHasItem = player.Weapons |> Array.exists (fun w -> item.Name = string w)
|
let weaponResult = weapons |> Array.tryFind (fun w -> w.Name = string hackId)
|
||||||
if not playerHasItem then
|
return!
|
||||||
let weapon = weaponInventory |> Array.find (fun w -> item.Name = string w)
|
match playerResult , weaponResult with
|
||||||
let p = { player with Bank = newBalance ; Weapons = Array.append [| weapon |] player.Weapons }
|
| Some player , Some item ->
|
||||||
do! DbService.updatePlayer p
|
async {
|
||||||
do! createSimpleResponseAsync $"Successfully purchased {item.Name}! You now have {newBalance} remaining" ctx
|
let newBalance = player.Bank - item.Cost
|
||||||
else
|
if newBalance >= 0 then
|
||||||
do! createSimpleResponseAsync $"You already own this item!" ctx
|
let playerHasItem = player.Weapons |> Array.exists (fun w -> item.Name = string w)
|
||||||
|
if not playerHasItem then
|
||||||
|
let weapon = weaponInventory |> Array.find (fun w -> item.Name = string w)
|
||||||
|
let p = { player with Bank = newBalance ; Weapons = Array.append [| weapon |] player.Weapons }
|
||||||
|
do! DbService.updatePlayer p
|
||||||
|
do! createSimpleResponseAsync $"Successfully purchased {item.Name}! You now have {newBalance} remaining" ctx
|
||||||
else
|
else
|
||||||
do! createSimpleResponseAsync $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT" ctx
|
do! createSimpleResponseAsync $"You already own this item!" ctx
|
||||||
}
|
else
|
||||||
| None , _ -> notYetAHackerMsg ctx
|
do! createSimpleResponseAsync $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT" ctx
|
||||||
| _ -> createSimpleResponseAsync "Something is wrong" ctx
|
}
|
||||||
} |> Async.StartAsTask
|
| None , _ -> notYetAHackerMsg ctx
|
||||||
:> Task
|
| _ -> createSimpleResponseAsync "Something is wrong" ctx
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
let buyShield (ctx : InteractionContext) shieldId =
|
let buyShield (ctx : InteractionContext) shieldId =
|
||||||
async {
|
async {
|
||||||
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||||
let shieldResult =
|
let shieldResult =
|
||||||
getItems ItemType.Shield
|
getItems ItemType.Shield
|
||||||
|> Array.tryFind (fun w -> w.Name = string shieldId)
|
|> Array.tryFind (fun w -> w.Name = string shieldId)
|
||||||
return!
|
return!
|
||||||
match playerResult , shieldResult with
|
match playerResult , shieldResult with
|
||||||
| Some player , Some item ->
|
| Some player , Some item ->
|
||||||
async {
|
async {
|
||||||
let newBalance = player.Bank - item.Cost
|
let newBalance = player.Bank - item.Cost
|
||||||
if newBalance >= 0.0f then
|
if newBalance >= 0 then
|
||||||
let playerHasItem = player.Shields |> Array.exists (fun w -> item.Name = string w)
|
let playerHasItem = player.Shields |> Array.exists (fun w -> item.Name = string w)
|
||||||
if not playerHasItem then
|
if not playerHasItem then
|
||||||
let shield = shieldInventory |> Array.find (fun w -> item.Name = string w)
|
let shield = shieldInventory |> Array.find (fun w -> item.Name = string w)
|
||||||
let p = { player with Bank = newBalance ; Shields = Array.append [| shield |] player.Shields }
|
let p = { player with Bank = newBalance ; Shields = Array.append [| shield |] player.Shields }
|
||||||
do! DbService.updatePlayer p
|
do! DbService.updatePlayer p
|
||||||
do! createSimpleResponseAsync $"Successfully purchased {item.Name}! You now have {newBalance} remaining" ctx
|
do! createSimpleResponseAsync $"Successfully purchased {item.Name}! You now have {newBalance} remaining" ctx
|
||||||
else
|
|
||||||
do! createSimpleResponseAsync $"You already own this item!" ctx
|
|
||||||
else
|
else
|
||||||
do! createSimpleResponseAsync $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT" ctx
|
do! createSimpleResponseAsync $"You already own this item!" ctx
|
||||||
}
|
else
|
||||||
| None , _ -> notYetAHackerMsg ctx
|
do! createSimpleResponseAsync $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT" ctx
|
||||||
| _ -> createSimpleResponseAsync "Something is wrong" ctx
|
}
|
||||||
} |> Async.StartAsTask
|
| None , _ -> notYetAHackerMsg ctx
|
||||||
:> Task
|
| _ -> createSimpleResponseAsync "Something is wrong" ctx
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
let constructItemButtons playerInfo itemType (items : 'a array) =
|
let constructItemButtons playerInfo itemType (items : 'a array) =
|
||||||
items
|
items
|
||||||
|> Seq.map (fun item -> DiscordButtonComponent(ButtonStyle.Primary, $"{playerInfo}-{itemType}-{item}", $"{item}"))
|
|> Seq.map (fun item -> DiscordButtonComponent(ButtonStyle.Primary, $"{playerInfo}-{itemType}-{item}", $"{item}"))
|
||||||
|
|
||||||
let sellItem (ctx : InteractionContext) =
|
let sellItem (ctx : InteractionContext) =
|
||||||
async {
|
async {
|
||||||
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||||
match playerResult with
|
match playerResult with
|
||||||
| Some player ->
|
| Some player ->
|
||||||
let hasInventoryToSell = Array.length player.Weapons + Array.length player.Shields > 0
|
let hasInventoryToSell = Array.length player.Weapons + Array.length player.Shields > 0
|
||||||
if hasInventoryToSell then
|
if hasInventoryToSell then
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
builder.AddEmbed (constructEmbed "Pick the item you wish to sell.") |> ignore
|
builder.AddEmbed (constructEmbed "Pick the item you wish to sell.") |> ignore
|
||||||
|
|
||||||
Array.chunkBySize 3 player.Weapons
|
Array.chunkBySize 3 player.Weapons
|
||||||
|> Array.iter
|
|> Array.iter
|
||||||
(fun wps ->
|
(fun wps ->
|
||||||
wps
|
wps
|
||||||
|> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"Weapon-{w}", $"{w}"))
|
|> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"Hack-{w}", $"{w}"))
|
||||||
|> Seq.cast<DiscordComponent>
|
|> Seq.cast<DiscordComponent>
|
||||||
|> builder.AddComponents
|
|> builder.AddComponents
|
||||||
|> ignore)
|
|> ignore)
|
||||||
Array.chunkBySize 3 player.Shields
|
Array.chunkBySize 3 player.Shields
|
||||||
|> Array.iter
|
|> Array.iter
|
||||||
(fun shs ->
|
(fun shs ->
|
||||||
shs
|
shs
|
||||||
|> Array.map (fun s -> DiscordButtonComponent(ButtonStyle.Primary, $"Shield-{s}", $"{s}"))
|
|> Array.map (fun s -> DiscordButtonComponent(ButtonStyle.Primary, $"Shield-{s}", $"{s}"))
|
||||||
|> Seq.cast<DiscordComponent>
|
|> Seq.cast<DiscordComponent>
|
||||||
|> builder.AddComponents
|
|> builder.AddComponents
|
||||||
|> ignore)
|
|> ignore)
|
||||||
|
|
||||||
builder.AsEphemeral true |> ignore
|
builder.AsEphemeral true |> ignore
|
||||||
|
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
else
|
else
|
||||||
do! createSimpleResponseAsync "You currently have no inventory to sell" ctx
|
do! createSimpleResponseAsync "You currently have no inventory to sell" ctx
|
||||||
| None -> do! notYetAHackerMsg ctx
|
| None -> do! notYetAHackerMsg ctx
|
||||||
return ()
|
return ()
|
||||||
} |> Async.StartAsTask
|
} |> Async.StartAsTask
|
||||||
:> Task
|
:> Task
|
||||||
|
|
||||||
let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||||
async {
|
async {
|
||||||
let! playerResult = DbService.tryFindPlayer event.User.Id
|
let! playerResult = DbService.tryFindPlayer event.User.Id
|
||||||
match playerResult with
|
match playerResult with
|
||||||
| Some player ->
|
| Some player ->
|
||||||
let split = event.Id.Split("-")
|
let split = event.Id.Split("-")
|
||||||
let itemType = match split.[0] with "Weapon" -> ItemType.Weapon | _ -> ItemType.Shield
|
let itemType = match split.[0] with "Hack" -> ItemType.Hack | _ -> ItemType.Shield
|
||||||
let itemName = split.[1]
|
let itemName = split.[1]
|
||||||
match itemType with
|
match itemType with
|
||||||
| ItemType.Weapon ->
|
| ItemType.Hack ->
|
||||||
let item = getItems ItemType.Weapon |> Array.find (fun w -> w.Name = itemName)
|
let item = getItems ItemType.Hack |> Array.find (fun w -> w.Name = itemName)
|
||||||
let salePrice = item.Cost / 2.f
|
let salePrice = item.Cost / 2
|
||||||
let updatedWeapons = player.Weapons |> Array.filter (fun (w : Weapon) -> string w <> itemName)
|
let updatedWeapons = player.Weapons |> Array.filter (fun (w : Hack) -> string w <> itemName)
|
||||||
let updatedPlayer = { player with Bank = player.Bank + salePrice ; Weapons = updatedWeapons }
|
let updatedPlayer = { player with Bank = player.Bank + salePrice ; Weapons = updatedWeapons }
|
||||||
do! DbService.updatePlayer updatedPlayer
|
do! DbService.updatePlayer updatedPlayer
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Sold weapon {itemName} for {salePrice}! Current Balance: {updatedPlayer.Bank}"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
| ItemType.Shield ->
|
|
||||||
let item = getItems ItemType.Shield |> Array.find (fun s -> s.Name = itemName)
|
|
||||||
let salePrice = item.Cost / 2.f
|
|
||||||
let updatedShields = player.Shields |> Array.filter (fun (s : Shield) -> string s <> itemName)
|
|
||||||
let updatedPlayer = { player with Bank = player.Bank + salePrice ; Shields = updatedShields }
|
|
||||||
do! DbService.updatePlayer updatedPlayer
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
|
||||||
builder.IsEphemeral <- true
|
|
||||||
builder.Content <- $"Sold shield {itemName} for {salePrice}! Current Balance: {updatedPlayer.Bank}"
|
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
|
||||||
|> Async.AwaitTask
|
|
||||||
| None ->
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
builder.IsEphemeral <- true
|
builder.IsEphemeral <- true
|
||||||
builder.Content <- "An error occurred and the user doesn't not exist"
|
builder.Content <- $"Sold hack {itemName} for {salePrice}! Current Balance: {updatedPlayer.Bank}"
|
||||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
} |> Async.StartAsTask
|
| ItemType.Shield ->
|
||||||
:> Task
|
let item = getItems ItemType.Shield |> Array.find (fun s -> s.Name = itemName)
|
||||||
|
let salePrice = item.Cost / 2
|
||||||
|
let updatedShields = player.Shields |> Array.filter (fun (s : Shield) -> string s <> itemName)
|
||||||
|
let updatedPlayer = { player with Bank = player.Bank + salePrice ; Shields = updatedShields }
|
||||||
|
do! DbService.updatePlayer updatedPlayer
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- $"Sold shield {itemName} for {salePrice}! Current Balance: {updatedPlayer.Bank}"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
| None ->
|
||||||
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
|
builder.IsEphemeral <- true
|
||||||
|
builder.Content <- "An error occurred and the user doesn't not exist"
|
||||||
|
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
|
|
||||||
type Store() =
|
type Store() =
|
||||||
inherit ApplicationCommandModule ()
|
inherit ApplicationCommandModule ()
|
||||||
|
|
||||||
[<SlashCommand("store", "View items available for purchase")>]
|
[<SlashCommand("store", "View items available for purchase")>]
|
||||||
member _.ViewStore (ctx : InteractionContext) = Commands.viewStore ctx
|
member _.ViewStore (ctx : InteractionContext) = viewStore ctx
|
||||||
|
|
||||||
[<SlashCommand("buy-hack", "Purchase a hack attack you can use to earn GoodBoyTokenz")>]
|
[<SlashCommand("buy-hack", "Purchase a hack attack you can use to earn GoodBoyTokenz")>]
|
||||||
member _.BuyHack (ctx : InteractionContext, [<Option("hack-id", "The ID of the hack you wish to purchase")>] hackId : Weapon) =
|
member _.BuyHack (ctx : InteractionContext, [<Option("hack-id", "The ID of the hack you wish to purchase")>] hackId : Hack) =
|
||||||
Commands.buyHack ctx hackId
|
buyHack ctx hackId
|
||||||
|
|
||||||
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
|
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
|
||||||
member this.BuyShield (ctx : InteractionContext, [<Option("shield-id", "The ID of the shield you wish to purchase")>] shieldId : Shield) =
|
member this.BuyShield (ctx : InteractionContext, [<Option("shield-id", "The ID of the shield you wish to purchase")>] shieldId : Shield) =
|
||||||
Commands.buyShield ctx shieldId
|
buyShield ctx shieldId
|
||||||
|
|
||||||
[<SlashCommand("sell", "Sell an item in your inventory for GoodBoyTokenz")>]
|
[<SlashCommand("sell", "Sell an item in your inventory for GoodBoyTokenz")>]
|
||||||
member this.SellItem (ctx : InteractionContext) =
|
member this.SellItem (ctx : InteractionContext) = sellItem ctx
|
||||||
Commands.sellItem ctx
|
|
||||||
|
|
||||||
|
@ -2,3 +2,4 @@ FSharp.Core
|
|||||||
DSharpPlus
|
DSharpPlus
|
||||||
DSharpPlus.SlashCommands
|
DSharpPlus.SlashCommands
|
||||||
dotenv.net
|
dotenv.net
|
||||||
|
DanielStout.AsciiTableFormatter
|
||||||
|
@ -6,7 +6,7 @@ open DSharpPlus.Entities
|
|||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
|
|
||||||
type ItemType =
|
type ItemType =
|
||||||
| Weapon
|
| Hack
|
||||||
| Shield
|
| Shield
|
||||||
|
|
||||||
type ActionClass =
|
type ActionClass =
|
||||||
@ -14,7 +14,7 @@ type ActionClass =
|
|||||||
| Exploit
|
| Exploit
|
||||||
| Penetration
|
| Penetration
|
||||||
|
|
||||||
type Weapon =
|
type Hack =
|
||||||
| Virus = 0
|
| Virus = 0
|
||||||
| Ransom = 1
|
| Ransom = 1
|
||||||
| Worm = 2
|
| Worm = 2
|
||||||
@ -34,20 +34,17 @@ type Shield =
|
|||||||
type Item = {
|
type Item = {
|
||||||
Name : string
|
Name : string
|
||||||
ItemType : ItemType
|
ItemType : ItemType
|
||||||
Cost : single
|
Cost : int
|
||||||
}
|
}
|
||||||
|
|
||||||
let weaponInventory = [| Weapon.Virus ; Weapon.Ransom ; Weapon.DDos ; Weapon.Worm ; Weapon.Crack ; Weapon.Injection |]
|
let weaponInventory = [| Hack.Virus ; Hack.Ransom ; Hack.DDos ; Hack.Worm ; Hack.Crack ; Hack.Injection |]
|
||||||
let shieldInventory = [| Shield.Firewall ; Shield.PortScan ; Shield.Encryption ; Shield.Cypher ; Shield.Hardening ; Shield.Sanitation |]
|
let shieldInventory = [| Shield.Firewall ; Shield.PortScan ; Shield.Encryption ; Shield.Cypher ; Shield.Hardening ; Shield.Sanitation |]
|
||||||
|
|
||||||
let getClass =
|
let getClass =
|
||||||
function
|
function
|
||||||
| 0
|
| 0 | 1 -> Network
|
||||||
| 1 -> Network
|
| 2 | 3 -> Exploit
|
||||||
| 2
|
| 4 | _ -> Penetration
|
||||||
| 3 -> Exploit
|
|
||||||
| 4
|
|
||||||
| _ -> Penetration
|
|
||||||
|
|
||||||
type HackResult =
|
type HackResult =
|
||||||
| Strong
|
| Strong
|
||||||
@ -58,7 +55,7 @@ type DiscordPlayer = { Id: uint64; Name: string }
|
|||||||
|
|
||||||
[<CLIMutable>]
|
[<CLIMutable>]
|
||||||
type Attack =
|
type Attack =
|
||||||
{ HackType: Weapon
|
{ HackType: Hack
|
||||||
Target: DiscordPlayer
|
Target: DiscordPlayer
|
||||||
Timestamp: DateTime }
|
Timestamp: DateTime }
|
||||||
|
|
||||||
@ -71,11 +68,11 @@ type Defense =
|
|||||||
type Player =
|
type Player =
|
||||||
{ DiscordId: uint64
|
{ DiscordId: uint64
|
||||||
Name: string
|
Name: string
|
||||||
Weapons: Weapon array
|
Weapons: Hack array
|
||||||
Shields: Shield array
|
Shields: Shield array
|
||||||
Attacks: Attack array
|
Attacks: Attack array
|
||||||
Defenses: Defense array
|
Defenses: Defense array
|
||||||
Bank: single }
|
Bank: int }
|
||||||
|
|
||||||
|
|
||||||
let createSimpleResponseAsync msg (ctx: InteractionContext) =
|
let createSimpleResponseAsync msg (ctx: InteractionContext) =
|
||||||
|
@ -13,3 +13,5 @@ nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01061
|
|||||||
nuget MongoDB.Driver
|
nuget MongoDB.Driver
|
||||||
|
|
||||||
nuget dotenv.net 3.1.1
|
nuget dotenv.net 3.1.1
|
||||||
|
|
||||||
|
nuget DanielStout.AsciiTableFormatter
|
||||||
|
@ -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
|
||||||
|
DanielStout.AsciiTableFormatter (1.1)
|
||||||
DnsClient (1.5)
|
DnsClient (1.5)
|
||||||
Microsoft.Win32.Registry (>= 5.0)
|
Microsoft.Win32.Registry (>= 5.0)
|
||||||
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net471)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net471)) (&& (== netstandard2.1) (< netstandard2.0))
|
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net471)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net471)) (&& (== netstandard2.1) (< netstandard2.0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user