Search in sources :

Example 1 with ModuleWrapper

use of de.nikos410.discordbot.framework.ModuleWrapper in project de-DiscordBot by DACH-Discord.

the class DiscordBot method discoverModules.

/**
 * Finds all classes in the package {@link de.nikos410.discordbot.modules} that extend {@link CommandModule}
 * and populates the module map using the module names as keys.
 */
private void discoverModules() {
    // Search in package 'de.nikos410.discordbot.modules'
    final Reflections reflections = new Reflections("de.nikos410.discordbot.modules");
    // Find classes that are subtypes of CommandModule
    final Set<Class<? extends CommandModule>> foundModuleClasses = reflections.getSubTypesOf(CommandModule.class);
    for (Class<? extends CommandModule> currentModuleClass : foundModuleClasses) {
        final ModuleWrapper module = new ModuleWrapper(currentModuleClass);
        modules.put(module.getName(), module);
    }
}
Also used : CommandModule(de.nikos410.discordbot.framework.CommandModule) ModuleWrapper(de.nikos410.discordbot.framework.ModuleWrapper) Reflections(org.reflections.Reflections)

Example 2 with ModuleWrapper

use of de.nikos410.discordbot.framework.ModuleWrapper in project de-DiscordBot by DACH-Discord.

the class DiscordBot method deactivateModule.

/**
 * Deactivate a module so the bot unloads it
 *
 * @param moduleName The name of the module
 * @return true if everything went fine, false if the module does not exist or is already deactivated
 */
public ModuleWrapper deactivateModule(final String moduleName) {
    if (!modules.containsKey(moduleName)) {
        // Module does not exist
        return null;
    }
    final ModuleWrapper module = modules.get(moduleName);
    if (module.getStatus().equals(ModuleStatus.INACTIVE)) {
        // Module is already inactive
        return null;
    }
    LOG.info("Deactivating module '{}'.", moduleName);
    unloadModule(module);
    LOG.info("Rebuilding command map to exclude commands from module \"{}\"", moduleName);
    makeCommandMap();
    // Everything went fine
    return module;
}
Also used : ModuleWrapper(de.nikos410.discordbot.framework.ModuleWrapper)

Example 3 with ModuleWrapper

use of de.nikos410.discordbot.framework.ModuleWrapper in project de-DiscordBot by DACH-Discord.

the class DiscordBot method discoverCommands.

private List<CommandWrapper> discoverCommands(final ModuleWrapper moduleWrapper) {
    LOG.debug("Registering command(s) for module '{}'.", moduleWrapper.getName());
    final List<CommandWrapper> commands = new LinkedList<>();
    final Method[] allMethods = moduleWrapper.getModuleClass().getMethods();
    final List<Method> commandMethods = Arrays.stream(allMethods).filter(module -> module.isAnnotationPresent(CommandSubscriber.class)).collect(Collectors.toList());
    for (final Method method : commandMethods) {
        // Register methods with the @CommandSubscriber as commands
        // All annotations of type CommandSubscriber declared for that Method. Should be exactly 1
        final CommandSubscriber annotation = method.getDeclaredAnnotationsByType(CommandSubscriber.class)[0];
        // Get command properties from annotation
        final String commandName = annotation.command();
        final String commandHelp = annotation.help();
        final boolean pmAllowed = annotation.pmAllowed();
        final PermissionLevel permissionLevel = annotation.permissionLevel();
        final boolean passContext = annotation.passContext();
        final boolean ignoreParameterCount = annotation.ignoreParameterCount();
        final int parameterCount = method.getParameterCount() - 1;
        if ((parameterCount >= 0 && parameterCount <= 5) || ignoreParameterCount) {
            final CommandWrapper commandWrapper = new CommandWrapper(commandName, commandHelp, moduleWrapper, method, pmAllowed, permissionLevel, parameterCount, passContext, ignoreParameterCount);
            commands.add(commandWrapper);
            LOG.debug("Saved command '{}'.", commandName);
        } else {
            LOG.warn("Method '{}' has an invalid number of arguments. Skipping", commandName);
        }
    }
    return commands;
}
Also used : java.util(java.util) Authorization(de.nikos410.discordbot.util.discord.Authorization) LoggerFactory(org.slf4j.LoggerFactory) MessageUpdateEvent(sx.blah.discord.handle.impl.events.guild.channel.message.MessageUpdateEvent) Reflections(org.reflections.Reflections) DiscordIO(de.nikos410.discordbot.util.discord.DiscordIO) ModuleWrapper(de.nikos410.discordbot.framework.ModuleWrapper) ReadyEvent(sx.blah.discord.handle.impl.events.ReadyEvent) MessageReceivedEvent(sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent) JSONObject(org.json.JSONObject) ModuleStatus(de.nikos410.discordbot.framework.ModuleWrapper.ModuleStatus) InitializationException(de.nikos410.discordbot.exception.InitializationException) CommandWrapper(de.nikos410.discordbot.framework.CommandWrapper) Method(java.lang.reflect.Method) Path(java.nio.file.Path) Logger(org.slf4j.Logger) PermissionLevel(de.nikos410.discordbot.framework.PermissionLevel) Files(java.nio.file.Files) CommandModule(de.nikos410.discordbot.framework.CommandModule) EventSubscriber(sx.blah.discord.api.events.EventSubscriber) Instant(java.time.Instant) UserUtils(de.nikos410.discordbot.util.discord.UserUtils) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) TimeUnit(java.util.concurrent.TimeUnit) IDiscordClient(sx.blah.discord.api.IDiscordClient) sx.blah.discord.handle.obj(sx.blah.discord.handle.obj) ChronoUnit(java.time.temporal.ChronoUnit) BotSetup(de.nikos410.discordbot.modules.BotSetup) IOUtil(de.nikos410.discordbot.util.io.IOUtil) Paths(java.nio.file.Paths) DiscordException(sx.blah.discord.util.DiscordException) EventDispatcher(sx.blah.discord.api.events.EventDispatcher) CommandSubscriber(de.nikos410.discordbot.framework.annotations.CommandSubscriber) JSONArray(org.json.JSONArray) CommandWrapper(de.nikos410.discordbot.framework.CommandWrapper) Method(java.lang.reflect.Method) PermissionLevel(de.nikos410.discordbot.framework.PermissionLevel) CommandSubscriber(de.nikos410.discordbot.framework.annotations.CommandSubscriber)

Example 4 with ModuleWrapper

use of de.nikos410.discordbot.framework.ModuleWrapper in project de-DiscordBot by DACH-Discord.

the class DiscordBot method loadModules.

/**
 * Loads modules from classes that are located in the package 'de.nikos410.discordbot.modules' and are annotated
 * with @CommandModule.
 */
private void loadModules() {
    LOG.debug("Loading modules.");
    LOG.info("Found {} total module(s).", this.modules.size());
    // Load modules from all found classes
    for (ModuleWrapper wrapper : this.modules.values()) {
        try {
            loadModule(wrapper);
        } catch (Exception e) {
            LOG.error("Failed to load module " + wrapper.getName() + ".", e);
            wrapper.setStatus(ModuleStatus.FAILED);
        }
    }
    // Wait until the bot is ready to run initializations
    LOG.debug("Waiting until the bot is ready.");
    while (!client.isReady()) {
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            LOG.warn("Sleep was interrupted");
            Thread.currentThread().interrupt();
        }
    }
    LOG.debug("Bot is ready. Running Inits.");
    for (ModuleWrapper wrapper : this.modules.values()) {
        final CommandModule module = wrapper.getInstance();
        if (wrapper.getStatus().equals(ModuleStatus.ACTIVE)) {
            module.initWhenReady();
        }
    }
    // Create command map
    this.makeCommandMap();
    LOG.info("{} module(s) with {} command(s) active.", this.modules.size(), this.commands.size());
}
Also used : CommandModule(de.nikos410.discordbot.framework.CommandModule) ModuleWrapper(de.nikos410.discordbot.framework.ModuleWrapper) InitializationException(de.nikos410.discordbot.exception.InitializationException) InvocationTargetException(java.lang.reflect.InvocationTargetException) DiscordException(sx.blah.discord.util.DiscordException)

Example 5 with ModuleWrapper

use of de.nikos410.discordbot.framework.ModuleWrapper in project de-DiscordBot by DACH-Discord.

the class BotSetup method command_help.

@CommandSubscriber(command = "help", help = "Zeigt diese Hilfe an")
public void command_help(final IMessage message) {
    final EmbedBuilder helpEmbedBuilder = new EmbedBuilder();
    final List<ModuleWrapper> loadedModules = bot.getLoadedModules();
    for (ModuleWrapper module : loadedModules) {
        final StringBuilder moduleHelpBuilder = new StringBuilder();
        for (CommandWrapper command : module.getCommands()) {
            // Only list commands that are available to that user
            if (bot.getUserPermissionLevel(message.getAuthor(), message.getGuild()).getLevel() >= command.getPermissionLevel().getLevel()) {
                moduleHelpBuilder.append(String.format("`%s` - %s%n", command.getName(), command.getHelp()));
            }
        }
        final String helpString = moduleHelpBuilder.toString();
        if (moduleHelpBuilder.length() > 0) {
            helpEmbedBuilder.appendField(module.getDisplayName(), helpString, false);
        }
    }
    final EmbedObject embedObject = helpEmbedBuilder.build();
    DiscordIO.sendEmbed(message.getAuthor().getOrCreatePMChannel(), embedObject);
    if (!message.getChannel().isPrivate()) {
        DiscordIO.sendMessage(message.getChannel(), ":mailbox_with_mail:");
    }
}
Also used : EmbedBuilder(sx.blah.discord.util.EmbedBuilder) ModuleWrapper(de.nikos410.discordbot.framework.ModuleWrapper) CommandWrapper(de.nikos410.discordbot.framework.CommandWrapper) EmbedObject(sx.blah.discord.api.internal.json.objects.EmbedObject) CommandSubscriber(de.nikos410.discordbot.framework.annotations.CommandSubscriber)

Aggregations

ModuleWrapper (de.nikos410.discordbot.framework.ModuleWrapper)8 CommandModule (de.nikos410.discordbot.framework.CommandModule)5 CommandWrapper (de.nikos410.discordbot.framework.CommandWrapper)3 CommandSubscriber (de.nikos410.discordbot.framework.annotations.CommandSubscriber)3 InitializationException (de.nikos410.discordbot.exception.InitializationException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 JSONArray (org.json.JSONArray)2 Reflections (org.reflections.Reflections)2 EventDispatcher (sx.blah.discord.api.events.EventDispatcher)2 DiscordException (sx.blah.discord.util.DiscordException)2 EmbedBuilder (sx.blah.discord.util.EmbedBuilder)2 ModuleStatus (de.nikos410.discordbot.framework.ModuleWrapper.ModuleStatus)1 PermissionLevel (de.nikos410.discordbot.framework.PermissionLevel)1 BotSetup (de.nikos410.discordbot.modules.BotSetup)1 Authorization (de.nikos410.discordbot.util.discord.Authorization)1 DiscordIO (de.nikos410.discordbot.util.discord.DiscordIO)1 UserUtils (de.nikos410.discordbot.util.discord.UserUtils)1 IOUtil (de.nikos410.discordbot.util.io.IOUtil)1 Method (java.lang.reflect.Method)1 Files (java.nio.file.Files)1