diff --git a/Bot/Game.fs b/Bot/Game.fs index c852d02..7137c32 100644 --- a/Bot/Game.fs +++ b/Bot/Game.fs @@ -32,7 +32,7 @@ module Game = builder.IsEphemeral <- true builder.Content <- "Content" do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask - let! playerResult = tryFindPlayer (ctx.GetDiscordMember().Id) + let! playerResult = tryFindPlayer GuildEnvironment.pgDb (ctx.GetDiscordMember().Id) match playerResult with | Some player -> do! dispatch player | None -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one" @@ -45,8 +45,8 @@ module Game = builder.Content <- "Content" do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! players = - [ tryFindPlayer (ctx.GetDiscordMember().Id) - tryFindPlayer targetPlayer.Id ] + [ tryFindPlayer GuildEnvironment.pgDb (ctx.GetDiscordMember().Id) + tryFindPlayer GuildEnvironment.pgDb targetPlayer.Id ] |> Async.Parallel match players.[0] , players.[1] with | Some player , Some target -> do! dispatch player target @@ -65,8 +65,8 @@ module Game = if defer then do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! players = - [ tryFindPlayer (ctx.GetDiscordMember().Id) - tryFindPlayer targetId ] + [ tryFindPlayer GuildEnvironment.pgDb (ctx.GetDiscordMember().Id) + tryFindPlayer GuildEnvironment.pgDb targetId ] |> Async.Parallel match players.[0] , players.[1] with | Some player , Some target -> do! dispatch player target diff --git a/Bot/GuildEnvironment.fs b/Bot/GuildEnvironment.fs index 81aa5ea..1be2aa8 100644 --- a/Bot/GuildEnvironment.fs +++ b/Bot/GuildEnvironment.fs @@ -11,6 +11,7 @@ DotEnv.Load(DotEnvOptions(envFilePaths = [ "../../../../.dev.env" ], overwriteEx let getVar str = Environment.GetEnvironmentVariable(str) let getId str = getVar str |> uint64 +let pgDb = getVar "CONN_STRING_2" let guildId = getId "DISCORD_GUILD" let tokenPlayerInteractions = getVar "TOKEN_PLAYER_INTERACTIONS" let tokenSteal = getVar "TOKEN_STEAL" diff --git a/Bot/HackerBattle.fs b/Bot/HackerBattle.fs index bbb600b..97b51fa 100644 --- a/Bot/HackerBattle.fs +++ b/Bot/HackerBattle.fs @@ -138,7 +138,7 @@ let handleAttack (ctx : IDiscordContext) = let hackId = int tokens.[1] let hack = Armory.getItem hackId let resultId , targetId = UInt64.TryParse tokens.[2] - let! resultTarget = DbService.tryFindPlayer targetId + let! resultTarget = DbService.tryFindPlayer GuildEnvironment.pgDb targetId match resultTarget , true , resultId with | Some defender , true , true -> diff --git a/Bot/PlayerInteractions.fs b/Bot/PlayerInteractions.fs index a7a7444..593923d 100644 --- a/Bot/PlayerInteractions.fs +++ b/Bot/PlayerInteractions.fs @@ -21,27 +21,19 @@ module Commands = Traits = PlayerTraits.empty Bank = 100 } - let addHackerRole (ctx : InteractionContext) = + let upsertPlayer discordId = async { - let! player = DbService.tryFindPlayer ctx.Member.Id + let! player = DbService.tryFindPlayer GuildEnvironment.pgDb discordId let! newPlayer = match player with | Some _ -> async.Return false | None -> async { - do! newPlayer ctx.Member.DisplayName ctx.Member.Id - |> DbService.insertNewPlayer + do! newPlayer "" discordId |> DbService.insertNewPlayer return true } - if newPlayer then - do! ctx.CreateResponseAsync("You are now an elite haxxor", true) - |> Async.AwaitTask - else - do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true) - |> Async.AwaitTask - - } |> Async.StartAsTask - :> Task + return newPlayer + } [] type LeaderboardEntry = { @@ -75,7 +67,7 @@ type PlayerInteractions() = inherit ApplicationCommandModule () [] - member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx + member _.AddHackerRole (ctx : InteractionContext) = Commands.upsertPlayer ctx.Member.Id // [] // member this.Leaderboard (ctx : InteractionContext) = Commands.leaderboard ctx diff --git a/Bot/Thief.fs b/Bot/Thief.fs index 4bbf55f..4a5bf7e 100644 --- a/Bot/Thief.fs +++ b/Bot/Thief.fs @@ -164,7 +164,7 @@ let handleSteal (ctx : IDiscordContext) = | true -> let embed = getResultEmbed' Success do! Messaging.sendFollowUpEmbed ctx (embed.Build()) - match! DbService.tryFindPlayer targetId with + match! DbService.tryFindPlayer GuildEnvironment.pgDb targetId with | Some t -> let mugged = { ItemId = -1 diff --git a/Bot/paket.references b/Bot/paket.references index 0598702..a4c97af 100644 --- a/Bot/paket.references +++ b/Bot/paket.references @@ -4,3 +4,4 @@ DSharpPlus.Interactivity DSharpPlus.SlashCommands dotenv.net DanielStout.AsciiTableFormatter +Npgsql.FSharp \ No newline at end of file diff --git a/DbService/DbService.fs b/DbService/DbService.fs index 8dfdb2e..16f1560 100644 --- a/DbService/DbService.fs +++ b/DbService/DbService.fs @@ -6,6 +6,14 @@ open System open MongoDB.Bson open MongoDB.Bson.Serialization open MongoDB.Driver +open Npgsql.FSharp + +type User = { + Name : string + DiscordId : uint64 + Bank : int + Strength : int +} let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING")) let db = mongo.GetDatabase("degenz") @@ -17,9 +25,9 @@ let tryWithDefault (bson : BsonDocument) field (defaultValue : 'a) (map : BsonVa if result then map bval else defaultValue with _ -> defaultValue -let mapBack (bson : BsonDocument) : PlayerData = - { DiscordId = tryWithDefault bson "DiscordId" 0uL (fun v -> v.AsInt64 |> uint64) - Name = tryWithDefault bson "Name" "Empty" (fun v -> v.AsString) +let mapBack user (bson : BsonDocument) : PlayerData = + { DiscordId = user.DiscordId + Name = user.Name Inventory = tryWithDefault bson "Inventory" [||] (fun v -> v.AsBsonArray @@ -31,24 +39,41 @@ let mapBack (bson : BsonDocument) : PlayerData = BsonSerializer.Deserialize(bv.ToBsonDocument())) |> Seq.toArray) Traits = - tryWithDefault bson "Traits" PlayerTraits.empty (fun v -> - BsonSerializer.Deserialize(v.ToBsonDocument())) + (let traits = + tryWithDefault bson "Traits" PlayerTraits.empty (fun v -> + BsonSerializer.Deserialize(v.ToBsonDocument())) + { traits with Strength = user.Strength}) Achievements = tryWithDefault bson "Achievements" [||] (fun v -> v.AsBsonArray |> Seq.map (fun (bv : BsonValue) -> bv.AsString) |> Seq.toArray) XP = tryWithDefault bson "XP" 0 (fun v -> v.AsInt32) - Bank = tryWithDefault bson "Bank" 0 (fun v -> v.AsInt32 * 1) + Bank = user.Bank } -let tryFindPlayer (id : uint64) = +let tryFindPlayer connStr (id : uint64) = async { let filter = Builders.Filter.Eq("Player.DiscordId", id) let! player = players.FindAsync(filter) |> Async.AwaitTask - match player.FirstOrDefault() with - | null -> return None - | p -> + let! user = + connStr + |> Sql.connect + |> Sql.query "SELECT * FROM users WHERE discordId = @did" + |> Sql.parameters [ "did", Sql.int64 (int64 id) ] + |> Sql.executeAsync (fun read -> + { + DiscordId = read.int64 "discordId" |> uint64 + Bank = read.int "gbt" * 1 + Strength = read.int "strength" + Name = read.string "displayName" + }) + |> Async.AwaitTask + + match player.FirstOrDefault() , List.tryHead user with + | null , _ + | _ , None -> return None + | p , Some u -> let v = p.GetValue("Player") - let playerData = v.ToBsonDocument() |> mapBack + let playerData = mapBack u (v.ToBsonDocument()) return Some playerData } diff --git a/DbService/paket.references b/DbService/paket.references index 5753ebc..8199177 100644 --- a/DbService/paket.references +++ b/DbService/paket.references @@ -5,3 +5,4 @@ DSharpPlus DSharpPlus.SlashCommands MongoDB.Driver +Npgsql.FSharp diff --git a/paket.dependencies b/paket.dependencies index 697dabe..042e561 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -16,3 +16,4 @@ nuget MongoDB.Driver nuget dotenv.net 3.1.1 nuget DanielStout.AsciiTableFormatter +nuget Npgsql.FSharp \ No newline at end of file diff --git a/paket.lock b/paket.lock index cc7c51e..e2ed42f 100644 --- a/paket.lock +++ b/paket.lock @@ -15,8 +15,9 @@ NUGET System.Runtime.CompilerServices.Unsafe (>= 5.0) System.ValueTuple (>= 4.5) FSharp.Core (6.0.1) - Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) + Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) + Microsoft.Bcl.HashCode (1.1.1) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) Microsoft.Extensions.DependencyInjection (6.0) Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0) @@ -53,6 +54,24 @@ NUGET System.Buffers (>= 4.5.1) MongoDB.Libmongocrypt (1.3) Newtonsoft.Json (13.0.1) + Npgsql (6.0.3) + Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) + Microsoft.Bcl.HashCode (>= 1.1.1) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) + System.Collections.Immutable (>= 6.0) - restriction: || (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) + System.Diagnostics.DiagnosticSource (>= 6.0) - restriction: || (&& (== net6.0) (< net5.0)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) + System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Text.Json (>= 6.0) - restriction: || (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) + System.Threading.Channels (>= 6.0) - restriction: || (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) + System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) + System.ValueTuple (>= 4.5) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) + Npgsql.FSharp (4.1) + FSharp.Core (>= 4.7.2) + Npgsql (>= 5.0.3) + Ply (>= 0.3.1) + Ply (0.3.1) + FSharp.Core (>= 4.6.2) + System.Threading.Tasks.Extensions (>= 4.5.4) runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) @@ -293,7 +312,7 @@ NUGET System.Threading (>= 4.3) System.Threading.Tasks (>= 4.3) System.Threading.Timer (>= 4.3) - System.Numerics.Vectors (4.5) - restriction: || (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard2.0)) (== netstandard2.0) (&& (== netstandard2.1) (< netstandard2.0)) + System.Numerics.Vectors (4.5) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) System.Reflection (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -452,6 +471,18 @@ NUGET Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) System.Text.Encoding (>= 4.3) + System.Text.Encodings.Web (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) + System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) + System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Text.Json (6.0.2) - restriction: || (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) + Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) + System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) + System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) + System.Numerics.Vectors (>= 4.5) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Text.Encodings.Web (>= 6.0) + System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) System.Threading (4.3) System.Runtime (>= 4.3) System.Threading.Tasks (>= 4.3) @@ -461,7 +492,7 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Threading.Tasks.Extensions (4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) + System.Threading.Tasks.Extensions (4.5.4) System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.0)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= wp8)) (== netstandard2.0) (== netstandard2.1) System.Threading.ThreadPool (4.3) System.Runtime (>= 4.3)