mirror of
https://github.com/RPCS3/discord-bot.git
synced 2026-01-31 01:25:22 +01:00
upgrade d#+ client and update event handlers to keep the ordering where necessary
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
37
CompatBot/EventHandlers/OrderedEventHandlerWrapper.cs
Normal file
37
CompatBot/EventHandlers/OrderedEventHandlerWrapper.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user