diff --git a/Boyfriend.csproj b/Boyfriend.csproj index a40b9a8..8c4cd81 100644 --- a/Boyfriend.csproj +++ b/Boyfriend.csproj @@ -23,10 +23,10 @@ - - - - + + + + diff --git a/src/Commands/AboutCommandGroup.cs b/src/Commands/AboutCommandGroup.cs index 50e7de7..b479764 100644 --- a/src/Commands/AboutCommandGroup.cs +++ b/src/Commands/AboutCommandGroup.cs @@ -57,7 +57,7 @@ public class AboutCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + var cfg = await _dataService.GetSettings(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(cfg); return await SendAboutBotAsync(currentUser, CancellationToken); diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index a8672a2..ad5ad5d 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -77,10 +77,10 @@ public class BanCommandGroup : CommandGroup { var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); - var guildResult = await _guildApi.GetGuildAsync(guildId.Value, ct: CancellationToken); + var guildResult = await _guildApi.GetGuildAsync(guildId, ct: CancellationToken); if (!guildResult.IsDefined(out var guild)) return Result.FromError(guildResult); @@ -88,7 +88,7 @@ public class BanCommandGroup : CommandGroup { Messages.Culture = GuildSettings.Language.Get(data.Settings); return await BanUserAsync( - target, reason, duration, guild, data, channelId.Value, user, currentUser, CancellationToken); + target, reason, duration, guild, data, channelId, user, currentUser, CancellationToken); } private async Task BanUserAsync( @@ -153,7 +153,7 @@ public class BanCommandGroup : CommandGroup { .WithColour(ColorsList.Green).Build(); var logResult = _utility.LogActionAsync( - data.Settings, channelId, user, title, description, target, ct); + data.Settings, channelId, user, title, description, target, ColorsList.Red, ct: ct); if (!logResult.IsSuccess) return Result.FromError(logResult.Error); @@ -193,15 +193,15 @@ public class BanCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); // Needed to get the tag and avatar - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); return await UnbanUserAsync( - target, reason, guildId.Value, data, channelId.Value, user, currentUser, CancellationToken); + target, reason, guildId, data, channelId, user, currentUser, CancellationToken); } private async Task UnbanUserAsync( @@ -227,7 +227,8 @@ public class BanCommandGroup : CommandGroup { var title = string.Format(Messages.UserUnbanned, target.GetTag()); var description = string.Format(Messages.DescriptionActionReason, reason); - var logResult = _utility.LogActionAsync(data.Settings, channelId, user, title, description, target, ct); + var logResult = _utility.LogActionAsync( + data.Settings, channelId, user, title, description, target, ColorsList.Green, ct: ct); if (!logResult.IsSuccess) return Result.FromError(logResult.Error); diff --git a/src/Commands/ClearCommandGroup.cs b/src/Commands/ClearCommandGroup.cs index 46ddc24..9fae93c 100644 --- a/src/Commands/ClearCommandGroup.cs +++ b/src/Commands/ClearCommandGroup.cs @@ -65,10 +65,10 @@ public class ClearCommandGroup : CommandGroup { new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); var messagesResult = await _channelApi.GetChannelMessagesAsync( - channelId.Value, limit: amount + 1, ct: CancellationToken); + channelId, limit: amount + 1, ct: CancellationToken); if (!messagesResult.IsDefined(out var messages)) return Result.FromError(messagesResult); - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); // The current user's avatar is used when sending messages @@ -76,10 +76,10 @@ public class ClearCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - return await ClearMessagesAsync(amount, data, channelId.Value, messages, user, currentUser, CancellationToken); + return await ClearMessagesAsync(amount, data, channelId, messages, user, currentUser, CancellationToken); } private async Task ClearMessagesAsync( @@ -103,7 +103,7 @@ public class ClearCommandGroup : CommandGroup { return Result.FromError(deleteResult.Error); var logResult = _utility.LogActionAsync( - data.Settings, channelId, user, title, description, currentUser, ct); + data.Settings, channelId, user, title, description, currentUser, ColorsList.Red, false, ct); if (!logResult.IsSuccess) return Result.FromError(logResult.Error); diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index 9111b7f..62bbbad 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -72,17 +72,17 @@ public class KickCommandGroup : CommandGroup { var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); - var guildResult = await _guildApi.GetGuildAsync(guildId.Value, ct: CancellationToken); + var guildResult = await _guildApi.GetGuildAsync(guildId, ct: CancellationToken); if (!guildResult.IsDefined(out var guild)) return Result.FromError(guildResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - var memberResult = await _guildApi.GetGuildMemberAsync(guildId.Value, target.ID, CancellationToken); + var memberResult = await _guildApi.GetGuildMemberAsync(guildId, target.ID, CancellationToken); if (!memberResult.IsSuccess) { var embed = new EmbedBuilder().WithSmallTitle(Messages.UserNotFoundShort, currentUser) .WithColour(ColorsList.Red).Build(); @@ -90,7 +90,7 @@ public class KickCommandGroup : CommandGroup { return await _feedbackService.SendContextualEmbedResultAsync(embed, CancellationToken); } - return await KickUserAsync(target, reason, guild, channelId.Value, data, user, currentUser, CancellationToken); + return await KickUserAsync(target, reason, guild, channelId, data, user, currentUser, CancellationToken); } private async Task KickUserAsync( @@ -133,7 +133,7 @@ public class KickCommandGroup : CommandGroup { var title = string.Format(Messages.UserKicked, target.GetTag()); var description = string.Format(Messages.DescriptionActionReason, reason); var logResult = _utility.LogActionAsync( - data.Settings, channelId, user, title, description, target, ct); + data.Settings, channelId, user, title, description, target, ColorsList.Red, ct: ct); if (!logResult.IsSuccess) return Result.FromError(logResult.Error); diff --git a/src/Commands/MuteCommandGroup.cs b/src/Commands/MuteCommandGroup.cs index 14895d5..697e24e 100644 --- a/src/Commands/MuteCommandGroup.cs +++ b/src/Commands/MuteCommandGroup.cs @@ -76,14 +76,14 @@ public class MuteCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - var memberResult = await _guildApi.GetGuildMemberAsync(guildId.Value, target.ID, CancellationToken); + var memberResult = await _guildApi.GetGuildMemberAsync(guildId, target.ID, CancellationToken); if (!memberResult.IsSuccess) { var embed = new EmbedBuilder().WithSmallTitle(Messages.UserNotFoundShort, currentUser) .WithColour(ColorsList.Red).Build(); @@ -92,7 +92,7 @@ public class MuteCommandGroup : CommandGroup { } return await MuteUserAsync( - target, reason, duration, guildId.Value, data, channelId.Value, user, currentUser, CancellationToken); + target, reason, duration, guildId, data, channelId, user, currentUser, CancellationToken); } private async Task MuteUserAsync( @@ -125,7 +125,7 @@ public class MuteCommandGroup : CommandGroup { Messages.DescriptionActionExpiresAt, Markdown.Timestamp(until))).ToString(); var logResult = _utility.LogActionAsync( - data.Settings, channelId, user, title, description, target, ct); + data.Settings, channelId, user, title, description, target, ColorsList.Red, ct: ct); if (!logResult.IsSuccess) return Result.FromError(logResult.Error); @@ -171,14 +171,14 @@ public class MuteCommandGroup : CommandGroup { return Result.FromError(currentUserResult); // Needed to get the tag and avatar - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - var memberResult = await _guildApi.GetGuildMemberAsync(guildId.Value, target.ID, CancellationToken); + var memberResult = await _guildApi.GetGuildMemberAsync(guildId, target.ID, CancellationToken); if (!memberResult.IsSuccess) { var embed = new EmbedBuilder().WithSmallTitle(Messages.UserNotFoundShort, currentUser) .WithColour(ColorsList.Red).Build(); @@ -187,7 +187,7 @@ public class MuteCommandGroup : CommandGroup { } return await UnmuteUserAsync( - target, reason, guildId.Value, data, channelId.Value, user, currentUser, CancellationToken); + target, reason, guildId, data, channelId, user, currentUser, CancellationToken); } private async Task UnmuteUserAsync( @@ -215,7 +215,7 @@ public class MuteCommandGroup : CommandGroup { var title = string.Format(Messages.UserUnmuted, target.GetTag()); var description = string.Format(Messages.DescriptionActionReason, reason); var logResult = _utility.LogActionAsync( - data.Settings, channelId, user, title, description, target, ct); + data.Settings, channelId, user, title, description, target, ColorsList.Green, ct: ct); if (!logResult.IsSuccess) return Result.FromError(logResult.Error); diff --git a/src/Commands/PingCommandGroup.cs b/src/Commands/PingCommandGroup.cs index 83b04c9..08e0c58 100644 --- a/src/Commands/PingCommandGroup.cs +++ b/src/Commands/PingCommandGroup.cs @@ -60,10 +60,10 @@ public class PingCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + var cfg = await _dataService.GetSettings(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(cfg); - return await SendLatencyAsync(channelId.Value, currentUser, CancellationToken); + return await SendLatencyAsync(channelId, currentUser, CancellationToken); } private async Task SendLatencyAsync( diff --git a/src/Commands/RemindCommandGroup.cs b/src/Commands/RemindCommandGroup.cs index 90016f6..2d892bc 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -55,14 +55,14 @@ public class RemindCommandGroup : CommandGroup { return Result.FromError( new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); - var userResult = await _userApi.GetUserAsync(userId.Value, CancellationToken); + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) return Result.FromError(userResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - return await AddReminderAsync(@in, message, data, channelId.Value, user, CancellationToken); + return await AddReminderAsync(@in, message, data, channelId, user, CancellationToken); } private async Task AddReminderAsync( diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 0e21155..8efce31 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -77,7 +77,7 @@ public class SettingsCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + var cfg = await _dataService.GetSettings(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(cfg); return await SendSettingsListAsync(cfg, currentUser, page, CancellationToken); @@ -142,7 +142,7 @@ public class SettingsCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var data = await _dataService.GetData(guildId.Value, CancellationToken); + var data = await _dataService.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); return await EditSettingAsync(setting, value, data, currentUser, CancellationToken); diff --git a/src/Data/Options/SnowflakeOption.cs b/src/Data/Options/SnowflakeOption.cs index f65065c..05921ff 100644 --- a/src/Data/Options/SnowflakeOption.cs +++ b/src/Data/Options/SnowflakeOption.cs @@ -1,11 +1,12 @@ using System.Text.Json.Nodes; +using System.Text.RegularExpressions; using Remora.Discord.Extensions.Formatting; using Remora.Rest.Core; using Remora.Results; namespace Boyfriend.Data.Options; -public class SnowflakeOption : Option { +public partial class SnowflakeOption : Option { public SnowflakeOption(string name) : base(name, 0UL.ToSnowflake()) { } public override string Display(JsonNode settings) { @@ -18,10 +19,13 @@ public class SnowflakeOption : Option { } public override Result Set(JsonNode settings, string from) { - if (!ulong.TryParse(from, out var parsed)) + if (!ulong.TryParse(NonNumbers().Replace(from, ""), out var parsed)) return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); settings[Name] = parsed; return Result.FromSuccess(); } + + [GeneratedRegex("[^0-9]")] + private static partial Regex NonNumbers(); } diff --git a/src/Extensions.cs b/src/Extensions.cs index a9e0d48..2fa342c 100644 --- a/src/Extensions.cs +++ b/src/Extensions.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Net; using System.Text; using DiffPlex.DiffBuilder.Model; @@ -182,11 +181,10 @@ public static class Extensions { } public static bool TryGetContextIDs( - this ICommandContext context, [NotNullWhen(true)] out Snowflake? guildId, - [NotNullWhen(true)] out Snowflake? channelId, [NotNullWhen(true)] out Snowflake? userId) { - guildId = null; - channelId = null; - userId = null; + this ICommandContext context, out Snowflake guildId, + out Snowflake channelId, out Snowflake userId) { + channelId = default; + userId = default; return context.TryGetGuildID(out guildId) && context.TryGetChannelID(out channelId) && context.TryGetUserID(out userId); diff --git a/src/Services/UtilityService.cs b/src/Services/UtilityService.cs index 18808eb..6ddc204 100644 --- a/src/Services/UtilityService.cs +++ b/src/Services/UtilityService.cs @@ -1,3 +1,4 @@ +using System.Drawing; using System.Text; using System.Text.Json.Nodes; using Boyfriend.Data; @@ -158,11 +159,13 @@ public class UtilityService : IHostedService { /// The title for the embed. /// The description of the embed. /// The user whose avatar will be displayed next to the of the embed. + /// The color of the embed. + /// Whether or not the embed should be sent in /// The cancellation token for this operation. - /// + /// A result which has succeeded. public Result LogActionAsync( - JsonNode cfg, Snowflake channelId, IUser user, string title, string description, IUser avatar, - CancellationToken ct = default) { + JsonNode cfg, Snowflake channelId, IUser user, string title, string description, IUser avatar, + Color color, bool isPublic = true, CancellationToken ct = default) { var publicChannel = GuildSettings.PublicFeedbackChannel.Get(cfg); var privateChannel = GuildSettings.PrivateFeedbackChannel.Get(cfg); if (GuildSettings.PublicFeedbackChannel.Get(cfg).EmptyOrEqualTo(channelId) @@ -173,7 +176,7 @@ public class UtilityService : IHostedService { .WithDescription(description) .WithActionFooter(user) .WithCurrentTimestamp() - .WithColour(ColorsList.Green) + .WithColour(color) .Build(); if (!logEmbed.IsDefined(out var logBuilt)) @@ -182,12 +185,12 @@ public class UtilityService : IHostedService { var builtArray = new[] { logBuilt }; // Not awaiting to reduce response time - if (publicChannel != channelId.Value) + if (isPublic && publicChannel != channelId) _ = _channelApi.CreateMessageAsync( publicChannel, embeds: builtArray, ct: ct); if (privateChannel != publicChannel - && privateChannel != channelId.Value) + && privateChannel != channelId) _ = _channelApi.CreateMessageAsync( privateChannel, embeds: builtArray, ct: ct);