From c6dd3727c393ecfa1a0f703880bd6749714a5ae0 Mon Sep 17 00:00:00 2001 From: Macintosh II <95250141+mctaylors@users.noreply.github.com> Date: Tue, 18 Jul 2023 15:25:02 +0300 Subject: [PATCH] The Milestone Commit (#48) mctaylors: - updated readme 7 times (and only adding new logo from /about) - [removed](https://github.com/TeamOctolings/Boyfriend/pull/48/commits/aeeb3d4399c31df70b47ccdf59f6963fdb68e9ec) bot footer from created event embed on the second try - [changed](https://github.com/TeamOctolings/Boyfriend/pull/48/commits/4b9b91d9e4d2289d9aad4e600f5ca6a424638a6e) cdn from discord to upload.systems Octol1ttle: - Guild settings code has been overhauled. Instead of instances of a `GuildConfiguration` class being (de-)serialized when used with listing and setting options provided by reflection, there are now multiple `Option` classes responsible for the type of option they are storing. The classes support getting a value, validating and setting values with Results, and getting a user-friendly representation of these values. This makes use of polymorphism, providing clean and easier to use and refactor code. - Gateway event responders have been split into their own separate files, which should make it easier to find and modify responders when needed. - Warning suppressions regarding unused and never instantiated classes have been replaced by `[ImplicitUse]` annotations provided by `JetBrains.Annotations`. This avoids hiding real issues and provides a better way to suppress false warnings while being explicit. - It is no longer possible to execute some slash commands if they are run without the correct permissions - Dependencies are now more explicitly defined neroduckale: - Made easter eggs case-insensitive --------- Signed-off-by: Macintosh II <95250141+mctaylors@users.noreply.github.com> Signed-off-by: Octol1ttle Co-authored-by: Octol1ttle Co-authored-by: nrdk --- .github/workflows/resharper.yml | 6 +- Boyfriend.csproj | 6 +- docs/README.md | 12 +- docs/assets/boyfriend.png | Bin 0 -> 229373 bytes src/Boyfriend.cs | 19 +- src/Commands/AboutCommandGroup.cs | 14 +- src/Commands/BanCommandGroup.cs | 53 +-- src/Commands/ClearCommandGroup.cs | 20 +- src/Commands/ErrorLoggingEvents.cs | 16 +- src/Commands/KickCommandGroup.cs | 30 +- src/Commands/MuteCommandGroup.cs | 53 +-- src/Commands/PingCommandGroup.cs | 11 +- src/Commands/RemindCommandGroup.cs | 12 +- src/Commands/SettingsCommandGroup.cs | 96 ++--- src/Data/GuildConfiguration.cs | 90 ----- src/Data/GuildData.cs | 15 +- src/Data/GuildSettings.cs | 63 ++++ src/Data/MemberData.cs | 4 +- src/Data/Options/BoolOption.cs | 34 ++ src/Data/Options/IOption.cs | 10 + src/Data/Options/LanguageOption.cs | 35 ++ src/Data/Options/Option.cs | 46 +++ src/Data/Options/SnowflakeOption.cs | 27 ++ src/Data/Options/TimeSpanOption.cs | 28 ++ src/Data/Reminder.cs | 6 +- src/EventResponders.cs | 335 ------------------ src/Extensions.cs | 6 +- src/InteractionResponders.cs | 6 +- {locale => src}/Messages.Designer.cs | 3 - src/Responders/GuildLoadedResponder.cs | 63 ++++ src/Responders/GuildMemberJoinedResponder.cs | 65 ++++ .../GuildMemberRolesUpdatedResponder.cs | 26 ++ src/Responders/MessageDeletedResponder.cs | 78 ++++ src/Responders/MessageEditedResponder.cs | 89 +++++ src/Responders/MessageReceivedResponder.cs | 34 ++ .../ScheduledEventCancelledResponder.cs | 45 +++ src/Services/GuildDataService.cs | 26 +- src/Services/GuildUpdateService.cs | 55 ++- src/Services/UtilityService.cs | 33 +- 39 files changed, 912 insertions(+), 658 deletions(-) create mode 100644 docs/assets/boyfriend.png delete mode 100644 src/Data/GuildConfiguration.cs create mode 100644 src/Data/GuildSettings.cs create mode 100644 src/Data/Options/BoolOption.cs create mode 100644 src/Data/Options/IOption.cs create mode 100644 src/Data/Options/LanguageOption.cs create mode 100644 src/Data/Options/Option.cs create mode 100644 src/Data/Options/SnowflakeOption.cs create mode 100644 src/Data/Options/TimeSpanOption.cs delete mode 100644 src/EventResponders.cs rename {locale => src}/Messages.Designer.cs (99%) create mode 100644 src/Responders/GuildLoadedResponder.cs create mode 100644 src/Responders/GuildMemberJoinedResponder.cs create mode 100644 src/Responders/GuildMemberRolesUpdatedResponder.cs create mode 100644 src/Responders/MessageDeletedResponder.cs create mode 100644 src/Responders/MessageEditedResponder.cs create mode 100644 src/Responders/MessageReceivedResponder.cs create mode 100644 src/Responders/ScheduledEventCancelledResponder.cs diff --git a/.github/workflows/resharper.yml b/.github/workflows/resharper.yml index 82b2562..b0ec1a3 100644 --- a/.github/workflows/resharper.yml +++ b/.github/workflows/resharper.yml @@ -4,10 +4,12 @@ concurrency: cancel-in-progress: true on: - push: - branches: [ "master" ] pull_request: branches: [ "master" ] + merge_group: + types: [checks_requested] + push: + branches: [ "master" ] jobs: inspect-code: diff --git a/Boyfriend.csproj b/Boyfriend.csproj index f6cc7dc..a40b9a8 100644 --- a/Boyfriend.csproj +++ b/Boyfriend.csproj @@ -21,8 +21,12 @@ + - + + + + diff --git a/docs/README.md b/docs/README.md index 21ffbbf..0cde8ef 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,12 +1,6 @@ - - - - - - - Boyfriend Logo - - +

+ Boyfriend logo +

![GitHub License](https://img.shields.io/github/license/TeamOctolings/Boyfriend) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/TeamOctolings/Boyfriend/.github/workflows/resharper.yml?branch=master) diff --git a/docs/assets/boyfriend.png b/docs/assets/boyfriend.png new file mode 100644 index 0000000000000000000000000000000000000000..a8a5d16d00a9d1f89ed810d4df10114194e65cb0 GIT binary patch literal 229373 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ξF6Jv2>c1wCgvURWH$; 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 - settings => { - settings.SetDefaultAbsoluteExpiration(TimeSpan.FromHours(1)); - settings.SetDefaultSlidingExpiration(TimeSpan.FromMinutes(30)); - settings.SetAbsoluteExpiration(TimeSpan.FromDays(7)); - settings.SetSlidingExpiration(TimeSpan.FromDays(7)); + cSettings => { + cSettings.SetDefaultAbsoluteExpiration(TimeSpan.FromHours(1)); + cSettings.SetDefaultSlidingExpiration(TimeSpan.FromMinutes(30)); + cSettings.SetAbsoluteExpiration(TimeSpan.FromDays(7)); + cSettings.SetSlidingExpiration(TimeSpan.FromDays(7)); }); services.AddTransient() + // Init .AddDiscordCaching() .AddDiscordCommands(true) - .AddPreparationErrorEvent() - .AddPostExecutionEvent() + // Interactions .AddInteractivity() .AddInteractionGroup() + // Slash command event handlers + .AddPreparationErrorEvent() + .AddPostExecutionEvent() + // Services .AddSingleton() .AddSingleton() .AddHostedService() + // Slash commands .AddCommandTree() .WithCommandGroup() .WithCommandGroup() diff --git a/src/Commands/AboutCommandGroup.cs b/src/Commands/AboutCommandGroup.cs index 5ff757e..edb34d2 100644 --- a/src/Commands/AboutCommandGroup.cs +++ b/src/Commands/AboutCommandGroup.cs @@ -1,6 +1,8 @@ using System.ComponentModel; using System.Text; +using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Rest; @@ -10,14 +12,12 @@ using Remora.Discord.Extensions.Embeds; using Remora.Discord.Extensions.Formatting; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; ///

/// Handles the command to show information about this bot: /about. /// +[UsedImplicitly] public class AboutCommandGroup : CommandGroup { private static readonly string[] Developers = { "Octol1ttle", "mctaylors", "neroduckale" }; private readonly ICommandContext _context; @@ -42,6 +42,7 @@ public class AboutCommandGroup : CommandGroup { /// [Command("about")] [Description("Shows Boyfriend's developers")] + [UsedImplicitly] public async Task SendAboutBotAsync() { if (!_context.TryGetContextIDs(out var guildId, out _, out _)) return Result.FromError( @@ -51,8 +52,8 @@ public class AboutCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); var builder = new StringBuilder().AppendLine(Markdown.Bold(Messages.AboutTitleDevelopers)); foreach (var dev in Developers) @@ -65,8 +66,7 @@ public class AboutCommandGroup : CommandGroup { var embed = new EmbedBuilder().WithSmallTitle(Messages.AboutBot, currentUser) .WithDescription(builder.ToString()) .WithColour(ColorsList.Cyan) - .WithImageUrl( - "https://media.discordapp.net/attachments/837385840946053181/1125009665592393738/boyfriend.png") + .WithImageUrl("https://cdn.upload.systems/uploads/JFAaX5vr.png") .Build(); if (!embed.IsDefined(out var built)) return Result.FromError(embed); diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index 02e0fa2..d2c1c76 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -1,11 +1,14 @@ using System.ComponentModel; using System.Text; +using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.API.Objects; +using Remora.Discord.Commands.Attributes; using Remora.Discord.Commands.Conditions; using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; @@ -13,14 +16,12 @@ using Remora.Discord.Extensions.Embeds; using Remora.Discord.Extensions.Formatting; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles commands related to ban management: /ban and /unban. /// +[UsedImplicitly] public class BanCommandGroup : CommandGroup { private readonly IDiscordRestChannelAPI _channelApi; private readonly ICommandContext _context; @@ -58,10 +59,13 @@ public class BanCommandGroup : CommandGroup { /// /// [Command("ban", "бан")] + [DiscordDefaultMemberPermissions(DiscordPermission.BanMembers)] + [DiscordDefaultDMPermission(false)] [RequireContext(ChannelContext.Guild)] [RequireDiscordPermission(DiscordPermission.BanMembers)] [RequireBotDiscordPermissions(DiscordPermission.BanMembers)] [Description("Ban user")] + [UsedImplicitly] public async Task BanUserAsync( [Description("User to ban")] IUser target, [Description("Ban reason")] string reason, @@ -76,8 +80,8 @@ public class BanCommandGroup : CommandGroup { return Result.FromError(currentUserResult); var data = await _dataService.GetData(guildId.Value, CancellationToken); - var cfg = data.Configuration; - Messages.Culture = data.Culture; + var cfg = data.Settings; + Messages.Culture = GuildSettings.Language.Get(cfg); var existingBanResult = await _guildApi.GetGuildBanAsync(guildId.Value, target.ID, CancellationToken); if (existingBanResult.IsDefined()) { @@ -145,8 +149,10 @@ public class BanCommandGroup : CommandGroup { string.Format(Messages.UserBanned, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - if ((cfg.PublicFeedbackChannel is not 0 && cfg.PublicFeedbackChannel != channelId.Value) - || (cfg.PrivateFeedbackChannel is not 0 && cfg.PrivateFeedbackChannel != channelId.Value)) { + if ((!GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) + || (!GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value)) { var logEmbed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.UserBanned, target.GetTag()), target) .WithDescription(description) @@ -160,14 +166,14 @@ public class BanCommandGroup : CommandGroup { var builtArray = new[] { logBuilt }; // Not awaiting to reduce response time - if (cfg.PublicFeedbackChannel != channelId.Value) + if (GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); - if (cfg.PrivateFeedbackChannel != cfg.PublicFeedbackChannel - && cfg.PrivateFeedbackChannel != channelId.Value) + if (GuildSettings.PrivateFeedbackChannel.Get(cfg) != GuildSettings.PublicFeedbackChannel.Get(cfg) + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); } } @@ -193,10 +199,13 @@ public class BanCommandGroup : CommandGroup { /// /// [Command("unban")] + [DiscordDefaultMemberPermissions(DiscordPermission.BanMembers)] + [DiscordDefaultDMPermission(false)] [RequireContext(ChannelContext.Guild)] [RequireDiscordPermission(DiscordPermission.BanMembers)] [RequireBotDiscordPermissions(DiscordPermission.BanMembers)] [Description("Unban user")] + [UsedImplicitly] public async Task UnbanUserAsync( [Description("User to unban")] IUser target, [Description("Unban reason")] string reason) { @@ -209,8 +218,8 @@ public class BanCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); var existingBanResult = await _guildApi.GetGuildBanAsync(guildId.Value, target.ID, CancellationToken); if (!existingBanResult.IsDefined()) { @@ -238,8 +247,10 @@ public class BanCommandGroup : CommandGroup { string.Format(Messages.UserUnbanned, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - if ((cfg.PublicFeedbackChannel is not 0 && cfg.PublicFeedbackChannel != channelId.Value) - || (cfg.PrivateFeedbackChannel is not 0 && cfg.PrivateFeedbackChannel != channelId.Value)) { + if ((!GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) + || (!GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value)) { var logEmbed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.UserUnbanned, target.GetTag()), target) .WithDescription(string.Format(Messages.DescriptionActionReason, reason)) @@ -254,14 +265,14 @@ public class BanCommandGroup : CommandGroup { var builtArray = new[] { logBuilt }; // Not awaiting to reduce response time - if (cfg.PublicFeedbackChannel != channelId.Value) + if (GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); - if (cfg.PrivateFeedbackChannel != cfg.PublicFeedbackChannel - && cfg.PrivateFeedbackChannel != channelId.Value) + if (GuildSettings.PrivateFeedbackChannel.Get(cfg) != GuildSettings.PublicFeedbackChannel.Get(cfg) + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); } diff --git a/src/Commands/ClearCommandGroup.cs b/src/Commands/ClearCommandGroup.cs index de44fbb..ede4d0b 100644 --- a/src/Commands/ClearCommandGroup.cs +++ b/src/Commands/ClearCommandGroup.cs @@ -1,6 +1,8 @@ using System.ComponentModel; using System.Text; +using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Objects; @@ -14,14 +16,12 @@ using Remora.Discord.Extensions.Formatting; using Remora.Rest.Core; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles the command to clear messages in a channel: /clear. /// +[UsedImplicitly] public class ClearCommandGroup : CommandGroup { private readonly IDiscordRestChannelAPI _channelApi; private readonly ICommandContext _context; @@ -48,10 +48,13 @@ public class ClearCommandGroup : CommandGroup { /// were cleared and vice-versa. /// [Command("clear", "очистить")] + [DiscordDefaultMemberPermissions(DiscordPermission.ManageMessages)] + [DiscordDefaultDMPermission(false)] [RequireContext(ChannelContext.Guild)] [RequireDiscordPermission(DiscordPermission.ManageMessages)] [RequireBotDiscordPermissions(DiscordPermission.ManageMessages)] [Description("Remove multiple messages")] + [UsedImplicitly] public async Task ClearMessagesAsync( [Description("Number of messages to remove (2-100)")] [MinValue(2)] [MaxValue(100)] int amount) { @@ -64,8 +67,8 @@ public class ClearCommandGroup : CommandGroup { if (!messagesResult.IsDefined(out var messages)) return Result.FromError(messagesResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); var idList = new List(messages.Count); var builder = new StringBuilder().AppendLine(Mention.Channel(channelId.Value)).AppendLine(); @@ -93,7 +96,8 @@ public class ClearCommandGroup : CommandGroup { return Result.FromError(currentUserResult); var title = string.Format(Messages.MessagesCleared, amount.ToString()); - if (cfg.PrivateFeedbackChannel is not 0 && cfg.PrivateFeedbackChannel != channelId.Value) { + if (!GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) { var logEmbed = new EmbedBuilder().WithSmallTitle(title, currentUser) .WithDescription(description) .WithActionFooter(user) @@ -105,9 +109,9 @@ public class ClearCommandGroup : CommandGroup { return Result.FromError(logEmbed); // Not awaiting to reduce response time - if (cfg.PrivateFeedbackChannel != channelId.Value) + if (GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { logBuilt }, + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { logBuilt }, ct: CancellationToken); } diff --git a/src/Commands/ErrorLoggingEvents.cs b/src/Commands/ErrorLoggingEvents.cs index 30869b4..c5eba21 100644 --- a/src/Commands/ErrorLoggingEvents.cs +++ b/src/Commands/ErrorLoggingEvents.cs @@ -1,15 +1,16 @@ +using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Remora.Discord.Commands.Contexts; +using Remora.Discord.Commands.Extensions; using Remora.Discord.Commands.Services; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global - namespace Boyfriend.Commands; /// /// Handles error logging for slash commands that couldn't be successfully prepared. /// +[UsedImplicitly] public class ErrorLoggingPreparationErrorEvent : IPreparationErrorEvent { private readonly ILogger _logger; @@ -27,8 +28,11 @@ public class ErrorLoggingPreparationErrorEvent : IPreparationErrorEvent { /// A result which has succeeded. public Task PreparationFailed( IOperationContext context, IResult preparationResult, CancellationToken ct = default) { - if (!preparationResult.IsSuccess) + if (!preparationResult.IsSuccess && !preparationResult.Error.IsUserOrEnvironmentError()) { _logger.LogWarning("Error in slash command preparation.\n{ErrorMessage}", preparationResult.Error.Message); + if (preparationResult.Error is ExceptionError exerr) + _logger.LogError(exerr.Exception, "An exception has been thrown"); + } return Task.FromResult(Result.FromSuccess()); } @@ -37,6 +41,7 @@ public class ErrorLoggingPreparationErrorEvent : IPreparationErrorEvent { /// /// Handles error logging for slash command groups. /// +[UsedImplicitly] public class ErrorLoggingPostExecutionEvent : IPostExecutionEvent { private readonly ILogger _logger; @@ -54,8 +59,11 @@ public class ErrorLoggingPostExecutionEvent : IPostExecutionEvent { /// A result which has succeeded. public Task AfterExecutionAsync( ICommandContext context, IResult commandResult, CancellationToken ct = default) { - if (!commandResult.IsSuccess) + if (!commandResult.IsSuccess && !commandResult.Error.IsUserOrEnvironmentError()) { _logger.LogWarning("Error in slash command execution.\n{ErrorMessage}", commandResult.Error.Message); + if (commandResult.Error is ExceptionError exerr) + _logger.LogError(exerr.Exception, "An exception has been thrown"); + } return Task.FromResult(Result.FromSuccess()); } diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index da7b2c5..5809677 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -1,24 +1,25 @@ using System.ComponentModel; +using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.API.Objects; +using Remora.Discord.Commands.Attributes; using Remora.Discord.Commands.Conditions; using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; using Remora.Discord.Extensions.Embeds; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles the command to kick members of a guild: /kick. /// +[UsedImplicitly] public class KickCommandGroup : CommandGroup { private readonly IDiscordRestChannelAPI _channelApi; private readonly ICommandContext _context; @@ -54,10 +55,13 @@ public class KickCommandGroup : CommandGroup { /// was kicked and vice-versa. /// [Command("kick", "кик")] + [DiscordDefaultMemberPermissions(DiscordPermission.KickMembers)] + [DiscordDefaultDMPermission(false)] [RequireContext(ChannelContext.Guild)] [RequireDiscordPermission(DiscordPermission.KickMembers)] [RequireBotDiscordPermissions(DiscordPermission.KickMembers)] [Description("Kick member")] + [UsedImplicitly] public async Task KickUserAsync( [Description("Member to kick")] IUser target, [Description("Kick reason")] string reason) { @@ -71,8 +75,8 @@ public class KickCommandGroup : CommandGroup { return Result.FromError(currentUserResult); var data = await _dataService.GetData(guildId.Value, CancellationToken); - var cfg = data.Configuration; - Messages.Culture = cfg.GetCulture(); + var cfg = data.Settings; + Messages.Culture = GuildSettings.Language.Get(cfg); var memberResult = await _guildApi.GetGuildMemberAsync(guildId.Value, target.ID, CancellationToken); if (!memberResult.IsSuccess) { @@ -129,8 +133,10 @@ public class KickCommandGroup : CommandGroup { string.Format(Messages.UserKicked, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - if ((cfg.PublicFeedbackChannel is not 0 && cfg.PublicFeedbackChannel != channelId.Value) - || (cfg.PrivateFeedbackChannel is not 0 && cfg.PrivateFeedbackChannel != channelId.Value)) { + if ((!GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) + || (!GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value)) { var logEmbed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.UserKicked, target.GetTag()), target) .WithDescription(string.Format(Messages.DescriptionActionReason, reason)) @@ -144,14 +150,14 @@ public class KickCommandGroup : CommandGroup { var builtArray = new[] { logBuilt }; // Not awaiting to reduce response time - if (cfg.PublicFeedbackChannel != channelId.Value) + if (GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); - if (cfg.PrivateFeedbackChannel != cfg.PublicFeedbackChannel - && cfg.PrivateFeedbackChannel != channelId.Value) + if (GuildSettings.PrivateFeedbackChannel.Get(cfg) != GuildSettings.PublicFeedbackChannel.Get(cfg) + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); } } diff --git a/src/Commands/MuteCommandGroup.cs b/src/Commands/MuteCommandGroup.cs index 764b4f4..4338d09 100644 --- a/src/Commands/MuteCommandGroup.cs +++ b/src/Commands/MuteCommandGroup.cs @@ -1,11 +1,14 @@ using System.ComponentModel; using System.Text; +using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.API.Objects; +using Remora.Discord.Commands.Attributes; using Remora.Discord.Commands.Conditions; using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; @@ -13,14 +16,12 @@ using Remora.Discord.Extensions.Embeds; using Remora.Discord.Extensions.Formatting; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles commands related to mute management: /mute and /unmute. /// +[UsedImplicitly] public class MuteCommandGroup : CommandGroup { private readonly IDiscordRestChannelAPI _channelApi; private readonly ICommandContext _context; @@ -58,10 +59,13 @@ public class MuteCommandGroup : CommandGroup { /// /// [Command("mute", "мут")] + [DiscordDefaultMemberPermissions(DiscordPermission.ModerateMembers)] + [DiscordDefaultDMPermission(false)] [RequireContext(ChannelContext.Guild)] [RequireDiscordPermission(DiscordPermission.ModerateMembers)] [RequireBotDiscordPermissions(DiscordPermission.ModerateMembers)] [Description("Mute member")] + [UsedImplicitly] public async Task MuteUserAsync( [Description("Member to mute")] IUser target, [Description("Mute reason")] string reason, @@ -93,8 +97,8 @@ public class MuteCommandGroup : CommandGroup { return Result.FromError(interactionResult); var data = await _dataService.GetData(guildId.Value, CancellationToken); - var cfg = data.Configuration; - Messages.Culture = data.Culture; + var cfg = data.Settings; + Messages.Culture = GuildSettings.Language.Get(cfg); Result responseEmbed; if (interactionResult.Entity is not null) { @@ -116,8 +120,10 @@ public class MuteCommandGroup : CommandGroup { string.Format(Messages.UserMuted, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - if ((cfg.PublicFeedbackChannel is not 0 && cfg.PublicFeedbackChannel != channelId.Value) - || (cfg.PrivateFeedbackChannel is not 0 && cfg.PrivateFeedbackChannel != channelId.Value)) { + if ((!GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) + || (!GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value)) { var builder = new StringBuilder().AppendLine(string.Format(Messages.DescriptionActionReason, reason)) .Append( string.Format( @@ -136,14 +142,14 @@ public class MuteCommandGroup : CommandGroup { var builtArray = new[] { logBuilt }; // Not awaiting to reduce response time - if (cfg.PublicFeedbackChannel != channelId.Value) + if (GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); - if (cfg.PrivateFeedbackChannel != cfg.PublicFeedbackChannel - && cfg.PrivateFeedbackChannel != channelId.Value) + if (GuildSettings.PrivateFeedbackChannel.Get(cfg) != GuildSettings.PublicFeedbackChannel.Get(cfg) + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); } } @@ -169,10 +175,13 @@ public class MuteCommandGroup : CommandGroup { /// /// [Command("unmute", "размут")] + [DiscordDefaultMemberPermissions(DiscordPermission.ModerateMembers)] + [DiscordDefaultDMPermission(false)] [RequireContext(ChannelContext.Guild)] [RequireDiscordPermission(DiscordPermission.ModerateMembers)] [RequireBotDiscordPermissions(DiscordPermission.ModerateMembers)] [Description("Unmute member")] + [UsedImplicitly] public async Task UnmuteUserAsync( [Description("Member to unmute")] IUser target, [Description("Unmute reason")] string reason) { @@ -185,8 +194,8 @@ public class MuteCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); var memberResult = await _guildApi.GetGuildMemberAsync(guildId.Value, target.ID, CancellationToken); if (!memberResult.IsSuccess) { @@ -220,8 +229,10 @@ public class MuteCommandGroup : CommandGroup { string.Format(Messages.UserUnmuted, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - if ((cfg.PublicFeedbackChannel is not 0 && cfg.PublicFeedbackChannel != channelId.Value) - || (cfg.PrivateFeedbackChannel is not 0 && cfg.PrivateFeedbackChannel != channelId.Value)) { + if ((!GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) + || (!GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty() + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value)) { var logEmbed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.UserUnmuted, target.GetTag()), target) .WithDescription(string.Format(Messages.DescriptionActionReason, reason)) @@ -236,14 +247,14 @@ public class MuteCommandGroup : CommandGroup { var builtArray = new[] { logBuilt }; // Not awaiting to reduce response time - if (cfg.PublicFeedbackChannel != channelId.Value) + if (GuildSettings.PublicFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); - if (cfg.PrivateFeedbackChannel != cfg.PublicFeedbackChannel - && cfg.PrivateFeedbackChannel != channelId.Value) + if (GuildSettings.PrivateFeedbackChannel.Get(cfg) != GuildSettings.PublicFeedbackChannel.Get(cfg) + && GuildSettings.PrivateFeedbackChannel.Get(cfg) != channelId.Value) _ = _channelApi.CreateMessageAsync( - cfg.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: builtArray, + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: builtArray, ct: CancellationToken); } diff --git a/src/Commands/PingCommandGroup.cs b/src/Commands/PingCommandGroup.cs index 45d27e2..52d924f 100644 --- a/src/Commands/PingCommandGroup.cs +++ b/src/Commands/PingCommandGroup.cs @@ -1,5 +1,7 @@ using System.ComponentModel; +using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Rest; @@ -9,14 +11,12 @@ using Remora.Discord.Extensions.Embeds; using Remora.Discord.Gateway; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles the command to get the time taken for the gateway to respond to the last heartbeat: /ping /// +[UsedImplicitly] public class PingCommandGroup : CommandGroup { private readonly IDiscordRestChannelAPI _channelApi; private readonly DiscordGatewayClient _client; @@ -44,6 +44,7 @@ public class PingCommandGroup : CommandGroup { /// [Command("ping", "пинг")] [Description("Get bot latency")] + [UsedImplicitly] public async Task SendPingAsync() { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out _)) return Result.FromError( @@ -53,8 +54,8 @@ public class PingCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); var latency = _client.Latency.TotalMilliseconds; if (latency is 0) { diff --git a/src/Commands/RemindCommandGroup.cs b/src/Commands/RemindCommandGroup.cs index d1c4519..7203fbd 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -1,23 +1,23 @@ using System.ComponentModel; using Boyfriend.Data; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Commands.Attributes; using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; using Remora.Discord.Extensions.Embeds; using Remora.Discord.Extensions.Formatting; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles the command to manage reminders: /remind /// +[UsedImplicitly] public class RemindCommandGroup : CommandGroup { private readonly ICommandContext _context; private readonly GuildDataService _dataService; @@ -40,7 +40,9 @@ public class RemindCommandGroup : CommandGroup { /// The text of the reminder. /// A feedback sending result which may or may not have succeeded. [Command("remind")] + [DiscordDefaultDMPermission(false)] [Description("Create a reminder")] + [UsedImplicitly] public async Task AddReminderAsync( [Description("After what period of time mention the reminder")] TimeSpan @in, @@ -57,8 +59,8 @@ public class RemindCommandGroup : CommandGroup { (await _dataService.GetMemberData(guildId.Value, userId.Value, CancellationToken)).Reminders.Add( new Reminder { - RemindAt = remindAt, - Channel = channelId.Value, + At = remindAt, + Channel = channelId.Value.Value, Text = message }); diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index e519d37..5c4a505 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -1,26 +1,44 @@ using System.ComponentModel; -using System.Reflection; using System.Text; using Boyfriend.Data; +using Boyfriend.Data.Options; using Boyfriend.Services; +using JetBrains.Annotations; using Remora.Commands.Attributes; using Remora.Commands.Groups; +using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Commands.Attributes; +using Remora.Discord.Commands.Conditions; using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; using Remora.Discord.Extensions.Embeds; using Remora.Discord.Extensions.Formatting; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend.Commands; /// /// Handles the commands to list and modify per-guild settings: /settings and /settings list. /// +[UsedImplicitly] public class SettingsCommandGroup : CommandGroup { + private static readonly IOption[] AllOptions = { + GuildSettings.Language, + GuildSettings.WelcomeMessage, + GuildSettings.ReceiveStartupMessages, + GuildSettings.RemoveRolesOnMute, + GuildSettings.ReturnRolesOnRejoin, + GuildSettings.AutoStartEvents, + GuildSettings.PublicFeedbackChannel, + GuildSettings.PrivateFeedbackChannel, + GuildSettings.EventNotificationChannel, + GuildSettings.DefaultRole, + GuildSettings.MuteRole, + GuildSettings.EventNotificationRole, + GuildSettings.EventEarlyNotificationOffset + }; + private readonly ICommandContext _context; private readonly GuildDataService _dataService; private readonly FeedbackService _feedbackService; @@ -36,13 +54,18 @@ public class SettingsCommandGroup : CommandGroup { } /// - /// A slash command that lists current per-guild settings. + /// A slash command that lists current per-guild GuildSettings. /// /// /// A feedback sending result which may or may not have succeeded. /// [Command("settingslist")] + [DiscordDefaultMemberPermissions(DiscordPermission.ManageGuild)] + [DiscordDefaultDMPermission(false)] + [RequireContext(ChannelContext.Guild)] + [RequireDiscordPermission(DiscordPermission.ManageGuild)] [Description("Shows settings list for this server")] + [UsedImplicitly] public async Task ListSettingsAsync() { if (!_context.TryGetContextIDs(out var guildId, out _, out _)) return Result.FromError( @@ -52,19 +75,15 @@ public class SettingsCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); var builder = new StringBuilder(); - foreach (var setting in typeof(GuildConfiguration).GetProperties()) { - builder.Append(Markdown.InlineCode(setting.Name)) + foreach (var option in AllOptions) { + builder.Append(Markdown.InlineCode(option.Name)) .Append(": "); - var something = setting.GetValue(cfg); - if (something!.GetType() == typeof(List)) { - var list = (something as List); - builder.AppendLine(string.Join(", ", list!.Select(v => Markdown.InlineCode(v.ToString())))); - } else { builder.AppendLine(Markdown.InlineCode(something.ToString()!)); } + builder.AppendLine(option.Display(cfg)); } var embed = new EmbedBuilder().WithSmallTitle(Messages.SettingsListTitle, currentUser) @@ -77,13 +96,18 @@ public class SettingsCommandGroup : CommandGroup { } /// - /// A slash command that modifies per-guild settings. + /// A slash command that modifies per-guild GuildSettings. /// /// The setting to modify. /// The new value of the setting. /// A feedback sending result which may or may not have succeeded. [Command("settings")] + [DiscordDefaultMemberPermissions(DiscordPermission.ManageGuild)] + [DiscordDefaultDMPermission(false)] + [RequireContext(ChannelContext.Guild)] + [RequireDiscordPermission(DiscordPermission.ManageGuild)] [Description("Change settings for this server")] + [UsedImplicitly] public async Task EditSettingsAsync( [Description("The setting whose value you want to change")] string setting, @@ -96,40 +120,16 @@ public class SettingsCommandGroup : CommandGroup { if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - var cfg = await _dataService.GetConfiguration(guildId.Value, CancellationToken); - Messages.Culture = cfg.GetCulture(); + var cfg = await _dataService.GetSettings(guildId.Value, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(cfg); - PropertyInfo? property = null; + var option = AllOptions.Single( + o => string.Equals(setting, o.Name, StringComparison.InvariantCultureIgnoreCase)); - try { - foreach (var prop in typeof(GuildConfiguration).GetProperties()) - if (string.Equals(setting, prop.Name, StringComparison.CurrentCultureIgnoreCase)) - property = prop; - if (property == null || !property.CanWrite) - throw new ApplicationException(Messages.SettingDoesntExist); - var type = property.PropertyType; - - if (value is "reset" or "default") { property.SetValue(cfg, null); } else if (type == typeof(string)) { - if (setting == "language" && value is not ("ru" or "en" or "mctaylors-ru")) - throw new ApplicationException(Messages.LanguageNotSupported); - property.SetValue(cfg, value); - } else { - try { - if (type == typeof(bool)) - property.SetValue(cfg, Convert.ToBoolean(value)); - - if (type == typeof(ulong)) { - var id = Convert.ToUInt64(value); - - property.SetValue(cfg, id); - } - } catch (Exception e) when (e is FormatException or OverflowException) { - throw new ApplicationException(Messages.InvalidSettingValue); - } - } - } catch (Exception e) { + var setResult = option.Set(cfg, value); + if (!setResult.IsSuccess) { var failedEmbed = new EmbedBuilder().WithSmallTitle(Messages.SettingNotChanged, currentUser) - .WithDescription(e.Message) + .WithDescription(setResult.Error.Message) .WithColour(ColorsList.Red) .Build(); if (!failedEmbed.IsDefined(out var failedBuilt)) return Result.FromError(failedEmbed); @@ -139,9 +139,9 @@ public class SettingsCommandGroup : CommandGroup { var builder = new StringBuilder(); - builder.Append(Markdown.InlineCode(setting)) + builder.Append(Markdown.InlineCode(option.Name)) .Append($" {Messages.SettingIsNow} ") - .Append(Markdown.InlineCode(value)); + .Append(option.Display(cfg)); var embed = new EmbedBuilder().WithSmallTitle(Messages.SettingSuccessfullyChanged, currentUser) .WithDescription(builder.ToString()) diff --git a/src/Data/GuildConfiguration.cs b/src/Data/GuildConfiguration.cs deleted file mode 100644 index 440e2b7..0000000 --- a/src/Data/GuildConfiguration.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Globalization; -using Remora.Discord.API.Abstractions.Objects; - -namespace Boyfriend.Data; - -/// -/// Stores per-guild settings that can be set by a member -/// with using the /settings command -/// -public class GuildConfiguration { - /// - /// Represents a scheduled event notification receiver. - /// - /// - /// Used to selectively mention guild members when a scheduled event has started or is about to start. - /// - public enum NotificationReceiver { - Interested, - Role - } - - public static readonly Dictionary CultureInfoCache = new() { - { "en", new CultureInfo("en-US") }, - { "ru", new CultureInfo("ru-RU") }, - { "mctaylors-ru", new CultureInfo("tt-RU") } - }; - - public string Language { get; set; } = "en"; - - /// - /// Controls what message should be sent in when a new member joins the server. - /// - /// - /// - /// No message will be sent if set to "off", "disable" or "disabled". - /// will be sent if set to "default" or "reset" - /// - /// - /// - public string WelcomeMessage { get; set; } = "default"; - - /// - /// Controls whether or not the message should be sent - /// in on startup. - /// - /// - public bool ReceiveStartupMessages { get; set; } - - public bool RemoveRolesOnMute { get; set; } - - /// - /// Controls whether or not a guild member's roles are returned if he/she leaves and then joins back. - /// - /// Roles will not be returned if the member left the guild because of /ban or /kick. - public bool ReturnRolesOnRejoin { get; set; } - - public bool AutoStartEvents { get; set; } - - /// - /// Controls what channel should all public messages be sent to. - /// - public ulong PublicFeedbackChannel { get; set; } - - /// - /// Controls what channel should all private, moderator-only messages be sent to. - /// - public ulong PrivateFeedbackChannel { get; set; } - - public ulong EventNotificationChannel { get; set; } - public ulong DefaultRole { get; set; } - public ulong MuteRole { get; set; } - public ulong EventNotificationRole { get; set; } - - /// - /// Controls what guild members should be mentioned when a scheduled event has started or is about to start. - /// - /// - public List EventStartedReceivers { get; set; } - = new() { NotificationReceiver.Interested, NotificationReceiver.Role }; - - /// - /// Controls the amount of time before a scheduled event to send a reminder in . - /// - public TimeSpan EventEarlyNotificationOffset { get; set; } = TimeSpan.Zero; - - // Do not convert this to a property, else serialization will be attempted - public CultureInfo GetCulture() { - return CultureInfoCache[Language]; - } -} diff --git a/src/Data/GuildData.cs b/src/Data/GuildData.cs index 992adc0..7c81364 100644 --- a/src/Data/GuildData.cs +++ b/src/Data/GuildData.cs @@ -1,4 +1,4 @@ -using System.Globalization; +using System.Text.Json.Nodes; using Remora.Rest.Core; namespace Boyfriend.Data; @@ -8,29 +8,26 @@ namespace Boyfriend.Data; /// /// This information is stored on disk as a JSON file. public class GuildData { - public readonly GuildConfiguration Configuration; - public readonly string ConfigurationPath; - public readonly Dictionary MemberData; public readonly string MemberDataPath; public readonly Dictionary ScheduledEvents; public readonly string ScheduledEventsPath; + public readonly JsonNode Settings; + public readonly string SettingsPath; public GuildData( - GuildConfiguration configuration, string configurationPath, + JsonNode settings, string settingsPath, Dictionary scheduledEvents, string scheduledEventsPath, Dictionary memberData, string memberDataPath) { - Configuration = configuration; - ConfigurationPath = configurationPath; + Settings = settings; + SettingsPath = settingsPath; ScheduledEvents = scheduledEvents; ScheduledEventsPath = scheduledEventsPath; MemberData = memberData; MemberDataPath = memberDataPath; } - public CultureInfo Culture => Configuration.GetCulture(); - public MemberData GetMemberData(Snowflake userId) { if (MemberData.TryGetValue(userId.Value, out var existing)) return existing; diff --git a/src/Data/GuildSettings.cs b/src/Data/GuildSettings.cs new file mode 100644 index 0000000..07e43a6 --- /dev/null +++ b/src/Data/GuildSettings.cs @@ -0,0 +1,63 @@ +using Boyfriend.Data.Options; +using Boyfriend.Responders; +using Remora.Discord.API.Abstractions.Objects; + +namespace Boyfriend.Data; + +/// +/// Contains all per-guild settings that can be set by a member +/// with using the /settings command +/// +public static class GuildSettings { + public static readonly LanguageOption Language = new("Language", "en"); + + /// + /// Controls what message should be sent in when a new member joins the server. + /// + /// + /// + /// No message will be sent if set to "off", "disable" or "disabled". + /// will be sent if set to "default" or "reset" + /// + /// + /// + public static readonly Option WelcomeMessage = new("WelcomeMessage", "default"); + + /// + /// Controls whether or not the message should be sent + /// in on startup. + /// + /// + public static readonly BoolOption ReceiveStartupMessages = new("ReceiveStartupMessages", false); + + public static readonly BoolOption RemoveRolesOnMute = new("RemoveRolesOnMute", false); + + /// + /// Controls whether or not a guild member's roles are returned if he/she leaves and then joins back. + /// + /// Roles will not be returned if the member left the guild because of /ban or /kick. + public static readonly BoolOption ReturnRolesOnRejoin = new("ReturnRolesOnRejoin", false); + + public static readonly BoolOption AutoStartEvents = new("AutoStartEvents", false); + + /// + /// Controls what channel should all public messages be sent to. + /// + public static readonly SnowflakeOption PublicFeedbackChannel = new("PublicFeedbackChannel"); + + /// + /// Controls what channel should all private, moderator-only messages be sent to. + /// + public static readonly SnowflakeOption PrivateFeedbackChannel = new("PrivateFeedbackChannel"); + + public static readonly SnowflakeOption EventNotificationChannel = new("EventNotificationChannel"); + public static readonly SnowflakeOption DefaultRole = new("DefaultRole"); + public static readonly SnowflakeOption MuteRole = new("MuteRole"); + public static readonly SnowflakeOption EventNotificationRole = new("EventNotificationRole"); + + /// + /// Controls the amount of time before a scheduled event to send a reminder in . + /// + public static readonly TimeSpanOption EventEarlyNotificationOffset = new( + "EventEarlyNotificationOffset", TimeSpan.Zero); +} diff --git a/src/Data/MemberData.cs b/src/Data/MemberData.cs index 72cbdec..7d49ec7 100644 --- a/src/Data/MemberData.cs +++ b/src/Data/MemberData.cs @@ -1,5 +1,3 @@ -using Remora.Rest.Core; - namespace Boyfriend.Data; /// @@ -13,6 +11,6 @@ public class MemberData { public ulong Id { get; } public DateTimeOffset? BannedUntil { get; set; } - public List Roles { get; set; } = new(); + public List Roles { get; set; } = new(); public List Reminders { get; } = new(); } diff --git a/src/Data/Options/BoolOption.cs b/src/Data/Options/BoolOption.cs new file mode 100644 index 0000000..a8ee954 --- /dev/null +++ b/src/Data/Options/BoolOption.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Nodes; +using Remora.Results; + +namespace Boyfriend.Data.Options; + +public class BoolOption : Option { + public BoolOption(string name, bool defaultValue) : base(name, defaultValue) { } + + public override string Display(JsonNode settings) { + return Get(settings) ? Messages.Yes : Messages.No; + } + + public override Result Set(JsonNode settings, string from) { + if (!TryParseBool(from, out var value)) + return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); + + settings[Name] = value; + return Result.FromSuccess(); + } + + private static bool TryParseBool(string from, out bool value) { + value = false; + switch (from) { + case "1" or "y" or "yes" or "д" or "да": + value = true; + return true; + case "0" or "n" or "no" or "н" or "не" or "нет": + value = false; + return true; + default: + return false; + } + } +} diff --git a/src/Data/Options/IOption.cs b/src/Data/Options/IOption.cs new file mode 100644 index 0000000..fc0f747 --- /dev/null +++ b/src/Data/Options/IOption.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Nodes; +using Remora.Results; + +namespace Boyfriend.Data.Options; + +public interface IOption { + string Name { get; } + string Display(JsonNode settings); + Result Set(JsonNode settings, string from); +} diff --git a/src/Data/Options/LanguageOption.cs b/src/Data/Options/LanguageOption.cs new file mode 100644 index 0000000..6c4a49f --- /dev/null +++ b/src/Data/Options/LanguageOption.cs @@ -0,0 +1,35 @@ +using System.Globalization; +using System.Text.Json.Nodes; +using Remora.Discord.Extensions.Formatting; +using Remora.Results; + +namespace Boyfriend.Data.Options; + +/// +public class LanguageOption : Option { + private static readonly Dictionary CultureInfoCache = new() { + { "en", new CultureInfo("en-US") }, + { "ru", new CultureInfo("ru-RU") }, + { "mctaylors-ru", new CultureInfo("tt-RU") } + }; + + public LanguageOption(string name, string defaultValue) : base(name, CultureInfoCache[defaultValue]) { } + + public override string Display(JsonNode settings) { + return Markdown.InlineCode(settings[Name]?.GetValue() ?? "en"); + } + + /// + public override CultureInfo Get(JsonNode settings) { + var property = settings[Name]; + return property != null ? CultureInfoCache[property.GetValue()] : DefaultValue; + } + + /// + public override Result Set(JsonNode settings, string from) { + if (!CultureInfoCache.ContainsKey(from.ToLowerInvariant())) + return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.LanguageNotSupported)); + + return base.Set(settings, from.ToLowerInvariant()); + } +} diff --git a/src/Data/Options/Option.cs b/src/Data/Options/Option.cs new file mode 100644 index 0000000..742d3a9 --- /dev/null +++ b/src/Data/Options/Option.cs @@ -0,0 +1,46 @@ +using System.Text.Json.Nodes; +using Remora.Discord.Extensions.Formatting; +using Remora.Results; + +namespace Boyfriend.Data.Options; + +/// +/// Represents an per-guild option. +/// +/// The type of the option. +public class Option : IOption +where T : notnull { + internal readonly T DefaultValue; + + public Option(string name, T defaultValue) { + Name = name; + DefaultValue = defaultValue; + } + + public string Name { get; } + + public virtual string Display(JsonNode settings) { + return Markdown.InlineCode(Get(settings).ToString()!); + } + + /// + /// Sets the value of the option from a to the provided JsonNode. + /// + /// The to set the value to. + /// The string from which the new value of the option will be parsed. + /// A value setting result which may or may not have succeeded. + public virtual Result Set(JsonNode settings, string from) { + settings[Name] = from; + return Result.FromSuccess(); + } + + /// + /// Gets the value of the option from the provided . + /// + /// The to get the value from. + /// The value of the option. + public virtual T Get(JsonNode settings) { + var property = settings[Name]; + return property != null ? property.GetValue() : DefaultValue; + } +} diff --git a/src/Data/Options/SnowflakeOption.cs b/src/Data/Options/SnowflakeOption.cs new file mode 100644 index 0000000..f65065c --- /dev/null +++ b/src/Data/Options/SnowflakeOption.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Nodes; +using Remora.Discord.Extensions.Formatting; +using Remora.Rest.Core; +using Remora.Results; + +namespace Boyfriend.Data.Options; + +public class SnowflakeOption : Option { + public SnowflakeOption(string name) : base(name, 0UL.ToSnowflake()) { } + + public override string Display(JsonNode settings) { + return Name.EndsWith("Channel") ? Mention.Channel(Get(settings)) : Mention.Role(Get(settings)); + } + + public override Snowflake Get(JsonNode settings) { + var property = settings[Name]; + return property != null ? property.GetValue().ToSnowflake() : DefaultValue; + } + + public override Result Set(JsonNode settings, string from) { + if (!ulong.TryParse(from, out var parsed)) + return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); + + settings[Name] = parsed; + return Result.FromSuccess(); + } +} diff --git a/src/Data/Options/TimeSpanOption.cs b/src/Data/Options/TimeSpanOption.cs new file mode 100644 index 0000000..659d88c --- /dev/null +++ b/src/Data/Options/TimeSpanOption.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Nodes; +using Remora.Commands.Parsers; +using Remora.Results; + +namespace Boyfriend.Data.Options; + +public class TimeSpanOption : Option { + private static readonly TimeSpanParser Parser = new(); + + public TimeSpanOption(string name, TimeSpan defaultValue) : base(name, defaultValue) { } + + public override TimeSpan Get(JsonNode settings) { + var property = settings[Name]; + return property != null ? ParseTimeSpan(property.GetValue()).Entity : DefaultValue; + } + + public override Result Set(JsonNode settings, string from) { + if (!ParseTimeSpan(from).IsDefined(out var span)) + return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); + + settings[Name] = span.ToString(); + return Result.FromSuccess(); + } + + private static Result ParseTimeSpan(string from) { + return Parser.TryParseAsync(from).AsTask().GetAwaiter().GetResult(); + } +} diff --git a/src/Data/Reminder.cs b/src/Data/Reminder.cs index 1d0410c..2246b5e 100644 --- a/src/Data/Reminder.cs +++ b/src/Data/Reminder.cs @@ -1,9 +1,7 @@ -using Remora.Rest.Core; - namespace Boyfriend.Data; public struct Reminder { - public DateTimeOffset RemindAt; + public DateTimeOffset At; public string Text; - public Snowflake Channel; + public ulong Channel; } diff --git a/src/EventResponders.cs b/src/EventResponders.cs deleted file mode 100644 index 708bbc1..0000000 --- a/src/EventResponders.cs +++ /dev/null @@ -1,335 +0,0 @@ -using Boyfriend.Data; -using Boyfriend.Services; -using DiffPlex.DiffBuilder; -using Microsoft.Extensions.Logging; -using Remora.Discord.API.Abstractions.Gateway.Events; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Discord.API.Abstractions.Rest; -using Remora.Discord.Caching; -using Remora.Discord.Caching.Services; -using Remora.Discord.Extensions.Embeds; -using Remora.Discord.Extensions.Formatting; -using Remora.Discord.Gateway.Responders; -using Remora.Rest.Core; -using Remora.Results; - -// ReSharper disable UnusedType.Global - -namespace Boyfriend; - -/// -/// Handles sending a message to a guild that has just initialized if that guild -/// has enabled -/// -public class GuildCreateResponder : IResponder { - private readonly IDiscordRestChannelAPI _channelApi; - private readonly GuildDataService _dataService; - private readonly ILogger _logger; - private readonly IDiscordRestUserAPI _userApi; - - public GuildCreateResponder( - IDiscordRestChannelAPI channelApi, GuildDataService dataService, ILogger logger, - IDiscordRestUserAPI userApi) { - _channelApi = channelApi; - _dataService = dataService; - _logger = logger; - _userApi = userApi; - } - - public async Task RespondAsync(IGuildCreate gatewayEvent, CancellationToken ct = default) { - if (!gatewayEvent.Guild.IsT0) return Result.FromSuccess(); // Guild isn't IAvailableGuild - - var guild = gatewayEvent.Guild.AsT0; - _logger.LogInformation("Joined guild \"{Name}\"", guild.Name); - - var guildConfig = await _dataService.GetConfiguration(guild.ID, ct); - if (!guildConfig.ReceiveStartupMessages) - return Result.FromSuccess(); - if (guildConfig.PrivateFeedbackChannel is 0) - return Result.FromSuccess(); - - var currentUserResult = await _userApi.GetCurrentUserAsync(ct); - if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - - Messages.Culture = guildConfig.GetCulture(); - var i = Random.Shared.Next(1, 4); - - var embed = new EmbedBuilder().WithSmallTitle(currentUser.GetTag(), currentUser) - .WithTitle($"Beep{i}".Localized()) - .WithDescription(Messages.Ready) - .WithCurrentTimestamp() - .WithColour(ColorsList.Blue) - .Build(); - if (!embed.IsDefined(out var built)) return Result.FromError(embed); - - return (Result)await _channelApi.CreateMessageAsync( - guildConfig.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built }, ct: ct); - } -} - -/// -/// Handles logging the contents of a deleted message and the user who deleted the message -/// to a guild's if one is set. -/// -public class MessageDeletedResponder : IResponder { - private readonly IDiscordRestAuditLogAPI _auditLogApi; - private readonly IDiscordRestChannelAPI _channelApi; - private readonly GuildDataService _dataService; - private readonly IDiscordRestUserAPI _userApi; - - public MessageDeletedResponder( - IDiscordRestAuditLogAPI auditLogApi, IDiscordRestChannelAPI channelApi, - GuildDataService dataService, IDiscordRestUserAPI userApi) { - _auditLogApi = auditLogApi; - _channelApi = channelApi; - _dataService = dataService; - _userApi = userApi; - } - - public async Task RespondAsync(IMessageDelete gatewayEvent, CancellationToken ct = default) { - if (!gatewayEvent.GuildID.IsDefined(out var guildId)) return Result.FromSuccess(); - - var guildConfiguration = await _dataService.GetConfiguration(guildId, ct); - if (guildConfiguration.PrivateFeedbackChannel is 0) return Result.FromSuccess(); - - var messageResult = await _channelApi.GetChannelMessageAsync(gatewayEvent.ChannelID, gatewayEvent.ID, ct); - if (!messageResult.IsDefined(out var message)) return Result.FromError(messageResult); - if (string.IsNullOrWhiteSpace(message.Content)) return Result.FromSuccess(); - - var auditLogResult = await _auditLogApi.GetGuildAuditLogAsync( - guildId, actionType: AuditLogEvent.MessageDelete, limit: 1, ct: ct); - if (!auditLogResult.IsDefined(out var auditLogPage)) return Result.FromError(auditLogResult); - - var auditLog = auditLogPage.AuditLogEntries.Single(); - if (!auditLog.Options.IsDefined(out var options)) - return Result.FromError(new ArgumentNullError(nameof(auditLog.Options))); - - var user = message.Author; - if (options.ChannelID == gatewayEvent.ChannelID - && DateTimeOffset.UtcNow.Subtract(auditLog.ID.Timestamp).TotalSeconds <= 2) { - var userResult = await _userApi.GetUserAsync(auditLog.UserID!.Value, ct); - if (!userResult.IsDefined(out user)) return Result.FromError(userResult); - } - - Messages.Culture = guildConfiguration.GetCulture(); - - var embed = new EmbedBuilder() - .WithSmallTitle( - string.Format( - Messages.CachedMessageDeleted, - message.Author.GetTag()), message.Author) - .WithDescription( - $"{Mention.Channel(gatewayEvent.ChannelID)}\n{message.Content.InBlockCode()}") - .WithActionFooter(user) - .WithTimestamp(message.Timestamp) - .WithColour(ColorsList.Red) - .Build(); - if (!embed.IsDefined(out var built)) return Result.FromError(embed); - - return (Result)await _channelApi.CreateMessageAsync( - guildConfiguration.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built }, - allowedMentions: Boyfriend.NoMentions, ct: ct); - } -} - -/// -/// Handles logging the difference between an edited message's old and new content -/// to a guild's if one is set. -/// -public class MessageEditedResponder : IResponder { - private readonly CacheService _cacheService; - private readonly IDiscordRestChannelAPI _channelApi; - private readonly GuildDataService _dataService; - private readonly IDiscordRestUserAPI _userApi; - - public MessageEditedResponder( - CacheService cacheService, IDiscordRestChannelAPI channelApi, GuildDataService dataService, - IDiscordRestUserAPI userApi) { - _cacheService = cacheService; - _channelApi = channelApi; - _dataService = dataService; - _userApi = userApi; - } - - public async Task RespondAsync(IMessageUpdate gatewayEvent, CancellationToken ct = default) { - if (!gatewayEvent.GuildID.IsDefined(out var guildId)) - return Result.FromSuccess(); - var guildConfiguration = await _dataService.GetConfiguration(guildId, ct); - if (guildConfiguration.PrivateFeedbackChannel is 0) - return Result.FromSuccess(); - if (!gatewayEvent.Content.IsDefined(out var newContent)) - return Result.FromSuccess(); - if (!gatewayEvent.EditedTimestamp.IsDefined(out var timestamp)) - return Result.FromSuccess(); // The message wasn't actually edited - - if (!gatewayEvent.ChannelID.IsDefined(out var channelId)) - return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.ChannelID))); - if (!gatewayEvent.ID.IsDefined(out var messageId)) - return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.ID))); - - var cacheKey = new KeyHelpers.MessageCacheKey(channelId, messageId); - var messageResult = await _cacheService.TryGetValueAsync( - cacheKey, ct); - if (!messageResult.IsDefined(out var message)) return Result.FromError(messageResult); - if (message.Content == newContent) return Result.FromSuccess(); - - // Custom event responders are called earlier than responders responsible for message caching - // This means that subsequent edit logs may contain the wrong content - // We can work around this by evicting the message from the cache - await _cacheService.EvictAsync(cacheKey, ct); - // However, since we evicted the message, subsequent edits won't have a cached instance to work with - // Getting the message will put it back in the cache, resolving all issues - // We don't need to await this since the result is not needed - // NOTE: Because this is not awaited, there may be a race condition depending on how fast clients are able to edit their messages - // NOTE: Awaiting this might not even solve this if the same responder is called asynchronously - _ = _channelApi.GetChannelMessageAsync(channelId, messageId, ct); - - var currentUserResult = await _userApi.GetCurrentUserAsync(ct); - if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); - - var diff = InlineDiffBuilder.Diff(message.Content, newContent); - - Messages.Culture = guildConfiguration.GetCulture(); - - var embed = new EmbedBuilder() - .WithSmallTitle(string.Format(Messages.CachedMessageEdited, message.Author.GetTag()), message.Author) - .WithDescription($"https://discord.com/channels/{guildId}/{channelId}/{messageId}\n{diff.AsMarkdown()}") - .WithUserFooter(currentUser) - .WithTimestamp(timestamp.Value) - .WithColour(ColorsList.Yellow) - .Build(); - if (!embed.IsDefined(out var built)) return Result.FromError(embed); - - return (Result)await _channelApi.CreateMessageAsync( - guildConfiguration.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built }, - allowedMentions: Boyfriend.NoMentions, ct: ct); - } -} - -/// -/// Handles sending a guild's if one is set. -/// If is enabled, roles will be returned. -/// -/// -public class GuildMemberAddResponder : IResponder { - private readonly IDiscordRestChannelAPI _channelApi; - private readonly GuildDataService _dataService; - private readonly IDiscordRestGuildAPI _guildApi; - - public GuildMemberAddResponder( - IDiscordRestChannelAPI channelApi, GuildDataService dataService, IDiscordRestGuildAPI guildApi) { - _channelApi = channelApi; - _dataService = dataService; - _guildApi = guildApi; - } - - public async Task RespondAsync(IGuildMemberAdd gatewayEvent, CancellationToken ct = default) { - if (!gatewayEvent.User.IsDefined(out var user)) - return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.User))); - var data = await _dataService.GetData(gatewayEvent.GuildID, ct); - var cfg = data.Configuration; - if (cfg.PublicFeedbackChannel is 0 || cfg.WelcomeMessage is "off" or "disable" or "disabled") - return Result.FromSuccess(); - if (cfg.ReturnRolesOnRejoin) { - var result = await _guildApi.ModifyGuildMemberAsync( - gatewayEvent.GuildID, user.ID, roles: data.GetMemberData(user.ID).Roles, ct: ct); - if (!result.IsSuccess) return Result.FromError(result.Error); - } - - Messages.Culture = data.Culture; - var welcomeMessage = cfg.WelcomeMessage is "default" or "reset" - ? Messages.DefaultWelcomeMessage - : cfg.WelcomeMessage; - - var guildResult = await _guildApi.GetGuildAsync(gatewayEvent.GuildID, ct: ct); - if (!guildResult.IsDefined(out var guild)) return Result.FromError(guildResult); - - var embed = new EmbedBuilder() - .WithSmallTitle(string.Format(welcomeMessage, user.GetTag(), guild.Name), user) - .WithGuildFooter(guild) - .WithTimestamp(gatewayEvent.JoinedAt) - .WithColour(ColorsList.Green) - .Build(); - if (!embed.IsDefined(out var built)) return Result.FromError(embed); - - return (Result)await _channelApi.CreateMessageAsync( - cfg.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built }, - allowedMentions: Boyfriend.NoMentions, ct: ct); - } -} - -/// -/// Handles sending a notification when a scheduled event has been cancelled -/// in a guild's if one is set. -/// -public class GuildScheduledEventDeleteResponder : IResponder { - private readonly IDiscordRestChannelAPI _channelApi; - private readonly GuildDataService _dataService; - - public GuildScheduledEventDeleteResponder(IDiscordRestChannelAPI channelApi, GuildDataService dataService) { - _channelApi = channelApi; - _dataService = dataService; - } - - public async Task RespondAsync(IGuildScheduledEventDelete gatewayEvent, CancellationToken ct = default) { - var guildData = await _dataService.GetData(gatewayEvent.GuildID, ct); - guildData.ScheduledEvents.Remove(gatewayEvent.ID.Value); - - if (guildData.Configuration.EventNotificationChannel is 0) - return Result.FromSuccess(); - - var embed = new EmbedBuilder() - .WithSmallTitle(string.Format(Messages.EventCancelled, gatewayEvent.Name)) - .WithDescription(":(") - .WithColour(ColorsList.Red) - .WithCurrentTimestamp() - .Build(); - - if (!embed.IsDefined(out var built)) return Result.FromError(embed); - - return (Result)await _channelApi.CreateMessageAsync( - guildData.Configuration.EventNotificationChannel.ToDiscordSnowflake(), embeds: new[] { built }, ct: ct); - } -} - -/// -/// Handles updating when a guild member is updated. -/// -public class GuildMemberUpdateResponder : IResponder { - private readonly GuildDataService _dataService; - - public GuildMemberUpdateResponder(GuildDataService dataService) { - _dataService = dataService; - } - - public async Task RespondAsync(IGuildMemberUpdate gatewayEvent, CancellationToken ct = default) { - var memberData = await _dataService.GetMemberData(gatewayEvent.GuildID, gatewayEvent.User.ID, ct); - memberData.Roles = gatewayEvent.Roles.ToList(); - return Result.FromSuccess(); - } -} - -/// -/// Handles sending replies to easter egg messages. -/// -public class MessageCreateResponder : IResponder { - private readonly IDiscordRestChannelAPI _channelApi; - - public MessageCreateResponder(IDiscordRestChannelAPI channelApi) { - _channelApi = channelApi; - } - - public Task RespondAsync(IMessageCreate gatewayEvent, CancellationToken ct = default) { - _ = _channelApi.CreateMessageAsync( - gatewayEvent.ChannelID, ct: ct, content: gatewayEvent.Content switch { - "whoami" => "`nobody`", - "сука !!" => "`root`", - "воооо" => "`removing /...`", - "пон" => - "https://cdn.discordapp.com/attachments/837385840946053181/1087236080950055023/vUORS10xPaY-1.jpg", - "++++" => "#", - _ => default(Optional) - }); - return Task.FromResult(Result.FromSuccess()); - } -} diff --git a/src/Extensions.cs b/src/Extensions.cs index 95500ac..18a3c06 100644 --- a/src/Extensions.cs +++ b/src/Extensions.cs @@ -170,7 +170,7 @@ public static class Extensions { return user.Discriminator is 0000 ? $"@{user.Username}" : $"{user.Username}#{user.Discriminator:0000}"; } - public static Snowflake ToDiscordSnowflake(this ulong id) { + public static Snowflake ToSnowflake(this ulong id) { return DiscordSnowflake.New(id); } @@ -190,4 +190,8 @@ public static class Extensions { && context.TryGetChannelID(out channelId) && context.TryGetUserID(out userId); } + + public static bool Empty(this Snowflake snowflake) { + return snowflake.Value is 0; + } } diff --git a/src/InteractionResponders.cs b/src/InteractionResponders.cs index 231df31..6f40d2a 100644 --- a/src/InteractionResponders.cs +++ b/src/InteractionResponders.cs @@ -1,17 +1,16 @@ +using JetBrains.Annotations; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.Commands.Feedback.Messages; using Remora.Discord.Commands.Feedback.Services; using Remora.Discord.Interactivity; using Remora.Results; -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedMember.Global - namespace Boyfriend; /// /// Handles responding to various interactions. /// +[UsedImplicitly] public class InteractionResponders : InteractionGroup { private readonly FeedbackService _feedbackService; @@ -25,6 +24,7 @@ public class InteractionResponders : InteractionGroup { /// The ID of the guild and scheduled event, encoded as "guildId:eventId". /// An ephemeral feedback sending result which may or may not have succeeded. [Button("scheduled-event-details")] + [UsedImplicitly] public async Task OnStatefulButtonClicked(string? state = null) { if (state is null) return Result.FromError(new ArgumentNullError(nameof(state))); diff --git a/locale/Messages.Designer.cs b/src/Messages.Designer.cs similarity index 99% rename from locale/Messages.Designer.cs rename to src/Messages.Designer.cs index de6955b..42a05be 100644 --- a/locale/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -8,9 +8,6 @@ //------------------------------------------------------------------------------ namespace Boyfriend { - using System; - - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/src/Responders/GuildLoadedResponder.cs b/src/Responders/GuildLoadedResponder.cs new file mode 100644 index 0000000..081f526 --- /dev/null +++ b/src/Responders/GuildLoadedResponder.cs @@ -0,0 +1,63 @@ +using Boyfriend.Data; +using Boyfriend.Services; +using JetBrains.Annotations; +using Microsoft.Extensions.Logging; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.API.Gateway.Events; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Gateway.Responders; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles sending a message to a guild that has just initialized if that guild +/// has enabled +/// +[UsedImplicitly] +public class GuildLoadedResponder : IResponder { + private readonly IDiscordRestChannelAPI _channelApi; + private readonly GuildDataService _dataService; + private readonly ILogger _logger; + private readonly IDiscordRestUserAPI _userApi; + + public GuildLoadedResponder( + IDiscordRestChannelAPI channelApi, GuildDataService dataService, ILogger logger, + IDiscordRestUserAPI userApi) { + _channelApi = channelApi; + _dataService = dataService; + _logger = logger; + _userApi = userApi; + } + + public async Task RespondAsync(IGuildCreate gatewayEvent, CancellationToken ct = default) { + if (!gatewayEvent.Guild.IsT0) return Result.FromSuccess(); // Guild is not IAvailableGuild + + var guild = gatewayEvent.Guild.AsT0; + _logger.LogInformation("Joined guild \"{Name}\"", guild.Name); + + var cfg = await _dataService.GetSettings(guild.ID, ct); + if (!GuildSettings.ReceiveStartupMessages.Get(cfg)) + return Result.FromSuccess(); + if (GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty()) + return Result.FromSuccess(); + + var currentUserResult = await _userApi.GetCurrentUserAsync(ct); + if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); + + Messages.Culture = GuildSettings.Language.Get(cfg); + var i = Random.Shared.Next(1, 4); + + var embed = new EmbedBuilder().WithSmallTitle(currentUser.GetTag(), currentUser) + .WithTitle($"Beep{i}".Localized()) + .WithDescription(Messages.Ready) + .WithCurrentTimestamp() + .WithColour(ColorsList.Blue) + .Build(); + if (!embed.IsDefined(out var built)) return Result.FromError(embed); + + return (Result)await _channelApi.CreateMessageAsync( + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, ct: ct); + } +} diff --git a/src/Responders/GuildMemberJoinedResponder.cs b/src/Responders/GuildMemberJoinedResponder.cs new file mode 100644 index 0000000..c61e500 --- /dev/null +++ b/src/Responders/GuildMemberJoinedResponder.cs @@ -0,0 +1,65 @@ +using Boyfriend.Data; +using Boyfriend.Services; +using JetBrains.Annotations; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Gateway.Responders; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles sending a guild's if one is set. +/// If is enabled, roles will be returned. +/// +/// +[UsedImplicitly] +public class GuildMemberJoinedResponder : IResponder { + private readonly IDiscordRestChannelAPI _channelApi; + private readonly GuildDataService _dataService; + private readonly IDiscordRestGuildAPI _guildApi; + + public GuildMemberJoinedResponder( + IDiscordRestChannelAPI channelApi, GuildDataService dataService, IDiscordRestGuildAPI guildApi) { + _channelApi = channelApi; + _dataService = dataService; + _guildApi = guildApi; + } + + public async Task RespondAsync(IGuildMemberAdd gatewayEvent, CancellationToken ct = default) { + if (!gatewayEvent.User.IsDefined(out var user)) + return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.User))); + var data = await _dataService.GetData(gatewayEvent.GuildID, ct); + var cfg = data.Settings; + if (GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() + || GuildSettings.WelcomeMessage.Get(cfg) is "off" or "disable" or "disabled") + return Result.FromSuccess(); + if (GuildSettings.ReturnRolesOnRejoin.Get(cfg)) { + var result = await _guildApi.ModifyGuildMemberAsync( + gatewayEvent.GuildID, user.ID, + roles: data.GetMemberData(user.ID).Roles.ConvertAll(r => r.ToSnowflake()), ct: ct); + if (!result.IsSuccess) return Result.FromError(result.Error); + } + + Messages.Culture = GuildSettings.Language.Get(cfg); + var welcomeMessage = GuildSettings.WelcomeMessage.Get(cfg) is "default" or "reset" + ? Messages.DefaultWelcomeMessage + : GuildSettings.WelcomeMessage.Get(cfg); + + var guildResult = await _guildApi.GetGuildAsync(gatewayEvent.GuildID, ct: ct); + if (!guildResult.IsDefined(out var guild)) return Result.FromError(guildResult); + + var embed = new EmbedBuilder() + .WithSmallTitle(string.Format(welcomeMessage, user.GetTag(), guild.Name), user) + .WithGuildFooter(guild) + .WithTimestamp(gatewayEvent.JoinedAt) + .WithColour(ColorsList.Green) + .Build(); + if (!embed.IsDefined(out var built)) return Result.FromError(embed); + + return (Result)await _channelApi.CreateMessageAsync( + GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: new[] { built }, + allowedMentions: Boyfriend.NoMentions, ct: ct); + } +} diff --git a/src/Responders/GuildMemberRolesUpdatedResponder.cs b/src/Responders/GuildMemberRolesUpdatedResponder.cs new file mode 100644 index 0000000..b61ce32 --- /dev/null +++ b/src/Responders/GuildMemberRolesUpdatedResponder.cs @@ -0,0 +1,26 @@ +using Boyfriend.Data; +using Boyfriend.Services; +using JetBrains.Annotations; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.Gateway.Responders; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles updating when a guild member is updated. +/// +[UsedImplicitly] +public class GuildMemberUpdateResponder : IResponder { + private readonly GuildDataService _dataService; + + public GuildMemberUpdateResponder(GuildDataService dataService) { + _dataService = dataService; + } + + public async Task RespondAsync(IGuildMemberUpdate gatewayEvent, CancellationToken ct = default) { + var memberData = await _dataService.GetMemberData(gatewayEvent.GuildID, gatewayEvent.User.ID, ct); + memberData.Roles = gatewayEvent.Roles.ToList().ConvertAll(r => r.Value); + return Result.FromSuccess(); + } +} diff --git a/src/Responders/MessageDeletedResponder.cs b/src/Responders/MessageDeletedResponder.cs new file mode 100644 index 0000000..903db84 --- /dev/null +++ b/src/Responders/MessageDeletedResponder.cs @@ -0,0 +1,78 @@ +using Boyfriend.Data; +using Boyfriend.Services; +using JetBrains.Annotations; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Extensions.Formatting; +using Remora.Discord.Gateway.Responders; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles logging the contents of a deleted message and the user who deleted the message +/// to a guild's if one is set. +/// +[UsedImplicitly] +public class MessageDeletedResponder : IResponder { + private readonly IDiscordRestAuditLogAPI _auditLogApi; + private readonly IDiscordRestChannelAPI _channelApi; + private readonly GuildDataService _dataService; + private readonly IDiscordRestUserAPI _userApi; + + public MessageDeletedResponder( + IDiscordRestAuditLogAPI auditLogApi, IDiscordRestChannelAPI channelApi, + GuildDataService dataService, IDiscordRestUserAPI userApi) { + _auditLogApi = auditLogApi; + _channelApi = channelApi; + _dataService = dataService; + _userApi = userApi; + } + + public async Task RespondAsync(IMessageDelete gatewayEvent, CancellationToken ct = default) { + if (!gatewayEvent.GuildID.IsDefined(out var guildId)) return Result.FromSuccess(); + + var cfg = await _dataService.GetSettings(guildId, ct); + if (GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty()) return Result.FromSuccess(); + + var messageResult = await _channelApi.GetChannelMessageAsync(gatewayEvent.ChannelID, gatewayEvent.ID, ct); + if (!messageResult.IsDefined(out var message)) return Result.FromError(messageResult); + if (string.IsNullOrWhiteSpace(message.Content)) return Result.FromSuccess(); + + var auditLogResult = await _auditLogApi.GetGuildAuditLogAsync( + guildId, actionType: AuditLogEvent.MessageDelete, limit: 1, ct: ct); + if (!auditLogResult.IsDefined(out var auditLogPage)) return Result.FromError(auditLogResult); + + var auditLog = auditLogPage.AuditLogEntries.Single(); + if (!auditLog.Options.IsDefined(out var options)) + return Result.FromError(new ArgumentNullError(nameof(auditLog.Options))); + + var user = message.Author; + if (options.ChannelID == gatewayEvent.ChannelID + && DateTimeOffset.UtcNow.Subtract(auditLog.ID.Timestamp).TotalSeconds <= 2) { + var userResult = await _userApi.GetUserAsync(auditLog.UserID!.Value, ct); + if (!userResult.IsDefined(out user)) return Result.FromError(userResult); + } + + Messages.Culture = GuildSettings.Language.Get(cfg); + + var embed = new EmbedBuilder() + .WithSmallTitle( + string.Format( + Messages.CachedMessageDeleted, + message.Author.GetTag()), message.Author) + .WithDescription( + $"{Mention.Channel(gatewayEvent.ChannelID)}\n{message.Content.InBlockCode()}") + .WithActionFooter(user) + .WithTimestamp(message.Timestamp) + .WithColour(ColorsList.Red) + .Build(); + if (!embed.IsDefined(out var built)) return Result.FromError(embed); + + return (Result)await _channelApi.CreateMessageAsync( + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, + allowedMentions: Boyfriend.NoMentions, ct: ct); + } +} diff --git a/src/Responders/MessageEditedResponder.cs b/src/Responders/MessageEditedResponder.cs new file mode 100644 index 0000000..0211170 --- /dev/null +++ b/src/Responders/MessageEditedResponder.cs @@ -0,0 +1,89 @@ +using Boyfriend.Data; +using Boyfriend.Services; +using DiffPlex.DiffBuilder; +using JetBrains.Annotations; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Caching; +using Remora.Discord.Caching.Services; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Gateway.Responders; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles logging the difference between an edited message's old and new content +/// to a guild's if one is set. +/// +[UsedImplicitly] +public class MessageEditedResponder : IResponder { + private readonly CacheService _cacheService; + private readonly IDiscordRestChannelAPI _channelApi; + private readonly GuildDataService _dataService; + private readonly IDiscordRestUserAPI _userApi; + + public MessageEditedResponder( + CacheService cacheService, IDiscordRestChannelAPI channelApi, GuildDataService dataService, + IDiscordRestUserAPI userApi) { + _cacheService = cacheService; + _channelApi = channelApi; + _dataService = dataService; + _userApi = userApi; + } + + public async Task RespondAsync(IMessageUpdate gatewayEvent, CancellationToken ct = default) { + if (!gatewayEvent.GuildID.IsDefined(out var guildId)) + return Result.FromSuccess(); + var cfg = await _dataService.GetSettings(guildId, ct); + if (GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty()) + return Result.FromSuccess(); + if (!gatewayEvent.Content.IsDefined(out var newContent)) + return Result.FromSuccess(); + if (!gatewayEvent.EditedTimestamp.IsDefined(out var timestamp)) + return Result.FromSuccess(); // The message wasn't actually edited + + if (!gatewayEvent.ChannelID.IsDefined(out var channelId)) + return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.ChannelID))); + if (!gatewayEvent.ID.IsDefined(out var messageId)) + return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.ID))); + + var cacheKey = new KeyHelpers.MessageCacheKey(channelId, messageId); + var messageResult = await _cacheService.TryGetValueAsync( + cacheKey, ct); + if (!messageResult.IsDefined(out var message)) return Result.FromError(messageResult); + if (message.Content == newContent) return Result.FromSuccess(); + + // Custom event responders are called earlier than responders responsible for message caching + // This means that subsequent edit logs may contain the wrong content + // We can work around this by evicting the message from the cache + await _cacheService.EvictAsync(cacheKey, ct); + // However, since we evicted the message, subsequent edits won't have a cached instance to work with + // Getting the message will put it back in the cache, resolving all issues + // We don't need to await this since the result is not needed + // NOTE: Because this is not awaited, there may be a race condition depending on how fast clients are able to edit their messages + // NOTE: Awaiting this might not even solve this if the same responder is called asynchronously + _ = _channelApi.GetChannelMessageAsync(channelId, messageId, ct); + + var currentUserResult = await _userApi.GetCurrentUserAsync(ct); + if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); + + var diff = InlineDiffBuilder.Diff(message.Content, newContent); + + Messages.Culture = GuildSettings.Language.Get(cfg); + + var embed = new EmbedBuilder() + .WithSmallTitle(string.Format(Messages.CachedMessageEdited, message.Author.GetTag()), message.Author) + .WithDescription($"https://discord.com/channels/{guildId}/{channelId}/{messageId}\n{diff.AsMarkdown()}") + .WithUserFooter(currentUser) + .WithTimestamp(timestamp.Value) + .WithColour(ColorsList.Yellow) + .Build(); + if (!embed.IsDefined(out var built)) return Result.FromError(embed); + + return (Result)await _channelApi.CreateMessageAsync( + GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, + allowedMentions: Boyfriend.NoMentions, ct: ct); + } +} diff --git a/src/Responders/MessageReceivedResponder.cs b/src/Responders/MessageReceivedResponder.cs new file mode 100644 index 0000000..a45a2f4 --- /dev/null +++ b/src/Responders/MessageReceivedResponder.cs @@ -0,0 +1,34 @@ +using JetBrains.Annotations; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Gateway.Responders; +using Remora.Rest.Core; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles sending replies to easter egg messages. +/// +[UsedImplicitly] +public class MessageCreateResponder : IResponder { + private readonly IDiscordRestChannelAPI _channelApi; + + public MessageCreateResponder(IDiscordRestChannelAPI channelApi) { + _channelApi = channelApi; + } + + public Task RespondAsync(IMessageCreate gatewayEvent, CancellationToken ct = default) { + _ = _channelApi.CreateMessageAsync( + gatewayEvent.ChannelID, ct: ct, content: gatewayEvent.Content.ToLowerInvariant() switch { + "whoami" => "`nobody`", + "сука !!" => "`root`", + "воооо" => "`removing /...`", + "пон" => "https://cdn.upload.systems/uploads/2LNfUSwM.jpg", + "++++" => "#", + "осу" => "https://github.com/ppy/osu", + _ => default(Optional) + }); + return Task.FromResult(Result.FromSuccess()); + } +} diff --git a/src/Responders/ScheduledEventCancelledResponder.cs b/src/Responders/ScheduledEventCancelledResponder.cs new file mode 100644 index 0000000..86453ef --- /dev/null +++ b/src/Responders/ScheduledEventCancelledResponder.cs @@ -0,0 +1,45 @@ +using Boyfriend.Data; +using Boyfriend.Services; +using JetBrains.Annotations; +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Gateway.Responders; +using Remora.Results; + +namespace Boyfriend.Responders; + +/// +/// Handles sending a notification when a scheduled event has been cancelled +/// in a guild's if one is set. +/// +[UsedImplicitly] +public class GuildScheduledEventDeleteResponder : IResponder { + private readonly IDiscordRestChannelAPI _channelApi; + private readonly GuildDataService _dataService; + + public GuildScheduledEventDeleteResponder(IDiscordRestChannelAPI channelApi, GuildDataService dataService) { + _channelApi = channelApi; + _dataService = dataService; + } + + public async Task RespondAsync(IGuildScheduledEventDelete gatewayEvent, CancellationToken ct = default) { + var guildData = await _dataService.GetData(gatewayEvent.GuildID, ct); + guildData.ScheduledEvents.Remove(gatewayEvent.ID.Value); + + if (GuildSettings.EventNotificationChannel.Get(guildData.Settings).Empty()) + return Result.FromSuccess(); + + var embed = new EmbedBuilder() + .WithSmallTitle(string.Format(Messages.EventCancelled, gatewayEvent.Name)) + .WithDescription(":(") + .WithColour(ColorsList.Red) + .WithCurrentTimestamp() + .Build(); + + if (!embed.IsDefined(out var built)) return Result.FromError(embed); + + return (Result)await _channelApi.CreateMessageAsync( + GuildSettings.EventNotificationChannel.Get(guildData.Settings), embeds: new[] { built }, ct: ct); + } +} diff --git a/src/Services/GuildDataService.cs b/src/Services/GuildDataService.cs index be873f1..990e731 100644 --- a/src/Services/GuildDataService.cs +++ b/src/Services/GuildDataService.cs @@ -1,5 +1,6 @@ using System.Collections.Concurrent; using System.Text.Json; +using System.Text.Json.Nodes; using Boyfriend.Data; using Microsoft.Extensions.Hosting; using Remora.Discord.API.Abstractions.Rest; @@ -36,8 +37,8 @@ public class GuildDataService : IHostedService { private async Task SaveAsync(CancellationToken ct) { var tasks = new List(); foreach (var data in _datas.Values) { - await using var configStream = File.OpenWrite(data.ConfigurationPath); - tasks.Add(JsonSerializer.SerializeAsync(configStream, data.Configuration, cancellationToken: ct)); + await using var settingsStream = File.OpenWrite(data.SettingsPath); + tasks.Add(JsonSerializer.SerializeAsync(settingsStream, data.Settings, cancellationToken: ct)); await using var eventsStream = File.OpenWrite(data.ScheduledEventsPath); tasks.Add(JsonSerializer.SerializeAsync(eventsStream, data.ScheduledEvents, cancellationToken: ct)); @@ -58,17 +59,16 @@ public class GuildDataService : IHostedService { private async Task InitializeData(Snowflake guildId, CancellationToken ct = default) { var idString = $"{guildId}"; var memberDataPath = $"{guildId}/MemberData"; - var configurationPath = $"{guildId}/Configuration.json"; + var settingsPath = $"{guildId}/Settings.json"; var scheduledEventsPath = $"{guildId}/ScheduledEvents.json"; if (!Directory.Exists(idString)) Directory.CreateDirectory(idString); if (!Directory.Exists(memberDataPath)) Directory.CreateDirectory(memberDataPath); - if (!File.Exists(configurationPath)) await File.WriteAllTextAsync(configurationPath, "{}", ct); + if (!File.Exists(settingsPath)) await File.WriteAllTextAsync(settingsPath, "{}", ct); if (!File.Exists(scheduledEventsPath)) await File.WriteAllTextAsync(scheduledEventsPath, "{}", ct); - await using var configurationStream = File.OpenRead(configurationPath); - var configuration - = JsonSerializer.DeserializeAsync( - configurationStream, cancellationToken: ct); + await using var settingsStream = File.OpenRead(settingsPath); + var jsonSettings + = JsonNode.Parse(settingsStream); await using var eventsStream = File.OpenRead(scheduledEventsPath); var events @@ -80,23 +80,23 @@ public class GuildDataService : IHostedService { await using var dataStream = File.OpenRead(dataPath); var data = await JsonSerializer.DeserializeAsync(dataStream, cancellationToken: ct); if (data is null) continue; - var memberResult = await _guildApi.GetGuildMemberAsync(guildId, data.Id.ToDiscordSnowflake(), ct); + var memberResult = await _guildApi.GetGuildMemberAsync(guildId, data.Id.ToSnowflake(), ct); if (memberResult.IsSuccess) - data.Roles = memberResult.Entity.Roles.ToList(); + data.Roles = memberResult.Entity.Roles.ToList().ConvertAll(r => r.Value); memberData.Add(data.Id, data); } var finalData = new GuildData( - await configuration ?? new GuildConfiguration(), configurationPath, + jsonSettings ?? new JsonObject(), settingsPath, await events ?? new Dictionary(), scheduledEventsPath, memberData, memberDataPath); while (!_datas.ContainsKey(guildId)) _datas.TryAdd(guildId, finalData); return finalData; } - public async Task GetConfiguration(Snowflake guildId, CancellationToken ct = default) { - return (await GetData(guildId, ct)).Configuration; + public async Task GetSettings(Snowflake guildId, CancellationToken ct = default) { + return (await GetData(guildId, ct)).Settings; } public async Task GetMemberData(Snowflake guildId, Snowflake userId, CancellationToken ct = default) { diff --git a/src/Services/GuildUpdateService.cs b/src/Services/GuildUpdateService.cs index 3d55f07..b119d90 100644 --- a/src/Services/GuildUpdateService.cs +++ b/src/Services/GuildUpdateService.cs @@ -1,3 +1,4 @@ +using System.Text.Json.Nodes; using Boyfriend.Data; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -94,9 +95,9 @@ public class GuildUpdateService : BackgroundService { /// This method does the following: /// /// Automatically unbans users once their ban period has expired. - /// Automatically grants members the guild's if one is set. + /// Automatically grants members the guild's if one is set. /// Sends reminders about an upcoming scheduled event. - /// Automatically starts scheduled events if is enabled. + /// Automatically starts scheduled events if is enabled. /// Sends scheduled event start notifications. /// Sends scheduled event completion notifications. /// Sends reminders to members. @@ -114,15 +115,15 @@ public class GuildUpdateService : BackgroundService { /// The cancellation token for this operation. private async Task TickGuildAsync(Snowflake guildId, CancellationToken ct = default) { var data = await _dataService.GetData(guildId, ct); - Messages.Culture = data.Culture; - var defaultRoleSnowflake = data.Configuration.DefaultRole.ToDiscordSnowflake(); + Messages.Culture = GuildSettings.Language.Get(data.Settings); + var defaultRole = GuildSettings.DefaultRole.Get(data.Settings); foreach (var memberData in data.MemberData.Values) { - var userId = memberData.Id.ToDiscordSnowflake(); + var userId = memberData.Id.ToSnowflake(); - if (defaultRoleSnowflake.Value is not 0 && !memberData.Roles.Contains(defaultRoleSnowflake)) + if (defaultRole.Value is not 0 && !memberData.Roles.Contains(defaultRole.Value)) _ = _guildApi.AddGuildMemberRoleAsync( - guildId, userId, defaultRoleSnowflake, ct: ct); + guildId, userId, defaultRole, ct: ct); if (DateTimeOffset.UtcNow > memberData.BannedUntil) { var unbanResult = await _guildApi.RemoveGuildBanAsync( @@ -139,7 +140,7 @@ public class GuildUpdateService : BackgroundService { for (var i = memberData.Reminders.Count - 1; i >= 0; i--) { var reminder = memberData.Reminders[i]; - if (DateTimeOffset.UtcNow < reminder.RemindAt) continue; + if (DateTimeOffset.UtcNow < reminder.At) continue; var embed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.Reminder, user.GetTag()), user) @@ -151,7 +152,7 @@ public class GuildUpdateService : BackgroundService { if (!embed.IsDefined(out var built)) continue; var messageResult = await _channelApi.CreateMessageAsync( - reminder.Channel, Mention.User(user), embeds: new[] { built }, ct: ct); + reminder.Channel.ToSnowflake(), Mention.User(user), embeds: new[] { built }, ct: ct); if (!messageResult.IsSuccess) _logger.LogWarning( "Error in reminder send.\n{ErrorMessage}", messageResult.Error.Message); @@ -163,7 +164,7 @@ public class GuildUpdateService : BackgroundService { var eventsResult = await _eventApi.ListScheduledEventsForGuildAsync(guildId, ct: ct); if (!eventsResult.IsDefined(out var events)) return; - if (data.Configuration.EventNotificationChannel is 0) return; + if (GuildSettings.EventNotificationChannel.Get(data.Settings).Empty()) return; foreach (var scheduledEvent in events) { if (!data.ScheduledEvents.ContainsKey(scheduledEvent.ID.Value)) { @@ -172,7 +173,7 @@ public class GuildUpdateService : BackgroundService { var storedEvent = data.ScheduledEvents[scheduledEvent.ID.Value]; if (storedEvent.Status == scheduledEvent.Status) { if (DateTimeOffset.UtcNow >= scheduledEvent.ScheduledStartTime) { - if (data.Configuration.AutoStartEvents + if (GuildSettings.AutoStartEvents.Get(data.Settings) && scheduledEvent.Status is not GuildScheduledEventStatus.Active) { var startResult = await _eventApi.ModifyGuildScheduledEventAsync( guildId, scheduledEvent.ID, @@ -182,10 +183,11 @@ public class GuildUpdateService : BackgroundService { "Error in automatic scheduled event start request.\n{ErrorMessage}", startResult.Error.Message); } - } else if (data.Configuration.EventEarlyNotificationOffset != TimeSpan.Zero + } else if (GuildSettings.EventEarlyNotificationOffset.Get(data.Settings) != TimeSpan.Zero && !storedEvent.EarlyNotificationSent && DateTimeOffset.UtcNow - >= scheduledEvent.ScheduledStartTime - data.Configuration.EventEarlyNotificationOffset) { + >= scheduledEvent.ScheduledStartTime + - GuildSettings.EventEarlyNotificationOffset.Get(data.Settings)) { var earlyResult = await SendScheduledEventUpdatedMessage(scheduledEvent, data, true, ct); if (earlyResult.IsSuccess) storedEvent.EarlyNotificationSent = true; @@ -203,7 +205,7 @@ public class GuildUpdateService : BackgroundService { var result = scheduledEvent.Status switch { GuildScheduledEventStatus.Scheduled => - await SendScheduledEventCreatedMessage(scheduledEvent, data.Configuration, ct), + await SendScheduledEventCreatedMessage(scheduledEvent, data.Settings, ct), GuildScheduledEventStatus.Active or GuildScheduledEventStatus.Completed => await SendScheduledEventUpdatedMessage(scheduledEvent, data, false, ct), _ => Result.FromError(new ArgumentOutOfRangeError(nameof(scheduledEvent.Status))) @@ -215,19 +217,17 @@ public class GuildUpdateService : BackgroundService { } /// - /// Handles sending a notification, mentioning the if one is + /// Handles sending a notification, mentioning the if one is /// set, /// when a scheduled event is created - /// in a guild's if one is set. + /// in a guild's if one is set. /// /// The scheduled event that has just been created. - /// The configuration of the guild containing the scheduled event. + /// The settings of the guild containing the scheduled event. /// The cancellation token for this operation. /// A notification sending result which may or may not have succeeded. private async Task SendScheduledEventCreatedMessage( - IGuildScheduledEvent scheduledEvent, GuildConfiguration config, CancellationToken ct = default) { - var currentUserResult = await _userApi.GetCurrentUserAsync(ct); - if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult); + IGuildScheduledEvent scheduledEvent, JsonNode settings, CancellationToken ct = default) { if (!scheduledEvent.CreatorID.IsDefined(out var creatorId)) return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.CreatorID))); @@ -275,14 +275,13 @@ public class GuildUpdateService : BackgroundService { .WithTitle(scheduledEvent.Name) .WithDescription(embedDescription) .WithEventCover(scheduledEvent.ID, scheduledEvent.Image) - .WithUserFooter(currentUser) .WithCurrentTimestamp() .WithColour(ColorsList.White) .Build(); if (!embed.IsDefined(out var built)) return Result.FromError(embed); - var roleMention = config.EventNotificationRole is not 0 - ? Mention.Role(config.EventNotificationRole.ToDiscordSnowflake()) + var roleMention = !GuildSettings.EventNotificationRole.Get(settings).Empty() + ? Mention.Role(GuildSettings.EventNotificationRole.Get(settings)) : string.Empty; var button = new ButtonComponent( @@ -294,14 +293,14 @@ public class GuildUpdateService : BackgroundService { ); return (Result)await _channelApi.CreateMessageAsync( - config.EventNotificationChannel.ToDiscordSnowflake(), roleMention, embeds: new[] { built }, + GuildSettings.EventNotificationChannel.Get(settings), roleMention, embeds: new[] { built }, components: new[] { new ActionRowComponent(new[] { button }) }, ct: ct); } /// - /// Handles sending a notification, mentioning the s, + /// Handles sending a notification, mentioning the and event subscribers, /// when a scheduled event is about to start, has started or completed - /// in a guild's if one is set. + /// in a guild's if one is set. /// /// The scheduled event that is about to start, has started or completed. /// The data for the guild containing the scheduled event. @@ -353,7 +352,7 @@ public class GuildUpdateService : BackgroundService { } var contentResult = await _utility.GetEventNotificationMentions( - scheduledEvent, data.Configuration, ct); + scheduledEvent, data.Settings, ct); if (!contentResult.IsDefined(out content)) return Result.FromError(contentResult); @@ -383,7 +382,7 @@ public class GuildUpdateService : BackgroundService { if (!result.IsDefined(out var built)) return Result.FromError(result); return (Result)await _channelApi.CreateMessageAsync( - data.Configuration.EventNotificationChannel.ToDiscordSnowflake(), + GuildSettings.EventNotificationChannel.Get(data.Settings), content ?? default(Optional), embeds: new[] { built }, ct: ct); } } diff --git a/src/Services/UtilityService.cs b/src/Services/UtilityService.cs index b4ff6fb..3b6a2bf 100644 --- a/src/Services/UtilityService.cs +++ b/src/Services/UtilityService.cs @@ -1,4 +1,5 @@ using System.Text; +using System.Text.Json.Nodes; using Boyfriend.Data; using Microsoft.Extensions.Hosting; using Remora.Discord.API.Abstractions.Objects; @@ -103,38 +104,32 @@ public class UtilityService : IHostedService { } /// - /// Gets the string mentioning all s related to a scheduled + /// Gets the string mentioning the and event subscribers related to a scheduled /// event. /// - /// - /// If the guild configuration enables , then the - /// will also be mentioned. - /// /// - /// The scheduled event whose subscribers will be mentioned if the guild configuration enables - /// . + /// The scheduled event whose subscribers will be mentioned. /// - /// The configuration of the guild containing the scheduled event + /// The settings of the guild containing the scheduled event /// The cancellation token for this operation. /// A result containing the string which may or may not have succeeded. public async Task> GetEventNotificationMentions( - IGuildScheduledEvent scheduledEvent, GuildConfiguration config, CancellationToken ct = default) { + IGuildScheduledEvent scheduledEvent, JsonNode settings, CancellationToken ct = default) { var builder = new StringBuilder(); - var receivers = config.EventStartedReceivers; - var role = config.EventNotificationRole.ToDiscordSnowflake(); + var role = GuildSettings.EventNotificationRole.Get(settings); var usersResult = await _eventApi.GetGuildScheduledEventUsersAsync( scheduledEvent.GuildID, scheduledEvent.ID, withMember: true, ct: ct); if (!usersResult.IsDefined(out var users)) return Result.FromError(usersResult); - if (receivers.Contains(GuildConfiguration.NotificationReceiver.Role) && role.Value is not 0) + if (role.Value is not 0) builder.Append($"{Mention.Role(role)} "); - if (receivers.Contains(GuildConfiguration.NotificationReceiver.Interested)) - builder = users.Where( - user => { - if (!user.GuildMember.IsDefined(out var member)) return true; - return !member.Roles.Contains(role); - }) - .Aggregate(builder, (current, user) => current.Append($"{Mention.User(user.User)} ")); + + builder = users.Where( + user => { + if (!user.GuildMember.IsDefined(out var member)) return true; + return !member.Roles.Contains(role); + }) + .Aggregate(builder, (current, user) => current.Append($"{Mention.User(user.User)} ")); return builder.ToString(); } }