121 lines
3.7 KiB
Forth

module Degenz.DbService
open System
open System.Collections.Generic
open System.Threading.Tasks
open Degenz.Types
open MongoDB.Bson
open MongoDB.Bson.Serialization
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 = 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)
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
Bank = player.Bank * 1<GBT>
}
let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING"))
let db = mongo.GetDatabase("degenz")
let players = db.GetCollection<BsonDocument>("players")
let tryFindPlayer (id : uint64) =
async {
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
let! player = players.FindAsync<BsonDocument>(filter) |> Async.AwaitTask
match player.FirstOrDefault() with
| null -> return None
| p -> return p
.GetValue("Player")
.ToBsonDocument()
|> BsonSerializer.Deserialize<PlayerEntry>
|> mapBack
|> Some
}
let insertNewPlayer (player : PlayerData) =
async {
let p = playerMap player
let dict = [ KeyValuePair("Player" , p.ToBsonDocument() :> Object) ]
do! BsonDocument(dict)
|> players.InsertOneAsync
|> Async.AwaitTask
}
//let deletePlayer (player : PlayerData) =
// async {
// let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
// do! BsonDocument(dict)
// |> players.InsertOneAsync
// |> Async.AwaitTask
// }
//
let updatePlayer (player : PlayerData) =
async {
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", player.DiscordId)
let update = Builders<BsonDocument>.Update.Set("Player", playerMap player)
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
}
//let getTopPlayers amount =
// async {
// return! players.FindAsync()
// }