From cd75780582d82cb53c252054ddf287f9aa721f4d Mon Sep 17 00:00:00 2001 From: Macintxsh <95250141+mctaylors@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:18:40 +0300 Subject: [PATCH] Add "Member left" message (#234) Closes #231 --------- Signed-off-by: mctaylors Signed-off-by: Macintxsh <95250141+mctaylors@users.noreply.github.com> --- locale/Messages.resx | 6 ++ locale/Messages.ru.resx | 6 ++ locale/Messages.tt-ru.resx | 6 ++ src/Commands/BanCommandGroup.cs | 8 ++- src/Commands/KickCommandGroup.cs | 6 +- src/Commands/SettingsCommandGroup.cs | 1 + src/Data/GuildSettings.cs | 16 ++++- src/Data/Options/AllOptionsEnum.cs | 1 + src/Messages.Designer.cs | 24 ++++--- src/Responders/GuildMemberLeftResponder.cs | 73 ++++++++++++++++++++++ 10 files changed, 132 insertions(+), 15 deletions(-) create mode 100644 src/Responders/GuildMemberLeftResponder.cs diff --git a/locale/Messages.resx b/locale/Messages.resx index c2be4cd..dfaff85 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -585,6 +585,12 @@ Report an issue + + See you soon, {0}! + + + Leave message + Time specified incorrectly! diff --git a/locale/Messages.ru.resx b/locale/Messages.ru.resx index d38509c..6169a13 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -585,6 +585,12 @@ Сообщить о проблеме + + До скорой встречи, {0}! + + + Сообщение о выходе + Неправильно указано время! diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index dfb1ee6..3118e74 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -585,6 +585,12 @@ зарепортить баг + + ну, мы потеряли {0} + + + до свидания (типо настройка) + ты там правильно напиши таймспан diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index c350729..30cff14 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -181,17 +181,19 @@ public class BanCommandGroup : CommandGroup await _channelApi.CreateMessageWithEmbedResultAsync(dmChannel.ID, embedResult: dmEmbed, ct: ct); } + var memberData = data.GetOrCreateMemberData(target.ID); + memberData.BannedUntil + = duration is not null ? DateTimeOffset.UtcNow.Add(duration.Value) : DateTimeOffset.MaxValue; + var banResult = await _guildApi.CreateGuildBanAsync( guild.ID, target.ID, reason: $"({executor.GetTag()}) {reason}".EncodeHeader(), ct: ct); if (!banResult.IsSuccess) { + memberData.BannedUntil = null; return Result.FromError(banResult.Error); } - var memberData = data.GetOrCreateMemberData(target.ID); - memberData.BannedUntil - = duration is not null ? DateTimeOffset.UtcNow.Add(duration.Value) : DateTimeOffset.MaxValue; memberData.Roles.Clear(); var embed = new EmbedBuilder().WithSmallTitle( diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index 0faa1d3..59c4045 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -143,17 +143,19 @@ public class KickCommandGroup : CommandGroup await _channelApi.CreateMessageWithEmbedResultAsync(dmChannel.ID, embedResult: dmEmbed, ct: ct); } + var memberData = data.GetOrCreateMemberData(target.ID); + memberData.Kicked = true; + var kickResult = await _guildApi.RemoveGuildMemberAsync( guild.ID, target.ID, $"({executor.GetTag()}) {reason}".EncodeHeader(), ct); if (!kickResult.IsSuccess) { + memberData.Kicked = false; return Result.FromError(kickResult.Error); } - var memberData = data.GetOrCreateMemberData(target.ID); memberData.Roles.Clear(); - memberData.Kicked = true; var title = string.Format(Messages.UserKicked, target.GetTag()); var description = MarkdownExtensions.BulletPoint(string.Format(Messages.DescriptionActionReason, reason)); diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 86f031f..97ebc32 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -39,6 +39,7 @@ public class SettingsCommandGroup : CommandGroup [ GuildSettings.Language, GuildSettings.WelcomeMessage, + GuildSettings.LeaveMessage, GuildSettings.ReceiveStartupMessages, GuildSettings.RemoveRolesOnMute, GuildSettings.ReturnRolesOnRejoin, diff --git a/src/Data/GuildSettings.cs b/src/Data/GuildSettings.cs index 5a99505..518465b 100644 --- a/src/Data/GuildSettings.cs +++ b/src/Data/GuildSettings.cs @@ -13,17 +13,29 @@ 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. + /// Controls what message should be sent in when a new member joins the guild. /// /// /// /// No message will be sent if set to "off", "disable" or "disabled". - /// will be sent if set to "default" or "reset" + /// will be sent if set to "default" or "reset". /// /// /// public static readonly Option WelcomeMessage = new("WelcomeMessage", "default"); + /// + /// Controls what message should be sent in when a member leaves the guild. + /// + /// + /// + /// 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 LeaveMessage = new("LeaveMessage", "default"); + /// /// Controls whether or not the message should be sent /// in on startup. diff --git a/src/Data/Options/AllOptionsEnum.cs b/src/Data/Options/AllOptionsEnum.cs index e9637d6..6932822 100644 --- a/src/Data/Options/AllOptionsEnum.cs +++ b/src/Data/Options/AllOptionsEnum.cs @@ -14,6 +14,7 @@ public enum AllOptionsEnum { [UsedImplicitly] Language, [UsedImplicitly] WelcomeMessage, + [UsedImplicitly] LeaveMessage, [UsedImplicitly] ReceiveStartupMessages, [UsedImplicitly] RemoveRolesOnMute, [UsedImplicitly] ReturnRolesOnRejoin, diff --git a/src/Messages.Designer.cs b/src/Messages.Designer.cs index 707c814..0fa4820 100644 --- a/src/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -1037,18 +1037,26 @@ namespace Octobot { } } - internal static string InvalidTimeSpan - { - get - { + internal static string DefaultLeaveMessage { + get { + return ResourceManager.GetString("DefaultLeaveMessage", resourceCulture); + } + } + + internal static string SettingsLeaveMessage { + get { + return ResourceManager.GetString("SettingsLeaveMessage", resourceCulture); + } + } + + internal static string InvalidTimeSpan { + get { return ResourceManager.GetString("InvalidTimeSpan", resourceCulture); } } - internal static string UserInfoKicked - { - get - { + internal static string UserInfoKicked { + get { return ResourceManager.GetString("UserInfoKicked", resourceCulture); } } diff --git a/src/Responders/GuildMemberLeftResponder.cs b/src/Responders/GuildMemberLeftResponder.cs new file mode 100644 index 0000000..5c6db36 --- /dev/null +++ b/src/Responders/GuildMemberLeftResponder.cs @@ -0,0 +1,73 @@ +using JetBrains.Annotations; +using Octobot.Data; +using Octobot.Extensions; +using Octobot.Services; +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 Octobot.Responders; + +/// +/// Handles sending a guild's if one is set. +/// +/// +[UsedImplicitly] +public class GuildMemberLeftResponder : IResponder +{ + private readonly IDiscordRestChannelAPI _channelApi; + private readonly IDiscordRestGuildAPI _guildApi; + private readonly GuildDataService _guildData; + + public GuildMemberLeftResponder( + IDiscordRestChannelAPI channelApi, GuildDataService guildData, IDiscordRestGuildAPI guildApi) + { + _channelApi = channelApi; + _guildData = guildData; + _guildApi = guildApi; + } + + public async Task RespondAsync(IGuildMemberRemove gatewayEvent, CancellationToken ct = default) + { + var user = gatewayEvent.User; + var data = await _guildData.GetData(gatewayEvent.GuildID, ct); + var cfg = data.Settings; + + var memberData = data.GetOrCreateMemberData(user.ID); + if (memberData.BannedUntil is not null || memberData.Kicked) + { + return Result.FromSuccess(); + } + + if (GuildSettings.WelcomeMessagesChannel.Get(cfg).Empty() + || GuildSettings.LeaveMessage.Get(cfg) is "off" or "disable" or "disabled") + { + return Result.FromSuccess(); + } + + Messages.Culture = GuildSettings.Language.Get(cfg); + var leaveMessage = GuildSettings.LeaveMessage.Get(cfg) is "default" or "reset" + ? Messages.DefaultLeaveMessage + : GuildSettings.LeaveMessage.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(leaveMessage, user.GetTag(), guild.Name), user) + .WithGuildFooter(guild) + .WithTimestamp(DateTimeOffset.UtcNow) + .WithColour(ColorsList.Black) + .Build(); + + return await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.WelcomeMessagesChannel.Get(cfg), embedResult: embed, + allowedMentions: Octobot.NoMentions, ct: ct); + } +} +