mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
add: Added .cleanupguilddata command which will delete all guildconfigs, xp stats and other data related to any guild the bot is no longer in. This is a highly destructive and irreversible command.
dev: Added cascade deletes to any tables which have guildconfigs FK, as well as to some other missing places
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
namespace NadekoBot.Modules.Administration.DangerousCommands;
|
||||
|
||||
public partial class Administration
|
||||
{
|
||||
[Group]
|
||||
public class CleanupCommands : CleanupModuleBase
|
||||
{
|
||||
private readonly ICleanupService _svc;
|
||||
|
||||
public CleanupCommands(ICleanupService svc)
|
||||
=> _svc = svc;
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
[RequireContext(ContextType.DM)]
|
||||
public async Task CleanupGuildData()
|
||||
{
|
||||
var result = await _svc.DeleteMissingGuildDataAsync();
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
await ctx.ErrorAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await Response()
|
||||
.Confirm($"{result.GuildCount} guilds' data remain in the database.")
|
||||
.SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
using LinqToDB;
|
||||
using LinqToDB.Data;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.DangerousCommands;
|
||||
|
||||
public sealed class CleanupService : ICleanupService, IReadyExecutor, INService
|
||||
{
|
||||
private readonly IPubSub _pubSub;
|
||||
private TypedKey<KeepReport> _keepReportKey = new("cleanup:report");
|
||||
private TypedKey<bool> _keepTriggerKey = new("cleanup:trigger");
|
||||
private readonly DiscordSocketClient _client;
|
||||
private ConcurrentDictionary<int, ulong[]> guildIds;
|
||||
private readonly IBotCredsProvider _creds;
|
||||
private readonly DbService _db;
|
||||
|
||||
public CleanupService(
|
||||
IPubSub pubSub,
|
||||
DiscordSocketClient client,
|
||||
IBotCredsProvider creds,
|
||||
DbService db)
|
||||
{
|
||||
_pubSub = pubSub;
|
||||
_client = client;
|
||||
_creds = creds;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public async Task<KeepResult?> DeleteMissingGuildDataAsync()
|
||||
{
|
||||
guildIds = new();
|
||||
var totalShards = _creds.GetCreds().TotalShards;
|
||||
await _pubSub.Pub(_keepTriggerKey, true);
|
||||
var counter = 0;
|
||||
while (guildIds.Keys.Count < totalShards)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
counter++;
|
||||
|
||||
if (counter >= 5)
|
||||
break;
|
||||
}
|
||||
|
||||
if (guildIds.Keys.Count < totalShards)
|
||||
return default;
|
||||
|
||||
var allIds = guildIds.SelectMany(x => x.Value)
|
||||
.ToArray();
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await using var linqCtx = ctx.CreateLinqToDBContext();
|
||||
await using var tempTable = linqCtx.CreateTempTable<CleanupId>();
|
||||
|
||||
foreach (var chunk in allIds.Chunk(20000))
|
||||
{
|
||||
await tempTable.BulkCopyAsync(chunk.Select(x => new CleanupId()
|
||||
{
|
||||
GuildId = x
|
||||
}));
|
||||
}
|
||||
|
||||
await ctx.GetTable<GuildConfig>()
|
||||
.Where(x => !tempTable.Select(x => x.GuildId)
|
||||
.Contains(x.GuildId))
|
||||
.DeleteAsync();
|
||||
|
||||
|
||||
await ctx.GetTable<UserXpStats>()
|
||||
.Where(x => !tempTable.Select(x => x.GuildId)
|
||||
.Contains(x.GuildId))
|
||||
.DeleteAsync();
|
||||
|
||||
return new()
|
||||
{
|
||||
GuildCount = guildIds.Keys.Count,
|
||||
};
|
||||
}
|
||||
|
||||
private ValueTask OnKeepReport(KeepReport report)
|
||||
{
|
||||
guildIds[report.ShardId] = report.GuildIds;
|
||||
return default;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await _pubSub.Sub(_keepTriggerKey, OnKeepTrigger);
|
||||
|
||||
if (_client.ShardId == 0)
|
||||
await _pubSub.Sub(_keepReportKey, OnKeepReport);
|
||||
}
|
||||
|
||||
private ValueTask OnKeepTrigger(bool arg)
|
||||
{
|
||||
_pubSub.Pub(_keepReportKey,
|
||||
new KeepReport()
|
||||
{
|
||||
ShardId = _client.ShardId,
|
||||
GuildIds = _client.GetGuildIds(),
|
||||
});
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.DangerousCommands;
|
||||
|
||||
public sealed class CleanupId
|
||||
{
|
||||
[Key]
|
||||
public ulong GuildId { get; set; }
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
namespace NadekoBot.Modules.Administration.DangerousCommands;
|
||||
|
||||
public interface ICleanupService
|
||||
{
|
||||
Task<KeepResult?> DeleteMissingGuildDataAsync();
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
namespace NadekoBot.Modules.Administration.DangerousCommands;
|
||||
|
||||
public sealed class KeepReport
|
||||
{
|
||||
public required int ShardId { get; init; }
|
||||
public required ulong[] GuildIds { get; init; }
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
namespace NadekoBot.Modules.Administration.DangerousCommands;
|
||||
|
||||
public sealed class KeepResult
|
||||
{
|
||||
public required int GuildCount { get; init; }
|
||||
}
|
@@ -489,17 +489,9 @@ public sealed partial class Help : NadekoModule<HelpService>
|
||||
|
||||
**Step 3** ⏰ Wait a short while (usually 1-3 minutes) ⏰
|
||||
|
||||
Nadeko will DM you the welcome instructions, and you may will receive your rewards!
|
||||
Nadeko will DM you the welcome instructions, and you will receive your rewards!
|
||||
🎉 **Enjoy!** 🎉
|
||||
""")
|
||||
.AddField("Troubleshooting",
|
||||
"""
|
||||
*In case you didn't receive the rewards within 5 minutes:*
|
||||
`1.` Make sure your DMs are open to everyone. Maybe your pledge was processed successfully but the bot was unable to DM you. Use the `.patron` command to check your status.
|
||||
`2.` Make sure you've connected the CORRECT Discord account. Quite often users log in to different Discord accounts in their browser. You may also try disconnecting and reconnecting your account.
|
||||
`3.` Make sure your payment has been processed and not declined by Patreon.
|
||||
`4.` If any of the previous steps don't help, you can join the nadeko support server <https://discord.nadeko.bot> and ask for help in the #help channel
|
||||
""");
|
||||
""");
|
||||
|
||||
try
|
||||
{
|
||||
|
Reference in New Issue
Block a user