From a8aae47e431f75107dce3b9685e4548668dda182 Mon Sep 17 00:00:00 2001 From: Pingex Date: Sat, 16 Apr 2016 00:41:28 +0200 Subject: [PATCH] Proper command analysis and parsing. --- .../pingex/discordbot/CommandDispatcher.java | 48 +++++++++++++++++-- .../pingex/discordbot/InvokableMethod.java | 14 +++++- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/pingex/discordbot/CommandDispatcher.java b/src/main/java/net/pingex/discordbot/CommandDispatcher.java index 5965eb4..b470e83 100644 --- a/src/main/java/net/pingex/discordbot/CommandDispatcher.java +++ b/src/main/java/net/pingex/discordbot/CommandDispatcher.java @@ -49,15 +49,34 @@ public class CommandDispatcher String module = m.group(1); String command = m.group(2); String fullCommand = module + ":" + command; - String[] args = (m.group(3) != null) ? m.group(3).split(" ") : null; + String[] args = (m.group(3) != null) ? m.group(3).split(" ") : new String[0]; - logger.info("Command invoked (" + event.getMessage().getAuthor().getName() + "): " + fullCommand); + logger.info("Command invoked (" + event.getMessage().getAuthor().getName() + "#" + event.getMessage().getAuthor().getDiscriminator() + "): " + fullCommand); try { if(commandList.containsKey(fullCommand)) { - String answer = (String) commandList.get(fullCommand).invoke(new Object[]{args}); // Bricolage + InvokableMethod foundMethod = commandList.get(fullCommand); + Object[] parsedArray = new Object[foundMethod.getMethod().getParameterCount()]; + parsedArray[0] = event; + + if(foundMethod.getMethod().getParameterCount()-1 != args.length) + { + event.getMessage().reply("Invalid arguments"); // TODO: Call !help + return; + } + + for(int i=1; i < foundMethod.getMethod().getParameterCount(); i++) + try + { + parsedArray[i] = parse(foundMethod.getMethod().getParameterTypes()[i], args[i-1]); + } catch (IllegalArgumentException e) + { + event.getMessage().reply("Failed to parse arguments"); // TODO: Call !help + } + + String answer = (String) commandList.get(fullCommand).invoke(parsedArray); if(answer != null) event.getMessage().reply(answer); } else @@ -94,7 +113,7 @@ public class CommandDispatcher String id = i.getClass().getAnnotation(Controllable.class).name() + ":" + j.getName(); logger.info("Found " + id); - if(j.getParameterCount() == 1 && j.getParameterTypes()[0] == String[].class && j.getReturnType() == String.class) + if(j.getParameterCount() >= 1 && j.getParameterTypes()[0] == MessageReceivedEvent.class && j.getReturnType() == String.class) commandList.put(id, new InvokableMethod(j, i)); else logger.warning(id + ": incorrect function prototype, thus won't be added to the command list."); @@ -102,4 +121,25 @@ public class CommandDispatcher logger.info("... Done"); } + + /** + * Parses a String into a primitive variable. Choice between boolean, byte, short, int, long, float, double, string + * @param target Target primitive + * @param value Input value + * @return `null` if the value is null or the string content is "null", or the parsed value. + * @throws IllegalArgumentException If the target primitive/class isn't part of the previous list + */ + public static Object parse(Class target, String value) throws IllegalArgumentException + { + if(value == null || value.equals("null") ) return null; + if(Boolean.class == target || Boolean.TYPE == target) return Boolean.parseBoolean(value); + if(Byte.class == target || Byte.TYPE == target) return Byte.parseByte(value); + if(Short.class == target || Short.TYPE == target) return Short.parseShort(value); + if(Integer.class == target || Integer.TYPE == target) return Integer.parseInt(value); + if(Long.class == target || Long.TYPE == target) return Long.parseLong(value); + if(Float.class == target || Float.TYPE == target) return Float.parseFloat(value); + if(Double.class == target || Double.TYPE == target) return Double.parseDouble(value); + if(String.class == target) return value; + throw new IllegalArgumentException("Unknown target type"); + } } diff --git a/src/main/java/net/pingex/discordbot/InvokableMethod.java b/src/main/java/net/pingex/discordbot/InvokableMethod.java index 4dd697f..b43e897 100644 --- a/src/main/java/net/pingex/discordbot/InvokableMethod.java +++ b/src/main/java/net/pingex/discordbot/InvokableMethod.java @@ -10,8 +10,8 @@ import java.lang.reflect.Method; */ public class InvokableMethod { - public Method method; - public Object object; + private Method method; + private Object object; public InvokableMethod(Method m, Object o) { @@ -23,4 +23,14 @@ public class InvokableMethod { return method.invoke(object, args); } + + public Method getMethod() + { + return method; + } + + public Object getObject() + { + return object; + } }