diff --git a/KfChatDotNetBot/Commands/MemeCommands.cs b/KfChatDotNetBot/Commands/MemeCommands.cs index a388739..846999c 100644 --- a/KfChatDotNetBot/Commands/MemeCommands.cs +++ b/KfChatDotNetBot/Commands/MemeCommands.cs @@ -1,5 +1,7 @@ using System.Text.RegularExpressions; using Humanizer; +using Humanizer.Localisation; +using KfChatDotNetBot.Models; using KfChatDotNetBot.Models.DbModels; using KfChatDotNetBot.Settings; using KfChatDotNetWsClient.Models.Events; @@ -198,6 +200,88 @@ public class RehbCommand : ICommand return; } var timespan = DateTimeOffset.Parse(end.Value) - DateTimeOffset.UtcNow; - await botInstance.SendChatMessageAsync($"Bossman's rehab will be over in roughly {timespan.Humanize(precision:3)}", true); + await botInstance.SendChatMessageAsync($"Bossman was kicked out of rehab {timespan.Humanize(precision:3)} ago", true); + } +} + +public class NextPoVisitCommand : ICommand +{ + public List Patterns => [ + new Regex("^po "), + new Regex("^po$") + ]; + public string? HelpText => "How long until the next PO visit?"; + public UserRight RequiredRight => UserRight.Loser; + public TimeSpan Timeout => TimeSpan.FromSeconds(120); + public async Task RunCommand(ChatBot botInstance, MessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx) + { + var time = await Helpers.GetValue(BuiltIn.Keys.BotPoNextVisit); + if (time.Value == null) + { + await botInstance.SendChatMessageAsync("There is no next PO visit :(", true); + return; + } + var timespan = DateTimeOffset.Parse(time.Value) - DateTimeOffset.UtcNow; + if (timespan.TotalSeconds < 0) + { + await botInstance.SendChatMessageAsync("It's over", true); + return; + } + var sent = await botInstance.SendChatMessageAsync($"Bossman's next PO visit will be in roughly {timespan.Humanize(precision: 10, minUnit: TimeUnit.Millisecond)}", true); + while (sent.Status != SentMessageTrackerStatus.ResponseReceived) + { + await Task.Delay(250, ctx); + } + var i = 0; + while (i < 60) + { + await Task.Delay(1000, ctx); + timespan = DateTimeOffset.Parse(time.Value) - DateTimeOffset.UtcNow; + await botInstance.KfClient.EditMessageAsync(sent.ChatMessageId!.Value, + $"Bossman's next PO visit will be in roughly {timespan.Humanize(precision: 10, minUnit: TimeUnit.Millisecond)}"); + i++; + } + } +} + +public class NextCourtHearingCommand : ICommand +{ + public List Patterns => [ + new Regex("^court"), + ]; + public string? HelpText => "How long until the next court hearing?"; + public UserRight RequiredRight => UserRight.Loser; + public TimeSpan Timeout => TimeSpan.FromSeconds(120); + public async Task RunCommand(ChatBot botInstance, MessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx) + { + var time = await Helpers.GetValue(BuiltIn.Keys.BotNextCourtHearing); + if (time.Value == null) + { + await botInstance.SendChatMessageAsync("There is no next court hearing :(", true); + return; + } + var timespan = DateTimeOffset.Parse(time.Value) - DateTimeOffset.UtcNow; + if (timespan.TotalSeconds < 0) + { + await botInstance.SendChatMessageAsync("It's over", true); + return; + } + + var sent = await botInstance.SendChatMessageAsync( + $"Bossman's next court hearing will be in {timespan.Humanize(precision: 10, minUnit: TimeUnit.Millisecond)}", + true); + while (sent.Status != SentMessageTrackerStatus.ResponseReceived) + { + await Task.Delay(250, ctx); + } + var i = 0; + while (i < 60) + { + await Task.Delay(1000, ctx); + timespan = DateTimeOffset.Parse(time.Value) - DateTimeOffset.UtcNow; + await botInstance.KfClient.EditMessageAsync(sent.ChatMessageId!.Value, + $"Bossman's next court hearing will be in {timespan.Humanize(precision: 10, minUnit: TimeUnit.Millisecond)}"); + i++; + } } } \ No newline at end of file diff --git a/KfChatDotNetBot/Commands/RestreamCommands.cs b/KfChatDotNetBot/Commands/RestreamCommands.cs index 6a76384..579ea6b 100644 --- a/KfChatDotNetBot/Commands/RestreamCommands.cs +++ b/KfChatDotNetBot/Commands/RestreamCommands.cs @@ -1,4 +1,5 @@ using System.Text.RegularExpressions; +using KfChatDotNetBot.Models; using KfChatDotNetBot.Models.DbModels; using KfChatDotNetBot.Settings; using KfChatDotNetWsClient.Models.Events; @@ -41,4 +42,29 @@ public class SetRestreamCommand : ICommand await botInstance.SendChatMessageAsync($"@{message.Author.Username}, updated URL", true); } +} + +public class SelfPromoCommand : ICommand +{ + public List Patterns => [ + new Regex("^selfpromo") + ]; + + public string? HelpText => "Promote your shit"; + public UserRight RequiredRight => UserRight.Loser; + public TimeSpan Timeout => TimeSpan.FromSeconds(10); + + public async Task RunCommand(ChatBot botInstance, MessageModel message, UserDbModel user, GroupCollection arguments, + CancellationToken ctx) + { + var channels = Helpers.GetValue(BuiltIn.Keys.KickChannels).Result.JsonDeserialize>(); + var channel = channels.FirstOrDefault(ch => ch.ForumId == user.KfId); + if (channel == null) + { + await botInstance.SendChatMessageAsync("You have no stream.", true); + return; + } + + await botInstance.SendChatMessageAsync($"@{user.KfUsername} is a weirdo who streams. Come check out his channel at https://kick.com/{channel.ChannelSlug}", true); + } } \ No newline at end of file diff --git a/KfChatDotNetBot/KfChatDotNetBot.csproj b/KfChatDotNetBot/KfChatDotNetBot.csproj index 9fb5f35..ddccf50 100644 --- a/KfChatDotNetBot/KfChatDotNetBot.csproj +++ b/KfChatDotNetBot/KfChatDotNetBot.csproj @@ -9,18 +9,18 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - - + + diff --git a/KfChatDotNetBot/Services/BotServices.cs b/KfChatDotNetBot/Services/BotServices.cs index 6515e21..56fd44e 100644 --- a/KfChatDotNetBot/Services/BotServices.cs +++ b/KfChatDotNetBot/Services/BotServices.cs @@ -307,12 +307,13 @@ public class BotServices { var settings = Helpers .GetMultipleValues([ - BuiltIn.Keys.RainbetBmjPublicId, BuiltIn.Keys.TwitchBossmanJackUsername, + BuiltIn.Keys.RainbetBmjPublicIds, BuiltIn.Keys.TwitchBossmanJackUsername, BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor ]).Result; _logger.Trace("Rainbet bet has arrived"); using var db = new ApplicationDbContext(); - foreach (var bet in bets.Where(b => b.User.PublicId == settings[BuiltIn.Keys.RainbetBmjPublicId].Value)) + var ids = settings[BuiltIn.Keys.RainbetBmjPublicIds].JsonDeserialize>(); + foreach (var bet in bets.Where(b => ids.Contains(b.User.PublicId))) //foreach (var bet in bets) { if (db.RainbetBets.Any(b => b.BetId == bet.Id)) diff --git a/KfChatDotNetBot/Settings/BuiltIn.cs b/KfChatDotNetBot/Settings/BuiltIn.cs index 66e2e46..fa1dae5 100644 --- a/KfChatDotNetBot/Settings/BuiltIn.cs +++ b/KfChatDotNetBot/Settings/BuiltIn.cs @@ -378,10 +378,10 @@ public static class BuiltIn }, new BuiltInSettingsModel { - Key = Keys.RainbetBmjPublicId, + Key = Keys.RainbetBmjPublicIds, Regex = ".+", - Description = "Bossman's rainbet public ID", - Default = "Ir04170wLulcjtePCL7P6lmeOlepRaNp", + Description = "Bossman's rainbet public IDs", + Default = "[\"Ir04170wLulcjtePCL7P6lmeOlepRaNp\", \"IA9RHFR1NLHL33AVOM9GL2G2CINM9I6P\"]", IsSecret = false, CacheDuration = TimeSpan.FromHours(1) }, @@ -589,6 +589,24 @@ public static class BuiltIn Default = "2024-10-24T09:00:00-04:00", IsSecret = false, CacheDuration = TimeSpan.FromHours(1) + }, + new BuiltInSettingsModel + { + Key = Keys.BotPoNextVisit, + Regex = ".+", + Description = "ISO8601 date of Bossman's next PO visit", + Default = "2024-10-18T12:00:00-04:00", + IsSecret = false, + CacheDuration = TimeSpan.FromHours(1) + }, + new BuiltInSettingsModel + { + Key = Keys.BotNextCourtHearing, + Regex = ".+", + Description = "ISO8601 date of Bossman's next court hearing", + Default = "2024-10-29T09:00:00-04:00", + IsSecret = false, + CacheDuration = TimeSpan.FromHours(1) } ]; @@ -624,7 +642,7 @@ public static class BuiltIn public static string KiwiFarmsGreenColor = "KiwiFarms.GreenColor"; public static string KiwiFarmsRedColor = "KiwiFarms.RedColor"; public static string JackpotBmjUsername = "Jackpot.BmjUsername"; - public static string RainbetBmjPublicId = "Rainbet.BmjPublicId"; + public static string RainbetBmjPublicIds = "Rainbet.BmjPublicIds"; public static string FlareSolverrApiUrl = "FlareSolverr.ApiUrl"; public static string FlareSolverrProxy = "FlareSolverr.Proxy"; public static string ChipsggBmjUserIds = "Chipsgg.BmjUserIds"; @@ -646,5 +664,7 @@ public static class BuiltIn public static string BotCrackpipeImgUrl = "Bot.Crackpipe.ImgUrl"; public static string BotCleanStartTime = "Bot.Clean.StartTime"; public static string BotRehabEndTime = "Bot.Rehab.EndTime"; + public static string BotPoNextVisit = "Bot.Po.NextVisit"; + public static string BotNextCourtHearing = "Bot.Court.NextHearing"; } } \ No newline at end of file diff --git a/KfChatDotNetWsClient/ChatClient.cs b/KfChatDotNetWsClient/ChatClient.cs index bac20aa..4fe9d1f 100644 --- a/KfChatDotNetWsClient/ChatClient.cs +++ b/KfChatDotNetWsClient/ChatClient.cs @@ -221,6 +221,13 @@ public class ChatClient _wsClient.Send($"/edit {payload}"); } + public async Task EditMessageAsync(int messageId, string newMessage) + { + var payload = JsonSerializer.Serialize(new EditMessageJsonModel {Id = messageId, Message = newMessage}); + _logger.Debug($"Editing {messageId} with '{newMessage}'"); + await _wsClient.SendInstant($"/edit {payload}"); + } + private void WsDeleteMessagesReceived(ResponseMessage message) { var data = JsonSerializer.Deserialize(message.Text);