From 920e465c2869c7052e13192477b400e9d21ff135 Mon Sep 17 00:00:00 2001 From: FloatingMilkshake Date: Sun, 15 Sep 2024 21:22:32 -0400 Subject: [PATCH 1/2] Fix conflict between automatic empty thread delete & auto-warn --- Events/MessageEvent.cs | 82 +++++++++++---------------------------- Helpers/DiscordHelpers.cs | 72 ++++++++++++++++++++++++++++++++++ Helpers/WarningHelpers.cs | 29 ++++++++++++++ 3 files changed, 124 insertions(+), 59 deletions(-) diff --git a/Events/MessageEvent.cs b/Events/MessageEvent.cs index 8ef2b88..4be4494 100644 --- a/Events/MessageEvent.cs +++ b/Events/MessageEvent.cs @@ -68,35 +68,7 @@ public static async Task MessageDeleted(DiscordClient client, MessageDeletedEven client.Logger.LogDebug("Got a message delete event for {message} by {user}", DiscordHelpers.MessageLink(e.Message), e.Message.Author.Id); } - // Delete thread if all messages are deleted - if (Program.cfgjson.AutoDeleteEmptyThreads && e.Channel is DiscordThreadChannel) - { - try - { - var member = await e.Guild.GetMemberAsync(e.Message.Author.Id); - if ((await GetPermLevelAsync(member)) >= ServerPermLevel.TrialModerator) - return; - } - catch - { - // User is not in the server. Assume they are not a moderator, - // so do nothing here. - } - - IReadOnlyList messages; - try - { - messages = await e.Channel.GetMessagesAsync(1).ToListAsync(); - } - catch (DSharpPlus.Exceptions.NotFoundException ex) - { - Program.discord.Logger.LogDebug(ex, "Delete event failed to fetch messages from channel {channel}", e.Channel.Id); - return; - } - - if (messages.Count == 0) - await e.Channel.DeleteAsync("All messages in thread were deleted."); - } + await DiscordHelpers.DoEmptyThreadCleanupAsync(e.Channel, e.Message); } static async Task DeleteAndWarnAsync(DiscordMessage message, string reason, DiscordClient client) @@ -107,15 +79,24 @@ static async Task DeleteAndWarnAsync(DiscordMessage message, string reason, Disc static async Task DeleteAndWarnAsync(MockDiscordMessage message, string reason, DiscordClient client, bool wasAutoModBlock = false) { var channel = message.Channel; - + DiscordMessage msg; + string warnMsgReason = $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"; if (!wasAutoModBlock) - _ = message.DeleteAsync(); + { + msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, warnMsgReason, wasAutoModBlock, true); + } else + { if (channel.Type is DiscordChannelType.GuildForum) + { if (Program.cfgjson.ForumChannelAutoWarnFallbackChannel == 0) Program.discord.Logger.LogWarning("A warning in forum channel {channelId} was attempted, but may fail due to the fallback channel not being set. Please set 'forumChannelAutoWarnFallbackChannel' in config.json to avoid this.", channel.Id); else channel = Program.ForumChannelAutoWarnFallbackChannel; + } + + msg = await channel.SendMessageAsync(warnMsgReason); + } try { @@ -125,14 +106,13 @@ static async Task DeleteAndWarnAsync(MockDiscordMessage message, string reason, { // still warn anyway } - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, wasAutoModBlock: wasAutoModBlock); } public static async Task MessageHandlerAsync(DiscordClient client, DiscordMessage message, DiscordChannel channel, bool isAnEdit = false, bool limitFilters = false, bool wasAutoModBlock = false) { - await MessageHandlerAsync(client, new MockDiscordMessage(message), channel, isAnEdit, limitFilters); + await MessageHandlerAsync(client, new MockDiscordMessage(message), channel, isAnEdit, limitFilters, wasAutoModBlock); } public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMessage message, DiscordChannel channel, bool isAnEdit = false, bool limitFilters = false, bool wasAutoModBlock = false) { @@ -309,7 +289,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe else { Program.discord.Logger.LogDebug("Message {messageId} in {channelId} by user {userId} triggered mass-mention filter", message.Id, channel.Id, message.Author.Id); - _ = message.DeleteAsync(); + await DiscordHelpers.ThreadChannelAwareDeleteMessageAsync(message); } _ = channel.Guild.BanMemberAsync(message.Author, TimeSpan.FromDays(7), $"Mentioned more than {Program.cfgjson.MassMentionBanThreshold} users in one message."); @@ -342,8 +322,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe string reason = listItem.Reason; try { - if (!wasAutoModBlock) - _ = message.DeleteAsync(); await InvestigationsHelpers.SendInfringingMessaageAsync("mod", message, reason, null, wasAutoModBlock: wasAutoModBlock); } catch @@ -353,8 +331,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe if (listItem.Name == "autoban.txt" && (await GetPermLevelAsync(member)) < ServerPermLevel.Tier4) { - if (!wasAutoModBlock) - _ = message.DeleteAsync(); await BanHelpers.BanFromServerAsync(message.Author.Id, reason, client.CurrentUser.Id, channel.Guild, 0, channel, default, true); return; } @@ -363,7 +339,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe match = true; - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock, true); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, extraField: ("Match", flaggedWord, true), wasAutoModBlock: wasAutoModBlock); return; @@ -390,7 +366,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe else { Program.discord.Logger.LogDebug("Message {messageId} in {channelId} by user {userId} triggered unapproved invite filter", message.Id, channel.Id, message.Author.Id); - _ = message.DeleteAsync(); } string reason = "Sent an unapproved invite"; @@ -403,7 +378,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe // still warn anyway } - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{{Program.cfgjson.Emoji.Denied}} {{message.Author.Mention}} was automatically warned: **{{reason.Replace(\"`\", \"\\\\`\").Replace(\"*\", \"\\\\*\")}}**", wasAutoModBlock, true); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, wasAutoModBlock: wasAutoModBlock); match = true; @@ -439,8 +414,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe if ((await GetPermLevelAsync(member)) < (ServerPermLevel)Program.cfgjson.InviteTierRequirement && disallowedInviteCodes.Contains(code)) { - if (!wasAutoModBlock) - _ = message.DeleteAsync(); //match = await InviteCheck(invite, message, client); if (!match) { @@ -469,11 +442,9 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe if (maliciousCache != default) { - if (!wasAutoModBlock) - _ = message.DeleteAsync(); string reason = "Sent a malicious Discord invite"; - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); string responseToSend = $"```json\n{JsonConvert.SerializeObject(maliciousCache)}\n```"; @@ -502,8 +473,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe ) ) { - if (!wasAutoModBlock) - _ = message.DeleteAsync(); disallowedInviteCodes.Add(code); match = await InviteCheck(invite, message, client, wasAutoModBlock); if (!match) @@ -555,7 +524,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe else { Program.discord.Logger.LogDebug("Message {messageId} in {channelId} by user {userId} triggered mass emoji filter", message.Id, channel.Id, message.Author.Id); - _ = message.DeleteAsync(); } string reason = "Mass emoji"; @@ -583,7 +551,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe await Program.db.HashSetAsync("emojiPardoned", member.Id.ToString(), true); } - DiscordMessage msg = await channel.SendMessageAsync(output); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, output, wasAutoModBlock); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, wasAutoModBlock: wasAutoModBlock); return; @@ -655,11 +623,10 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe else { Program.discord.Logger.LogDebug("Message {messageId} in {channelId} by user {userId} triggered phishing message filter", message.Id, channel.Id, message.Author.Id); - _ = message.DeleteAsync(); } string reason = "Sending phishing URL(s)"; - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); string responseToSend = await StringHelpers.CodeOrHasteBinAsync(responseText, "json", 1000, true); @@ -681,11 +648,10 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe else { Program.discord.Logger.LogDebug("Message {messageId} in {channelId} by user {userId} triggered everyone/here mention filter", message.Id, channel.Id, message.Author.Id); - _ = message.DeleteAsync(); } string reason = "Attempted to ping everyone/here"; - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, wasAutoModBlock: wasAutoModBlock); return; @@ -706,8 +672,6 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe string reason = "Mass mentions"; try { - if (!wasAutoModBlock) - _ = message.DeleteAsync(); _ = InvestigationsHelpers.SendInfringingMessaageAsync("mod", message, reason, null, wasAutoModBlock: wasAutoModBlock); } catch @@ -715,7 +679,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe // still warn anyway } - DiscordMessage msg = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, wasAutoModBlock: wasAutoModBlock); return; @@ -736,7 +700,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe else { Program.discord.Logger.LogDebug("Message {messageId} in {channelId} by user {userId} triggered line limit filter", message.Id, channel.Id, message.Author.Id); - _ = message.DeleteAsync(); + await DiscordHelpers.ThreadChannelAwareDeleteMessageAsync(message); } string reason = "Too many lines in a single message"; @@ -948,7 +912,7 @@ public static async Task InviteCheck(DiscordInvite? invite, MockDiscordMes else if (serverMatch) { if (!wasAutoModBlock) - _ = message.DeleteAsync(); + await DiscordHelpers.ThreadChannelAwareDeleteMessageAsync(message); string reason = "Sent a malicious Discord invite"; DiscordMessage msg = await message.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"); diff --git a/Helpers/DiscordHelpers.cs b/Helpers/DiscordHelpers.cs index 6d40249..8a54d49 100644 --- a/Helpers/DiscordHelpers.cs +++ b/Helpers/DiscordHelpers.cs @@ -242,6 +242,78 @@ public static async Task GenerateMessageRelay(DiscordMess return new DiscordMessageBuilder().AddEmbeds(embeds.AsEnumerable()); } + + public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, DiscordMessage message, bool wasAutoWarn = false) + { + return await DoEmptyThreadCleanupAsync(channel, new MockDiscordMessage(message), wasAutoWarn); + } + + public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, MockDiscordMessage message, bool wasAutoWarn = false) + { + // Delete thread if all messages are deleted. + // Otherwise, do nothing. + // Returns whether the thread was deleted. + + if (Program.cfgjson.AutoDeleteEmptyThreads && channel is DiscordThreadChannel) + { + try + { + var member = await channel.Guild.GetMemberAsync(message.Author.Id); + if ((await GetPermLevelAsync(member)) >= ServerPermLevel.TrialModerator) + return false; + } + catch + { + // User is not in the server. Assume they are not a moderator, + // so do nothing here. + } + + IReadOnlyList messages; + try + { + messages = await channel.GetMessagesAsync(wasAutoWarn ? 2 : 1).ToListAsync(); + } + catch (DSharpPlus.Exceptions.NotFoundException ex) + { + Program.discord.Logger.LogDebug(ex, "Delete event failed to fetch messages from channel {channel}", channel.Id); + return false; + } + + // If this is coming after an automatic warning, 1 message in the thread is okay; + // this is the message that triggered the warning, and we can just delete the thread. + if (messages.Count == (wasAutoWarn ? 1 : 0)) + { + await channel.DeleteAsync("All messages in thread were deleted."); + return true; + } + } + + return false; + } + + public static async Task ThreadChannelAwareDeleteMessageAsync(DiscordMessage message, bool wasAutoWarn = false) + { + await ThreadChannelAwareDeleteMessageAsync(new MockDiscordMessage(message), wasAutoWarn); + } + + public static async Task ThreadChannelAwareDeleteMessageAsync(MockDiscordMessage message, bool wasAutoWarn = false) + { + // Deletes a message in a thread channel, or if it is the last message, deletes the thread instead. + // If this is not a thread channel, just deletes the message. + + bool wasThreadDeleted = false; + + if (message.Channel.Type == DiscordChannelType.GuildForum || message.Channel.Parent.Type == DiscordChannelType.GuildForum) + { + wasThreadDeleted = await DoEmptyThreadCleanupAsync(message.Channel, message, wasAutoWarn); + if (!wasThreadDeleted) + await message.DeleteAsync(); + } + else + await message.DeleteAsync(); + + return wasThreadDeleted; + } } } diff --git a/Helpers/WarningHelpers.cs b/Helpers/WarningHelpers.cs index 3cabfff..20eb8ae 100644 --- a/Helpers/WarningHelpers.cs +++ b/Helpers/WarningHelpers.cs @@ -389,6 +389,35 @@ public static UserWarning GetWarning(ulong targetUserId, long warnId = default) return null; } } + + public static async Task SendPublicWarningMessageAndDeleteInfringingMessageAsync(DiscordMessage infringingMessage, string warningMessageContent, bool wasAutoModBlock = false, bool wasAutoWarn = false) + { + return await SendPublicWarningMessageAndDeleteInfringingMessageAsync(new MockDiscordMessage(infringingMessage), warningMessageContent, wasAutoModBlock, wasAutoWarn); + } + + public static async Task SendPublicWarningMessageAndDeleteInfringingMessageAsync(MockDiscordMessage infringingMessage, string warningMessageContent, bool wasAutoModBlock = false, bool wasAutoWarn = false) + { + // If this is a `GuildForum` channel, delete the thread if it is empty (empty = 1 message left if `isAutoWarn`, otherwise 0); if not empty, just delete the infringing message. + // Then, based on whether the thread was deleted, send the warning message into the thread or into the configured fallback channel. + // Return the sent warning message for logging. + + var targetChannel = infringingMessage.Channel; + if (infringingMessage.Channel.Type == DiscordChannelType.GuildForum) + { + if (Program.cfgjson.ForumChannelAutoWarnFallbackChannel == 0) + Program.discord.Logger.LogWarning("A warning in forum channel {channelId} was attempted, but may fail due to the fallback channel not being set. Please set 'forumChannelAutoWarnFallbackChannel' in config.json to avoid this.", targetChannel.Id); + else + targetChannel = Program.ForumChannelAutoWarnFallbackChannel; + } + + if (!wasAutoModBlock) + { + if (await DiscordHelpers.ThreadChannelAwareDeleteMessageAsync(infringingMessage, wasAutoWarn)) + targetChannel = await Program.discord.GetChannelAsync(Program.cfgjson.ForumChannelAutoWarnFallbackChannel); + } + var warningMessage = await targetChannel.SendMessageAsync(warningMessageContent); + return warningMessage; + } } } From 2e2379df8ba40afc17c5379a054dcf09fc953edb Mon Sep 17 00:00:00 2001 From: FloatingMilkshake Date: Wed, 18 Sep 2024 07:35:39 -0400 Subject: [PATCH 2/2] Use an int parameter instead of a boolean --- Events/MessageEvent.cs | 6 +++--- Helpers/DiscordHelpers.cs | 18 +++++++++--------- Helpers/WarningHelpers.cs | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Events/MessageEvent.cs b/Events/MessageEvent.cs index 4be4494..bde003f 100644 --- a/Events/MessageEvent.cs +++ b/Events/MessageEvent.cs @@ -83,7 +83,7 @@ static async Task DeleteAndWarnAsync(MockDiscordMessage message, string reason, string warnMsgReason = $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**"; if (!wasAutoModBlock) { - msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, warnMsgReason, wasAutoModBlock, true); + msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, warnMsgReason, wasAutoModBlock, 1); } else { @@ -339,7 +339,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe match = true; - DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock, true); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{Program.cfgjson.Emoji.Denied} {message.Author.Mention} was automatically warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**", wasAutoModBlock, 1); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, extraField: ("Match", flaggedWord, true), wasAutoModBlock: wasAutoModBlock); return; @@ -378,7 +378,7 @@ public static async Task MessageHandlerAsync(DiscordClient client, MockDiscordMe // still warn anyway } - DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{{Program.cfgjson.Emoji.Denied}} {{message.Author.Mention}} was automatically warned: **{{reason.Replace(\"`\", \"\\\\`\").Replace(\"*\", \"\\\\*\")}}**", wasAutoModBlock, true); + DiscordMessage msg = await WarningHelpers.SendPublicWarningMessageAndDeleteInfringingMessageAsync(message, $"{{Program.cfgjson.Emoji.Denied}} {{message.Author.Mention}} was automatically warned: **{{reason.Replace(\"`\", \"\\\\`\").Replace(\"*\", \"\\\\*\")}}**", wasAutoModBlock, 1); var warning = await WarningHelpers.GiveWarningAsync(message.Author, client.CurrentUser, reason, contextMessage: msg, channel, " automatically "); await InvestigationsHelpers.SendInfringingMessaageAsync("investigations", message, reason, warning.ContextLink, wasAutoModBlock: wasAutoModBlock); match = true; diff --git a/Helpers/DiscordHelpers.cs b/Helpers/DiscordHelpers.cs index 8a54d49..673ddd0 100644 --- a/Helpers/DiscordHelpers.cs +++ b/Helpers/DiscordHelpers.cs @@ -243,12 +243,12 @@ public static async Task GenerateMessageRelay(DiscordMess return new DiscordMessageBuilder().AddEmbeds(embeds.AsEnumerable()); } - public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, DiscordMessage message, bool wasAutoWarn = false) + public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, DiscordMessage message, int minMessages = 0) { - return await DoEmptyThreadCleanupAsync(channel, new MockDiscordMessage(message), wasAutoWarn); + return await DoEmptyThreadCleanupAsync(channel, new MockDiscordMessage(message), minMessages); } - public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, MockDiscordMessage message, bool wasAutoWarn = false) + public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, MockDiscordMessage message, int minMessages = 0) { // Delete thread if all messages are deleted. // Otherwise, do nothing. @@ -271,7 +271,7 @@ public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, IReadOnlyList messages; try { - messages = await channel.GetMessagesAsync(wasAutoWarn ? 2 : 1).ToListAsync(); + messages = await channel.GetMessagesAsync(minMessages + 1).ToListAsync(); } catch (DSharpPlus.Exceptions.NotFoundException ex) { @@ -281,7 +281,7 @@ public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, // If this is coming after an automatic warning, 1 message in the thread is okay; // this is the message that triggered the warning, and we can just delete the thread. - if (messages.Count == (wasAutoWarn ? 1 : 0)) + if (messages.Count == minMessages) { await channel.DeleteAsync("All messages in thread were deleted."); return true; @@ -291,12 +291,12 @@ public static async Task DoEmptyThreadCleanupAsync(DiscordChannel channel, return false; } - public static async Task ThreadChannelAwareDeleteMessageAsync(DiscordMessage message, bool wasAutoWarn = false) + public static async Task ThreadChannelAwareDeleteMessageAsync(DiscordMessage message, int minMessages = 0) { - await ThreadChannelAwareDeleteMessageAsync(new MockDiscordMessage(message), wasAutoWarn); + await ThreadChannelAwareDeleteMessageAsync(new MockDiscordMessage(message), minMessages); } - public static async Task ThreadChannelAwareDeleteMessageAsync(MockDiscordMessage message, bool wasAutoWarn = false) + public static async Task ThreadChannelAwareDeleteMessageAsync(MockDiscordMessage message, int minMessages = 0) { // Deletes a message in a thread channel, or if it is the last message, deletes the thread instead. // If this is not a thread channel, just deletes the message. @@ -305,7 +305,7 @@ public static async Task ThreadChannelAwareDeleteMessageAsync(MockDiscordM if (message.Channel.Type == DiscordChannelType.GuildForum || message.Channel.Parent.Type == DiscordChannelType.GuildForum) { - wasThreadDeleted = await DoEmptyThreadCleanupAsync(message.Channel, message, wasAutoWarn); + wasThreadDeleted = await DoEmptyThreadCleanupAsync(message.Channel, message, minMessages); if (!wasThreadDeleted) await message.DeleteAsync(); } diff --git a/Helpers/WarningHelpers.cs b/Helpers/WarningHelpers.cs index 20eb8ae..9277915 100644 --- a/Helpers/WarningHelpers.cs +++ b/Helpers/WarningHelpers.cs @@ -390,12 +390,12 @@ public static UserWarning GetWarning(ulong targetUserId, long warnId = default) } } - public static async Task SendPublicWarningMessageAndDeleteInfringingMessageAsync(DiscordMessage infringingMessage, string warningMessageContent, bool wasAutoModBlock = false, bool wasAutoWarn = false) + public static async Task SendPublicWarningMessageAndDeleteInfringingMessageAsync(DiscordMessage infringingMessage, string warningMessageContent, bool wasAutoModBlock = false, int minMessages = 0) { - return await SendPublicWarningMessageAndDeleteInfringingMessageAsync(new MockDiscordMessage(infringingMessage), warningMessageContent, wasAutoModBlock, wasAutoWarn); + return await SendPublicWarningMessageAndDeleteInfringingMessageAsync(new MockDiscordMessage(infringingMessage), warningMessageContent, wasAutoModBlock, minMessages); } - public static async Task SendPublicWarningMessageAndDeleteInfringingMessageAsync(MockDiscordMessage infringingMessage, string warningMessageContent, bool wasAutoModBlock = false, bool wasAutoWarn = false) + public static async Task SendPublicWarningMessageAndDeleteInfringingMessageAsync(MockDiscordMessage infringingMessage, string warningMessageContent, bool wasAutoModBlock = false, int minMessages = 0) { // If this is a `GuildForum` channel, delete the thread if it is empty (empty = 1 message left if `isAutoWarn`, otherwise 0); if not empty, just delete the infringing message. // Then, based on whether the thread was deleted, send the warning message into the thread or into the configured fallback channel. @@ -412,7 +412,7 @@ public static async Task SendPublicWarningMessageAndDeleteInfrin if (!wasAutoModBlock) { - if (await DiscordHelpers.ThreadChannelAwareDeleteMessageAsync(infringingMessage, wasAutoWarn)) + if (await DiscordHelpers.ThreadChannelAwareDeleteMessageAsync(infringingMessage, minMessages)) targetChannel = await Program.discord.GetChannelAsync(Program.cfgjson.ForumChannelAutoWarnFallbackChannel); } var warningMessage = await targetChannel.SendMessageAsync(warningMessageContent);