Fixing some trainer bugs, mapping value cause Mongo hates F#
This commit is contained in:
parent
7c8a460d5b
commit
7b48ff0a9b
@ -26,7 +26,6 @@ for conf in configs do
|
|||||||
conf.TokenType <- TokenType.Bot
|
conf.TokenType <- TokenType.Bot
|
||||||
conf.Intents <- DiscordIntents.All
|
conf.Intents <- DiscordIntents.All
|
||||||
|
|
||||||
|
|
||||||
let guild = GuildEnvironment.guildId
|
let guild = GuildEnvironment.guildId
|
||||||
|
|
||||||
playerInteractionsConfig.Token <- GuildEnvironment.tokenPlayerInteractions
|
playerInteractionsConfig.Token <- GuildEnvironment.tokenPlayerInteractions
|
||||||
|
@ -84,7 +84,7 @@ let responseSuccessfulHackTrainer defenderName (hack : BattleItem) prize =
|
|||||||
embed.ImageUrl <- getHackGif (enum<HackId>(hack.Id))
|
embed.ImageUrl <- getHackGif (enum<HackId>(hack.Id))
|
||||||
|
|
||||||
DiscordFollowupMessageBuilder()
|
DiscordFollowupMessageBuilder()
|
||||||
.WithContent($"Successfully hacked {defenderName} using {hack}! You just won {prize} GoodBoyTokenz!")
|
.WithContent($"Successfully hacked {defenderName} using {hack.Name}! You just won {prize} GoodBoyTokenz!")
|
||||||
.AddEmbed(embed.Build())
|
.AddEmbed(embed.Build())
|
||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ open DSharpPlus.EventArgs
|
|||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Degenz
|
open Degenz
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
|
open Degenz.Store
|
||||||
|
|
||||||
let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
|
let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
|
||||||
let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
|
let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
|
||||||
@ -42,7 +43,7 @@ let checkIfHackHasCooldown hackId attacker =
|
|||||||
|> Array.tryFind (fun a -> a.ActionId = hackId)
|
|> Array.tryFind (fun a -> a.ActionId = hackId)
|
||||||
|> function
|
|> function
|
||||||
| Some a -> a.Timestamp
|
| Some a -> a.Timestamp
|
||||||
| None -> DateTime.MinValue
|
| None -> DateTime.MinValue;
|
||||||
if DateTime.UtcNow - mostRecentHackAttack > TimeSpan.FromMinutes(5) then
|
if DateTime.UtcNow - mostRecentHackAttack > TimeSpan.FromMinutes(5) then
|
||||||
Ok attacker
|
Ok attacker
|
||||||
else
|
else
|
||||||
@ -56,7 +57,7 @@ let checkIfInventoryIsEmpty attacker =
|
|||||||
| _ -> Ok attacker
|
| _ -> Ok attacker
|
||||||
|
|
||||||
let calculateDamage (hack : BattleItem) (shield : BattleItem) =
|
let calculateDamage (hack : BattleItem) (shield : BattleItem) =
|
||||||
if hack.Power > shield.Power
|
if hack.Class = shield.Class
|
||||||
then Strong
|
then Strong
|
||||||
else Weak
|
else Weak
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ let updateCombatants attacker defender hack prize =
|
|||||||
let updatePlayer amount attack p =
|
let updatePlayer amount attack p =
|
||||||
{ p with Actions = Array.append [| attack |] p.Actions ; Bank = max (p.Bank + amount) 0<GBT> }
|
{ p with Actions = Array.append [| attack |] p.Actions ; Bank = max (p.Bank + amount) 0<GBT> }
|
||||||
let target = { Id = defender.DiscordId ; Name = defender.Name }
|
let target = { Id = defender.DiscordId ; Name = defender.Name }
|
||||||
let attack = { ActionId = int hack ; Type = Attack ( target , prize > 0<GBT> ) ; Timestamp = DateTime.UtcNow }
|
let attack = { ActionId = int hack ; Type = Attack { Target = target ; Result = prize > 0<GBT> } ; Timestamp = DateTime.UtcNow }
|
||||||
|
|
||||||
[ DbService.updatePlayer <| updatePlayer prize attack attacker
|
[ DbService.updatePlayer <| updatePlayer prize attack attacker
|
||||||
DbService.updatePlayer <| modifyPlayerBank defender -prize ]
|
DbService.updatePlayer <| modifyPlayerBank defender -prize ]
|
||||||
@ -179,7 +180,7 @@ let defend (ctx : InteractionContext) =
|
|||||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||||
match player with
|
match player with
|
||||||
| Some player ->
|
| Some player ->
|
||||||
if Player.defenses player |> Array.length > 0 then
|
if Player.shields player |> Array.length > 0 then
|
||||||
let embed = Embeds.pickDefense "Defend" player
|
let embed = Embeds.pickDefense "Defend" player
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"Case": "Hack"
|
"Case": "Hack"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Exploit"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -45,7 +45,7 @@
|
|||||||
"Case": "Hack"
|
"Case": "Hack"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Exploit"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -58,7 +58,7 @@
|
|||||||
"Case": "Hack"
|
"Case": "Hack"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Penetration"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -71,7 +71,7 @@
|
|||||||
"Case": "Hack"
|
"Case": "Hack"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Penetration"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -110,7 +110,7 @@
|
|||||||
"Case": "Shield"
|
"Case": "Shield"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Exploit"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -123,7 +123,7 @@
|
|||||||
"Case": "Shield"
|
"Case": "Shield"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Penetration"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -136,7 +136,7 @@
|
|||||||
"Case": "Shield"
|
"Case": "Shield"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Penetration"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
@ -149,7 +149,7 @@
|
|||||||
"Case": "Shield"
|
"Case": "Shield"
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"Case": "Network"
|
"Case": "Exploit"
|
||||||
},
|
},
|
||||||
"Cost": 100,
|
"Cost": 100,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
|
@ -1,77 +1,48 @@
|
|||||||
module Degenz.PlayerInteractions
|
module Degenz.PlayerInteractions
|
||||||
|
|
||||||
open System
|
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
open AsciiTableFormatter
|
|
||||||
open DSharpPlus.Entities
|
open DSharpPlus.Entities
|
||||||
open DSharpPlus
|
open DSharpPlus
|
||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Degenz
|
open Degenz.Store
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
|
|
||||||
module Commands =
|
module Commands =
|
||||||
// let newPlayer nickname (membr : uint64) =
|
let newPlayer nickname (membr : uint64) =
|
||||||
// let h1 = [| Weapon.Virus ; Weapon.Ransom |]
|
|
||||||
// let h2 = [| Weapon.DDos ; Weapon.Worm |]
|
|
||||||
// let h3 = [| Weapon.Crack ; Weapon.Injection |]
|
|
||||||
// let d1 = [| Shield.Firewall ; Shield.PortScan |]
|
|
||||||
// let d2 = [| Shield.Encryption ; Shield.Cypher |]
|
|
||||||
// let d3 = [| Shield.Hardening ; Shield.Sanitation |]
|
|
||||||
|
|
||||||
// let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
||||||
// let getRandom (actions : 'a array) = actions.[rand.Next(0, max 0 (actions.Length - 1))]
|
let randHack = rand.Next(0, 3)
|
||||||
//
|
let randShield = rand.Next(3, 6)
|
||||||
// let weapons = [| getRandom hackInventory |]
|
let hack = armoury |> Array.find (fun i -> i.Id = randHack)
|
||||||
// let shields = [| getRandom shieldInventory |]
|
let shield = armoury |> Array.find (fun i -> i.Id = randShield)
|
||||||
//
|
|
||||||
// { DiscordId = membr
|
|
||||||
// Name = nickname
|
|
||||||
// Weapons = weapons
|
|
||||||
// Shields = shields
|
|
||||||
// Attacks = [||]
|
|
||||||
// Defenses = [||]
|
|
||||||
// Bank = 15 }
|
|
||||||
|
|
||||||
// let addHackerRole (ctx : InteractionContext) =
|
{ DiscordId = membr
|
||||||
// async {
|
Name = nickname
|
||||||
// let! player = DbService.tryFindPlayer ctx.Member.Id
|
Arsenal = [| hack ; shield |]
|
||||||
// let! newPlayer =
|
Actions = [||]
|
||||||
// match player with
|
Bank = 100<GBT> }
|
||||||
// | Some _ -> async.Return false
|
|
||||||
// | None ->
|
|
||||||
// async {
|
|
||||||
// do! newPlayer ctx.Member.DisplayName ctx.Member.Id
|
|
||||||
// |> DbService.insertNewPlayer
|
|
||||||
//
|
|
||||||
// for role in ctx.Guild.Roles do
|
|
||||||
// if role.Value.Name = "Hacker" then
|
|
||||||
// do! ctx.Member.GrantRoleAsync(role.Value)
|
|
||||||
// |> Async.AwaitTask
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if newPlayer then
|
|
||||||
// do! ctx.CreateResponseAsync("You are now an elite haxxor", true)
|
|
||||||
// |> Async.AwaitTask
|
|
||||||
// else
|
|
||||||
// do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true)
|
|
||||||
// |> Async.AwaitTask
|
|
||||||
//
|
|
||||||
// } |> Async.StartAsTask
|
|
||||||
// :> Task
|
|
||||||
|
|
||||||
// let removeHackerRole (ctx : InteractionContext) =
|
let addHackerRole (ctx : InteractionContext) =
|
||||||
// async {
|
async {
|
||||||
// for role in ctx.Member.Roles do
|
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||||
// if role.Name = "Hacker" then
|
let! newPlayer =
|
||||||
// do! ctx.Member.RevokeRoleAsync(role)
|
match player with
|
||||||
// |> Async.AwaitTask
|
| Some _ -> async.Return false
|
||||||
|
| None ->
|
||||||
|
async {
|
||||||
|
do! newPlayer ctx.Member.DisplayName ctx.Member.Id
|
||||||
|
|> DbService.insertNewPlayer
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if newPlayer then
|
||||||
|
do! ctx.CreateResponseAsync("You are now an elite haxxor", true)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
else
|
||||||
|
do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true)
|
||||||
|
|> Async.AwaitTask
|
||||||
|
|
||||||
// do! DbService.removePlayer ctx.Member.Id
|
} |> Async.StartAsTask
|
||||||
|
:> Task
|
||||||
// do! ctx.CreateResponseAsync("You are now lame", true)
|
|
||||||
// |> Async.AwaitTask
|
|
||||||
// } |> Async.StartAsTask
|
|
||||||
// :> Task
|
|
||||||
|
|
||||||
[<CLIMutable>]
|
[<CLIMutable>]
|
||||||
type LeaderboardEntry = {
|
type LeaderboardEntry = {
|
||||||
@ -103,18 +74,17 @@ module Commands =
|
|||||||
|
|
||||||
let status (ctx : InteractionContext) =
|
let status (ctx : InteractionContext) =
|
||||||
async {
|
async {
|
||||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
let! maybePlayer = DbService.tryFindPlayer ctx.Member.Id
|
||||||
match player with
|
match maybePlayer with
|
||||||
| Some p ->
|
| Some player ->
|
||||||
// let updatedAttacks = p.Attacks |> removeExpiredActions (TimeSpan.FromHours(24)) (fun (atk : Attack) -> atk.Timestamp)
|
let updatedActions = removeExpiredActions player.Actions
|
||||||
// let updatedDefenses = p.Defenses |> removeExpiredActions (TimeSpan.FromHours(6)) (fun (p : Defense) -> p.Timestamp)
|
let updatedPlayer = { player with Actions = updatedActions }
|
||||||
// let updatedPlayer = { p with Attacks = updatedAttacks ; Defenses = updatedDefenses }
|
|
||||||
// do! DbService.updatePlayer updatedPlayer
|
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
builder.IsEphemeral <- true
|
builder.IsEphemeral <- true
|
||||||
// builder.Content <- statusFormat updatedPlayer
|
builder.Content <- statusFormat updatedPlayer
|
||||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|
do! DbService.updatePlayer updatedPlayer
|
||||||
| None -> do! notYetAHackerMsg ctx
|
| None -> do! notYetAHackerMsg ctx
|
||||||
} |> Async.StartAsTask
|
} |> Async.StartAsTask
|
||||||
:> Task
|
:> Task
|
||||||
@ -122,11 +92,8 @@ module Commands =
|
|||||||
type PlayerInteractions() =
|
type PlayerInteractions() =
|
||||||
inherit ApplicationCommandModule ()
|
inherit ApplicationCommandModule ()
|
||||||
|
|
||||||
// [<SlashCommand("redpill", "Take the redpill and become a hacker")>]
|
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
|
||||||
// member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
|
member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
|
||||||
|
|
||||||
// [<SlashCommand("bluepill", "Take the bluepill and become lame")>]
|
|
||||||
// member _.RemoveHackerRole (ctx : InteractionContext) = Commands.removeHackerRole ctx
|
|
||||||
|
|
||||||
[<SlashCommand("status", "Get your current status like bank account, and active hacks and defenses")>]
|
[<SlashCommand("status", "Get your current status like bank account, and active hacks and defenses")>]
|
||||||
member this.Status (ctx : InteractionContext) = Commands.status ctx
|
member this.Status (ctx : InteractionContext) = Commands.status ctx
|
||||||
|
10
Bot/Store.fs
10
Bot/Store.fs
@ -1,5 +1,6 @@
|
|||||||
module Degenz.Store
|
module Degenz.Store
|
||||||
|
|
||||||
|
open System
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
open DSharpPlus.Entities
|
open DSharpPlus.Entities
|
||||||
open DSharpPlus
|
open DSharpPlus
|
||||||
@ -8,6 +9,15 @@ open DSharpPlus.SlashCommands
|
|||||||
open Degenz
|
open Degenz
|
||||||
open Degenz.Embeds
|
open Degenz.Embeds
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
|
open Newtonsoft.Json
|
||||||
|
|
||||||
|
let getItemFromArmoury id = armoury |> Array.find (fun w -> w.Id = id)
|
||||||
|
|
||||||
|
let removeExpiredActions actions =
|
||||||
|
actions
|
||||||
|
|> Array.filter (fun (act : Action) ->
|
||||||
|
let item = armoury |> Array.find (fun w -> w.Id = act.ActionId)
|
||||||
|
DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown))
|
||||||
|
|
||||||
let viewStore (ctx : InteractionContext) =
|
let viewStore (ctx : InteractionContext) =
|
||||||
async {
|
async {
|
||||||
|
@ -6,6 +6,7 @@ open DSharpPlus.Entities
|
|||||||
open DSharpPlus.EventArgs
|
open DSharpPlus.EventArgs
|
||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Degenz.Shared
|
open Degenz.Shared
|
||||||
|
open Degenz.Store
|
||||||
|
|
||||||
let defaultHack = armoury |> Array.find (fun i -> i.Id = int HackId.Virus)
|
let defaultHack = armoury |> Array.find (fun i -> i.Id = int HackId.Virus)
|
||||||
let defaultShield = armoury |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
|
let defaultShield = armoury |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
|
||||||
@ -54,7 +55,7 @@ let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
|
|||||||
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 weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield
|
let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
||||||
do! Message.sendInteractionEvent 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."
|
||||||
@ -92,11 +93,11 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
|||||||
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! maybePlayer = DbService.tryFindPlayer event.User.Id
|
||||||
match result with
|
match maybePlayer with
|
||||||
| Some player ->
|
| Some player ->
|
||||||
let prize = 0.223f
|
let prize = 0.223f
|
||||||
let shield = player.Arsenal |> Array.tryHead |> Option.defaultValue defaultShield
|
let shield = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield
|
||||||
let embed = Embeds.responseCreatedShieldTrainer shield
|
let embed = Embeds.responseCreatedShieldTrainer shield
|
||||||
do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore
|
do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore
|
||||||
do! Async.Sleep 2000
|
do! Async.Sleep 2000
|
||||||
@ -116,7 +117,7 @@ let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) =
|
|||||||
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 weaponName = player.Arsenal |> Array.tryHead |> Option.defaultValue defaultHack
|
let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
||||||
do! Message.sendInteractionEvent 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."
|
||||||
|
@ -7,6 +7,68 @@ open MongoDB.Bson
|
|||||||
open MongoDB.Bson.Serialization
|
open MongoDB.Bson.Serialization
|
||||||
open MongoDB.Driver
|
open MongoDB.Driver
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type AttackAction =
|
||||||
|
{ ActionId : int
|
||||||
|
Result : bool
|
||||||
|
Target : DiscordPlayer
|
||||||
|
Timestamp : DateTime }
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type DefenseAction =
|
||||||
|
{ ActionId : int
|
||||||
|
Timestamp : DateTime }
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
|
type PlayerEntry =
|
||||||
|
{ DiscordId : uint64
|
||||||
|
Name : string
|
||||||
|
Arsenal : int array
|
||||||
|
Attacks : AttackAction array
|
||||||
|
Defenses : DefenseAction array
|
||||||
|
Bank : int }
|
||||||
|
|
||||||
|
let private actionToAttack (action : Action) (hack : AttackResult) =
|
||||||
|
{ ActionId = action.ActionId
|
||||||
|
Result = hack.Result
|
||||||
|
Target = hack.Target
|
||||||
|
Timestamp = action.Timestamp }
|
||||||
|
|
||||||
|
let private actionToDefense (action : Action) =
|
||||||
|
{ ActionId = action.ActionId
|
||||||
|
Timestamp = action.Timestamp }
|
||||||
|
|
||||||
|
let private attackToAction (attack : AttackAction) =
|
||||||
|
{ ActionId = attack.ActionId
|
||||||
|
Type = Attack { Target = attack.Target ; Result = attack.Result }
|
||||||
|
Timestamp = attack.Timestamp }
|
||||||
|
|
||||||
|
let private defenseToAction (action : DefenseAction) =
|
||||||
|
{ ActionId = action.ActionId
|
||||||
|
Type = Defense
|
||||||
|
Timestamp = action.Timestamp }
|
||||||
|
|
||||||
|
let private playerMap (player : PlayerData) = {
|
||||||
|
DiscordId = player.DiscordId
|
||||||
|
Name = player.Name
|
||||||
|
Arsenal = player.Arsenal |> Array.map (fun w -> w.Id)
|
||||||
|
Attacks = [||]
|
||||||
|
Defenses = [||]
|
||||||
|
Bank = int player.Bank
|
||||||
|
}
|
||||||
|
|
||||||
|
let private mapBack (player : PlayerEntry) : PlayerData = {
|
||||||
|
DiscordId = player.DiscordId
|
||||||
|
Name = player.Name
|
||||||
|
Arsenal = player.Arsenal |> Array.map (fun w -> armoury |> Array.find (fun w' -> w = w'.Id))
|
||||||
|
Actions =
|
||||||
|
let atks = player.Attacks |> Array.map attackToAction
|
||||||
|
let dfns = player.Defenses |> Array.map defenseToAction
|
||||||
|
Array.append atks dfns
|
||||||
|
Bank = player.Bank * 1<GBT>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING"))
|
let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING"))
|
||||||
let db = mongo.GetDatabase("degenz")
|
let db = mongo.GetDatabase("degenz")
|
||||||
let players = db.GetCollection<BsonDocument>("players")
|
let players = db.GetCollection<BsonDocument>("players")
|
||||||
@ -20,30 +82,32 @@ let tryFindPlayer (id : uint64) =
|
|||||||
| p -> return p
|
| p -> return p
|
||||||
.GetValue("Player")
|
.GetValue("Player")
|
||||||
.ToBsonDocument()
|
.ToBsonDocument()
|
||||||
|> BsonSerializer.Deserialize<PlayerData>
|
|> BsonSerializer.Deserialize<PlayerEntry>
|
||||||
|
|> mapBack
|
||||||
|> Some
|
|> Some
|
||||||
}
|
}
|
||||||
|
|
||||||
let insertNewPlayer (player : PlayerData) =
|
let insertNewPlayer (player : PlayerData) =
|
||||||
async {
|
async {
|
||||||
let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
let p = playerMap player
|
||||||
|
let dict = [ KeyValuePair("Player" , p.ToBsonDocument() :> Object) ]
|
||||||
do! BsonDocument(dict)
|
do! BsonDocument(dict)
|
||||||
|> players.InsertOneAsync
|
|> players.InsertOneAsync
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
}
|
}
|
||||||
|
|
||||||
let deletePlayer (player : PlayerData) =
|
//let deletePlayer (player : PlayerData) =
|
||||||
async {
|
// async {
|
||||||
let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
// let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
||||||
do! BsonDocument(dict)
|
// do! BsonDocument(dict)
|
||||||
|> players.InsertOneAsync
|
// |> players.InsertOneAsync
|
||||||
|> Async.AwaitTask
|
// |> Async.AwaitTask
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let updatePlayer player =
|
let updatePlayer (player : PlayerData) =
|
||||||
async {
|
async {
|
||||||
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", player.DiscordId)
|
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", player.DiscordId)
|
||||||
let update = Builders<BsonDocument>.Update.Set("Player", player)
|
let update = Builders<BsonDocument>.Update.Set("Player", playerMap player)
|
||||||
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,15 +55,17 @@ type HackResult =
|
|||||||
[<CLIMutable>]
|
[<CLIMutable>]
|
||||||
type DiscordPlayer = { Id: uint64; Name: string }
|
type DiscordPlayer = { Id: uint64; Name: string }
|
||||||
|
|
||||||
type Attack = {
|
[<CLIMutable>]
|
||||||
|
type AttackResult = {
|
||||||
Result : bool
|
Result : bool
|
||||||
Target : DiscordPlayer
|
Target : DiscordPlayer
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionType =
|
type ActionType =
|
||||||
| Attack of target : DiscordPlayer * result : bool
|
| Attack of AttackResult
|
||||||
| Defense
|
| Defense
|
||||||
|
|
||||||
|
[<CLIMutable>]
|
||||||
type Action =
|
type Action =
|
||||||
{ ActionId : int
|
{ ActionId : int
|
||||||
Type : ActionType
|
Type : ActionType
|
||||||
@ -79,13 +81,13 @@ type PlayerData =
|
|||||||
|
|
||||||
module Player =
|
module Player =
|
||||||
let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
|
let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
|
||||||
let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
|
let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield)
|
||||||
let attacks player =
|
let attacks player =
|
||||||
player.Actions
|
player.Actions
|
||||||
|> Array.choose (fun act -> match act.Type with Attack (t,r) -> Some (act,t,r) | Defense -> None)
|
|> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
|
||||||
let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense _ -> true | _ -> false)
|
let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense _ -> true | _ -> false)
|
||||||
|
|
||||||
let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack (t,r) -> Some (act,t,r) | Defense -> None)
|
let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
|
||||||
|
|
||||||
let createSimpleResponseAsync msg (ctx: InteractionContext) =
|
let createSimpleResponseAsync msg (ctx: InteractionContext) =
|
||||||
async {
|
async {
|
||||||
@ -105,29 +107,21 @@ let hackDescription = ""
|
|||||||
|
|
||||||
let statusFormat p =
|
let statusFormat p =
|
||||||
$"Hacks: {Player.hacks p |> Array.toList}
|
$"Hacks: {Player.hacks p |> Array.toList}
|
||||||
Shields: {Player.defenses p |> Array.toList}
|
Shields: {Player.shields p |> Array.toList}
|
||||||
Hack Attacks: {Player.attacks p |> Array.toList}
|
Hack Attacks: {Player.attacks p |> Array.toList}
|
||||||
Active Defenses: {Player.defenses p |> Array.toList}
|
Active Defenses: {Player.defenses p |> Array.toList}
|
||||||
Bank: {p.Bank}"
|
Bank: {p.Bank}"
|
||||||
|
|
||||||
|
let constructButtons (actionType: string) (playerInfo: string) (weapons: BattleItem array) =
|
||||||
|
weapons
|
||||||
|
|> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"{actionType}-{w.Id}-{playerInfo}", $"{w.Name}"))
|
||||||
|
|
||||||
|
let modifyPlayerBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
|
||||||
|
|
||||||
let armoury =
|
let armoury =
|
||||||
let file = System.IO.File.ReadAllText("Items.json")
|
let file = System.IO.File.ReadAllText("Items.json")
|
||||||
JsonConvert.DeserializeObject<BattleItem array>(file)
|
JsonConvert.DeserializeObject<BattleItem array>(file)
|
||||||
|
|
||||||
let getItemFromArmoury id = armoury |> Array.find (fun w -> w.Id = id)
|
|
||||||
|
|
||||||
let constructButtons (actionType: string) (playerInfo: string) (weapons: 'a array) =
|
|
||||||
weapons
|
|
||||||
|> Seq.map (fun hack -> DiscordButtonComponent(ButtonStyle.Primary, $"{actionType}-{hack}-{playerInfo}", $"{hack}"))
|
|
||||||
|
|
||||||
let removeExpiredActions actions =
|
|
||||||
actions
|
|
||||||
|> Array.filter (fun (act : Action) ->
|
|
||||||
let item = armoury |> Array.find (fun w -> w.Id = act.ActionId)
|
|
||||||
DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown))
|
|
||||||
|
|
||||||
let modifyPlayerBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
|
|
||||||
|
|
||||||
module Message =
|
module Message =
|
||||||
let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg =
|
let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg =
|
||||||
async {
|
async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user