package dev.plex.module; import dev.plex.api.PlexApi; import dev.plex.command.PlexCommand; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; import org.apache.logging.log4j.Logger; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Base class for Plex modules. * *

This class is part of the public module API. Modules use {@link #api()} for * supported integration points.

*/ public abstract class PlexModule { private final List commands = new ArrayList<>(); private final List listeners = new ArrayList<>(); private PlexApi api; private PlexModuleFile plexModuleFile; private File dataFolder; private Logger logger; /** * Creates a Plex module. */ public PlexModule() { } /** * Returns the Plex API facade. * * @return Plex API facade for supported module integrations */ public PlexApi api() { return api; } /** * Called when the module is loaded. */ public void load() { } /** * Called when the module is enabled. */ public void enable() { } /** * Called when the module is disabled. */ public void disable() { } /** * Registers and tracks a listener owned by this module. * * @param listener listener to register */ public void registerListener(Listener listener) { listeners.add(listener); if (api != null) { api.listeners().register(listener); } } /** * Unregisters and stops tracking a listener owned by this module. * * @param listener listener to unregister */ public void unregisterListener(Listener listener) { listeners.remove(listener); if (api != null) { api.listeners().unregister(listener); return; } HandlerList.unregisterAll(listener); } /** * Registers and tracks a command owned by this module. * * @param command command to register */ public void registerCommand(PlexCommand command) { commands.add(command); if (api != null) { api.commands().register(command); } } /** * Unregisters and stops tracking a command owned by this module. * * @param command command to unregister */ public void unregisterCommand(PlexCommand command) { commands.remove(command); if (api != null) { api.commands().unregister(command); } } /** * Looks up a tracked command by name or alias. * * @param name command name or alias * @return matching command, or {@code null} when no command matches */ @Nullable public PlexCommand getCommand(String name) { return commands.stream() .filter(command -> command.getName().equalsIgnoreCase(name) || command.getAliases().stream().map(String::toLowerCase).toList().contains(name.toLowerCase(Locale.ROOT))) .findFirst() .orElse(null); } /** * Adds a default message if the message key is not already configured. * * @param message message key * @param initValue default value to write */ public void addDefaultMessage(String message, Object initValue) { if (api.configuration().messages().getString(message) == null) { api.configuration().messages().set(message, initValue); api.configuration().messages().save(); logger.debug("'{}' message added from {}", message, plexModuleFile.getName()); } } /** * Adds a default message and comments if the message key is not already configured. * * @param message message key * @param initValue default value to write * @param comments comments to write above the message key */ public void addDefaultMessage(String message, Object initValue, String... comments) { if (api.configuration().messages().getString(message) == null) { api.configuration().messages().set(message, initValue); api.configuration().messages().save(); api.configuration().messages().setComments(message, Arrays.asList(comments)); api.configuration().messages().save(); logger.debug("'{}' message added from {}", message, plexModuleFile.getName()); } } /** * Opens a resource from this module's class loader. * * @param filename resource path * @return resource stream, or {@code null} when the resource cannot be opened */ @Nullable public InputStream getResource(@NotNull String filename) { try { URL url = this.getClass().getClassLoader().getResource(filename); if (url == null) { return null; } URLConnection connection = url.openConnection(); connection.setUseCaches(false); return connection.getInputStream(); } catch (IOException ex) { return null; } } /** * Returns commands currently tracked by this module. * * @return commands currently tracked by this module */ public List getCommands() { return commands; } /** * Returns listeners currently tracked by this module. * * @return listeners currently tracked by this module */ public List getListeners() { return listeners; } /** * Returns metadata read from this module's module.yml. * * @return metadata read from this module's module.yml */ public PlexModuleFile getPlexModuleFile() { return plexModuleFile; } /** * Returns the module data folder. * * @return module data folder */ public File getDataFolder() { return dataFolder; } /** * Returns the module logger. * * @return module logger */ public Logger getLogger() { return logger; } /** * Sets the Plex API facade for this module. * * @param api Plex API facade */ public void setApi(PlexApi api) { this.api = api; } /** * Sets metadata read from this module's module.yml. * * @param plexModuleFile module metadata */ public void setPlexModuleFile(PlexModuleFile plexModuleFile) { this.plexModuleFile = plexModuleFile; } /** * Sets the module data folder. * * @param dataFolder data folder */ public void setDataFolder(File dataFolder) { this.dataFolder = dataFolder; } /** * Sets the module logger. * * @param logger logger */ public void setLogger(Logger logger) { this.logger = logger; } }