chore: format with csharpier

This commit is contained in:
sam 2024-10-09 17:35:11 +02:00
parent 2f516dcb73
commit 4f54077c68
59 changed files with 2000 additions and 942 deletions

View file

@ -16,7 +16,8 @@ public class WebhookExecutorService(
ILogger logger,
IWebhookCache webhookCache,
ChannelCache channelCache,
IDiscordRestWebhookAPI webhookApi)
IDiscordRestWebhookAPI webhookApi
)
{
private readonly ILogger _logger = logger.ForContext<WebhookExecutorService>();
private readonly Snowflake _applicationId = DiscordSnowflake.New(config.Discord.ApplicationId);
@ -35,7 +36,8 @@ public class WebhookExecutorService(
public void QueueLog(Guild guildConfig, LogChannelType logChannelType, IEmbed embed)
{
var logChannel = GetLogChannel(guildConfig, logChannelType, channelId: null, userId: null);
if (logChannel == null) return;
if (logChannel == null)
return;
QueueLog(logChannel.Value, embed);
}
@ -45,7 +47,8 @@ public class WebhookExecutorService(
/// </summary>
public void QueueLog(ulong channelId, IEmbed embed)
{
if (channelId == 0) return;
if (channelId == 0)
return;
var queue = _cache.GetOrAdd(channelId, []);
queue.Enqueue(embed);
@ -60,40 +63,65 @@ public class WebhookExecutorService(
/// <param name="channelId">The channel ID to send the content to.</param>
/// <param name="embeds">The embeds to send. Must be under 6000 characters in length total, this is not checked by this method.</param>
/// <param name="files">The files to send.</param>
public async Task SendLogAsync(ulong channelId, List<IEmbed> embeds, IEnumerable<FileData> files)
public async Task SendLogAsync(
ulong channelId,
List<IEmbed> embeds,
IEnumerable<FileData> files
)
{
if (channelId == 0) return;
if (channelId == 0)
return;
var attachments = files
.Select<FileData, OneOf.OneOf<FileData, IPartialAttachment>>(f => f)
.ToList();
_logger.Debug("Sending {EmbedCount} embeds/{FileCount} files to channel {ChannelId}", embeds.Count,
attachments.Count, channelId);
_logger.Debug(
"Sending {EmbedCount} embeds/{FileCount} files to channel {ChannelId}",
embeds.Count,
attachments.Count,
channelId
);
var webhook = await webhookCache.GetOrFetchWebhookAsync(channelId, id => FetchWebhookAsync(id));
await webhookApi.ExecuteWebhookAsync(DiscordSnowflake.New(webhook.Id), webhook.Token, shouldWait: false,
embeds: embeds, attachments: attachments, username: _selfUser!.Username,
avatarUrl: _selfUser.AvatarUrl());
var webhook = await webhookCache.GetOrFetchWebhookAsync(
channelId,
id => FetchWebhookAsync(id)
);
await webhookApi.ExecuteWebhookAsync(
DiscordSnowflake.New(webhook.Id),
webhook.Token,
shouldWait: false,
embeds: embeds,
attachments: attachments,
username: _selfUser!.Username,
avatarUrl: _selfUser.AvatarUrl()
);
}
/// <summary>
/// Sets a 3 second timer for the given channel.
/// Sets a 3 second timer for the given channel.
/// </summary>
private void SetTimer(ulong channelId, ConcurrentQueue<IEmbed> queue)
{
if (_timers.TryGetValue(channelId, out var existingTimer)) existingTimer.Dispose();
_timers[channelId] = new Timer(_ =>
{
_logger.Debug("Sending 5 queued embeds");
var __ = SendLogAsync(channelId, TakeFromQueue(channelId).ToList(), []);
if (!queue.IsEmpty)
if (_timers.TryGetValue(channelId, out var existingTimer))
existingTimer.Dispose();
_timers[channelId] = new Timer(
_ =>
{
if (_timers.TryGetValue(channelId, out var timer)) timer.Dispose();
SetTimer(channelId, queue);
}
}, null, 3000, Timeout.Infinite);
_logger.Debug("Sending 5 queued embeds");
var __ = SendLogAsync(channelId, TakeFromQueue(channelId).ToList(), []);
if (!queue.IsEmpty)
{
if (_timers.TryGetValue(channelId, out var timer))
timer.Dispose();
SetTimer(channelId, queue);
}
},
null,
3000,
Timeout.Infinite
);
}
/// <summary>
@ -109,7 +137,8 @@ public class WebhookExecutorService(
var embeds = new List<IEmbed>();
for (var i = 0; i < 5; i++)
{
if (!queue.TryDequeue(out var embed)) break;
if (!queue.TryDequeue(out var embed))
break;
embeds.Add(embed);
}
@ -118,25 +147,48 @@ public class WebhookExecutorService(
}
// TODO: make it so this method can only have one request per channel in flight simultaneously
private async Task<IWebhook> FetchWebhookAsync(Snowflake channelId, CancellationToken ct = default)
private async Task<IWebhook> FetchWebhookAsync(
Snowflake channelId,
CancellationToken ct = default
)
{
var channelWebhooks =
await webhookApi.GetChannelWebhooksAsync(channelId, ct).GetOrThrow();
var webhook = channelWebhooks.FirstOrDefault(w => w.ApplicationID == _applicationId && w.Token.IsDefined());
if (webhook != null) return webhook;
var channelWebhooks = await webhookApi.GetChannelWebhooksAsync(channelId, ct).GetOrThrow();
var webhook = channelWebhooks.FirstOrDefault(w =>
w.ApplicationID == _applicationId && w.Token.IsDefined()
);
if (webhook != null)
return webhook;
return await webhookApi.CreateWebhookAsync(channelId, "Catalogger", default, reason: "Creating logging webhook",
ct: ct).GetOrThrow();
return await webhookApi
.CreateWebhookAsync(
channelId,
"Catalogger",
default,
reason: "Creating logging webhook",
ct: ct
)
.GetOrThrow();
}
public ulong? GetLogChannel(Guild guild, LogChannelType logChannelType, Snowflake? channelId = null,
ulong? userId = null)
public ulong? GetLogChannel(
Guild guild,
LogChannelType logChannelType,
Snowflake? channelId = null,
ulong? userId = null
)
{
if (channelId == null) return GetDefaultLogChannel(guild, logChannelType);
if (!channelCache.TryGet(channelId.Value, out var channel)) return null;
if (channelId == null)
return GetDefaultLogChannel(guild, logChannelType);
if (!channelCache.TryGet(channelId.Value, out var channel))
return null;
Snowflake? categoryId;
if (channel.Type is ChannelType.AnnouncementThread or ChannelType.PrivateThread or ChannelType.PublicThread)
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;
@ -151,67 +203,88 @@ public class WebhookExecutorService(
}
// Check if the channel, or its category, or the user is ignored
if (guild.Channels.IgnoredChannels.Contains(channelId.Value.Value) ||
categoryId != null && guild.Channels.IgnoredChannels.Contains(categoryId.Value.Value)) return null;
if (
guild.Channels.IgnoredChannels.Contains(channelId.Value.Value)
|| categoryId != null && guild.Channels.IgnoredChannels.Contains(categoryId.Value.Value)
)
return null;
if (userId != null)
{
if (guild.Channels.IgnoredUsers.Contains(userId.Value)) return null;
if (guild.Channels.IgnoredUsers.Contains(userId.Value))
return null;
// Check the channel-local and category-local ignored users
var channelIgnoredUsers =
guild.Channels.IgnoredUsersPerChannel.GetValueOrDefault(channelId.Value.Value) ?? [];
var categoryIgnoredUsers = (categoryId != null
? guild.Channels.IgnoredUsersPerChannel.GetValueOrDefault(categoryId.Value.Value)
: []) ?? [];
if (channelIgnoredUsers.Concat(categoryIgnoredUsers).Contains(userId.Value)) return null;
guild.Channels.IgnoredUsersPerChannel.GetValueOrDefault(channelId.Value.Value)
?? [];
var categoryIgnoredUsers =
(
categoryId != null
? guild.Channels.IgnoredUsersPerChannel.GetValueOrDefault(
categoryId.Value.Value
)
: []
) ?? [];
if (channelIgnoredUsers.Concat(categoryIgnoredUsers).Contains(userId.Value))
return null;
}
// These three events can be redirected to other channels. Redirects can be on a channel or category level.
// Obviously, the events are only redirected if they're supposed to be logged in the first place.
if (logChannelType is LogChannelType.MessageUpdate or LogChannelType.MessageDelete
or LogChannelType.MessageDeleteBulk)
if (
logChannelType
is LogChannelType.MessageUpdate
or LogChannelType.MessageDelete
or LogChannelType.MessageDeleteBulk
)
{
if (GetDefaultLogChannel(guild, logChannelType) == 0) return null;
if (GetDefaultLogChannel(guild, logChannelType) == 0)
return null;
var categoryRedirect = categoryId != null
? guild.Channels.Redirects.GetValueOrDefault(categoryId.Value.Value)
: 0;
var categoryRedirect =
categoryId != null
? guild.Channels.Redirects.GetValueOrDefault(categoryId.Value.Value)
: 0;
if (guild.Channels.Redirects.TryGetValue(channelId.Value.Value, out var channelRedirect))
if (
guild.Channels.Redirects.TryGetValue(channelId.Value.Value, out var channelRedirect)
)
return channelRedirect;
if (categoryRedirect != 0) return categoryRedirect;
if (categoryRedirect != 0)
return categoryRedirect;
return GetDefaultLogChannel(guild, logChannelType);
}
return GetDefaultLogChannel(guild, logChannelType);
}
public static ulong GetDefaultLogChannel(Guild guild, LogChannelType channelType) => channelType switch
{
LogChannelType.GuildUpdate => guild.Channels.GuildUpdate,
LogChannelType.GuildEmojisUpdate => guild.Channels.GuildEmojisUpdate,
LogChannelType.GuildRoleCreate => guild.Channels.GuildRoleCreate,
LogChannelType.GuildRoleUpdate => guild.Channels.GuildRoleUpdate,
LogChannelType.GuildRoleDelete => guild.Channels.GuildRoleDelete,
LogChannelType.ChannelCreate => guild.Channels.ChannelCreate,
LogChannelType.ChannelUpdate => guild.Channels.ChannelUpdate,
LogChannelType.ChannelDelete => guild.Channels.ChannelDelete,
LogChannelType.GuildMemberAdd => guild.Channels.GuildMemberAdd,
LogChannelType.GuildMemberUpdate => guild.Channels.GuildMemberUpdate,
LogChannelType.GuildKeyRoleUpdate => guild.Channels.GuildKeyRoleUpdate,
LogChannelType.GuildMemberNickUpdate => guild.Channels.GuildMemberNickUpdate,
LogChannelType.GuildMemberAvatarUpdate => guild.Channels.GuildMemberAvatarUpdate,
LogChannelType.GuildMemberRemove => guild.Channels.GuildMemberRemove,
LogChannelType.GuildMemberKick => guild.Channels.GuildMemberKick,
LogChannelType.GuildBanAdd => guild.Channels.GuildBanAdd,
LogChannelType.GuildBanRemove => guild.Channels.GuildBanRemove,
LogChannelType.InviteCreate => guild.Channels.InviteCreate,
LogChannelType.InviteDelete => guild.Channels.InviteDelete,
LogChannelType.MessageUpdate => guild.Channels.MessageUpdate,
LogChannelType.MessageDelete => guild.Channels.MessageDelete,
LogChannelType.MessageDeleteBulk => guild.Channels.MessageDeleteBulk,
_ => throw new ArgumentOutOfRangeException(nameof(channelType))
};
public static ulong GetDefaultLogChannel(Guild guild, LogChannelType channelType) =>
channelType switch
{
LogChannelType.GuildUpdate => guild.Channels.GuildUpdate,
LogChannelType.GuildEmojisUpdate => guild.Channels.GuildEmojisUpdate,
LogChannelType.GuildRoleCreate => guild.Channels.GuildRoleCreate,
LogChannelType.GuildRoleUpdate => guild.Channels.GuildRoleUpdate,
LogChannelType.GuildRoleDelete => guild.Channels.GuildRoleDelete,
LogChannelType.ChannelCreate => guild.Channels.ChannelCreate,
LogChannelType.ChannelUpdate => guild.Channels.ChannelUpdate,
LogChannelType.ChannelDelete => guild.Channels.ChannelDelete,
LogChannelType.GuildMemberAdd => guild.Channels.GuildMemberAdd,
LogChannelType.GuildMemberUpdate => guild.Channels.GuildMemberUpdate,
LogChannelType.GuildKeyRoleUpdate => guild.Channels.GuildKeyRoleUpdate,
LogChannelType.GuildMemberNickUpdate => guild.Channels.GuildMemberNickUpdate,
LogChannelType.GuildMemberAvatarUpdate => guild.Channels.GuildMemberAvatarUpdate,
LogChannelType.GuildMemberRemove => guild.Channels.GuildMemberRemove,
LogChannelType.GuildMemberKick => guild.Channels.GuildMemberKick,
LogChannelType.GuildBanAdd => guild.Channels.GuildBanAdd,
LogChannelType.GuildBanRemove => guild.Channels.GuildBanRemove,
LogChannelType.InviteCreate => guild.Channels.InviteCreate,
LogChannelType.InviteDelete => guild.Channels.InviteDelete,
LogChannelType.MessageUpdate => guild.Channels.MessageUpdate,
LogChannelType.MessageDelete => guild.Channels.MessageDelete,
LogChannelType.MessageDeleteBulk => guild.Channels.MessageDeleteBulk,
_ => throw new ArgumentOutOfRangeException(nameof(channelType)),
};
}
public enum LogChannelType
@ -237,5 +310,5 @@ public enum LogChannelType
InviteDelete,
MessageUpdate,
MessageDelete,
MessageDeleteBulk
}
MessageDeleteBulk,
}