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
}
[ DbService.updatePlayer <| updatePlayer prize (event false) attacker
DbService.updatePlayer <| updatePlayer -prize (event true) defender ]
[ DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer prize (event false) attacker
DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer -prize (event true) defender ]
|> Async.Parallel
|> Async.Ignore
@ -190,7 +190,8 @@ let handleDefense (ctx : IDiscordContext) =
IsInstigator = true
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()
builder.WithContent($"{ctx.GetDiscordMember().Username} has protected their system!") |> ignore
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
@ -209,7 +210,8 @@ let arsenal (ctx : IDiscordContext) =
builder.AddEmbed(embed) |> ignore
builder.IsEphemeral <- true
do! ctx.FollowUp(builder) |> Async.AwaitTask
do! DbService.updatePlayer updatedPlayer
do! DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer
|> Async.Ignore
})
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =

View File

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

View File

@ -24,9 +24,11 @@ type SlotMachine() =
|| (results.[0] <> results.[1] && results.[1] <> results.[2] && results.[0] <> results.[2])
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
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)

View File

@ -52,7 +52,8 @@ let handleBuyItem (ctx : IDiscordContext) itemId =
|> handleResultWithResponse ctx (fun player -> async {
let newBalance = player.Bank - item.Price
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"
})
})
@ -72,7 +73,8 @@ let handleSell (ctx : IDiscordContext) itemId =
then player.Events |> Array.filter (fun a -> a.ItemId <> itemId)
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}"
})
})

View File

@ -176,7 +176,8 @@ let handleSteal (ctx : IDiscordContext) =
Cooldown = VictimRecovery.Minutes * 1<mins>
}
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 -> ()
let stole = {
@ -189,10 +190,12 @@ let handleSteal (ctx : IDiscordContext) =
Cooldown = ThiefCooldown.Minutes * 1<mins>
}
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 ->
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! Async.Sleep 2000
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 = true
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(", you'll need em to survive\n\n") |> ignore
@ -179,7 +180,8 @@ let handleArsenal (ctx : IDiscordContext) =
else
Player.removeExpiredActions player
if not hasStockWeapons then
do! DbService.updatePlayer updatedPlayer
do! DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer
|> Async.Ignore
let embed = Embeds.getArsenalEmbed updatedPlayer
do! ctx.FollowUp(embed) |> Async.AwaitTask
// TODO DB:

View File

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