diff --git a/api/src/main/java/com/discordsrv/api/discord/connection/details/DiscordGatewayIntent.java b/api/src/main/java/com/discordsrv/api/discord/connection/details/DiscordGatewayIntent.java index 427fc35c..0ec845a5 100644 --- a/api/src/main/java/com/discordsrv/api/discord/connection/details/DiscordGatewayIntent.java +++ b/api/src/main/java/com/discordsrv/api/discord/connection/details/DiscordGatewayIntent.java @@ -26,6 +26,8 @@ package com.discordsrv.api.discord.connection.details; import com.discordsrv.api.discord.entity.JDAEntity; import net.dv8tion.jda.api.requests.GatewayIntent; +import java.util.EnumSet; + public enum DiscordGatewayIntent implements JDAEntity { GUILD_MEMBERS(GatewayIntent.GUILD_MEMBERS, "Server Members Intent"), @@ -43,16 +45,31 @@ public enum DiscordGatewayIntent implements JDAEntity { DIRECT_MESSAGE_TYPING(GatewayIntent.DIRECT_MESSAGE_TYPING), MESSAGE_CONTENT(GatewayIntent.MESSAGE_CONTENT, "Message Content Intent"), SCHEDULED_EVENTS(GatewayIntent.SCHEDULED_EVENTS), + AUTO_MODERATION_CONFIGURATION(GatewayIntent.AUTO_MODERATION_CONFIGURATION), + AUTO_MODERATION_EXECUTION(GatewayIntent.AUTO_MODERATION_EXECUTION), ; - static DiscordGatewayIntent getByJda(GatewayIntent jda) { + public static final EnumSet PRIVILEGED; + + static { + EnumSet privileged = EnumSet.noneOf(DiscordGatewayIntent.class); + for (DiscordGatewayIntent intent : values()) { + if (intent.privileged()) { + privileged.add(intent); + } + } + + PRIVILEGED = privileged; + } + + public static DiscordGatewayIntent getByJda(GatewayIntent jda) { for (DiscordGatewayIntent value : values()) { if (value.asJDA() == jda) { return value; } } - throw new IllegalArgumentException("This intent does not have a "); + throw new IllegalArgumentException("This intent does not have a DiscordGatewayIntent"); } private final GatewayIntent jda; diff --git a/api/src/main/java/com/discordsrv/api/event/bus/EventBus.java b/api/src/main/java/com/discordsrv/api/event/bus/EventBus.java index a1b0f68d..a686535f 100644 --- a/api/src/main/java/com/discordsrv/api/event/bus/EventBus.java +++ b/api/src/main/java/com/discordsrv/api/event/bus/EventBus.java @@ -28,6 +28,8 @@ import net.dv8tion.jda.api.events.GenericEvent; import org.jetbrains.annotations.Blocking; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + /** * DiscordSRV's event bus, handling all events extending {@link Event}s and {@link GenericEvent}s. */ @@ -48,6 +50,14 @@ public interface EventBus { */ void unsubscribe(@NotNull Object eventListener); + /** + * Gets the listeners for a given event listener. + * + * @param eventListener an event listener that has valid {@link Subscribe} methods. + * @return a set of event listener in the provided class according to this {@link EventBus} + */ + Collection getListeners(@NotNull Object eventListener); + /** * Publishes a DiscordSRV {@link Event} to this {@link EventBus}. * diff --git a/api/src/main/java/com/discordsrv/api/event/bus/EventListener.java b/api/src/main/java/com/discordsrv/api/event/bus/EventListener.java index 039e9a22..56f087c6 100644 --- a/api/src/main/java/com/discordsrv/api/event/bus/EventListener.java +++ b/api/src/main/java/com/discordsrv/api/event/bus/EventListener.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.Method; /** - * A event listener. + * An event listener. */ @SuppressWarnings("unused") // API public interface EventListener { @@ -49,4 +49,11 @@ public interface EventListener { @NotNull String methodName(); + /** + * The event this listener is listening to. + * @return the event extending {@link com.discordsrv.api.event.events.Event} or {@link net.dv8tion.jda.api.events.GenericEvent} + */ + @NotNull + Class eventClass(); + } diff --git a/api/src/main/java/com/discordsrv/api/event/bus/internal/EventStateHolder.java b/api/src/main/java/com/discordsrv/api/event/bus/internal/EventStateHolder.java index e57fe395..4ab31b42 100644 --- a/api/src/main/java/com/discordsrv/api/event/bus/internal/EventStateHolder.java +++ b/api/src/main/java/com/discordsrv/api/event/bus/internal/EventStateHolder.java @@ -50,5 +50,10 @@ public final class EventStateHolder { public @NotNull String methodName() { return null; } + + @Override + public @NotNull Class eventClass() { + return null; + } } } diff --git a/api/src/main/java/com/discordsrv/api/module/Module.java b/api/src/main/java/com/discordsrv/api/module/Module.java index d261cb68..346485fd 100644 --- a/api/src/main/java/com/discordsrv/api/module/Module.java +++ b/api/src/main/java/com/discordsrv/api/module/Module.java @@ -27,10 +27,14 @@ import com.discordsrv.api.DiscordSRVApi; import com.discordsrv.api.discord.connection.details.DiscordCacheFlag; import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent; import com.discordsrv.api.discord.connection.details.DiscordMemberCachePolicy; +import com.discordsrv.api.event.bus.EventListener; +import com.discordsrv.api.event.events.discord.message.AbstractDiscordMessageEvent; +import net.dv8tion.jda.api.events.GenericEvent; +import net.dv8tion.jda.api.events.guild.member.GenericGuildMemberEvent; +import net.dv8tion.jda.api.requests.GatewayIntent; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import java.util.Collections; +import java.util.*; import java.util.function.Consumer; public interface Module { @@ -46,11 +50,55 @@ public interface Module { /** * Provides a {@link Collection} of {@link DiscordGatewayIntent}s that are required for this {@link Module}. + * This defaults to determining intents based on the events listened to in this class via {@link com.discordsrv.api.event.bus.Subscribe} methods. * @return the collection of gateway intents required by this module at the time this method is called */ + @SuppressWarnings("unchecked") // Class generic cast @NotNull default Collection requiredIntents() { - return Collections.emptyList(); + DiscordSRVApi api = DiscordSRVApi.get(); + if (api == null) { + return Collections.emptyList(); + } + + Collection listeners = api.eventBus().getListeners(this); + EnumSet intents = EnumSet.noneOf(DiscordGatewayIntent.class); + + for (EventListener listener : listeners) { + Class eventClass = listener.eventClass(); + + // DiscordSRV + if (AbstractDiscordMessageEvent.class.isAssignableFrom(eventClass)) { + intents.addAll(EnumSet.of(DiscordGatewayIntent.GUILD_MESSAGES, DiscordGatewayIntent.DIRECT_MESSAGES)); + } + if (GenericGuildMemberEvent.class.isAssignableFrom(eventClass)) { + intents.add(DiscordGatewayIntent.GUILD_MEMBERS); + } + + // JDA + if (!GenericEvent.class.isAssignableFrom(eventClass)) { + continue; + } + + EnumSet jdaIntents = GatewayIntent.fromEvents((Class) listener.eventClass()); + for (GatewayIntent jdaIntent : jdaIntents) { + try { + intents.add(DiscordGatewayIntent.getByJda(jdaIntent)); + } catch (IllegalArgumentException ignored) {} + } + } + + // Below are some intents that will not be added by event reference (and have to be specified intentionally) + + // Direct messages are rarely used by bots (and Guild & Direct message events are the same) + intents.remove(DiscordGatewayIntent.DIRECT_MESSAGES); + intents.remove(DiscordGatewayIntent.DIRECT_MESSAGE_REACTIONS); + intents.remove(DiscordGatewayIntent.DIRECT_MESSAGE_TYPING); + + // Presences change A LOT + intents.remove(DiscordGatewayIntent.GUILD_PRESENCES); + + return intents; } /** diff --git a/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java b/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java index 5089aa84..edcf3919 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java @@ -91,7 +91,8 @@ public class ConsoleConfig { ); } - @Comment("If command execution is enabled") + @Comment("If command execution in this console channel is enabled\n" + + "Requires the \"Message Content Intent\"") public boolean enabled = true; @Comment("At least one condition has to match to allow execution") diff --git a/common/src/main/java/com/discordsrv/common/config/main/MemberCachingConfig.java b/common/src/main/java/com/discordsrv/common/config/main/MemberCachingConfig.java index e0121056..92c0a745 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/MemberCachingConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/MemberCachingConfig.java @@ -27,13 +27,16 @@ import java.util.List; @ConfigSerializable public class MemberCachingConfig { - @Comment("If linked users' members should be cached, this requires the \"Server Members Intent\"") + @Comment("If linked users' members should be cached\n" + + "Requires the \"Server Members Intent\"") public boolean linkedUsers = true; - @Comment("If all members should be cached, this requires the \"Server Members Intent\"") + @Comment("If all members should be cached\n" + + "Requires the \"Server Members Intent\"") public boolean all = false; - @Comment("If members should be cached at startup, this requires the \"Server Members Intent\"") + @Comment("If members should be cached at startup\n" + + "Requires the \"Server Members Intent\"") public boolean chunk = true; @Comment("Filter for which servers should be cached at startup") diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java index 27511036..4b156f14 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java @@ -31,6 +31,7 @@ import java.util.regex.Pattern; @ConfigSerializable public class DiscordToMinecraftChatConfig { + @Comment("Requires the \"Message Content Intent\"") public boolean enabled = true; @Comment("The Discord to Minecraft message format for regular users and bots") diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/MinecraftToDiscordChatConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/MinecraftToDiscordChatConfig.java index 37f3e2c3..19cfd9e2 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/MinecraftToDiscordChatConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/MinecraftToDiscordChatConfig.java @@ -70,7 +70,8 @@ public class MinecraftToDiscordChatConfig implements IMessageConfig { public boolean channels = true; @Comment("If user mentions should be rendered on Discord\n" - + "The player needs the discordsrv.mention.user permission to trigger a notification") + + "The player needs the discordsrv.mention.user permission to trigger a notification\n" + + "Requires the \"Server Members Intent\"") public boolean users = true; @Comment("If uncached users should be looked up from the Discord API when a mention (\"@something\") occurs in chat.\n" diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/MirroringConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/MirroringConfig.java index b9adbe56..600b454d 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/MirroringConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/MirroringConfig.java @@ -25,6 +25,7 @@ import org.spongepowered.configurate.objectmapping.meta.Comment; @ConfigSerializable public class MirroringConfig { + @Comment("Requires the \"Message Content Intent\"") public boolean enabled = true; @Comment("Users, bots, roles and webhooks to ignore when mirroring") diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/base/BaseChannelConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/base/BaseChannelConfig.java index c71ebbb2..31b12873 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/base/BaseChannelConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/base/BaseChannelConfig.java @@ -28,6 +28,7 @@ public class BaseChannelConfig { @Order(0) public MinecraftToDiscordChatConfig minecraftToDiscord = new MinecraftToDiscordChatConfig(); + @Order(0) public DiscordToMinecraftChatConfig discordToMinecraft = new DiscordToMinecraftChatConfig(); diff --git a/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java b/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java index 45f8141e..bb22ef7e 100644 --- a/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java +++ b/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java @@ -2,6 +2,8 @@ package com.discordsrv.common.console; import com.discordsrv.api.DiscordSRVApi; import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent; +import com.discordsrv.api.event.bus.Subscribe; +import com.discordsrv.api.event.events.discord.message.DiscordMessageReceiveEvent; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.config.main.ConsoleConfig; import com.discordsrv.common.config.main.generic.DestinationConfig; @@ -15,10 +17,7 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.function.Consumer; public class ConsoleModule extends AbstractModule implements LogAppender { @@ -32,7 +31,12 @@ public class ConsoleModule extends AbstractModule implements LogAppe @Override public @NotNull Collection requiredIntents() { - return Collections.singletonList(DiscordGatewayIntent.MESSAGE_CONTENT); + boolean anyExecutors = discordSRV.config().console.stream().anyMatch(config -> config.commandExecution.enabled); + if (anyExecutors) { + return EnumSet.of(DiscordGatewayIntent.GUILD_MESSAGES, DiscordGatewayIntent.MESSAGE_CONTENT); + } + + return Collections.emptySet(); } @Override @@ -83,4 +87,11 @@ public class ConsoleModule extends AbstractModule implements LogAppe handler.queue(entry); } } + + @Subscribe + public void onDiscordMessageReceived(DiscordMessageReceiveEvent event) { + for (SingleConsoleHandler handler : handlers) { + handler.handleDiscordMessageReceived(event); + } + } } diff --git a/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java b/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java index f8666c37..9a3f6b0e 100644 --- a/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java +++ b/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java @@ -9,7 +9,6 @@ import com.discordsrv.api.discord.entity.guild.DiscordGuildMember; import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage; import com.discordsrv.api.discord.entity.message.SendableDiscordMessage; import com.discordsrv.api.discord.util.DiscordFormattingUtil; -import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.discord.message.DiscordMessageReceiveEvent; import com.discordsrv.api.placeholder.PlainPlaceholderFormat; import com.discordsrv.api.placeholder.provider.SinglePlaceholder; @@ -67,11 +66,13 @@ public class SingleConsoleHandler { this.messageCache = config.appender.useEditing ? new ArrayList<>() : null; timeQueueProcess(); - discordSRV.eventBus().subscribe(this); } - @Subscribe - public void onDiscordMessageReceived(DiscordMessageReceiveEvent event) { + public void handleDiscordMessageReceived(DiscordMessageReceiveEvent event) { + if (!config.commandExecution.enabled) { + return; + } + DiscordMessageChannel messageChannel = event.getChannel(); DiscordGuildChannel channel = messageChannel instanceof DiscordGuildChannel ? (DiscordGuildChannel) messageChannel : null; if (channel == null) { @@ -174,7 +175,6 @@ public class SingleConsoleHandler { @SuppressWarnings("SynchronizeOnNonFinalField") public void shutdown() { shutdown = true; - discordSRV.eventBus().unsubscribe(this); queueProcessingFuture.cancel(false); try { synchronized (queueProcessingFuture) { diff --git a/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIEventModule.java b/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIEventModule.java index 467555a2..076ab97a 100644 --- a/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIEventModule.java +++ b/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIEventModule.java @@ -18,6 +18,7 @@ package com.discordsrv.common.discord.api; +import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent; import com.discordsrv.api.discord.entity.DiscordUser; import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel; import com.discordsrv.api.discord.entity.guild.DiscordGuildMember; @@ -37,6 +38,7 @@ import com.discordsrv.api.event.events.discord.member.role.DiscordMemberRoleRemo import com.discordsrv.api.event.events.discord.message.DiscordMessageDeleteEvent; import com.discordsrv.api.event.events.discord.message.DiscordMessageReceiveEvent; import com.discordsrv.api.event.events.discord.message.DiscordMessageUpdateEvent; +import com.discordsrv.api.module.Module; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.discord.api.entity.component.DiscordInteractionHookImpl; import com.discordsrv.common.discord.api.entity.message.ReceivedDiscordMessageImpl; @@ -59,10 +61,9 @@ import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageUpdateEvent; import net.dv8tion.jda.api.interactions.callbacks.IDeferrableCallback; import net.dv8tion.jda.api.interactions.commands.Command; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -76,6 +77,15 @@ public class DiscordAPIEventModule extends AbstractModule { return discordSRV.discordAPI(); } + /** + * See {@link Module#requiredIntents()} implementation. + * @return no intents as these events might not be listened to + */ + @Override + public @NotNull Collection requiredIntents() { + return Collections.emptyList(); + } + @Subscribe public void onMessageReceived(MessageReceivedEvent event) { discordSRV.eventBus().publish(new DiscordMessageReceiveEvent( diff --git a/common/src/main/java/com/discordsrv/common/event/bus/EventBusImpl.java b/common/src/main/java/com/discordsrv/common/event/bus/EventBusImpl.java index 28b05c09..4f409846 100644 --- a/common/src/main/java/com/discordsrv/common/event/bus/EventBusImpl.java +++ b/common/src/main/java/com/discordsrv/common/event/bus/EventBusImpl.java @@ -40,10 +40,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Function; @@ -78,6 +75,28 @@ public class EventBusImpl implements EventBus { throw new IllegalArgumentException("Listener is already registered"); } + Pair, List> parsed = parseListeners(eventListener); + List suppressedMethods = parsed.getValue(); + List methods = parsed.getKey(); + + if (methods.isEmpty() || !suppressedMethods.isEmpty()) { + IllegalArgumentException exception = new IllegalArgumentException(eventListener.getClass().getName() + + " doesn't have valid listener methods that are annotated with " + Subscribe.class.getName()); + suppressedMethods.forEach(exception::addSuppressed); + throw exception; + } + + listeners.put(eventListener, methods); + allListeners.addAll(methods); + logger.debug("Listener " + eventListener.getClass().getName() + " subscribed"); + } + + @Override + public Collection getListeners(@NotNull Object eventListener) { + return parseListeners(eventListener).getKey(); + } + + private Pair, List> parseListeners(Object eventListener) { Class listenerClass = eventListener.getClass(); List suppressedMethods = new ArrayList<>(); @@ -90,16 +109,7 @@ public class EventBusImpl implements EventBus { } } while ((currentClass = currentClass.getSuperclass()) != null); - if (methods.isEmpty() || !suppressedMethods.isEmpty()) { - IllegalArgumentException exception = new IllegalArgumentException(listenerClass.getName() - + " doesn't have valid listener methods that are annotated with " + Subscribe.class.getName()); - suppressedMethods.forEach(exception::addSuppressed); - throw exception; - } - - listeners.put(eventListener, methods); - allListeners.addAll(methods); - logger.debug("Listener " + eventListener.getClass().getName() + " subscribed"); + return Pair.of(methods, suppressedMethods); } private void checkMethod(Object eventListener, Class listenerClass, Method method, @@ -215,6 +225,9 @@ public class EventBusImpl implements EventBus { if (eventListener.className().startsWith("com.discordsrv")) { logger.error("Failed to pass " + eventClassName + " to " + eventListener, cause); } else { + // Print the listener failing without references to the DiscordSRV event bus + // as it isn't relevant to the exception, and often causes users to suspect DiscordSRV is doing something wrong when it isn't + //noinspection CallToPrintStackTrace e.getCause().printStackTrace(); } TestHelper.fail(cause); diff --git a/common/src/main/java/com/discordsrv/common/event/bus/EventListenerImpl.java b/common/src/main/java/com/discordsrv/common/event/bus/EventListenerImpl.java index a1c810fd..7ea37c92 100644 --- a/common/src/main/java/com/discordsrv/common/event/bus/EventListenerImpl.java +++ b/common/src/main/java/com/discordsrv/common/event/bus/EventListenerImpl.java @@ -53,7 +53,8 @@ public class EventListenerImpl implements EventListener { return listener; } - public Class eventClass() { + @Override + public @NotNull Class eventClass() { return eventClass; } diff --git a/common/src/main/java/com/discordsrv/common/invite/DiscordInviteModule.java b/common/src/main/java/com/discordsrv/common/invite/DiscordInviteModule.java index 7b8fd256..a905f2ab 100644 --- a/common/src/main/java/com/discordsrv/common/invite/DiscordInviteModule.java +++ b/common/src/main/java/com/discordsrv/common/invite/DiscordInviteModule.java @@ -39,6 +39,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.function.Consumer; @@ -56,10 +57,10 @@ public class DiscordInviteModule extends AbstractModule { public @NotNull Collection requiredIntents() { DiscordInviteConfig config = discordSRV.config().invite; if (StringUtils.isNotEmpty(config.inviteUrl)) { - return Collections.emptyList(); + return Collections.emptySet(); } - return Collections.singleton(DiscordGatewayIntent.GUILD_INVITES); + return EnumSet.of(DiscordGatewayIntent.GUILD_INVITES); } @Subscribe diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java index 6061dd6c..5253a11f 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java @@ -49,8 +49,8 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import java.time.Duration; -import java.util.Arrays; import java.util.Collection; +import java.util.EnumSet; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; @@ -92,7 +92,7 @@ public class DiscordChatMessageModule extends AbstractModule { @Override public @NotNull Collection requiredIntents() { - return Arrays.asList(DiscordGatewayIntent.GUILD_MESSAGES, DiscordGatewayIntent.MESSAGE_CONTENT); + return EnumSet.of(DiscordGatewayIntent.GUILD_MESSAGES, DiscordGatewayIntent.MESSAGE_CONTENT); } @Subscribe diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java index 3188b841..32ebea60 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java @@ -83,7 +83,7 @@ public class DiscordMessageMirroringModule extends AbstractModule { @Override public @NotNull Collection requiredIntents() { - return Arrays.asList(DiscordGatewayIntent.GUILD_MESSAGES, DiscordGatewayIntent.MESSAGE_CONTENT); + return EnumSet.of(DiscordGatewayIntent.GUILD_MESSAGES, DiscordGatewayIntent.MESSAGE_CONTENT); } @SuppressWarnings("unchecked") // Wacky generics diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/game/minecrafttodiscord/MentionCachingModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/game/minecrafttodiscord/MentionCachingModule.java index 7c25ee55..9e65b1ca 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/game/minecrafttodiscord/MentionCachingModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/game/minecrafttodiscord/MentionCachingModule.java @@ -18,6 +18,7 @@ package com.discordsrv.common.messageforwarding.game.minecrafttodiscord; +import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.config.main.channels.MinecraftToDiscordChatConfig; @@ -38,6 +39,7 @@ import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameE import net.dv8tion.jda.api.events.role.RoleCreateEvent; import net.dv8tion.jda.api.events.role.RoleDeleteEvent; import net.dv8tion.jda.api.events.role.update.RoleUpdateNameEvent; +import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -57,6 +59,29 @@ public class MentionCachingModule extends AbstractModule { super(discordSRV); } + @Override + public @NotNull Collection requiredIntents() { + boolean anyUserMentions = false; + for (BaseChannelConfig channel : discordSRV.channelConfig().getAllChannels()) { + MinecraftToDiscordChatConfig config = channel.minecraftToDiscord; + if (!config.enabled) { + continue; + } + + MinecraftToDiscordChatConfig.Mentions mentions = config.mentions; + if (mentions.users) { + anyUserMentions = true; + break; + } + } + + if (anyUserMentions) { + return EnumSet.of(DiscordGatewayIntent.GUILD_MEMBERS); + } + + return Collections.emptySet(); + } + @Override public boolean isEnabled() { for (BaseChannelConfig channel : discordSRV.channelConfig().getAllChannels()) {