From 63e38537880443afd663187e10fd962358761bf9 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 17 Feb 2022 21:31:46 +0700 Subject: [PATCH] Improve steal game presentation and fix exploit. Fix bug --- Bot/Game.fs | 2 +- Bot/Thief.fs | 96 ++++++++++++++++++++++++++++------------------------ 2 files changed, 53 insertions(+), 45 deletions(-) diff --git a/Bot/Game.fs b/Bot/Game.fs index 95088bd..63600a9 100644 --- a/Bot/Game.fs +++ b/Bot/Game.fs @@ -80,7 +80,7 @@ module Player = player.Events |> Array.filter (fun (act : PlayerEvent) -> let itemCooldown = - if act.ItemId < 12 then + if act.ItemId > 0 && act.ItemId < 12 then (Armory.getItem act.ItemId).Cooldown else match act.Type with diff --git a/Bot/Thief.fs b/Bot/Thief.fs index bfb6971..83975d0 100644 --- a/Bot/Thief.fs +++ b/Bot/Thief.fs @@ -40,11 +40,11 @@ let payout defenderBank chance = let randomAmount = baseAmount + randomBonus |> int max 1 randomAmount -let getStealEmbed (chance : double) prize (target : PlayerData) = +let getStealEmbed amount (chance : double) prize (target : PlayerData) = let chance = int (chance * 100.0) let buttons = // let yes , no = getRandomStealBtnLabels () - let btnId = $"Steal-yes-{target.DiscordId}-{target.Name}-{chance}-{prize}" + let btnId = $"Steal-yes-{target.DiscordId}-{target.Name}-{amount}" [ DiscordButtonComponent(ButtonStyle.Success, btnId, "Do it") ] // DiscordButtonComponent(ButtonStyle.Danger, $"Steal-no", no) ] |> Seq.cast @@ -59,27 +59,36 @@ let getStealEmbed (chance : double) prize (target : PlayerData) = .AddComponents(buttons) .AsEphemeral(true) -let getResultEmbed targetName result = - let resultMsg , msg , img = +let getResultEmbed chance prize (bank : int) thief (victim : DiscordPlayer) result = + let embed = + DiscordEmbedBuilder() + .AddField("Thief", $"<@{thief.DiscordId}>") + .AddField("Victim", $"<@{victim.Id}>") + .AddField("Chance of Success" , $"{chance * 100.0 |> int}%%", true) + let msg , img , color = match result with | Success -> - "You successfully robbed the poor bastard" - , "Your mean ugly face and athletic physique intimidated your poor victim into giving you their money" + embed.AddField("Loot" , $"{prize}", true) + .AddField("New GoodBoyTokenⒸ Balance", $"`{bank}` => 💰 `{bank + prize}` (+{prize}) ") |> ignore + ($"\n\n You **STOLE** `{prize} $GBT` 🎉\n\n" + + "Your mean ugly face and athletic physique intimidated your poor victim into giving you their money") , "https://f8n-production-collection-assets.imgix.net/0x3B3ee1931Dc30C1957379FAc9aba94D1C48a5405/127502/QmPLPg1CLovKzS7mP8QkrMoHws1D4VZTzpfbZBALLwKZ5b/nft.png" - | WentToPrison -> - "Looks like you went to prison" - , $"{targetName} knows Karate and elbowed you in the nose. While unconscious, they called the cops. You're on your way to prison now... " - , "https://thumbs.dreamstime.com/b/vector-pixel-art-prisoner-isolated-cartoon-vector-pixel-art-prisoner-129807237.jpg" + , DiscordColor.Green | VictimRanAway -> - "You tried to snatch their money and they ran away" - , $"{targetName} got nervous seeing a shadowy figure and ran in the opposite direction" + embed.AddField("Result" , $"Ran Away", true) |> ignore + $"Target **ran away**...\n\n{thief.Name} saw a shadowy figure and got nervous so they ran in the opposite direction" , "https://i.imgur.com/NLHMvVK.jpg" + , DiscordColor.Grayple + | WentToPrison -> + embed.AddField("Result" , $"Imprisoned", true) |> ignore + $"You're going to **PRISON**...\n\n{thief.Name} knows Karate and elbowed you in the nose. While unconscious, they called the cops." + , "https://thumbs.dreamstime.com/b/vector-pixel-art-prisoner-isolated-cartoon-vector-pixel-art-prisoner-129807237.jpg" + , DiscordColor.Red - DiscordEmbedBuilder() -// .AddField("Result" , resultMsg) - .WithDescription(msg) -// .WithImageUrl(img) - .WithTitle($"Robbery Results") + embed.WithTitle($"Steal Results") + .WithColor(color) + .WithDescription(msg) + .WithImageUrl(img) let checkVictimStealingCooldown defender attacker = defender @@ -110,26 +119,23 @@ let checkThiefCooldown attacker = let calculateWinPercentage amountRequested bank attackerStrength defenderStrength = - let powerPercentage = float (attackerStrength - defenderStrength) * 0.005 + 0.25 - printfn $"{(attackerStrength - defenderStrength)}" - printfn $"{powerPercentage}" + let powerPercentage = float (attackerStrength - defenderStrength) * 0.005 + 0.1 let cappedAmount = float bank * 0.5 let cappedRequest = min amountRequested (cappedAmount |> ceil) let wagerPercentage = 1.0 - (cappedRequest / cappedAmount) - // Max chance of success is 97.5% - ( cappedRequest , max 0.0 (wagerPercentage * 0.7 + powerPercentage * 1.3 ) / 2.05 ) + // Max chance of success is 90.0% + ( cappedRequest , max 0.0 (wagerPercentage * 0.7 + powerPercentage * 1.3 ) / 2.0 ) -//calculateWinPercentage 500 1000 100 50 +//calculateWinPercentage 50 200 100 85 let steal target amount (ctx : IDiscordContext) = - Game.executePlayerActionWithTarget target ctx (fun attacker defender -> async { - do! + Game.executePlayerActionWithTarget target ctx (fun attacker defender -> async { do! attacker |> checkVictimStealingCooldown defender >>= checkThiefCooldown |> handleResultWithResponse ctx (fun _ -> async { let cappedPrize , winPercentage = calculateWinPercentage amount (int defender.Bank) attacker.Traits.Strength defender.Traits.Strength - let embed = getStealEmbed winPercentage cappedPrize defender + let embed = getStealEmbed amount winPercentage cappedPrize defender do! ctx.FollowUp(embed) |> Async.AwaitTask }) @@ -139,44 +145,46 @@ let handleSteal (ctx : IDiscordContext) = let split = ctx.GetInteractionId().Split("-") let answer = split.[1] - let handleYes (player : PlayerData) = async { + let handleYes (victim : PlayerData) (thief : PlayerData) = async { let targetId = uint64 split.[2] let targetName = split.[3] - let chance = double split.[4] - let prize = int split.[5] * 1 + let amount = int split.[4] + let prize , winPercentage = calculateWinPercentage amount (int victim.Bank) thief.Traits.Strength victim.Traits.Strength + let prize = int prize * 1 let rand = Random(Guid.NewGuid().GetHashCode()) - let result = chance >= rand.NextDouble() , rand.Next(0,3) = 0 + let num = rand.NextDouble() + let result = winPercentage >= num , rand.Next(0,3) = 0 let dp = { DiscordPlayer.Id = targetId ; DiscordPlayer.Name = targetName } let stealAction result = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = result ; Adversary = dp ; Timestamp = DateTime.UtcNow } + let getResultEmbed' = getResultEmbed winPercentage prize thief.Bank thief dp // TODO: Send event to the hall of privacy // TODO: We need to check if the player is on cooldown match result with | true , _ -> - let xp = 25 - let embed = getResultEmbed targetName Success - embed.AddField("$GBT Stolen", string prize) |> ignore - embed.AddField("XP Gained", $"{xp}") |> ignore + let embed = getResultEmbed' Success +// let xp = 25 +// embed.AddField("XP Gained", $"{xp}") |> ignore do! Messaging.sendFollowUpEmbed ctx (embed.Build()) match! DbService.tryFindPlayer targetId with | Some t -> - let mugged = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Negative ; Adversary = player.basicPlayer ; Timestamp = DateTime.UtcNow } + let mugged = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Negative ; Adversary = thief.basicPlayer ; Timestamp = DateTime.UtcNow } let actions = t |> Player.removeExpiredActions false |> fun p -> Array.append [| mugged |] p.Events do! DbService.updatePlayer { t with Bank = max (t.Bank - prize) 0 ; Events = actions } | None -> () let stole = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Positive ; Adversary = dp ; Timestamp = DateTime.UtcNow } - let actions = player |> Player.removeExpiredActions false |> fun p -> Array.append [| stole |] p.Events - do! DbService.updatePlayer { player with Bank = player.Bank + prize ; XP = player.XP + xp ; Events = actions } - do! Async.Sleep 2000 - do! ctx.FollowUp (XP.getRewardsEmbed 1 player) |> Async.AwaitTask + let actions = thief |> Player.removeExpiredActions false |> fun p -> Array.append [| stole |] p.Events + do! DbService.updatePlayer { thief with Bank = thief.Bank + prize ; XP = thief.XP + 0 ; Events = actions } +// do! Async.Sleep 2000 +// do! ctx.FollowUp (XP.getRewardsEmbed 1 player) |> Async.AwaitTask | false , false -> - let embed = getResultEmbed targetName VictimRanAway - do! DbService.updatePlayer { player with Events = Array.append [| stealAction PlayerEventResult.Neutral |] player.Events } + let embed = getResultEmbed' VictimRanAway + do! DbService.updatePlayer { thief with Events = Array.append [| stealAction PlayerEventResult.Neutral |] thief.Events } do! Messaging.sendFollowUpEmbed ctx (embed.Build()) | false , true -> - let embed = getResultEmbed targetName WentToPrison - do! DbService.updatePlayer { player with Events = Array.append [| stealAction PlayerEventResult.Neutral |] player.Events } + let embed = getResultEmbed' WentToPrison + do! DbService.updatePlayer { thief with Events = Array.append [| stealAction PlayerEventResult.Neutral |] thief.Events } do! Messaging.sendFollowUpEmbed ctx (embed.Build()) do! Async.Sleep 2000 let role = ctx.GetGuild().GetRole(GuildEnvironment.rolePrisoner) @@ -189,7 +197,7 @@ let handleSteal (ctx : IDiscordContext) = |> Player.removeExpiredActions false |> checkVictimStealingCooldown defender >>= checkThiefCooldown - |> handleResultWithResponse ctx handleYes + |> handleResultWithResponse ctx (handleYes defender ) }) else async {