From 02e6ccb13c978564e0fb3d29b55962c8dbf7cd86 Mon Sep 17 00:00:00 2001 From: FloatingMilkshake Date: Sat, 18 Jan 2025 22:21:01 -0500 Subject: [PATCH] Channel events: check user ban status before trying to fetch them Reduces 404s on channel create/update --- Tasks/EventTasks.cs | 56 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/Tasks/EventTasks.cs b/Tasks/EventTasks.cs index 107919c5..c7885f05 100644 --- a/Tasks/EventTasks.cs +++ b/Tasks/EventTasks.cs @@ -5,11 +5,39 @@ public class EventTasks public static Dictionary PendingChannelCreateEvents = new(); public static Dictionary PendingChannelUpdateEvents = new(); public static Dictionary PendingChannelDeleteEvents = new(); + + // populated in Channel Create & Update handlers to save API calls in IsMemberInServer method + private static List CurrentBans = new(); + + // set to true if the last attempt to populate CurrentBans failed, to suppress warnings in case of repeated failures + private static bool LastBanListPopulationFailed = false; // todo(milkshake): combine create & update handlers to reduce duplicate code public static async Task HandlePendingChannelCreateEventsAsync() { bool success = false; + + // populate CurrentBans list + try + { + Dictionary bans = (await Program.db.HashGetAllAsync("bans")).ToDictionary( + x => x.Name.ToString(), + x => JsonConvert.DeserializeObject(x.Value) + ); + + CurrentBans = bans.Values.ToList(); + + LastBanListPopulationFailed = false; + } + catch (Exception ex) + { + if (!LastBanListPopulationFailed) + Program.discord.Logger.LogWarning(ex, "Failed to populate list of current bans during override persistence checks! This warning will be suppressed until the next success!"); + + // Since this is likely caused by corrupt or otherwise unreadable data in the db, set a flag so that this warning is not spammed + // The flag will be reset on the next successful attempt to populate the CurrentBans list + LastBanListPopulationFailed = true; + } try { @@ -163,6 +191,28 @@ await Program.db.HashSetAsync("overrides", public static async Task HandlePendingChannelUpdateEventsAsync() { bool success = false; + + // populate CurrentBans list + try + { + Dictionary bans = (await Program.db.HashGetAllAsync("bans")).ToDictionary( + x => x.Name.ToString(), + x => JsonConvert.DeserializeObject(x.Value) + ); + + CurrentBans = bans.Values.ToList(); + + LastBanListPopulationFailed = false; + } + catch (Exception ex) + { + if (!LastBanListPopulationFailed) + Program.discord.Logger.LogWarning(ex, "Failed to populate list of current bans during override persistence checks! This warning will be suppressed until the next success!"); + + // Since this is likely caused by corrupt or otherwise unreadable data in the db, set a flag so that this warning is not spammed + // The flag will be reset on the next successful attempt to populate the CurrentBans list + LastBanListPopulationFailed = true; + } try { @@ -405,7 +455,11 @@ private static async Task IsMemberInServer(ulong userId, DiscordGuild guil if (guild.Members.ContainsKey(userId)) return true; - // If the user isn't cached, try fetching them to confirm + // If the user isn't cached, maybe they are banned? Check before making any API calls. + if (CurrentBans.Any(b => b.MemberId == userId)) + return false; + + // If the user isn't cached or banned, try fetching them to confirm try { await guild.GetMemberAsync(userId);