2022-07-06 03:59:19 +00:00
|
|
|
|
using Discord;
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
namespace RegexBot.Modules.RegexModerator;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The namesake of RegexBot. This module allows users to define pattern-based rules with other constraints.
|
|
|
|
|
/// When triggered, one or more actions are executed as defined in its configuration.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[RegexbotModule]
|
2022-07-21 03:34:29 +00:00
|
|
|
|
internal class RegexModerator : RegexbotModule {
|
2022-07-06 03:59:19 +00:00
|
|
|
|
public RegexModerator(RegexbotClient bot) : base(bot) {
|
|
|
|
|
DiscordClient.MessageReceived += DiscordClient_MessageReceived;
|
|
|
|
|
DiscordClient.MessageUpdated += DiscordClient_MessageUpdated;
|
|
|
|
|
}
|
2021-08-26 03:18:45 +00:00
|
|
|
|
|
2022-10-23 00:47:23 +00:00
|
|
|
|
public override Task<object?> CreateGuildStateAsync(ulong guildID, JToken? config) {
|
2022-07-06 03:59:19 +00:00
|
|
|
|
if (config == null) return Task.FromResult<object?>(null);
|
|
|
|
|
var defs = new List<ConfDefinition>();
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
if (config.Type != JTokenType.Array)
|
|
|
|
|
throw new ModuleLoadException(Name + " configuration must be a JSON array.");
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
// TODO better error reporting during this process
|
|
|
|
|
foreach (var def in config.Children<JObject>())
|
|
|
|
|
defs.Add(new ConfDefinition(def));
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
if (defs.Count == 0) return Task.FromResult<object?>(null);
|
|
|
|
|
Log(DiscordClient.GetGuild(guildID), $"Loaded {defs.Count} definition(s).");
|
|
|
|
|
return Task.FromResult<object?>(defs.AsReadOnly());
|
|
|
|
|
}
|
2021-08-26 03:18:45 +00:00
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
private Task DiscordClient_MessageReceived(SocketMessage arg) => ReceiveIncomingMessage(arg);
|
2022-07-28 05:02:17 +00:00
|
|
|
|
private Task DiscordClient_MessageUpdated(Cacheable<Discord.IMessage, ulong> arg1, SocketMessage arg2, ISocketMessageChannel arg3) {
|
|
|
|
|
// Ignore embed edits (see comment in MessageCachingSubservice)
|
|
|
|
|
if (!arg2.EditedTimestamp.HasValue) return Task.CompletedTask;
|
|
|
|
|
|
|
|
|
|
return ReceiveIncomingMessage(arg2);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Does initial message checking before further processing.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private async Task ReceiveIncomingMessage(SocketMessage msg) {
|
2022-07-09 20:22:39 +00:00
|
|
|
|
if (!Common.Utilities.IsValidUserMessage(msg, out var ch)) return;
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-06 03:59:19 +00:00
|
|
|
|
// Get config?
|
|
|
|
|
var defs = GetGuildState<IEnumerable<ConfDefinition>>(ch.Guild.Id);
|
|
|
|
|
if (defs == null) return;
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-29 02:33:49 +00:00
|
|
|
|
// Matching and response processing
|
2022-07-06 03:59:19 +00:00
|
|
|
|
foreach (var item in defs) {
|
|
|
|
|
// Need to check sender's moderator status here. Definition can't access mod list.
|
|
|
|
|
var isMod = GetModerators(ch.Guild.Id).IsListMatch(msg, true);
|
2019-06-17 05:37:11 +00:00
|
|
|
|
|
2022-07-29 02:33:49 +00:00
|
|
|
|
if (!item.IsMatch(msg, isMod)) continue;
|
|
|
|
|
Log(ch.Guild, $"Rule '{item.Label}' triggered by {msg.Author}.");
|
|
|
|
|
var exec = new ResponseExecutor(item, Bot, msg, (string logLine) => Log(ch.Guild, logLine));
|
|
|
|
|
await exec.Execute();
|
2019-06-17 05:37:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|