diff --git a/CompatApiClient/Utils/Utils.cs b/CompatApiClient/Utils/Utils.cs index 9fc9237b..4b87c178 100644 --- a/CompatApiClient/Utils/Utils.cs +++ b/CompatApiClient/Utils/Utils.cs @@ -33,7 +33,8 @@ namespace CompatApiClient.Utils public static string Sanitize(this string str) { - return str?.Replace("`", "`\u200d").Replace("@", "@\u200d"); + return str?.Replace("`", "`\u200d").Replace("@", "@\u200d") + .Replace(".", ".\u200d").Replace(":", ":\u200d"); } public static int Clamp(this int amount, int low, int high) diff --git a/CompatBot/Commands/CompatList.cs b/CompatBot/Commands/CompatList.cs index 2b768eff..dafbb245 100644 --- a/CompatBot/Commands/CompatList.cs +++ b/CompatBot/Commands/CompatList.cs @@ -9,6 +9,7 @@ using CompatApiClient.POCOs; using CompatApiClient.Utils; using CompatBot.Commands.Attributes; using CompatBot.Database; +using CompatBot.EventHandlers; using CompatBot.Utils; using CompatBot.Utils.ResultFormatters; using DSharpPlus; @@ -44,6 +45,12 @@ namespace CompatBot.Commands return; } + if (!await DiscordInviteFilter.CheckMessageForInvitesAsync(ctx.Client, ctx.Message).ConfigureAwait(false)) + return; + + if (!await AntipiracyMonitor.IsClean(ctx.Client, ctx.Message).ConfigureAwait(false)) + return; + try { var requestBuilder = RequestBuilder.Start().SetSearch(title); @@ -218,7 +225,7 @@ Example usage: i.Title.Contains("africa", StringComparison.InvariantCultureIgnoreCase))) ) { - var sqvat = DiscordEmoji.FromName(ctx.Client, ":sqvat:"); + var sqvat = ctx.Client.GetEmoji(":sqvat:", Config.Reactions.No); result.AppendLine($"One day this meme will die {sqvat}"); } } diff --git a/CompatBot/Commands/Explain.cs b/CompatBot/Commands/Explain.cs index ca1bd210..0aabe3b0 100644 --- a/CompatBot/Commands/Explain.cs +++ b/CompatBot/Commands/Explain.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using CompatApiClient.Utils; using CompatBot.Commands.Attributes; using CompatBot.Database; +using CompatBot.EventHandlers; using CompatBot.Utils; using DSharpPlus.CommandsNext; using DSharpPlus.CommandsNext.Attributes; @@ -28,6 +29,15 @@ namespace CompatBot.Commands var spamChannel = await ctx.Client.GetChannelAsync(Config.BotSpamId).ConfigureAwait(false); inSpecificLocation = $" in {spamChannel.Mention} or bot DMs"; } + + + if (!await DiscordInviteFilter.CheckMessageForInvitesAsync(ctx.Client, ctx.Message).ConfigureAwait(false)) + return; + + if (!await AntipiracyMonitor.IsClean(ctx.Client, ctx.Message).ConfigureAwait(false)) + return; + + if (string.IsNullOrEmpty(term)) { await ctx.RespondAsync($"You may want to look at available terms by using `{Config.CommandPrefix}explain list`{inSpecificLocation}").ConfigureAwait(false); diff --git a/CompatBot/Commands/Misc.cs b/CompatBot/Commands/Misc.cs index 6a3e367d..17ed26c4 100644 --- a/CompatBot/Commands/Misc.cs +++ b/CompatBot/Commands/Misc.cs @@ -78,15 +78,7 @@ namespace CompatBot.Commands [Description("Author Credit")] public async Task Credits(CommandContext ctx) { - DiscordEmoji hcorion; - try - { - hcorion = DiscordEmoji.FromName(ctx.Client, ":hcorion:"); - } - catch - { - hcorion = DiscordEmoji.FromUnicode("🍁"); - } + var hcorion = ctx.Client.GetEmoji(":hcorion:", DiscordEmoji.FromUnicode("🍁")); var embed = new DiscordEmbedBuilder { Title = "RPCS3 Compatibility Bot", @@ -98,7 +90,8 @@ namespace CompatBot.Commands .AddField("People who ~~broke~~ helped test the bot", "🐱 Juhn\n" + $"{hcorion} hcorion\n" + - "🙃 TGE"); + "🙃 TGE\n" + + "Ⓜ Maru"); await ctx.RespondAsync(embed: embed.Build()); } diff --git a/CompatBot/Commands/Psn.Check.cs b/CompatBot/Commands/Psn.Check.cs index 630c38c2..111c7248 100644 --- a/CompatBot/Commands/Psn.Check.cs +++ b/CompatBot/Commands/Psn.Check.cs @@ -48,8 +48,10 @@ namespace CompatBot.Commands if (partStart > -1) newTitle += embed.Title.Substring(partStart); embed.Title = newTitle; + if (!string.IsNullOrEmpty(embed.ThumbnailUrl)) + embed.ThumbnailUrl = "https://cdn.discordapp.com/attachments/417347469521715210/516340151589535745/onionoff.png"; } - var sqvat = DiscordEmoji.FromName(ctx.Client, ":sqvat:"); + var sqvat = ctx.Client.GetEmoji(":sqvat:", Config.Reactions.No); await ctx.Message.ReactWithAsync(ctx.Client, sqvat).ConfigureAwait(false); } if (embeds.Count > 1 || embeds[0].Fields?.Count > 0) diff --git a/CompatBot/Config.cs b/CompatBot/Config.cs index dd702b7c..2eb562d6 100644 --- a/CompatBot/Config.cs +++ b/CompatBot/Config.cs @@ -67,6 +67,7 @@ namespace CompatBot public static readonly DiscordEmoji Denied = DiscordEmoji.FromUnicode("👮"); public static readonly DiscordEmoji Starbucks = DiscordEmoji.FromUnicode("☕"); public static readonly DiscordEmoji Moderated = DiscordEmoji.FromUnicode("🔨"); + public static readonly DiscordEmoji No = DiscordEmoji.FromUnicode("😐"); } public static class Moderation diff --git a/CompatBot/EventHandlers/AntipiracyMonitor.cs b/CompatBot/EventHandlers/AntipiracyMonitor.cs index 5ca2b377..8af6c0f2 100644 --- a/CompatBot/EventHandlers/AntipiracyMonitor.cs +++ b/CompatBot/EventHandlers/AntipiracyMonitor.cs @@ -22,9 +22,12 @@ namespace CompatBot.EventHandlers args.Handled = !await IsClean(args.Client, args.Message).ConfigureAwait(false); } - private static async Task IsClean(DiscordClient client, DiscordMessage message) + public static async Task IsClean(DiscordClient client, DiscordMessage message) { - if (DefaultHandlerFilter.IsFluff(message)) + if (message.Channel.IsPrivate) + return true; + + if (message.Author.IsBot) return true; if (message.Author.IsWhitelisted(client, message.Channel.Guild)) diff --git a/CompatBot/EventHandlers/DiscordInviteFilter.cs b/CompatBot/EventHandlers/DiscordInviteFilter.cs index 745cdd1a..22b3e9c6 100644 --- a/CompatBot/EventHandlers/DiscordInviteFilter.cs +++ b/CompatBot/EventHandlers/DiscordInviteFilter.cs @@ -23,10 +23,17 @@ namespace CompatBot.EventHandlers private static readonly Regex DiscordMeLink = new Regex(@"(https?://)?discord\.me/(?.*?)(\s|$)", DefaultOptions); private static readonly HttpClient HttpClient = HttpClientFactory.Create(new CompressionMessageHandler()); - public static Task OnMessageCreated(MessageCreateEventArgs args) => CheckMessageForInvitesAsync(args.Client, args.Message); - public static Task OnMessageUpdated(MessageUpdateEventArgs args) => CheckMessageForInvitesAsync(args.Client, args.Message); + public static async Task OnMessageCreated(MessageCreateEventArgs args) + { + args.Handled = !await CheckMessageForInvitesAsync(args.Client, args.Message).ConfigureAwait(false); + } - public static async Task CheckBacklogAsync(DiscordClient client, DiscordGuild guild) + public static async Task OnMessageUpdated(MessageUpdateEventArgs args) + { + args.Handled = !await CheckMessageForInvitesAsync(args.Client, args.Message).ConfigureAwait(false); + } + + public static async Task CheckBacklogAsync(DiscordClient client, DiscordGuild guild) { try { @@ -47,20 +54,23 @@ namespace CompatBot.EventHandlers } } - private static async Task CheckMessageForInvitesAsync(DiscordClient client, DiscordMessage message) + public static async Task CheckMessageForInvitesAsync(DiscordClient client, DiscordMessage message) { - if (DefaultHandlerFilter.IsFluff(message)) - return; + if (message.Channel.IsPrivate) + return true; + + if (message.Author.IsBot) + return true; if (message.Author.IsWhitelisted(client, message.Channel.Guild)) - return; + return true; if (message.Reactions.Any(r => r.Emoji == Config.Reactions.Moderated && r.IsMe)) - return; + return true; var (hasInvalidResults, invites) = await client.GetInvitesAsync(message.Content).ConfigureAwait(false); if (!hasInvalidResults && invites.Count == 0) - return; + return true; if (hasInvalidResults) { @@ -81,7 +91,7 @@ namespace CompatBot.EventHandlers true ).ConfigureAwait(false); } - return; + return false; } foreach (var invite in invites) @@ -107,9 +117,10 @@ namespace CompatBot.EventHandlers true ).ConfigureAwait(false); } - return; + return false; } } + return true; } public static async Task<(bool hasInvalidInvite, List invites)> GetInvitesAsync(this DiscordClient client, string message, bool tryMessageAsACode = false) diff --git a/CompatBot/EventHandlers/ProductCodeLookup.cs b/CompatBot/EventHandlers/ProductCodeLookup.cs index bfc5ffec..57d761ef 100644 --- a/CompatBot/EventHandlers/ProductCodeLookup.cs +++ b/CompatBot/EventHandlers/ProductCodeLookup.cs @@ -58,10 +58,10 @@ namespace CompatBot.EventHandlers return; await args.Channel.TriggerTypingAsync().ConfigureAwait(false); - var results = new List<(string code, Task task)>(codesToLookup.Count); + var results = new List<(string code, Task task)>(codesToLookup.Count); foreach (var code in codesToLookup) results.Add((code, args.Client.LookupGameInfoAsync(code))); - var formattedResults = new List(results.Count); + var formattedResults = new List(results.Count); foreach (var result in results) try { @@ -85,11 +85,12 @@ namespace CompatBot.EventHandlers result.Title.Contains("afrika", StringComparison.InvariantCultureIgnoreCase) )) { - sqvat = sqvat ?? DiscordEmoji.FromName(args.Client, ":sqvat:"); - await args.Message.ReactWithAsync(args.Client, sqvat, "How about no (๑•ิཬ•ั๑)").ConfigureAwait(false); - continue; + sqvat = sqvat ?? args.Client.GetEmoji(":sqvat:", Config.Reactions.No); + result.Title = "How about no (๑•ิཬ•ั๑)"; + if (!string.IsNullOrEmpty(result.ThumbnailUrl)) + result.ThumbnailUrl = "https://cdn.discordapp.com/attachments/417347469521715210/516340151589535745/onionoff.png"; + await args.Message.ReactWithAsync(args.Client, sqvat).ConfigureAwait(false); } - await args.Channel.SendMessageAsync(embed: result).ConfigureAwait(false); } catch (Exception e) @@ -106,7 +107,7 @@ namespace CompatBot.EventHandlers .ToList(); } - public static async Task LookupGameInfoAsync(this DiscordClient client, string code, string gameTitle = null, bool forLog = false) + public static async Task LookupGameInfoAsync(this DiscordClient client, string code, string gameTitle = null, bool forLog = false) { if (string.IsNullOrEmpty(code)) return TitleInfo.Unknown.AsEmbed(code); diff --git a/CompatBot/Utils/DiscordClientExtensions.cs b/CompatBot/Utils/DiscordClientExtensions.cs index 7c996e3a..ba5b25c6 100644 --- a/CompatBot/Utils/DiscordClientExtensions.cs +++ b/CompatBot/Utils/DiscordClientExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using CompatApiClient; using CompatApiClient.Utils; using DSharpPlus; using DSharpPlus.CommandsNext; @@ -129,6 +130,19 @@ namespace CompatBot.Utils return string.IsNullOrEmpty(member.Nickname) ? $"<@{member.Id}> (`{member.Username.Sanitize()}#{member.Discriminator}`)" : $"<@{member.Id}> (`{member.Username.Sanitize()}#{member.Discriminator}`, shown as `{member.Nickname.Sanitize()}`)"; } + public static DiscordEmoji GetEmoji(this DiscordClient client, string emojiName, DiscordEmoji fallbackEmoji = null) + { + try + { + return DiscordEmoji.FromName(client, emojiName); + } + catch (Exception e) + { + ApiConfig.Log.Warn(e); + return fallbackEmoji; + } + } + private static DiscordEmbedBuilder MakeReportTemplate(DiscordClient client, string infraction, DiscordMessage message, ReportSeverity severity) { var content = message.Content; diff --git a/CompatBot/Utils/ResultFormatters/TitleInfoFormatter.cs b/CompatBot/Utils/ResultFormatters/TitleInfoFormatter.cs index fee0d5c0..68e92e3d 100644 --- a/CompatBot/Utils/ResultFormatters/TitleInfoFormatter.cs +++ b/CompatBot/Utils/ResultFormatters/TitleInfoFormatter.cs @@ -53,13 +53,13 @@ namespace CompatBot.Utils.ResultFormatters return $"Product code {titleId} was not found in compatibility database, possibly untested!"; } - public static DiscordEmbed AsEmbed(this TitleInfo info, string titleId, string gameTitle = null, bool forLog = false, string thumbnailUrl = null) + public static DiscordEmbedBuilder AsEmbed(this TitleInfo info, string titleId, string gameTitle = null, bool forLog = false, string thumbnailUrl = null) { if (info.Status == TitleInfo.Maintenance.Status) - return new DiscordEmbedBuilder{Description = "API is undergoing maintenance, please try again later.", Color = Config.Colors.Maintenance}.Build(); + return new DiscordEmbedBuilder{Description = "API is undergoing maintenance, please try again later.", Color = Config.Colors.Maintenance}; if (info.Status == TitleInfo.CommunicationError.Status) - return new DiscordEmbedBuilder{Description = "Error communicating with compatibility API, please try again later.", Color = Config.Colors.Maintenance}.Build(); + return new DiscordEmbedBuilder{Description = "Error communicating with compatibility API, please try again later.", Color = Config.Colors.Maintenance}; if (string.IsNullOrWhiteSpace(gameTitle)) gameTitle = null; @@ -82,8 +82,7 @@ namespace CompatBot.Utils.ResultFormatters Description = desc, Color = color, ThumbnailUrl = thumbnailUrl - } - .Build(); + }; } else { @@ -101,7 +100,7 @@ namespace CompatBot.Utils.ResultFormatters gameTitle = titleName; if (!string.IsNullOrEmpty(gameTitle)) result.Title = $"[{titleId}] {gameTitle.Sanitize().Trim(200)}"; - return result.Build(); + return result; } }