mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-04-30 03:22:04 -04:00
332 lines
16 KiB
C#
332 lines
16 KiB
C#
using System.Text.RegularExpressions;
|
||
using Humanizer;
|
||
using KfChatDotNetBot.Models;
|
||
using KfChatDotNetBot.Models.DbModels;
|
||
using KfChatDotNetBot.Services;
|
||
using KfChatDotNetBot.Settings;
|
||
using KfChatDotNetWsClient.Models.Events;
|
||
using NLog;
|
||
using Zalgo;
|
||
|
||
namespace KfChatDotNetBot.Commands;
|
||
|
||
public class InsanityCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [new Regex("^insanity")];
|
||
public string? HelpText => "Insanity";
|
||
public UserRight RequiredRight => UserRight.Guest;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
// ReSharper disable once StringLiteralTypo
|
||
await botInstance.SendChatMessageAsync("definition of insanity = doing the same thing over and over and over excecting a different result, and heres my dumbass trying to get rich every day and losing everythign i fucking touch every fucking time FUCK this bullshit FUCK MY LIEFdefinition of insanity = doing the same thing over and over and over excecting a different result, and heres my dumbass trying to get rich every day and losing everythign i fucking touch every fucking time FUCK this bullshit FUCK MY LIEF");
|
||
}
|
||
}
|
||
|
||
public class TwistedCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [new Regex("^twisted")];
|
||
public string? HelpText => "Get it twisted";
|
||
public UserRight RequiredRight => UserRight.Guest;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
// ReSharper disable once StringLiteralTypo
|
||
await botInstance.SendChatMessageAsync("🦍 🗣 GET IT TWISTED 🌪 , GAMBLE ✅ . PLEASE START GAMBLING 👍 . GAMBLING IS AN INVESTMENT 🎰 AND AN INVESTMENT ONLY 👍 . YOU WILL PROFIT 💰 , YOU WILL WIN ❗ ️. YOU WILL DO ALL OF THAT 💯 , YOU UNDERSTAND ⁉ ️ YOU WILL BECOME A BILLIONAIRE 💵 📈 AND REBUILD YOUR FUCKING LIFE 🤯");
|
||
}
|
||
}
|
||
|
||
public class ScratchCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [new Regex("^scratch")];
|
||
public string? HelpText => "Start scratching";
|
||
public UserRight RequiredRight => UserRight.Guest;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
// ReSharper disable once StringLiteralTypo
|
||
await botInstance.SendChatMessageAsync("🐀 🗣 GET IT TWISTED 🌪, SCRATCH ✅. PLEASE START SCRATCHING 👍. SCRATCHING YOUR SCABIES SORES IS RELIEF 😌 AND RELIEF ONLY 👍. YOU WILL FEEL BETTER 💪, YOU WILL FIND COMFORT ❗️. YOU WILL DO ALL OF THAT 💯, YOU UNDERSTAND ⁉️ YOU WILL CONQUER THE ITCH 🦠 AND REBUILD YOUR SKIN’S PEACE 🤯", true);
|
||
}
|
||
}
|
||
|
||
public class CrackedCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [
|
||
new Regex("^cracked (?<msg>.+)"),
|
||
new Regex("^crackhead (?<msg>.+)")
|
||
];
|
||
public string? HelpText => "Crackhead Zalgo text";
|
||
public UserRight RequiredRight => UserRight.Guest;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var logger = LogManager.GetCurrentClassLogger();
|
||
var msg = arguments["msg"].Value.TrimStart('/');
|
||
var settings = await SettingsProvider.GetMultipleValuesAsync([
|
||
BuiltIn.Keys.CrackedZalgoFuckUpMode, BuiltIn.Keys.CrackedZalgoFuckUpPosition
|
||
]);
|
||
var zalgo = new ZalgoString(msg, (FuckUpMode)settings[BuiltIn.Keys.CrackedZalgoFuckUpMode].ToType<int>(),
|
||
(FuckUpPosition)settings[BuiltIn.Keys.CrackedZalgoFuckUpPosition].ToType<int>());
|
||
logger.Info($"Zalgo length: {zalgo.ToString().Length}");
|
||
await botInstance.SendChatMessageAsync(zalgo.ToString(), true, ChatBot.LengthLimitBehavior.TruncateExactly);
|
||
}
|
||
}
|
||
|
||
public class CleanCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [
|
||
new Regex("^clean")
|
||
];
|
||
public string? HelpText => "How long has Bossman been clean?";
|
||
public UserRight RequiredRight => UserRight.Loser;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var settings =
|
||
await SettingsProvider.GetMultipleValuesAsync([BuiltIn.Keys.BotCleanStartTime, BuiltIn.Keys.TwitchBossmanJackUsername]);
|
||
var start = settings[BuiltIn.Keys.BotCleanStartTime];
|
||
if (start.Value == null)
|
||
{
|
||
await botInstance.SendChatMessageAsync("Austin's sobriety start date was null", true);
|
||
return;
|
||
}
|
||
var timespan = DateTimeOffset.UtcNow - DateTimeOffset.Parse(start.Value);
|
||
await botInstance.SendChatMessageAsync($"{settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value} has been clean {timespan.Humanize(precision:5)}", true);
|
||
}
|
||
}
|
||
|
||
public class RehabCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [
|
||
new Regex("^rehab")
|
||
];
|
||
public string? HelpText => "How long until rehab is over?";
|
||
public UserRight RequiredRight => UserRight.Loser;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var settings =
|
||
await SettingsProvider.GetMultipleValuesAsync([BuiltIn.Keys.BotRehabEndTime, BuiltIn.Keys.TwitchBossmanJackUsername]);
|
||
var end = settings[BuiltIn.Keys.BotRehabEndTime];
|
||
if (end.Value == null)
|
||
{
|
||
await botInstance.SendChatMessageAsync("Austin's rehab end date was null", true);
|
||
return;
|
||
}
|
||
|
||
var endDate = DateTimeOffset.Parse(end.Value);
|
||
var timespan = endDate - DateTimeOffset.UtcNow;
|
||
if (endDate > DateTimeOffset.UtcNow)
|
||
{
|
||
await botInstance.SendChatMessageAsync($"{settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value} should finish rehab in {timespan.Humanize(precision:3)}", true);
|
||
return;
|
||
}
|
||
await botInstance.SendChatMessageAsync($"{settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value} left rehab {timespan.Humanize(precision:3)} ago", true);
|
||
}
|
||
}
|
||
|
||
public class NextPoVisitCommand : ICommand
|
||
{
|
||
public List<Regex> 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 RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var time = await SettingsProvider.GetValueAsync(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($"Austin's next PO visit will be in roughly {timespan.Humanize(precision: 10, minUnit: TimeUnit.Millisecond)}", true);
|
||
var success = await botInstance.WaitForChatMessageAsync(sent, TimeSpan.FromSeconds(30), ctx);
|
||
if (!success) throw new InvalidOperationException();
|
||
var i = 0;
|
||
while (i < 60)
|
||
{
|
||
await Task.Delay(1000, ctx);
|
||
timespan = DateTimeOffset.Parse(time.Value) - DateTimeOffset.UtcNow;
|
||
await botInstance.KfClient.EditMessageAsync(sent.ChatMessageUuid!,
|
||
$"Austin's next PO visit will be in roughly {timespan.Humanize(precision: 10, minUnit: TimeUnit.Millisecond)}");
|
||
i++;
|
||
}
|
||
}
|
||
}
|
||
|
||
public class NextCourtHearingCommand : ICommand
|
||
{
|
||
public List<Regex> 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 RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var hearings = (await SettingsProvider.GetValueAsync(BuiltIn.Keys.BotCourtCalendar)).JsonDeserialize<List<CourtHearingModel>>();
|
||
if (hearings == null)
|
||
{
|
||
await botInstance.SendChatMessageAsync("Caught a null when grabbing hearings", true);
|
||
return;
|
||
}
|
||
|
||
if (RenderHearings(hearings) == string.Empty)
|
||
{
|
||
await botInstance.SendChatMessageAsync("There are no upcoming hearings in the bot's calendar", true);
|
||
return;
|
||
}
|
||
|
||
var sent = await botInstance.SendChatMessageAsync(RenderHearings(hearings),true);
|
||
var success = await botInstance.WaitForChatMessageAsync(sent, TimeSpan.FromSeconds(15), ctx);
|
||
if (!success) throw new InvalidOperationException();
|
||
var i = 0;
|
||
while (i < 60)
|
||
{
|
||
await Task.Delay(1000, ctx);
|
||
await botInstance.KfClient.EditMessageAsync(sent.ChatMessageUuid!, RenderHearings(hearings));
|
||
i++;
|
||
}
|
||
}
|
||
|
||
private static string RenderHearings(List<CourtHearingModel> hearings)
|
||
{
|
||
var i = 0;
|
||
var result = string.Empty;
|
||
foreach (var hearing in hearings)
|
||
{
|
||
i++;
|
||
var timespan = hearing.Time - DateTimeOffset.UtcNow;
|
||
if (timespan.TotalSeconds < 0) continue; // Already passed
|
||
result +=
|
||
$"{i}: [url=https://eapps.courts.state.va.us/ocis/details;fromOcis=true;fullcaseNumber=109{hearing.CaseNumber.Replace("-", string.Empty)}]{hearing.CaseNumber}[/url] " +
|
||
//$"{i}: {hearing.CaseNumber} " +
|
||
$"{hearing.Description} will be heard in {timespan.Humanize(precision: 10, minUnit: TimeUnit.Second, maxUnit: TimeUnit.Year)}\r\n";
|
||
}
|
||
return result.Trim();
|
||
}
|
||
}
|
||
|
||
public class JailCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [
|
||
new Regex("^jail")
|
||
];
|
||
public string? HelpText => "How long has Bossman been in jail?";
|
||
public UserRight RequiredRight => UserRight.Loser;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var settings = await SettingsProvider.GetMultipleValuesAsync([BuiltIn.Keys.BotJailStartTime, BuiltIn.Keys.TwitchBossmanJackUsername]);
|
||
var start = settings[BuiltIn.Keys.BotJailStartTime];
|
||
if (start.Value == null)
|
||
{
|
||
await botInstance.SendChatMessageAsync("He ain't in jail nigga", true);
|
||
return;
|
||
}
|
||
var timespan = DateTimeOffset.UtcNow - DateTimeOffset.Parse(start.Value);
|
||
await botInstance.SendChatMessageAsync($"{settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value} has been in jail {timespan.Humanize(precision:5)}", true);
|
||
}
|
||
}
|
||
|
||
public class LastStreamCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [new Regex("^laststream")];
|
||
public string? HelpText => "How long ago did Austin Gambles last stream (on Twitch)?";
|
||
public UserRight RequiredRight => UserRight.Guest;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var settings = await SettingsProvider.GetMultipleValuesAsync([
|
||
BuiltIn.Keys.TwitchGraphQlPersistedCurrentlyLive, BuiltIn.Keys.TwitchBossmanJackUsername
|
||
]);
|
||
var username = settings[BuiltIn.Keys.TwitchBossmanJackUsername].Value;
|
||
var isLive = settings[BuiltIn.Keys.TwitchGraphQlPersistedCurrentlyLive].ToBoolean();
|
||
if (isLive)
|
||
{
|
||
await botInstance.SendChatMessageAsync($"{username} is currently live on Twitch https://twitch.tv/{username}", true);
|
||
return;
|
||
}
|
||
await using var db = new ApplicationDbContext();
|
||
var latest = db.TwitchViewCounts.OrderByDescending(x => x.Id).FirstOrDefault();
|
||
if (latest == null)
|
||
{
|
||
await botInstance.SendChatMessageAsync("The Twitch view counts table is empty", true);
|
||
return;
|
||
}
|
||
|
||
var timespan = DateTimeOffset.UtcNow - latest.Time;
|
||
var agt = TimeZoneInfo.ConvertTime(latest.Time, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
|
||
// The table doesn't contain the name of the person so we'll just have to assume it's his Twitch username
|
||
await botInstance.SendChatMessageAsync($"{username} last streamed on Twitch approximately {timespan.Humanize(precision: 2, minUnit: TimeUnit.Minute, maxUnit: TimeUnit.Hour)} ago at {agt:dddd h:mm tt} AGT", true);
|
||
}
|
||
}
|
||
|
||
public class AlmanacCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [
|
||
new Regex("^almanac", RegexOptions.IgnoreCase)
|
||
];
|
||
public string? HelpText => "Return details on how to submit almanac entries";
|
||
public UserRight RequiredRight => UserRight.Guest;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
var text = await SettingsProvider.GetValueAsync(BuiltIn.Keys.BotAlmanacText);
|
||
if (message.MessageRaw.Contains("almanac plain"))
|
||
{
|
||
await botInstance.SendChatMessageAsync($"@{user.KfUsername}, [plain]{text.Value}", true);
|
||
return;
|
||
}
|
||
await botInstance.SendChatMessageAsync($"@{user.KfUsername}, {text.Value}", true);
|
||
}
|
||
}
|
||
|
||
public class JuiceSportsCommand : ICommand
|
||
{
|
||
public List<Regex> Patterns => [
|
||
new Regex("^juicesports", RegexOptions.IgnoreCase)
|
||
];
|
||
public string? HelpText => "Juicesports LFG!";
|
||
public UserRight RequiredRight => UserRight.Loser;
|
||
public TimeSpan Timeout => TimeSpan.FromSeconds(10);
|
||
public RateLimitOptionsModel? RateLimitOptions => null;
|
||
public bool WhisperCanInvoke => false;
|
||
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
|
||
{
|
||
await botInstance.SendChatMessageAsync(":juice: [img]https://i.ddos.lgbt/u/3GJtHq.gif[/img] :juice: [br]⠀⠀⠀⠀⠀⠀⠀" +
|
||
"[img]https://i.ddos.lgbt/u/KAwWMW.webp[/img][br]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀" +
|
||
"[img]https://i.ddos.lgbt/u/uCuSOw.gif[/img][br]", true);
|
||
}
|
||
} |