diff --git a/locale/Messages.resx b/locale/Messages.resx index f370773..f7500b6 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -117,13 +117,13 @@ {0}, welcome to {1} - + Veemo! - + Woomy! - + Ngyes! @@ -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 2fed107..e28b405 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -117,13 +117,13 @@ {0}, добро пожаловать на сервер {1} - + Виимо! - + Вууми! - + Нгьес! @@ -585,6 +585,12 @@ Сообщить о проблеме + + До скорой встречи, {0}! + + + Сообщение о выходе + Неправильно указано время! diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index 31453d8..58e1178 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -117,13 +117,13 @@ {0}, добро пожаловать на сервер {1} - + вииимо! - + вуууми! - + нгьес! @@ -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/PingCommandGroup.cs b/src/Commands/PingCommandGroup.cs index 31fa6dc..f74e5e2 100644 --- a/src/Commands/PingCommandGroup.cs +++ b/src/Commands/PingCommandGroup.cs @@ -91,7 +91,7 @@ public class PingCommandGroup : CommandGroup } var embed = new EmbedBuilder().WithSmallTitle(bot.GetTag(), bot) - .WithTitle($"Sound{Random.Shared.Next(1, 4)}".Localized()) + .WithTitle($"Generic{Random.Shared.Next(1, 4)}".Localized()) .WithDescription($"{latency:F0}{Messages.Milliseconds}") .WithColour(latency < 250 ? ColorsList.Green : latency < 500 ? ColorsList.Yellow : ColorsList.Red) .WithCurrentTimestamp() 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 2a8ae0d..3d452a6 100644 --- a/src/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -66,21 +66,21 @@ namespace Octobot { } } - internal static string Loaded1 { + internal static string Generic1 { get { - return ResourceManager.GetString("Loaded1", resourceCulture); + return ResourceManager.GetString("Generic1", resourceCulture); } } - internal static string Loaded2 { + internal static string Generic2 { get { - return ResourceManager.GetString("Loaded2", resourceCulture); + return ResourceManager.GetString("Generic2", resourceCulture); } } - internal static string Loaded3 { + internal static string Generic3 { get { - return ResourceManager.GetString("Loaded3", resourceCulture); + return ResourceManager.GetString("Generic3", resourceCulture); } } @@ -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/GuildLoadedResponder.cs b/src/Responders/GuildLoadedResponder.cs index 304076f..f802bb8 100644 --- a/src/Responders/GuildLoadedResponder.cs +++ b/src/Responders/GuildLoadedResponder.cs @@ -88,7 +88,7 @@ public class GuildLoadedResponder : IResponder var i = Random.Shared.Next(1, 4); var embed = new EmbedBuilder().WithSmallTitle(bot.GetTag(), bot) - .WithTitle($"Loaded{i}".Localized()) + .WithTitle($"Generic{i}".Localized()) .WithDescription(Messages.Ready) .WithCurrentTimestamp() .WithColour(ColorsList.Blue) 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); + } +} +