refactor: clean up log channel resolution
This commit is contained in:
parent
24f6aee57d
commit
a4a6fb5d31
1 changed files with 114 additions and 106 deletions
|
|
@ -43,7 +43,7 @@ public class WebhookExecutorService(
|
||||||
private readonly ILogger _logger = logger.ForContext<WebhookExecutorService>();
|
private readonly ILogger _logger = logger.ForContext<WebhookExecutorService>();
|
||||||
private readonly Snowflake _applicationId = DiscordSnowflake.New(config.Discord.ApplicationId);
|
private readonly Snowflake _applicationId = DiscordSnowflake.New(config.Discord.ApplicationId);
|
||||||
private readonly ConcurrentDictionary<ulong, ConcurrentQueue<IEmbed>> _cache = new();
|
private readonly ConcurrentDictionary<ulong, ConcurrentQueue<IEmbed>> _cache = new();
|
||||||
private readonly ConcurrentDictionary<ulong, object> _locks = new();
|
private readonly ConcurrentDictionary<ulong, Lock> _locks = new();
|
||||||
private readonly ConcurrentDictionary<ulong, Timer> _timers = new();
|
private readonly ConcurrentDictionary<ulong, Timer> _timers = new();
|
||||||
private IUser? _selfUser;
|
private IUser? _selfUser;
|
||||||
|
|
||||||
|
|
@ -189,7 +189,7 @@ public class WebhookExecutorService(
|
||||||
private List<IEmbed> TakeFromQueue(ulong channelId)
|
private List<IEmbed> TakeFromQueue(ulong channelId)
|
||||||
{
|
{
|
||||||
var queue = _cache.GetOrAdd(channelId, []);
|
var queue = _cache.GetOrAdd(channelId, []);
|
||||||
var channelLock = _locks.GetOrAdd(channelId, channelId);
|
var channelLock = _locks.GetOrAdd(channelId, new Lock());
|
||||||
lock (channelLock)
|
lock (channelLock)
|
||||||
{
|
{
|
||||||
var totalContentLength = 0;
|
var totalContentLength = 0;
|
||||||
|
|
@ -293,10 +293,10 @@ public class WebhookExecutorService(
|
||||||
roleIds != null && logChannelType is LogChannelType.GuildMemberUpdate;
|
roleIds != null && logChannelType is LogChannelType.GuildMemberUpdate;
|
||||||
|
|
||||||
if (isMessageLog)
|
if (isMessageLog)
|
||||||
return GetMessageLogChannel(guild, logChannelType, channelId, userId);
|
return GetLogChannelForMessageEvent(guild, logChannelType, channelId, userId);
|
||||||
|
|
||||||
if (isChannelLog)
|
if (isChannelLog)
|
||||||
return GetChannelLogChannel(guild, logChannelType, channelId!.Value);
|
return GetLogChannelForChannelEvent(guild, logChannelType, channelId!.Value);
|
||||||
|
|
||||||
if (isRoleLog && guild.IgnoredRoles.Contains(roleId!.Value.Value))
|
if (isRoleLog && guild.IgnoredRoles.Contains(roleId!.Value.Value))
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -305,77 +305,11 @@ public class WebhookExecutorService(
|
||||||
if (isMemberRoleUpdateLog && roleIds!.All(r => guild.IgnoredRoles.Contains(r.Value)))
|
if (isMemberRoleUpdateLog && roleIds!.All(r => guild.IgnoredRoles.Contains(r.Value)))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// If nothing is ignored, return the correct log channel!
|
// If nothing is ignored, and this isn't a message or channel event, return the default log channel.
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong? GetChannelLogChannel(
|
private ulong? GetLogChannelForMessageEvent(
|
||||||
Guild guild,
|
|
||||||
LogChannelType logChannelType,
|
|
||||||
Snowflake channelId
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_logger.Verbose(
|
|
||||||
"Getting log channel for event {Event} in guild {GuildId} and channel {ChannelId}",
|
|
||||||
logChannelType,
|
|
||||||
guild.Id,
|
|
||||||
channelId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!channelCache.TryGet(channelId, out var channel))
|
|
||||||
{
|
|
||||||
_logger.Verbose(
|
|
||||||
"Channel with ID {ChannelId} is not cached, returning default log channel",
|
|
||||||
channelId
|
|
||||||
);
|
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
|
||||||
}
|
|
||||||
|
|
||||||
Snowflake? categoryId;
|
|
||||||
if (
|
|
||||||
channel.Type
|
|
||||||
is ChannelType.AnnouncementThread
|
|
||||||
or ChannelType.PrivateThread
|
|
||||||
or ChannelType.PublicThread
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// parent_id should always have a value for threads
|
|
||||||
channelId = channel.ParentID.Value!.Value;
|
|
||||||
if (!channelCache.TryGet(channelId, out var parentChannel))
|
|
||||||
{
|
|
||||||
_logger.Verbose(
|
|
||||||
"Parent channel for thread {ChannelId} is not in cache, returning the default log channel",
|
|
||||||
channelId
|
|
||||||
);
|
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
|
||||||
}
|
|
||||||
categoryId = parentChannel.ParentID.Value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
channelId = channel.ID;
|
|
||||||
categoryId = channel.ParentID.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the channel or its category is ignored
|
|
||||||
if (
|
|
||||||
guild.IgnoredChannels.Contains(channelId.Value)
|
|
||||||
|| (categoryId != null && guild.IgnoredChannels.Contains(categoryId.Value.Value))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_logger.Verbose(
|
|
||||||
"Channel {ChannelId} or its parent {CategoryId} is ignored",
|
|
||||||
channelId,
|
|
||||||
categoryId
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Verbose("Returning default log channel for {EventType}", logChannelType);
|
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ulong? GetMessageLogChannel(
|
|
||||||
Guild guild,
|
Guild guild,
|
||||||
LogChannelType logChannelType,
|
LogChannelType logChannelType,
|
||||||
Snowflake? channelId = null,
|
Snowflake? channelId = null,
|
||||||
|
|
@ -415,41 +349,24 @@ public class WebhookExecutorService(
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
}
|
}
|
||||||
|
|
||||||
Snowflake? categoryId;
|
if (!GetChannelAndParentId(channel, out var actualChannelId, out var categoryId))
|
||||||
if (
|
|
||||||
channel.Type
|
|
||||||
is ChannelType.AnnouncementThread
|
|
||||||
or ChannelType.PrivateThread
|
|
||||||
or ChannelType.PublicThread
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// parent_id should always have a value for threads
|
|
||||||
channelId = channel.ParentID.Value!.Value;
|
|
||||||
if (!channelCache.TryGet(channelId.Value, out var parentChannel))
|
|
||||||
{
|
{
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
"Parent channel for thread {ChannelId} is not in cache, returning the default log channel",
|
"Could not get root channel and category ID for channel {ChannelId}, returning default log channel",
|
||||||
channelId
|
channelId
|
||||||
);
|
);
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
}
|
}
|
||||||
categoryId = parentChannel.ParentID.Value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
channelId = channel.ID;
|
|
||||||
categoryId = channel.ParentID.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the channel or its category is ignored
|
// Check if the channel or its category is ignored
|
||||||
if (
|
if (
|
||||||
guild.Messages.IgnoredChannels.Contains(channelId.Value.Value)
|
guild.Messages.IgnoredChannels.Contains(actualChannelId.Value)
|
||||||
|| categoryId != null && guild.Messages.IgnoredChannels.Contains(categoryId.Value.Value)
|
|| categoryId != null && guild.Messages.IgnoredChannels.Contains(categoryId.Value.Value)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
"Channel {ChannelId} or its parent {CategoryId} is ignored",
|
"Channel {ChannelId} or its parent {CategoryId} is ignored",
|
||||||
channelId,
|
actualChannelId,
|
||||||
categoryId
|
categoryId
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -459,8 +376,10 @@ public class WebhookExecutorService(
|
||||||
{
|
{
|
||||||
// Check the channel-local and category-local ignored users
|
// Check the channel-local and category-local ignored users
|
||||||
var channelIgnoredUsers =
|
var channelIgnoredUsers =
|
||||||
guild.Messages.IgnoredUsersPerChannel.GetValueOrDefault(channelId.Value.Value)
|
guild.Messages.IgnoredUsersPerChannel.GetValueOrDefault(actualChannelId.Value)
|
||||||
?? [];
|
?? [];
|
||||||
|
|
||||||
|
// Obviously, we can only check for category-level ignored users if we actually got a category ID.
|
||||||
var categoryIgnoredUsers =
|
var categoryIgnoredUsers =
|
||||||
(
|
(
|
||||||
categoryId != null
|
categoryId != null
|
||||||
|
|
@ -469,6 +388,8 @@ public class WebhookExecutorService(
|
||||||
)
|
)
|
||||||
: []
|
: []
|
||||||
) ?? [];
|
) ?? [];
|
||||||
|
|
||||||
|
// Combine the ignored users in the channel and category, then check if the user is in there.
|
||||||
if (channelIgnoredUsers.Concat(categoryIgnoredUsers).Contains(userId.Value))
|
if (channelIgnoredUsers.Concat(categoryIgnoredUsers).Contains(userId.Value))
|
||||||
{
|
{
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
|
|
@ -482,7 +403,7 @@ public class WebhookExecutorService(
|
||||||
}
|
}
|
||||||
|
|
||||||
// These three events can be redirected to other channels. Redirects can be on a channel or category level.
|
// These three events can be redirected to other channels. Redirects can be on a channel or category level.
|
||||||
// The events are only redirected if they're supposed to be logged in the first place.
|
// The events are only redirected if they're supposed to be logged in the first place (i.e. GetDefaultLogChannel doesn't return 0)
|
||||||
if (GetDefaultLogChannel(guild, logChannelType) == 0)
|
if (GetDefaultLogChannel(guild, logChannelType) == 0)
|
||||||
{
|
{
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
|
|
@ -492,21 +413,21 @@ public class WebhookExecutorService(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var categoryRedirect =
|
if (guild.Channels.Redirects.TryGetValue(actualChannelId.Value, out var channelRedirect))
|
||||||
categoryId != null
|
|
||||||
? guild.Channels.Redirects.GetValueOrDefault(categoryId.Value.Value)
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
if (guild.Channels.Redirects.TryGetValue(channelId.Value.Value, out var channelRedirect))
|
|
||||||
{
|
{
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
"Messages from channel {ChannelId} should be redirected to {RedirectId}",
|
"Messages from channel {ChannelId} should be redirected to {RedirectId}",
|
||||||
channelId,
|
actualChannelId,
|
||||||
channelRedirect
|
channelRedirect
|
||||||
);
|
);
|
||||||
return channelRedirect;
|
return channelRedirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var categoryRedirect =
|
||||||
|
categoryId != null
|
||||||
|
? guild.Channels.Redirects.GetValueOrDefault(categoryId.Value.Value)
|
||||||
|
: 0;
|
||||||
|
|
||||||
if (categoryRedirect != 0)
|
if (categoryRedirect != 0)
|
||||||
{
|
{
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
|
|
@ -514,6 +435,7 @@ public class WebhookExecutorService(
|
||||||
categoryId,
|
categoryId,
|
||||||
categoryRedirect
|
categoryRedirect
|
||||||
);
|
);
|
||||||
|
return categoryRedirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Verbose(
|
_logger.Verbose(
|
||||||
|
|
@ -523,6 +445,92 @@ public class WebhookExecutorService(
|
||||||
return GetDefaultLogChannel(guild, logChannelType);
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ulong? GetLogChannelForChannelEvent(
|
||||||
|
Guild guild,
|
||||||
|
LogChannelType logChannelType,
|
||||||
|
Snowflake channelId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_logger.Verbose(
|
||||||
|
"Getting log channel for event {Event} in guild {GuildId} and channel {ChannelId}",
|
||||||
|
logChannelType,
|
||||||
|
guild.Id,
|
||||||
|
channelId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!channelCache.TryGet(channelId, out var channel))
|
||||||
|
{
|
||||||
|
_logger.Verbose(
|
||||||
|
"Channel with ID {ChannelId} is not cached, returning default log channel",
|
||||||
|
channelId
|
||||||
|
);
|
||||||
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetChannelAndParentId(channel, out channelId, out var categoryId))
|
||||||
|
{
|
||||||
|
_logger.Verbose(
|
||||||
|
"Could not get root channel and category ID for channel {ChannelId}, returning default log channel",
|
||||||
|
channelId
|
||||||
|
);
|
||||||
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the channel or its category is ignored
|
||||||
|
if (
|
||||||
|
guild.IgnoredChannels.Contains(channelId.Value)
|
||||||
|
|| (categoryId != null && guild.IgnoredChannels.Contains(categoryId.Value.Value))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_logger.Verbose(
|
||||||
|
"Channel {ChannelId} or its parent {CategoryId} is ignored",
|
||||||
|
channelId,
|
||||||
|
categoryId
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Verbose("Returning default log channel for {EventType}", logChannelType);
|
||||||
|
return GetDefaultLogChannel(guild, logChannelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetChannelAndParentId(
|
||||||
|
IChannel channel,
|
||||||
|
out Snowflake channelId,
|
||||||
|
out Snowflake? categoryId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
channel.Type
|
||||||
|
is ChannelType.AnnouncementThread
|
||||||
|
or ChannelType.PrivateThread
|
||||||
|
or ChannelType.PublicThread
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// parent_id should always have a value for threads
|
||||||
|
channelId = channel.ParentID.Value!.Value;
|
||||||
|
if (!channelCache.TryGet(channelId, out var parentChannel))
|
||||||
|
{
|
||||||
|
_logger.Verbose(
|
||||||
|
"Parent channel for thread {ChannelId} is not in cache, returning the default log channel",
|
||||||
|
channelId
|
||||||
|
);
|
||||||
|
|
||||||
|
channelId = Snowflake.CreateTimestampSnowflake();
|
||||||
|
categoryId = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
categoryId = parentChannel.ParentID.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
channelId = channel.ID;
|
||||||
|
categoryId = channel.ParentID.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static ulong GetDefaultLogChannel(Guild guild, LogChannelType logChannelType) =>
|
public static ulong GetDefaultLogChannel(Guild guild, LogChannelType logChannelType) =>
|
||||||
logChannelType switch
|
logChannelType switch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue