Added feature to track messages sent by the bot by reference so they can be edited

This commit is contained in:
barelyprofessional
2024-08-11 21:11:37 +08:00
parent 2c54ca30dd
commit c0d7f62c61
3 changed files with 129 additions and 6 deletions

View File

@@ -1,4 +1,6 @@
using KfChatDotNetBot.Models;
using System.Net;
using System.Text.Json;
using KfChatDotNetBot.Models;
using KfChatDotNetBot.Models.DbModels;
using KfChatDotNetBot.Services;
using KfChatDotNetBot.Settings;
@@ -42,6 +44,7 @@ public class ChatBot
private Task _websocketWatchdog;
private Jackpot _jackpot;
private Rainbet _rainbet;
private List<SentMessageTrackerModel> _sentMessages = [];
public ChatBot()
{
@@ -544,13 +547,32 @@ public class ChatBot
private void OnKfChatMessage(object sender, List<MessageModel> messages, MessagesJsonModel jsonPayload)
{
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.GambaSeshDetectEnabled, BuiltIn.Keys.GambaSeshUserId])
var settings = Helpers.GetMultipleValues([BuiltIn.Keys.GambaSeshDetectEnabled,
BuiltIn.Keys.GambaSeshUserId, BuiltIn.Keys.KiwiFarmsUsername])
.Result;
_lastKfEvent = DateTime.Now;
_logger.Debug($"Received {messages.Count} message(s)");
foreach (var message in messages)
{
_logger.Info($"KF ({message.MessageDate.ToLocalTime():HH:mm:ss}) <{message.Author.Username}> {message.Message}");
if (message.Author.Username == settings[BuiltIn.Keys.KiwiFarmsUsername].Value && message.MessageEditDate == null)
{
// MessageRaw is not actually REAL and RAW. The messages are still HTML encoded
var decodedMessage = WebUtility.HtmlDecode(message.MessageRaw);
var sentMessage = _sentMessages.FirstOrDefault(sent =>
sent.Message == decodedMessage && sent.Status == SentMessageTrackerStatus.WaitingForResponse);
if (sentMessage == null)
{
_logger.Info("Received message from Sneedchat that I sent but have no idea about. Bot restart? Ignoring it.");
_logger.Info(JsonSerializer.Serialize(message));
}
else
{
sentMessage.ChatMessageId = message.MessageId;
sentMessage.Delay = DateTimeOffset.UtcNow - sentMessage.SentAt;
sentMessage.Status = SentMessageTrackerStatus.ResponseReceived;
}
}
if (settings[BuiltIn.Keys.GambaSeshDetectEnabled].ToBoolean() && !_initialStartCooldown && message.Author.Id == settings[BuiltIn.Keys.GambaSeshUserId].ToType<int>() && !GambaSeshPresent)
{
_logger.Info("Received a GambaSesh message after cooldown and while thinking he's not here. Setting the presence flag to avoid spamming chat");
@@ -569,26 +591,53 @@ public class ChatBot
}
}
public void SendChatMessage(string message, bool bypassSeshDetect = false)
public string SendChatMessage(string message, bool bypassSeshDetect = false)
{
var settings = Helpers
.GetMultipleValues([BuiltIn.Keys.KiwiFarmsSuppressChatMessages, BuiltIn.Keys.GambaSeshDetectEnabled])
.Result;
var reference = Guid.NewGuid().ToString();
var messageTracker = new SentMessageTrackerModel
{
Reference = reference,
Message = message,
Status = SentMessageTrackerStatus.Unknown,
};
if (settings[BuiltIn.Keys.KiwiFarmsSuppressChatMessages].ToBoolean())
{
_logger.Info("Not sending message as SuppressChatMessages is enabled");
_logger.Info($"Message was: {message}");
return;
messageTracker.Status = SentMessageTrackerStatus.NotSending;
_sentMessages.Add(messageTracker);
return reference;
}
if (GambaSeshPresent && settings[BuiltIn.Keys.GambaSeshDetectEnabled].ToBoolean() && !bypassSeshDetect)
{
_logger.Info($"Not sending message '{message}' as GambaSesh is present");
return;
messageTracker.Status = SentMessageTrackerStatus.NotSending;
_sentMessages.Add(messageTracker);
return reference;
}
messageTracker.Status = SentMessageTrackerStatus.WaitingForResponse;
messageTracker.SentAt = DateTimeOffset.UtcNow;
_sentMessages.Add(messageTracker);
KfClient.SendMessage(message);
return reference;
}
public SentMessageTrackerModel GetSentMessageStatus(string reference)
{
var message = _sentMessages.FirstOrDefault(m => m.Reference == reference);
if (message == null)
{
throw new SentMessageNotFoundException();
}
KfClient.SendMessage(message);
return message;
}
public class SentMessageNotFoundException : Exception;
private void OnKickChatMessage(object sender, KickModels.ChatMessageEventModel? e)
{
if (e == null) return;

View File

@@ -0,0 +1,51 @@
using System.Text.RegularExpressions;
using KfChatDotNetBot.Models;
using KfChatDotNetBot.Models.DbModels;
using KfChatDotNetWsClient.Models.Events;
using NLog;
namespace KfChatDotNetBot.Commands;
public class EditTestCommand : ICommand
{
public List<Regex> Patterns => [
new Regex("^test edit (?<msg>.+)")
];
public string HelpText => "Test the editing functionality";
public bool HideFromHelp => true;
public UserRight RequiredRight => UserRight.Admin;
public async Task RunCommand(ChatBot botInstance, MessageModel message, UserDbModel user, GroupCollection arguments, CancellationToken ctx)
{
var logger = LogManager.GetCurrentClassLogger();
var msg = arguments["msg"].Value;
var iterations = 3;
var i = 0;
var delay = 1000;
var reference = botInstance.SendChatMessage($"{msg} {i}");
while (botInstance.GetSentMessageStatus(reference).Status == SentMessageTrackerStatus.WaitingForResponse)
{
await Task.Delay(100, ctx);
}
var status = botInstance.GetSentMessageStatus(reference);
if (status.Status == SentMessageTrackerStatus.NotSending || status.Status == SentMessageTrackerStatus.Unknown ||
status.ChatMessageId == null)
{
logger.Error("Either message refused to send due to bot settings or something fucked up getting the message ID");
return;
}
while (i < iterations)
{
i++;
await Task.Delay(delay, ctx);
botInstance.KfClient.EditMessage(status.ChatMessageId!.Value, $"{msg} {i}");
}
await Task.Delay(delay, ctx);
botInstance.KfClient.EditMessage(status.ChatMessageId!.Value, "This message will self destruct in 1 second");
await Task.Delay(delay, ctx);
botInstance.KfClient.DeleteMessage(status.ChatMessageId!.Value);
}
}

View File

@@ -0,0 +1,23 @@
namespace KfChatDotNetBot.Models;
public class SentMessageTrackerModel
{
// Unique GUID for each message
public required string Reference { get; set; }
public required string Message { get; set; }
public required SentMessageTrackerStatus Status { get; set; }
public int? ChatMessageId { get; set; }
// Timespan from when the message was sent until we saw it come back
public TimeSpan? Delay { get; set; }
public DateTimeOffset? SentAt { get; set; }
}
public enum SentMessageTrackerStatus
{
WaitingForResponse,
ResponseReceived,
// If the bot is blocked from sending the message, e.g. due to suppress chat messages being enabled
NotSending,
// Shouldn't happen normally, it's just set before the bot has made a decision on whether to send or not,
Unknown
}