diff --git a/README.md b/README.md index 157edaf..cec752c 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ A **s**imple **D**iscord **c**ommand **f**ramework **for** **J**ava, supporting de.btobastian.sdcf4j sdcf4j-core - 1.0.0 + 1.0.2 de.btobastian.sdcf4j sdcf4j-javacord - 1.0.0 + 1.0.2 ``` @@ -28,7 +28,7 @@ A **s**imple **D**iscord **c**ommand **f**ramework **for** **J**ava, supporting * [Javacord server](https://discord.gg/0qJ2jjyneLEgG7y3) * [DiscordAPI #java_javacord channel](https://discord.gg/0SBTUU1wZTVXVKEo) -You can find me on one of these servers/channels. Fell free to contact me if you need help. :) +You can find me on one of these servers/channels. Feel free to contact me if you need help. :) #Download For those of you how don't use maven: [Jenkins](http://ci.ketrwu.de/job/sdcf4j/lastSuccessfulBuild/) @@ -93,4 +93,4 @@ CommandHandler cmdHandler = new Discord4JHandler(client); // register the command cmdHandler.registerCommand(new PingCommand()); -``` +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index fbb370d..904058e 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ de.btobastian.sdcf4j sdcf4j pom - 1.0.1 + 1.0.2 UTF-8 diff --git a/sdcf4j-core/pom.xml b/sdcf4j-core/pom.xml index f38dbac..1e79f52 100644 --- a/sdcf4j-core/pom.xml +++ b/sdcf4j-core/pom.xml @@ -5,7 +5,7 @@ sdcf4j de.btobastian.sdcf4j - 1.0.1 + 1.0.2 jar 4.0.0 diff --git a/sdcf4j-core/src/main/java/de/btobastian/sdcf4j/CommandHandler.java b/sdcf4j-core/src/main/java/de/btobastian/sdcf4j/CommandHandler.java index 6202433..b5ab49f 100644 --- a/sdcf4j-core/src/main/java/de/btobastian/sdcf4j/CommandHandler.java +++ b/sdcf4j-core/src/main/java/de/btobastian/sdcf4j/CommandHandler.java @@ -20,6 +20,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -32,6 +33,8 @@ public abstract class CommandHandler { protected final List commandList = new ArrayList<>(); private final HashMap> permissions = new HashMap<>(); + protected String defaultPrefix = ""; + /** * Registers an executor. * @@ -49,7 +52,7 @@ public void registerCommand(CommandExecutor executor) { SimpleCommand command = new SimpleCommand(annotation, method, executor); for (String alias : annotation.aliases()) { // add command to map. It's faster to access it from the map than iterating to the whole list - commands.put(alias.toLowerCase(), command); + commands.put(defaultPrefix + alias.toLowerCase().replace(" ", ""), command); } // we need a list, too, because a HashMap is not ordered. commandList.add(command); @@ -96,6 +99,39 @@ public boolean hasPermission(String userId, String permission) { return false; } + /** + * Gets a list with all commands in the order they were registered. + * This is useful for automatic help commands. + * + * @return A list with all commands the the order they were registered. + */ + public List getCommands() { + return Collections.unmodifiableList(commandList); + } + + /** + * Sets the default command prefix. + * Changing the default prefix after registering a command has no effect! + * + * @param defaultPrefix The default command prefix. + */ + public void setDefaultPrefix(String defaultPrefix) { + if (defaultPrefix == null) { + this.defaultPrefix = ""; + } else { + this.defaultPrefix = defaultPrefix.replace(" ", ""); + } + } + + /** + * Gets the default command prefix. + * + * @return The default command prefix. + */ + public String getDefaultPrefix() { + return defaultPrefix; + } + /** * Checks if you are allowed to do something with the given permission. * diff --git a/sdcf4j-discord4j/pom.xml b/sdcf4j-discord4j/pom.xml index c680f47..20d89f3 100644 --- a/sdcf4j-discord4j/pom.xml +++ b/sdcf4j-discord4j/pom.xml @@ -5,7 +5,7 @@ sdcf4j de.btobastian.sdcf4j - 1.0.1 + 1.0.2 jar 4.0.0 diff --git a/sdcf4j-discord4j/src/main/java/de/btobastian/sdcf4j/handler/Discord4JHandler.java b/sdcf4j-discord4j/src/main/java/de/btobastian/sdcf4j/handler/Discord4JHandler.java index b1b831e..c40b733 100644 --- a/sdcf4j-discord4j/src/main/java/de/btobastian/sdcf4j/handler/Discord4JHandler.java +++ b/sdcf4j-discord4j/src/main/java/de/btobastian/sdcf4j/handler/Discord4JHandler.java @@ -168,10 +168,18 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes String[] args = Arrays.copyOfRange(splitMessage, 1, splitMessage.length); Class[] parameterTypes = command.getMethod().getParameterTypes(); final Object[] parameters = new Object[parameterTypes.length]; + int stringCounter = 0; for (int i = 0; i < parameterTypes.length; i++) { // check all parameters Class type = parameterTypes[i]; if (type == String.class) { - parameters[i] = splitMessage[0]; + if (stringCounter++ == 0) { + parameters[i] = splitMessage[0]; // the first split is the command + } else { + if (args.length + 2 > stringCounter) { + // the first string parameter is the command, the other ones are the arguments + parameters[i] = args[stringCounter - 2]; + } + } } else if (type == String[].class) { parameters[i] = args; } else if (type == IMessage.class) { @@ -184,6 +192,8 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes parameters[i] = event.getMessage().getAuthor(); } else if (type == IGuild.class) { parameters[i] = event.getMessage().getChannel().getGuild(); + } else if (type == Object[].class) { + parameters[i] = getObjectsFromString(event.getClient(), args); } else { // unknown type parameters[i] = null; @@ -192,4 +202,50 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes return parameters; } + /** + * Tries to get objects (like channel, user, integer) from the given strings. + * + * @param client The client. + * @param args The string array. + * @return An object array. + */ + private Object[] getObjectsFromString(IDiscordClient client, String[] args) { + Object[] objects = new Object[args.length]; + for (int i = 0; i < args.length; i++) { + objects[i] = getObjectFromString(client, args[i]); + } + return objects; + } + + /** + * Tries to get an object (like channel, user, integer) from the given string. + * + * @param client The client. + * @param arg The string. + * @return The object. + */ + private Object getObjectFromString(IDiscordClient client, String arg) { + try { + // test int + return Integer.valueOf(arg); + } catch (NumberFormatException e) {} + // test user + if (arg.matches("<@([0-9]*)>")) { + String id = arg.substring(2, arg.length() - 1); + IUser user = client.getUserByID(id); + if (user != null) { + return user; + } + } + // test channel + if (arg.matches("<#([0-9]*)>")) { + String id = arg.substring(2, arg.length() - 1); + IChannel channel = client.getChannelByID(id); + if (channel != null) { + return channel; + } + } + return arg; + } + } diff --git a/sdcf4j-javacord/pom.xml b/sdcf4j-javacord/pom.xml index 0891738..3b74bc8 100644 --- a/sdcf4j-javacord/pom.xml +++ b/sdcf4j-javacord/pom.xml @@ -5,7 +5,7 @@ sdcf4j de.btobastian.sdcf4j - 1.0.1 + 1.0.2 jar 4.0.0 diff --git a/sdcf4j-javacord/src/main/java/de/btobastian/sdcf4j/handler/JavacordHandler.java b/sdcf4j-javacord/src/main/java/de/btobastian/sdcf4j/handler/JavacordHandler.java index ddaed7b..bedd1aa 100644 --- a/sdcf4j-javacord/src/main/java/de/btobastian/sdcf4j/handler/JavacordHandler.java +++ b/sdcf4j-javacord/src/main/java/de/btobastian/sdcf4j/handler/JavacordHandler.java @@ -31,7 +31,6 @@ import de.btobastian.sdcf4j.Sdcf4jMessage; import org.slf4j.Logger; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; @@ -148,8 +147,8 @@ private void invokeMethod(SimpleCommand command, Message message, Object[] param Object reply = null; try { reply = method.invoke(command.getExecutor(), parameters); - } catch (IllegalAccessException | InvocationTargetException e) { - logger.warn("Cannot invoke method {}!", method.getName(), e); + } catch (Exception e) { + logger.warn("An error occurred while invoking method {}!", method.getName(), e); } if (reply != null) { message.reply(String.valueOf(reply)); @@ -169,10 +168,18 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes String[] args = Arrays.copyOfRange(splitMessage, 1, splitMessage.length); Class[] parameterTypes = command.getMethod().getParameterTypes(); final Object[] parameters = new Object[parameterTypes.length]; + int stringCounter = 0; for (int i = 0; i < parameterTypes.length; i++) { // check all parameters Class type = parameterTypes[i]; if (type == String.class) { - parameters[i] = splitMessage[0]; // the first split is the command + if (stringCounter++ == 0) { + parameters[i] = splitMessage[0]; // the first split is the command + } else { + if (args.length + 2 > stringCounter) { + // the first string parameter is the command, the other ones are the arguments + parameters[i] = args[stringCounter - 2]; + } + } } else if (type == String[].class) { parameters[i] = args; } else if (type == Message.class) { @@ -189,6 +196,8 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes if (message.getChannelReceiver() != null) { parameters[i] = message.getChannelReceiver().getServer(); } + } else if (type == Object[].class) { + parameters[i] = getObjectsFromString(api, args); } else { // unknown type parameters[i] = null; @@ -197,4 +206,50 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes return parameters; } + /** + * Tries to get objects (like channel, user, integer) from the given strings. + * + * @param api The api. + * @param args The string array. + * @return An object array. + */ + private Object[] getObjectsFromString(DiscordAPI api, String[] args) { + Object[] objects = new Object[args.length]; + for (int i = 0; i < args.length; i++) { + objects[i] = getObjectFromString(api, args[i]); + } + return objects; + } + + /** + * Tries to get an object (like channel, user, integer) from the given string. + * + * @param api The api. + * @param arg The string. + * @return The object. + */ + private Object getObjectFromString(DiscordAPI api, String arg) { + try { + // test int + return Integer.valueOf(arg); + } catch (NumberFormatException e) {} + // test user + if (arg.matches("<@([0-9]*)>")) { + String id = arg.substring(2, arg.length() - 1); + User user = api.getCachedUserById(id); + if (user != null) { + return user; + } + } + // test channel + if (arg.matches("<#([0-9]*)>")) { + String id = arg.substring(2, arg.length() - 1); + Channel channel = api.getChannelById(id); + if (channel != null) { + return channel; + } + } + return arg; + } + } diff --git a/sdcf4j-jda/pom.xml b/sdcf4j-jda/pom.xml index 6b2dc1e..e223c1a 100644 --- a/sdcf4j-jda/pom.xml +++ b/sdcf4j-jda/pom.xml @@ -5,7 +5,7 @@ sdcf4j de.btobastian.sdcf4j - 1.0.1 + 1.0.2 jar 4.0.0 diff --git a/sdcf4j-jda/src/main/java/de/btobastian/sdcf4j/handler/JDAHandler.java b/sdcf4j-jda/src/main/java/de/btobastian/sdcf4j/handler/JDAHandler.java index 610c16a..e6764ed 100644 --- a/sdcf4j-jda/src/main/java/de/btobastian/sdcf4j/handler/JDAHandler.java +++ b/sdcf4j-jda/src/main/java/de/btobastian/sdcf4j/handler/JDAHandler.java @@ -164,10 +164,18 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes String[] args = Arrays.copyOfRange(splitMessage, 1, splitMessage.length); Class[] parameterTypes = command.getMethod().getParameterTypes(); final Object[] parameters = new Object[parameterTypes.length]; + int stringCounter = 0; for (int i = 0; i < parameterTypes.length; i++) { // check all parameters Class type = parameterTypes[i]; if (type == String.class) { - parameters[i] = splitMessage[0]; + if (stringCounter++ == 0) { + parameters[i] = splitMessage[0]; // the first split is the command + } else { + if (args.length + 2 > stringCounter) { + // the first string parameter is the command, the other ones are the arguments + parameters[i] = args[stringCounter - 2]; + } + } } else if (type == String[].class) { parameters[i] = args; } else if (type == MessageReceivedEvent.class) { @@ -186,6 +194,8 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes parameters[i] = event.getGuild(); } else if (type == Integer.class || type == int.class) { parameters[i] = event.getResponseNumber(); + } else if (type == Object[].class) { + parameters[i] = getObjectsFromString(event.getJDA(), args); } else { // unknown type parameters[i] = null; @@ -194,4 +204,50 @@ private Object[] getParameters(String[] splitMessage, SimpleCommand command, Mes return parameters; } + /** + * Tries to get objects (like channel, user, integer) from the given strings. + * + * @param jda The jda object. + * @param args The string array. + * @return An object array. + */ + private Object[] getObjectsFromString(JDA jda, String[] args) { + Object[] objects = new Object[args.length]; + for (int i = 0; i < args.length; i++) { + objects[i] = getObjectFromString(jda, args[i]); + } + return objects; + } + + /** + * Tries to get an object (like channel, user, integer) from the given string. + * + * @param jda The jda object. + * @param arg The string. + * @return The object. + */ + private Object getObjectFromString(JDA jda, String arg) { + try { + // test int + return Integer.valueOf(arg); + } catch (NumberFormatException e) {} + // test user + if (arg.matches("<@([0-9]*)>")) { + String id = arg.substring(2, arg.length() - 1); + User user = jda.getUserById(id); + if (user != null) { + return user; + } + } + // test channel + if (arg.matches("<#([0-9]*)>")) { + String id = arg.substring(2, arg.length() - 1); + Channel channel = jda.getTextChannelById(id); + if (channel != null) { + return channel; + } + } + return arg; + } + }