diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java index 92c0c19d..2429d32b 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java @@ -1,8 +1,12 @@ package me.libraryaddict.disguise; import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.utilities.*; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.LibsPremium; +import me.libraryaddict.disguise.utilities.PacketsManager; +import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java index 16640e26..131b3886 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java @@ -13,12 +13,12 @@ import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsMsg; import me.libraryaddict.disguise.utilities.UpdateChecker; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java index 655034ae..a63b3c43 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java @@ -6,14 +6,12 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; import org.bukkit.entity.Player; -import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; /** diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java index 8a37972e..ba2e786f 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java @@ -2,13 +2,11 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.TranslateType; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java index e1774132..d63f1a1b 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java @@ -5,12 +5,12 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -22,7 +22,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -122,7 +121,7 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter } else { ArrayList usedOptions = new ArrayList<>(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (int i = disguiseType.getType() == DisguiseType.PLAYER ? 2 : 1; i < args.length; i++) { String arg = args[i]; @@ -139,19 +138,18 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter if (args.length > 1) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) + if (!info.isParam(boolean.class)) { addMethods = false; + } - if (info.isEnums()) { - tabs.addAll(Arrays.asList(info.getEnums(origArgs[origArgs.length - 1]))); - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -159,7 +157,7 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers + for (Method method : ParamInfoManager .getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java index 34931d96..e7df516b 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java @@ -4,13 +4,12 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -46,7 +45,9 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom Disguise disguise; try { - disguise = DisguiseParser.parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(args, " ")), getPermissions(sender)); + disguise = DisguiseParser + .parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(args, " ")), + getPermissions(sender)); } catch (DisguiseParseException ex) { if (ex.getMessage() != null) { @@ -96,7 +97,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom } else { ArrayList usedOptions = new ArrayList<>(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (int i = disguiseType.getType() == DisguiseType.PLAYER ? 2 : 1; i < args.length; i++) { String arg = args[i]; @@ -113,21 +114,18 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom if (args.length > 1) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) + if (!info.isParam(boolean.class)) { addMethods = false; + } - if (info.isEnums()) { - for (String e : info.getEnums(origArgs[origArgs.length - 1])) { - tabs.add(e); - } - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -135,7 +133,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers + for (Method method : ParamInfoManager .getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java index 52fba925..9d05da45 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java @@ -1,13 +1,11 @@ package me.libraryaddict.disguise.commands; -import me.libraryaddict.disguise.disguisetypes.FlagWatcher; -import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.ChatColor; import org.bukkit.command.Command; @@ -16,7 +14,6 @@ import org.bukkit.command.TabCompleter; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -35,7 +32,7 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl } else { ParamInfo help = null; - for (ParamInfo s : ReflectionFlagWatchers.getParamInfos()) { + for (ParamInfo s : ParamInfoManager.getParamInfos()) { String name = s.getName().replaceAll(" ", ""); if (args[0].equalsIgnoreCase(name) || args[0].equalsIgnoreCase(name + "s")) { @@ -45,11 +42,16 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl } if (help != null) { - if (help.isEnums()) { + if (help.hasValues() && help.canTranslateValues()) { sender.sendMessage(LibsMsg.DHELP_HELP4.get(help.getName(), StringUtils.join(help.getEnums(""), LibsMsg.DHELP_HELP4_SEPERATOR.get()))); } else { - sender.sendMessage(LibsMsg.DHELP_HELP5.get(help.getName(), help.getDescription())); + if (!help.getName().equals(help.getDescriptiveName())) { + sender.sendMessage(LibsMsg.DHELP_HELP6 + .get(help.getName(), help.getDescriptiveName(), help.getDescription())); + } else { + sender.sendMessage(LibsMsg.DHELP_HELP5.get(help.getName(), help.getDescription())); + } } return true; @@ -68,12 +70,11 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl } ArrayList methods = new ArrayList<>(); - HashMap map = new HashMap<>(); Class watcher = type.getWatcherClass(); int ignored = 0; try { - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(watcher)) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(watcher)) { if (args.length < 2 || !args[1].equalsIgnoreCase(LibsMsg.DHELP_SHOW.get())) { boolean allowed = false; @@ -96,19 +97,14 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl } Class c = method.getParameterTypes()[0]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(c); - - if (info == null) - continue; + ParamInfo info = ParamInfoManager.getParamInfo(c); + int value = ParamInfoManager.getValue(method); ChatColor methodColor = ChatColor.YELLOW; - Class declaring = method.getDeclaringClass(); - - if (declaring == LivingWatcher.class) { + if (value == 1) { methodColor = ChatColor.AQUA; - } else if (!(FlagWatcher.class.isAssignableFrom(declaring)) || - declaring == FlagWatcher.class) { + } else if (value == 2) { methodColor = ChatColor.GRAY; } @@ -116,20 +112,13 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl TranslateType.DISGUISE_OPTIONS.get(method.getName()) + ChatColor.DARK_RED + "(" + ChatColor.GREEN + info.getName() + ChatColor.DARK_RED + ")"; - map.put(str, methodColor); - methods.add(str); + methods.add(methodColor + str); } } catch (Exception ex) { ex.printStackTrace(); } - Collections.sort(methods, String.CASE_INSENSITIVE_ORDER); - - for (int i = 0; i < methods.size(); i++) { - methods.set(i, map.get(methods.get(i)) + methods.get(i)); - } - if (methods.isEmpty()) { methods.add(LibsMsg.DHELP_NO_OPTIONS.get()); } @@ -167,7 +156,7 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl tabs.add(type.toReadable().replaceAll(" ", "_")); } - for (ParamInfo s : ReflectionFlagWatchers.getParamInfos()) { + for (ParamInfo s : ParamInfoManager.getParamInfos()) { tabs.add(s.getName().replaceAll(" ", "")); } } else if (DisguiseParser.getDisguisePerm(args[0]) == null) { @@ -187,8 +176,10 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl sender.sendMessage(LibsMsg.DHELP_HELP1.get()); sender.sendMessage(LibsMsg.DHELP_HELP2.get()); - for (ParamInfo s : ReflectionFlagWatchers.getParamInfos()) { - sender.sendMessage(LibsMsg.DHELP_HELP3.get(s.getName().replaceAll(" ", ""), s.getDescription())); + for (ParamInfo s : ParamInfoManager.getParamInfos()) { + sender.sendMessage(LibsMsg.DHELP_HELP3.get(s.getName().replaceAll(" ", "") + + (!s.getName().equals(s.getDescriptiveName()) ? " ~ " + s.getDescriptiveName() : ""), + s.getDescription())); } } } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java index 2a4675b4..f9b4ebb5 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java @@ -3,13 +3,12 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; -import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -21,7 +20,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -99,7 +97,7 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom ArrayList usedOptions = new ArrayList<>(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (int i = disguiseType.getType() == DisguiseType.PLAYER ? 2 : 1; i < args.length; i++) { String arg = args[i]; @@ -116,20 +114,18 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom if (args.length > 0) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) { + if (!info.isParam(boolean.class)) { addMethods = false; } - if (info.isEnums()) { - tabs.addAll(Arrays.asList(info.getEnums(origArgs[origArgs.length - 1]))); - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -137,7 +133,7 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java index a04ed5ac..7a4855be 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java @@ -2,11 +2,11 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -17,7 +17,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -41,8 +40,8 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements // TODO Validate if any disguises have this arg - LibsDisguises.getInstance().getListener().setDisguiseModify(sender.getName(), DisguiseParser - .split(StringUtils.join(args, " "))); + LibsDisguises.getInstance().getListener() + .setDisguiseModify(sender.getName(), DisguiseParser.split(StringUtils.join(args, " "))); sender.sendMessage(LibsMsg.DMODIFYENT_CLICK.get(DisguiseConfig.getDisguiseEntityExpire())); return true; @@ -69,20 +68,18 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements if (args.length > 0) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(perm.getType(), prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(perm.getType(), prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) { + if (!info.isParam(boolean.class)) { addMethods = false; } - if (info.isEnums()) { - tabs.addAll(Arrays.asList(info.getEnums(origArgs[origArgs.length - 1]))); - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -90,8 +87,7 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers - .getDisguiseWatcherMethods(perm.getType().getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(perm.getType().getWatcherClass())) { tabs.add(method.getName()); } } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java index 957558e2..37613764 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java @@ -2,12 +2,12 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -130,7 +130,7 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements ArrayList usedOptions = new ArrayList<>(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (int i = 1; i < args.length; i++) { String arg = args[i]; @@ -147,21 +147,18 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements if (args.length > 1) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) + if (!info.isParam(boolean.class)) { addMethods = false; + } - if (info.isEnums()) { - for (String e : info.getEnums(origArgs[origArgs.length - 1])) { - tabs.add(e); - } - } else { - if (info.getParamClass() == String.class) { - for (Player p : Bukkit.getOnlinePlayers()) { - tabs.add(p.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player p : Bukkit.getOnlinePlayers()) { + tabs.add(p.getName()); } } } @@ -169,8 +166,7 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers - .getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java index 6808e691..2de53c70 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java @@ -3,10 +3,13 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.utilities.*; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; +import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -16,7 +19,6 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import java.lang.reflect.Method; @@ -60,8 +62,8 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements return true; } - if (args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("DisguiseType")) || args[0] - .equalsIgnoreCase(TranslateType.DISGUISES.get("DisguiseType") + "s")) { + if (args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("DisguiseType")) || + args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("DisguiseType") + "s")) { ArrayList classes = new ArrayList<>(); for (DisguiseType type : DisguiseType.values()) { @@ -230,7 +232,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements DisguiseType disguiseType = disguise.getType(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (String arg : args) { if (!method.getName().equalsIgnoreCase(arg) || usedOptions.contains(arg)) continue; @@ -245,19 +247,18 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements if (args.length > 1 + starting) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) + if (!info.isParam(boolean.class)) { addMethods = false; + } - if (info.isEnums()) { - tabs.addAll(Arrays.asList(info.getEnums(origArgs[origArgs.length - 1]))); - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -265,8 +266,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers - .getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java index 48172408..e4d727f9 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java @@ -5,12 +5,12 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.utilities.DisguiseParser; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -21,7 +21,10 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCompleter { @@ -162,7 +165,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom } else { ArrayList usedOptions = new ArrayList<>(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (int i = disguiseType.getType() == DisguiseType.PLAYER ? 3 : 2; i < args.length; i++) { String arg = args[i]; @@ -179,19 +182,18 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom if (args.length > 2) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) + if (!info.isParam(boolean.class)) { addMethods = false; + } - if (info.isEnums()) { - tabs.addAll(Arrays.asList(info.getEnums(origArgs[origArgs.length - 1]))); - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -199,7 +201,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers + for (Method method : ParamInfoManager .getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java index a519e5e5..22c53627 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java @@ -5,10 +5,14 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; -import me.libraryaddict.disguise.utilities.*; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; -import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; +import me.libraryaddict.disguise.utilities.ClassGetter; +import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -23,7 +27,10 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCompleter { private int maxRadius = 30; @@ -269,7 +276,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom } else { ArrayList usedOptions = new ArrayList<>(); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (int i = disguiseType.getType() == DisguiseType.PLAYER ? starting + 2 : starting + 1; i < args.length; i++) { String arg = args[i]; @@ -287,19 +294,18 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom if (args.length > 1 + starting) { String prevArg = args[args.length - 1]; - ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + ParamInfo info = ParamInfoManager.getParamInfo(disguiseType, prevArg); if (info != null) { - if (info.getParamClass() != boolean.class) + if (!info.isParam(boolean.class)) { addMethods = false; + } - if (info.isEnums()) { - tabs.addAll(Arrays.asList(info.getEnums(origArgs[origArgs.length - 1]))); - } else { - if (info.getParamClass() == String.class) { - for (Player player : Bukkit.getOnlinePlayers()) { - tabs.add(player.getName()); - } + if (info.hasValues()) { + tabs.addAll(info.getEnums(origArgs[origArgs.length - 1])); + } else if (info.isParam(String.class)) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); } } } @@ -307,7 +313,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom if (addMethods) { // If this is a method, add. Else if it can be a param of the previous argument, add. - for (Method method : ReflectionFlagWatchers + for (Method method : ParamInfoManager .getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { tabs.add(method.getName()); } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java b/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java index 0d3b916b..58e318e7 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java @@ -29,10 +29,11 @@ public enum LibsMsg { " to use"), DHELP_HELP2(ChatColor.RED + "/disguisehelp " + ChatColor.GREEN + "- View information about the " + "disguise options such as 'RabbitType'"), - DHELP_HELP3(ChatColor.RED + "/disguisehelp %s" + ChatColor.GREEN + " - %s"), + DHELP_HELP3(ChatColor.RED + "/disguisehelp " + ChatColor.DARK_GREEN + "%s" + ChatColor.GREEN + " - %s"), DHELP_HELP4(ChatColor.RED + "%s: " + ChatColor.GREEN + "%s"), DHELP_HELP4_SEPERATOR(ChatColor.RED + ", " + ChatColor.GREEN), DHELP_HELP5(ChatColor.RED + "%s: " + ChatColor.GREEN + "%s"), + DHELP_HELP6(ChatColor.RED + "%s: " + ChatColor.DARK_GREEN + "%s " + ChatColor.GREEN + "%s"), DHELP_OPTIONS("%s options: %s"), DISABLED_LIVING_TO_MISC( ChatColor.RED + "Can't disguise a living entity as a misc disguise. This has been disabled in the config!"), diff --git a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java b/src/main/java/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java deleted file mode 100644 index 3c18e99d..00000000 --- a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java +++ /dev/null @@ -1,289 +0,0 @@ -package me.libraryaddict.disguise.utilities; - -import com.comphenix.protocol.wrappers.BlockPosition; -import com.comphenix.protocol.wrappers.WrappedGameProfile; -import me.libraryaddict.disguise.disguisetypes.*; -import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; -import org.apache.commons.lang.StringUtils; -import org.bukkit.*; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.*; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.MainHand; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.EulerAngle; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; - -public class ReflectionFlagWatchers { - public static class ParamInfo { - private Class paramClass; - private String name; - private String[] enums; - private String description; - - public ParamInfo(Class paramClass, String name, String description) { - this(name, description); - this.paramClass = paramClass; - - Enum[] enums = (Enum[]) paramClass.getEnumConstants(); - - if (enums != null) { - this.enums = new String[enums.length]; - - for (int i = 0; i < enums.length; i++) { - this.enums[i] = enums[i].name(); - } - } - - paramList.add(this); - } - - private ParamInfo(String name, String description) { - this.name = name; - this.description = description; - } - - public ParamInfo(Class paramClass, Enum[] enums, String name, String description) { - this(name, description); - this.enums = new String[enums.length]; - this.paramClass = paramClass; - - for (int i = 0; i < enums.length; i++) { - this.enums[i] = enums[i].name(); - } - - paramList.add(this); - } - - public ParamInfo(Class paramClass, String name, String description, String[] enums) { - this(name, description); - this.enums = enums; - this.paramClass = paramClass; - - paramList.add(this); - } - - public boolean isEnums() { - return enums != null; - } - - public Class getParamClass() { - return paramClass; - } - - public String getName() { - return TranslateType.DISGUISE_OPTIONS_PARAMETERS.get(getRawName()); - } - - public String getRawName() { - return name; - } - - public String getDescription() { - return TranslateType.DISGUISE_OPTIONS_PARAMETERS.get(getRawDescription()); - } - - public String getRawDescription() { - return description; - } - - public String[] getEnums(String tabComplete) { - return enums; - } - } - - private static ArrayList paramList = new ArrayList<>(); - - public static ArrayList getParamInfos() { - return paramList; - } - - public static ParamInfo getParamInfo(Class c) { - for (ParamInfo info : getParamInfos()) { - if (info.getParamClass() != c) - continue; - - return info; - } - - return null; - } - - public static ParamInfo getParamInfo(DisguisePerm disguiseType, String methodName) { - return getParamInfo(disguiseType.getType(), methodName); - } - - public static ParamInfo getParamInfo(DisguiseType disguiseType, String methodName) { - for (Method method : getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { - if (!method.getName().toLowerCase().equals(methodName.toLowerCase())) - continue; - - if (method.getParameterTypes().length != 1) - continue; - - if (method.getAnnotation(Deprecated.class) != null) - continue; - - return getParamInfo(method.getParameterTypes()[0]); - } - - return null; - } - - static { - new ParamInfo(AnimalColor.class, "Animal Color", "View all the colors you can use for an animal color"); - new ParamInfo(Art.class, "Art", "View all the paintings you can use for a painting disguise"); - new ParamInfo(Horse.Color.class, "Horse Color", "View all the colors you can use for a horses color"); - - new ParamInfo(Ocelot.Type.class, "Ocelot Type", "View all the ocelot types you can use for ocelots"); - new ParamInfo(Villager.Profession.class, "Villager Profession", - "View all the professions you can set on a Zombie and Normal Villager"); - new ParamInfo(BlockFace.class, Arrays.copyOf(BlockFace.values(), 6), - "Direction (North, East, South, West, Up, Down)", - "View the directions usable on player setSleeping and shulker direction"); - new ParamInfo(RabbitType.class, "Rabbit Type", "View the kinds of rabbits you can turn into"); - new ParamInfo(TreeSpecies.class, "Tree Species", "View the different types of tree species"); - new ParamInfo(EulerAngle.class, "Euler Angle (X,Y,Z)", "Set the X,Y,Z directions on an armorstand"); - new ParamInfo(MainHand.class, "Main Hand", "Set the main hand for an entity"); - new ParamInfo(Llama.Color.class, "Llama Color", "View all the colors you can use for a llama color"); - new ParamInfo(Parrot.Variant.class, "Parrot Variant", "View the different colors a parrot can be"); - new ParamInfo(Particle.class, "Particle", "The different particles of Minecraft"); - new ParamInfo(TropicalFish.Pattern.class, "Pattern", "Patterns of a tropical fish"); - new ParamInfo(DyeColor.class, "DyeColor", "Dye colors of many different colors"); - - try { - ArrayList colors = new ArrayList<>(); - Class cl = Class.forName("org.bukkit.Color"); - - for (Field field : cl.getFields()) { - if (field.getType() != cl) { - continue; - } - - colors.add(field.getName()); - } - - new ParamInfo(Color.class, "Color", "Colors that can also be defined through RGB", - colors.toArray(new String[0])); - } - catch (ClassNotFoundException e) { - e.printStackTrace(); - } - - ArrayList potionEnums = new ArrayList<>(); - - for (PotionEffectType effectType : PotionEffectType.values()) { - if (effectType == null) - continue; - - potionEnums.add(toReadable(effectType.getName())); - } - - String[] materials = new String[Material.values().length]; - - for (int i = 0; i < Material.values().length; i++) { - materials[i] = Material.values()[i].name(); - } - - new ParamInfo(ItemStack.class, "Item (Material:Damage:Amount:Glow), only Material required", - "An ItemStack compromised of Material:Durability", materials); - - new ParamInfo(ItemStack[].class, - "Four ItemStacks (Material:Damage:Amount:Glow,Material:Damage:Amount:Glow..), only Material required", - "Four ItemStacks separated by an ,", materials) { - @Override - public String[] getEnums(String tabComplete) { - String beginning = tabComplete - .substring(0, tabComplete.contains(",") ? tabComplete.lastIndexOf(",") + 1 : 0); - String end = tabComplete.substring(tabComplete.contains(",") ? tabComplete.lastIndexOf(",") + 1 : 0); - - ArrayList toReturn = new ArrayList<>(); - - for (String material : super.getEnums("")) { - if (!material.toLowerCase().startsWith(end.toLowerCase())) - continue; - - toReturn.add(beginning + material); - } - - return toReturn.toArray(new String[0]); - } - }; - - new ParamInfo(PotionEffectType.class, "Potion Effect", "View all the potion effects you can add", - potionEnums.toArray(new String[0])); - new ParamInfo(String.class, "Text", "A line of text"); - new ParamInfo(boolean.class, "True/False", "True or False", new String[]{"true", "false"}); - new ParamInfo(int.class, "Number", "A whole number, no decimals"); - new ParamInfo(double.class, "Number.0", "A number which can have decimals"); - new ParamInfo(float.class, "Number.0", "A number which can have decimals"); - - new ParamInfo(Horse.Style.class, "Horse Style", "Horse style which is the patterns on the horse"); - new ParamInfo(int[].class, "number,number,number..", "Numbers separated by an ,"); - - new ParamInfo(BlockPosition.class, "Block Position (num,num,num)", "Three numbers separated by a ,"); - new ParamInfo(WrappedGameProfile.class, "GameProfile", "Get the gameprofile here https://sessionserver.mojang" + - ".com/session/minecraft/profile/PLAYER_UUID_GOES_HERE?unsigned=false"); - - Collections.sort(paramList, new Comparator() { - @Override - public int compare(ParamInfo o1, ParamInfo o2) { - return String.CASE_INSENSITIVE_ORDER.compare(o1.getName(), o2.getName()); - } - }); - } - - public static Method[] getDisguiseWatcherMethods(@Nullable Class watcherClass) { - if (watcherClass == null) { - return new Method[0]; - } - - ArrayList methods = new ArrayList<>(Arrays.asList(watcherClass.getMethods())); - - Iterator itel = methods.iterator(); - - while (itel.hasNext()) { - Method method = itel.next(); - - if (method.getParameterTypes().length != 1) { - itel.remove(); - } else if (method.getName().startsWith("get")) { - itel.remove(); - } else if (method.getAnnotation(Deprecated.class) != null) { - itel.remove(); - } else if (getParamInfo(method.getParameterTypes()[0]) == null) { - itel.remove(); - } else if (!method.getReturnType().equals(Void.TYPE)) { - itel.remove(); - } else if (method.getName().equals("removePotionEffect")) { - itel.remove(); - } - } - - for (String methodName : new String[]{"setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf", - "setHearSelfDisguise", "setHidePlayer"}) { - try { - methods.add(Disguise.class.getMethod(methodName, boolean.class)); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } - - return methods.toArray(new Method[0]); - } - - private static String toReadable(String string) { - String[] split = string.split("_"); - - for (int i = 0; i < split.length; i++) { - split[i] = split[i].substring(0, 1) + split[i].substring(1).toLowerCase(); - } - - return StringUtils.join(split, "_"); - } -} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java b/src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java index 80065785..41319a6c 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/TranslateFiller.java @@ -1,9 +1,10 @@ package me.libraryaddict.disguise.utilities; import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.entity.Entity; -import org.bukkit.inventory.ItemStack; import java.lang.reflect.Method; @@ -14,16 +15,29 @@ public class TranslateFiller { public static void fillConfigs() { // Fill the configs - for (ReflectionFlagWatchers.ParamInfo info : ReflectionFlagWatchers.getParamInfos()) { - TranslateType.DISGUISE_OPTIONS_PARAMETERS.save(info.getRawName(), "Used as a disguise option"); + for (ParamInfo info : ParamInfoManager.getParamInfos()) { + TranslateType.DISGUISE_OPTIONS_PARAMETERS.save(info.getRawName(), "A disguise option name, has description " + info.getDescription()); + + if (!info.getRawName().equals(info.getRawDescriptiveName())) { + TranslateType.DISGUISE_OPTIONS_PARAMETERS + .save(info.getRawDescriptiveName(), "A disguise option descriptive name"); + } + TranslateType.DISGUISE_OPTIONS_PARAMETERS .save(info.getRawDescription(), "Description for the disguise option " + info.getRawName()); - if (!info.isEnums() || info.getParamClass() == ItemStack.class || info.getParamClass() == ItemStack[].class) - continue; + if (info.canTranslateValues()) { + for (String e : info.getValues().keySet()) { + TranslateType.DISGUISE_OPTIONS_PARAMETERS + .save(e, "Used for the disguise option " + info.getRawName()); + } + } - for (String e : info.getEnums("")) { - TranslateType.DISGUISE_OPTIONS_PARAMETERS.save(e, "Used for the disguise option " + info.getRawName()); + if (info.getOtherValues() != null) { + for (String e : info.getOtherValues()) { + TranslateType.DISGUISE_OPTIONS_PARAMETERS + .save(e, "Used for the disguise option " + info.getRawName()); + } } } @@ -36,7 +50,7 @@ public class TranslateFiller { TranslateType.DISGUISES.save(StringUtils.join(split, " "), "Name for the " + type.name() + " disguise"); - for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(type.getWatcherClass())) { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(type.getWatcherClass())) { Class para = method.getParameterTypes()[0]; String className = method.getDeclaringClass().getSimpleName().replace("Watcher", ""); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java new file mode 100644 index 00000000..a72fd30a --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParseException.java @@ -0,0 +1,18 @@ +package me.libraryaddict.disguise.utilities.parser; + +import me.libraryaddict.disguise.utilities.LibsMsg; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class DisguiseParseException extends Exception { + private static final long serialVersionUID = 1276971370793124510L; + + public DisguiseParseException() { + super(); + } + + public DisguiseParseException(LibsMsg message, String... params) { + super(message.get((Object[]) params)); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseParser.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java similarity index 56% rename from src/main/java/me/libraryaddict/disguise/utilities/DisguiseParser.java rename to src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java index 6f569698..844b9da9 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseParser.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java @@ -1,1094 +1,745 @@ -package me.libraryaddict.disguise.utilities; - -import com.comphenix.protocol.wrappers.BlockPosition; -import com.comphenix.protocol.wrappers.WrappedGameProfile; -import me.libraryaddict.disguise.DisguiseConfig; -import me.libraryaddict.disguise.disguisetypes.*; -import org.bukkit.*; -import org.bukkit.block.BlockFace; -import org.bukkit.command.CommandSender; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.*; -import org.bukkit.inventory.ItemStack; -import org.bukkit.permissions.PermissionAttachmentInfo; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.EulerAngle; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class DisguiseParser { - public static class DisguiseParseException extends Exception { - private static final long serialVersionUID = 1276971370793124510L; - - public DisguiseParseException() { - super(); - } - - public DisguiseParseException(LibsMsg message, String... params) { - super(message.get((Object[]) params)); - } - } - - public static class DisguisePerm { - private DisguiseType disguiseType; - private String permName; - - public DisguisePerm(DisguiseType disguiseType) { - this.disguiseType = disguiseType; - } - - public DisguisePerm(DisguiseType disguiseType, String disguisePerm) { - this.disguiseType = disguiseType; - permName = disguisePerm; - } - - public Class getEntityClass() { - return getType().getEntityClass(); - } - - public EntityType getEntityType() { - return getType().getEntityType(); - } - - public DisguiseType getType() { - return disguiseType; - } - - public Class getWatcherClass() { - return getType().getWatcherClass(); - } - - public boolean isMisc() { - return getType().isMisc(); - } - - public boolean isMob() { - return getType().isMob(); - } - - public boolean isPlayer() { - return getType().isPlayer(); - } - - public boolean isUnknown() { - return getType().isUnknown(); - } - - public String toReadable() { - return permName == null ? getType().toReadable() : permName; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((disguiseType == null) ? 0 : disguiseType.hashCode()); - result = prime * result + ((permName == null) ? 0 : permName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (obj == null) - return false; - - if (!(obj instanceof DisguisePerm)) - return false; - - DisguisePerm other = (DisguisePerm) obj; - - if (disguiseType != other.disguiseType) - return false; - - return Objects.equals(permName, other.permName); - } - } - - private static Object callValueOf(Class param, String valueString, - String methodName) throws DisguiseParseException { - Object value; - try { - value = param.getMethod("valueOf", String.class).invoke(null, valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - return value; - } - - private static void doCheck(CommandSender sender, HashMap, Boolean> optionPermissions, - ArrayList usedOptions) throws DisguiseParseException { - - if (!passesCheck(sender, optionPermissions, usedOptions)) { - throw new DisguiseParseException(LibsMsg.D_PARSE_NOPERM, usedOptions.get(usedOptions.size() - 1)); - } - } - - private static HashMap getDisguiseOptions(CommandSender sender, String permNode, - DisguisePerm type) { - switch (type.getType()) { - case PLAYER: - case FALLING_BLOCK: - case PAINTING: - case SPLASH_POTION: - case FISHING_HOOK: - case DROPPED_ITEM: - HashMap returns = new HashMap<>(); - - String beginning = "libsdisguises.options." + permNode + "."; - - for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) { - String lowerPerm = permission.getPermission().toLowerCase(); - - if (lowerPerm.startsWith(beginning)) { - String[] split = lowerPerm.substring(beginning.length()).split("\\."); - - if (split.length > 1) { - if (split[0].replace("_", "").equals(type.toReadable().toLowerCase().replace(" ", ""))) { - for (int i = 1; i < split.length; i++) { - returns.put(split[i], permission.getValue()); - } - } - } - } - } - - return returns; - default: - return new HashMap<>(); - } - } - - public static DisguisePerm getDisguisePerm(String name) { - for (DisguisePerm perm : getDisguisePerms()) { - if (!perm.toReadable().replaceAll("[ |_]", "").equalsIgnoreCase(name.replaceAll("[ |_]", ""))) - continue; - - return perm; - } - - if (name.equalsIgnoreCase("p")) - return getDisguisePerm(DisguiseType.PLAYER.toReadable()); - - return null; - } - - public static DisguisePerm[] getDisguisePerms() { - DisguisePerm[] perms = new DisguisePerm[DisguiseType.values().length + - DisguiseConfig.getCustomDisguises().size()]; - int i = 0; - - for (DisguiseType disguiseType : DisguiseType.values()) { - perms[i++] = new DisguisePerm(disguiseType); - } - - for (Entry entry : DisguiseConfig.getCustomDisguises().entrySet()) { - perms[i++] = new DisguisePerm(entry.getValue().getType(), entry.getKey()); - } - - return perms; - } - - private static Entry getMethod(Method[] methods, String methodName, int toStart) { - for (int i = toStart; i < methods.length; i++) { - Method method = methods[i]; - - if (!method.getName().equalsIgnoreCase(methodName)) - continue; - - return new HashMap.SimpleEntry(method, ++i); - } - return null; - } - - private static HashMap, Boolean> getOptions(String perm) { - ArrayList list = new ArrayList<>(); - boolean isRemove = true; - String[] split = perm.split("\\."); - - for (int i = 1; i < split.length; i++) { - String option = split[i]; - boolean value = option.startsWith("-"); - - if (value) { - option = option.substring(1); - isRemove = false; - } - - if (option.equals("baby")) { - option = "setbaby"; - } - - list.add(option); - } - - HashMap, Boolean> options = new HashMap<>(); - options.put(list, isRemove); - - return options; - } - - /** - * Get perms for the node. Returns a hashmap of allowed disguisetypes and their options - */ - public static HashMap, Boolean>> getPermissions(CommandSender sender, - String permissionNode) { - HashMap, Boolean>> singleDisguises = new HashMap<>(); - HashMap, Boolean>> rangeDisguises = new HashMap<>(); - HashMap perms = new HashMap<>(); - - for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) { - String perm = permission.getPermission().toLowerCase(); - - if (perm.startsWith(permissionNode) && (!perms.containsKey(perm) || !permission.getValue())) { - perms.put(perm, permission.getValue()); - } - } - - if (!perms.containsKey(permissionNode + "*") && sender.hasPermission(permissionNode + "*")) { - perms.put(permissionNode + "*", true); - } - - if (!perms.containsKey(permissionNode + "*.*") && sender.hasPermission(permissionNode + "*.*")) { - perms.put(permissionNode + "*.*", true); - } - - for (String perm : perms.keySet()) { - if (perms.get(perm)) { - perm = perm.substring(permissionNode.length()); - - String disguiseType = perm.split("\\.")[0]; - DisguisePerm dPerm = DisguiseParser.getDisguisePerm(disguiseType); - - if (dPerm != null) { - HashMap, Boolean> list; - - if (singleDisguises.containsKey(dPerm)) { - list = singleDisguises.get(dPerm); - } else { - list = new HashMap<>(); - singleDisguises.put(dPerm, list); - } - - HashMap, Boolean> map1 = getOptions(perm); - list.put(map1.keySet().iterator().next(), map1.values().iterator().next()); - } else { - for (DisguisePerm type : getDisguisePerms()) { - HashMap, Boolean> options = null; - Class entityClass = type.getEntityClass(); - - if (disguiseType.equals("mob")) { - if (type.isMob()) { - options = getOptions(perm); - } - } else if (disguiseType.equals("animal") || disguiseType.equals("animals")) { - if (Animals.class.isAssignableFrom(entityClass)) { - options = getOptions(perm); - } - } else if (disguiseType.equals("monster") || disguiseType.equals("monsters")) { - if (Monster.class.isAssignableFrom(entityClass)) { - options = getOptions(perm); - } - } else if (disguiseType.equals("misc")) { - if (type.isMisc()) { - options = getOptions(perm); - } - } else if (disguiseType.equals("ageable")) { - if (Ageable.class.isAssignableFrom(entityClass)) { - options = getOptions(perm); - } - } else if (disguiseType.equals("*")) { - options = getOptions(perm); - } - - if (options != null) { - HashMap, Boolean> list; - - if (rangeDisguises.containsKey(type)) { - list = rangeDisguises.get(type); - } else { - list = new HashMap<>(); - rangeDisguises.put(type, list); - } - - HashMap, Boolean> map1 = getOptions(perm); - - list.put(map1.keySet().iterator().next(), map1.values().iterator().next()); - } - } - } - } - } - - for (String perm : perms.keySet()) { - if (!perms.get(perm)) { - perm = perm.substring(permissionNode.length()); - - String disguiseType = perm.split("\\.")[0]; - DisguisePerm dType = DisguiseParser.getDisguisePerm(disguiseType); - - if (dType != null) { - singleDisguises.remove(dType); - rangeDisguises.remove(dType); - } else { - for (DisguisePerm type : getDisguisePerms()) { - boolean foundHim = false; - Class entityClass = type.getEntityClass(); - - switch (disguiseType) { - case "mob": - if (type.isMob()) { - foundHim = true; - } - - break; - case "animal": - case "animals": - if (Animals.class.isAssignableFrom(entityClass)) { - foundHim = true; - } - - break; - case "monster": - case "monsters": - if (Monster.class.isAssignableFrom(entityClass)) { - foundHim = true; - } - - break; - case "misc": - if (type.isMisc()) { - foundHim = true; - } - - break; - case "ageable": - if (Ageable.class.isAssignableFrom(entityClass)) { - foundHim = true; - } - - break; - case "*": - foundHim = true; - break; - } - - if (foundHim) { - rangeDisguises.remove(type); - } - } - } - } - } - - HashMap, Boolean>> map = new HashMap<>(); - - for (DisguisePerm type : getDisguisePerms()) { - HashMap, Boolean> temp = new HashMap<>(); - - if (singleDisguises.containsKey(type)) { - temp.putAll(singleDisguises.get(type)); - } - - if (rangeDisguises.containsKey(type)) { - temp.putAll(rangeDisguises.get(type)); - } - - if (!temp.isEmpty()) { - map.put(type, temp); - } - } - - return map; - } - - private static boolean isDouble(String string) { - try { - Float.parseFloat(string); - return true; - } - catch (Exception ex) { - return false; - } - } - - private static boolean isInteger(String string) { - try { - Integer.parseInt(string); - return true; - } - catch (Exception ex) { - return false; - } - } - - /** - * Splits a string while respecting quotes - */ - public static String[] split(String string) { - Matcher matcher = Pattern.compile("\"(?:\"(?=\\S)|\\\\\"|[^\"])*(?:[^\\\\]\"(?=\\s|$))|\\S+").matcher(string); - - List list = new ArrayList<>(); - - while (matcher.find()) { - list.add(matcher.group()); - } - - return list.toArray(new String[0]); - } - - /** - * Returns the disguise if it all parsed correctly. Returns a exception with a complete message if it didn't. The - * commandsender is purely used for checking permissions. Would defeat the purpose otherwise. To reach this - * point, the - * disguise has been feed a proper disguisetype. - */ - public static Disguise parseDisguise(CommandSender sender, String permNode, String[] args, - HashMap, Boolean>> permissionMap) throws DisguiseParseException, - IllegalAccessException, InvocationTargetException { - if (sender instanceof Player) { - DisguiseUtilities.setCommandsUsed(); - } - - if (permissionMap.isEmpty()) { - throw new DisguiseParseException(LibsMsg.NO_PERM); - } - - if (args.length == 0) { - throw new DisguiseParseException(LibsMsg.PARSE_NO_ARGS); - } - - // How many args to skip due to the disugise being constructed - // Time to start constructing the disguise. - // We will need to check between all 3 kinds of disguises - int toSkip = 1; - ArrayList usedOptions = new ArrayList<>(); - Disguise disguise = null; - HashMap, Boolean> optionPermissions; - - if (args[0].startsWith("@")) { - if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) { - disguise = DisguiseUtilities.getClonedDisguise(args[0].toLowerCase()); - - if (disguise == null) { - throw new DisguiseParseException(LibsMsg.PARSE_NO_REF, args[0]); - } - } else { - throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_REF); - } - - optionPermissions = (permissionMap.containsKey(new DisguisePerm(disguise.getType())) ? - permissionMap.get(new DisguisePerm(disguise.getType())) : - new HashMap, Boolean>()); - } else { - DisguisePerm disguisePerm = getDisguisePerm(args[0]); - Entry customDisguise = DisguiseConfig.getCustomDisguise(args[0]); - - if (customDisguise != null) { - disguise = customDisguise.getValue().clone(); - } - - if (disguisePerm == null) { - throw new DisguiseParseException(LibsMsg.PARSE_DISG_NO_EXIST, args[0]); - } - - if (disguisePerm.isUnknown()) { - throw new DisguiseParseException(LibsMsg.PARSE_CANT_DISG_UNKNOWN); - } - - if (disguisePerm.getEntityType() == null) { - throw new DisguiseParseException(LibsMsg.PARSE_CANT_LOAD); - } - - if (!permissionMap.containsKey(disguisePerm)) { - throw new DisguiseParseException(LibsMsg.NO_PERM_DISGUISE); - } - - optionPermissions = permissionMap.get(disguisePerm); - - HashMap disguiseOptions = getDisguiseOptions(sender, permNode, disguisePerm); - - if (disguise == null) { - if (disguisePerm.isPlayer()) { - // If he is doing a player disguise - if (args.length == 1) { - // He needs to give the player name - throw new DisguiseParseException(LibsMsg.PARSE_SUPPLY_PLAYER); - } else { - if (!disguiseOptions.isEmpty() && (!disguiseOptions.containsKey(args[1].toLowerCase()) || - !disguiseOptions.get(args[1].toLowerCase()))) { - throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_NAME); - } - - args[1] = args[1].replace("\\_", " "); - - // Construct the player disguise - disguise = new PlayerDisguise(ChatColor.translateAlternateColorCodes('&', args[1])); - toSkip++; - } - } else if (disguisePerm.isMob()) { // Its a mob, use the mob constructor - boolean adult = true; - - if (args.length > 1) { - if (args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("baby")) || - args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("adult"))) { - usedOptions.add("setbaby"); - doCheck(sender, optionPermissions, usedOptions); - adult = args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("adult")); - - toSkip++; - } - } - - disguise = new MobDisguise(disguisePerm.getType(), adult); - } else if (disguisePerm.isMisc()) { - // Its a misc, we are going to use the MiscDisguise constructor. - ItemStack itemStack = new ItemStack(Material.STONE); - int miscId = -1; - int miscData = -1; - String secondArg = null; - - if (args.length > 1) { - // They have defined more arguments! - // If the first arg is a number - if (args[1].contains(":")) { - String[] split = args[1].split(":"); - if (isInteger(split[1])) { - secondArg = split[1]; - } - args[1] = split[0]; - } - - if (isInteger(args[1])) { - miscId = Integer.parseInt(args[1]); - } else { - if (disguisePerm.getType() == DisguiseType.FALLING_BLOCK || - disguisePerm.getType() == DisguiseType.DROPPED_ITEM) { - for (Material mat : Material.values()) { - if (mat.name().replace("_", "").equalsIgnoreCase(args[1].replace("_", ""))) { - itemStack = new ItemStack(mat); - miscId = mat.getId(); - break; - } - } - } - } - if (miscId != -1) { - switch (disguisePerm.getType()) { - case PAINTING: - case FALLING_BLOCK: - case SPLASH_POTION: - case DROPPED_ITEM: - case FISHING_HOOK: - case ARROW: - case TIPPED_ARROW: - case SPECTRAL_ARROW: - case SMALL_FIREBALL: - case FIREBALL: - case WITHER_SKULL: - case TRIDENT: - break; - default: - throw new DisguiseParseException(LibsMsg.PARSE_TOO_MANY_ARGS, - disguisePerm.toReadable(), args[1]); - } - toSkip++; - // If they also defined a data value - if (args.length > 2 && secondArg == null && isInteger(args[2])) { - secondArg = args[2]; - toSkip++; - } - if (secondArg != null) { - if (disguisePerm.getType() != DisguiseType.FALLING_BLOCK && - disguisePerm.getType() != DisguiseType.DROPPED_ITEM) { - throw new DisguiseParseException(LibsMsg.PARSE_USE_SECOND_NUM, - DisguiseType.FALLING_BLOCK.toReadable(), - DisguiseType.DROPPED_ITEM.toReadable()); - } - miscData = Integer.parseInt(secondArg); - } - } - } - - if (!disguiseOptions.isEmpty() && miscId != -1) { - String toCheck = "" + miscId; - - if (miscData == 0 || miscData == -1) { - if (!disguiseOptions.containsKey(toCheck) || !disguiseOptions.get(toCheck)) { - toCheck += ":0"; - } - } else { - toCheck += ":" + miscData; - } - - if (!disguiseOptions.containsKey(toCheck) || !disguiseOptions.get(toCheck)) { - throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, toCheck, - disguisePerm.toReadable()); - } - } - - if (miscId != -1) { - if (disguisePerm.getType() == DisguiseType.FALLING_BLOCK) { - usedOptions.add("setblock"); - - doCheck(sender, optionPermissions, usedOptions); - } else if (disguisePerm.getType() == DisguiseType.PAINTING) { - usedOptions.add("setpainting"); - - doCheck(sender, optionPermissions, usedOptions); - } else if (disguisePerm.getType() == DisguiseType.SPLASH_POTION) { - usedOptions.add("setpotionid"); - - doCheck(sender, optionPermissions, usedOptions); - } - } - - // Construct the disguise - if (disguisePerm.getType() == DisguiseType.DROPPED_ITEM) { - disguise = new MiscDisguise(itemStack); - } else { - disguise = new MiscDisguise(disguisePerm.getType(), miscId, miscData); - } - } - } - } - - // Copy strings to their new range - String[] newArgs = new String[args.length - toSkip]; - System.arraycopy(args, toSkip, newArgs, 0, args.length - toSkip); - - callMethods(sender, disguise, optionPermissions, usedOptions, newArgs); - - // Alright. We've constructed our disguise. - return disguise; - } - - public static void callMethods(CommandSender sender, Disguise disguise, - HashMap, Boolean> optionPermissions, ArrayList usedOptions, - String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, - DisguiseParseException { - Method[] methods = ReflectionFlagWatchers.getDisguiseWatcherMethods(disguise.getWatcher().getClass()); - - for (int i = 0; i < args.length; i += 2) { - String methodNameRaw; - String methodName = TranslateType.DISGUISE_OPTIONS.reverseGet(methodNameRaw = args[i]); - String valueString = TranslateType.DISGUISE_OPTIONS_PARAMETERS - .reverseGet(args.length - 1 == i ? null : args[i + 1]); - Method methodToUse = null; - Object value = null; - DisguiseParseException storedEx = null; - int c = 0; - - while (c < methods.length) { - try { - Entry entry = getMethod(methods, methodName, c); - - if (entry == null) { - break; - } - - methodToUse = entry.getKey(); - c = entry.getValue(); - methodName = TranslateType.DISGUISE_OPTIONS.reverseGet(methodNameRaw = methodToUse.getName()); - Class[] types = methodToUse.getParameterTypes(); - Class param = types[0]; - - if (valueString != null) { - if (int.class == param) { - // Parse to integer - if (isInteger(valueString)) { - value = Integer.parseInt(valueString); - } else { - throw parseToException(param, valueString, methodName); - } - } else if (WrappedGameProfile.class == param && valueString.length() > 20) { - try { - value = DisguiseUtilities.getGson().fromJson(valueString, WrappedGameProfile.class); - } - catch (Exception ex) { - throw parseToException(WrappedGameProfile.class, valueString, methodName); - } - } else if (float.class == param || double.class == param) { - // Parse to number - if (isDouble(valueString)) { - float obj = Float.parseFloat(valueString); - if (param == float.class) { - value = obj; - } else if (param == double.class) { - value = (double) obj; - } - } else { - throw parseToException(param, valueString, methodName); - } - } else if (param == String.class) { - if (methodNameRaw.equalsIgnoreCase("setskin") && valueString.length() > 20) { - value = valueString; - } else { - // Parse to string - value = ChatColor.translateAlternateColorCodes('&', valueString); - } - } else if (param == EulerAngle.class) { - String[] split = valueString.split(","); - - if (split.length != 3) - throw parseToException(param, valueString, methodName); - - if (!isDouble(split[0]) || !isDouble(split[1]) || !isDouble(split[2])) - throw parseToException(param, valueString, methodName); - - value = new EulerAngle(Double.parseDouble(split[0]), Double.parseDouble(split[1]), - Double.parseDouble(split[2])); - } else if (param == Villager.Profession.class) { - try { - value = Villager.Profession.valueOf(valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == AnimalColor.class) { - // Parse to animal color - try { - value = AnimalColor.valueOf(valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param.getName().equals("org.bukkit.entity.Llama$Color")) { - try { - value = Llama.Color.valueOf(valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == TropicalFish.Pattern.class) { - try { - value = TropicalFish.Pattern.valueOf(valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == DyeColor.class) { - try { - value = DyeColor.valueOf(valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == ItemStack.class) { - // Parse to itemstack - value = parseToItemstack(param, methodName, valueString); - } else if (param == ItemStack[].class) { - // Parse to itemstack array - ItemStack[] items = new ItemStack[4]; - - String[] split = valueString.split(",", -1); - - if (split.length == 4) { - for (int a = 0; a < 4; a++) { - try { - items[a] = parseToItemstack(param, methodName, split[a]); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } - } else { - throw parseToException(param, valueString, methodName); - } - - value = items; - } else if (param == Horse.Color.class) { - // Parse to horse color - value = callValueOf(param, valueString, methodName); - } else if (param == Horse.Style.class) { - // Parse to horse style - value = callValueOf(param, valueString, methodName); - } else if (param == Art.class) { - // Parse to art type - value = callValueOf(param, valueString, methodName); - } else if (param == Ocelot.Type.class) { - // Parse to ocelot type - value = callValueOf(param, valueString, methodName); - } else if (param == Color.class) { - Class cl = Class.forName("org.bukkit.Color"); - - try { - value = cl.getField(valueString.toUpperCase()).get(null); - } - catch (Exception ex) { - try { - String[] split = valueString.split(","); - - if (split.length == 1) { - value = Color.fromRGB(Integer.parseInt(split[0])); - } else if (split.length == 3) { - value = Color.fromRGB(Integer.parseInt(split[0]), Integer.parseInt(split[1]), - Integer.parseInt(split[2])); - } else { - throw new Exception(); - } - } - catch (Exception ex2) { - throw parseToException(param, valueString, methodName); - } - } - } else if (param.getSimpleName().equals("TreeSpecies")) { - // Parse to tree species - value = callValueOf(param, valueString, methodName); - } else if (param == PotionEffectType.class) { - // Parse to potion effect - try { - PotionEffectType potionType = PotionEffectType.getByName(valueString.toUpperCase()); - - if (potionType == null && isInteger(valueString)) { - potionType = PotionEffectType.getById(Integer.parseInt(valueString)); - } - - if (potionType == null) { - throw new DisguiseParseException(); - } - - value = potionType; - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == int[].class) { - String[] split = valueString.split(","); - - int[] values = new int[split.length]; - - for (int b = 0; b < values.length; b++) { - try { - values[b] = Integer.parseInt(split[b]); - } - catch (NumberFormatException ex) { - throw parseToException(param, valueString, methodName); - } - } - - value = values; - } else if (param == BlockFace.class) { - try { - BlockFace face = BlockFace.valueOf(valueString.toUpperCase()); - - if (face.ordinal() > 5) { - throw new DisguiseParseException(); - } - - value = face; - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == RabbitType.class) { - try { - for (RabbitType type : RabbitType.values()) { - if (type.name().replace("_", "") - .equalsIgnoreCase(valueString.replace("_", "").replace(" ", ""))) { - value = type; - - break; - } - } - - if (value == null) { - throw new Exception(); - } - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == BlockPosition.class) { - try { - String[] split = valueString.split(","); - - if (split.length != 3) { - throw new Exception(); - } - - value = new BlockPosition(Integer.parseInt(split[0]), Integer.parseInt(split[1]), - Integer.parseInt(split[2])); - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } else if (param == Parrot.Variant.class) { - value = callValueOf(param, valueString, methodName); - } else if (param == Particle.class) { - try { - for (Particle type : Particle.values()) { - if (type.name().replace("_", "") - .equalsIgnoreCase(valueString.replace("_", "").replace(" ", ""))) { - value = type; - - break; - } - } - - if (value == null) { - throw new Exception(); - } - } - catch (Exception ex) { - throw parseToException(param, valueString, methodName); - } - } - } - - if (value == null && boolean.class == param) { - if (valueString == null) { - value = true; - i--; - } else if (valueString - .equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("true"))) { - value = true; - } else if (valueString - .equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("false"))) { - value = false; - } else { - if (getMethod(methods, valueString, 0) == null) { - throw parseToException(param, valueString, methodName); - } else { - value = true; - i--; - } - } - } - - if (value != null) { - break; - } - } - catch (DisguiseParseException ex) { - storedEx = ex; - methodToUse = null; - } - catch (Exception ex) { - ex.printStackTrace(); - methodToUse = null; - } - } - - if (methodToUse == null) { - if (storedEx != null) { - throw storedEx; - } - - throw new DisguiseParseException(LibsMsg.PARSE_OPTION_NA, methodName); - } - if (value == null) { - throw new DisguiseParseException(LibsMsg.PARSE_NO_OPTION_VALUE, methodName); - } - - if (!usedOptions.contains(methodNameRaw.toLowerCase())) { - usedOptions.add(methodNameRaw.toLowerCase()); - } - - doCheck(sender, optionPermissions, usedOptions); - - if (FlagWatcher.class.isAssignableFrom(methodToUse.getDeclaringClass())) { - methodToUse.invoke(disguise.getWatcher(), value); - } else { - methodToUse.invoke(disguise, value); - } - } - } - - private static DisguiseParseException parseToException(Class paramType, String receivedInstead, String methodName) { - return new DisguiseParseException(LibsMsg.PARSE_EXPECTED_RECEIVED, - ReflectionFlagWatchers.getParamInfo(paramType).getName(), receivedInstead, methodName); - } - - private static ItemStack parseToItemstack(Class param, String method, String string) throws DisguiseParseException { - String[] split = string.split(":", -1); - - if (split[0].isEmpty() || split[0].equalsIgnoreCase("null")) { - return null; - } - - Material material = Material.getMaterial(split[0]); - - if (material != null) { - short itemDura = 0; - int amount = 1; - boolean enchanted = false; - - for (int i = 1; i < split.length; i++) { - String s = split[i]; - - if (!enchanted && - (s.equalsIgnoreCase("glow") || s.equalsIgnoreCase("glowing") || s.equalsIgnoreCase("enchant") || - s.equalsIgnoreCase("enchanted"))) { - enchanted = true; - } else if (isInteger(s)) { - if (i == (enchanted ? 2 : 1)) { - itemDura = Short.parseShort(s); - } else if (i == (enchanted ? 3 : 2)) { - amount = Integer.parseInt(s); - } else { - throw parseToException(param, string, "%s"); - } - } else { - throw parseToException(param, string, "%s"); - } - } - - ItemStack itemStack = new ItemStack(material, amount, itemDura); - - if (enchanted) { - itemStack.addUnsafeEnchantment(Enchantment.DURABILITY, 1); - } - - return itemStack; - } else { - if (split.length == 1) { - throw parseToException(param, string, "%s"); - } else { - throw parseToException(param, string, "%s"); - } - } - } - - public static boolean passesCheck(CommandSender sender, HashMap, Boolean> theirPermissions, - ArrayList usedOptions) { - if (theirPermissions == null) - return false; - - boolean hasPermission = false; - - for (ArrayList list : theirPermissions.keySet()) { - boolean myPerms = true; - - for (String option : usedOptions) { - if (!sender.getName().equals("CONSOLE") && option.equalsIgnoreCase("setInvisible") && - DisguiseConfig.isDisabledInvisibility()) { - myPerms = false; - } - - if (!(theirPermissions.get(list) && list.contains("*")) && - (list.contains(option) != theirPermissions.get(list))) { - myPerms = false; - break; - } - } - - if (myPerms) { - hasPermission = true; - } - } - - return hasPermission; - } -} +package me.libraryaddict.disguise.utilities.parser; + +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.*; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.permissions.PermissionAttachmentInfo; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DisguiseParser { + public static class DisguisePerm { + private DisguiseType disguiseType; + private String permName; + + public DisguisePerm(DisguiseType disguiseType) { + this.disguiseType = disguiseType; + } + + public DisguisePerm(DisguiseType disguiseType, String disguisePerm) { + this.disguiseType = disguiseType; + permName = disguisePerm; + } + + public Class getEntityClass() { + return getType().getEntityClass(); + } + + public EntityType getEntityType() { + return getType().getEntityType(); + } + + public DisguiseType getType() { + return disguiseType; + } + + public Class getWatcherClass() { + return getType().getWatcherClass(); + } + + public boolean isMisc() { + return getType().isMisc(); + } + + public boolean isMob() { + return getType().isMob(); + } + + public boolean isPlayer() { + return getType().isPlayer(); + } + + public boolean isUnknown() { + return getType().isUnknown(); + } + + public String toReadable() { + return permName == null ? getType().toReadable() : permName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((disguiseType == null) ? 0 : disguiseType.hashCode()); + result = prime * result + ((permName == null) ? 0 : permName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (!(obj instanceof DisguisePerm)) + return false; + + DisguisePerm other = (DisguisePerm) obj; + + if (disguiseType != other.disguiseType) + return false; + + return Objects.equals(permName, other.permName); + } + } + + private static void doCheck(CommandSender sender, HashMap, Boolean> optionPermissions, + ArrayList usedOptions) throws DisguiseParseException { + + if (!passesCheck(sender, optionPermissions, usedOptions)) { + throw new DisguiseParseException(LibsMsg.D_PARSE_NOPERM, usedOptions.get(usedOptions.size() - 1)); + } + } + + private static HashMap getDisguiseOptions(CommandSender sender, String permNode, + DisguisePerm type) { + switch (type.getType()) { + case PLAYER: + case FALLING_BLOCK: + case PAINTING: + case SPLASH_POTION: + case FISHING_HOOK: + case DROPPED_ITEM: + HashMap returns = new HashMap<>(); + + String beginning = "libsdisguises.options." + permNode + "."; + + for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) { + String lowerPerm = permission.getPermission().toLowerCase(); + + if (lowerPerm.startsWith(beginning)) { + String[] split = lowerPerm.substring(beginning.length()).split("\\."); + + if (split.length > 1) { + if (split[0].replace("_", "").equals(type.toReadable().toLowerCase().replace(" ", ""))) { + for (int i = 1; i < split.length; i++) { + returns.put(split[i], permission.getValue()); + } + } + } + } + } + + return returns; + default: + return new HashMap<>(); + } + } + + public static DisguisePerm getDisguisePerm(String name) { + for (DisguisePerm perm : getDisguisePerms()) { + if (!perm.toReadable().replaceAll("[ |_]", "").equalsIgnoreCase(name.replaceAll("[ |_]", ""))) + continue; + + return perm; + } + + if (name.equalsIgnoreCase("p")) + return getDisguisePerm(DisguiseType.PLAYER.toReadable()); + + return null; + } + + public static DisguisePerm[] getDisguisePerms() { + DisguisePerm[] perms = new DisguisePerm[DisguiseType.values().length + + DisguiseConfig.getCustomDisguises().size()]; + int i = 0; + + for (DisguiseType disguiseType : DisguiseType.values()) { + perms[i++] = new DisguisePerm(disguiseType); + } + + for (Entry entry : DisguiseConfig.getCustomDisguises().entrySet()) { + perms[i++] = new DisguisePerm(entry.getValue().getType(), entry.getKey()); + } + + return perms; + } + + private static HashMap, Boolean> getOptions(String perm) { + ArrayList list = new ArrayList<>(); + boolean isRemove = true; + String[] split = perm.split("\\."); + + for (int i = 1; i < split.length; i++) { + String option = split[i]; + boolean value = option.startsWith("-"); + + if (value) { + option = option.substring(1); + isRemove = false; + } + + if (option.equals("baby")) { + option = "setbaby"; + } + + list.add(option); + } + + HashMap, Boolean> options = new HashMap<>(); + options.put(list, isRemove); + + return options; + } + + /** + * Get perms for the node. Returns a hashmap of allowed disguisetypes and their options + */ + public static HashMap, Boolean>> getPermissions(CommandSender sender, + String permissionNode) { + HashMap, Boolean>> singleDisguises = new HashMap<>(); + HashMap, Boolean>> rangeDisguises = new HashMap<>(); + HashMap perms = new HashMap<>(); + + for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) { + String perm = permission.getPermission().toLowerCase(); + + if (perm.startsWith(permissionNode) && (!perms.containsKey(perm) || !permission.getValue())) { + perms.put(perm, permission.getValue()); + } + } + + if (!perms.containsKey(permissionNode + "*") && sender.hasPermission(permissionNode + "*")) { + perms.put(permissionNode + "*", true); + } + + if (!perms.containsKey(permissionNode + "*.*") && sender.hasPermission(permissionNode + "*.*")) { + perms.put(permissionNode + "*.*", true); + } + + for (String perm : perms.keySet()) { + if (perms.get(perm)) { + perm = perm.substring(permissionNode.length()); + + String disguiseType = perm.split("\\.")[0]; + DisguisePerm dPerm = DisguiseParser.getDisguisePerm(disguiseType); + + if (dPerm != null) { + HashMap, Boolean> list; + + if (singleDisguises.containsKey(dPerm)) { + list = singleDisguises.get(dPerm); + } else { + list = new HashMap<>(); + singleDisguises.put(dPerm, list); + } + + HashMap, Boolean> map1 = getOptions(perm); + list.put(map1.keySet().iterator().next(), map1.values().iterator().next()); + } else { + for (DisguisePerm type : getDisguisePerms()) { + HashMap, Boolean> options = null; + Class entityClass = type.getEntityClass(); + + if (disguiseType.equals("mob")) { + if (type.isMob()) { + options = getOptions(perm); + } + } else if (disguiseType.equals("animal") || disguiseType.equals("animals")) { + if (Animals.class.isAssignableFrom(entityClass)) { + options = getOptions(perm); + } + } else if (disguiseType.equals("monster") || disguiseType.equals("monsters")) { + if (Monster.class.isAssignableFrom(entityClass)) { + options = getOptions(perm); + } + } else if (disguiseType.equals("misc")) { + if (type.isMisc()) { + options = getOptions(perm); + } + } else if (disguiseType.equals("ageable")) { + if (Ageable.class.isAssignableFrom(entityClass)) { + options = getOptions(perm); + } + } else if (disguiseType.equals("*")) { + options = getOptions(perm); + } + + if (options != null) { + HashMap, Boolean> list; + + if (rangeDisguises.containsKey(type)) { + list = rangeDisguises.get(type); + } else { + list = new HashMap<>(); + rangeDisguises.put(type, list); + } + + HashMap, Boolean> map1 = getOptions(perm); + + list.put(map1.keySet().iterator().next(), map1.values().iterator().next()); + } + } + } + } + } + + for (String perm : perms.keySet()) { + if (!perms.get(perm)) { + perm = perm.substring(permissionNode.length()); + + String disguiseType = perm.split("\\.")[0]; + DisguisePerm dType = DisguiseParser.getDisguisePerm(disguiseType); + + if (dType != null) { + singleDisguises.remove(dType); + rangeDisguises.remove(dType); + } else { + for (DisguisePerm type : getDisguisePerms()) { + boolean foundHim = false; + Class entityClass = type.getEntityClass(); + + switch (disguiseType) { + case "mob": + if (type.isMob()) { + foundHim = true; + } + + break; + case "animal": + case "animals": + if (Animals.class.isAssignableFrom(entityClass)) { + foundHim = true; + } + + break; + case "monster": + case "monsters": + if (Monster.class.isAssignableFrom(entityClass)) { + foundHim = true; + } + + break; + case "misc": + if (type.isMisc()) { + foundHim = true; + } + + break; + case "ageable": + if (Ageable.class.isAssignableFrom(entityClass)) { + foundHim = true; + } + + break; + case "*": + foundHim = true; + break; + } + + if (foundHim) { + rangeDisguises.remove(type); + } + } + } + } + } + + HashMap, Boolean>> map = new HashMap<>(); + + for (DisguisePerm type : getDisguisePerms()) { + HashMap, Boolean> temp = new HashMap<>(); + + if (singleDisguises.containsKey(type)) { + temp.putAll(singleDisguises.get(type)); + } + + if (rangeDisguises.containsKey(type)) { + temp.putAll(rangeDisguises.get(type)); + } + + if (!temp.isEmpty()) { + map.put(type, temp); + } + } + + return map; + } + + private static boolean isDouble(String string) { + try { + Float.parseFloat(string); + return true; + } + catch (Exception ex) { + return false; + } + } + + private static boolean isInteger(String string) { + try { + Integer.parseInt(string); + return true; + } + catch (Exception ex) { + return false; + } + } + + /** + * Splits a string while respecting quotes + */ + public static String[] split(String string) { + Matcher matcher = Pattern.compile("\"(?:\"(?=\\S)|\\\\\"|[^\"])*(?:[^\\\\]\"(?=\\s|$))|\\S+").matcher(string); + + List list = new ArrayList<>(); + + while (matcher.find()) { + list.add(matcher.group()); + } + + return list.toArray(new String[0]); + } + + /** + * Returns the disguise if it all parsed correctly. Returns a exception with a complete message if it didn't. The + * commandsender is purely used for checking permissions. Would defeat the purpose otherwise. To reach this + * point, the + * disguise has been feed a proper disguisetype. + */ + public static Disguise parseDisguise(CommandSender sender, String permNode, String[] args, + HashMap, Boolean>> permissionMap) throws DisguiseParseException, + IllegalAccessException, InvocationTargetException { + if (sender instanceof Player) { + DisguiseUtilities.setCommandsUsed(); + } + + if (permissionMap.isEmpty()) { + throw new DisguiseParseException(LibsMsg.NO_PERM); + } + + if (args.length == 0) { + throw new DisguiseParseException(LibsMsg.PARSE_NO_ARGS); + } + + // How many args to skip due to the disugise being constructed + // Time to start constructing the disguise. + // We will need to check between all 3 kinds of disguises + int toSkip = 1; + ArrayList usedOptions = new ArrayList<>(); + Disguise disguise = null; + HashMap, Boolean> optionPermissions; + + if (args[0].startsWith("@")) { + if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) { + disguise = DisguiseUtilities.getClonedDisguise(args[0].toLowerCase()); + + if (disguise == null) { + throw new DisguiseParseException(LibsMsg.PARSE_NO_REF, args[0]); + } + } else { + throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_REF); + } + + optionPermissions = (permissionMap.containsKey(new DisguisePerm(disguise.getType())) ? + permissionMap.get(new DisguisePerm(disguise.getType())) : + new HashMap, Boolean>()); + } else { + DisguisePerm disguisePerm = getDisguisePerm(args[0]); + Entry customDisguise = DisguiseConfig.getCustomDisguise(args[0]); + + if (customDisguise != null) { + disguise = customDisguise.getValue().clone(); + } + + if (disguisePerm == null) { + throw new DisguiseParseException(LibsMsg.PARSE_DISG_NO_EXIST, args[0]); + } + + if (disguisePerm.isUnknown()) { + throw new DisguiseParseException(LibsMsg.PARSE_CANT_DISG_UNKNOWN); + } + + if (disguisePerm.getEntityType() == null) { + throw new DisguiseParseException(LibsMsg.PARSE_CANT_LOAD); + } + + if (!permissionMap.containsKey(disguisePerm)) { + throw new DisguiseParseException(LibsMsg.NO_PERM_DISGUISE); + } + + optionPermissions = permissionMap.get(disguisePerm); + + HashMap disguiseOptions = getDisguiseOptions(sender, permNode, disguisePerm); + + if (disguise == null) { + if (disguisePerm.isPlayer()) { + // If he is doing a player disguise + if (args.length == 1) { + // He needs to give the player name + throw new DisguiseParseException(LibsMsg.PARSE_SUPPLY_PLAYER); + } else { + if (!disguiseOptions.isEmpty() && (!disguiseOptions.containsKey(args[1].toLowerCase()) || + !disguiseOptions.get(args[1].toLowerCase()))) { + throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_NAME); + } + + args[1] = args[1].replace("\\_", " "); + + // Construct the player disguise + disguise = new PlayerDisguise(ChatColor.translateAlternateColorCodes('&', args[1])); + toSkip++; + } + } else if (disguisePerm.isMob()) { // Its a mob, use the mob constructor + boolean adult = true; + + if (args.length > 1) { + if (args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("baby")) || + args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("adult"))) { + usedOptions.add("setbaby"); + doCheck(sender, optionPermissions, usedOptions); + adult = args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("adult")); + + toSkip++; + } + } + + disguise = new MobDisguise(disguisePerm.getType(), adult); + } else if (disguisePerm.isMisc()) { + // Its a misc, we are going to use the MiscDisguise constructor. + ItemStack itemStack = new ItemStack(Material.STONE); + int miscId = -1; + int miscData = -1; + String secondArg = null; + + if (args.length > 1) { + // They have defined more arguments! + // If the first arg is a number + if (args[1].contains(":")) { + String[] split = args[1].split(":"); + if (isInteger(split[1])) { + secondArg = split[1]; + } + args[1] = split[0]; + } + + if (isInteger(args[1])) { + miscId = Integer.parseInt(args[1]); + } else { + if (disguisePerm.getType() == DisguiseType.FALLING_BLOCK || + disguisePerm.getType() == DisguiseType.DROPPED_ITEM) { + for (Material mat : Material.values()) { + if (mat.name().replace("_", "").equalsIgnoreCase(args[1].replace("_", ""))) { + itemStack = new ItemStack(mat); + miscId = mat.getId(); + break; + } + } + } + } + if (miscId != -1) { + switch (disguisePerm.getType()) { + case PAINTING: + case FALLING_BLOCK: + case SPLASH_POTION: + case DROPPED_ITEM: + case FISHING_HOOK: + case ARROW: + case TIPPED_ARROW: + case SPECTRAL_ARROW: + case SMALL_FIREBALL: + case FIREBALL: + case WITHER_SKULL: + case TRIDENT: + break; + default: + throw new DisguiseParseException(LibsMsg.PARSE_TOO_MANY_ARGS, + disguisePerm.toReadable(), args[1]); + } + toSkip++; + // If they also defined a data value + if (args.length > 2 && secondArg == null && isInteger(args[2])) { + secondArg = args[2]; + toSkip++; + } + if (secondArg != null) { + if (disguisePerm.getType() != DisguiseType.FALLING_BLOCK && + disguisePerm.getType() != DisguiseType.DROPPED_ITEM) { + throw new DisguiseParseException(LibsMsg.PARSE_USE_SECOND_NUM, + DisguiseType.FALLING_BLOCK.toReadable(), + DisguiseType.DROPPED_ITEM.toReadable()); + } + miscData = Integer.parseInt(secondArg); + } + } + } + + if (!disguiseOptions.isEmpty() && miscId != -1) { + String toCheck = "" + miscId; + + if (miscData == 0 || miscData == -1) { + if (!disguiseOptions.containsKey(toCheck) || !disguiseOptions.get(toCheck)) { + toCheck += ":0"; + } + } else { + toCheck += ":" + miscData; + } + + if (!disguiseOptions.containsKey(toCheck) || !disguiseOptions.get(toCheck)) { + throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, toCheck, + disguisePerm.toReadable()); + } + } + + if (miscId != -1) { + if (disguisePerm.getType() == DisguiseType.FALLING_BLOCK) { + usedOptions.add("setblock"); + + doCheck(sender, optionPermissions, usedOptions); + } else if (disguisePerm.getType() == DisguiseType.PAINTING) { + usedOptions.add("setpainting"); + + doCheck(sender, optionPermissions, usedOptions); + } else if (disguisePerm.getType() == DisguiseType.SPLASH_POTION) { + usedOptions.add("setpotionid"); + + doCheck(sender, optionPermissions, usedOptions); + } + } + + // Construct the disguise + if (disguisePerm.getType() == DisguiseType.DROPPED_ITEM) { + disguise = new MiscDisguise(itemStack); + } else { + disguise = new MiscDisguise(disguisePerm.getType(), miscId, miscData); + } + } + } + } + + // Copy strings to their new range + String[] newArgs = new String[args.length - toSkip]; + System.arraycopy(args, toSkip, newArgs, 0, args.length - toSkip); + + callMethods(sender, disguise, optionPermissions, usedOptions, newArgs); + + // Alright. We've constructed our disguise. + return disguise; + } + + public static void callMethods(CommandSender sender, Disguise disguise, + HashMap, Boolean> optionPermissions, ArrayList usedOptions, + String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, + DisguiseParseException { + Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass()); + List list = new ArrayList<>(Arrays.asList(args)); + + for (int argIndex = 0; argIndex < args.length; argIndex++) { + // This is the method name they provided + String methodNameProvided = list.remove(0); + // Translate the name they provided, to a name we recognize + String methodNameJava = TranslateType.DISGUISE_OPTIONS.reverseGet(methodNameProvided); + // The method we'll use + Method methodToUse = null; + Object valueToSet = null; + DisguiseParseException parseException = null; + + for (Method method : methods) { + if (!method.getName().equalsIgnoreCase(methodNameJava)) { + continue; + } + + Class paramType = method.getParameterTypes()[0]; + + ParamInfo paramInfo = ParamInfoManager.getParamInfo(paramType); + + try { + // Store how many args there were before calling the param + int argCount = list.size(); + + if (argCount < paramInfo.getMinArguments()) { + throw new DisguiseParseException(LibsMsg.PARSE_NO_OPTION_VALUE, + TranslateType.DISGUISE_OPTIONS.reverseGet(method.getName())); + } + + valueToSet = paramInfo.fromString(list); + + if (valueToSet == null && !paramInfo.canReturnNull()) { + throw new IllegalStateException(); + } + + // Skip ahead as many args as were consumed on successful parse + argIndex += argCount - list.size(); + + methodToUse = method; + // We've found a method which will accept a valid value, break + break; + } + catch (Exception ignored) { + ignored.printStackTrace(); + parseException = new DisguiseParseException(LibsMsg.PARSE_EXPECTED_RECEIVED, + paramInfo.getDescriptiveName(), list.isEmpty() ? null : list.get(0), + TranslateType.DISGUISE_OPTIONS.reverseGet(method.getName())); + } + } + + if (methodToUse == null) { + if (parseException != null) { + throw parseException; + } + + throw new DisguiseParseException(LibsMsg.PARSE_OPTION_NA, methodNameProvided); + } + + if (!usedOptions.contains(methodToUse.getName().toLowerCase())) { + usedOptions.add(methodToUse.getName().toLowerCase()); + } + + doCheck(sender, optionPermissions, usedOptions); + + if (FlagWatcher.class.isAssignableFrom(methodToUse.getDeclaringClass())) { + methodToUse.invoke(disguise.getWatcher(), valueToSet); + } else { + methodToUse.invoke(disguise, valueToSet); + } + } + } + + public static boolean passesCheck(CommandSender sender, HashMap, Boolean> theirPermissions, + ArrayList usedOptions) { + if (theirPermissions == null) + return false; + + boolean hasPermission = false; + + for (ArrayList list : theirPermissions.keySet()) { + boolean myPerms = true; + + for (String option : usedOptions) { + if (!sender.getName().equals("CONSOLE") && option.equalsIgnoreCase("setInvisible") && + DisguiseConfig.isDisabledInvisibility()) { + myPerms = false; + } + + if (!(theirPermissions.get(list) && list.contains("*")) && + (list.contains(option) != theirPermissions.get(list))) { + myPerms = false; + break; + } + } + + if (myPerms) { + hasPermission = true; + } + } + + return hasPermission; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/ParamInfoManager.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/ParamInfoManager.java new file mode 100644 index 00000000..24effcac --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/ParamInfoManager.java @@ -0,0 +1,135 @@ +package me.libraryaddict.disguise.utilities.parser; + +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; +import me.libraryaddict.disguise.utilities.parser.DisguiseParser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfoTypes; +import org.bukkit.ChatColor; + +import javax.annotation.Nullable; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +public class ParamInfoManager { + private static List paramList; + + public static List getParamInfos() { + return paramList; + } + + public static ParamInfo getParamInfo(Class c) { + for (ParamInfo info : getParamInfos()) { + if (!info.isParam(c)) { + continue; + } + + return info; + } + + return null; + } + + public static ParamInfo getParamInfo(DisguisePerm disguiseType, String methodName) { + return getParamInfo(disguiseType.getType(), methodName); + } + + public static ParamInfo getParamInfo(DisguiseType disguiseType, String methodName) { + for (Method method : getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + if (!method.getName().toLowerCase().equals(methodName.toLowerCase())) + continue; + + if (method.getParameterTypes().length != 1) + continue; + + if (method.getAnnotation(Deprecated.class) != null) + continue; + + return getParamInfo(method.getParameterTypes()[0]); + } + + return null; + } + + static { + paramList = new ParamInfoTypes().getParamInfos(); + + //paramList.sort((o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getName(), o2.getName())); + } + + public static Method[] getDisguiseWatcherMethods(@Nullable Class watcherClass) { + if (watcherClass == null) { + return new Method[0]; + } + + ArrayList methods = new ArrayList<>(Arrays.asList(watcherClass.getMethods())); + + Iterator itel = methods.iterator(); + + while (itel.hasNext()) { + Method method = itel.next(); + + if (method.getParameterTypes().length != 1) { + itel.remove(); + } else if (method.getName().startsWith("get")) { + itel.remove(); + } else if (method.isAnnotationPresent(Deprecated.class)) { + itel.remove(); + } else if (getParamInfo(method.getParameterTypes()[0]) == null) { + itel.remove(); + } else if (!method.getReturnType().equals(Void.TYPE)) { + itel.remove(); + } else if (method.getName().equals("removePotionEffect")) { + itel.remove(); + } + } + + // Order first by their declaring class, the top class (SheepWatcher) goes before (FlagWatcher) + // Order methods in the same watcher by their name from A to Z + methods.sort((m1, m2) -> { + int v1 = getValue(m1); + int v2 = getValue(m2); + + if (v1 != v2) { + return v1 - v2; + } + + return String.CASE_INSENSITIVE_ORDER.compare(m1.getName(), m2.getName()); + }); + + // Add these last as it's what we want to present to be called the least + for (String methodName : new String[]{"setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf", + "setHearSelfDisguise", "setHidePlayer"}) { + try { + methods.add(Disguise.class.getMethod(methodName, boolean.class)); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + return methods.toArray(new Method[0]); + } + + /** + * Value of the method, used namely for displaying the more unique methods to a disguise + */ + public static int getValue(Method method) { + ChatColor methodColor = ChatColor.YELLOW; + + Class declaring = method.getDeclaringClass(); + + if (declaring == LivingWatcher.class) { + return 1; + } else if (!(FlagWatcher.class.isAssignableFrom(declaring)) || declaring == FlagWatcher.class) { + return 2; + } + + return 0; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/ParsedDisguise.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/ParsedDisguise.java new file mode 100644 index 00000000..4f681464 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/ParsedDisguise.java @@ -0,0 +1,8 @@ +package me.libraryaddict.disguise.utilities.parser; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParsedDisguise { + private String[] arguments; +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java new file mode 100644 index 00000000..dc9ae682 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfo.java @@ -0,0 +1,140 @@ +package me.libraryaddict.disguise.utilities.parser.params; + +import me.libraryaddict.disguise.utilities.TranslateType; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public abstract class ParamInfo { + private Class paramClass; + private String descriptiveName; + private String name; + private Map possibleValues; + /** + * Used for translations, namely ItemStack and it's 'Glowing' and 'null' counterparts + */ + private String[] otherValues; + private String description; + + public ParamInfo(Class paramClass, String name, String description) { + this(paramClass, name, name, description); + } + + public ParamInfo(Class paramClass, String name, String descriptiveName, String description) { + this.name = name; + this.paramClass = paramClass; + this.descriptiveName = descriptiveName; + this.description = description; + } + + public ParamInfo(Class paramClass, String name, String description, Enum[] possibleValues) { + this(paramClass, name, name, description); + } + + public ParamInfo(Class paramClass, String name, String descriptiveName, String description, Enum[] possibleValues) { + this(paramClass, name, descriptiveName, description); + + this.possibleValues = new HashMap<>(); + + for (Enum anEnum : possibleValues) { + this.getValues().put(anEnum.name(), anEnum); + } + } + + public ParamInfo(Class paramClass, String name, String description, String[] possibleValues) { + this(paramClass, name, name, description); + } + + public ParamInfo(Class paramClass, String name, String descriptiveName, String description, + String[] possibleValues) { + this(paramClass, name, descriptiveName, description); + + this.possibleValues = new HashMap<>(); + + for (String value : possibleValues) { + getValues().put(value, value); + } + } + + public boolean canTranslateValues() { + return getValues() != null; + } + + public String[] getOtherValues() { + return this.otherValues; + } + + public void setOtherValues(String... otherValues) { + this.otherValues = otherValues; + } + + public boolean canReturnNull() { + return false; + } + + protected abstract Object fromString(String string); + + public Object fromString(List arguments) { + // Don't consume a string immediately, if it errors we need to check other param types + String string = arguments.get(0); + + Object value = fromString(string); + + arguments.remove(0); + + return value; + } + + public int getMinArguments() { + return 1; + } + + public boolean hasValues() { + return getValues() != null; + } + + private Class getParamClass() { + return paramClass; + } + + public boolean isParam(Class paramClass) { + return getParamClass() == paramClass; + } + + public String getName() { + return TranslateType.DISGUISE_OPTIONS_PARAMETERS.get(getRawName()); + } + + public String getDescriptiveName() { + return TranslateType.DISGUISE_OPTIONS_PARAMETERS.get(getRawDescriptiveName()); + } + + public String getRawName() { + return this.name; + } + + public String getRawDescriptiveName() { + return descriptiveName; + } + + public String getDescription() { + return TranslateType.DISGUISE_OPTIONS_PARAMETERS.get(getRawDescription()); + } + + public String getRawDescription() { + return description; + } + + public Map getValues() { + return this.possibleValues; + } + + public Set getEnums(String tabComplete) { + return getValues().keySet(); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfoTypes.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfoTypes.java new file mode 100644 index 00000000..a519951c --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/ParamInfoTypes.java @@ -0,0 +1,162 @@ +package me.libraryaddict.disguise.utilities.parser.params; + +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import me.libraryaddict.disguise.disguisetypes.AnimalColor; +import me.libraryaddict.disguise.disguisetypes.RabbitType; +import me.libraryaddict.disguise.utilities.parser.params.types.ParamInfoEnum; +import me.libraryaddict.disguise.utilities.parser.params.types.base.*; +import me.libraryaddict.disguise.utilities.parser.params.types.custom.*; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MainHand; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.EulerAngle; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoTypes { + /** + * Constructor values are listed here for continuity + */ + public List getParamInfos() { + List paramInfos = new ArrayList<>(); + + // Register enum types + paramInfos.add(new ParamInfoEnum(AnimalColor.class, "Animal Color", + "View all the colors you can use for an animal color")); + paramInfos + .add(new ParamInfoEnum(Art.class, "Art", "View all the paintings you can use for a painting disguise")); + paramInfos.add(new ParamInfoEnum(Horse.Color.class, "Horse Color", + "View all the colors you can use for a horses color")); + + paramInfos.add(new ParamInfoEnum(Ocelot.Type.class, "Ocelot Type", + "View all the ocelot types you can use for ocelots")); + paramInfos.add(new ParamInfoEnum(Villager.Profession.class, "Villager Profession", + "View all the professions you can set on a Zombie and Normal Villager")); + paramInfos.add(new ParamInfoEnum(BlockFace.class, "Direction", "Direction (North, East, South, West, Up, Down)", + "View the directions usable on player setSleeping and shulker direction", + Arrays.copyOf(BlockFace.values(), 6))); + paramInfos + .add(new ParamInfoEnum(RabbitType.class, "Rabbit Type", "View the kinds of rabbits you can turn into")); + paramInfos + .add(new ParamInfoEnum(TreeSpecies.class, "Tree Species", "View the different types of tree species")); + + paramInfos.add(new ParamInfoEnum(MainHand.class, "Main Hand", "Set the main hand for an entity")); + paramInfos.add(new ParamInfoEnum(Llama.Color.class, "Llama Color", + "View all the colors you can use for a llama color")); + paramInfos.add(new ParamInfoEnum(Parrot.Variant.class, "Parrot Variant", + "View the different colors a parrot can be")); + paramInfos.add(new ParamInfoEnum(Particle.class, "Particle", "The different particles of Minecraft")); + paramInfos.add(new ParamInfoEnum(TropicalFish.Pattern.class, "Pattern", "Patterns of a tropical fish")); + paramInfos.add(new ParamInfoEnum(DyeColor.class, "DyeColor", "Dye colors of many different colors")); + paramInfos.add(new ParamInfoEnum(Horse.Style.class, "Horse Style", + "Horse style which is the patterns on the horse")); + + // Register custom types + paramInfos.add(new ParamInfoEulerAngle(EulerAngle.class, "Euler Angle", "Euler Angle (X,Y,Z)", + "Set the X,Y,Z directions on an armorstand")); + paramInfos.add(new ParamInfoEnum(Color.class, "Color", "Colors that can also be defined through RGB", + getColors())); + paramInfos.add(new ParamInfoEnum(Material.class, "Material", "A material used for blocks and items", + getMaterials())); + paramInfos.add(new ParamInfoItemStack(ItemStack.class, "ItemStack", "ItemStack (Material:Amount?:Glow?)", + "An ItemStack compromised of Material:Amount:Glow, only requires Material", getMaterials())); + paramInfos.add(new ParamInfoItemStackArray(ItemStack[].class, "ItemStack[]", + "Four ItemStacks (Material:Amount?:Glow?,Material:Amount?:Glow?..)", + "Four ItemStacks separated by a comma", getMaterials())); + paramInfos.add(new ParamInfoPotionType(PotionEffectType.class, "Potion Effect", + "View all the potion effects you can add", getPotions())); + + paramInfos.add(new ParamInfoBlockPosition(BlockPosition.class, "Block Position", "Block Position (num,num,num)", + "Three numbers separated by a ,")); + paramInfos.add(new ParamInfoGameProfile(WrappedGameProfile.class, "GameProfile", + "Get the gameprofile here https://sessionserver.mojang" + + ".com/session/minecraft/profile/PLAYER_UUID_GOES_HERE?unsigned=false")); + + // Register base types + paramInfos.add(new ParamInfoBoolean("Boolean", "True/False", "True or False", new String[]{"true", "false"})); + paramInfos.add(new ParamInfoString(String.class, "Text", "A line of text")); + paramInfos.add(new ParamInfoInteger("Number", "A whole number without decimals")); + paramInfos.add(new ParamInfoFloat("Number.0", "A number which can have decimal places")); + paramInfos.add(new ParamInfoDouble("Number.0", "A number which can have decimal places")); + + return paramInfos; + } + + private String[] getColors() { + try { + List colors = new ArrayList<>(); + Class cl = Class.forName("org.bukkit.Color"); + + for (Field field : cl.getFields()) { + if (field.getType() != cl) { + continue; + } + + colors.add(field.getName()); + } + + return colors.toArray(new String[0]); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + return null; + } + + private Material[] getMaterials() { + List list = new ArrayList<>(); + + for (Material material : Material.values()) { + try { + Field field = Material.class.getField(material.name()); + + // Ignore all legacies materials + if (field.isAnnotationPresent(Deprecated.class)) { + continue; + } + + list.add(material); + } + catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + + return list.toArray(new Material[0]); + } + + private String[] getPotions() { + List potionEnums = new ArrayList<>(); + + for (PotionEffectType effectType : PotionEffectType.values()) { + if (effectType == null) + continue; + + potionEnums.add(toReadable(effectType.getName())); + } + + return potionEnums.toArray(new String[0]); + } + + private String toReadable(String string) { + String[] split = string.split("_"); + + for (int i = 0; i < split.length; i++) { + split[i] = split[i].substring(0, 1) + split[i].substring(1).toLowerCase(); + } + + return StringUtils.join(split, "_"); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/ParamInfoEnum.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/ParamInfoEnum.java new file mode 100644 index 00000000..e4153e7f --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/ParamInfoEnum.java @@ -0,0 +1,41 @@ +package me.libraryaddict.disguise.utilities.parser.params.types; + +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +import java.util.Map; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoEnum extends ParamInfo { + public ParamInfoEnum(Class paramClass, String name, String description) { + super(paramClass, name, name, description, paramClass.getEnumConstants()); + } + + public ParamInfoEnum(Class paramClass, String name, String valueType, String description, Enum[] possibleValues) { + super(paramClass, name, valueType, description); + } + + public ParamInfoEnum(Class paramClass, String name, String description, Enum[] possibleValues) { + super(paramClass, name, name, description); + } + + public ParamInfoEnum(Class paramClass, String name, String description, String[] possibleValues) { + super(paramClass, name, name, description); + } + + @Override + protected Object fromString(String string) { + string = string.replace("_", ""); + + for (Map.Entry entry : getValues().entrySet()) { + if (!entry.getKey().replace("_", "").equalsIgnoreCase(string)) { + continue; + } + + return entry.getValue(); + } + + return null; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java new file mode 100644 index 00000000..684470fc --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoBoolean.java @@ -0,0 +1,48 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.base; + +import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +import java.util.List; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoBoolean extends ParamInfo { + public ParamInfoBoolean(String name, String valueType, String description, String[] possibleValues) { + super(Boolean.class, name, valueType, description, possibleValues); + } + + @Override + public boolean isParam(Class classType) { + return classType == Boolean.class || classType == Boolean.TYPE; + } + + @Override + public Object fromString(List list) { + if (list.isEmpty()) { + return true; + } + + String string = list.get(0); + + if (string.equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("true"))) { + list.remove(0); + } else if (string.equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("false"))) { + list.remove(0); + return false; + } + + return true; + } + + @Override + protected Object fromString(String string) { + throw new IllegalStateException("This shouldn't be called"); + } + + @Override + public int getMinArguments() { + return 0; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoDouble.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoDouble.java new file mode 100644 index 00000000..97874087 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoDouble.java @@ -0,0 +1,22 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.base; + +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoDouble extends ParamInfo { + public ParamInfoDouble(String name, String description) { + super(null, name, description); + } + + @Override + public boolean isParam(Class classType) { + return classType == Double.class || classType == Double.TYPE; + } + + @Override + protected Object fromString(String string) { + return Double.parseDouble(string); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoFloat.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoFloat.java new file mode 100644 index 00000000..7830c3bb --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoFloat.java @@ -0,0 +1,22 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.base; + +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoFloat extends ParamInfo { + public ParamInfoFloat(String name, String description) { + super(Number.class, name, description); + } + + @Override + public boolean isParam(Class classType) { + return classType == Float.class || classType == Float.TYPE; + } + + @Override + protected Object fromString(String string) { + return Float.parseFloat(string); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoInteger.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoInteger.java new file mode 100644 index 00000000..0b0e2dc3 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoInteger.java @@ -0,0 +1,22 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.base; + +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoInteger extends ParamInfo { + public ParamInfoInteger(String name, String description) { + super(null, name, description); + } + + @Override + public boolean isParam(Class classType) { + return classType == Integer.class || classType == Integer.TYPE; + } + + @Override + protected Object fromString(String string) { + return Integer.parseInt(string); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoString.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoString.java new file mode 100644 index 00000000..d6da3512 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/base/ParamInfoString.java @@ -0,0 +1,18 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.base; + +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; +import org.bukkit.ChatColor; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoString extends ParamInfo { + public ParamInfoString(Class paramClass, String name, String description) { + super(paramClass, name, description); + } + + @Override + protected Object fromString(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoBlockPosition.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoBlockPosition.java new file mode 100644 index 00000000..ec59651e --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoBlockPosition.java @@ -0,0 +1,24 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.custom; + +import com.comphenix.protocol.wrappers.BlockPosition; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoBlockPosition extends ParamInfo { + public ParamInfoBlockPosition(Class paramClass, String name, String valueType, String description) { + super(paramClass, name, valueType, description); + } + + @Override + protected Object fromString(String string) { + String[] split = string.split(","); + + if (split.length != 3) { + return null; + } + + return new BlockPosition(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoEulerAngle.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoEulerAngle.java new file mode 100644 index 00000000..ec17ee83 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoEulerAngle.java @@ -0,0 +1,24 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.custom; + +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; +import org.bukkit.util.EulerAngle; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoEulerAngle extends ParamInfo { + public ParamInfoEulerAngle(Class paramClass, String name, String valueType, String description) { + super(paramClass, name, valueType, description); + } + + @Override + protected Object fromString(String string) { + String[] split = string.split(","); + + if (split.length != 3) { + return null; + } + + return new EulerAngle(Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoGameProfile.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoGameProfile.java new file mode 100644 index 00000000..585962a5 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoGameProfile.java @@ -0,0 +1,21 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.custom; + +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; + +import java.lang.reflect.Method; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoGameProfile extends ParamInfo { + public ParamInfoGameProfile(Class paramClass, String name, String description) { + super(paramClass, name, description); + } + + @Override + protected Object fromString( String string) { + return DisguiseUtilities.getGson().fromJson(string, WrappedGameProfile.class); + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java new file mode 100644 index 00000000..ffc7d3c5 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStack.java @@ -0,0 +1,71 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.custom; + +import me.libraryaddict.disguise.utilities.TranslateType; +import me.libraryaddict.disguise.utilities.parser.params.types.ParamInfoEnum; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoItemStack extends ParamInfoEnum { + public ParamInfoItemStack(Class paramClass, String name, String valueType, String description, + Enum[] possibleValues) { + super(paramClass, name, valueType, description, possibleValues); + + setOtherValues("null", "glow"); + } + + @Override + public boolean canTranslateValues() { + return false; + } + + @Override + public boolean canReturnNull() { + return true; + } + + @Override + public Object fromString(String string) { + return parseToItemstack(string); + } + + protected ItemStack parseToItemstack(String string) { + String[] split = string.split(":", -1); + + if (split[0].isEmpty() || split[0].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("null"))) { + return null; + } + + Material material = Material.getMaterial(split[0]); + + if (material == null) { + throw new IllegalArgumentException(); + } + + Integer amount = null; + boolean enchanted = false; + + for (int i = 1; i < split.length; i++) { + String s = split[i]; + + if (!enchanted && s.equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("glow"))) { + enchanted = true; + } else if (s.matches("\\d+") && amount == null) { + amount = Integer.parseInt(s); + } else { + throw new IllegalArgumentException(); + } + } + + ItemStack itemStack = new ItemStack(material, amount == null ? 1 : amount); + + if (enchanted) { + itemStack.addUnsafeEnchantment(Enchantment.DURABILITY, 1); + } + + return itemStack; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStackArray.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStackArray.java new file mode 100644 index 00000000..265a46dd --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoItemStackArray.java @@ -0,0 +1,51 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.custom; + +import org.bukkit.inventory.ItemStack; + +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoItemStackArray extends ParamInfoItemStack { + public ParamInfoItemStackArray(Class paramClass, String name, String valueType, String description, + Enum[] possibleValues) { + super(paramClass, name, valueType, description, possibleValues); + } + + @Override + public Set getEnums(String tabComplete) { + String beginning = tabComplete.substring(0, tabComplete.contains(",") ? tabComplete.lastIndexOf(",") + 1 : 0); + String end = tabComplete.substring(tabComplete.contains(",") ? tabComplete.lastIndexOf(",") + 1 : 0); + + Set toReturn = new LinkedHashSet<>(); + + for (String material : super.getEnums(null)) { + if (!material.toLowerCase().startsWith(end.toLowerCase())) + continue; + + toReturn.add(beginning + material); + } + + return toReturn; + } + + @Override + public Object fromString(String string) { + String[] split = string.split(",", -1); + + if (split.length != 4) { + return null; + } + + // Parse to itemstack array + ItemStack[] items = new ItemStack[4]; + + for (int a = 0; a < 4; a++) { + items[a] = parseToItemstack(split[a]); + } + + return items; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoPotionType.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoPotionType.java new file mode 100644 index 00000000..d65be9e5 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/params/types/custom/ParamInfoPotionType.java @@ -0,0 +1,18 @@ +package me.libraryaddict.disguise.utilities.parser.params.types.custom; + +import me.libraryaddict.disguise.utilities.parser.params.types.ParamInfoEnum; +import org.bukkit.potion.PotionEffectType; + +/** + * Created by libraryaddict on 7/09/2018. + */ +public class ParamInfoPotionType extends ParamInfoEnum { + public ParamInfoPotionType(Class paramClass, String name, String description, String[] possibleValues) { + super(paramClass, name, description, possibleValues); + } + + @Override + public Object fromString(String string) { + return PotionEffectType.getByName(string); + } +}