Skip to content

Commit

Permalink
Merge pull request #515 from beanbeanjuice/514-fix-clear-command
Browse files Browse the repository at this point in the history
Fixed the Clear-Chat Command
  • Loading branch information
beanbeanjuice authored Sep 4, 2022
2 parents 9301c14 + f976e3b commit a3d9784
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,122 +2,44 @@

import com.beanbeanjuice.utility.command.CommandCategory;
import com.beanbeanjuice.utility.command.ICommand;
import com.beanbeanjuice.utility.handler.guild.CustomGuild;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.exceptions.ErrorHandler;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;

/**
* An {@link ICommand} used to clear a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}.
*
* @author beanbeanjuice
* @since v3.1.1
*/
public class ClearChatCommand implements ICommand {

@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
if (GuildHandler.getCustomGuild(event.getGuild()).containsTextChannelDeletingMessages(event.getTextChannel())) {
event.getHook().sendMessageEmbeds(alreadyDeletingMessagesEmbed()).queue();
return;
}

int amount = event.getOption("amount").getAsInt();

// Send message that it is deleting, save the message and exclude it from being deleted.
event.getHook().sendMessageEmbeds(beginDeletionEmbed(amount)).queue(e -> {

// +1 is needed because it removes the one just sent.
event.getChannel().getHistory().retrievePast(amount+1).queue(messages -> {
messages.remove(e);
startMessagesDeletions(new ArrayList<>(messages), e);
});
});
}

private MessageEmbed beginDeletionEmbed(@NotNull Integer amount) {
return new EmbedBuilder()
.setTitle("Starting Deletion")
.setColor(Helper.getRandomColor())
.setDescription("Deleting `" + amount + "` messages. This might take a while.")
.build();
}

private MessageEmbed alreadyDeletingMessagesEmbed() {
return new EmbedBuilder()
.setTitle("Already Deleting Messages")
.setDescription("You are already deleting messages in this channel. " +
"Please use this command in another channel or wait for this action to stop.")
.setColor(Color.red)
.build();
}

private void startMessagesDeletions(@NotNull ArrayList<Message> messages, @NotNull Message deletionMessage) {

Collections.reverse(messages);

TextChannel textChannel = deletionMessage.getTextChannel();
int messageCount = messages.size();
CustomGuild guild = GuildHandler.getCustomGuild(deletionMessage.getGuild());

guild.addTextChannelToDeletingMessages(deletionMessage.getTextChannel());

Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {

int count = 0;

@Override
public void run() {

Message message = messages.get(count++);

// Go through each message and delete it individually. Ignores the error response it might get.
message.delete().queue(null, new ErrorHandler().ignore(ErrorResponseException.class));

// If the messages is empty, cancel it.
if (count == messageCount) {
timer.cancel(); // Cancel the timer.
textChannel.sendMessageEmbeds(completedDeletionEmbed(messageCount)).queue(e -> {
try {
// Makes the thread sleep for 10 seconds.
Thread.sleep(10000);
} catch (InterruptedException ignored) {}

// Removes the current channel from channels having current deletions in it.
guild.removeTextChannelFromDeletingMessages(e.getTextChannel());
e.delete().queue();
});
}
}
};
timer.scheduleAtFixedRate(timerTask, 0, 50);
}

private MessageEmbed completedDeletionEmbed(@NotNull Integer count) {
return new EmbedBuilder()
.setTitle("Completed Deletion")
.setDescription("Successfully deleted `" + count + "` messages. " +
"There might be a time lag for deleting messages. This message will disappear once " +
"all of the messages have been successfully deleted from discord.")
.setColor(Helper.getRandomColor())
.build();
try {
event.getMessageChannel().getIterableHistory().takeAsync(amount)
.thenApply(messages -> event.getChannel().purgeMessages(messages));
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Deleting Messages",
"Attempting to delete `" + amount + "` messages. This might take a while..."
)).queue();
} catch (InsufficientPermissionException e) {
event.getHook().sendMessageEmbeds(Helper.errorEmbed(
"Error Deleting Messages",
"There was an error deleting your messages. The " +
"bot may have insufficient permissions. `" + e.getMessage() + "` " +
"Please click on my avatar and re-invite me to the server!"
)).queue();
}
}

@NotNull
Expand All @@ -136,8 +58,7 @@ public String exampleUsage() {
@Override
public ArrayList<OptionData> getOptions() {
ArrayList<OptionData> options = new ArrayList<>();
options.add(new OptionData(OptionType.INTEGER, "amount", "The number of messages to clear.", true, false)
.setRequiredRange(1, 99));
options.add(new OptionData(OptionType.INTEGER, "amount", "The number of messages to clear.", true));
return options;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ public class CustomGuild {
private Boolean notifyOnUpdate;
private Boolean aiState;

private final ArrayList<TextChannel> deletingMessagesChannels;

private final HashMap<CustomChannel, String> customChannelIDs;

/**
Expand Down Expand Up @@ -84,8 +82,6 @@ public CustomGuild(@NotNull String guildID, @NotNull String prefix, @NotNull Str
// Checks if a Listener has already been created for that guild.
// This is so that if the cache is reloaded, it does not need to recreate the Listeners.
TwitchHandler.addTwitchChannels(guildID, this.twitchChannels);

deletingMessagesChannels = new ArrayList<>();
}

/**
Expand Down Expand Up @@ -431,36 +427,6 @@ public Role getLiveNotificationsRole() {
return GuildHandler.getGuild(guildID).getRoleById(liveNotificationsRoleID);
}

/**
* Remove a {@link TextChannel} from the list of currently deleting {@link Message}s.
*
* @param channel The {@link TextChannel} to remove.
*/
public void removeTextChannelFromDeletingMessages(@NotNull TextChannel channel) {
deletingMessagesChannels.remove(channel);
}

/**
* Add a {@link TextChannel} to the list of currently deleting {@link Message}s.
*
* @param channel The {@link TextChannel} to add.
*/
public void addTextChannelToDeletingMessages(@NotNull TextChannel channel) {
deletingMessagesChannels.add(channel);
}

/**
* Checks to make sure that a {@link TextChannel} does not already have {@link Message}s being
* currently deleted.
*
* @param channel The {@link TextChannel} to check.
* @return True, if it already has {@link Message}s being deleted in it.
*/
@NotNull
public Boolean containsTextChannelDeletingMessages(@NotNull TextChannel channel) {
return deletingMessagesChannels.contains(channel);
}

/**
* @return The {@link String} ID of the live channel to send messages.
*/
Expand Down

0 comments on commit a3d9784

Please sign in to comment.