From 03a6f8080997183eaf3ea04f5f5ff24bf6cfdac2 Mon Sep 17 00:00:00 2001 From: Yusuf Date: Thu, 28 Oct 2021 11:14:10 +0100 Subject: [PATCH 1/5] Getting started --- .gitignore | 1 + .../togetherjava/tjbot/commands/moderation/purgeCommand.java | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java diff --git a/.gitignore b/.gitignore index 0ce9cdb2ce..f24a747936 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,4 @@ logviewer/types.d.ts logviewer/pnpm-lock.yaml logviewer/webpack.config.js logviewer/webpack.generated.js +.DS_Store diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java new file mode 100644 index 0000000000..d4e75bff3f --- /dev/null +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java @@ -0,0 +1,4 @@ +package org.togetherjava.tjbot.commands.moderation; + +public class purgeCommand { +} From 878a8ca81b61c03df3847ac66fd4bbe912f52df5 Mon Sep 17 00:00:00 2001 From: Yusuf Date: Fri, 29 Oct 2021 11:15:03 +0100 Subject: [PATCH 2/5] added purge command --- .../togetherjava/tjbot/commands/Commands.java | 3 +- .../commands/moderation/PurgeCommand.java | 77 +++++++++++++++++++ .../commands/moderation/purgeCommand.java | 4 - 3 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java delete mode 100644 application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/Commands.java b/application/src/main/java/org/togetherjava/tjbot/commands/Commands.java index 3961b19ed8..b0dfb0f9f9 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/Commands.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/Commands.java @@ -4,6 +4,7 @@ import org.togetherjava.tjbot.commands.basic.DatabaseCommand; import org.togetherjava.tjbot.commands.basic.PingCommand; import org.togetherjava.tjbot.commands.mathcommands.TeXCommand; +import org.togetherjava.tjbot.commands.moderation.PurgeCommand; import org.togetherjava.tjbot.commands.tags.TagCommand; import org.togetherjava.tjbot.commands.tags.TagManageCommand; import org.togetherjava.tjbot.commands.tags.TagSystem; @@ -41,6 +42,6 @@ public enum Commands { // available. return List.of(new PingCommand(), new DatabaseCommand(database), new TeXCommand(), new TagCommand(tagSystem), new TagManageCommand(tagSystem), - new TagsCommand(tagSystem)); + new TagsCommand(tagSystem), new PurgeCommand()); } } diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java new file mode 100644 index 0000000000..fcdd7ca39e --- /dev/null +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java @@ -0,0 +1,77 @@ +package org.togetherjava.tjbot.commands.moderation; + +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.togetherjava.tjbot.commands.SlashCommandAdapter; +import org.togetherjava.tjbot.commands.SlashCommandVisibility; + +import java.util.Objects; + +/** + * This command requires the user to + */ +public class PurgeCommand extends SlashCommandAdapter { + private static final Logger logger = LoggerFactory.getLogger(PurgeCommand.class); + private static final String FIRST_MESSAGE_ID = "first_message_id"; + private static final String LAST_MESSAGE_ID = "last_message_id"; + + + public PurgeCommand() { + super("purge", "Delete specific messages using there ids.", SlashCommandVisibility.GUILD); + + getData() + .addOption(OptionType.NUMBER, FIRST_MESSAGE_ID, + "The id of the message you want to delete from.", true) + .addOption(OptionType.NUMBER, LAST_MESSAGE_ID, + "The id of the message you want to delete to.", true); + } + + @Override + public void onSlashCommand(@NotNull SlashCommandEvent event) { + final Member author = event.getMember(); + final TextChannel channel = event.getTextChannel(); + + if (!Objects.requireNonNull(author).hasPermission(Permission.MESSAGE_MANAGE)) { + event.reply("You are missing MESSAGE_MANAGE permission to delete these the message") + .setEphemeral(true) + .queue(); + return; + } + + final Member bot = Objects.requireNonNull(event.getGuild()).getSelfMember(); + if (!bot.hasPermission(Permission.MESSAGE_MANAGE)) { + event.reply( + "I am missing MESSAGE_MANAGE permission which means I am unable to delete messages in this server.") + .setEphemeral(true) + .queue(); + + logger.error("The bot does not have MESSAGE_MANAGE permission on the server '{}' ", + event.getGuild().getId()); + return; + } + + long firstMessageId = Objects.requireNonNull(event.getOption(FIRST_MESSAGE_ID)).getAsLong(); + long lastMessageId = Objects.requireNonNull(event.getOption(LAST_MESSAGE_ID)).getAsLong(); + + deleteMessagesById(channel, author, firstMessageId, lastMessageId, event); + } + + public static void deleteMessagesById(@NotNull TextChannel channel, @NotNull Member author, + long firstMessageId, long lastMessageId, @NotNull SlashCommandEvent event) { + + channel.purgeMessagesById(firstMessageId, lastMessageId); + + event.reply("I have deleted the messages from " + firstMessageId + " to " + lastMessageId) + .setEphemeral(true) + .queue(); + + logger.info(" '{}' deleted messages from '{}' till '{}", author, firstMessageId, + lastMessageId); + } +} diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java deleted file mode 100644 index d4e75bff3f..0000000000 --- a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/purgeCommand.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.togetherjava.tjbot.commands.moderation; - -public class purgeCommand { -} From b7f4ae79abb900ff2837d41a3c009c441a8b1c20 Mon Sep 17 00:00:00 2001 From: Yusuf Date: Fri, 29 Oct 2021 11:19:07 +0100 Subject: [PATCH 3/5] Update PurgeCommand.java --- .../tjbot/commands/moderation/PurgeCommand.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java index fcdd7ca39e..2f24dfb550 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java @@ -14,7 +14,11 @@ import java.util.Objects; /** - * This command requires the user to + * This command can remove specific messages using their ids. The command requires the user to input + * the id of message they want to delete from and the id of the messages they want to delete to. + *

+ * The command fails if one of the message id that was given is invalid or the user lacks the + * permission to delete messages. */ public class PurgeCommand extends SlashCommandAdapter { private static final Logger logger = LoggerFactory.getLogger(PurgeCommand.class); From c4f5e54c22dcb25663d04c94f05de737e08d2478 Mon Sep 17 00:00:00 2001 From: Yusuf Date: Sat, 30 Oct 2021 13:19:00 +0100 Subject: [PATCH 4/5] Update PurgeCommand.java --- .../commands/moderation/PurgeCommand.java | 71 +++++++++++++------ 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java index 2f24dfb550..872d2100fd 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java @@ -1,7 +1,9 @@ package org.togetherjava.tjbot.commands.moderation; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; import net.dv8tion.jda.api.interactions.commands.OptionType; @@ -11,7 +13,12 @@ import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.commands.SlashCommandVisibility; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; +import java.util.stream.Collectors; /** * This command can remove specific messages using their ids. The command requires the user to input @@ -21,6 +28,7 @@ * permission to delete messages. */ public class PurgeCommand extends SlashCommandAdapter { + // TODO Test the command private static final Logger logger = LoggerFactory.getLogger(PurgeCommand.class); private static final String FIRST_MESSAGE_ID = "first_message_id"; private static final String LAST_MESSAGE_ID = "last_message_id"; @@ -30,30 +38,29 @@ public PurgeCommand() { super("purge", "Delete specific messages using there ids.", SlashCommandVisibility.GUILD); getData() - .addOption(OptionType.NUMBER, FIRST_MESSAGE_ID, - "The id of the message you want to delete from.", true) - .addOption(OptionType.NUMBER, LAST_MESSAGE_ID, - "The id of the message you want to delete to.", true); + .addOption(OptionType.NUMBER, FIRST_MESSAGE_ID, + "The id of the message you want to delete from.", true) + .addOption(OptionType.NUMBER, LAST_MESSAGE_ID, + "The id of the message you want to delete to.", true); } @Override public void onSlashCommand(@NotNull SlashCommandEvent event) { final Member author = event.getMember(); - final TextChannel channel = event.getTextChannel(); - if (!Objects.requireNonNull(author).hasPermission(Permission.MESSAGE_MANAGE)) { + if (!author.hasPermission(Permission.MESSAGE_MANAGE)) { event.reply("You are missing MESSAGE_MANAGE permission to delete these the message") - .setEphemeral(true) - .queue(); + .setEphemeral(true) + .queue(); return; } final Member bot = Objects.requireNonNull(event.getGuild()).getSelfMember(); if (!bot.hasPermission(Permission.MESSAGE_MANAGE)) { event.reply( - "I am missing MESSAGE_MANAGE permission which means I am unable to delete messages in this server.") - .setEphemeral(true) - .queue(); + "I am missing MESSAGE_MANAGE permission which means I am unable to delete messages in this server.") + .setEphemeral(true) + .queue(); logger.error("The bot does not have MESSAGE_MANAGE permission on the server '{}' ", event.getGuild().getId()); @@ -63,19 +70,39 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) { long firstMessageId = Objects.requireNonNull(event.getOption(FIRST_MESSAGE_ID)).getAsLong(); long lastMessageId = Objects.requireNonNull(event.getOption(LAST_MESSAGE_ID)).getAsLong(); - deleteMessagesById(channel, author, firstMessageId, lastMessageId, event); - } - - public static void deleteMessagesById(@NotNull TextChannel channel, @NotNull Member author, - long firstMessageId, long lastMessageId, @NotNull SlashCommandEvent event) { + deleteMessagesById(firstMessageId, lastMessageId, event.getMessageChannel(), strings -> { - channel.purgeMessagesById(firstMessageId, lastMessageId); + }); + } - event.reply("I have deleted the messages from " + firstMessageId + " to " + lastMessageId) - .setEphemeral(true) - .queue(); + private static void deleteMessagesById(long firstMessageId, long lastMessageId, + MessageChannel mc, Consumer> cb) { + getBetween0(firstMessageId, lastMessageId, mc, new ArrayList<>(), new ReentrantLock(), cb); + } - logger.info(" '{}' deleted messages from '{}' till '{}", author, firstMessageId, - lastMessageId); + private static void getBetween0(long firstMessageId, long lastMessageId, MessageChannel mc, + List acc, ReentrantLock lock, Consumer> cb) { + mc.getHistoryBefore(firstMessageId, 100).queue(his -> { + try { + lock.lock(); + List collected = his.getRetrievedHistory() + .stream() + .map(ISnowflake::getId) + .collect(Collectors.toList()); + + int foundIdx = collected.indexOf(String.valueOf(lastMessageId)); + + if (foundIdx != -1) { + acc.addAll(collected.subList(0, foundIdx)); + cb.accept(acc); + } else { + acc.addAll(collected); + getBetween0(Long.parseLong(collected.get(collected.size() - 1)), lastMessageId, + mc, acc, lock, cb); + } + } finally { + lock.unlock(); + } + }); } } From af6a6ad64a17318f84d9b528eebdae7d2228bea5 Mon Sep 17 00:00:00 2001 From: Yusuf Date: Sat, 30 Oct 2021 13:24:41 +0100 Subject: [PATCH 5/5] spotlessApply --- .../commands/moderation/PurgeCommand.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java index 872d2100fd..367285a6e0 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/PurgeCommand.java @@ -38,10 +38,10 @@ public PurgeCommand() { super("purge", "Delete specific messages using there ids.", SlashCommandVisibility.GUILD); getData() - .addOption(OptionType.NUMBER, FIRST_MESSAGE_ID, - "The id of the message you want to delete from.", true) - .addOption(OptionType.NUMBER, LAST_MESSAGE_ID, - "The id of the message you want to delete to.", true); + .addOption(OptionType.NUMBER, FIRST_MESSAGE_ID, + "The id of the message you want to delete from.", true) + .addOption(OptionType.NUMBER, LAST_MESSAGE_ID, + "The id of the message you want to delete to.", true); } @Override @@ -50,17 +50,17 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) { if (!author.hasPermission(Permission.MESSAGE_MANAGE)) { event.reply("You are missing MESSAGE_MANAGE permission to delete these the message") - .setEphemeral(true) - .queue(); + .setEphemeral(true) + .queue(); return; } final Member bot = Objects.requireNonNull(event.getGuild()).getSelfMember(); if (!bot.hasPermission(Permission.MESSAGE_MANAGE)) { event.reply( - "I am missing MESSAGE_MANAGE permission which means I am unable to delete messages in this server.") - .setEphemeral(true) - .queue(); + "I am missing MESSAGE_MANAGE permission which means I am unable to delete messages in this server.") + .setEphemeral(true) + .queue(); logger.error("The bot does not have MESSAGE_MANAGE permission on the server '{}' ", event.getGuild().getId()); @@ -76,19 +76,19 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) { } private static void deleteMessagesById(long firstMessageId, long lastMessageId, - MessageChannel mc, Consumer> cb) { + MessageChannel mc, Consumer> cb) { getBetween0(firstMessageId, lastMessageId, mc, new ArrayList<>(), new ReentrantLock(), cb); } private static void getBetween0(long firstMessageId, long lastMessageId, MessageChannel mc, - List acc, ReentrantLock lock, Consumer> cb) { + List acc, ReentrantLock lock, Consumer> cb) { mc.getHistoryBefore(firstMessageId, 100).queue(his -> { try { lock.lock(); List collected = his.getRetrievedHistory() - .stream() - .map(ISnowflake::getId) - .collect(Collectors.toList()); + .stream() + .map(ISnowflake::getId) + .collect(Collectors.toList()); int foundIdx = collected.indexOf(String.valueOf(lastMessageId));