diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index 8ce446b4..f1f0c312 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -4,6 +4,9 @@ import java.io.IOException; import java.lang.reflect.Field; import org.bukkit.Bukkit; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.PluginCommand; +import org.bukkit.command.TabCompleter; import org.bukkit.entity.Ageable; import org.bukkit.entity.Creature; import org.bukkit.entity.Damageable; @@ -20,9 +23,9 @@ import com.comphenix.protocol.wrappers.WrappedWatchableObject; import me.libraryaddict.disguise.commands.CloneDisguiseCommand; import me.libraryaddict.disguise.commands.DisguiseCommand; +import me.libraryaddict.disguise.commands.DisguiseHelpCommand; import me.libraryaddict.disguise.commands.DisguiseViewSelf; import me.libraryaddict.disguise.commands.EntityDisguiseCommand; -import me.libraryaddict.disguise.commands.HelpDisguiseCommand; import me.libraryaddict.disguise.commands.LibsDisguisesCommand; import me.libraryaddict.disguise.commands.PlayerDisguiseCommand; import me.libraryaddict.disguise.commands.RadiusDisguiseCommand; @@ -93,18 +96,18 @@ public class LibsDisguises extends JavaPlugin { Bukkit.getPluginManager().registerEvents(listener, this); - getCommand("disguise").setExecutor(new DisguiseCommand()); - getCommand("undisguise").setExecutor(new UndisguiseCommand()); - getCommand("disguiseplayer").setExecutor(new PlayerDisguiseCommand()); - getCommand("undisguiseplayer").setExecutor(new UndisguisePlayerCommand()); - getCommand("undisguiseentity").setExecutor(new UndisguiseEntityCommand()); - getCommand("disguiseentity").setExecutor(new EntityDisguiseCommand()); - getCommand("disguiseradius").setExecutor(new RadiusDisguiseCommand(getConfig().getInt("DisguiseRadiusMax"))); - getCommand("undisguiseradius").setExecutor(new UndisguiseRadiusCommand(getConfig().getInt("UndisguiseRadiusMax"))); - getCommand("disguisehelp").setExecutor(new HelpDisguiseCommand()); - getCommand("disguiseclone").setExecutor(new CloneDisguiseCommand()); - getCommand("libsdisguises").setExecutor(new LibsDisguisesCommand()); - getCommand("disguiseviewself").setExecutor(new DisguiseViewSelf()); + registerCommand("disguise", new DisguiseCommand()); + registerCommand("undisguise", new UndisguiseCommand()); + registerCommand("disguiseplayer", new PlayerDisguiseCommand()); + registerCommand("undisguiseplayer", new UndisguisePlayerCommand()); + registerCommand("undisguiseentity", new UndisguiseEntityCommand()); + registerCommand("disguiseentity", new EntityDisguiseCommand()); + registerCommand("disguiseradius", new RadiusDisguiseCommand(getConfig().getInt("DisguiseRadiusMax"))); + registerCommand("undisguiseradius", new UndisguiseRadiusCommand(getConfig().getInt("UndisguiseRadiusMax"))); + registerCommand("disguisehelp", new DisguiseHelpCommand()); + registerCommand("disguiseclone", new CloneDisguiseCommand()); + registerCommand("libsdisguises", new LibsDisguisesCommand()); + registerCommand("disguiseviewself", new DisguiseViewSelf()); registerValues(); @@ -118,6 +121,16 @@ public class LibsDisguises extends JavaPlugin { } } + private void registerCommand(String commandName, CommandExecutor executioner) { + PluginCommand command = getCommand(commandName); + + command.setExecutor(executioner); + + if (executioner instanceof TabCompleter) { + command.setTabCompleter((TabCompleter) executioner); + } + } + /** * Reloads the config with new config options. */ diff --git a/src/me/libraryaddict/disguise/commands/BaseDisguiseCommand.java b/src/me/libraryaddict/disguise/commands/BaseDisguiseCommand.java index 556b6b31..b38b95e6 100644 --- a/src/me/libraryaddict/disguise/commands/BaseDisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/BaseDisguiseCommand.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; @@ -55,6 +56,46 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { } } + private Object callValueOf(Class param, String valueString, String methodName, String description) + throws DisguiseParseException { + Object value; + try { + value = param.getMethod("valueOf", String.class).invoke(null, valueString.toUpperCase()); + } + catch (Exception ex) { + throw parseToException(description, valueString, methodName); + } + return value; + } + + private void doCheck(HashMap, Boolean> optionPermissions, ArrayList usedOptions) + throws DisguiseParseException { + + if (!passesCheck(optionPermissions, usedOptions)) { + throw new DisguiseParseException(ChatColor.RED + "You do not have the permission to use the option " + + usedOptions.get(usedOptions.size() - 1)); + } + } + + protected ArrayList filterTabs(ArrayList list, String[] origArgs) { + if (origArgs.length == 0) + return list; + + Iterator itel = list.iterator(); + String label = origArgs[origArgs.length - 1].toLowerCase(); + + while (itel.hasNext()) { + String name = itel.next(); + + if (name.toLowerCase().startsWith(label)) + continue; + + itel.remove(); + } + + return list; + } + protected ArrayList getAllowedDisguises(HashMap, Boolean>> hashMap) { ArrayList allowedDisguises = new ArrayList<>(); @@ -67,8 +108,19 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { return allowedDisguises; } - protected HashMap, Boolean>> getPermissions(CommandSender sender) { - return getPermissions(sender, "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + "."); + protected String[] getArgs(String[] args) { + ArrayList newArgs = new ArrayList(); + + for (int i = 0; i < args.length - 1; i++) { + String s = args[i]; + + if (s.trim().isEmpty()) + continue; + + newArgs.add(s); + } + + return newArgs.toArray(new String[0]); } protected HashMap getDisguiseOptions(CommandSender sender, DisguiseType type) { @@ -125,6 +177,44 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { return methods; } + private Entry getMethod(Method[] methods, String methodName, int toStart) { + for (int i = toStart; i < methods.length; i++) { + Method method = methods[i]; + if (!method.getName().startsWith("get") && method.getName().equalsIgnoreCase(methodName) + && method.getAnnotation(Deprecated.class) == null && method.getParameterTypes().length == 1) { + return new HashMap.SimpleEntry(method, ++i); + } + } + return null; + } + + private 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; + } + + protected HashMap, Boolean>> getPermissions(CommandSender sender) { + return getPermissions(sender, "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + "."); + } + /** * Get perms for the node. Returns a hashmap of allowed disguisetypes and their options * @@ -325,29 +415,6 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { return map; } - private 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; - } - protected boolean isDouble(String string) { try { Float.parseFloat(string); @@ -387,6 +454,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { if (map.isEmpty()) { throw new DisguiseParseException(ChatColor.RED + "You are forbidden to use this command."); } + if (args.length == 0) { sendCommandUsage(sender, map); throw new DisguiseParseException(); @@ -403,6 +471,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { if (args[0].startsWith("@")) { if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) { disguise = DisguiseUtilities.getClonedDisguise(args[0].toLowerCase()); + if (disguise == null) { throw new DisguiseParseException(ChatColor.RED + "Cannot find a disguise under the reference " + args[0]); } @@ -410,6 +479,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { else { throw new DisguiseParseException(ChatColor.RED + "You do not have perimssion to use disguise references!"); } + optionPermissions = (map.containsKey(disguise.getType()) ? map.get(disguise.getType()) : new HashMap, Boolean>()); } @@ -477,6 +547,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { usedOptions.add("setbaby"); doCheck(optionPermissions, usedOptions); adult = args[1].equalsIgnoreCase("adult"); + toSkip++; } } @@ -488,6 +559,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { 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 @@ -498,6 +570,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { } args[1] = split[0]; } + if (isNumeric(args[1])) { miscId = Integer.parseInt(args[1]); } @@ -545,6 +618,7 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { } } } + if (!disguiseOptions.isEmpty() && miscId != -1) { String toCheck = "" + miscId; @@ -563,17 +637,21 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { + " on the " + disguiseType.toReadable() + " disguise!"); } } + if (miscId != -1) { if (disguiseType == DisguiseType.FALLING_BLOCK) { usedOptions.add("setblock"); + doCheck(optionPermissions, usedOptions); } else if (disguiseType == DisguiseType.PAINTING) { usedOptions.add("setpainting"); + doCheck(optionPermissions, usedOptions); } else if (disguiseType == DisguiseType.SPLASH_POTION) { usedOptions.add("setpotionid"); + doCheck(optionPermissions, usedOptions); } } @@ -899,54 +977,6 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { return disguise; } - private Entry getMethod(Method[] methods, String methodName, int toStart) { - for (int i = toStart; i < methods.length; i++) { - Method method = methods[i]; - if (!method.getName().startsWith("get") && method.getName().equalsIgnoreCase(methodName) - && method.getAnnotation(Deprecated.class) == null && method.getParameterTypes().length == 1) { - return new HashMap.SimpleEntry(method, ++i); - } - } - return null; - } - - private Object callValueOf(Class param, String valueString, String methodName, String description) - throws DisguiseParseException { - Object value; - try { - value = param.getMethod("valueOf", String.class).invoke(null, valueString.toUpperCase()); - } - catch (Exception ex) { - throw parseToException(description, valueString, methodName); - } - return value; - } - - private boolean passesCheck(HashMap, Boolean> map1, ArrayList usedOptions) { - boolean hasPermission = false; - for (ArrayList list : map1.keySet()) { - boolean myPerms = true; - for (String option : usedOptions) { - if (!(map1.get(list) && list.contains("*")) && (list.contains(option) != map1.get(list))) { - myPerms = false; - break; - } - } - if (myPerms) { - hasPermission = true; - } - } - return hasPermission; - } - - private void doCheck(HashMap, Boolean> optionPermissions, ArrayList usedOptions) - throws DisguiseParseException { - if (!passesCheck(optionPermissions, usedOptions)) { - throw new DisguiseParseException(ChatColor.RED + "You do not have the permission to use the option " - + usedOptions.get(usedOptions.size() - 1)); - } - } - private DisguiseParseException parseToException(String expectedValue, String receivedInstead, String methodName) { return new DisguiseParseException( ChatColor.RED + "Expected " + ChatColor.GREEN + expectedValue + ChatColor.RED + ", received " + ChatColor.GREEN @@ -978,6 +1008,27 @@ public abstract class BaseDisguiseCommand implements CommandExecutor { } } + public boolean passesCheck(HashMap, Boolean> theirPermissions, ArrayList usedOptions) { + boolean hasPermission = false; + + for (ArrayList list : theirPermissions.keySet()) { + boolean myPerms = true; + + for (String option : usedOptions) { + if (!(theirPermissions.get(list) && list.contains("*")) + && (list.contains(option) != theirPermissions.get(list))) { + myPerms = false; + break; + } + } + + if (myPerms) { + hasPermission = true; + } + } + return hasPermission; + } + protected abstract void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map); } diff --git a/src/me/libraryaddict/disguise/commands/CloneDisguiseCommand.java b/src/me/libraryaddict/disguise/commands/CloneDisguiseCommand.java index a9cbf5bb..1094c438 100644 --- a/src/me/libraryaddict/disguise/commands/CloneDisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/CloneDisguiseCommand.java @@ -2,79 +2,84 @@ package me.libraryaddict.disguise.commands; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import org.apache.commons.lang.StringUtils; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.DisguiseType; -public class CloneDisguiseCommand extends BaseDisguiseCommand -{ - +public class CloneDisguiseCommand extends BaseDisguiseCommand implements TabCompleter { @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (sender.getName().equals("CONSOLE")) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { sender.sendMessage(ChatColor.RED + "You may not use this command from the console!"); return true; } - if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) - { + + if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) { boolean doEquipment = true; boolean doSneak = false; boolean doSprint = false; - for (String option : args) - { + + for (String option : args) { if (StringUtils.startsWithIgnoreCase(option, "ignoreEquip") - || StringUtils.startsWithIgnoreCase(option, "ignoreEnquip")) - { + || StringUtils.startsWithIgnoreCase(option, "ignoreEnquip")) { doEquipment = false; } - else if (option.equalsIgnoreCase("doSneakSprint")) - { + else if (option.equalsIgnoreCase("doSneakSprint")) { doSneak = true; doSprint = true; } - else if (option.equalsIgnoreCase("doSneak")) - { + else if (option.equalsIgnoreCase("doSneak")) { doSneak = true; } - else if (option.equalsIgnoreCase("doSprint")) - { + else if (option.equalsIgnoreCase("doSprint")) { doSprint = true; } - else - { + else { sender.sendMessage(ChatColor.DARK_RED + "Unknown option '" + option + "' - Valid options are 'IgnoreEquipment' 'DoSneakSprint' 'DoSneak' 'DoSprint'"); return true; } } - LibsDisguises.getInstance().getListener().setDisguiseClone(sender.getName(), new Boolean[] - { - doEquipment, doSneak, doSprint - }); + + LibsDisguises.getInstance().getListener().setDisguiseClone(sender.getName(), new Boolean[] { + doEquipment, doSneak, doSprint + }); + sender.sendMessage(ChatColor.RED + "Right click a entity in the next " + DisguiseConfig.getDisguiseCloneExpire() + " seconds to grab the disguise reference!"); } - else - { + else { sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); } + return true; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + + tabs.add("ignoreEquip"); + tabs.add("doSneakSprint"); + tabs.add("doSneak"); + tabs.add("doSprint"); + + return filterTabs(tabs, origArgs); + } + /** * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) - { + protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { sender.sendMessage(ChatColor.DARK_GREEN + "Right click a entity to get a disguise reference you can pass to other disguise commands!"); sender.sendMessage(ChatColor.DARK_GREEN diff --git a/src/me/libraryaddict/disguise/commands/DisguiseCommand.java b/src/me/libraryaddict/disguise/commands/DisguiseCommand.java index 227fc65f..bd880299 100644 --- a/src/me/libraryaddict/disguise/commands/DisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/DisguiseCommand.java @@ -1,12 +1,16 @@ package me.libraryaddict.disguise.commands; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; 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; import org.bukkit.entity.Player; import me.libraryaddict.disguise.DisguiseAPI; @@ -14,46 +18,39 @@ 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.ReflectionFlagWatchers; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; -public class DisguiseCommand extends BaseDisguiseCommand -{ - +public class DisguiseCommand extends BaseDisguiseCommand implements TabCompleter { @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (sender.getName().equals("CONSOLE")) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { sender.sendMessage(ChatColor.RED + "You may not use this command from the console!"); return true; } + Disguise disguise; - try - { + + try { disguise = parseDisguise(sender, args, getPermissions(sender)); } - catch (DisguiseParseException ex) - { - if (ex.getMessage() != null) - { + catch (DisguiseParseException ex) { + if (ex.getMessage() != null) { sender.sendMessage(ex.getMessage()); } return true; } - catch (Exception ex) - { + catch (Exception ex) { ex.printStackTrace(); return true; } - if (DisguiseConfig.isNameOfPlayerShownAboveDisguise()) - { - if (disguise.getWatcher() instanceof LivingWatcher) - { + if (DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { disguise.getWatcher().setCustomName(((Player) sender).getDisplayName()); - if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) - { + if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { disguise.getWatcher().setCustomNameVisible(true); } } @@ -61,35 +58,115 @@ public class DisguiseCommand extends BaseDisguiseCommand DisguiseAPI.disguiseToAll((Player) sender, disguise); - if (disguise.isDisguiseInUse()) - { + if (disguise.isDisguiseInUse()) { sender.sendMessage(ChatColor.RED + "Now disguised as a " + disguise.getType().toReadable()); } - else - { + else { sender.sendMessage(ChatColor.RED + "Failed to disguise as a " + disguise.getType().toReadable()); } return true; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + HashMap, Boolean>> perms = getPermissions(sender); + + if (args.length == 0) { + for (DisguiseType type : perms.keySet()) { + tabs.add(type.toReadable().replaceAll(" ", "_")); + } + } + else { + DisguiseType disguiseType; + + try { + disguiseType = DisguiseType.valueOf(args[0].toUpperCase()); + } + catch (Exception ex) { + // No disguisetype specificied, cannot help. + return filterTabs(tabs, origArgs); + } + + if (args.length == 1 && disguiseType == DisguiseType.PLAYER) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + else { + ArrayList usedOptions = new ArrayList(); + + for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (int i = disguiseType == DisguiseType.PLAYER ? 2 : 1; i < args.length; i++) { + String arg = args[i]; + + if (!method.getName().equalsIgnoreCase(arg)) + continue; + + usedOptions.add(arg); + } + } + + if (passesCheck(perms.get(disguiseType), usedOptions)) { + boolean addMethods = true; + + if (args.length > 1) { + String prevArg = args[args.length - 1]; + + ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + + if (info != null) { + if (info.getParamClass() != boolean.class) + addMethods = false; + + if (info.isEnums()) { + for (String e : info.getEnums()) { + tabs.add(e); + } + } + else { + if (info.getParamClass() == String.class) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + } + } + } + + 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())) { + tabs.add(method.getName()); + } + } + } + } + } + + return filterTabs(tabs, origArgs); + } + /** * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) - { + protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { ArrayList allowedDisguises = getAllowedDisguises(map); sender.sendMessage(ChatColor.DARK_GREEN + "Choose a disguise to become the disguise!"); sender.sendMessage(ChatColor.DARK_GREEN + "You can use the disguises: " + ChatColor.GREEN + StringUtils.join(allowedDisguises, ChatColor.RED + ", " + ChatColor.GREEN)); - if (allowedDisguises.contains("player")) - { + + if (allowedDisguises.contains("player")) { sender.sendMessage(ChatColor.DARK_GREEN + "/disguise player "); } + sender.sendMessage(ChatColor.DARK_GREEN + "/disguise "); - if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) - { + + if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) { sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseplayer "); } } diff --git a/src/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java b/src/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java new file mode 100644 index 00000000..f9a078ee --- /dev/null +++ b/src/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java @@ -0,0 +1,198 @@ +package me.libraryaddict.disguise.commands; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; + +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; + +public class DisguiseHelpCommand extends BaseDisguiseCommand implements TabCompleter { + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + for (String node : new String[] { + "disguise", "disguiseradius", "disguiseentity", "disguiseplayer" + }) { + HashMap, Boolean>> permMap = getPermissions(sender, + "libsdisguises." + node + "."); + if (!permMap.isEmpty()) { + if (args.length == 0) { + sendCommandUsage(sender, null); + return true; + } + else { + ParamInfo help = null; + + for (ParamInfo s : ReflectionFlagWatchers.getParamInfos()) { + String name = s.getName().replaceAll(" ", ""); + + if (args[0].equalsIgnoreCase(name) || args[0].equalsIgnoreCase(name + "s")) { + help = s; + break; + } + } + + if (help != null) { + sender.sendMessage(ChatColor.RED + help.getName() + ": " + ChatColor.GREEN + + StringUtils.join(help.getEnums(), ChatColor.RED + ", " + ChatColor.GREEN)); + return true; + } + + DisguiseType type = null; + + for (DisguiseType disguiseType : DisguiseType.values()) { + if (args[0].equalsIgnoreCase(disguiseType.name()) + || disguiseType.name().replace("_", "").equalsIgnoreCase(args[0])) { + + type = disguiseType; + break; + } + } + + if (type == null) { + sender.sendMessage(ChatColor.RED + "Cannot find the disguise " + args[0]); + return true; + } + + if (!permMap.containsKey(type)) { + sender.sendMessage(ChatColor.RED + "You do not have permission for that disguise!"); + return true; + } + + ArrayList methods = new ArrayList<>(); + HashMap map = new HashMap<>(); + Class watcher = type.getWatcherClass(); + int ignored = 0; + + try { + for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(watcher)) { + if (args.length < 2 || !args[1].equalsIgnoreCase("show")) { + boolean allowed = false; + + for (ArrayList key : permMap.get(type).keySet()) { + if (permMap.get(type).get(key)) { + if (key.contains("*") || key.contains(method.getName().toLowerCase())) { + allowed = true; + break; + } + } + else if (!key.contains(method.getName().toLowerCase())) { + allowed = true; + break; + } + } + + if (!allowed) { + ignored++; + continue; + } + } + + Class c = method.getParameterTypes()[0]; + ParamInfo info = ReflectionFlagWatchers.getParamInfo(c); + + if (info == null) + continue; + + ChatColor methodColor = ChatColor.YELLOW; + + Class declaring = method.getDeclaringClass(); + + if (declaring == LivingWatcher.class) { + methodColor = ChatColor.AQUA; + } + else if (!(FlagWatcher.class.isAssignableFrom(declaring)) || declaring == FlagWatcher.class) { + methodColor = ChatColor.GRAY; + } + + String str = method.getName() + ChatColor.DARK_RED + "(" + ChatColor.GREEN + info.getName() + + ChatColor.DARK_RED + ")"; + + map.put(str, methodColor); + methods.add(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(ChatColor.RED + "No options with permission to use"); + } + + sender.sendMessage(ChatColor.DARK_RED + type.toReadable() + " options: " + + StringUtils.join(methods, ChatColor.DARK_RED + ", ")); + + if (ignored > 0) { + sender.sendMessage(ChatColor.RED + "Ignored " + ignored + + " options you do not have permission to view. Add 'show' to view unusable options."); + } + return true; + } + } + } + sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); + return true; + } + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + HashMap, Boolean>> perms = getPermissions(sender); + + if (args.length == 0) { + for (DisguiseType type : perms.keySet()) { + tabs.add(type.toReadable().replaceAll(" ", "_")); + } + + for (ParamInfo s : ReflectionFlagWatchers.getParamInfos()) { + tabs.add(s.getName().replaceAll(" ", "")); + } + } + else { + try { + DisguiseType.valueOf(args[0].toUpperCase()); + } + catch (Exception ex) { + tabs.add("Show"); + } + + } + + return filterTabs(tabs, origArgs); + } + + /** + * Send the player the information + */ + @Override + protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { + sender.sendMessage(ChatColor.RED + "/disguisehelp " + ChatColor.GREEN + + "- View the options you can set on a disguise. Add 'show' to reveal the options you don't have permission to use"); + + for (ParamInfo s : ReflectionFlagWatchers.getParamInfos()) { + sender.sendMessage(ChatColor.RED + "/disguisehelp " + s.getName().replaceAll(" ", "") + ChatColor.GREEN + " - " + + s.getDescription()); + } + } +} diff --git a/src/me/libraryaddict/disguise/commands/DisguiseViewSelf.java b/src/me/libraryaddict/disguise/commands/DisguiseViewSelf.java index 836b3a95..91ddc1c5 100644 --- a/src/me/libraryaddict/disguise/commands/DisguiseViewSelf.java +++ b/src/me/libraryaddict/disguise/commands/DisguiseViewSelf.java @@ -11,28 +11,26 @@ import me.libraryaddict.disguise.DisguiseAPI; /** * @author Navid */ -public class DisguiseViewSelf implements CommandExecutor -{ +public class DisguiseViewSelf implements CommandExecutor { @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) - { - if (sender.getName().equals("CONSOLE")) - { + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { sender.sendMessage(ChatColor.RED + "You may not use this command from the console!"); return true; } + Player player = (Player) sender; - if (DisguiseAPI.isViewSelfToggled(player)) - { + + if (DisguiseAPI.isViewSelfToggled(player)) { DisguiseAPI.setViewDisguiseToggled(player, false); sender.sendMessage(ChatColor.GREEN + "Toggled viewing own disguise off!"); } - else - { + else { DisguiseAPI.setViewDisguiseToggled(player, true); sender.sendMessage(ChatColor.GREEN + "Toggled viewing own disguise on!"); } + return true; } diff --git a/src/me/libraryaddict/disguise/commands/EntityDisguiseCommand.java b/src/me/libraryaddict/disguise/commands/EntityDisguiseCommand.java index 8bd17f57..e21c3b99 100644 --- a/src/me/libraryaddict/disguise/commands/EntityDisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/EntityDisguiseCommand.java @@ -1,54 +1,140 @@ package me.libraryaddict.disguise.commands; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; 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; +import org.bukkit.entity.Player; 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.ReflectionFlagWatchers; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; -public class EntityDisguiseCommand extends BaseDisguiseCommand -{ - +public class EntityDisguiseCommand extends BaseDisguiseCommand implements TabCompleter { @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (sender.getName().equals("CONSOLE")) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { sender.sendMessage(ChatColor.RED + "You may not use this command from the console!"); return true; } + Disguise disguise; - try - { + + try { disguise = parseDisguise(sender, args, getPermissions(sender)); } - catch (DisguiseParseException ex) - { - if (ex.getMessage() != null) - { + catch (DisguiseParseException ex) { + if (ex.getMessage() != null) { sender.sendMessage(ex.getMessage()); } + return true; } - catch (IllegalAccessException | InvocationTargetException ex) - { + catch (IllegalAccessException | InvocationTargetException ex) { ex.printStackTrace(); return true; } + LibsDisguises.getInstance().getListener().setDisguiseEntity(sender.getName(), disguise); + sender.sendMessage(ChatColor.RED + "Right click a entity in the next " + DisguiseConfig.getDisguiseEntityExpire() + " seconds to disguise it as a " + disguise.getType().toReadable() + "!"); return true; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + HashMap, Boolean>> perms = getPermissions(sender); + + if (args.length == 0) { + for (DisguiseType type : perms.keySet()) { + tabs.add(type.toReadable().replaceAll(" ", "_")); + } + } + else { + DisguiseType disguiseType; + + try { + disguiseType = DisguiseType.valueOf(args[0].toUpperCase()); + } + catch (Exception ex) { + // No disguisetype specificied, cannot help. + return filterTabs(tabs, origArgs); + } + + if (args.length == 1 && disguiseType == DisguiseType.PLAYER) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + else { + ArrayList usedOptions = new ArrayList(); + + for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (int i = disguiseType == DisguiseType.PLAYER ? 2 : 1; i < args.length; i++) { + String arg = args[i]; + + if (!method.getName().equalsIgnoreCase(arg)) + continue; + + usedOptions.add(arg); + } + } + + if (passesCheck(perms.get(disguiseType), usedOptions)) { + boolean addMethods = true; + + if (args.length > 1) { + String prevArg = args[args.length - 1]; + + ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + + if (info != null) { + if (info.getParamClass() != boolean.class) + addMethods = false; + + if (info.isEnums()) { + for (String e : info.getEnums()) { + tabs.add(e); + } + } + else { + if (info.getParamClass() == String.class) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + } + } + } + + 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())) { + tabs.add(method.getName()); + } + } + } + } + } + + return filterTabs(tabs, origArgs); + } + /** * Send the player the information * @@ -56,19 +142,19 @@ public class EntityDisguiseCommand extends BaseDisguiseCommand * @param map */ @Override - protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) - { + protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { ArrayList allowedDisguises = getAllowedDisguises(map); sender.sendMessage(ChatColor.DARK_GREEN + "Choose a disguise then right click a entity to disguise it!"); sender.sendMessage(ChatColor.DARK_GREEN + "You can use the disguises: " + ChatColor.GREEN + StringUtils.join(allowedDisguises, ChatColor.RED + ", " + ChatColor.GREEN)); - if (allowedDisguises.contains("player")) - { + + if (allowedDisguises.contains("player")) { sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseentity player "); } + sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseentity "); - if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) - { + + if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) { sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseentity "); } } diff --git a/src/me/libraryaddict/disguise/commands/HelpDisguiseCommand.java b/src/me/libraryaddict/disguise/commands/HelpDisguiseCommand.java deleted file mode 100644 index 8b19baf9..00000000 --- a/src/me/libraryaddict/disguise/commands/HelpDisguiseCommand.java +++ /dev/null @@ -1,334 +0,0 @@ -package me.libraryaddict.disguise.commands; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; - -import org.apache.commons.lang.StringUtils; -import org.bukkit.ChatColor; -import org.bukkit.block.BlockFace; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffectType; - -import com.comphenix.protocol.wrappers.BlockPosition; -import com.comphenix.protocol.wrappers.WrappedGameProfile; - -import me.libraryaddict.disguise.disguisetypes.AnimalColor; -import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.disguisetypes.FlagWatcher; -import me.libraryaddict.disguise.disguisetypes.RabbitType; -import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; - -public class HelpDisguiseCommand extends BaseDisguiseCommand { - - private class EnumHelp { - - private String enumDescription; - private String enumName; - private String[] enums; - private String readableEnum; - - public EnumHelp(String enumName, String enumReadable, String enumDescription, Enum[] enums) { - String[] strings = new String[enums.length]; - for (int i = 0; i < strings.length; i++) { - strings[i] = toReadable(enums[i].name()); - } - this.enumName = enumName; - this.enumDescription = enumDescription; - this.enums = strings; - this.readableEnum = enumReadable; - } - - public EnumHelp(String enumName, String enumReadable, String enumDescription, String[] enums) { - this.enumName = enumName; - this.enumDescription = enumDescription; - this.enums = enums; - this.readableEnum = enumReadable; - } - - public String getEnumDescription() { - return enumDescription; - } - - public String getEnumName() { - return enumName; - } - - public String[] getEnums() { - return enums; - } - - public String getReadableEnum() { - return readableEnum; - } - } - - private ArrayList enumHelp = new ArrayList<>(); - - public HelpDisguiseCommand() { - try { - enumHelp.add(new EnumHelp("AnimalColor", "Animal colors", ChatColor.RED + "/disguisehelp AnimalColors " - + ChatColor.GREEN + "- View all the colors you can use for a animal color", AnimalColor.values())); - } - catch (Exception ex) { - ex.printStackTrace(); - } - try { - enumHelp.add(new EnumHelp("Art", "Arts", - ChatColor.RED + "/disguisehelp Art " + ChatColor.GREEN - + "- View all the painting arts you can use on a painting disguise", - (Enum[]) Class.forName("org.bukkit.Art").getEnumConstants())); - } - catch (Exception ex) { - } - try { - enumHelp.add(new EnumHelp("LlamaColors", "Llama Colors", - ChatColor.RED + "/disguisehelp LlamaColors " + ChatColor.GREEN - + "- View all the colors you can use for a llama color", - (Enum[]) Class.forName("org.bukkit.entity.Llama$Color").getEnumConstants())); - } - catch (Exception ex) { - } - try { - enumHelp.add(new EnumHelp("HorseColors", "Horse colors", - ChatColor.RED + "/disguisehelp HorseColors " + ChatColor.GREEN - + "- View all the colors you can use for a horses color", - (Enum[]) Class.forName("org.bukkit.entity.Horse$Color").getEnumConstants())); - } - catch (Exception ex) { - } - try { - enumHelp.add(new EnumHelp("HorseStyles", "Horse styles", - ChatColor.RED + "/disguisehelp HorseStyles " + ChatColor.GREEN - + "- View all the styles you can use for a horses style", - (Enum[]) Class.forName("org.bukkit.entity.Horse$Style").getEnumConstants())); - } - catch (Exception ex) { - } - try { - enumHelp.add(new EnumHelp("OcelotTypes", "Ocelot types", - ChatColor.RED + "/disguisehelp OcelotTypes " + ChatColor.GREEN - + "- View all the ocelot types you can use for ocelots", - (Enum[]) Class.forName("org.bukkit.entity.Ocelot$Type").getEnumConstants())); - } - catch (Exception ex) { - } - try { - ArrayList enumReturns = new ArrayList<>(); - for (PotionEffectType potionType : PotionEffectType.values()) { - if (potionType != null) { - enumReturns.add(toReadable(potionType.getName()) + ChatColor.RED + "(" + ChatColor.GREEN + potionType.getId() - + ChatColor.RED + ")"); - } - } - enumHelp.add(new EnumHelp("PotionEffect", "PotionEffect", - ChatColor.RED + "/disguisehelp PotionEffect " + ChatColor.GREEN + "- View all the potion effects you can set", - enumReturns.toArray(new String[enumReturns.size()]))); - } - catch (Exception ex) { - ex.printStackTrace(); - } - try { - enumHelp.add(new EnumHelp("Profession", "Villager professions", - ChatColor.RED + "/disguisehelp Professions " + ChatColor.GREEN - + "- View all the professions you can set on a villager", - (Enum[]) Class.forName("org.bukkit.entity.Villager$Profession").getEnumConstants())); - } - catch (Exception ex) { - } - enumHelp.add(new EnumHelp("Direction", "Directions", - ChatColor.RED + "/disguisehelp Directions " + ChatColor.GREEN - + "- View the five directions usable on player setsleeping disguise", - Arrays.copyOf(BlockFace.values(), 5))); - enumHelp.add(new EnumHelp("RabbitType", "RabbitType", - ChatColor.RED + "/disguisehelp RabbitType " + ChatColor.GREEN + "View the kinds of rabbits you can turn into", - RabbitType.values())); - } - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - for (String node : new String[] { - "disguise", "disguiseradius", "disguiseentity", "disguiseplayer" - }) { - HashMap, Boolean>> permMap = getPermissions(sender, - "libsdisguises." + node + "."); - if (!permMap.isEmpty()) { - if (args.length == 0) { - sendCommandUsage(sender, null); - return true; - } - else { - EnumHelp help = null; - for (EnumHelp s : enumHelp) { - if (args[0].equalsIgnoreCase(s.getEnumName()) || args[0].equalsIgnoreCase(s.getEnumName() + "s")) { - help = s; - break; - } - } - if (help != null) { - sender.sendMessage(ChatColor.RED + help.getReadableEnum() + ": " + ChatColor.GREEN - + StringUtils.join(help.getEnums(), ChatColor.RED + ", " + ChatColor.GREEN)); - return true; - } - DisguiseType type = null; - for (DisguiseType disguiseType : DisguiseType.values()) { - if (args[0].equalsIgnoreCase(disguiseType.name()) - || disguiseType.name().replace("_", "").equalsIgnoreCase(args[0])) { - type = disguiseType; - break; - } - } - if (type == null) { - sender.sendMessage(ChatColor.RED + "Cannot find the disguise " + args[0]); - return true; - } - if (!permMap.containsKey(type)) { - sender.sendMessage(ChatColor.RED + "You do not have permission for that disguise!"); - return true; - } - ArrayList methods = new ArrayList<>(); - HashMap map = new HashMap<>(); - Class watcher = type.getWatcherClass(); - int ignored = 0; - try { - for (Method method : this.getDisguiseWatcherMethods(watcher)) { - if (!method.getName().startsWith("get") && method.getParameterTypes().length == 1 - && method.getAnnotation(Deprecated.class) == null) { - if (args.length < 2 || !args[1].equalsIgnoreCase("show")) { - boolean allowed = false; - for (ArrayList key : permMap.get(type).keySet()) { - if (permMap.get(type).get(key)) { - if (key.contains("*") || key.contains(method.getName().toLowerCase())) { - allowed = true; - break; - } - } - else if (!key.contains(method.getName().toLowerCase())) { - allowed = true; - break; - } - } - if (!allowed) { - ignored++; - continue; - } - } - Class c = method.getParameterTypes()[0]; - String valueType = null; - if (c == String.class) { - valueType = "String"; - } - else if (boolean.class == c) { - valueType = "True/False"; - } - else if (int.class == c) { - valueType = "Number"; - } - else if (float.class == c || double.class == c) { - valueType = "Decimal"; - } - else if (AnimalColor.class == c) { - valueType = "Color"; - } - else if (ItemStack.class == c) { - valueType = "Item (id:damage)"; - } - else if (ItemStack[].class == c) { - valueType = "4 items (id:damage,id,...)"; - } - else if (c.getSimpleName().equals("Style")) { - valueType = "Horse Style"; - } - else if (c.getSimpleName().equals("Color")) { - valueType = "Horse Color"; - } - else if (c.getSimpleName().equals("Type")) { - valueType = "Ocelot type"; - } - else if (c.getSimpleName().equals("Profession")) { - valueType = "Villager Profession"; - } - else if (PotionEffectType.class == c) { - valueType = "Potion effect"; - } - else if (c == int[].class) { - valueType = "number,number,number..."; - } - else if (c == BlockFace.class) { - valueType = "direction"; - } - else if (c == RabbitType.class) { - valueType = "rabbit type"; - } - else if (c == BlockPosition.class) { - valueType = "three numbers"; - } - else if (c == WrappedGameProfile.class) { - valueType = "gameprofile"; - } - - if (valueType != null) { - ChatColor methodColor = ChatColor.YELLOW; - Class declaring = method.getDeclaringClass(); - if (declaring == LivingWatcher.class) { - methodColor = ChatColor.AQUA; - } - else if (!(FlagWatcher.class.isAssignableFrom(declaring)) || declaring == FlagWatcher.class) { - methodColor = ChatColor.GRAY; - } - String str = method.getName() + ChatColor.DARK_RED + "(" + ChatColor.GREEN + valueType - + ChatColor.DARK_RED + ")"; - map.put(str, methodColor); - methods.add(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(ChatColor.RED + "No options with permission to use"); - } - sender.sendMessage(ChatColor.DARK_RED + type.toReadable() + " options: " - + StringUtils.join(methods, ChatColor.DARK_RED + ", ")); - if (ignored > 0) { - sender.sendMessage(ChatColor.RED + "Ignored " + ignored - + " options you do not have permission to view. Add 'show' to view unusable options."); - } - return true; - } - } - } - sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); - return true; - } - - /** - * Send the player the information - */ - @Override - protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { - sender.sendMessage(ChatColor.RED + "/disguisehelp " + ChatColor.GREEN - + "- View the options you can set on a disguise. Add 'show' to reveal the options you don't have permission to use"); - for (EnumHelp s : enumHelp) { - sender.sendMessage(s.getEnumDescription()); - } - } - - public 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/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java b/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java index 82a91e13..d515c776 100644 --- a/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java +++ b/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java @@ -1,46 +1,87 @@ package me.libraryaddict.disguise.commands; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; import me.libraryaddict.disguise.LibsDisguises; -public class LibsDisguisesCommand implements CommandExecutor -{ +public class LibsDisguisesCommand implements CommandExecutor, TabCompleter { + protected ArrayList filterTabs(ArrayList list, String[] origArgs) { + if (origArgs.length == 0) + return list; + + Iterator itel = list.iterator(); + String label = origArgs[origArgs.length - 1].toLowerCase(); + + while (itel.hasNext()) { + String name = itel.next(); + + if (name.toLowerCase().startsWith(label)) + continue; + + itel.remove(); + } + + return list; + } + + protected String[] getArgs(String[] args) { + ArrayList newArgs = new ArrayList(); + + for (int i = 0; i < args.length - 1; i++) { + String s = args[i]; + + if (s.trim().isEmpty()) + continue; + + newArgs.add(s); + } + + return newArgs.toArray(new String[0]); + } @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (args.length == 0) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (args.length == 0) { sender.sendMessage(ChatColor.DARK_GREEN + "This server is running " + "Lib's Disguises v." + Bukkit.getPluginManager().getPlugin("LibsDisguises").getDescription().getVersion() - + " by libraryaddict, maintained by NavidK0.\n" - + "Use /libsdisguises reload to reload the config. All disguises will be blown by doing this."); + + " by libraryaddict, maintained by NavidK0.\n" + "Use " + ChatColor.GREEN + "/libsdisguises reload" + + ChatColor.DARK_GREEN + " to reload the config. All disguises will be blown by doing this."); } - else if (args.length > 0) - { - if (sender.hasPermission("libsdisguises.reload")) - { - if (args[0].equalsIgnoreCase("reload")) - { + else if (args.length > 0) { + if (sender.hasPermission("libsdisguises.reload")) { + if (args[0].equalsIgnoreCase("reload")) { LibsDisguises.getInstance().reload(); sender.sendMessage(ChatColor.GREEN + "[LibsDisguises] Reloaded config."); return true; } - else - { + else { sender.sendMessage(ChatColor.RED + "[LibsDisguises] That command doesn't exist!"); } } - else - { + else { sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); } } return true; } + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + if (args.length == 0) + tabs.add("Reload"); + + return filterTabs(tabs, origArgs); + } } diff --git a/src/me/libraryaddict/disguise/commands/PlayerDisguiseCommand.java b/src/me/libraryaddict/disguise/commands/PlayerDisguiseCommand.java index df559943..22da868d 100644 --- a/src/me/libraryaddict/disguise/commands/PlayerDisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/PlayerDisguiseCommand.java @@ -1,13 +1,16 @@ package me.libraryaddict.disguise.commands; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; 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; import org.bukkit.entity.Player; import me.libraryaddict.disguise.DisguiseAPI; @@ -15,103 +18,192 @@ 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.ReflectionFlagWatchers; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; -public class PlayerDisguiseCommand extends BaseDisguiseCommand -{ +public class PlayerDisguiseCommand extends BaseDisguiseCommand implements TabCompleter { @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { HashMap, Boolean>> map = getPermissions(sender); - if (map.isEmpty()) - { + + if (map.isEmpty()) { sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); return true; } - if (args.length == 0) - { + + if (args.length == 0) { sendCommandUsage(sender, map); return true; } - if (args.length == 1) - { + + if (args.length == 1) { sender.sendMessage(ChatColor.RED + "You need to supply a disguise as well as the player"); return true; } + Player player = Bukkit.getPlayer(args[0]); - if (player == null) - { + + if (player == null) { sender.sendMessage(ChatColor.RED + "Cannot find the player '" + args[0] + "'"); return true; } + String[] newArgs = new String[args.length - 1]; System.arraycopy(args, 1, newArgs, 0, newArgs.length); + Disguise disguise; - try - { + try { disguise = parseDisguise(sender, newArgs, map); } - catch (DisguiseParseException ex) - { - if (ex.getMessage() != null) - { + catch (DisguiseParseException ex) { + if (ex.getMessage() != null) { sender.sendMessage(ex.getMessage()); } return true; } - catch (Exception ex) - { + + catch (Exception ex) { ex.printStackTrace(); return true; } - if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled()) - { + + if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled()) { sender.sendMessage( ChatColor.RED + "Can't disguise a living entity as a misc disguise. This has been disabled in the config!"); return true; } - if (DisguiseConfig.isNameOfPlayerShownAboveDisguise()) - { - if (disguise.getWatcher() instanceof LivingWatcher) - { + + if (DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { + disguise.getWatcher().setCustomName(player.getDisplayName()); - if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) - { + + if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { disguise.getWatcher().setCustomNameVisible(true); } } } + DisguiseAPI.disguiseToAll(player, disguise); - if (disguise.isDisguiseInUse()) - { + + if (disguise.isDisguiseInUse()) { sender.sendMessage(ChatColor.RED + "Successfully disguised " + player.getName() + " as a " + disguise.getType().toReadable() + "!"); } - else - { + else { sender.sendMessage( ChatColor.RED + "Failed to disguise " + player.getName() + " as a " + disguise.getType().toReadable() + "!"); } + return true; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + HashMap, Boolean>> perms = getPermissions(sender); + + if (args.length == 0) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + else if (args.length == 1) { + for (DisguiseType type : perms.keySet()) { + tabs.add(type.toReadable().replaceAll(" ", "_")); + } + } + else { + DisguiseType disguiseType; + + try { + disguiseType = DisguiseType.valueOf(args[1].toUpperCase()); + } + catch (Exception ex) { + // No disguisetype specificied, cannot help. + return filterTabs(tabs, origArgs); + } + + if (args.length == 2 && disguiseType == DisguiseType.PLAYER) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + else { + ArrayList usedOptions = new ArrayList(); + + for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (int i = disguiseType == DisguiseType.PLAYER ? 3 : 2; i < args.length; i++) { + String arg = args[i]; + + if (!method.getName().equalsIgnoreCase(arg)) + continue; + + usedOptions.add(arg); + } + } + + if (passesCheck(perms.get(disguiseType), usedOptions)) { + boolean addMethods = true; + + if (args.length > 2) { + String prevArg = args[args.length - 1]; + + ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + + if (info != null) { + if (info.getParamClass() != boolean.class) + addMethods = false; + + if (info.isEnums()) { + for (String e : info.getEnums()) { + tabs.add(e); + } + } + else { + if (info.getParamClass() == String.class) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + } + } + } + + 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())) { + tabs.add(method.getName()); + } + } + } + } + } + + return filterTabs(tabs, origArgs); + } + /** * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) - { + protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { ArrayList allowedDisguises = getAllowedDisguises(map); + sender.sendMessage(ChatColor.DARK_GREEN + "Disguise another player!"); sender.sendMessage(ChatColor.DARK_GREEN + "You can use the disguises: " + ChatColor.GREEN + StringUtils.join(allowedDisguises, ChatColor.RED + ", " + ChatColor.GREEN)); - if (allowedDisguises.contains("player")) - { + + if (allowedDisguises.contains("player")) { sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseplayer player "); } + sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseplayer "); - if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) - { + + if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) { sender.sendMessage( ChatColor.DARK_GREEN + "/disguiseplayer "); } diff --git a/src/me/libraryaddict/disguise/commands/RadiusDisguiseCommand.java b/src/me/libraryaddict/disguise/commands/RadiusDisguiseCommand.java index de65fab1..f230e686 100644 --- a/src/me/libraryaddict/disguise/commands/RadiusDisguiseCommand.java +++ b/src/me/libraryaddict/disguise/commands/RadiusDisguiseCommand.java @@ -1,13 +1,17 @@ package me.libraryaddict.disguise.commands; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; 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; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -19,54 +23,45 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.ClassGetter; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers; +import me.libraryaddict.disguise.utilities.ReflectionFlagWatchers.ParamInfo; -public class RadiusDisguiseCommand extends BaseDisguiseCommand -{ +public class RadiusDisguiseCommand extends BaseDisguiseCommand implements TabCompleter { private int maxRadius = 30; - private ArrayList validClasses = new ArrayList<>(); + private ArrayList> validClasses = new ArrayList<>(); - public RadiusDisguiseCommand(int maxRadius) - { + public RadiusDisguiseCommand(int maxRadius) { this.maxRadius = maxRadius; - - for (Class c : ClassGetter.getClassesForPackage("org.bukkit.entity")) - { - if (c != Entity.class && Entity.class.isAssignableFrom(c) && c.getAnnotation(Deprecated.class) == null) - { + for (Class c : ClassGetter.getClassesForPackage("org.bukkit.entity")) { + if (c != Entity.class && Entity.class.isAssignableFrom(c) && c.getAnnotation(Deprecated.class) == null) { validClasses.add(c); } } } @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (sender.getName().equals("CONSOLE")) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { sender.sendMessage(ChatColor.RED + "You may not use this command from the console!"); return true; } HashMap, Boolean>> map = getPermissions(sender); - if (map.isEmpty()) - { + if (map.isEmpty()) { sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); return true; } - if (args.length == 0) - { + if (args.length == 0) { sendCommandUsage(sender, map); return true; } - if (args[0].equalsIgnoreCase("entitytype") || args[0].equalsIgnoreCase("entitytypes")) - { + if (args[0].equalsIgnoreCase("entitytype") || args[0].equalsIgnoreCase("entitytypes")) { ArrayList classes = new ArrayList<>(); - for (Class c : validClasses) - { + for (Class c : validClasses) { classes.add(c.getSimpleName()); } @@ -81,58 +76,47 @@ public class RadiusDisguiseCommand extends BaseDisguiseCommand EntityType type = null; int starting = 0; - if (!isNumeric(args[0])) - { - for (Class c : validClasses) - { - if (c.getSimpleName().equalsIgnoreCase(args[0])) - { + if (!isNumeric(args[0])) { + for (Class c : validClasses) { + if (c.getSimpleName().equalsIgnoreCase(args[0])) { entityClass = c; starting = 1; break; } } - if (starting == 0) - { - try - { + if (starting == 0) { + try { type = EntityType.valueOf(args[0].toUpperCase()); } - catch (Exception ex) - { + catch (Exception ex) { } - if (type == null) - { + if (type == null) { sender.sendMessage(ChatColor.RED + "Unrecognised EntityType " + args[0]); return true; } } } - if (args.length == starting + 1) - { + if (args.length == starting + 1) { sender.sendMessage(ChatColor.RED + "You need to supply a disguise as well as the radius" + (starting != 0 ? " and EntityType" : "")); return true; } - else if (args.length < 2) - { - sender.sendMessage(ChatColor.RED + "You need to supply a radius as well as the disguise"); - return true; - } + else if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "You need to supply a radius as well as the disguise"); + return true; + } - if (!isNumeric(args[starting])) - { + if (!isNumeric(args[starting])) { sender.sendMessage(ChatColor.RED + args[starting] + " is not a number"); return true; } int radius = Integer.parseInt(args[starting]); - if (radius > maxRadius) - { + if (radius > maxRadius) { sender.sendMessage(ChatColor.RED + "Limited radius to " + maxRadius + "! Don't want to make too much lag right?"); radius = maxRadius; } @@ -141,21 +125,17 @@ public class RadiusDisguiseCommand extends BaseDisguiseCommand System.arraycopy(args, starting + 1, newArgs, 0, newArgs.length); Disguise disguise; - try - { + try { disguise = parseDisguise(sender, newArgs, map); } - catch (DisguiseParseException ex) - { - if (ex.getMessage() != null) - { + catch (DisguiseParseException ex) { + if (ex.getMessage() != null) { sender.sendMessage(ex.getMessage()); } return true; } - catch (Exception ex) - { + catch (Exception ex) { ex.printStackTrace(); return true; } @@ -164,31 +144,24 @@ public class RadiusDisguiseCommand extends BaseDisguiseCommand int disguisedEntitys = 0; int miscDisguises = 0; - for (Entity entity : ((Player) sender).getNearbyEntities(radius, radius, radius)) - { - if (entity == sender) - { + for (Entity entity : ((Player) sender).getNearbyEntities(radius, radius, radius)) { + if (entity == sender) { continue; } - if (type != null ? entity.getType() == type : entityClass.isAssignableFrom(entity.getClass())) - { + if (type != null ? entity.getType() == type : entityClass.isAssignableFrom(entity.getClass())) { if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() - && entity instanceof LivingEntity) - { + && entity instanceof LivingEntity) { miscDisguises++; continue; } disguise = disguise.clone(); - if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) - { - if (disguise.getWatcher() instanceof LivingWatcher) - { + if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { + if (disguise.getWatcher() instanceof LivingWatcher) { disguise.getWatcher().setCustomName(((Player) entity).getDisplayName()); - if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) - { + if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { disguise.getWatcher().setCustomNameVisible(true); } } @@ -196,24 +169,20 @@ public class RadiusDisguiseCommand extends BaseDisguiseCommand DisguiseAPI.disguiseToAll(entity, disguise); - if (disguise.isDisguiseInUse()) - { + if (disguise.isDisguiseInUse()) { disguisedEntitys++; } } } - if (disguisedEntitys > 0) - { + if (disguisedEntitys > 0) { sender.sendMessage(ChatColor.RED + "Successfully disguised " + disguisedEntitys + " entities!"); } - else - { + else { sender.sendMessage(ChatColor.RED + "Couldn't find any entities to disguise!"); } - if (miscDisguises > 0) - { + if (miscDisguises > 0) { sender.sendMessage(ChatColor.RED + "Failed to disguise " + miscDisguises + " entities because the option to disguise a living entity as a non-living has been disabled in the config"); } @@ -221,22 +190,126 @@ public class RadiusDisguiseCommand extends BaseDisguiseCommand return true; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + HashMap, Boolean>> perms = getPermissions(sender); + + if (args.length == 0) { + for (Class entityClass : validClasses) { + tabs.add(entityClass.getSimpleName()); + } + + return filterTabs(tabs, origArgs); + } + + int starting = 1; + + if (!isNumeric(args[0])) { + for (Class c : validClasses) { + if (!c.getSimpleName().equalsIgnoreCase(args[0])) + continue; + + starting = 2; + break; + } + + // Not a valid radius + if (starting == 1 || args.length == 1 || !isNumeric(args[1])) + return filterTabs(tabs, origArgs); + } + + if (args.length == starting) { + for (DisguiseType type : perms.keySet()) { + tabs.add(type.toReadable().replaceAll(" ", "_")); + } + } + else { + DisguiseType disguiseType; + + try { + disguiseType = DisguiseType.valueOf(args[starting].toUpperCase()); + } + catch (Exception ex) { + // No disguisetype specificied, cannot help. + return filterTabs(tabs, origArgs); + } + + if (args.length == 1 + starting && disguiseType == DisguiseType.PLAYER) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + else { + ArrayList usedOptions = new ArrayList(); + + for (Method method : ReflectionFlagWatchers.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { + for (int i = disguiseType == DisguiseType.PLAYER ? starting + 2 : starting + 1; i < args.length; i++) { + String arg = args[i]; + + if (!method.getName().equalsIgnoreCase(arg)) + continue; + + usedOptions.add(arg); + } + } + + if (passesCheck(perms.get(disguiseType), usedOptions)) { + boolean addMethods = true; + + if (args.length > 1 + starting) { + String prevArg = args[args.length - 1]; + + ParamInfo info = ReflectionFlagWatchers.getParamInfo(disguiseType, prevArg); + + if (info != null) { + if (info.getParamClass() != boolean.class) + addMethods = false; + + if (info.isEnums()) { + for (String e : info.getEnums()) { + tabs.add(e); + } + } + else { + if (info.getParamClass() == String.class) { + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + } + } + } + } + + 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())) { + tabs.add(method.getName()); + } + } + } + } + } + + return filterTabs(tabs, origArgs); + } + /** * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) - { + protected void sendCommandUsage(CommandSender sender, HashMap, Boolean>> map) { ArrayList allowedDisguises = getAllowedDisguises(map); - sender.sendMessage(ChatColor.DARK_GREEN + "Disguise all entities in a radius! Caps at 30 blocks!"); + sender.sendMessage(ChatColor.DARK_GREEN + "Disguise all entities in a radius! Caps at " + maxRadius + " blocks!"); sender.sendMessage(ChatColor.DARK_GREEN + "You can use the disguises: " + ChatColor.GREEN + StringUtils.join(allowedDisguises, ChatColor.RED + ", " + ChatColor.GREEN)); String optional = ChatColor.DARK_GREEN + "(" + ChatColor.GREEN + "Optional" + ChatColor.DARK_GREEN + ")"; - if (allowedDisguises.contains("player")) - { + if (allowedDisguises.contains("player")) { sender.sendMessage((ChatColor.DARK_GREEN + "/disguiseradius player ") .replace("<", "<" + ChatColor.GREEN).replace(">", ChatColor.DARK_GREEN + ">")); } @@ -244,8 +317,7 @@ public class RadiusDisguiseCommand extends BaseDisguiseCommand sender.sendMessage((ChatColor.DARK_GREEN + "/disguiseradius ").replace("<", "<" + ChatColor.GREEN).replace(">", ChatColor.DARK_GREEN + ">")); - if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) - { + if (allowedDisguises.contains("dropped_item") || allowedDisguises.contains("falling_block")) { sender.sendMessage((ChatColor.DARK_GREEN + "/disguiseradius ") .replace("<", "<" + ChatColor.GREEN).replace(">", ChatColor.DARK_GREEN + ">")); diff --git a/src/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java b/src/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java index 3b973c79..75c2b5fa 100644 --- a/src/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java +++ b/src/me/libraryaddict/disguise/commands/UndisguisePlayerCommand.java @@ -1,51 +1,94 @@ package me.libraryaddict.disguise.commands; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; import me.libraryaddict.disguise.DisguiseAPI; -public class UndisguisePlayerCommand implements CommandExecutor -{ +public class UndisguisePlayerCommand implements CommandExecutor, TabCompleter { + protected ArrayList filterTabs(ArrayList list, String[] origArgs) { + if (origArgs.length == 0) + return list; + + Iterator itel = list.iterator(); + String label = origArgs[origArgs.length - 1].toLowerCase(); + + while (itel.hasNext()) { + String name = itel.next(); + + if (name.toLowerCase().startsWith(label)) + continue; + + itel.remove(); + } + + return list; + } + + protected String[] getArgs(String[] args) { + ArrayList newArgs = new ArrayList(); + + for (int i = 0; i < args.length - 1; i++) { + String s = args[i]; + + if (s.trim().isEmpty()) + continue; + + newArgs.add(s); + } + + return newArgs.toArray(new String[0]); + } @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (sender.hasPermission("libsdisguises.undisguiseplayer")) - { - if (args.length > 0) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.hasPermission("libsdisguises.undisguiseplayer")) { + if (args.length > 0) { Player p = Bukkit.getPlayer(args[0]); - if (p != null) - { - if (DisguiseAPI.isDisguised(p)) - { + if (p != null) { + if (DisguiseAPI.isDisguised(p)) { DisguiseAPI.undisguiseToAll(p); sender.sendMessage(ChatColor.RED + "The player is no longer disguised"); } - else - { + else { sender.sendMessage(ChatColor.RED + "The player is not disguised!"); } } - else - { + else { sender.sendMessage(ChatColor.RED + "Player not found"); } } - else - { + else { sender.sendMessage(ChatColor.RED + "/undisguiseplayer "); } } - else - { + else { sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); } return true; } + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] origArgs) { + ArrayList tabs = new ArrayList(); + String[] args = getArgs(origArgs); + + if (args.length != 0) + return filterTabs(tabs, origArgs); + + for (Player player : Bukkit.getOnlinePlayers()) { + tabs.add(player.getName()); + } + + return filterTabs(tabs, origArgs); + } } diff --git a/src/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java b/src/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java index e3a33730..b8d12918 100644 --- a/src/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java +++ b/src/me/libraryaddict/disguise/commands/UndisguiseRadiusCommand.java @@ -9,73 +9,57 @@ import org.bukkit.entity.Player; import me.libraryaddict.disguise.DisguiseAPI; -public class UndisguiseRadiusCommand implements CommandExecutor -{ - +public class UndisguiseRadiusCommand implements CommandExecutor { private int maxRadius = 30; - public UndisguiseRadiusCommand(int maxRadius) - { + public UndisguiseRadiusCommand(int maxRadius) { this.maxRadius = maxRadius; } - private boolean isNumeric(String string) - { - try - { + private boolean isNumeric(String string) { + try { Integer.parseInt(string); return true; } - catch (Exception ex) - { + catch (Exception ex) { return false; } } @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) - { - if (sender.getName().equals("CONSOLE")) - { + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { sender.sendMessage(ChatColor.RED + "You may not use this command from the console!"); return true; } - if (sender.hasPermission("libsdisguises.undisguiseradius")) - { + if (sender.hasPermission("libsdisguises.undisguiseradius")) { int radius = maxRadius; - if (args.length > 0) - { - if (!isNumeric(args[0])) - { + if (args.length > 0) { + if (!isNumeric(args[0])) { sender.sendMessage( ChatColor.RED + "Error! " + ChatColor.GREEN + args[0] + ChatColor.RED + " is not a number!"); return true; } radius = Integer.parseInt(args[0]); - if (radius > maxRadius) - { + if (radius > maxRadius) { sender.sendMessage( ChatColor.RED + "Limited radius to " + maxRadius + "! Don't want to make too much lag right?"); radius = maxRadius; } } int disguisedEntitys = 0; - for (Entity entity : ((Player) sender).getNearbyEntities(radius, radius, radius)) - { - if (entity == sender) - { + for (Entity entity : ((Player) sender).getNearbyEntities(radius, radius, radius)) { + if (entity == sender) { continue; } - if (DisguiseAPI.isDisguised(entity)) - { + if (DisguiseAPI.isDisguised(entity)) { DisguiseAPI.undisguiseToAll(entity); disguisedEntitys++; } } sender.sendMessage(ChatColor.RED + "Successfully undisguised " + disguisedEntitys + " entities!"); } - else - { + else { sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); } return true; diff --git a/src/me/libraryaddict/disguise/disguisetypes/FlagType.java b/src/me/libraryaddict/disguise/disguisetypes/FlagType.java index 4182a0cc..ac76e61d 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/FlagType.java +++ b/src/me/libraryaddict/disguise/disguisetypes/FlagType.java @@ -172,12 +172,12 @@ public class FlagType { public static FlagType HORSE_ARMOR = new FlagType(HorseWatcher.class, 1, 0); + public static FlagType HORSE_CHESTED_CARRYING_CHEST = new FlagType(HorseChestedWatcher.class, 0, false); + public static FlagType HORSE_COLOR = new FlagType(HorseWatcher.class, 0, 0); public static FlagType HORSE_META = new FlagType(HorseAbstractWatcher.class, 0, (byte) 0); - public static FlagType HORSE_CHESTED_CARRYING_CHEST = new FlagType(HorseChestedWatcher.class, 0, false); - public static FlagType> HORSE_OWNER = new FlagType>(HorseAbstractWatcher.class, 1, Optional. absent()); @@ -192,12 +192,6 @@ public class FlagType { public static FlagType ITEMFRAME_ROTATION = new FlagType(ItemFrameWatcher.class, 1, 0); - public static FlagType LLAMA_STRENGTH = new FlagType(LlamaWatcher.class, 0, 0); - - public static FlagType LLAMA_COLOR = new FlagType(LlamaWatcher.class, 1, -1); - - public static FlagType LLAMA_CARPET = new FlagType(LlamaWatcher.class, 2, 0); - public static FlagType LIVING_ARROWS = new FlagType(LivingWatcher.class, 4, 0); public static FlagType LIVING_HAND = new FlagType(LivingWatcher.class, 0, (byte) 0); @@ -208,6 +202,12 @@ public class FlagType { public static FlagType LIVING_POTIONS = new FlagType(LivingWatcher.class, 2, 0); + public static FlagType LLAMA_CARPET = new FlagType(LlamaWatcher.class, 2, 0); + + public static FlagType LLAMA_COLOR = new FlagType(LlamaWatcher.class, 1, -1); + + public static FlagType LLAMA_STRENGTH = new FlagType(LlamaWatcher.class, 0, 0); + public static FlagType MINECART_BLOCK = new FlagType(MinecartWatcher.class, 3, 0); public static FlagType MINECART_BLOCK_VISIBLE = new FlagType(MinecartWatcher.class, 5, false); @@ -241,12 +241,12 @@ public class FlagType { public static FlagType> SHULKER_ATTACHED = new FlagType>(ShulkerWatcher.class, 1, Optional. absent()); + public static FlagType SHULKER_COLOR = new FlagType(ShulkerWatcher.class, 3, (byte) 10); + public static FlagType SHULKER_FACING = new FlagType(ShulkerWatcher.class, 0, Direction.DOWN); public static FlagType SHULKER_PEEKING = new FlagType(ShulkerWatcher.class, 2, (byte) 0); - public static FlagType SHULKER_COLOR = new FlagType(ShulkerWatcher.class, 3, (byte) 10); - public static FlagType SKELETON_SWING_ARMS = new FlagType(SkeletonWatcher.class, 0, false); public static FlagType SLIME_SIZE = new FlagType(SlimeWatcher.class, 0, 0); @@ -299,10 +299,10 @@ public class FlagType { public static FlagType ZOMBIE_AGGRESSIVE = new FlagType(ZombieWatcher.class, 2, false); - public static FlagType ZOMBIE_PLACEHOLDER = new FlagType(ZombieWatcher.class, 1, 0); - public static FlagType ZOMBIE_BABY = new FlagType(ZombieWatcher.class, 0, false); + public static FlagType ZOMBIE_PLACEHOLDER = new FlagType(ZombieWatcher.class, 1, 0); + public static FlagType ZOMBIE_VILLAGER_PROFESSION = new FlagType(ZombieVillagerWatcher.class, 1, 0); public static FlagType ZOMBIE_VILLAGER_SHAKING = new FlagType(ZombieVillagerWatcher.class, 0, false); diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java b/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java new file mode 100644 index 00000000..f45cc40d --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/ReflectionFlagWatchers.java @@ -0,0 +1,212 @@ +package me.libraryaddict.disguise.utilities; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +import org.apache.commons.lang.StringUtils; +import org.bukkit.Art; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Llama; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Villager; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffectType; + +import com.comphenix.protocol.wrappers.BlockPosition; +import com.mojang.authlib.GameProfile; + +import me.libraryaddict.disguise.disguisetypes.AnimalColor; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagWatcher; + +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 = name; + this.description = 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(); + } + } + } + + public ParamInfo(Class paramClass, Enum[] enums, String name, String description) { + this.name = name; + this.enums = new String[enums.length]; + this.description = description; + this.paramClass = paramClass; + + for (int i = 0; i < enums.length; i++) { + this.enums[i] = enums[i].name(); + } + } + + public ParamInfo(Class paramClass, String name, String description, String[] enums) { + this.name = name; + this.enums = enums; + this.description = description; + this.paramClass = paramClass; + } + + public boolean isEnums() { + return enums != null; + } + + public Class getParamClass() { + return paramClass; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String[] getEnums() { + 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(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.add(new ParamInfo(AnimalColor.class, "Animal Color", "View all the colors you can use for an animal color")); + paramList.add(new ParamInfo(Art.class, "Art", "View all the paintings you can use for a painting disguise")); + paramList.add(new ParamInfo(Llama.Color.class, "Llama Color", "View all the colors you can use for a llama color")); + paramList.add(new ParamInfo(Horse.Color.class, "Horse Color", "View all the colors you can use for a horses color")); + paramList.add(new ParamInfo(Ocelot.Type.class, "Ocelot Type", "View all the ocelot types you can use for ocelots")); + paramList.add(new ParamInfo(Villager.Profession.class, "Villager Profession", + "View all the professions you can set on a villager")); + paramList.add(new ParamInfo(BlockFace.class, Arrays.copyOf(BlockFace.values(), 5), "Direction", + "View the five directions usable on player setSleeping disguise")); + paramList.add(new ParamInfo(Rabbit.Type.class, "Rabbit Type", "View the kinds of rabbits you can turn into")); + + ArrayList potionEnums = new ArrayList(); + + for (PotionEffectType effectType : PotionEffectType.values()) { + if (effectType == null) + continue; + + potionEnums.add(toReadable(effectType.getName())); + } + + paramList.add(new ParamInfo(PotionEffectType.class, "Potion Effect", "View all the potion effects you can add", + potionEnums.toArray(new String[0]))); + paramList.add(new ParamInfo(String.class, "Text", "A line of text")); + paramList.add(new ParamInfo(boolean.class, "True/False", "True or False", new String[] { + "true", "false" + })); + paramList.add(new ParamInfo(int.class, "Number", "A whole number, no decimcals")); + paramList.add(new ParamInfo(double.class, "Number", "A number which can have decimals")); + paramList.add(new ParamInfo(float.class, "Number", "A number which can have decimals")); + paramList.add(new ParamInfo(ItemStack.class, "Item (id:damage)", "An ItemStack compromised of ID:Durability")); + paramList.add( + new ParamInfo(ItemStack[].class, "Four ItemStacks (id:damage,id:damage..)", "Four ItemStacks seperated by an ,")); + paramList.add(new ParamInfo(Horse.Style.class, "Horse Style", "Horse style which is the patterns on the horse")); + paramList.add(new ParamInfo(int[].class, "number,number,number...", "Numbers seperated by an ,")); + paramList.add(new ParamInfo(BlockPosition.class, "Block Position (num,num,num)", "Three numbers seperated by an ,")); + paramList.add(new ParamInfo(GameProfile.class, "GameProfile", + "Get the gameprofile here https://sessionserver.mojang.com/session/minecraft/profile/PLAYER_UUID_GOES_HERE?unsigned=false")); + } + + public static Method[] getDisguiseWatcherMethods(Class watcherClass) { + 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(); + } + } + + for (String methodName : new String[] { + "setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf", "setHearSelfDisguise" + }) { + 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, "_"); + } +}