Skip to content

Commit 02e6ccb

Browse files
Channel events: check user ban status before trying to fetch them
Reduces 404s on channel create/update
1 parent c9269c6 commit 02e6ccb

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

Tasks/EventTasks.cs

+55-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,39 @@ public class EventTasks
55
public static Dictionary<DateTime, ChannelCreatedEventArgs> PendingChannelCreateEvents = new();
66
public static Dictionary<DateTime, ChannelUpdatedEventArgs> PendingChannelUpdateEvents = new();
77
public static Dictionary<DateTime, ChannelDeletedEventArgs> PendingChannelDeleteEvents = new();
8+
9+
// populated in Channel Create & Update handlers to save API calls in IsMemberInServer method
10+
private static List<MemberPunishment> CurrentBans = new();
11+
12+
// set to true if the last attempt to populate CurrentBans failed, to suppress warnings in case of repeated failures
13+
private static bool LastBanListPopulationFailed = false;
814

915
// todo(milkshake): combine create & update handlers to reduce duplicate code
1016
public static async Task<bool> HandlePendingChannelCreateEventsAsync()
1117
{
1218
bool success = false;
19+
20+
// populate CurrentBans list
21+
try
22+
{
23+
Dictionary<string, MemberPunishment> bans = (await Program.db.HashGetAllAsync("bans")).ToDictionary(
24+
x => x.Name.ToString(),
25+
x => JsonConvert.DeserializeObject<MemberPunishment>(x.Value)
26+
);
27+
28+
CurrentBans = bans.Values.ToList();
29+
30+
LastBanListPopulationFailed = false;
31+
}
32+
catch (Exception ex)
33+
{
34+
if (!LastBanListPopulationFailed)
35+
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!");
36+
37+
// Since this is likely caused by corrupt or otherwise unreadable data in the db, set a flag so that this warning is not spammed
38+
// The flag will be reset on the next successful attempt to populate the CurrentBans list
39+
LastBanListPopulationFailed = true;
40+
}
1341

1442
try
1543
{
@@ -163,6 +191,28 @@ await Program.db.HashSetAsync("overrides",
163191
public static async Task<bool> HandlePendingChannelUpdateEventsAsync()
164192
{
165193
bool success = false;
194+
195+
// populate CurrentBans list
196+
try
197+
{
198+
Dictionary<string, MemberPunishment> bans = (await Program.db.HashGetAllAsync("bans")).ToDictionary(
199+
x => x.Name.ToString(),
200+
x => JsonConvert.DeserializeObject<MemberPunishment>(x.Value)
201+
);
202+
203+
CurrentBans = bans.Values.ToList();
204+
205+
LastBanListPopulationFailed = false;
206+
}
207+
catch (Exception ex)
208+
{
209+
if (!LastBanListPopulationFailed)
210+
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!");
211+
212+
// Since this is likely caused by corrupt or otherwise unreadable data in the db, set a flag so that this warning is not spammed
213+
// The flag will be reset on the next successful attempt to populate the CurrentBans list
214+
LastBanListPopulationFailed = true;
215+
}
166216

167217
try
168218
{
@@ -405,7 +455,11 @@ private static async Task<bool> IsMemberInServer(ulong userId, DiscordGuild guil
405455
if (guild.Members.ContainsKey(userId))
406456
return true;
407457

408-
// If the user isn't cached, try fetching them to confirm
458+
// If the user isn't cached, maybe they are banned? Check before making any API calls.
459+
if (CurrentBans.Any(b => b.MemberId == userId))
460+
return false;
461+
462+
// If the user isn't cached or banned, try fetching them to confirm
409463
try
410464
{
411465
await guild.GetMemberAsync(userId);

0 commit comments

Comments
 (0)