From df7b72f0c469a8c3153965fff252453f4996c814 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Apr 2022 18:38:24 +0700 Subject: [PATCH] Add small cooldown so users don't spam --- Bot/DbService.fs | 44 ++++++++++++++++++++++++++++++++++------ Bot/GameTypes.fs | 1 + Bot/Games/SlotMachine.fs | 20 ++++++++++++++---- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/Bot/DbService.fs b/Bot/DbService.fs index 12d0af4..eb8434b 100644 --- a/Bot/DbService.fs +++ b/Bot/DbService.fs @@ -26,6 +26,7 @@ let getPlayerEvents (did : uint64) = } | "Shielding" -> Shielding (read.int "item_id") | "Stealing" -> Stealing ( read.bool "is_instigator" , { Id = read.string "adversary_id" |> uint64 ; Name = read.string "adversary_name" } ) + | "PlayingSlot" -> PlayingSlot | _ -> Imprison |> fun t -> let date = read.dateTimeOrNone "created_at" |> Option.defaultValue DateTime.UtcNow @@ -33,6 +34,36 @@ let getPlayerEvents (did : uint64) = ) |> Async.AwaitTask +let getLastPlayedSlotFromPlayer (did : uint64) = async { + let! events = + connStr + |> Sql.connect + |> Sql.parameters [ "did", Sql.string (string did) ] + |> Sql.query """ + SELECT player_event.updated_at FROM player_event + JOIN "user" u on u.id = player_event.user_id + WHERE u.discord_id = @did AND event_type = 'PlayingSlot' + """ + |> Sql.executeAsync (fun read -> read.dateTime "updated_at" ) + |> Async.AwaitTask + match events with + | [] -> return None + | es -> return Some (List.head es) +} + +let updateSlotPlayedFromPlayer (did : uint64) = + connStr + |> Sql.connect + |> Sql.parameters [ "did", Sql.string (string did) ] + |> Sql.query """ + WITH usr AS (SELECT id FROM "user" WHERE discord_id = @did) + UPDATE player_event SET updated_at = now() at time zone 'utc' + FROM usr WHERE usr.id = user_id; + """ + |> Sql.executeNonQueryAsync + |> Async.AwaitTask + |> Async.Ignore + let updatePlayerStats (player : PlayerData) = connStr |> Sql.connect @@ -54,12 +85,6 @@ let updatePlayerStats (player : PlayerData) = let tryFindPlayer (discordId : uint64) = async { try let! user = -// use cert = new X509Certificate2("~/Downloads/ca-certificate.crt") -// (Uri connStr) -// |> Sql.fromUriToConfig -// |> Sql.requireSslMode -// |> Sql.formatConnectionString -// |> Sql.clientCertificate cert connStr |> Sql.connect |> Sql.parameters [ "did", Sql.string (string discordId) ] @@ -220,6 +245,13 @@ let addPlayerEvent (did : uint64) (playerEvent : PlayerEvent) = INSERT INTO player_event (event_type, is_instigator, adversary_id, adversary_name, cooldown, user_id) SELECT 'Stealing', @is_instigator, @adversary_id, @adversary_name, @cooldown, usr.id FROM usr """ + | PlayingSlot -> + [ ( "did" , Sql.string (string did) ) ] , + """ + WITH usr AS (SELECT id FROM "user" WHERE discord_id = @did) + INSERT INTO player_event (event_type, cooldown, user_id) + SELECT 'Imprison', 1, usr.id FROM usr + """ | Imprison -> [ ( "did" , Sql.string (string did) ) diff --git a/Bot/GameTypes.fs b/Bot/GameTypes.fs index 1f17d7a..5f04ce7 100644 --- a/Bot/GameTypes.fs +++ b/Bot/GameTypes.fs @@ -75,6 +75,7 @@ type PlayerEventType = | Hacking of HackEvent | Shielding of shieldId : int | Stealing of instigator : bool * adversary : DiscordPlayer + | PlayingSlot | Imprison type PlayerEvent = diff --git a/Bot/Games/SlotMachine.fs b/Bot/Games/SlotMachine.fs index 7a1aed5..ed8a37e 100644 --- a/Bot/Games/SlotMachine.fs +++ b/Bot/Games/SlotMachine.fs @@ -5,6 +5,7 @@ open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities open DSharpPlus.EventArgs +open Degenz open Degenz.Messaging open Degenz.Types open Npgsql.FSharp @@ -227,7 +228,7 @@ let spin multiplier (ctx : IDiscordContext) = | 1 -> PlayPricex1 | 2 -> PlayPricex2 | _ -> PlayPricex3 - let execute player = async { + let execute player = async { do! DbService.updatePlayerCurrency -playAmount player |> Async.Ignore let random = Random(Guid.NewGuid().GetHashCode()) let symbols = [| reel1.[random.Next(0, reel1.Length)] ; reel2.[random.Next(0, reel2.Length)] ; reel3.[random.Next(0, reel3.Length)] |] @@ -295,11 +296,22 @@ let spin multiplier (ctx : IDiscordContext) = do! itx.EditFollowupMessageAsync(followUpMessage.Id, dwb) |> Async.AwaitTask |> Async.Ignore do! Analytics.slotPlayed (ctx.GetDiscordMember()) playAmount result prizeAmount } - PlayerInteractions.executePlayerAction ctx (fun player -> + PlayerInteractions.executePlayerAction ctx (fun player -> async { if player.Bank >= playAmount then - execute player + match! DbService.getLastPlayedSlotFromPlayer player.DiscordId with + | Some timestamp -> + if DateTime.UtcNow - timestamp > TimeSpan.FromSeconds(8) then + do! DbService.updateSlotPlayedFromPlayer player.DiscordId + do! execute player + else + do! Messaging.sendFollowUpMessage ctx "Wait till you finish the current spin!" + | None -> + let event = { Type = PlayingSlot ; Cooldown = 1 ; Timestamp = DateTime.UtcNow } + do! DbService.addPlayerEvent player.DiscordId event |> Async.Ignore + do! execute player else - Messaging.sendFollowUpMessage ctx "You do not have sufficient funds to play") + do! Messaging.sendFollowUpMessage ctx "You do not have sufficient funds to play" + }) let handleButton (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) = let ctx = DiscordEventContext event