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.MessageMenuContext; import me.bobert.netneutrality.context.command.SlashCommandContext; import me.bobert.netneutrality.context.command.UserMenuContext; import me.bobert.netneutrality.context.tasks.ButtonTaskContext; import me.bobert.netneutrality.context.tasks.EmojiTaskContext; import me.bobert.netneutrality.context.tasks.MessageTaskContext; import me.bobert.netneutrality.context.tasks.ModalTaskContext; import me.bobert.netneutrality.core.LogHandler; 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.db.service.GuildService; import me.bobert.netneutrality.utils.Settings; import net.dv8tion.jda.api.entities.Message; 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.guild.GuildLeaveEvent; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; 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; } Message message = event.getMessage(); String rawMessage = message.getContentDisplay().trim(); String prefix = Settings.getInstance().get("NETNEUTRALITY_BOT_PREFIX", "$"); if (rawMessage.startsWith(prefix)) { return new MessageCommandContext(event); } return new MessageTaskContext(event); }); addListener(UserContextInteractionEvent.class, UserMenuContext::new); addListener(MessageContextInteractionEvent.class, MessageMenuContext::new); addListener(SlashCommandInteractionEvent.class, SlashCommandContext::new); addListener(ModalInteractionEvent.class, ModalTaskContext::new); addListener(ButtonInteractionEvent.class, ButtonTaskContext::new); addListener(MessageReactionAddEvent.class, EmojiTaskContext::new); addGenericListener(GuildJoinEvent.class, event -> { GuildService service = GuildService.get(event.getGuild()); if (service.isDebugEnabled()) { LogHandler.sendMessageToDebugChannel(event.getGuild(), "Error logging enabled on this channel"); } }); addGenericListener(GuildLeaveEvent.class, event -> GuildService.get(event.getGuild()).deleteGuild()); } /** * 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(@Nonnull 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 instanceof CommandContext commandContext) { handleCommand(commandContext); } if (context instanceof TaskContext taskContext) { handleTask(taskContext); } break; } eventClass = eventClass.getSuperclass(); } } private void handleCommand(CommandContext context) { CommandProcessor processor = new CommandProcessor(context); processor.dispatch(); } private void handleTask(TaskContext context) { TaskManager.getInstance().handle(context); } }