diff --git a/src/main/java/net/pingex/discordbot/CommandDispatcher.java b/src/main/java/net/pingex/discordbot/CommandDispatcher.java index ab13da6..0f45df9 100644 --- a/src/main/java/net/pingex/discordbot/CommandDispatcher.java +++ b/src/main/java/net/pingex/discordbot/CommandDispatcher.java @@ -24,6 +24,11 @@ class CommandDispatcher { private Logger logger; + /** + * Singleton instance + */ + private static final CommandDispatcher INSTANCE = new CommandDispatcher(); + /** * Contains all available commands, built using `rebuildCommandList()` */ @@ -47,7 +52,7 @@ class CommandDispatcher /** * Basic Constructor, automatically rebuilds command list from the modules registry */ - public CommandDispatcher() + private CommandDispatcher() { logger = Logger.getLogger(this.getClass().getName()); rebuildCommandList(); @@ -62,6 +67,15 @@ class CommandDispatcher } } + /** + * Gets the unique instance of `CommandDispatcher` + * @return The current instance of `CommandDispatcher` + */ + public static CommandDispatcher getInstance() + { + return INSTANCE; + } + /** * Fired when receiving a message * @param event Event from Discord API @@ -87,31 +101,38 @@ class CommandDispatcher Object[] parsedArray = null; // Conditions - if(commandList.containsKey(fullCommand)) + try { - logger.info("Command invoked (" + event.getMessage().getAuthor().getName() + "#" + event.getMessage().getAuthor().getDiscriminator() + "): " + fullCommand); + if(commandList.containsKey(fullCommand)) + { + logger.info("Command invoked (" + event.getMessage().getAuthor().getName() + "#" + event.getMessage().getAuthor().getDiscriminator() + "): " + fullCommand); - InvokableMethod foundMethod = commandList.get(fullCommand); - parsedArray = new Object[foundMethod.getMethod().getParameterCount()]; - parsedArray[0] = event; + InvokableMethod foundMethod = commandList.get(fullCommand); + parsedArray = new Object[foundMethod.getMethod().getParameterCount()]; + parsedArray[0] = event; - if(foundMethod.getMethod().getParameterCount()-1 == args.size()) - { - for(int i=1; i < foundMethod.getMethod().getParameterCount(); i++) - try - { - parsedArray[i] = parse(foundMethod.getMethod().getParameterTypes()[i], args.get(i-1)); - } catch (IllegalArgumentException e) - { - commandAnswer = "Failed to parse arguments, are they correct ? " + getHelp(fullCommand); - break; - } + if(foundMethod.getMethod().getParameterCount()-1 == args.size()) + { + for(int i=1; i < foundMethod.getMethod().getParameterCount(); i++) + try + { + parsedArray[i] = parse(foundMethod.getMethod().getParameterTypes()[i], args.get(i-1)); + } catch (IllegalArgumentException e) + { + commandAnswer = "Failed to parse arguments, are they correct ? " + commandList.get("internal:help").invoke(event, fullCommand); + break; + } + } + else + commandAnswer = "Invalid arguments. " + commandList.get("internal:help").invoke(event, fullCommand); } else - commandAnswer = "Invalid arguments. " + getHelp(fullCommand); + commandAnswer = "Unknown command"; + } + catch (InvocationTargetException | IllegalAccessException e) + { + logger.severe("Couldn't get help: " + e.getMessage()); } - else - commandAnswer = "Unknown command"; // Run command if(commandAnswer == null) @@ -149,7 +170,7 @@ class CommandDispatcher /** * Rebuilds command list using the module registry. * - It looks for methods with @Command annotation inside class with @Controllable annotation - * - Check his prototype (should be `method(String[]):String`) + * - Check his prototype (should be `method(IDiscordClient, ...):String`) * - Add usable methods in his local registry, using InvokableMethod * @see InvokableMethod * @see ModulesRegistry @@ -213,20 +234,20 @@ class CommandDispatcher } /** - * Scans and print the usage of a command - * @param command Full command `module:command` - * @return Human-readable string + * Gets the command list (cloned to avoid modifications) + * @return The current cloned command list */ - private String getHelp(String command) + public HashMap getCommandList() { - if(!commandList.containsKey(command)) return "No help available for this command."; - InvokableMethod matchingMethod = commandList.get(command); - - StringBuffer toReturn = new StringBuffer("Usage: "); - toReturn.append(commandPrefix + command + " "); - for(int i=1; i) commandList.clone(); + } - return toReturn.toString(); + /** + * Gets the shorthands list (cloned to avoid edits) + * @return The current cloned short list + */ + public HashMap getShortList() + { + return (HashMap) shortList.clone(); } } diff --git a/src/main/java/net/pingex/discordbot/DiscordBot.java b/src/main/java/net/pingex/discordbot/DiscordBot.java index fa5279a..e1dd349 100644 --- a/src/main/java/net/pingex/discordbot/DiscordBot.java +++ b/src/main/java/net/pingex/discordbot/DiscordBot.java @@ -36,13 +36,16 @@ class DiscordBot LOGGER.info("Logged in as \"" + event.getClient().getOurUser().getName() + "#" + event.getClient().getOurUser().getDiscriminator() + "\" (#" + event.getClient().getOurUser().getID() + ")")); enableModules(); - this.client.getDispatcher().registerListener(new CommandDispatcher()); + this.client.getDispatcher().registerListener(CommandDispatcher.getInstance()); } private void enableModules() { LOGGER.info("Enabling modules"); + // Hardcoded internal modules + new InternalCommandsModule(client); + if(!Configuration.exists("plugins", "enable") || Configuration.getValue("plugins", "enable").isEmpty()) { LOGGER.warning("Key \"plugins/enable\" doesn't exist in Configuration. No module will be enabled."); diff --git a/src/main/java/net/pingex/discordbot/InternalCommandsModule.java b/src/main/java/net/pingex/discordbot/InternalCommandsModule.java new file mode 100644 index 0000000..2e4b1f0 --- /dev/null +++ b/src/main/java/net/pingex/discordbot/InternalCommandsModule.java @@ -0,0 +1,42 @@ +package net.pingex.discordbot; + +import sx.blah.discord.api.IDiscordClient; +import sx.blah.discord.handle.impl.events.MessageReceivedEvent; + +import java.util.HashMap; + +/** + * Internal commands of the bot, such as `help`, and so on + * @version 0.1-dev + * @author Raphael "Pingex" NAAS + */ +@Controllable(name="internal") +public class InternalCommandsModule extends AbstractModule +{ + public InternalCommandsModule(IDiscordClient client) + { + super(client); + } + + /** + * Scans and print the usage of a command + * @param command Full command, ie `module:command` + * @return The man of this command + */ + @Command(shorthand = "help") + public String help(MessageReceivedEvent event, String command) + { + if(!command.contains(":") && CommandDispatcher.getInstance().getShortList().containsKey(command)) + command = CommandDispatcher.getInstance().getShortList().get(command); + + if(!CommandDispatcher.getInstance().getCommandList().containsKey(command)) return "No help available for this command."; + InvokableMethod matchingMethod = CommandDispatcher.getInstance().getCommandList().get(command); + + StringBuffer toReturn = new StringBuffer("Usage: "); + toReturn.append((Configuration.exists("general", "commandPrefix") ? Configuration.getValue("general", "commandPrefix") : "!") + command + " "); + for(int i=1; i