upgrade d#+ client and update event handlers to keep the ordering where necessary

This commit is contained in:
13xforever
2023-04-15 19:39:51 +05:00
parent 833cc81f1c
commit d130b2f501
9 changed files with 138 additions and 96 deletions

View File

@@ -87,7 +87,7 @@ internal sealed class CompatList : BaseCommandModuleCustom
title = response.Result.Content.TrimEager().Truncate(40);
}
if (!await DiscordInviteFilter.CheckMessageForInvitesAsync(ctx.Client, ctx.Message).ConfigureAwait(false))
if (!await DiscordInviteFilter.CheckMessageInvitesAreSafeAsync(ctx.Client, ctx.Message).ConfigureAwait(false))
return;
if (!await ContentFilter.IsClean(ctx.Client, ctx.Message).ConfigureAwait(false))

View File

@@ -58,7 +58,7 @@ internal sealed class Explain: BaseCommandModuleCustom
}
}
if (!await DiscordInviteFilter.CheckMessageForInvitesAsync(ctx.Client, ctx.Message).ConfigureAwait(false))
if (!await DiscordInviteFilter.CheckMessageInvitesAreSafeAsync(ctx.Client, ctx.Message).ConfigureAwait(false))
return;
if (!await ContentFilter.IsClean(ctx.Client, ctx.Message).ConfigureAwait(false))
@@ -326,7 +326,7 @@ internal sealed class Explain: BaseCommandModuleCustom
return;
}
if (!await DiscordInviteFilter.CheckMessageForInvitesAsync(ctx.Client, ctx.Message).ConfigureAwait(false))
if (!await DiscordInviteFilter.CheckMessageInvitesAreSafeAsync(ctx.Client, ctx.Message).ConfigureAwait(false))
return;
termOrLink = termOrLink.ToLowerInvariant().StripQuotes();

View File

@@ -238,7 +238,6 @@ internal sealed partial class Psn
if (e.User.Id != authorId)
return;
e.Handled = true;
await e.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate).ConfigureAwait(false);
await e.Message.DeleteAsync().ConfigureAwait(false);
var refMsg = await e.Channel.GetMessageAsync(refMsgId).ConfigureAwait(false);

View File

@@ -39,10 +39,10 @@
<AdditionalFiles Include="..\win32_error_codes*.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DSharpPlus" Version="4.4.0-nightly-01386" />
<PackageReference Include="DSharpPlus.CommandsNext" Version="4.4.0-nightly-01386" />
<PackageReference Include="DSharpPlus.Interactivity" Version="4.4.0-nightly-01386" />
<PackageReference Include="DSharpPlus.SlashCommands" Version="4.4.0-nightly-01386" />
<PackageReference Include="DSharpPlus" Version="4.4.0" />
<PackageReference Include="DSharpPlus.CommandsNext" Version="4.4.0" />
<PackageReference Include="DSharpPlus.Interactivity" Version="4.4.0" />
<PackageReference Include="DSharpPlus.SlashCommands" Version="4.4.0" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.60.0.2986" />
<PackageReference Include="ksemenenko.ColorThief" Version="1.1.1.4" />
<PackageReference Include="MathParser.org-mXparser" Version="5.2.1" />

View File

@@ -9,15 +9,8 @@ namespace CompatBot.EventHandlers;
internal static class ContentFilterMonitor
{
public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArgs args)
{
args.Handled = !await ContentFilter.IsClean(c, args.Message).ConfigureAwait(false);
}
public static async Task OnMessageUpdated(DiscordClient c, MessageUpdateEventArgs args)
{
args.Handled = !await ContentFilter.IsClean(c, args.Message).ConfigureAwait(false);
}
public static Task<bool> OnMessageCreated(DiscordClient c, MessageCreateEventArgs args) => ContentFilter.IsClean(c, args.Message);
public static Task<bool> OnMessageUpdated(DiscordClient c, MessageUpdateEventArgs args) => ContentFilter.IsClean(c, args.Message);
public static async Task OnReaction(DiscordClient c, MessageReactionAddEventArgs e)
{

View File

@@ -25,66 +25,10 @@ internal static class DiscordInviteFilter
private static readonly MemoryCache InviteCodeCache = new(new MemoryCacheOptions{ExpirationScanFrequency = TimeSpan.FromHours(1)});
private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(24);
public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArgs args)
=> args.Handled = !await CheckMessageForInvitesAsync(c, args.Message).ConfigureAwait(false);
public static Task<bool> OnMessageCreated(DiscordClient c, MessageCreateEventArgs args) => CheckMessageInvitesAreSafeAsync(c, args.Message);
public static Task<bool> OnMessageUpdated(DiscordClient c, MessageUpdateEventArgs args) => CheckMessageInvitesAreSafeAsync(c, args.Message);
public static async Task OnMessageUpdated(DiscordClient c, MessageUpdateEventArgs args)
=> args.Handled = !await CheckMessageForInvitesAsync(c, args.Message).ConfigureAwait(false);
public static async Task CheckBacklogAsync(DiscordClient client, DiscordGuild guild)
{
try
{
var botMember = client.GetMember(guild, client.CurrentUser);
if (botMember == null)
{
await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);
botMember = client.GetMember(guild, client.CurrentUser);
if (botMember == null)
{
Config.Log.Error("Failed to resolve bot as the guild member for guild " + guild);
return;
}
}
var after = DateTime.UtcNow - Config.ModerationBacklogThresholdInHours;
foreach (var channel in guild.Channels.Values.Where(ch => !ch.IsCategory && ch.Type != ChannelType.Voice))
{
var permissions = channel.PermissionsFor(botMember);
if (!permissions.HasPermission(Permissions.ReadMessageHistory))
{
Config.Log.Warn($"No permissions to read message history in #{channel.Name}");
continue;
}
if (!permissions.HasPermission(Permissions.AccessChannels))
{
Config.Log.Warn($"No permissions to access #{channel.Name}");
continue;
}
try
{
var messages = await channel.GetMessagesCachedAsync(100).ConfigureAwait(false);
var messagesToCheck = from msg in messages
where msg.CreationTimestamp > after
select msg;
foreach (var message in messagesToCheck)
await CheckMessageForInvitesAsync(client, message).ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Warn(e, $"Some missing permissions in #{channel.Name}");
}
}
}
catch (Exception e)
{
Config.Log.Error(e);
}
}
public static async Task<bool> CheckMessageForInvitesAsync(DiscordClient client, DiscordMessage message)
public static async Task<bool> CheckMessageInvitesAreSafeAsync(DiscordClient client, DiscordMessage message)
{
if (message.Channel.IsPrivate)
return true;
@@ -187,6 +131,59 @@ internal static class DiscordInviteFilter
return true;
}
public static async Task CheckBacklogAsync(DiscordClient client, DiscordGuild guild)
{
try
{
var botMember = client.GetMember(guild, client.CurrentUser);
if (botMember == null)
{
await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);
botMember = client.GetMember(guild, client.CurrentUser);
if (botMember == null)
{
Config.Log.Error("Failed to resolve bot as the guild member for guild " + guild);
return;
}
}
var after = DateTime.UtcNow - Config.ModerationBacklogThresholdInHours;
foreach (var channel in guild.Channels.Values.Where(ch => !ch.IsCategory && ch.Type != ChannelType.Voice))
{
var permissions = channel.PermissionsFor(botMember);
if (!permissions.HasPermission(Permissions.ReadMessageHistory))
{
Config.Log.Warn($"No permissions to read message history in #{channel.Name}");
continue;
}
if (!permissions.HasPermission(Permissions.AccessChannels))
{
Config.Log.Warn($"No permissions to access #{channel.Name}");
continue;
}
try
{
var messages = await channel.GetMessagesCachedAsync(100).ConfigureAwait(false);
var messagesToCheck = from msg in messages
where msg.CreationTimestamp > after
select msg;
foreach (var message in messagesToCheck)
await CheckMessageInvitesAreSafeAsync(client, message).ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Warn(e, $"Some missing permissions in #{channel.Name}");
}
}
}
catch (Exception e)
{
Config.Log.Error(e);
}
}
public static async Task<(bool hasInvalidInvite, bool attemptToWorkaround, List<DiscordInvite> invites)> GetInvitesAsync(this DiscordClient client, string message, DiscordUser? author = null, bool tryMessageAsACode = false)
{
if (string.IsNullOrEmpty(message))

View File

@@ -33,6 +33,9 @@ internal sealed class MediaScreenshotMonitor
public async Task OnMessageCreated(DiscordClient _, MessageCreateEventArgs evt)
{
if (string.IsNullOrEmpty(Config.AzureComputerVisionKey))
return;
var message = evt.Message;
if (message == null)
return;

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DSharpPlus;
using DSharpPlus.EventArgs;
namespace CompatBot.EventHandlers;
public class OrderedEventHandlerWrapper<T> where T: DiscordEventArgs
{
private readonly ICollection<Func<DiscordClient,T,Task<bool>>> orderedHandlers;
private readonly ICollection<Func<DiscordClient,T,Task>> unorderedHandlers;
public OrderedEventHandlerWrapper(ICollection<Func<DiscordClient, T, Task<bool>>> orderedHandlers, ICollection<Func<DiscordClient, T, Task>> unorderedHandlers)
{
this.orderedHandlers = orderedHandlers;
this.unorderedHandlers = unorderedHandlers;
}
public async Task OnEvent(DiscordClient client, T eventArgs)
{
try
{
foreach (var h in orderedHandlers)
if (!await h(client, eventArgs).ConfigureAwait(false))
return;
var unorderedTasks = unorderedHandlers.Select(async h => await h(client, eventArgs).ConfigureAwait(false));
await Task.WhenAll(unorderedTasks).ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Error(e);
}
}
}

View File

@@ -17,6 +17,7 @@ using CompatBot.Utils.Extensions;
using DSharpPlus;
using DSharpPlus.CommandsNext;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.Interactivity.Extensions;
using DSharpPlus.SlashCommands;
using Microsoft.EntityFrameworkCore;
@@ -254,28 +255,40 @@ internal static class Program
client.MessageReactionAdded += Starbucks.Handler;
client.MessageReactionAdded += ContentFilterMonitor.OnReaction;
client.MessageCreated += Watchdog.OnMessageCreated;
client.MessageCreated += ContentFilterMonitor.OnMessageCreated; // should be first
client.MessageCreated += GlobalMessageCache.OnMessageCreated;
var mediaScreenshotMonitor = new MediaScreenshotMonitor(client);
if (!string.IsNullOrEmpty(Config.AzureComputerVisionKey))
client.MessageCreated += mediaScreenshotMonitor.OnMessageCreated;
client.MessageCreated += ProductCodeLookup.OnMessageCreated;
client.MessageCreated += LogParsingHandler.OnMessageCreated;
client.MessageCreated += LogAsTextMonitor.OnMessageCreated;
client.MessageCreated += DiscordInviteFilter.OnMessageCreated;
client.MessageCreated += PostLogHelpHandler.OnMessageCreated;
client.MessageCreated += BotReactionsHandler.OnMessageCreated;
client.MessageCreated += GithubLinksHandler.OnMessageCreated;
client.MessageCreated += NewBuildsMonitor.OnMessageCreated;
client.MessageCreated += TableFlipMonitor.OnMessageCreated;
client.MessageCreated += IsTheGamePlayableHandler.OnMessageCreated;
client.MessageCreated += EmpathySimulationHandler.OnMessageCreated;
client.MessageCreated += Watchdog.OnMessageCreated;
client.MessageCreated += new OrderedEventHandlerWrapper<MessageCreateEventArgs>(
new[]
{
ContentFilterMonitor.OnMessageCreated, // should be first
DiscordInviteFilter.OnMessageCreated,
},
new[]
{
GlobalMessageCache.OnMessageCreated,
mediaScreenshotMonitor.OnMessageCreated,
ProductCodeLookup.OnMessageCreated,
LogParsingHandler.OnMessageCreated,
LogAsTextMonitor.OnMessageCreated,
PostLogHelpHandler.OnMessageCreated,
BotReactionsHandler.OnMessageCreated,
GithubLinksHandler.OnMessageCreated,
NewBuildsMonitor.OnMessageCreated,
TableFlipMonitor.OnMessageCreated,
IsTheGamePlayableHandler.OnMessageCreated,
EmpathySimulationHandler.OnMessageCreated,
}).OnEvent;
client.MessageUpdated += GlobalMessageCache.OnMessageUpdated;
client.MessageUpdated += ContentFilterMonitor.OnMessageUpdated;
client.MessageUpdated += DiscordInviteFilter.OnMessageUpdated;
client.MessageUpdated += EmpathySimulationHandler.OnMessageUpdated;
client.MessageUpdated += new OrderedEventHandlerWrapper<MessageUpdateEventArgs>(new[]
{
ContentFilterMonitor.OnMessageUpdated,
DiscordInviteFilter.OnMessageUpdated,
},
new[]
{
GlobalMessageCache.OnMessageUpdated,
EmpathySimulationHandler.OnMessageUpdated,
}).OnEvent;
client.MessageDeleted += GlobalMessageCache.OnMessageDeleted;
if (Config.DeletedMessagesLogChannelId > 0)