From 272317f8288a98d48cde915a344342119616eb1d Mon Sep 17 00:00:00 2001 From: barelyprofessional <150058423+barelyprofessional@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:02:44 +1000 Subject: [PATCH] Added a basic Howl.gg stats command, implemented a setting for controlling the magic number to divide by and retroactively updating bet/profit amounts for unrealized gains on slot feaches --- .../Commands/HowlggCommands.cs | 34 +++++++++++++++++++ KfChatDotNetKickBot/KickBot.cs | 26 +++++++++----- KfChatDotNetKickBot/Settings/BuiltIn.cs | 9 +++++ 3 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 KfChatDotNetKickBot/Commands/HowlggCommands.cs diff --git a/KfChatDotNetKickBot/Commands/HowlggCommands.cs b/KfChatDotNetKickBot/Commands/HowlggCommands.cs new file mode 100644 index 0000000..666afbb --- /dev/null +++ b/KfChatDotNetKickBot/Commands/HowlggCommands.cs @@ -0,0 +1,34 @@ +using System.Text.RegularExpressions; +using KfChatDotNetKickBot.Models.DbModels; +using KfChatDotNetKickBot.Settings; +using KfChatDotNetWsClient.Models.Events; +using Microsoft.EntityFrameworkCore; + +namespace KfChatDotNetKickBot.Commands; + +public class HowlggStatsCommand : ICommand +{ + public List Patterns => [ + new Regex(@"^howl stats (?\d+)$") + ]; + public string HelpText => "Get betting statistics in the given window"; + public bool HideFromHelp => false; + public UserRight RequiredRight => UserRight.Guest; + public async Task RunCommand(KickBot botInstance, MessageModel message, GroupCollection arguments, CancellationToken ctx) + { + var window = Convert.ToInt32(arguments["window"].Value); + var start = DateTimeOffset.UtcNow.AddHours(-window); + var division = (await Helpers.GetValue(BuiltIn.Keys.HowlggDivisionAmount)).ToType(); + await using var db = new ApplicationDbContext(); + // EF SQLite doesn't support filtering on dates :( + var bets = (await db.HowlggBets.ToListAsync(ctx)).Where(b => b.Date.UtcDateTime > start).ToList(); + if (bets.Count == 0) + { + botInstance.SendChatMessage("No bets captured during this window", true); + return; + } + var output = $"Howl.gg stats for the last {window} hours:[br]" + + $"Bets: {bets.Count:N0}; Profit: {bets.Sum(b => b.Profit) / division:C}; Wagered: {bets.Sum(b => b.Bet) / division:C}"; + botInstance.SendChatMessage(output, true); + } +} \ No newline at end of file diff --git a/KfChatDotNetKickBot/KickBot.cs b/KfChatDotNetKickBot/KickBot.cs index 7419a88..3e60137 100644 --- a/KfChatDotNetKickBot/KickBot.cs +++ b/KfChatDotNetKickBot/KickBot.cs @@ -131,25 +131,33 @@ public class KickBot { _logger.Debug("Received bet history from Howl.gg"); using var db = new ApplicationDbContext(); - foreach (var bets in data.History.Data) + foreach (var bet in data.History.Data) { - if (db.HowlggBets.Any(b => b.GameId == bets.GameId)) + // Slot feature buys have an unrealized value that means they show no profit until the feature finishes + // The feed will return the correct profit later hence updating the values + var existingBet = db.HowlggBets.FirstOrDefault(b => b.BetId == bet.Id); + if (existingBet != null) { _logger.Trace("Bet already exists in DB"); + if (existingBet.Bet == bet.Bet && existingBet.Profit == bet.Profit) continue; + _logger.Debug("Updating fields"); + existingBet.Bet = bet.Bet; + existingBet.Profit = bet.Profit; + db.SaveChanges(); continue; } db.HowlggBets.Add(new HowlggBetsDbModel { UserId = data.User.Id, - BetId = bets.Id, - GameId = bets.GameId, - Bet = bets.Bet, - Profit = bets.Profit, - Date = bets.Date, - Game = bets.Game + BetId = bet.Id, + GameId = bet.GameId, + Bet = bet.Bet, + Profit = bet.Profit, + Date = bet.Date, + Game = bet.Game }); - _logger.Debug("Added bet to DB"); + _logger.Info("Added bet to DB"); } db.SaveChanges(); diff --git a/KfChatDotNetKickBot/Settings/BuiltIn.cs b/KfChatDotNetKickBot/Settings/BuiltIn.cs index 0fe1fd4..c1d6a58 100644 --- a/KfChatDotNetKickBot/Settings/BuiltIn.cs +++ b/KfChatDotNetKickBot/Settings/BuiltIn.cs @@ -320,6 +320,14 @@ public static class BuiltIn Description = "Whether to enable Kick functionality (Pusher websocket mainly)", Default = "true", IsSecret = false + }, + new BuiltInSettingsModel + { + Key = Keys.HowlggDivisionAmount, + Regex = @"\d+", + Description = "How much to divide the Howlgg bets/profit by to get the real value", + Default = "1650", + IsSecret = false } ]; @@ -351,5 +359,6 @@ public static class BuiltIn public static string JuiceAmount = "Juice.Amount"; public static string KiwiFarmsToken = "KiwiFarms.Token"; public static string KickEnabled = "Kick.Enabled"; + public static string HowlggDivisionAmount = "Howlgg.DivisionAmount"; } } \ No newline at end of file