Fix advanced relay breaking when multiple channels were defined

This commit is contained in:
Josh Roy 2021-07-28 16:25:47 -04:00
parent 28578a5d8a
commit e2cb7b2102
2 changed files with 48 additions and 40 deletions

View File

@ -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;

View File

@ -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<Message.MentionType> 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<Webhook> getAndCleanWebhooks(final TextChannel channel, final String webhookName) {
final Member self = channel.getGuild().getSelfMember();
final CompletableFuture<Webhook> future = new CompletableFuture<>();
final Consumer<List<Webhook>> 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<Webhook> getOrCreateWebhook(final TextChannel channel, final String webhookName) {
if (!channel.getGuild().getSelfMember().hasPermission(channel, Permission.MANAGE_WEBHOOKS)) {
return CompletableFuture.completedFuture(null);
}
final CompletableFuture<Webhook> 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.
*