From c1c51dcd9946ee107a2febf6999724d68d19c068 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 16 Feb 2022 00:36:29 +0700 Subject: [PATCH] Refactoring data model to new stuff --- Bot/PlayerInteractions.fs | 3 +- Bot/Thief.fs | 2 +- DbService/DbService.fs | 90 +++++++++++++++++---------------------- Shared/Shared.fs | 20 +++++---- 4 files changed, 54 insertions(+), 61 deletions(-) diff --git a/Bot/PlayerInteractions.fs b/Bot/PlayerInteractions.fs index 5a97e0c..85a2987 100644 --- a/Bot/PlayerInteractions.fs +++ b/Bot/PlayerInteractions.fs @@ -17,7 +17,8 @@ module Commands = Arsenal = [| hack ; shield |] Actions = [||] XP = 0 - Stats = PlayerStats.empty + Achievements = [||] + Traits = PlayerTraits.empty Bank = 100 } let addHackerRole (ctx : InteractionContext) = diff --git a/Bot/Thief.fs b/Bot/Thief.fs index 686c0ff..9090245 100644 --- a/Bot/Thief.fs +++ b/Bot/Thief.fs @@ -133,7 +133,7 @@ let steal target amount (ctx : IDiscordContext) = |> checkVictimStealingCooldown defender >>= checkThiefCooldown |> handleResultWithResponse ctx (fun _ -> async { - let cappedPrize , winPercentage = calculateWinPercentage amount (int defender.Bank) attacker.Stats.Strength defender.Stats.Strength + let cappedPrize , winPercentage = calculateWinPercentage amount (int defender.Bank) attacker.Traits.Strength defender.Traits.Strength let embed = getStealEmbed winPercentage cappedPrize defender do! ctx.FollowUp(embed) |> Async.AwaitTask diff --git a/DbService/DbService.fs b/DbService/DbService.fs index b5be678..5efacc2 100644 --- a/DbService/DbService.fs +++ b/DbService/DbService.fs @@ -23,10 +23,7 @@ type DefenseAction = type PlayerEntry = { DiscordId : uint64 Name : string - Arsenal : int array - Attacks : AttackAction array - Defenses : DefenseAction array -// XP : int + XP : int Bank : int } let private actionToAttack (action : Action) (hack : AttackResult) = @@ -52,46 +49,30 @@ let private defenseToAction (action : DefenseAction) = let private playerMap (player : PlayerData) = { DiscordId = player.DiscordId Name = player.Name - Arsenal = player.Arsenal |> Array.map (fun w -> w.Id) - Attacks = player.Actions - |> Array.choose (fun a -> match a.Type with Attack ar -> Some (actionToAttack a ar) | _ -> None) - Defenses = player.Actions - |> Array.choose (fun a -> match a.Type with Defense -> Some (actionToDefense a) | _ -> None) + XP = player.XP Bank = int player.Bank } -let private mapBack (player : PlayerEntry) : PlayerData = { - DiscordId = player.DiscordId - Name = player.Name - Arsenal = player.Arsenal |> Array.map (fun w -> Armory.battleItems |> 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 - Stats = PlayerStats.empty - XP = 0 - Bank = player.Bank * 1 +let tryWithDefault (bson : BsonDocument) field (defaultValue : 'a) (map : BsonValue -> 'a) = + let result , bval = bson.TryGetValue(field) + if result then map bval else defaultValue + +let private mapBack (bson : BsonDocument) : PlayerData = + { DiscordId = tryWithDefault bson "Player.DiscordId" 0uL (fun v -> v.AsInt64 |> uint64) + Name = tryWithDefault bson "Player.Name" "Empty" (fun v -> v.AsString) + Arsenal = + tryWithDefault bson "Inventory" [||] (fun v -> + v.AsBsonArray + |> Seq.map (fun (bv : BsonValue) -> bv.AsInt32) + |> Seq.map (fun w -> Armory.battleItems |> Array.find (fun w' -> w = w'.Id)) + |> Seq.toArray) + Actions = tryWithDefault bson "Events" [||] (fun _ -> [||]) + Traits = tryWithDefault bson "Traits" PlayerTraits.empty (fun _ -> PlayerTraits.empty) + Achievements = tryWithDefault bson "Achievements" [||] (fun _ -> [||]) + XP = tryWithDefault bson "XP" 0 (fun _ -> 0) + Bank = tryWithDefault bson "Player.Bank" 0 (fun v -> v.AsInt32 * 1) } -//let private mapBack (bson : BsonDocument) : PlayerData = { -// DiscordId = bson.GetValue("Player.DiscordId").AsInt64 |> uint64 -// Name = bson.GetValue("Player.Name").AsString -// Arsenal = -// bson.GetValue("Inventory").AsBsonArray -// |> Seq.map (fun (bv : BsonValue) -> bv.AsInt32) -// |> Seq.map (fun w -> Armory.battleItems |> Array.find (fun w' -> w = w'.Id)) -// |> Seq.toArray -// Actions = -// let atks = player.Attacks |> Array.map attackToAction -// let dfns = player.Defenses |> Array.map defenseToAction -// Array.append atks dfns -// Stats = PlayerStats.empty -// XP = 0 -// Bank = player.Bank * 1 -//} -// - - let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING")) let db = mongo.GetDatabase("degenz") let players = db.GetCollection("players") @@ -105,11 +86,22 @@ let tryFindPlayer (id : uint64) = | p -> return p .GetValue("Player") .ToBsonDocument() - |> BsonSerializer.Deserialize |> mapBack |> Some } +let updatePlayer (player : PlayerData) = + async { + let filter = Builders.Filter.Eq("Player.DiscordId", player.DiscordId) + let update = Builders.Update + .Set("Player", playerMap player) + .AddToSet("Traits", player.Traits) + .AddToSet("Events", player.Actions) + .AddToSet("Achievements", player.Achievements) + .AddToSet("Inventory", player.Arsenal) + return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore + } + let getAchievements (id : uint64) = async { let filter = Builders.Filter.Eq("Player.DiscordId", id) @@ -128,14 +120,19 @@ let getAchievements (id : uint64) = let addAchievement (id : uint64) (achievement : string) = async { let filter = Builders.Filter.Eq("Player.DiscordId", id) - let update = Builders.Update.Push("achievements", achievement) + let update = Builders.Update.Push("Achievements", achievement) return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore } let insertNewPlayer (player : PlayerData) = async { - let p = playerMap player - let dict = [ KeyValuePair("Player" , p.ToBsonDocument() :> Object) ] + let dict = [ + KeyValuePair("Player" , (playerMap player).ToBsonDocument() :> Object) + KeyValuePair("Events" , [||] :> Object) + KeyValuePair("Inventory" , [||] :> Object) + KeyValuePair("Traits" , PlayerTraits.empty.ToBsonDocument() :> Object) + KeyValuePair("XP" , 0 :> Object) + ] do! BsonDocument(dict) |> players.InsertOneAsync |> Async.AwaitTask @@ -149,13 +146,6 @@ let insertNewPlayer (player : PlayerData) = // |> Async.AwaitTask // } // -let updatePlayer (player : PlayerData) = - async { - let filter = Builders.Filter.Eq("Player.DiscordId", player.DiscordId) - let update = Builders.Update.Set("Player", playerMap player) - return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore - } - //let getTopPlayers amount = // async { // return! players.FindAsync() diff --git a/Shared/Shared.fs b/Shared/Shared.fs index f263f14..c69ebd3 100644 --- a/Shared/Shared.fs +++ b/Shared/Shared.fs @@ -95,7 +95,7 @@ module Types = | Strength = 0 | Cunning = 1 - type PlayerStats = { + type PlayerTraits = { Strength : int Focus : int } @@ -106,14 +106,16 @@ module Types = } [] - type PlayerData = - { DiscordId : uint64 - Name : string - Arsenal : BattleItem array - Actions : Action array - Stats : PlayerStats - XP : int - Bank : int } + type PlayerData = { + DiscordId : uint64 + Name : string + Arsenal : BattleItem array + Actions : Action array + Traits : PlayerTraits + Achievements : string array + XP : int + Bank : int + } module Armory = let battleItems =