diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java index 5a0ea867b..6c5e25112 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java @@ -183,6 +183,10 @@ public class JDADiscordService implements DiscordService { updateTypesRelay(); + // We will see you in the future :balloon: + // DiscordUtil.cleanWebhooks(guild, DiscordUtil.CONSOLE_RELAY_NAME); + // DiscordUtil.cleanWebhooks(guild, DiscordUtil.ADVANCED_RELAY_NAME); + Bukkit.getPluginManager().registerEvents(new BukkitListener(this), plugin); try { @@ -271,9 +275,7 @@ public class JDADiscordService implements DiscordService { continue; } - final String webhookName = "EssX Advanced Relay"; - Webhook webhook = DiscordUtil.getAndCleanWebhooks(channel, webhookName).join(); - webhook = webhook == null ? DiscordUtil.createWebhook(channel, webhookName).join() : webhook; + final Webhook webhook = DiscordUtil.getOrCreateWebhook(channel, DiscordUtil.ADVANCED_RELAY_NAME).join(); if (webhook == null) { final WebhookClient current = channelIdToWebhook.get(channel.getId()); if (current != null) { @@ -317,9 +319,7 @@ public class JDADiscordService implements DiscordService { return; } - final String webhookName = "EssX Console Relay"; - Webhook webhook = DiscordUtil.getAndCleanWebhooks(channel, webhookName).join(); - webhook = webhook == null ? DiscordUtil.createWebhook(channel, webhookName).join() : webhook; + final Webhook webhook = DiscordUtil.getOrCreateWebhook(channel, DiscordUtil.CONSOLE_RELAY_NAME).join(); if (webhook == null) { logger.info(tl("discordErrorLoggerNoPerms")); return; diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java index 55ac88e70..cb3a82488 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java @@ -8,6 +8,7 @@ import com.earth2me.essentials.utils.FormatUtil; import com.earth2me.essentials.utils.VersionUtil; import com.google.common.collect.ImmutableList; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Role; @@ -23,9 +24,10 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.Consumer; public final class DiscordUtil { + public final static String ADVANCED_RELAY_NAME = "EssX Advanced Relay"; + public final static String CONSOLE_RELAY_NAME = "EssX Console Relay"; public final static List NO_GROUP_MENTIONS; public final static AllowedMentions ALL_MENTIONS_WEBHOOK = AllowedMentions.all(); public final static AllowedMentions NO_GROUP_MENTIONS_WEBHOOK = new AllowedMentions().withParseEveryone(false).withParseRoles(false).withParseUsers(true); @@ -60,48 +62,54 @@ public final class DiscordUtil { } /** - * Gets and cleans webhooks with the given name from channels other than the specified one. + * Gets or creates a webhook with the given name in the given channel. * - * @param channel The channel to search for webhooks in. - * @param webhookName The name of the webhook to validate it. + * @param channel The channel to search for/create webhooks in. + * @param webhookName The name of the webhook to search for/create. * - * @return A future which completes with the webhook by the given name in the given channel, if present, otherwise null. + * @return A future which completes with the webhook by the given name in the given channel, or null + * if the bot lacks the proper permissions. */ - public static CompletableFuture getAndCleanWebhooks(final TextChannel channel, final String webhookName) { - final Member self = channel.getGuild().getSelfMember(); - - final CompletableFuture future = new CompletableFuture<>(); - final Consumer> consumer = webhooks -> { - boolean foundWebhook = false; - for (final Webhook webhook : webhooks) { - if (webhook.getName().equalsIgnoreCase(webhookName)) { - if (foundWebhook || !webhook.getChannel().equals(channel)) { - ACTIVE_WEBHOOKS.remove(webhook.getId()); - webhook.delete().reason("EssX Webhook Cleanup").queue(); - continue; - } - ACTIVE_WEBHOOKS.addIfAbsent(webhook.getId()); - future.complete(webhook); - foundWebhook = true; - } - } - - if (!foundWebhook) { - future.complete(null); - } - }; - - if (self.hasPermission(Permission.MANAGE_WEBHOOKS)) { - channel.getGuild().retrieveWebhooks().queue(consumer); - } else if (self.hasPermission(channel, Permission.MANAGE_WEBHOOKS)) { - channel.retrieveWebhooks().queue(consumer); - } else { + public static CompletableFuture getOrCreateWebhook(final TextChannel channel, final String webhookName) { + if (!channel.getGuild().getSelfMember().hasPermission(channel, Permission.MANAGE_WEBHOOKS)) { return CompletableFuture.completedFuture(null); } + final CompletableFuture future = new CompletableFuture<>(); + channel.retrieveWebhooks().queue(webhooks -> { + for (final Webhook webhook : webhooks) { + if (webhook.getName().equals(webhookName)) { + ACTIVE_WEBHOOKS.addIfAbsent(webhook.getId()); + future.complete(webhook); + return; + } + } + createWebhook(channel, webhookName).thenAccept(future::complete); + }); return future; } + /** + * Cleans up unused webhooks from channels that no longer require an advanced relay. + * + * @param guild The guild which to preform the cleanup in. + * @param webhookName The name of the webhook to scan for. + */ + @SuppressWarnings("unused") // :balloon: + private static void cleanWebhooks(final Guild guild, String webhookName) { + if (!guild.getSelfMember().hasPermission(Permission.MANAGE_WEBHOOKS)) { + return; + } + + guild.retrieveWebhooks().queue(webhooks -> { + for (final Webhook webhook : webhooks) { + if (webhook.getName().equalsIgnoreCase(webhookName) && !ACTIVE_WEBHOOKS.contains(webhook.getId())) { + webhook.delete().reason("EssentialsX Discord: webhook cleanup").queue(); + } + } + }); + } + /** * Creates a webhook with the given name in the given channel. *