Skip to content

Commit 47e115c

Browse files
committed
improve purge command
1 parent 5340c80 commit 47e115c

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

src/main/java/net/javadiscord/javabot/systems/moderation/PurgeCommand.java

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.dv8tion.jda.api.entities.*;
44
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
55
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
6+
import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion;
67
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
78
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
89
import net.dv8tion.jda.api.interactions.commands.OptionType;
@@ -27,7 +28,10 @@
2728
import java.time.OffsetDateTime;
2829
import java.time.format.DateTimeFormatter;
2930
import java.util.List;
31+
import java.util.Map;
32+
import java.util.Map.Entry;
3033
import java.util.concurrent.ExecutorService;
34+
import java.util.stream.Collectors;
3135

3236
/**
3337
* <h3>This class represents the /purge command.</h3>
@@ -60,7 +64,7 @@ protected ReplyCallbackAction handleModerationCommand(@NotNull SlashCommandInter
6064
boolean archive = event.getOption("archive", true, OptionMapping::getAsBoolean);
6165

6266
ModerationConfig config = botConfig.get(event.getGuild()).getModerationConfig();
63-
Long amount = (amountOption == null) ? null : amountOption.getAsLong();
67+
Long amount = (amountOption == null) ? 1 : amountOption.getAsLong();
6468
User user = (userOption == null) ? null : userOption.getAsUser();
6569
int maxAmount = config.getPurgeMaxMessageCount();
6670
if (amount == null || amount < 1 || amount > maxAmount) {
@@ -87,7 +91,7 @@ protected ReplyCallbackAction handleModerationCommand(@NotNull SlashCommandInter
8791
* @param channel The channel to remove messages from.
8892
* @param logChannel The channel to write log messages to during the purge.
8993
*/
90-
private void purge(@Nullable Long amount, @Nullable User user, User initiatedBy, boolean archive, MessageChannel channel, TextChannel logChannel) {
94+
private void purge(long amount, @Nullable User user, User initiatedBy, boolean archive, MessageChannel channel, TextChannel logChannel) {
9195
MessageHistory history = channel.getHistory();
9296
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
9397
String file = String.format("purge_%s_%s.txt", channel.getName(), timestamp);
@@ -97,19 +101,25 @@ private void purge(@Nullable Long amount, @Nullable User user, User initiatedBy,
97101
long count = 0;
98102
logChannel.sendMessageFormat("Starting purge of channel %s, initiated by %s", channel.getAsMention(), initiatedBy.getAsMention())
99103
.queue();
104+
int lastEmptyIterations = 0;
100105
do {
101-
messages = history.retrievePast(amount == null ? 100 : (int) Math.min(100, amount)).complete();
106+
messages = history.retrievePast((int) Math.min(100, user==null ? amount : Math.max(amount, 10))).complete();
102107
if (!messages.isEmpty()) {
103-
int messagesRemoved = removeMessages(messages, user, archiveWriter);
108+
int messagesRemoved = removeMessages(messages, user, archiveWriter, amount - count);
104109
count += messagesRemoved;
105110
logChannel.sendMessage(String.format(
106111
"Removed **%d** messages from %s; a total of **%d** messages have been removed in this purge so far.",
107112
messagesRemoved,
108113
channel.getAsMention(),
109114
count
110115
)).queue();
116+
if (messagesRemoved == 0) {
117+
lastEmptyIterations++;
118+
}else {
119+
lastEmptyIterations = 0;
120+
}
111121
}
112-
} while (!messages.isEmpty() && (amount == null || amount > count));
122+
} while (!messages.isEmpty() && amount > count && lastEmptyIterations <= 20);
113123
if (archiveWriter != null) {
114124
archiveWriter.close();
115125
}
@@ -133,20 +143,27 @@ private void purge(@Nullable Long amount, @Nullable User user, User initiatedBy,
133143
* @param messages The messages to remove.
134144
* @param user The user to remove messages for.
135145
* @param archiveWriter The writer to write message archive info to.
146+
* @param max The maximum number of messages to delete
136147
* @return The number of messages that were actually deleted.
137148
*/
138-
private int removeMessages(List<Message> messages, @Nullable User user, @Nullable PrintWriter archiveWriter) {
139-
int messagesRemoved = 0;
140-
for (Message msg : messages) {
141-
if (user == null || msg.getAuthor().equals(user)) {
142-
msg.delete().complete();
143-
messagesRemoved++;
144-
if (archiveWriter != null) {
149+
private int removeMessages(List<Message> messages, @Nullable User user, @Nullable PrintWriter archiveWriter, long max) {
150+
Map<MessageChannelUnion, List<Message>> toRemove = messages
151+
.stream()
152+
.filter(msg -> user == null || msg.getAuthor().equals(user))
153+
.limit(max)
154+
.collect(Collectors.groupingBy(Message::getChannel));
155+
int count = 0;
156+
if (archiveWriter != null) {
157+
for (Entry<MessageChannelUnion, List<Message>> entry : toRemove.entrySet()) {
158+
List<Message> msgs = entry.getValue();
159+
count += msgs.size();
160+
for (Message msg : msgs) {
145161
archiveMessage(archiveWriter, msg);
146162
}
163+
entry.getKey().purgeMessages(messages);
147164
}
148165
}
149-
return messagesRemoved;
166+
return count;
150167
}
151168

152169
/**

0 commit comments

Comments
 (0)