package io.mazenmc.skypebot.engine.bot; import com.samczsun.skype4j.chat.messages.ReceivedMessage; import io.mazenmc.skypebot.SkypeBot; import io.mazenmc.skypebot.utils.Resource; import io.mazenmc.skypebot.utils.Utils; import org.reflections.Reflections; import sun.reflect.MethodAccessor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ModuleManager { private static HashMap<String, CommandData> allCommands = new HashMap<>(); private static HashMap<String, CommandData> commandData = new HashMap<>(); private static long lastCommand = 0L; private static void executeCommand(ReceivedMessage chat, CommandData data, Matcher m) { if (data.getCommand().admin()) { try { if (!Arrays.asList(Resource.GROUP_ADMINS).contains(chat.getSender().getUsername())) { Resource.sendMessage(chat, "Access Denied!"); return; } } catch (Exception ignored) { return; } } try { if (data.getCommand().cooldown() > 0 && !Arrays.asList(Resource.GROUP_ADMINS).contains(chat.getSender().getUsername())) { if (!SkypeBot.getInstance().getCooldownHandler().canUse(data.getCommand())) { return; } } long difference = System.currentTimeMillis() - lastCommand; if (difference <= 5000L) { return; } } catch (Exception e) { e.printStackTrace(); } List<Object> a = new ArrayList<>(); a.add(chat); if (m.groupCount() > 0) { for (int i = 1; i <= m.groupCount(); i++) { String g = m.group(i); if (g.contains(".") && Utils.isDouble(g)) { a.add(Double.parseDouble(g)); } else if (Utils.isInteger(g)) { a.add(Integer.parseInt(g)); } else { a.add(g); } } } if (a.size() < data.getMethod().getParameterCount()) { for (int i = a.size(); i < data.getMethod().getParameterCount(); i++) { if (data.getMethod().getParameters()[i].getType().equals(String.class)) { a.add(null); } else { a.add(0); } } } MethodAccessor methodAccessor = null; try { Field methodAccessorField = Method.class.getDeclaredField("methodAccessor"); methodAccessorField.setAccessible(true); methodAccessor = (MethodAccessor) methodAccessorField.get(data.getMethod()); if (methodAccessor == null) { Method acquireMethodAccessorMethod = Method.class.getDeclaredMethod("acquireMethodAccessor", null); acquireMethodAccessorMethod.setAccessible(true); methodAccessor = (MethodAccessor) acquireMethodAccessorMethod.invoke(data.getMethod(), null); lastCommand = System.currentTimeMillis(); } } catch (NoSuchFieldException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { Resource.sendMessage(chat, "Failed..."); } try { methodAccessor.invoke(null, a.toArray()); } catch (Exception e) { Resource.sendMessage(chat, "Failed..."); } } public static HashMap<String, CommandData> getCommands() { return commandData; } public static void loadModules(String modulePackage) { Reflections r = new Reflections(modulePackage); Set<Class<? extends Module>> classes = r.getSubTypesOf(Module.class); classes.forEach(ModuleManager::registerModule); } public static void registerModule(Class<? extends Module> c) { for (Method m : c.getMethods()) { Command command; command = m.getAnnotation(Command.class); if (command != null) { CommandData data = new CommandData(command, m); System.out.println("registered " + command.name()); commandData.put(command.name(), data); allCommands.put(command.name(), data); if (command.alias() != null && command.alias().length > 0) { for (String s : command.alias()) { allCommands.put(s, data); } } } } } public static void removeModule(Class<? extends Module> c) { for (Method m : c.getMethods()) { Command command; command = m.getAnnotation(Command.class); if (command != null) { System.out.println("unregistered " + command.name()); commandData.remove(command.name()); allCommands.remove(command.name()); if (command.alias() != null && command.alias().length > 0) { for (String s : command.alias()) { allCommands.remove(s); } } } } } public static void parseText(ReceivedMessage chat) { String command; String originalCommand; try { command = chat.getContent().asPlaintext(); originalCommand = command; } catch (Exception ignored) { System.out.println("Skype exception occurred"); return; } if (command == null) { System.out.println("Command is null"); return; } System.out.println("Received chat message: " + command + " from " + chat.getChat().getIdentity()); if (command.length() < 1) { System.out.println("low command length"); return; } if (command.startsWith(Resource.COMMAND_PREFIX)) { command = command.substring(1); } String[] commandSplit = command.split(" "); if (commandSplit.length == 0) { System.out.println("nothing"); return; } for (Map.Entry<String, CommandData> s : allCommands.entrySet()) { String match = s.getKey(); if (!s.getValue().getParameterRegex(false).equals("")) { match += " " + s.getValue().getParameterRegex(false); } if (s.getValue().getCommand().command()) { match = Resource.COMMAND_PREFIX + match; } if (s.getValue().getCommand().exact()) { match = "^" + match + "$"; } Pattern r = Pattern.compile(match); Matcher m = r.matcher(originalCommand); if (m.find()) { executeCommand(chat, s.getValue(), m); System.out.println("executed command"); return; } else if (!s.getValue().getParameterRegex(false).equals(s.getValue().getParameterRegex(true))) { match = s.getKey(); if (!s.getValue().getParameterRegex(true).equals("")) { match += " " + s.getValue().getParameterRegex(true); } if (s.getValue().getCommand().command()) { match = Resource.COMMAND_PREFIX + match; } if (s.getValue().getCommand().exact()) { match = "^" + match + "$"; } r = Pattern.compile(match); m = r.matcher(originalCommand); if (m.find()) { executeCommand(chat, s.getValue(), m); return; } } } if (allCommands.containsKey(commandSplit[0].toLowerCase())) { CommandData d = allCommands.get(commandSplit[0].toLowerCase()); Command c = d.getCommand(); String correct = commandSplit[0]; if (!d.getParameterNames().equals("")) { correct += " " + d.getParameterNames(); } if (c.command()) { if (!originalCommand.startsWith(Resource.COMMAND_PREFIX)) { return; } correct = Resource.COMMAND_PREFIX + correct; } Resource.sendMessage(chat, "Incorrect syntax: " + correct); return; } } }