updatePlayer, achievements, and find player queries

This commit is contained in:
Joseph Ferano 2022-02-22 13:06:22 +07:00
parent 24ce8bdc7f
commit fc56b4a64b
7 changed files with 70 additions and 62 deletions

View File

@ -82,8 +82,8 @@ let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerDa
| false , false -> PlayerEventResult.Negative | false , false -> PlayerEventResult.Negative
} }
[ DbService.updatePlayer <| updatePlayer prize (event false) attacker [ DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer prize (event false) attacker
DbService.updatePlayer <| updatePlayer -prize (event true) defender ] DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer -prize (event true) defender ]
|> Async.Parallel |> Async.Parallel
|> Async.Ignore |> Async.Ignore
@ -190,7 +190,8 @@ let handleDefense (ctx : IDiscordContext) =
IsInstigator = true IsInstigator = true
Adversary = DiscordPlayer.empty Adversary = DiscordPlayer.empty
} }
do! DbService.updatePlayer <| { p with Events = Array.append [| defense |] p.Events } do! DbService.updatePlayer GuildEnvironment.pgDb <| { p with Events = Array.append [| defense |] p.Events }
|> Async.Ignore
let builder = DiscordMessageBuilder() let builder = DiscordMessageBuilder()
builder.WithContent($"{ctx.GetDiscordMember().Username} has protected their system!") |> ignore builder.WithContent($"{ctx.GetDiscordMember().Username} has protected their system!") |> ignore
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle) let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
@ -209,7 +210,8 @@ let arsenal (ctx : IDiscordContext) =
builder.AddEmbed(embed) |> ignore builder.AddEmbed(embed) |> ignore
builder.IsEphemeral <- true builder.IsEphemeral <- true
do! ctx.FollowUp(builder) |> Async.AwaitTask do! ctx.FollowUp(builder) |> Async.AwaitTask
do! DbService.updatePlayer updatedPlayer do! DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer
|> Async.Ignore
}) })
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) = let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =

View File

@ -29,7 +29,7 @@ module Commands =
| Some _ -> async.Return false | Some _ -> async.Return false
| None -> | None ->
async { async {
do! newPlayer "" discordId |> DbService.insertNewPlayer // do! newPlayer "" discordId |> DbService.insertNewPlayer
return true return true
} }
return newPlayer return newPlayer

View File

@ -24,9 +24,11 @@ type SlotMachine() =
|| (results.[0] <> results.[1] && results.[1] <> results.[2] && results.[0] <> results.[2]) || (results.[0] <> results.[1] && results.[1] <> results.[2] && results.[0] <> results.[2])
if winConditions then if winConditions then
do! DbService.updatePlayer { player with Bank = player.Bank + 10<GBT> } do! DbService.updatePlayer GuildEnvironment.pgDb { player with Bank = player.Bank + 10<GBT> }
|> Async.Ignore
else else
do! DbService.updatePlayer { player with Bank = max (player.Bank - 1<GBT>) 0<GBT> } do! DbService.updatePlayer GuildEnvironment.pgDb { player with Bank = max (player.Bank - 1<GBT>) 0<GBT> }
|> Async.Ignore
do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource) do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource)

View File

@ -52,7 +52,8 @@ let handleBuyItem (ctx : IDiscordContext) itemId =
|> handleResultWithResponse ctx (fun player -> async { |> handleResultWithResponse ctx (fun player -> async {
let newBalance = player.Bank - item.Price let newBalance = player.Bank - item.Price
let p = { player with Bank = newBalance ; Inventory = Array.append [| item |] player.Inventory } let p = { player with Bank = newBalance ; Inventory = Array.append [| item |] player.Inventory }
do! DbService.updatePlayer p do! DbService.updatePlayer GuildEnvironment.pgDb p
|> Async.Ignore
do! sendFollowUpMessage ctx $"Successfully purchased {item.Name}! You now have {newBalance} 💰$GBT remaining" do! sendFollowUpMessage ctx $"Successfully purchased {item.Name}! You now have {newBalance} 💰$GBT remaining"
}) })
}) })
@ -72,7 +73,8 @@ let handleSell (ctx : IDiscordContext) itemId =
then player.Events |> Array.filter (fun a -> a.ItemId <> itemId) then player.Events |> Array.filter (fun a -> a.ItemId <> itemId)
else player.Events else player.Events
} }
do! DbService.updatePlayer updatedPlayer do! DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer
|> Async.Ignore
do! sendFollowUpMessage ctx $"Sold {item.Type} {item.Name} for {item.Price}! Current Balance: {updatedPlayer.Bank}" do! sendFollowUpMessage ctx $"Sold {item.Type} {item.Name} for {item.Price}! Current Balance: {updatedPlayer.Bank}"
}) })
}) })

View File

@ -176,7 +176,8 @@ let handleSteal (ctx : IDiscordContext) =
Cooldown = VictimRecovery.Minutes * 1<mins> Cooldown = VictimRecovery.Minutes * 1<mins>
} }
let actions = t |> Player.removeExpiredActions |> fun p -> Array.append [| mugged |] p.Events let actions = t |> Player.removeExpiredActions |> fun p -> Array.append [| mugged |] p.Events
do! DbService.updatePlayer { t with Bank = max (t.Bank - prize) 0<GBT> ; Events = actions } do! DbService.updatePlayer GuildEnvironment.pgDb { t with Bank = max (t.Bank - prize) 0<GBT> ; Events = actions }
|> Async.Ignore
| None -> () | None -> ()
let stole = { let stole = {
@ -189,10 +190,12 @@ let handleSteal (ctx : IDiscordContext) =
Cooldown = ThiefCooldown.Minutes * 1<mins> Cooldown = ThiefCooldown.Minutes * 1<mins>
} }
let actions = thief |> Player.removeExpiredActions |> fun p -> Array.append [| stole |] p.Events let actions = thief |> Player.removeExpiredActions |> fun p -> Array.append [| stole |] p.Events
do! DbService.updatePlayer { thief with Bank = thief.Bank + prize ; Events = actions } do! DbService.updatePlayer GuildEnvironment.pgDb { thief with Bank = thief.Bank + prize ; Events = actions }
|> Async.Ignore
| false -> | false ->
let embed = getResultEmbed' WentToPrison let embed = getResultEmbed' WentToPrison
do! DbService.updatePlayer { thief with Events = Array.append [| stealAction PlayerEventResult.Neutral |] thief.Events } do! DbService.updatePlayer GuildEnvironment.pgDb { thief with Events = Array.append [| stealAction PlayerEventResult.Neutral |] thief.Events }
|> Async.Ignore
do! Messaging.sendFollowUpEmbed ctx (embed.Build()) do! Messaging.sendFollowUpEmbed ctx (embed.Build())
do! Async.Sleep 2000 do! Async.Sleep 2000
let role = ctx.GetGuild().GetRole(GuildEnvironment.rolePrisoner) let role = ctx.GetGuild().GetRole(GuildEnvironment.rolePrisoner)

View File

@ -152,7 +152,8 @@ let handleHack (ctx : IDiscordContext) =
// let isFirstTrainer = player.Achievements |> Seq.contains trainerAchievement |> not // let isFirstTrainer = player.Achievements |> Seq.contains trainerAchievement |> not
let isFirstTrainer = true let isFirstTrainer = true
if isFirstTrainer then if isFirstTrainer then
do! DbService.addAchievement player.DiscordId trainerAchievement do! DbService.addAchievement GuildEnvironment.pgDb player.DiscordId trainerAchievement
|> Async.Ignore
sb.Append($"I'm going to gift you a hack,`{defaultHack.Name}` and a shield, `{defaultShield.Name}`") |> ignore sb.Append($"I'm going to gift you a hack,`{defaultHack.Name}` and a shield, `{defaultShield.Name}`") |> ignore
sb.Append(", you'll need em to survive\n\n") |> ignore sb.Append(", you'll need em to survive\n\n") |> ignore
@ -179,7 +180,8 @@ let handleArsenal (ctx : IDiscordContext) =
else else
Player.removeExpiredActions player Player.removeExpiredActions player
if not hasStockWeapons then if not hasStockWeapons then
do! DbService.updatePlayer updatedPlayer do! DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer
|> Async.Ignore
let embed = Embeds.getArsenalEmbed updatedPlayer let embed = Embeds.getArsenalEmbed updatedPlayer
do! ctx.FollowUp(embed) |> Async.AwaitTask do! ctx.FollowUp(embed) |> Async.AwaitTask
// TODO DB: // TODO DB:

View File

@ -3,9 +3,8 @@
open Degenz.Types open Degenz.Types
open System open System
open MongoDB.Bson //open MongoDB.Bson
open MongoDB.Bson.Serialization //open MongoDB.Driver
open MongoDB.Driver
open Npgsql.FSharp open Npgsql.FSharp
type User = { type User = {
@ -16,17 +15,7 @@ type User = {
Inventory : int array Inventory : int array
} }
let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING")) let mapBack user : PlayerData =
let db = mongo.GetDatabase("degenz")
let players = db.GetCollection<BsonDocument>("players")
let tryWithDefault (bson : BsonDocument) field (defaultValue : 'a) (map : BsonValue -> 'a) =
try
let result , bval = bson.TryGetValue(field)
if result then map bval else defaultValue
with _ -> defaultValue
let mapBack user (bson : BsonDocument) : PlayerData =
{ DiscordId = user.DiscordId { DiscordId = user.DiscordId
Name = user.Name Name = user.Name
Inventory = Inventory =
@ -38,11 +27,7 @@ let mapBack user (bson : BsonDocument) : PlayerData =
| Some i -> [| i |] | Some i -> [| i |]
| None -> [||]) | None -> [||])
|> Array.concat |> Array.concat
Events = tryWithDefault bson "Events" [||] (fun v -> Events = [||]
v.AsBsonArray
|> Seq.map (fun (bv : BsonValue) ->
BsonSerializer.Deserialize<PlayerEvent>(bv.ToBsonDocument()))
|> Seq.toArray)
Traits = { PlayerTraits.empty with Strength = user.Strength } Traits = { PlayerTraits.empty with Strength = user.Strength }
// Achievements = // Achievements =
// tryWithDefault bson "Achievements" [||] (fun v -> // tryWithDefault bson "Achievements" [||] (fun v ->
@ -53,47 +38,59 @@ let mapBack user (bson : BsonDocument) : PlayerData =
let tryFindPlayer connStr (id : uint64) = let tryFindPlayer connStr (id : uint64) =
async { async {
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
let! player = players.FindAsync<BsonDocument>(filter) |> Async.AwaitTask
let! user = let! user =
connStr connStr
|> Sql.connect |> Sql.connect
|> Sql.query "SELECT * FROM users WHERE discordId = @did" |> Sql.query "SELECT * FROM users WHERE discord_id = @did"
|> Sql.parameters [ "did", Sql.int64 (int64 id) ] |> Sql.parameters [ "did", Sql.string (string id) ]
|> Sql.executeAsync (fun read -> |> Sql.executeAsync (fun read ->
{ {
DiscordId = read.int64 "discordId" |> uint64 DiscordId = read.string "discord_id" |> uint64
Name = read.string "displayName" Name = read.string "display_name"
Bank = read.int "gbt" * 1<GBT> Bank = read.int "gbt" * 1<GBT>
Strength = read.int "strength" Strength = read.int "strength"
Inventory = read.intArray "inventory" Inventory = read.intArray "inventory"
}) })
|> Async.AwaitTask |> Async.AwaitTask
match player.FirstOrDefault() , List.tryHead user with match List.tryHead user with
| null , _ | None -> return None
| _ , None -> return None | Some u -> return Some (mapBack u)
| p , Some u ->
let v = p.GetValue("Player")
let playerData = mapBack u (v.ToBsonDocument())
return Some playerData
} }
let insertNewPlayer (player : PlayerData) = //let insertNewPlayer (player : PlayerData) =
async { // async {
do! BsonDocument("Player", player.ToBsonDocument()) |> players.InsertOneAsync |> Async.AwaitTask // do! BsonDocument("Player", player.ToBsonDocument()) |> players.InsertOneAsync |> Async.AwaitTask
} // }
let updatePlayer (player : PlayerData) = let updatePlayer connStr (player : PlayerData) =
async { connStr
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", player.DiscordId) |> Sql.connect
let update = Builders<BsonDocument>.Update.Set("Player", player.ToBsonDocument()) |> Sql.query ("UPDATE users " +
do! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore "SET bank = @bank, strength = @str, inventory = @inv " +
} "WHERE discordId = @did")
|> Sql.parameters [
"did", Sql.string (string player.DiscordId)
"bank", Sql.int (int player.Bank)
"str", Sql.int (int player.Traits.Strength)
"inv", Sql.intArray (player.Inventory |> Array.map (fun i -> i.Id))
]
|> Sql.executeNonQueryAsync
|> Async.AwaitTask
let addAchievement (id : uint64) (achievement : string) = //let addAchievement (id : uint64) (achievement : string) =
async { // async {
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id) // let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
let update = Builders<BsonDocument>.Update.Push("Player.Achievements", achievement) // let update = Builders<BsonDocument>.Update.Push("Player.Achievements", achievement)
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore // return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
} // }
let addAchievement connStr (did : uint64) (achievement : string) =
connStr
|> Sql.connect
|> Sql.query ("WITH ach_id AS (INSERT INTO achievement (symbol) VALUES (@symbol)), " +
" usr_id AS (SELECT id FROM user WHERE discord_id = @did" +
"INSERT INTO user_achievements_achievement (user_id, achievement_id) VALUES (usr_id, ach_id) ")
|> Sql.parameters [ ( "did" , Sql.string (string did) ) ; ( "achievement", Sql.string achievement ) ]
|> Sql.executeNonQueryAsync
|> Async.AwaitTask