132 lines
4.6 KiB
Forth
132 lines
4.6 KiB
Forth
module Degenz.DbService
|
|
|
|
open System
|
|
open System.Collections.Generic
|
|
open MongoDB.Bson
|
|
open MongoDB.Bson.Serialization
|
|
open MongoDB.Driver
|
|
open Degenz.Types
|
|
|
|
[<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
|
|
XP : int
|
|
Bank : int }
|
|
|
|
let private playerMap (player : PlayerData) = {
|
|
DiscordId = player.DiscordId
|
|
Name = player.Name
|
|
XP = player.XP
|
|
Bank = int player.Bank
|
|
}
|
|
|
|
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)
|
|
Inventory =
|
|
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)
|
|
Events = 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<GBT> (fun v -> v.AsInt32 * 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()
|
|
|> mapBack
|
|
|> Some
|
|
}
|
|
|
|
let updatePlayer (player : PlayerData) =
|
|
async {
|
|
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", player.DiscordId)
|
|
let update = Builders<BsonDocument>.Update
|
|
.Set("Player", playerMap player)
|
|
.AddToSet("Traits", player.Traits)
|
|
.AddToSet("Events", player.Events)
|
|
.AddToSet("Achievements", player.Achievements)
|
|
.AddToSet("Inventory", player.Inventory)
|
|
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
|
}
|
|
|
|
let getAchievements (id : uint64) =
|
|
async {
|
|
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
|
|
try
|
|
let! player = players.FindAsync<BsonDocument>(filter) |> Async.AwaitTask
|
|
match player.FirstOrDefault() with
|
|
| null -> return None
|
|
| p -> return p
|
|
.GetValue("achievements")
|
|
.AsBsonArray
|
|
|> Seq.map (fun (bv : BsonValue) -> bv.AsString)
|
|
|> Some
|
|
with ex -> return None
|
|
}
|
|
|
|
let addAchievement (id : uint64) (achievement : string) =
|
|
async {
|
|
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
|
|
let update = Builders<BsonDocument>.Update.Push("Achievements", achievement)
|
|
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
|
}
|
|
|
|
let insertNewPlayer (player : PlayerData) =
|
|
async {
|
|
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
|
|
}
|
|
|
|
//let deletePlayer (player : PlayerData) =
|
|
// async {
|
|
// let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
|
// do! BsonDocument(dict)
|
|
// |> players.InsertOneAsync
|
|
// |> Async.AwaitTask
|
|
// }
|
|
//
|
|
//let getTopPlayers amount =
|
|
// async {
|
|
// return! players.FindAsync()
|
|
// } |