diff --git a/Bot/HackerBattle.fs b/Bot/HackerBattle.fs index 97374fb..aaf6a1c 100644 --- a/Bot/HackerBattle.fs +++ b/Bot/HackerBattle.fs @@ -18,7 +18,7 @@ let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp = else $"{timeRemaining.Seconds} seconds" -let checkForExistingHack attacker defenderId = +let checkForExistingHack defenderId attacker = let updatedAttacks = attacker.Attacks |> removeExpiredActions (TimeSpan.FromHours(24)) (fun atk -> atk.Timestamp) @@ -29,21 +29,26 @@ let checkForExistingHack attacker defenderId = let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromHours(24)) attack.Timestamp Error $"You can only hack the same target once every 24 hours, wait {cooldown} to attempt another hack on {attack.Target.Name}." | None -> - Ok updatedAttacks + Ok attacker -let checkIfHackHasCooldown hack updatedAttacks = +let checkIfHackHasCooldown hack attacker = let mostRecentHackAttack = - updatedAttacks + attacker.Attacks |> Array.tryFind (fun a -> a.HackType = hack) |> function | Some a -> a.Timestamp | None -> DateTime.MinValue if DateTime.UtcNow - mostRecentHackAttack > TimeSpan.FromMinutes(5) then - Ok updatedAttacks + Ok attacker else let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromMinutes(5)) mostRecentHackAttack Error $"{hack} is currently on cooldown, wait {cooldown} to use it again." +let checkIfInventoryIsEmpty attacker = + match attacker.Weapons with + | [||] -> Error $"You currently do not have any Hacks to use against others. Please go to the store and purchase one." + | _ -> Ok attacker + let calculateDamage (hack: int) (shield: int) = let hackClass = getClass hack let protectionClass = getClass shield @@ -117,8 +122,10 @@ let attack (ctx : InteractionContext) (target : DiscordUser) = let! defender = DbService.tryFindPlayer target.Id match attacker , defender with | Some attacker , Some defender -> - let existingHack = checkForExistingHack attacker defender.DiscordId - match existingHack with + let hackAttempt = + checkForExistingHack defender.DiscordId attacker + |> Result.bind checkIfInventoryIsEmpty + match hackAttempt with | Ok _ -> let embed = Embeds.pickHack "Attack" attacker defender do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) @@ -146,7 +153,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) = // TODO: Do not let player hack themselves match resultPlayer , resultTarget , true , resultId with | Some attacker , Some defender , true , true -> - do! checkForExistingHack attacker defender.DiscordId + do! checkForExistingHack defender.DiscordId attacker |> Result.bind (checkIfHackHasCooldown hack) |> function | Ok _ -> diff --git a/DbService/DbService.fs b/DbService/DbService.fs index f03079d..a96cfec 100644 --- a/DbService/DbService.fs +++ b/DbService/DbService.fs @@ -7,23 +7,23 @@ open MongoDB.Bson open MongoDB.Bson.Serialization open MongoDB.Driver - let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING")) let db = mongo.GetDatabase("degenz") let players = db.GetCollection("players") + let tryFindPlayer (id : uint64) = async { - let filter = Builders.Filter.Eq("Player.DiscordId", id); - let! player = players.Find(filter).FirstOrDefaultAsync() |> Async.AwaitTask - return match player with - | null -> None - | player -> - player - .GetValue("Player") - .ToBsonDocument() - |> BsonSerializer.Deserialize - |> Some + let filter = Builders.Filter.Eq("Player.DiscordId", id) + let! player = players.FindAsync(filter) |> Async.AwaitTask + match player.FirstOrDefault() with + | null -> return None + | p -> + return p + .GetValue("Player") + .ToBsonDocument() + |> BsonSerializer.Deserialize + |> Some } let insertNewPlayer (player : Player) =