From 5e6691fef5f0402224ffc5e4e024d5ecfdbfc04b Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Sat, 20 Nov 2021 19:54:21 +0700 Subject: [PATCH 1/8] change_reprimand_original_entry_on_update --- Zhongli.Services/Moderation/ModerationLoggingService.cs | 2 +- Zhongli.Services/Moderation/ModerationService.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zhongli.Services/Moderation/ModerationLoggingService.cs b/Zhongli.Services/Moderation/ModerationLoggingService.cs index c585f90..d234afc 100644 --- a/Zhongli.Services/Moderation/ModerationLoggingService.cs +++ b/Zhongli.Services/Moderation/ModerationLoggingService.cs @@ -47,7 +47,7 @@ public async Task UpdatedEmbedAsync(Reprimand reprimand, Reprimand .WithTitle($"{reprimand.Status.Humanize()} {reprimand.GetTitle()}") .WithColor(Color.Purple); - AddReason(embed, reprimand.ModifiedAction); + AddReason(embed, reprimand.Action); await AddReprimandDetailsAsync(embed, reprimand, cancellationToken); return embed; diff --git a/Zhongli.Services/Moderation/ModerationService.cs b/Zhongli.Services/Moderation/ModerationService.cs index 8268b96..047bff7 100644 --- a/Zhongli.Services/Moderation/ModerationService.cs +++ b/Zhongli.Services/Moderation/ModerationService.cs @@ -355,8 +355,8 @@ private async Task ExpireReprimandAsync(ExpirableReprimand reprimand, Cancellati private async Task UpdateReprimandAsync(Reprimand reprimand, ReprimandDetails details, ReprimandStatus status, CancellationToken cancellationToken) { - reprimand.Status = status; - reprimand.ModifiedAction = details; + reprimand.Status = status; + reprimand.Action = details; await _db.SaveChangesAsync(cancellationToken); await _logging.PublishReprimandAsync(reprimand, details, cancellationToken); From 097dd0b5c03a2c1206f2b0b6e7e3252417313457 Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Sun, 21 Nov 2021 11:24:57 +0700 Subject: [PATCH 2/8] feat: add_mute_list_command --- .../Modules/Moderation/ModerationModule.cs | 38 ++++++++++++++- .../Moderation/ReprimandExtensions.cs | 48 ++++++++++++++++--- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/Zhongli.Bot/Modules/Moderation/ModerationModule.cs b/Zhongli.Bot/Modules/Moderation/ModerationModule.cs index fc10ee9..6fb088d 100644 --- a/Zhongli.Bot/Modules/Moderation/ModerationModule.cs +++ b/Zhongli.Bot/Modules/Moderation/ModerationModule.cs @@ -1,7 +1,10 @@ using System; +using System.Text; using System.Linq; using System.Threading.Tasks; using Discord; +using Discord.Addons.Interactive; +using Discord.Addons.Interactive.Paginator; using Discord.Commands; using Humanizer; using Zhongli.Data; @@ -18,7 +21,7 @@ namespace Zhongli.Bot.Modules.Moderation { [Name("Moderation")] [Summary("Guild moderation commands.")] - public class ModerationModule : ModuleBase + public class ModerationModule : InteractiveBase { private readonly CommandErrorHandler _error; private readonly ModerationLoggingService _logging; @@ -234,6 +237,35 @@ public async Task WarnAsync(IGuildUser user, uint amount = 1, [Remainder] string public Task WarnAsync(IGuildUser user, [Remainder] string? reason = null) => WarnAsync(user, 1, reason); + [Command("mute list")] + [Summary("View active mutes on the current guild.")] + [RequireAuthorization(AuthorizationScope.Moderator)] + public async Task MuteListAsync() + { + var guild = await _db.Guilds.TrackGuildAsync(Context.Guild); + var history = guild.ReprimandHistory + .Where(r => r.Status is not ReprimandStatus.Deleted && r.Status is not ReprimandStatus.Expired) + .OfType(InfractionType.Mute); + + var reprimands = new EmbedBuilder().Fields; + + var pages = history + .OrderByDescending(r => r.Action?.Date) + .Select(r => CreateEmbed(r)); + + var message = new PaginatedMessage + { + Title = "Currently Active Mutes", + Pages = reprimands.Concat(pages), + Options = new PaginatedAppearanceOptions + { + FieldsPerPage = 10 + } + }; + + await PagedReplyAsync(message); + } + private async Task ReplyReprimandAsync(ReprimandResult result, ReprimandDetails details) { var guild = await result.Primary.GetGuildAsync(_db); @@ -267,5 +299,9 @@ private async Task GetDetailsAsync(IUser user, string? reason) return details; } + + private static EmbedFieldBuilder CreateEmbed(Reprimand r) => new EmbedFieldBuilder() + .WithName(r.GetTitle()) + .WithValue(r.GetReprimandExpiration()); } } \ No newline at end of file diff --git a/Zhongli.Services/Moderation/ReprimandExtensions.cs b/Zhongli.Services/Moderation/ReprimandExtensions.cs index ef69ced..774a9ee 100644 --- a/Zhongli.Services/Moderation/ReprimandExtensions.cs +++ b/Zhongli.Services/Moderation/ReprimandExtensions.cs @@ -30,16 +30,52 @@ public static bool IsIncluded(this Reprimand reprimand, ReprimandNoticeType type return reprimand switch { - Ban => type.HasFlag(ReprimandNoticeType.Ban), + Ban => type.HasFlag(ReprimandNoticeType.Ban), Censored => type.HasFlag(ReprimandNoticeType.Censor), - Kick => type.HasFlag(ReprimandNoticeType.Kick), - Mute => type.HasFlag(ReprimandNoticeType.Mute), - Notice => type.HasFlag(ReprimandNoticeType.Notice), - Warning => type.HasFlag(ReprimandNoticeType.Warning), - _ => false + Kick => type.HasFlag(ReprimandNoticeType.Kick), + Mute => type.HasFlag(ReprimandNoticeType.Mute), + Notice => type.HasFlag(ReprimandNoticeType.Notice), + Warning => type.HasFlag(ReprimandNoticeType.Warning), + _ => false }; } + public static string GetExpirationTime(this IExpirable expirable) + { + if (expirable.ExpireAt is not null && expirable.Length is not null) + { + if (expirable.ExpireAt > DateTimeOffset.Now) + { + TimeSpan? dif = expirable.ExpireAt - DateTimeOffset.Now; + return $"{(int)dif.Value.TotalDays} days {dif.Value.Hours} hours {dif.Value.Minutes} minutes {dif.Value.Seconds} seconds"; + + } + else + { + return "Now"; + } + } + else + { + return "Indefinitely"; + } + } + + public static string GetReprimandExpiration(this Reprimand reprimand) + { + var mention = $"<@{reprimand.UserId}>"; + var line = reprimand switch + { + Ban b => $"Expired in: {b.GetExpirationTime()}.", + Mute m => $"Expired in: {m.GetExpirationTime()}.", + _ => throw new ArgumentOutOfRangeException( + nameof(reprimand), reprimand, "This reprimand is not expirable.") + }; + return new StringBuilder() + .AppendLine($"User: {mention}") + .AppendLine(line).ToString(); + } + public static Color GetColor(this Reprimand reprimand) { return reprimand switch From 8bfda2cdd1c611b935b4b3baf87f5227b1159f0a Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Sun, 21 Nov 2021 11:31:18 +0700 Subject: [PATCH 3/8] fix: split pull request --- Zhongli.Services/Moderation/ModerationLoggingService.cs | 2 +- Zhongli.Services/Moderation/ModerationService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Zhongli.Services/Moderation/ModerationLoggingService.cs b/Zhongli.Services/Moderation/ModerationLoggingService.cs index d234afc..c585f90 100644 --- a/Zhongli.Services/Moderation/ModerationLoggingService.cs +++ b/Zhongli.Services/Moderation/ModerationLoggingService.cs @@ -47,7 +47,7 @@ public async Task UpdatedEmbedAsync(Reprimand reprimand, Reprimand .WithTitle($"{reprimand.Status.Humanize()} {reprimand.GetTitle()}") .WithColor(Color.Purple); - AddReason(embed, reprimand.Action); + AddReason(embed, reprimand.ModifiedAction); await AddReprimandDetailsAsync(embed, reprimand, cancellationToken); return embed; diff --git a/Zhongli.Services/Moderation/ModerationService.cs b/Zhongli.Services/Moderation/ModerationService.cs index 047bff7..3103d91 100644 --- a/Zhongli.Services/Moderation/ModerationService.cs +++ b/Zhongli.Services/Moderation/ModerationService.cs @@ -356,7 +356,7 @@ private async Task UpdateReprimandAsync(Reprimand reprimand, ReprimandDetails de ReprimandStatus status, CancellationToken cancellationToken) { reprimand.Status = status; - reprimand.Action = details; + reprimand.ModifiedAction = details; await _db.SaveChangesAsync(cancellationToken); await _logging.PublishReprimandAsync(reprimand, details, cancellationToken); From e61365039ea2457b3403b69917998c24fe338e52 Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Sun, 21 Nov 2021 11:34:10 +0700 Subject: [PATCH 4/8] fix: fix_changes --- Zhongli.Services/Moderation/ModerationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zhongli.Services/Moderation/ModerationService.cs b/Zhongli.Services/Moderation/ModerationService.cs index 3103d91..8268b96 100644 --- a/Zhongli.Services/Moderation/ModerationService.cs +++ b/Zhongli.Services/Moderation/ModerationService.cs @@ -355,7 +355,7 @@ private async Task ExpireReprimandAsync(ExpirableReprimand reprimand, Cancellati private async Task UpdateReprimandAsync(Reprimand reprimand, ReprimandDetails details, ReprimandStatus status, CancellationToken cancellationToken) { - reprimand.Status = status; + reprimand.Status = status; reprimand.ModifiedAction = details; await _db.SaveChangesAsync(cancellationToken); From 2653b0f94f243199f0e921a4f8cfcbba20b13244 Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Sun, 21 Nov 2021 11:34:51 +0700 Subject: [PATCH 5/8] fix_changes2 --- Zhongli.Services/Moderation/ReprimandExtensions.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Zhongli.Services/Moderation/ReprimandExtensions.cs b/Zhongli.Services/Moderation/ReprimandExtensions.cs index 774a9ee..515573e 100644 --- a/Zhongli.Services/Moderation/ReprimandExtensions.cs +++ b/Zhongli.Services/Moderation/ReprimandExtensions.cs @@ -30,13 +30,13 @@ public static bool IsIncluded(this Reprimand reprimand, ReprimandNoticeType type return reprimand switch { - Ban => type.HasFlag(ReprimandNoticeType.Ban), + Ban => type.HasFlag(ReprimandNoticeType.Ban), Censored => type.HasFlag(ReprimandNoticeType.Censor), - Kick => type.HasFlag(ReprimandNoticeType.Kick), - Mute => type.HasFlag(ReprimandNoticeType.Mute), - Notice => type.HasFlag(ReprimandNoticeType.Notice), - Warning => type.HasFlag(ReprimandNoticeType.Warning), - _ => false + Kick => type.HasFlag(ReprimandNoticeType.Kick), + Mute => type.HasFlag(ReprimandNoticeType.Mute), + Notice => type.HasFlag(ReprimandNoticeType.Notice), + Warning => type.HasFlag(ReprimandNoticeType.Warning), + _ => false }; } From 2b9d34605040bdd1ade20c769878b70a9222dc9d Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Tue, 23 Nov 2021 08:39:23 +0700 Subject: [PATCH 6/8] chore: repush_reprimand_update_original_entry --- Zhongli.Services/Moderation/ModerationLoggingService.cs | 2 +- Zhongli.Services/Moderation/ModerationService.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zhongli.Services/Moderation/ModerationLoggingService.cs b/Zhongli.Services/Moderation/ModerationLoggingService.cs index c585f90..d234afc 100644 --- a/Zhongli.Services/Moderation/ModerationLoggingService.cs +++ b/Zhongli.Services/Moderation/ModerationLoggingService.cs @@ -47,7 +47,7 @@ public async Task UpdatedEmbedAsync(Reprimand reprimand, Reprimand .WithTitle($"{reprimand.Status.Humanize()} {reprimand.GetTitle()}") .WithColor(Color.Purple); - AddReason(embed, reprimand.ModifiedAction); + AddReason(embed, reprimand.Action); await AddReprimandDetailsAsync(embed, reprimand, cancellationToken); return embed; diff --git a/Zhongli.Services/Moderation/ModerationService.cs b/Zhongli.Services/Moderation/ModerationService.cs index 8268b96..047bff7 100644 --- a/Zhongli.Services/Moderation/ModerationService.cs +++ b/Zhongli.Services/Moderation/ModerationService.cs @@ -355,8 +355,8 @@ private async Task ExpireReprimandAsync(ExpirableReprimand reprimand, Cancellati private async Task UpdateReprimandAsync(Reprimand reprimand, ReprimandDetails details, ReprimandStatus status, CancellationToken cancellationToken) { - reprimand.Status = status; - reprimand.ModifiedAction = details; + reprimand.Status = status; + reprimand.Action = details; await _db.SaveChangesAsync(cancellationToken); await _logging.PublishReprimandAsync(reprimand, details, cancellationToken); From 80ec51971a5bb5dd1ceb9633e6dd8bbeb7da880d Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Fri, 26 Nov 2021 17:11:25 +0700 Subject: [PATCH 7/8] fix: check delete days parameter before executing a ban --- .../Modules/Moderation/ModerationModule.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Zhongli.Bot/Modules/Moderation/ModerationModule.cs b/Zhongli.Bot/Modules/Moderation/ModerationModule.cs index 6fb088d..5c7df5b 100644 --- a/Zhongli.Bot/Modules/Moderation/ModerationModule.cs +++ b/Zhongli.Bot/Modules/Moderation/ModerationModule.cs @@ -47,13 +47,20 @@ public ModerationModule( public async Task BanAsync(IUser user, uint deleteDays = 0, TimeSpan? length = null, [Remainder] string? reason = null) { - var details = await GetDetailsAsync(user, reason); - var result = await _moderation.TryBanAsync(deleteDays, length, details); - - if (result is null) - await _error.AssociateError(Context.Message, "Failed to ban user."); + if (deleteDays < 0 || deleteDays > 7) + { + await ReplyAsync($"Error: Parameter DeleteMessageDays must be between 1-7, {deleteDays} given."); + } else - await ReplyReprimandAsync(result, details); + { + var details = await GetDetailsAsync(user, reason); + var result = await _moderation.TryBanAsync(deleteDays, length, details); + + if (result is null) + await _error.AssociateError(Context.Message, "Failed to ban user."); + else + await ReplyReprimandAsync(result, details); + } } [Command("ban")] From 087b48a2151ff1cc5f0b04e2abb1aa48e40e9057 Mon Sep 17 00:00:00 2001 From: Andy Gunawan Date: Fri, 26 Nov 2021 17:17:58 +0700 Subject: [PATCH 8/8] fix: adjust error message --- Zhongli.Bot/Modules/Moderation/ModerationModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zhongli.Bot/Modules/Moderation/ModerationModule.cs b/Zhongli.Bot/Modules/Moderation/ModerationModule.cs index 5c7df5b..ca35a46 100644 --- a/Zhongli.Bot/Modules/Moderation/ModerationModule.cs +++ b/Zhongli.Bot/Modules/Moderation/ModerationModule.cs @@ -49,7 +49,7 @@ public async Task BanAsync(IUser user, uint deleteDays = 0, TimeSpan? length = n { if (deleteDays < 0 || deleteDays > 7) { - await ReplyAsync($"Error: Parameter DeleteMessageDays must be between 1-7, {deleteDays} given."); + await ReplyAsync($"Error: Parameter deleteDays cannot be higher than 7, {deleteDays} given."); } else {