diff --git a/src/EllieBot/Modules/Administration/DangerousCommands/CleanupService.cs b/src/EllieBot/Modules/Administration/DangerousCommands/CleanupService.cs index 3555a61..b2dbf46 100644 --- a/src/EllieBot/Modules/Administration/DangerousCommands/CleanupService.cs +++ b/src/EllieBot/Modules/Administration/DangerousCommands/CleanupService.cs @@ -61,17 +61,66 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, IEService })); } + // delete guild configs await ctx.GetTable() .Where(x => !tempTable.Select(x => x.GuildId) .Contains(x.GuildId)) .DeleteAsync(); - - + + // delete guild xp await ctx.GetTable() .Where(x => !tempTable.Select(x => x.GuildId) .Contains(x.GuildId)) .DeleteAsync(); - + + // delete expressions + await ctx.GetTable() + .Where(x => x.GuildId != null && !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId.Value)) + .DeleteAsync(); + + // delete quotes + await ctx.GetTable() + .Where(x => !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId)) + .DeleteAsync(); + + // delete planted currencies + await ctx.GetTable() + .Where(x => !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId)) + .DeleteAsync(); + + // delete image only channels + await ctx.GetTable() + .Where(x => !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId)) + .DeleteAsync(); + + // delete reaction roles + await ctx.GetTable() + .Where(x => !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId)) + .DeleteAsync(); + + // delete ignored users + await ctx.GetTable() + .Where(x => x.GuildId != null && !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId.Value)) + .DeleteAsync(); + + // delete perm overrides + await ctx.GetTable() + .Where(x => x.GuildId != null && !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId.Value)) + .DeleteAsync(); + + // delete repeaters + await ctx.GetTable() + .Where(x => !tempTable.Select(x => x.GuildId) + .Contains(x.GuildId)) + .DeleteAsync(); + return new() { GuildCount = guildIds.Keys.Count, diff --git a/src/EllieBot/Modules/Administration/Mute/MuteService.cs b/src/EllieBot/Modules/Administration/Mute/MuteService.cs index a3fbea3..df52c0c 100644 --- a/src/EllieBot/Modules/Administration/Mute/MuteService.cs +++ b/src/EllieBot/Modules/Administration/Mute/MuteService.cs @@ -293,7 +293,7 @@ public class MuteService : IEService { ArgumentNullException.ThrowIfNull(guild); - const string defaultMuteRoleName = "ellie-mute"; + const string defaultMuteRoleName = "nadeko-mute"; var muteRoleName = GuildMuteRoles.GetOrAdd(guild.Id, defaultMuteRoleName); diff --git a/src/EllieBot/Modules/Administration/Prune/PruneCommands.cs b/src/EllieBot/Modules/Administration/Prune/PruneCommands.cs index 58b586e..2317bf0 100644 --- a/src/EllieBot/Modules/Administration/Prune/PruneCommands.cs +++ b/src/EllieBot/Modules/Administration/Prune/PruneCommands.cs @@ -45,23 +45,43 @@ public partial class Administration var progressMsg = await Response().Pending(strs.prune_progress(0, 100)).SendAsync(); var progress = GetProgressTracker(progressMsg); + PruneResult result; if (opts.Safe) - await _service.PruneWhere((ITextChannel)ctx.Channel, + result = await _service.PruneWhere((ITextChannel)ctx.Channel, 100, x => x.Author.Id == user.Id && !x.IsPinned, progress, opts.After); else - await _service.PruneWhere((ITextChannel)ctx.Channel, + result = await _service.PruneWhere((ITextChannel)ctx.Channel, 100, x => x.Author.Id == user.Id, progress, opts.After); ctx.Message.DeleteAfter(3); + + await SendResult(result); await progressMsg.DeleteAsync(); } + private async Task SendResult(PruneResult result) + { + switch (result) + { + case PruneResult.Success: + break; + case PruneResult.AlreadyRunning: + break; + case PruneResult.FeatureLimit: + await Response().Pending(strs.feature_limit_reached_owner).SendAsync(); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(result), result, null); + } + } + // prune x [Cmd] [RequireContext(ContextType.Guild)] @@ -83,19 +103,21 @@ public partial class Administration var progressMsg = await Response().Pending(strs.prune_progress(0, count)).SendAsync(); var progress = GetProgressTracker(progressMsg); + PruneResult result; if (opts.Safe) - await _service.PruneWhere((ITextChannel)ctx.Channel, + result = await _service.PruneWhere((ITextChannel)ctx.Channel, count, x => !x.IsPinned && x.Id != progressMsg.Id, progress, opts.After); else - await _service.PruneWhere((ITextChannel)ctx.Channel, + result = await _service.PruneWhere((ITextChannel)ctx.Channel, count, x => x.Id != progressMsg.Id, progress, opts.After); + await SendResult(result); await progressMsg.DeleteAsync(); } @@ -155,9 +177,10 @@ public partial class Administration var progressMsg = await Response().Pending(strs.prune_progress(0, count)).SendAsync(); var progress = GetProgressTracker(progressMsg); + PruneResult result; if (opts.Safe) { - await _service.PruneWhere((ITextChannel)ctx.Channel, + result = await _service.PruneWhere((ITextChannel)ctx.Channel, count, m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks && !m.IsPinned, progress, @@ -166,7 +189,7 @@ public partial class Administration } else { - await _service.PruneWhere((ITextChannel)ctx.Channel, + result = await _service.PruneWhere((ITextChannel)ctx.Channel, count, m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks, progress, @@ -174,6 +197,7 @@ public partial class Administration ); } + await SendResult(result); await progressMsg.DeleteAsync(); } diff --git a/src/EllieBot/Modules/Administration/Prune/PruneResult.cs b/src/EllieBot/Modules/Administration/Prune/PruneResult.cs new file mode 100644 index 0000000..b6ac515 --- /dev/null +++ b/src/EllieBot/Modules/Administration/Prune/PruneResult.cs @@ -0,0 +1,9 @@ +#nullable disable +namespace EllieBot.Modules.Administration.Services; + +public enum PruneResult +{ + Success, + AlreadyRunning, + FeatureLimit, +} \ No newline at end of file diff --git a/src/EllieBot/Modules/Administration/Prune/PruneService.cs b/src/EllieBot/Modules/Administration/Prune/PruneService.cs index 006f9e8..753b56b 100644 --- a/src/EllieBot/Modules/Administration/Prune/PruneService.cs +++ b/src/EllieBot/Modules/Administration/Prune/PruneService.cs @@ -1,4 +1,6 @@ #nullable disable +using EllieBot.Modules.Patronage; + namespace EllieBot.Modules.Administration.Services; public class PruneService : IEService @@ -7,11 +9,15 @@ public class PruneService : IEService private readonly ConcurrentDictionary _pruningGuilds = new(); private readonly TimeSpan _twoWeeks = TimeSpan.FromDays(14); private readonly ILogCommandService _logService; + private readonly IPatronageService _ps; - public PruneService(ILogCommandService logService) - => _logService = logService; + public PruneService(ILogCommandService logService, IPatronageService ps) + { + _logService = logService; + _ps = ps; + } - public async Task PruneWhere( + public async Task PruneWhere( ITextChannel channel, int amount, Func predicate, @@ -26,8 +32,13 @@ public class PruneService : IEService using var cancelSource = new CancellationTokenSource(); if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource)) - return; + return PruneResult.AlreadyRunning; + if (!await _ps.LimitHitAsync(LimitedFeatureName.Prune, channel.Guild.OwnerId)) + { + return PruneResult.FeatureLimit; + } + try { var now = DateTime.UtcNow; @@ -47,7 +58,7 @@ public class PruneService : IEService .ToArray(); if (!msgs.Any()) - return; + return PruneResult.Success; lastMessage = msgs[^1]; @@ -88,6 +99,8 @@ public class PruneService : IEService { _pruningGuilds.TryRemove(channel.GuildId, out _); } + + return PruneResult.Success; } public async Task CancelAsync(ulong guildId) diff --git a/src/EllieBot/Modules/Administration/Role/IReactionRoleService.cs b/src/EllieBot/Modules/Administration/Role/IReactionRoleService.cs index 85f7945..771ceb0 100644 --- a/src/EllieBot/Modules/Administration/Role/IReactionRoleService.cs +++ b/src/EllieBot/Modules/Administration/Role/IReactionRoleService.cs @@ -18,7 +18,7 @@ public interface IReactionRoleService /// /// /// The result of the operation - Task> AddReactionRole( + Task> AddReactionRole( IGuild guild, IMessage msg, string emote, diff --git a/src/EllieBot/Modules/Administration/Role/ReactionRoleCommands.cs b/src/EllieBot/Modules/Administration/Role/ReactionRoleCommands.cs index 800512a..3a728ed 100644 --- a/src/EllieBot/Modules/Administration/Role/ReactionRoleCommands.cs +++ b/src/EllieBot/Modules/Administration/Role/ReactionRoleCommands.cs @@ -55,12 +55,10 @@ public partial class Administration await res.Match( _ => ctx.OkAsync(), - fl => + async fl => { _ = msg.RemoveReactionAsync(emote, ctx.Client.CurrentUser); - return !fl.IsPatronLimit - ? Response().Error(strs.limit_reached(fl.Quota)).SendAsync() - : Response().Pending(strs.feature_limit_reached_owner(fl.Quota, fl.Name)).SendAsync(); + await Response().Pending(strs.feature_limit_reached_owner).SendAsync(); }); } diff --git a/src/EllieBot/Modules/Administration/Role/ReactionRolesService.cs b/src/EllieBot/Modules/Administration/Role/ReactionRolesService.cs index f1216ef..cf36457 100644 --- a/src/EllieBot/Modules/Administration/Role/ReactionRolesService.cs +++ b/src/EllieBot/Modules/Administration/Role/ReactionRolesService.cs @@ -21,22 +21,16 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR private readonly SemaphoreSlim _assignementLock = new(1, 1); private readonly IPatronageService _ps; - private static readonly FeatureLimitKey _reroFLKey = new() - { - Key = "rero:max_count", - PrettyName = "Reaction Role" - }; - public ReactionRolesService( DiscordSocketClient client, + IPatronageService ps, DbService db, - IBotCredentials creds, - IPatronageService ps) + IBotCredentials creds) { _db = db; - _ps = ps; _client = client; _creds = creds; + _ps = ps; _cache = new(); } @@ -242,7 +236,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR /// /// /// The result of the operation - public async Task> AddReactionRole( + public async Task> AddReactionRole( IGuild guild, IMessage msg, string emote, @@ -261,9 +255,12 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR .Where(x => x.GuildId == guild.Id) .CountAsync(); - var result = await _ps.TryGetFeatureLimitAsync(_reroFLKey, guild.OwnerId, 50); - if (result.Quota != -1 && activeReactionRoles >= result.Quota) - return result; + var limit = await _ps.GetUserLimit(LimitedFeatureName.ReactionRole, guild.OwnerId); + + if (!_creds.IsOwner(guild.OwnerId) && (activeReactionRoles >= limit.Quota && limit.Quota >= 0)) + { + return new Error(); + } await ctx.GetTable() .InsertOrUpdateAsync(() => new()