This commit is contained in:
Kwoth
2024-06-13 18:54:21 +00:00
parent a6adf73ecf
commit ab93380d7c
80 changed files with 12076 additions and 1694 deletions

View File

@@ -61,17 +61,66 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, INService
}));
}
// delete guild configs
await ctx.GetTable<GuildConfig>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete guild xp
await ctx.GetTable<UserXpStats>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete expressions
await ctx.GetTable<NadekoExpression>()
.Where(x => x.GuildId != null && !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId.Value))
.DeleteAsync();
// delete quotes
await ctx.GetTable<Quote>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete planted currencies
await ctx.GetTable<PlantedCurrency>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete image only channels
await ctx.GetTable<ImageOnlyChannel>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete reaction roles
await ctx.GetTable<ReactionRoleV2>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete ignored users
await ctx.GetTable<DiscordPermOverride>()
.Where(x => x.GuildId != null && !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId.Value))
.DeleteAsync();
// delete perm overrides
await ctx.GetTable<DiscordPermOverride>()
.Where(x => x.GuildId != null && !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId.Value))
.DeleteAsync();
// delete repeaters
await ctx.GetTable<Repeater>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
return new()
{
GuildCount = guildIds.Keys.Count,

View File

@@ -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();
}

View File

@@ -0,0 +1,9 @@
#nullable disable
namespace NadekoBot.Modules.Administration.Services;
public enum PruneResult
{
Success,
AlreadyRunning,
FeatureLimit,
}

View File

@@ -1,4 +1,6 @@
#nullable disable
using NadekoBot.Modules.Patronage;
namespace NadekoBot.Modules.Administration.Services;
public class PruneService : INService
@@ -7,11 +9,15 @@ public class PruneService : INService
private readonly ConcurrentDictionary<ulong, CancellationTokenSource> _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<PruneResult> PruneWhere(
ITextChannel channel,
int amount,
Func<IMessage, bool> predicate,
@@ -26,8 +32,13 @@ public class PruneService : INService
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 : INService
.ToArray();
if (!msgs.Any())
return;
return PruneResult.Success;
lastMessage = msgs[^1];
@@ -88,6 +99,8 @@ public class PruneService : INService
{
_pruningGuilds.TryRemove(channel.GuildId, out _);
}
return PruneResult.Success;
}
public async Task<bool> CancelAsync(ulong guildId)

View File

@@ -18,7 +18,7 @@ public interface IReactionRoleService
/// <param name="group"></param>
/// <param name="levelReq"></param>
/// <returns>The result of the operation</returns>
Task<OneOf<Success, FeatureLimit>> AddReactionRole(
Task<OneOf<Success, Error>> AddReactionRole(
IGuild guild,
IMessage msg,
string emote,

View File

@@ -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();
});
}

View File

@@ -21,22 +21,16 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, 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, INService, IReactionR
/// <param name="group"></param>
/// <param name="levelReq"></param>
/// <returns>The result of the operation</returns>
public async Task<OneOf<Success, FeatureLimit>> AddReactionRole(
public async Task<OneOf<Success, Error>> AddReactionRole(
IGuild guild,
IMessage msg,
string emote,
@@ -260,10 +254,13 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, IReactionR
var activeReactionRoles = await ctx.GetTable<ReactionRoleV2>()
.Where(x => x.GuildId == guild.Id)
.CountAsync();
var limit = await _ps.GetUserLimit(LimitedFeatureName.ReactionRole, guild.OwnerId);
var result = await _ps.TryGetFeatureLimitAsync(_reroFLKey, guild.OwnerId, 50);
if (result.Quota != -1 && activeReactionRoles >= result.Quota)
return result;
if (!_creds.IsOwner(guild.OwnerId) && (activeReactionRoles >= limit.Quota && limit.Quota >= 0))
{
return new Error();
}
await ctx.GetTable<ReactionRoleV2>()
.InsertOrUpdateAsync(() => new()