ProjectMakoto/ProjectMakoto/Commands/Moderation/GuildPurgeCommand.cs

157 lines
No EOL
6.7 KiB
C#

// Project Makoto
// Copyright (C) 2024 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
namespace ProjectMakoto.Commands;
internal sealed class GuildPurgeCommand : BaseCommand
{
public override async Task<bool> BeforeExecution(SharedCommandContext ctx) => (await this.CheckPermissions(Permissions.ManageMessages) && await this.CheckPermissions(Permissions.ManageChannels) && await this.CheckOwnPermissions(Permissions.ManageMessages));
public override Task ExecuteCommand(SharedCommandContext ctx, Dictionary<string, object> arguments)
{
return Task.Run(async () =>
{
var CommandKey = this.t.Commands.Moderation.GuildPurge;
var number = (int)arguments["number"];
var victim = (DiscordUser)arguments["user"];
if (await ctx.DbUser.Cooldown.WaitForHeavy(ctx))
return;
if (number is > 2000 or < 1)
{
this.SendSyntaxError();
return;
}
_ = await this.RespondOrEdit(new DiscordMessageBuilder().AddEmbed(new DiscordEmbedBuilder().
WithDescription(this.GetString(CommandKey.Scanning, true, new TVar("Victim", victim.Mention)))
.AsLoading(ctx)));
var currentProg = 0;
var maxProg = ctx.Guild.Channels.Count;
var allMsg = 0;
Dictionary<ulong, List<DiscordMessage>> channelList = new();
foreach (var channel in ctx.Guild.Channels.Where(x => x.Value.Type is ChannelType.Text or ChannelType.PublicThread or ChannelType.PrivateThread or ChannelType.News or ChannelType.Voice))
{
allMsg = 0;
foreach (var b in channelList)
allMsg += b.Value.Count;
currentProg++;
_ = await this.RespondOrEdit(new DiscordMessageBuilder().AddEmbed(new DiscordEmbedBuilder().
WithDescription($"{this.GetString(CommandKey.Scanning, true, new TVar("Victim", victim.Mention))}\n" +
$"`{StringTools.GenerateASCIIProgressbar(currentProg, maxProg)} {MathTools.CalculatePercentage(currentProg, maxProg),3}%`")
.AsLoading(ctx)));
var MessageInt = number;
List<DiscordMessage> requested_messages = new();
var pre_request = await channel.Value.GetMessagesAsync(1);
if (pre_request.Count > 0)
{
requested_messages.Add(pre_request[0]);
MessageInt -= 1;
}
while (true)
{
if (pre_request.Count == 0)
break;
if (MessageInt <= 0)
break;
if (MessageInt > 100)
{
var current_request = await channel.Value.GetMessagesBeforeAsync(requested_messages.Last().Id, 100);
if (current_request.Count == 0)
break;
foreach (var b in current_request)
requested_messages.Add(b);
MessageInt -= 100;
}
else
{
var current_request = await channel.Value.GetMessagesBeforeAsync(requested_messages.Last().Id, MessageInt);
if (current_request.Count == 0)
break;
foreach (var b in current_request)
requested_messages.Add(b);
MessageInt -= MessageInt;
}
}
if (requested_messages.Count > 0)
foreach (var b in requested_messages.ToList())
{
if (b.Author.Id == victim.Id && b.CreationTimestamp.AddDays(14) > DateTime.UtcNow)
{
if (!channelList.ContainsKey(channel.Key))
channelList.Add(channel.Key, new List<DiscordMessage>());
channelList[channel.Key].Add(b);
}
}
}
foreach (var channel in channelList)
foreach (var message in channel.Value.ToList())
if (message.CreationTimestamp.GetTimespanSince() > TimeSpan.FromDays(14))
_ = channel.Value.Remove(message);
_ = await this.RespondOrEdit(new DiscordMessageBuilder().AddEmbed(new DiscordEmbedBuilder()
.WithDescription($"{this.GetString(CommandKey.Deleting, true, new TVar("Victim", victim.Mention), new TVar("Count", allMsg))}\n" +
$"`{StringTools.GenerateASCIIProgressbar(currentProg, maxProg)} {MathTools.CalculatePercentage(currentProg, maxProg)}%`")
.AsLoading(ctx)));
currentProg = 0;
maxProg = 0;
foreach (var channel in channelList)
maxProg += channel.Value.Count;
foreach (var channel in channelList)
{
try
{
_ = await this.RespondOrEdit(new DiscordMessageBuilder().AddEmbed(new DiscordEmbedBuilder()
.WithDescription($"{this.GetString(CommandKey.Deleting, true, new TVar("Victim", victim.Mention), new TVar("Count", allMsg))}\n" +
$"`{StringTools.GenerateASCIIProgressbar(currentProg, maxProg)} {MathTools.CalculatePercentage(currentProg, maxProg)}%`")
.AsLoading(ctx)));
while (channel.Value.Count > 0)
{
var msgs = channel.Value.Take(100).ToList();
await ctx.Guild.GetChannel(channel.Key).DeleteMessagesAsync(msgs);
channel.Value.RemoveRange(0, msgs.Count);
currentProg += msgs.Count;
}
}
catch { }
}
_ = await this.RespondOrEdit(new DiscordMessageBuilder().AddEmbed(new DiscordEmbedBuilder()
.WithDescription(this.GetString(CommandKey.Ended, true, new TVar("Victim", victim.Mention), new TVar("Min", currentProg), new TVar("Max", maxProg), new TVar("ChannelCount", channelList.Count)))
.AsSuccess(ctx)));
});
}
}