From fb872f2b0bfeb467194f1305875667693b7e88bb Mon Sep 17 00:00:00 2001 From: anthorob Date: Tue, 31 Dec 2024 20:45:16 -0500 Subject: [PATCH] change how events are handled by using a single class to register listeners onto --- .../bobert/netneutrality/NetNeutrality.java | 25 +--- .../command/git/ReportIssueCommand.java | 2 +- .../{ => command}/MessageCommandContext.java | 3 +- .../context/command/MessageMenuContext.java | 61 ++++++++ .../{ => command}/SlashCommandContext.java | 8 +- .../context/command/UserMenuContext.java | 62 ++++++++ .../context/tasks/EmojiTaskContext.java | 6 + .../command/AbstractMessageMenuCommand.java | 46 ++++++ .../core/command/AbstractUserMenuCommand.java | 46 ++++++ .../core/command/CommandManager.java | 4 +- .../core/command/CommandProcessor.java | 11 +- .../core/context/InteractionContext.java | 10 +- .../core/context/TaskContext.java | 6 - .../netneutrality/hooks/EventsHandler.java | 135 ++++++++++++++++++ .../hooks/guilds/ServerJoinHook.java | 26 ---- .../interaction/ButtonInteractionHook.java | 22 --- .../interaction/ModalInteractionHook.java | 22 --- .../hooks/interaction/SlashCommandHook.java | 22 --- .../hooks/message/EditHandler.java | 57 -------- .../hooks/message/EmojiReactionHook.java | 22 --- .../hooks/message/MessageReceivedHook.java | 31 ---- .../hooks/voice/VoiceEventHook.java | 18 --- .../netneutrality/utils/MusicUtils.java | 2 +- .../netneutrality/utils/UserFunction.java | 2 +- 24 files changed, 386 insertions(+), 263 deletions(-) rename src/main/java/me/bobert/netneutrality/context/{ => command}/MessageCommandContext.java (99%) create mode 100644 src/main/java/me/bobert/netneutrality/context/command/MessageMenuContext.java rename src/main/java/me/bobert/netneutrality/context/{ => command}/SlashCommandContext.java (90%) create mode 100644 src/main/java/me/bobert/netneutrality/context/command/UserMenuContext.java create mode 100644 src/main/java/me/bobert/netneutrality/core/command/AbstractMessageMenuCommand.java create mode 100644 src/main/java/me/bobert/netneutrality/core/command/AbstractUserMenuCommand.java create mode 100644 src/main/java/me/bobert/netneutrality/hooks/EventsHandler.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/guilds/ServerJoinHook.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/interaction/ButtonInteractionHook.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/interaction/ModalInteractionHook.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/interaction/SlashCommandHook.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/message/EditHandler.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/message/EmojiReactionHook.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/message/MessageReceivedHook.java delete mode 100644 src/main/java/me/bobert/netneutrality/hooks/voice/VoiceEventHook.java diff --git a/src/main/java/me/bobert/netneutrality/NetNeutrality.java b/src/main/java/me/bobert/netneutrality/NetNeutrality.java index 0662446..b4c2d26 100644 --- a/src/main/java/me/bobert/netneutrality/NetNeutrality.java +++ b/src/main/java/me/bobert/netneutrality/NetNeutrality.java @@ -12,12 +12,7 @@ import me.bobert.netneutrality.core.command.CommandManager; import me.bobert.netneutrality.core.db.SessionManager; import me.bobert.netneutrality.core.tasks.TaskManager; import me.bobert.netneutrality.core.thread.ThreadManager; -import me.bobert.netneutrality.hooks.guilds.ServerJoinHook; -import me.bobert.netneutrality.hooks.interaction.ButtonInteractionHook; -import me.bobert.netneutrality.hooks.interaction.ModalInteractionHook; -import me.bobert.netneutrality.hooks.interaction.SlashCommandHook; -import me.bobert.netneutrality.hooks.message.EmojiReactionHook; -import me.bobert.netneutrality.hooks.message.MessageReceivedHook; +import me.bobert.netneutrality.hooks.EventsHandler; import me.bobert.netneutrality.http.server.WebApi; import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.thread.ShutdownThread; @@ -25,7 +20,6 @@ import me.bobert.netneutrality.utils.Settings; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Activity; -import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.exceptions.InvalidTokenException; import net.dv8tion.jda.api.requests.GatewayIntent; import org.apache.logging.log4j.Level; @@ -67,6 +61,11 @@ public class NetNeutrality { } private void startup() { + String token = Settings.getInstance().get("NETNEUTRALITY_BOT_TOKEN"); + if (token == null) { + throw new RuntimeException("No bot token provided, exiting."); + } + // DatabaseMigration.migrate(); SessionManager.getSessionFactory(); CommandManager.init(); @@ -74,9 +73,7 @@ public class NetNeutrality { TaskManager.getInstance().init(); initJDA(); CommandManager.registerSlashCommands(jda); - jda.addEventListener(new ServerJoinHook()); - jda.addEventListener(new MessageReceivedHook(), new SlashCommandHook()); - jda.addEventListener(new ModalInteractionHook(), new ButtonInteractionHook(), new EmojiReactionHook()); + jda.addEventListener(new EventsHandler()); new WebApi(Integer.parseInt(Settings.getInstance().get("NETNEUTRALITY_API_PORT", "9000"))); jda.getPresence().setActivity(Activity.watching("you")); @@ -120,17 +117,9 @@ public class NetNeutrality { return jda; } - public User getSelf() { - return jda.getSelfUser(); - - } - private void disconnect() { if (jda != null) { jda.shutdown(); } - } - - } diff --git a/src/main/java/me/bobert/netneutrality/command/git/ReportIssueCommand.java b/src/main/java/me/bobert/netneutrality/command/git/ReportIssueCommand.java index 134ad39..e65f342 100644 --- a/src/main/java/me/bobert/netneutrality/command/git/ReportIssueCommand.java +++ b/src/main/java/me/bobert/netneutrality/command/git/ReportIssueCommand.java @@ -5,7 +5,7 @@ package me.bobert.netneutrality.command.git; * https://discord.gg/qUa6zNFZsd */ -import me.bobert.netneutrality.context.SlashCommandContext; +import me.bobert.netneutrality.context.command.SlashCommandContext; import me.bobert.netneutrality.core.command.AbstractCommand; import me.bobert.netneutrality.core.command.CommandCategory; import me.bobert.netneutrality.core.command.CommandExecutionResult; diff --git a/src/main/java/me/bobert/netneutrality/context/MessageCommandContext.java b/src/main/java/me/bobert/netneutrality/context/command/MessageCommandContext.java similarity index 99% rename from src/main/java/me/bobert/netneutrality/context/MessageCommandContext.java rename to src/main/java/me/bobert/netneutrality/context/command/MessageCommandContext.java index b319386..510d0d7 100644 --- a/src/main/java/me/bobert/netneutrality/context/MessageCommandContext.java +++ b/src/main/java/me/bobert/netneutrality/context/command/MessageCommandContext.java @@ -1,10 +1,11 @@ -package me.bobert.netneutrality.context; +package me.bobert.netneutrality.context.command; /* * Copyright (c) anthorob * * https://discord.gg/qUa6zNFZsd */ +import me.bobert.netneutrality.context.AsyncContext; import me.bobert.netneutrality.core.command.options.CommandOption; import me.bobert.netneutrality.core.command.options.MessageCommandOption; import me.bobert.netneutrality.core.context.CommandContext; diff --git a/src/main/java/me/bobert/netneutrality/context/command/MessageMenuContext.java b/src/main/java/me/bobert/netneutrality/context/command/MessageMenuContext.java new file mode 100644 index 0000000..89e2d6b --- /dev/null +++ b/src/main/java/me/bobert/netneutrality/context/command/MessageMenuContext.java @@ -0,0 +1,61 @@ +package me.bobert.netneutrality.context.command; + +/* + * Copyright (c) anthorob + * + * https://discord.gg/qUa6zNFZsd + */ + +import me.bobert.netneutrality.core.command.options.CommandOption; +import me.bobert.netneutrality.core.context.CommandContext; +import me.bobert.netneutrality.core.context.InteractionContext; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.events.Event; +import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.util.List; + +public class MessageMenuContext extends CommandContext implements InteractionContext { + private final MessageContextInteractionEvent event; + + public MessageMenuContext(MessageContextInteractionEvent event) { + super(event.getJDA(), event.getGuild(), event.getChannel(), event.getMember(), event.getUser()); + this.event = event; + } + + @Override + public Event getEvent() { + return event; + } + + @Override + public ChannelType getType() { + return event.getChannelType(); + } + + @Override + public void deleteMessage() { + + } + + @Override + public List parseOptions(String[] args, List commandOptions) { + return List.of(); // no options for context menu commands + } + + @Override + public String parseCommandName() { + return getFullCommand(); + } + + @Override + public String getFullCommand() { + return event.getName(); + } + + public Message getTarget() { + return event.getTarget(); + } +} diff --git a/src/main/java/me/bobert/netneutrality/context/SlashCommandContext.java b/src/main/java/me/bobert/netneutrality/context/command/SlashCommandContext.java similarity index 90% rename from src/main/java/me/bobert/netneutrality/context/SlashCommandContext.java rename to src/main/java/me/bobert/netneutrality/context/command/SlashCommandContext.java index 275a9c1..2d81b39 100644 --- a/src/main/java/me/bobert/netneutrality/context/SlashCommandContext.java +++ b/src/main/java/me/bobert/netneutrality/context/command/SlashCommandContext.java @@ -1,4 +1,4 @@ -package me.bobert.netneutrality.context; +package me.bobert.netneutrality.context.command; /* * Copyright (c) anthorob * @@ -12,7 +12,6 @@ import me.bobert.netneutrality.core.context.InteractionContext; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.modals.Modal; import java.util.List; import java.util.stream.Collectors; @@ -40,11 +39,6 @@ public class SlashCommandContext extends CommandContext implements InteractionCo // not implemented } - @Override - public void reply(Modal modal) { - event.replyModal(modal).queue(); - } - @Override public List parseOptions(String[] args, List commandOptions) { return event.getOptions().stream().map(SlashCommandOption::new).collect(Collectors.toUnmodifiableList()); diff --git a/src/main/java/me/bobert/netneutrality/context/command/UserMenuContext.java b/src/main/java/me/bobert/netneutrality/context/command/UserMenuContext.java new file mode 100644 index 0000000..b3342ed --- /dev/null +++ b/src/main/java/me/bobert/netneutrality/context/command/UserMenuContext.java @@ -0,0 +1,62 @@ +package me.bobert.netneutrality.context.command; + +/* + * Copyright (c) anthorob + * + * https://discord.gg/qUa6zNFZsd + */ + +import me.bobert.netneutrality.core.command.options.CommandOption; +import me.bobert.netneutrality.core.context.CommandContext; +import me.bobert.netneutrality.core.context.InteractionContext; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; +import net.dv8tion.jda.api.events.Event; +import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.util.List; + +public class UserMenuContext extends CommandContext implements InteractionContext { + private final UserContextInteractionEvent event; + + public UserMenuContext(UserContextInteractionEvent event) { + super(event.getJDA(), event.getGuild(), (MessageChannel) event.getChannel(), event.getMember(), event.getUser()); + this.event = event; + } + + @Override + public Event getEvent() { + return event; + } + + @Override + public ChannelType getType() { + return event.getChannelType(); + } + + @Override + public void deleteMessage() { + + } + + @Override + public List parseOptions(String[] args, List commandOptions) { + return List.of(); // no options for context menu commands + } + + @Override + public String parseCommandName() { + return getFullCommand(); + } + + @Override + public String getFullCommand() { + return event.getName(); + } + + public User getTarget() { + return event.getTarget(); + } +} diff --git a/src/main/java/me/bobert/netneutrality/context/tasks/EmojiTaskContext.java b/src/main/java/me/bobert/netneutrality/context/tasks/EmojiTaskContext.java index ac65383..2bc4911 100644 --- a/src/main/java/me/bobert/netneutrality/context/tasks/EmojiTaskContext.java +++ b/src/main/java/me/bobert/netneutrality/context/tasks/EmojiTaskContext.java @@ -11,6 +11,7 @@ import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.components.LayoutComponent; +import net.dv8tion.jda.api.interactions.modals.Modal; import net.dv8tion.jda.api.utils.messages.MessageCreateData; import java.util.List; @@ -61,6 +62,11 @@ public class EmojiTaskContext extends TaskContext { return event.isFromGuild(); } + @Override + public void reply(Modal modal) { + + } + @Override public void reply(MessageCreateData messageCreateData, boolean ephemeral, List components, Consumer consumer) { if (getChannel() != null && getChannel().canTalk()) { diff --git a/src/main/java/me/bobert/netneutrality/core/command/AbstractMessageMenuCommand.java b/src/main/java/me/bobert/netneutrality/core/command/AbstractMessageMenuCommand.java new file mode 100644 index 0000000..3ea7a84 --- /dev/null +++ b/src/main/java/me/bobert/netneutrality/core/command/AbstractMessageMenuCommand.java @@ -0,0 +1,46 @@ +package me.bobert.netneutrality.core.command; + +/* + * Copyright (c) anthorob + * + * https://discord.gg/qUa6zNFZsd + */ + +import me.bobert.netneutrality.context.command.MessageMenuContext; +import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder; +import me.bobert.netneutrality.core.context.CommandContext; +import net.dv8tion.jda.api.entities.Message; + +public abstract class AbstractMessageMenuCommand extends AbstractCommand { + @Override + public String getDescription() { + return null; + } + + @Override + public boolean isSlashCommandOnly() { + return false; + } + + @Override + public void registerCommandOptions(CommandOptionsBuilder builder) { + // no options for context commands + } + + @Override + public Type getType() { + return Type.MESSAGE; + } + + @Override + public CommandExecutionResult execute(CommandContext context) { + if (context instanceof MessageMenuContext mc) { + Message message = mc.getTarget(); + return execute(message, context); + } + + throw new IllegalArgumentException("Wrong context type for this command"); + } + + public abstract CommandExecutionResult execute(Message target, CommandContext context); +} diff --git a/src/main/java/me/bobert/netneutrality/core/command/AbstractUserMenuCommand.java b/src/main/java/me/bobert/netneutrality/core/command/AbstractUserMenuCommand.java new file mode 100644 index 0000000..c9b2625 --- /dev/null +++ b/src/main/java/me/bobert/netneutrality/core/command/AbstractUserMenuCommand.java @@ -0,0 +1,46 @@ +package me.bobert.netneutrality.core.command; + +/* + * Copyright (c) anthorob + * + * https://discord.gg/qUa6zNFZsd + */ + +import me.bobert.netneutrality.context.command.UserMenuContext; +import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder; +import me.bobert.netneutrality.core.context.CommandContext; +import net.dv8tion.jda.api.entities.User; + +public abstract class AbstractUserMenuCommand extends AbstractCommand { + @Override + public String getDescription() { + return null; + } + + @Override + public boolean isSlashCommandOnly() { + return false; + } + + @Override + public void registerCommandOptions(CommandOptionsBuilder builder) { + // no options for context commands + } + + @Override + public Type getType() { + return Type.USER; + } + + @Override + public CommandExecutionResult execute(CommandContext context) { + if (context instanceof UserMenuContext uc) { + User user = uc.getTarget(); + return execute(user, context); + } + + throw new IllegalArgumentException("Wrong context type for this command"); + } + + public abstract CommandExecutionResult execute(User target, CommandContext context); +} diff --git a/src/main/java/me/bobert/netneutrality/core/command/CommandManager.java b/src/main/java/me/bobert/netneutrality/core/command/CommandManager.java index 88fbb4d..b0e2627 100644 --- a/src/main/java/me/bobert/netneutrality/core/command/CommandManager.java +++ b/src/main/java/me/bobert/netneutrality/core/command/CommandManager.java @@ -57,7 +57,7 @@ public class CommandManager { throw new IllegalArgumentException("Command name is null"); } - if (command.getDescription() == null) { + if (command.getDescription() == null && command.getType() == Command.Type.SLASH) { throw new IllegalArgumentException("Command description is null"); } @@ -68,7 +68,7 @@ public class CommandManager { commands.put(command.getCommandName(), container); } } catch (Exception e) { - logger.error("Failed to instantiate command {}: {}", s.getSimpleName(), e.getMessage()); + logger.error("Failed to load command {}: {}", s.getSimpleName(), e.getMessage()); } } } diff --git a/src/main/java/me/bobert/netneutrality/core/command/CommandProcessor.java b/src/main/java/me/bobert/netneutrality/core/command/CommandProcessor.java index 96ec623..c0c5615 100644 --- a/src/main/java/me/bobert/netneutrality/core/command/CommandProcessor.java +++ b/src/main/java/me/bobert/netneutrality/core/command/CommandProcessor.java @@ -6,10 +6,11 @@ package me.bobert.netneutrality.core.command; */ import io.sentry.Sentry; -import me.bobert.netneutrality.context.SlashCommandContext; +import me.bobert.netneutrality.context.command.SlashCommandContext; import me.bobert.netneutrality.core.LogHandler; import me.bobert.netneutrality.core.command.options.CommandOptions; import me.bobert.netneutrality.core.context.CommandContext; +import me.bobert.netneutrality.core.context.InteractionContext; import me.bobert.netneutrality.exceptions.CommandExecutionException; import me.bobert.netneutrality.utils.UserFunction; import net.dv8tion.jda.api.interactions.commands.OptionType; @@ -65,12 +66,12 @@ public class CommandProcessor { logger.info("Executing command {} on guild {}", command.getCommandName(), context.getGuild() == null ? "PrivateMessage" : context.getGuild().getId()); configureSentry(command); - if (!canExecute(command)) { + if (command.getType() == Command.Type.SLASH && !canExecute(command)) { context.reply("You are not powerful enough, scrub"); return; } - if (!checkUsage(container.getCommandOptions())) { + if (command.getType() == Command.Type.SLASH && !checkUsage(container.getCommandOptions())) { return; } @@ -96,7 +97,7 @@ public class CommandProcessor { String message = commandExecutionResult.getMessage(); if (result == ERROR) { - logger.error("Error from command {}: {}", command.getCommandName(), message, commandExecutionResult.getException()); + logger.error("Context[{}]: Error from command: {}", context.getId(), message, commandExecutionResult.getException()); } context.reply(message); @@ -175,7 +176,7 @@ public class CommandProcessor { } private boolean checkOptions(String[] args, int skip, List options) { - if (context instanceof SlashCommandContext) { + if (context instanceof InteractionContext) { context.setCurrentCommandOptions(args, options); return true; // slash commands are validated by discord } diff --git a/src/main/java/me/bobert/netneutrality/core/context/InteractionContext.java b/src/main/java/me/bobert/netneutrality/core/context/InteractionContext.java index e7405a9..9008e75 100644 --- a/src/main/java/me/bobert/netneutrality/core/context/InteractionContext.java +++ b/src/main/java/me/bobert/netneutrality/core/context/InteractionContext.java @@ -6,11 +6,12 @@ package me.bobert.netneutrality.core.context; */ import me.bobert.netneutrality.context.AsyncContext; -import net.dv8tion.jda.api.events.Event; import net.dv8tion.jda.api.interactions.Interaction; import net.dv8tion.jda.api.interactions.InteractionHook; +import net.dv8tion.jda.api.interactions.callbacks.IModalCallback; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.components.LayoutComponent; +import net.dv8tion.jda.api.interactions.modals.Modal; import net.dv8tion.jda.api.utils.messages.MessageCreateData; import java.util.List; @@ -66,6 +67,13 @@ public interface InteractionContext extends Context { getReplyCallback().reply(messageCreateData).setEphemeral(ephemeral).setComponents(components).queue(message -> consumer.accept(new AsyncContext(message))); } + @Override + default void reply(Modal modal) { + if (getInteraction() instanceof IModalCallback) { + ((IModalCallback) getInteraction()).replyModal(modal).queue(); + } + } + private IReplyCallback getReplyCallback() { try { return (IReplyCallback) getEvent(); diff --git a/src/main/java/me/bobert/netneutrality/core/context/TaskContext.java b/src/main/java/me/bobert/netneutrality/core/context/TaskContext.java index 4fd23a7..86a8044 100644 --- a/src/main/java/me/bobert/netneutrality/core/context/TaskContext.java +++ b/src/main/java/me/bobert/netneutrality/core/context/TaskContext.java @@ -10,7 +10,6 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; -import net.dv8tion.jda.api.interactions.modals.Modal; import java.util.HashMap; import java.util.Map; @@ -28,11 +27,6 @@ public abstract class TaskContext extends AbstractContext { } - @Override - public void reply(Modal modal) { - - } - public abstract String getId(); public void addContextData(String key, Object value) { diff --git a/src/main/java/me/bobert/netneutrality/hooks/EventsHandler.java b/src/main/java/me/bobert/netneutrality/hooks/EventsHandler.java new file mode 100644 index 0000000..97fca8a --- /dev/null +++ b/src/main/java/me/bobert/netneutrality/hooks/EventsHandler.java @@ -0,0 +1,135 @@ +package me.bobert.netneutrality.hooks; + +/* + * Copyright (c) anthorob + * + * https://discord.gg/qUa6zNFZsd + */ + +import me.bobert.netneutrality.context.command.MessageCommandContext; +import me.bobert.netneutrality.context.command.SlashCommandContext; +import me.bobert.netneutrality.context.tasks.ButtonTaskContext; +import me.bobert.netneutrality.context.tasks.EmojiTaskContext; +import me.bobert.netneutrality.context.tasks.ModalTaskContext; +import me.bobert.netneutrality.core.GuildManager; +import me.bobert.netneutrality.core.command.CommandProcessor; +import me.bobert.netneutrality.core.context.CommandContext; +import me.bobert.netneutrality.core.context.Context; +import me.bobert.netneutrality.core.context.TaskContext; +import me.bobert.netneutrality.core.tasks.TaskManager; +import me.bobert.netneutrality.utils.Settings; +import net.dv8tion.jda.api.events.Event; +import net.dv8tion.jda.api.events.GenericEvent; +import net.dv8tion.jda.api.events.guild.GuildJoinEvent; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; +import net.dv8tion.jda.api.hooks.EventListener; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Function; + +public class EventsHandler implements EventListener { + private static final Map, Function> listeners = new ConcurrentHashMap<>(); + private static final Logger logger = LoggerFactory.getLogger(EventsHandler.class); + + static { + addListener(MessageReceivedEvent.class, event -> { + if (event.getAuthor().isBot()) return null; + if (event.isWebhookMessage()) return null; + + String rawMessage = event.getMessage().getContentDisplay().trim(); + String prefix = Settings.getInstance().get("NETNEUTRALITY_BOT_PREFIX", "$"); + + if (rawMessage.startsWith(prefix)) { + return new MessageCommandContext(event); + } + + return null; + }); + + addListener(SlashCommandInteractionEvent.class, SlashCommandContext::new); + addListener(ModalInteractionEvent.class, ModalTaskContext::new); + addListener(ButtonInteractionEvent.class, ButtonTaskContext::new); + addListener(MessageReactionAddEvent.class, EmojiTaskContext::new); + addGenericListener(GuildJoinEvent.class, event -> GuildManager.getManager(event.getGuild()).removeFromDB()); + } + + /** + * Register a listener for an event assocated with a {@link Context}. + * + * @param eventClass the class type of the event to listen for + * @param function the function to handle the event, which takes an event of the specified type and returns a {@link Context} + * @param the type of the event that extends the {@link Event} class + */ + @SuppressWarnings("unchecked") + public static void addListener(Class eventClass, Function function) { + logger.info("Registering listener for {}", eventClass.getSimpleName()); + listeners.put(eventClass, (Function) function); + } + + /** + * Adds a generic listener for a specified event type. The consumer will be invoked + * whenever an event of the specified type is detected. + * + * @param eventClass the class type of the event to listen for + * @param consumer the consumer to handle the event, which takes an event of the specified type and performs an action + * @param the type of the event that extends the {@link Event} class + */ + public static void addGenericListener(Class eventClass, Consumer consumer) { + addListener(eventClass, t -> { + consumer.accept(t); + return null; + }); + } + + @Override + public void onEvent(@NotNull GenericEvent event) { + handleEvent((Event) event); + } + + @SuppressWarnings("unchecked") + private void handleEvent(Event event) { + Class eventClass = event.getClass(); + + while (eventClass != null) { + if (listeners.containsKey(eventClass)) { + Function function = (Function) listeners.get(eventClass); + Context context = function.apply(event); + + if (context == null) { + logger.debug("Handling event {} by generic listener", event); + return; + } + + if (context instanceof CommandContext commandContext) { + handleCommand(commandContext); + return; + } + + if (context instanceof TaskContext taskContext) { + handleTask(taskContext); + return; + } + } + + eventClass = eventClass.getSuperclass(); // Move up the hierarchy + } + } + + private void handleCommand(CommandContext context) { + CommandProcessor processor = new CommandProcessor(context); + processor.dispatch(); + } + + private void handleTask(TaskContext context) { + TaskManager.getInstance().handle(context); + } +} diff --git a/src/main/java/me/bobert/netneutrality/hooks/guilds/ServerJoinHook.java b/src/main/java/me/bobert/netneutrality/hooks/guilds/ServerJoinHook.java deleted file mode 100644 index 9151539..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/guilds/ServerJoinHook.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.bobert.netneutrality.hooks.guilds; - -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.core.GuildManager; -import net.dv8tion.jda.api.events.guild.GuildJoinEvent; -import net.dv8tion.jda.api.events.guild.GuildLeaveEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class ServerJoinHook extends ListenerAdapter { - - @Override - public void onGuildJoin(@NotNull GuildJoinEvent event) { - GuildManager.getManager(event.getGuild()); - } - - @Override - public void onGuildLeave(@NotNull GuildLeaveEvent event) { - GuildManager.getManager(event.getGuild()).removeFromDB(); - } -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/interaction/ButtonInteractionHook.java b/src/main/java/me/bobert/netneutrality/hooks/interaction/ButtonInteractionHook.java deleted file mode 100644 index 14aa283..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/interaction/ButtonInteractionHook.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.bobert.netneutrality.hooks.interaction; -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.context.tasks.ButtonTaskContext; -import me.bobert.netneutrality.core.tasks.TaskManager; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class ButtonInteractionHook extends ListenerAdapter { - - @Override - public void onButtonInteraction(@NotNull ButtonInteractionEvent event) { - ButtonTaskContext context = new ButtonTaskContext(event); - - TaskManager.getInstance().handle(context); - } -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/interaction/ModalInteractionHook.java b/src/main/java/me/bobert/netneutrality/hooks/interaction/ModalInteractionHook.java deleted file mode 100644 index 203af42..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/interaction/ModalInteractionHook.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.bobert.netneutrality.hooks.interaction; -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.context.tasks.ModalTaskContext; -import me.bobert.netneutrality.core.tasks.TaskManager; -import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class ModalInteractionHook extends ListenerAdapter { - - @Override - public void onModalInteraction(@NotNull ModalInteractionEvent event) { - ModalTaskContext context = new ModalTaskContext(event); - - TaskManager.getInstance().handle(context); - } -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/interaction/SlashCommandHook.java b/src/main/java/me/bobert/netneutrality/hooks/interaction/SlashCommandHook.java deleted file mode 100644 index c0ebf8e..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/interaction/SlashCommandHook.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.bobert.netneutrality.hooks.interaction; -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.context.SlashCommandContext; -import me.bobert.netneutrality.core.command.CommandProcessor; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class SlashCommandHook extends ListenerAdapter { - - @Override - public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { - SlashCommandContext commandContext = new SlashCommandContext(event); - CommandProcessor processor = new CommandProcessor(commandContext); - processor.dispatch(); - } -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/message/EditHandler.java b/src/main/java/me/bobert/netneutrality/hooks/message/EditHandler.java deleted file mode 100644 index 82bd172..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/message/EditHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.bobert.netneutrality.hooks.message; - -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.core.GuildManager; -import me.bobert.netneutrality.core.db.SessionManager; -import me.bobert.netneutrality.db.entities.OGuild; -import me.bobert.netneutrality.db.repository.MessageRepository; -import me.bobert.netneutrality.utils.JpaUtils; -import me.bobert.netneutrality.utils.MessageFunction; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.events.message.MessageUpdateEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.hibernate.Session; - -import java.util.stream.Collectors; - -public class EditHandler extends ListenerAdapter { - - @Override - public void onMessageUpdate(MessageUpdateEvent event) { - - if (event.getAuthor().isBot()) return; - - GuildManager guildManager = GuildManager.getManager(event.getGuild()); - - if (guildManager.getGuildEntity().getLogging()) { - OGuild guildEntity = guildManager.getGuildEntity(); - - if (guildEntity.getLogChannel() != null && !guildEntity.getLogChannel().isEmpty()) { - JpaUtils.getWithSession(guildEntity, guildEntity.getGuildId(), session -> { - int size = guildEntity.getLoggings() - .stream() - .filter(oLogging -> oLogging.getId().getChannelId().equals(event.getChannel().getId()) && oLogging.getEnabled()) - .collect(Collectors.toSet()) - .size(); - - if (size > 0) { - TextChannel channel = event.getGuild().getTextChannelById(guildEntity.getLogChannel()); - - if (channel != null) { - MessageRepository repository = new MessageRepository(); - String originalMessage = repository.getMessageString(event.getMessage().getId()); - repository.logEdit(event.getMessage().getId(), event.getMessage().getContentDisplay()); - - channel.sendMessageEmbeds(MessageFunction.buildEditMessage(event.getMember(), event.getMessage(), originalMessage)).queue(); - } - } - }); - } - } - } -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/message/EmojiReactionHook.java b/src/main/java/me/bobert/netneutrality/hooks/message/EmojiReactionHook.java deleted file mode 100644 index 7fb8483..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/message/EmojiReactionHook.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.bobert.netneutrality.hooks.message; -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.context.tasks.EmojiTaskContext; -import me.bobert.netneutrality.core.tasks.TaskManager; -import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class EmojiReactionHook extends ListenerAdapter { - - @Override - public void onMessageReactionAdd(@NotNull MessageReactionAddEvent event) { - EmojiTaskContext context = new EmojiTaskContext(event); - TaskManager.getInstance().handle(context); - } - -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/message/MessageReceivedHook.java b/src/main/java/me/bobert/netneutrality/hooks/message/MessageReceivedHook.java deleted file mode 100644 index 3285ac2..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/message/MessageReceivedHook.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.bobert.netneutrality.hooks.message; -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import me.bobert.netneutrality.context.MessageCommandContext; -import me.bobert.netneutrality.core.command.CommandProcessor; -import me.bobert.netneutrality.utils.Settings; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class MessageReceivedHook extends ListenerAdapter { - - @Override - public void onMessageReceived(@NotNull MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - if (event.isWebhookMessage()) return; - - String rawMessage = event.getMessage().getContentDisplay().trim(); - String prefix = Settings.getInstance().get("NETNEUTRALITY_BOT_PREFIX", "$"); - - if (rawMessage.startsWith(prefix)) { - MessageCommandContext context = new MessageCommandContext(event); - CommandProcessor processor = new CommandProcessor(context); - processor.dispatch(); - } - } -} diff --git a/src/main/java/me/bobert/netneutrality/hooks/voice/VoiceEventHook.java b/src/main/java/me/bobert/netneutrality/hooks/voice/VoiceEventHook.java deleted file mode 100644 index 0733a38..0000000 --- a/src/main/java/me/bobert/netneutrality/hooks/voice/VoiceEventHook.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.bobert.netneutrality.hooks.voice; -/* - * Copyright (c) anthorob - * - * https://discord.gg/qUa6zNFZsd - */ - -import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.jetbrains.annotations.NotNull; - -public class VoiceEventHook extends ListenerAdapter { - - @Override - public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) { - super.onGuildVoiceUpdate(event); - } -} diff --git a/src/main/java/me/bobert/netneutrality/utils/MusicUtils.java b/src/main/java/me/bobert/netneutrality/utils/MusicUtils.java index e6ca08c..7dac00a 100644 --- a/src/main/java/me/bobert/netneutrality/utils/MusicUtils.java +++ b/src/main/java/me/bobert/netneutrality/utils/MusicUtils.java @@ -6,7 +6,7 @@ package me.bobert.netneutrality.utils; */ import me.bobert.netneutrality.context.MusicChannelContext; -import me.bobert.netneutrality.context.SlashCommandContext; +import me.bobert.netneutrality.context.command.SlashCommandContext; import me.bobert.netneutrality.core.context.Context; import me.bobert.netneutrality.exceptions.ContextException; import me.bobert.netneutrality.music.MusicManager; diff --git a/src/main/java/me/bobert/netneutrality/utils/UserFunction.java b/src/main/java/me/bobert/netneutrality/utils/UserFunction.java index b733d32..1f99800 100644 --- a/src/main/java/me/bobert/netneutrality/utils/UserFunction.java +++ b/src/main/java/me/bobert/netneutrality/utils/UserFunction.java @@ -6,7 +6,7 @@ package me.bobert.netneutrality.utils; * https://discord.gg/qUa6zNFZsd */ -import me.bobert.netneutrality.context.SlashCommandContext; +import me.bobert.netneutrality.context.command.SlashCommandContext; import me.bobert.netneutrality.core.context.Context; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member;