From 1c04576ae31ae16d96d406e31e71046739484e93 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Wed, 24 Oct 2018 10:13:13 +1300 Subject: [PATCH] Changed permission system from maps/lists to object based supporting inheritance with unit testing. --- pom.xml | 7 + .../disguise/DisguiseListener.java | 12 +- .../commands/DisguiseBaseCommand.java | 64 +-- .../commands/DisguiseCloneCommand.java | 6 +- .../disguise/commands/DisguiseCommand.java | 15 +- .../commands/DisguiseEntityCommand.java | 19 +- .../commands/DisguiseHelpCommand.java | 199 ++++---- .../commands/DisguiseModifyCommand.java | 31 +- .../commands/DisguiseModifyEntityCommand.java | 23 +- .../commands/DisguiseModifyPlayerCommand.java | 34 +- .../commands/DisguiseModifyRadiusCommand.java | 45 +- .../commands/DisguisePlayerCommand.java | 26 +- .../commands/DisguiseRadiusCommand.java | 34 +- .../utilities/parser/DisguiseParser.java | 301 ++---------- .../utilities/parser/DisguisePerm.java | 5 + .../utilities/parser/DisguisePermissions.java | 441 ++++++++++++++++++ .../parser/DisguisePermissionsTest.java | 303 ++++++++++++ 17 files changed, 1024 insertions(+), 541 deletions(-) create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java create mode 100644 src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java diff --git a/pom.xml b/pom.xml index 1b3040bc..675f3755 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,13 @@ spigot 1.13-R0.1-SNAPSHOT + + + junit + junit + 4.12 + test + diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java index 387ae3a1..50a3930c 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java @@ -19,6 +19,7 @@ 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.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -42,7 +43,7 @@ import org.bukkit.scheduler.BukkitTask; import org.bukkit.scoreboard.Team; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -529,17 +530,16 @@ public class DisguiseListener implements Listener { return; } - HashMap, Boolean>> perms = DisguiseParser - .getPermissions(p, "libsdisguises.disguiseentitymodify."); + DisguisePermissions perms = DisguiseParser.getPermissions(p, "disguiseentitymodify"); + DisguisePerm disguisePerm = new DisguisePerm(disguise.getType()); - if (!perms.containsKey(new DisguisePerm(disguise.getType()))) { + if (!perms.isAllowedDisguise(disguisePerm, Arrays.asList(options))) { p.sendMessage(LibsMsg.DMODPLAYER_NOPERM.get()); return; } try { - DisguiseParser.callMethods(p, disguise, perms.get(new DisguisePerm(disguise.getType())), - new ArrayList(), options); + DisguiseParser.callMethods(p, disguise, perms, disguisePerm, Arrays.asList(options), options); p.sendMessage(LibsMsg.LISTENER_MODIFIED_DISG.get()); } catch (DisguiseParseException ex) { diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java index a59e0596..378e3ab2 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseBaseCommand.java @@ -2,6 +2,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import me.libraryaddict.disguise.utilities.parser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -13,6 +14,22 @@ import java.util.*; * @author libraryaddict */ public abstract class DisguiseBaseCommand implements CommandExecutor { + private static final Map, String> disguiseCommands; + + static { + HashMap, String> map = new HashMap<>(); + + map.put(DisguiseCommand.class, "Disguise"); + map.put(DisguiseEntityCommand.class, "DisguiseEntity"); + map.put(DisguisePlayerCommand.class, "DisguisePlayer"); + map.put(DisguiseRadiusCommand.class, "DisguiseRadius"); + map.put(DisguiseModifyCommand.class, "DisguiseModify"); + map.put(DisguiseModifyEntityCommand.class, "DisguiseModifyEntity"); + map.put(DisguiseModifyPlayerCommand.class, "DisguiseModifyPlayer"); + map.put(DisguiseModifyRadiusCommand.class, "DisguiseModifyRadius"); + + disguiseCommands = map; + } protected ArrayList filterTabs(ArrayList list, String[] origArgs) { if (origArgs.length == 0) @@ -39,19 +56,16 @@ public abstract class DisguiseBaseCommand implements CommandExecutor { return (team == null ? "" : team.getPrefix()) + player.getName() + (team == null ? "" : team.getSuffix()); } - protected ArrayList getAllowedDisguises( - HashMap, Boolean>> hashMap) { + protected ArrayList getAllowedDisguises(DisguisePermissions permissions) { ArrayList allowedDisguises = new ArrayList<>(); - for (DisguisePerm type : hashMap.keySet()) { + for (DisguisePerm type : permissions.getAllowed()) { if (type.isUnknown()) continue; allowedDisguises.add(type.toReadable().replaceAll(" ", "_")); } - Collections.sort(allowedDisguises, String.CASE_INSENSITIVE_ORDER); - return allowedDisguises; } @@ -70,33 +84,25 @@ public abstract class DisguiseBaseCommand implements CommandExecutor { return newArgs.toArray(new String[0]); } + protected static final Map, String> getCommandNames() { + return disguiseCommands; + } + public final String getPermNode() { - if (this instanceof DisguiseCommand) { - return "disguise"; - } else if (this instanceof DisguiseEntityCommand) { - return "disguiseentity"; - } else if (this instanceof DisguisePlayerCommand) { - return "disguiseplayer"; - } else if (this instanceof DisguiseRadiusCommand) { - return "disguiseradius"; - } else if (this instanceof DisguiseModifyCommand) { - return "disguisemodify"; - } else if (this instanceof DisguiseModifyEntityCommand) { - return "disguisemodifyentity"; - } else if (this instanceof DisguiseModifyPlayerCommand) { - return "disguisemodifyplayer"; - } else if (this instanceof DisguiseModifyRadiusCommand) { - return "disguisemodifyradius"; - } else { + String name = getCommandNames().get(this.getClass()); + + if (name == null) { throw new UnsupportedOperationException("Unknown disguise command, perm node not found"); } + + return name; } - protected HashMap, Boolean>> getPermissions(CommandSender sender) { - return DisguiseParser.getPermissions(sender, "libsdisguises." + getPermNode() + "."); + protected DisguisePermissions getPermissions(CommandSender sender) { + return DisguiseParser.getPermissions(sender, getPermNode()); } - protected boolean isNumeric(String string) { + protected boolean isInteger(String string) { try { Integer.parseInt(string); return true; @@ -106,11 +112,5 @@ public abstract class DisguiseBaseCommand implements CommandExecutor { } } - public boolean passesCheck(CommandSender sender, HashMap, Boolean> theirPermissions, - ArrayList usedOptions) { - return DisguiseParser.passesCheck(sender, theirPermissions, usedOptions); - } - - protected abstract void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map); + protected abstract void sendCommandUsage(CommandSender sender, DisguisePermissions disguisePermissions); } diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java index bfe441eb..4a7c0893 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCloneCommand.java @@ -2,9 +2,9 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.utilities.parser.DisguisePerm; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsMsg; +import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -13,7 +13,6 @@ import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; public class DisguiseCloneCommand extends DisguiseBaseCommand implements TabCompleter { @@ -91,8 +90,7 @@ public class DisguiseCloneCommand extends DisguiseBaseCommand implements TabComp * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { sender.sendMessage(LibsMsg.CLONE_HELP1.get()); sender.sendMessage(LibsMsg.CLONE_HELP2.get()); sender.sendMessage(LibsMsg.CLONE_HELP3.get()); diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java index 5c8f4458..9c582c9d 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseCommand.java @@ -6,10 +6,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.parser.DisguiseParser; -import me.libraryaddict.disguise.utilities.parser.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -22,7 +19,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter { @@ -103,7 +99,7 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter ArrayList tabs = new ArrayList<>(); String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); if (args.length == 0) { tabs.addAll(getAllowedDisguises(perms)); @@ -132,7 +128,7 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter } } - if (passesCheck(sender, perms.get(disguiseType), usedOptions)) { + if (perms.isAllowedDisguise(disguiseType, usedOptions)) { boolean addMethods = true; if (args.length > 1) { @@ -173,9 +169,8 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.DISG_HELP1.get()); sender.sendMessage(LibsMsg.CAN_USE_DISGS .get(ChatColor.GREEN + StringUtils.join(allowedDisguises, ChatColor.RED + ", " + ChatColor.GREEN))); diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java index 844052b8..69bbe536 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseEntityCommand.java @@ -5,10 +5,7 @@ import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.parser.DisguiseParser; -import me.libraryaddict.disguise.utilities.parser.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -32,7 +29,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom return true; } - if (getPermissions(sender).isEmpty()) { + if (!getPermissions(sender).hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } @@ -78,7 +75,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); if (args.length == 0) { for (String type : getAllowedDisguises(perms)) { @@ -108,7 +105,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom } } - if (passesCheck(sender, perms.get(disguiseType), usedOptions)) { + if (perms.isAllowedDisguise(disguiseType, usedOptions)) { boolean addMethods = true; if (args.length > 1) { @@ -147,14 +144,10 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom /** * Send the player the information - * - * @param sender - * @param map */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.DISG_ENT_HELP1.get()); sender.sendMessage(LibsMsg.CAN_USE_DISGS diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java index f8cf9ccf..92f1e4e0 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseHelpCommand.java @@ -4,6 +4,7 @@ import me.libraryaddict.disguise.utilities.LibsMsg; import me.libraryaddict.disguise.utilities.TranslateType; import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import me.libraryaddict.disguise.utilities.parser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; @@ -14,124 +15,110 @@ import org.bukkit.command.TabCompleter; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.List; public class DisguiseHelpCommand extends DisguiseBaseCommand 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 = DisguiseParser - .getPermissions(sender, "libsdisguises." + node + "."); + for (String node : getCommandNames().values()) { + DisguisePermissions perms = DisguiseParser.getPermissions(sender, node); - if (!permMap.isEmpty()) { - if (args.length == 0) { - sendCommandUsage(sender, null); - return true; - } else { - ParamInfo help = null; + if (!perms.hasPermissions()) { + continue; + } - for (ParamInfo s : ParamInfoManager.getParamInfos()) { - String name = s.getName().replaceAll(" ", ""); + if (args.length == 0) { + sendCommandUsage(sender, null); + return true; + } else { + ParamInfo help = null; - if (args[0].equalsIgnoreCase(name) || args[0].equalsIgnoreCase(name + "s")) { - help = s; - break; - } + for (ParamInfo s : ParamInfoManager.getParamInfos()) { + String name = s.getName().replaceAll(" ", ""); + + if (args[0].equalsIgnoreCase(name) || args[0].equalsIgnoreCase(name + "s")) { + help = s; + break; } + } - if (help != null) { - if (help.hasValues() && help.canTranslateValues()) { - sender.sendMessage(LibsMsg.DHELP_HELP4.get(help.getName(), - StringUtils.join(help.getEnums(""), LibsMsg.DHELP_HELP4_SEPERATOR.get()))); + if (help != null) { + if (help.hasValues() && help.canTranslateValues()) { + sender.sendMessage(LibsMsg.DHELP_HELP4.get(help.getName(), + StringUtils.join(help.getEnums(""), LibsMsg.DHELP_HELP4_SEPERATOR.get()))); + } else { + if (!help.getName().equals(help.getDescriptiveName())) { + sender.sendMessage(LibsMsg.DHELP_HELP6 + .get(help.getName(), help.getDescriptiveName(), help.getDescription())); } else { - 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())); - } + sender.sendMessage(LibsMsg.DHELP_HELP5.get(help.getName(), help.getDescription())); } - - return true; - } - - DisguisePerm type = DisguiseParser.getDisguisePerm(args[0]); - - if (type == null) { - sender.sendMessage(LibsMsg.DHELP_CANTFIND.get(args[0])); - return true; - } - - if (!permMap.containsKey(type)) { - sender.sendMessage(LibsMsg.NO_PERM_DISGUISE.get()); - return true; - } - - ArrayList methods = new ArrayList<>(); - Class watcher = type.getWatcherClass(); - int ignored = 0; - - try { - for (Method method : ParamInfoManager.getDisguiseWatcherMethods(watcher)) { - if (args.length < 2 || !args[1].equalsIgnoreCase(LibsMsg.DHELP_SHOW.get())) { - 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 = ParamInfoManager.getParamInfo(c); - - int value = ParamInfoManager.getValue(method); - ChatColor methodColor = ChatColor.YELLOW; - - if (value == 1) { - methodColor = ChatColor.AQUA; - } else if (value == 2) { - methodColor = ChatColor.GRAY; - } - - String str = - TranslateType.DISGUISE_OPTIONS.get(method.getName()) + ChatColor.DARK_RED + "(" + - ChatColor.GREEN + info.getName() + ChatColor.DARK_RED + ")"; - - methods.add(methodColor + str); - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - - if (methods.isEmpty()) { - methods.add(LibsMsg.DHELP_NO_OPTIONS.get()); - } - - sender.sendMessage(LibsMsg.DHELP_OPTIONS.get(ChatColor.DARK_RED + type.toReadable(), - StringUtils.join(methods, ChatColor.DARK_RED + ", "))); - - if (ignored > 0) { - sender.sendMessage(LibsMsg.NO_PERMS_USE_OPTIONS.get(ignored)); } return true; } + + DisguisePerm type = DisguiseParser.getDisguisePerm(args[0]); + + if (type == null) { + sender.sendMessage(LibsMsg.DHELP_CANTFIND.get(args[0])); + return true; + } + + if (!perms.isAllowedDisguise(type)) { + sender.sendMessage(LibsMsg.NO_PERM_DISGUISE.get()); + return true; + } + + ArrayList methods = new ArrayList<>(); + Class watcher = type.getWatcherClass(); + int ignored = 0; + + try { + for (Method method : ParamInfoManager.getDisguiseWatcherMethods(watcher)) { + if (args.length < 2 || !args[1].equalsIgnoreCase(LibsMsg.DHELP_SHOW.get())) { + if (!perms.isAllowedDisguise(type, Collections.singleton(method.getName().toLowerCase()))) { + ignored++; + continue; + } + } + + Class c = method.getParameterTypes()[0]; + ParamInfo info = ParamInfoManager.getParamInfo(c); + + int value = ParamInfoManager.getValue(method); + ChatColor methodColor = ChatColor.YELLOW; + + if (value == 1) { + methodColor = ChatColor.AQUA; + } else if (value == 2) { + methodColor = ChatColor.GRAY; + } + + String str = TranslateType.DISGUISE_OPTIONS.get(method.getName()) + ChatColor.DARK_RED + "(" + + ChatColor.GREEN + info.getName() + ChatColor.DARK_RED + ")"; + + methods.add(methodColor + str); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + + if (methods.isEmpty()) { + methods.add(LibsMsg.DHELP_NO_OPTIONS.get()); + } + + sender.sendMessage(LibsMsg.DHELP_OPTIONS.get(ChatColor.DARK_RED + type.toReadable(), + StringUtils.join(methods, ChatColor.DARK_RED + ", "))); + + if (ignored > 0) { + sender.sendMessage(LibsMsg.NO_PERMS_USE_OPTIONS.get(ignored)); + } + + return true; } } @@ -144,12 +131,11 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl ArrayList tabs = new ArrayList<>(); String[] args = getArgs(origArgs); - for (String node : new String[]{"disguise", "disguiseradius", "disguiseentity", "disguiseplayer"}) { - HashMap, Boolean>> perms = DisguiseParser - .getPermissions(sender, "libsdisguises." + node + "."); + for (String node : getCommandNames().values()) { + DisguisePermissions perms = DisguiseParser.getPermissions(sender, node); if (args.length == 0) { - for (DisguisePerm type : perms.keySet()) { + for (DisguisePerm type : perms.getAllowed()) { if (type.isUnknown()) continue; @@ -171,8 +157,7 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { sender.sendMessage(LibsMsg.DHELP_HELP1.get()); sender.sendMessage(LibsMsg.DHELP_HELP2.get()); diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java index 02e12ace..1a911390 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyCommand.java @@ -4,10 +4,7 @@ import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.parser.DisguiseParser; -import me.libraryaddict.disguise.utilities.parser.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -20,7 +17,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCompleter { @@ -31,15 +27,15 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom return true; } - HashMap, Boolean>> map = getPermissions(sender); + DisguisePermissions permissions = getPermissions(sender); - if (map.isEmpty()) { + if (!permissions.hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } if (args.length == 0) { - sendCommandUsage(sender, getPermissions(sender)); + sendCommandUsage(sender, permissions); return true; } @@ -50,15 +46,16 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom return true; } - if (!map.containsKey(new DisguisePerm(disguise.getType()))) { + DisguisePerm disguisePerm = new DisguisePerm(disguise.getType()); + + if (!permissions.isAllowedDisguise(disguisePerm)) { sender.sendMessage(LibsMsg.DMODIFY_NO_PERM.get()); return true; } try { - DisguiseParser - .callMethods(sender, disguise, getPermissions(sender).get(new DisguisePerm(disguise.getType())), - new ArrayList(), DisguiseParser.split(StringUtils.join(args, " "))); + DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(), + DisguiseParser.split(StringUtils.join(args, " "))); } catch (DisguiseParseException ex) { if (ex.getMessage() != null) { @@ -91,7 +88,7 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); DisguisePerm disguiseType = new DisguisePerm(disguise.getType()); @@ -108,7 +105,7 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom } } - if (passesCheck(sender, perms.get(disguiseType), usedOptions)) { + if (perms.isAllowedDisguise(disguiseType, usedOptions)) { boolean addMethods = true; if (args.length > 0) { @@ -146,9 +143,9 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); + sender.sendMessage(LibsMsg.DMODIFY_HELP3.get()); sender.sendMessage(LibsMsg.DMODIFY_HELP3.get()); sender.sendMessage(LibsMsg.DMODIFY_HELP3 diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java index 7a8b70da..4ccf95f6 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyEntityCommand.java @@ -5,6 +5,7 @@ import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.utilities.LibsMsg; import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import me.libraryaddict.disguise.utilities.parser.DisguisePerm; +import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; @@ -17,7 +18,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements TabCompleter { @@ -28,13 +28,15 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements return true; } - if (getPermissions(sender).isEmpty()) { + DisguisePermissions permissions = getPermissions(sender); + + if (!permissions.hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } if (args.length == 0) { - sendCommandUsage(sender, getPermissions(sender)); + sendCommandUsage(sender, permissions); return true; } @@ -57,12 +59,13 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); - if (perms.isEmpty()) + if (!perms.hasPermissions()) { return tabs; + } - for (DisguisePerm perm : perms.keySet()) { + for (DisguisePerm perm : perms.getAllowed()) { boolean addMethods = true; if (args.length > 0) { @@ -98,14 +101,10 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements /** * Send the player the information - * - * @param sender - * @param map */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.DMODENT_HELP1.get()); sender.sendMessage(LibsMsg.DMODIFY_HELP3 diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java index 9d805937..b44147c8 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyPlayerCommand.java @@ -3,10 +3,7 @@ package me.libraryaddict.disguise.commands; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.parser.DisguiseParser; -import me.libraryaddict.disguise.utilities.parser.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -18,22 +15,21 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements TabCompleter { @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - HashMap, Boolean>> map = getPermissions(sender); + DisguisePermissions permissions = getPermissions(sender); - if (map.isEmpty()) { + if (!permissions.hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } if (args.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -48,7 +44,7 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements System.arraycopy(args, 1, newArgs, 0, newArgs.length); if (newArgs.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -65,14 +61,16 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements return true; } - if (!map.containsKey(new DisguisePerm(disguise.getType()))) { + DisguisePerm disguisePerm = new DisguisePerm(disguise.getType()); + + if (!permissions.isAllowedDisguise(disguisePerm)) { sender.sendMessage(LibsMsg.DMODPLAYER_NOPERM.get()); return true; } try { - DisguiseParser.callMethods(sender, disguise, map.get(new DisguisePerm(disguise.getType())), - new ArrayList(), DisguiseParser.split(StringUtils.join(newArgs, " "))); + DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(), + DisguiseParser.split(StringUtils.join(newArgs, " "))); } catch (DisguiseParseException ex) { if (ex.getMessage() != null) { @@ -96,10 +94,11 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements ArrayList tabs = new ArrayList<>(); String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); - if (perms.isEmpty()) + if (!perms.hasPermissions()) { return tabs; + } if (args.length == 0) { for (Player player : Bukkit.getOnlinePlayers()) { @@ -141,7 +140,7 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements } } - if (passesCheck(sender, perms.get(disguiseType), usedOptions)) { + if (perms.isAllowedDisguise(disguiseType, usedOptions)) { boolean addMethods = true; if (args.length > 1) { @@ -180,9 +179,8 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.DMODPLAYER_HELP1.get()); sender.sendMessage(LibsMsg.DMODIFY_HELP3 diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java index 1c59da89..75dcac67 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseModifyRadiusCommand.java @@ -5,10 +5,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; 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.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -22,7 +19,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.Collection; +import java.util.Collections; +import java.util.List; public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements TabCompleter { private int maxRadius = 30; @@ -50,15 +50,15 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements return true; } - HashMap, Boolean>> map = getPermissions(sender); + DisguisePermissions permissions = getPermissions(sender); - if (map.isEmpty()) { + if (!permissions.hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } if (args.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -80,7 +80,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements DisguiseType baseType = null; int starting = 0; - if (!isNumeric(args[0])) { + if (!isInteger(args[0])) { for (DisguiseType t : DisguiseType.values()) { if (t.toReadable().replaceAll(" ", "").equalsIgnoreCase(args[0].replaceAll("_", ""))) { baseType = t; @@ -104,7 +104,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements return true; } - if (!isNumeric(args[starting])) { + if (!isInteger(args[starting])) { sender.sendMessage(LibsMsg.NOT_NUMBER.get(args[starting])); return true; } @@ -120,7 +120,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements System.arraycopy(args, starting + 1, newArgs, 0, newArgs.length); if (newArgs.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -144,14 +144,16 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements else disguise = DisguiseAPI.getDisguise(entity); - if (!map.containsKey(new DisguisePerm(disguise.getType()))) { + DisguisePerm disguisePerm = new DisguisePerm(disguise.getType()); + + if (!permissions.isAllowedDisguise(disguisePerm)) { noPermission++; continue; } try { - DisguiseParser.callMethods(sender, disguise, map.get(new DisguisePerm(disguise.getType())), - new ArrayList(), DisguiseParser.split(StringUtils.join(newArgs, " "))); + DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(), + DisguiseParser.split(StringUtils.join(newArgs, " "))); modifiedDisguises++; } catch (DisguiseParseException ex) { @@ -185,7 +187,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements ArrayList tabs = new ArrayList<>(); String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); if (args.length == 0) { for (DisguiseType type : DisguiseType.values()) { @@ -197,7 +199,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements int starting = 0; - if (!isNumeric(args[0])) { + if (!isInteger(args[0])) { for (DisguiseType t : DisguiseType.values()) { if (t.toReadable().replaceAll(" ", "").equalsIgnoreCase(args[0].replaceAll("_", ""))) { @@ -207,11 +209,11 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements } // Not a valid radius - if (starting == 1 || args.length == 1 || !isNumeric(args[1])) + if (starting == 1 || args.length == 1 || !isInteger(args[1])) return filterTabs(tabs, origArgs); } - if (!isNumeric(args[starting])) { + if (!isInteger(args[starting])) { return filterTabs(tabs, origArgs); } @@ -241,7 +243,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements } } - if (passesCheck(sender, perms.get(new DisguisePerm(disguiseType)), usedOptions)) { + if (perms.isAllowedDisguise(new DisguisePerm(disguiseType), usedOptions)) { boolean addMethods = true; if (args.length > 1 + starting) { @@ -280,9 +282,8 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.DMODRADIUS_HELP1.get(maxRadius)); sender.sendMessage(LibsMsg.DMODIFY_HELP3 diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java index c599cc97..f5fb03c9 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguisePlayerCommand.java @@ -6,10 +6,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; import me.libraryaddict.disguise.utilities.LibsMsg; -import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; -import me.libraryaddict.disguise.utilities.parser.DisguiseParser; -import me.libraryaddict.disguise.utilities.parser.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -22,7 +19,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.UUID; @@ -30,15 +26,15 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - HashMap, Boolean>> map = getPermissions(sender); + DisguisePermissions permissions = getPermissions(sender); - if (map.isEmpty()) { + if (!permissions.hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } if (args.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -68,7 +64,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom System.arraycopy(args, 1, newArgs, 0, newArgs.length); if (newArgs.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -76,7 +72,8 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom try { disguise = DisguiseParser - .parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(newArgs, " ")), map); + .parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(newArgs, " ")), + permissions); } catch (DisguiseParseException ex) { if (ex.getMessage() != null) { @@ -144,7 +141,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom ArrayList tabs = new ArrayList<>(); String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); if (args.length == 0) { for (Player player : Bukkit.getOnlinePlayers()) { @@ -176,7 +173,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom } } - if (passesCheck(sender, perms.get(disguiseType), usedOptions)) { + if (perms.isAllowedDisguise(disguiseType, usedOptions)) { boolean addMethods = true; if (args.length > 2) { @@ -217,9 +214,8 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.D_HELP1.get()); sender.sendMessage(LibsMsg.CAN_USE_DISGS diff --git a/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java index e9e1a885..645ebf22 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/DisguiseRadiusCommand.java @@ -8,10 +8,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; 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.DisguisePerm; -import me.libraryaddict.disguise.utilities.parser.ParamInfoManager; +import me.libraryaddict.disguise.utilities.parser.*; import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; @@ -29,7 +26,6 @@ import org.bukkit.entity.Player; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCompleter { @@ -52,15 +48,15 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom return true; } - HashMap, Boolean>> map = getPermissions(sender); + DisguisePermissions permissions = getPermissions(sender); - if (map.isEmpty()) { + if (!permissions.hasPermissions()) { sender.sendMessage(LibsMsg.NO_PERM.get()); return true; } if (args.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } @@ -83,7 +79,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom EntityType type = null; int starting = 0; - if (!isNumeric(args[0])) { + if (!isInteger(args[0])) { for (Class c : validClasses) { if (TranslateType.DISGUISES.get(c.getSimpleName()).equalsIgnoreCase(args[0])) { entityClass = c; @@ -115,7 +111,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom return true; } - if (!isNumeric(args[starting])) { + if (!isInteger(args[starting])) { sender.sendMessage(LibsMsg.NOT_NUMBER.get(args[starting])); return true; } @@ -132,13 +128,14 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom Disguise disguise; if (newArgs.length == 0) { - sendCommandUsage(sender, map); + sendCommandUsage(sender, permissions); return true; } try { disguise = DisguiseParser - .parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(newArgs, " ")), map); + .parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(newArgs, " ")), + permissions); } catch (DisguiseParseException ex) { if (ex.getMessage() != null) { @@ -234,7 +231,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom ArrayList tabs = new ArrayList<>(); String[] args = getArgs(origArgs); - HashMap, Boolean>> perms = getPermissions(sender); + DisguisePermissions perms = getPermissions(sender); if (args.length == 0) { for (Class entityClass : validClasses) { @@ -246,7 +243,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom int starting = 1; - if (!isNumeric(args[0])) { + if (!isInteger(args[0])) { for (Class c : validClasses) { if (!TranslateType.DISGUISES.get(c.getSimpleName()).equalsIgnoreCase(args[0])) continue; @@ -256,7 +253,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom } // Not a valid radius - if (starting == 1 || args.length == 1 || !isNumeric(args[1])) + if (starting == 1 || args.length == 1 || !isInteger(args[1])) return filterTabs(tabs, origArgs); } @@ -288,7 +285,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom } } - if (passesCheck(sender, perms.get(disguiseType), usedOptions)) { + if (perms.isAllowedDisguise(disguiseType, usedOptions)) { boolean addMethods = true; if (args.length > 1 + starting) { @@ -329,9 +326,8 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom * Send the player the information */ @Override - protected void sendCommandUsage(CommandSender sender, - HashMap, Boolean>> map) { - ArrayList allowedDisguises = getAllowedDisguises(map); + protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { + ArrayList allowedDisguises = getAllowedDisguises(permissions); sender.sendMessage(LibsMsg.DRADIUS_HELP1.get(maxRadius)); sender.sendMessage(LibsMsg.CAN_USE_DISGS diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java index 3fc8bfd3..a5f4e6d5 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguiseParser.java @@ -6,33 +6,27 @@ 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.apache.commons.lang3.tuple.Pair; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Ageable; -import org.bukkit.entity.Animals; -import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.permissions.PermissionAttachmentInfo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DisguiseParser { - private static void doCheck(CommandSender sender, HashMap, Boolean> optionPermissions, - ArrayList usedOptions) throws DisguiseParseException { + private static void doCheck(CommandSender sender, DisguisePermissions permissions, DisguisePerm disguisePerm, + Collection usedOptions) throws DisguiseParseException { - if (!passesCheck(sender, optionPermissions, usedOptions)) { - throw new DisguiseParseException(LibsMsg.D_PARSE_NOPERM, usedOptions.get(usedOptions.size() - 1)); + if (!permissions.isAllowedDisguise(disguisePerm, usedOptions)) { + throw new DisguiseParseException(LibsMsg.D_PARSE_NOPERM, + usedOptions.stream().reduce((first, second) -> second).orElse(null)); } } @@ -101,213 +95,11 @@ public class DisguiseParser { return perms; } - private static Pair, Boolean> getOptions(String perm, boolean permitted) { - ArrayList list = new ArrayList<>(); - 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); - permitted = false; - } - - if (option.equals("baby")) { - option = "setbaby"; - } - - list.add(option); - } - - return Pair.of(list, permitted); - } - /** * 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); - } - - // The first passthrough - // This sets what permissions they can use where a negated permission is refering to the parameters - for (Entry entry : perms.entrySet()) { - String perm = entry.getKey().substring(permissionNode.length()); - String[] split = perm.split("\\."); - - String disguiseType = split[0]; - - // Permission was negated, wasn't refering to parameters - if (!entry.getValue() && split.length == 1) { - continue; - } - - 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); - } - - Pair, Boolean> options = getOptions(perm, entry.getValue()); - - list.put(options.getKey(), options.getValue()); - } else { - for (DisguisePerm type : getDisguisePerms()) { - Pair, Boolean> options = null; - Class entityClass = type.getEntityClass(); - - if (disguiseType.equals("mob")) { - if (type.isMob()) { - options = getOptions(perm, entry.getValue()); - } - } else if (disguiseType.equals("animal") || disguiseType.equals("animals")) { - if (Animals.class.isAssignableFrom(entityClass)) { - options = getOptions(perm, entry.getValue()); - } - } else if (disguiseType.equals("monster") || disguiseType.equals("monsters")) { - if (Monster.class.isAssignableFrom(entityClass)) { - options = getOptions(perm, entry.getValue()); - } - } else if (disguiseType.equals("misc")) { - if (type.isMisc()) { - options = getOptions(perm, entry.getValue()); - } - } else if (disguiseType.equals("ageable")) { - if (Ageable.class.isAssignableFrom(entityClass)) { - options = getOptions(perm, entry.getValue()); - } - } else if (disguiseType.equals("*")) { - options = getOptions(perm, entry.getValue()); - } - - if (options != null) { - HashMap, Boolean> list = rangeDisguises - .computeIfAbsent(type, k -> new HashMap<>()); - - list.put(new ArrayList<>(options.getKey()), options.getValue()); - } - } - } - } - - // Find disguises to negate, only removes does not add - for (String perm : perms.keySet()) { - // If not negated, continue - if (perms.get(perm)) { - continue; - } - - perm = perm.substring(permissionNode.length()); - - String[] split = perm.split("\\."); - - // Permission has parameters, which means the parameters were negated not the disguise - if (split.length > 1) { - continue; - } - - String disguiseType = split[0]; - - DisguisePerm dType = DisguiseParser.getDisguisePerm(disguiseType); - - if (dType != null) { - singleDisguises.remove(dType); - rangeDisguises.remove(dType); - } else { - for (DisguisePerm type : getDisguisePerms()) { - boolean foundDisguiseType = false; - Class entityClass = type.getEntityClass(); - - switch (disguiseType) { - case "mob": - if (type.isMob()) { - foundDisguiseType = true; - } - - break; - case "animal": - case "animals": - if (Animals.class.isAssignableFrom(entityClass)) { - foundDisguiseType = true; - } - - break; - case "monster": - case "monsters": - if (Monster.class.isAssignableFrom(entityClass)) { - foundDisguiseType = true; - } - - break; - case "misc": - if (type.isMisc()) { - foundDisguiseType = true; - } - - break; - case "ageable": - if (Ageable.class.isAssignableFrom(entityClass)) { - foundDisguiseType = true; - } - - break; - case "*": - foundDisguiseType = true; - break; - } - - if (foundDisguiseType) { - 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; + public static DisguisePermissions getPermissions(CommandSender sender, String commandName) { + return new DisguisePermissions(sender, commandName); } private static boolean isDouble(String string) { @@ -352,13 +144,13 @@ public class DisguiseParser { * disguise has been feed a proper disguisetype. */ public static Disguise parseDisguise(CommandSender sender, String permNode, String[] args, - HashMap, Boolean>> permissionMap) throws DisguiseParseException, - IllegalAccessException, InvocationTargetException { + DisguisePermissions permissions) throws DisguiseParseException, IllegalAccessException, + InvocationTargetException { if (sender instanceof Player) { DisguiseUtilities.setCommandsUsed(); } - if (permissionMap.isEmpty()) { + if (!permissions.hasPermissions()) { throw new DisguiseParseException(LibsMsg.NO_PERM); } @@ -372,7 +164,7 @@ public class DisguiseParser { int toSkip = 1; ArrayList usedOptions = new ArrayList<>(); Disguise disguise = null; - HashMap, Boolean> optionPermissions; + DisguisePerm disguisePerm; if (args[0].startsWith("@")) { if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) { @@ -385,11 +177,21 @@ public class DisguiseParser { throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_REF); } - optionPermissions = (permissionMap.containsKey(new DisguisePerm(disguise.getType())) ? - permissionMap.get(new DisguisePerm(disguise.getType())) : - new HashMap, Boolean>()); + disguisePerm = new DisguisePerm(disguise.getType()); + + if (disguisePerm.isUnknown()) { + throw new DisguiseParseException(LibsMsg.PARSE_CANT_DISG_UNKNOWN); + } + + if (disguisePerm.getEntityType() == null) { + throw new DisguiseParseException(LibsMsg.PARSE_CANT_LOAD); + } + + if (!permissions.isAllowedDisguise(disguisePerm)) { + throw new DisguiseParseException(LibsMsg.NO_PERM_DISGUISE); + } } else { - DisguisePerm disguisePerm = getDisguisePerm(args[0]); + disguisePerm = getDisguisePerm(args[0]); Entry customDisguise = DisguiseConfig.getCustomDisguise(args[0]); if (customDisguise != null) { @@ -408,12 +210,10 @@ public class DisguiseParser { throw new DisguiseParseException(LibsMsg.PARSE_CANT_LOAD); } - if (!permissionMap.containsKey(disguisePerm)) { + if (!permissions.isAllowedDisguise(disguisePerm)) { throw new DisguiseParseException(LibsMsg.NO_PERM_DISGUISE); } - optionPermissions = permissionMap.get(disguisePerm); - HashMap disguiseOptions = getDisguiseOptions(sender, permNode, disguisePerm); if (disguise == null) { @@ -441,7 +241,7 @@ public class DisguiseParser { if (args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("baby")) || args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("adult"))) { usedOptions.add("setbaby"); - doCheck(sender, optionPermissions, usedOptions); + doCheck(sender, permissions, disguisePerm, usedOptions); adult = args[1].equalsIgnoreCase(TranslateType.DISGUISE_OPTIONS.get("adult")); toSkip++; @@ -539,15 +339,15 @@ public class DisguiseParser { if (disguisePerm.getType() == DisguiseType.FALLING_BLOCK) { usedOptions.add("setblock"); - doCheck(sender, optionPermissions, usedOptions); + doCheck(sender, permissions, disguisePerm, usedOptions); } else if (disguisePerm.getType() == DisguiseType.PAINTING) { usedOptions.add("setpainting"); - doCheck(sender, optionPermissions, usedOptions); + doCheck(sender, permissions, disguisePerm, usedOptions); } else if (disguisePerm.getType() == DisguiseType.SPLASH_POTION) { usedOptions.add("setpotionid"); - doCheck(sender, optionPermissions, usedOptions); + doCheck(sender, permissions, disguisePerm, usedOptions); } } @@ -566,14 +366,14 @@ public class DisguiseParser { String[] newArgs = new String[args.length - toSkip]; System.arraycopy(args, toSkip, newArgs, 0, args.length - toSkip); - callMethods(sender, disguise, optionPermissions, usedOptions, newArgs); + callMethods(sender, disguise, permissions, disguisePerm, usedOptions, newArgs); // Alright. We've constructed our disguise. return disguise; } - public static void callMethods(CommandSender sender, Disguise disguise, - HashMap, Boolean> optionPermissions, ArrayList usedOptions, + public static void callMethods(CommandSender sender, Disguise disguise, DisguisePermissions disguisePermission, + DisguisePerm disguisePerm, Collection usedOptions, String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, DisguiseParseException { Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass()); @@ -642,7 +442,7 @@ public class DisguiseParser { usedOptions.add(methodToUse.getName().toLowerCase()); } - doCheck(sender, optionPermissions, usedOptions); + doCheck(sender, disguisePermission, disguisePerm, usedOptions); if (FlagWatcher.class.isAssignableFrom(methodToUse.getDeclaringClass())) { methodToUse.invoke(disguise.getWatcher(), valueToSet); @@ -651,35 +451,4 @@ public class DisguiseParser { } } } - - 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/DisguisePerm.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePerm.java index fa5d7585..4d4bb560 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePerm.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePerm.java @@ -85,4 +85,9 @@ public class DisguisePerm { return Objects.equals(permName, other.permName); } + + @Override + public String toString() { + return "DisguisePerm{" + "disguiseType=" + disguiseType + ", permName='" + permName + '\'' + '}'; + } } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java new file mode 100644 index 00000000..16975778 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java @@ -0,0 +1,441 @@ +package me.libraryaddict.disguise.utilities.parser; + +import me.libraryaddict.disguise.DisguiseConfig; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Monster; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.PermissionAttachmentInfo; + +import java.util.*; + +/** + * Created by libraryaddict on 14/10/2018. + */ +public class DisguisePermissions { + private class PermissionStorage { + private DisguisePerm disguisePerm; + private List permittedOptions = new ArrayList<>(); + private List negatedOptions = new ArrayList<>(); + private boolean wildcardAllow = false; + + public PermissionStorage(DisguisePerm disguisePerm) { + this.disguisePerm = disguisePerm; + } + + public DisguisePerm getDisguise() { + return this.disguisePerm; + } + } + + private class ParsedPermission { + private Vector disguisePerm; + private HashMap options; + private boolean negated; + /** + * 0 = Names a specific disguise + * 1 = Animal + * 2 = Monster + * 3... = etc + * 4 = * = Disguise wildcard + */ + private byte inheritance; + private boolean wildcardCommand; + + public ParsedPermission(DisguisePerm[] disguisePerm, HashMap options, byte inheritance, + boolean wildcardCommand) { + this.disguisePerm = new Vector<>(Arrays.asList(disguisePerm)); + this.options = options; + this.inheritance = inheritance; + this.wildcardCommand = wildcardCommand; + } + + public boolean isWildcardCommand() { + return wildcardCommand; + } + + public boolean isDisguise(DisguisePerm perm) { + return disguisePerm.contains(perm); + } + + public boolean isNegated() { + return negated; + } + + public void setNegated(boolean negated) { + this.negated = negated; + } + + public byte getInheritance() { + return inheritance; + } + } + + class DisguisePermitted { + private boolean strictAllowed; + private List optionsAllowed; + private List optionsForbidden; + + public DisguisePermitted(List optionsAllowed, List optionsForbidden, boolean strict) { + this.strictAllowed = strict; + this.optionsAllowed = optionsAllowed; + this.optionsForbidden = optionsForbidden; + } + + public boolean isStrictAllowed() { + return strictAllowed; + } + + public List getOptionsAllowed() { + return optionsAllowed; + } + + public List getOptionsForbidden() { + return optionsForbidden; + } + } + + /** + * List of PermissionStorage that the permission holder is able to use + */ + private List disguises = new ArrayList<>(); + + /** + * @param permissionHolder The permissions to check + * @param commandName A lowercase string consisting of the name of one of Lib's Disguises commands + */ + public DisguisePermissions(Permissible permissionHolder, String commandName) { + loadPermissions(permissionHolder, commandName.toLowerCase()); + } + + /** + * @return If any of the disguises can be used + */ + public boolean hasPermissions() { + return !disguises.isEmpty(); + } + + public Collection getAllowed() { + ArrayList list = new ArrayList<>(); + + for (PermissionStorage allowed : disguises) { + if (list.contains(allowed.getDisguise())) { + continue; + } + + list.add(allowed.getDisguise()); + } + + list.sort((perm1, perm2) -> String.CASE_INSENSITIVE_ORDER.compare(perm1.toReadable(), perm2.toReadable())); + + return list; + } + + private ParsedPermission parsePermission(String permission) { + // libsdisguises.disguise.sheep + String[] split = permission.split("\\."); + + String disguiseName = split[2]; + + DisguisePerm dPerm = DisguiseParser.getDisguisePerm(disguiseName); + HashMap options = getOptions(permission); + + // If this refers to a specific disguise + if (dPerm != null) { + return new ParsedPermission(new DisguisePerm[]{dPerm}, options, (byte) 0, split[1].equals("*")); + } + + // If the disguise can't be found, it may be refering to a range + List disguisePerms = new ArrayList<>(); + int inheritance = 0; + + for (DisguisePerm disguisePerm : DisguiseParser.getDisguisePerms()) { + int inherit = getInheritance(disguisePerm, disguiseName); + + if (inherit < 0) { + continue; + } + + inheritance = inherit; + + disguisePerms.add(disguisePerm); + } + + // If there were no disguises that can be found by that name + if (disguisePerms.isEmpty()) { + return null; + } + + return new ParsedPermission(disguisePerms.toArray(new DisguisePerm[0]), options, (byte) inheritance, + split[1].equals("*")); + } + + /** + * Calculate permissions. + *

+ * A specified disguise (cow) and disguise range (animal) differs in that + * A disguise range cannot negate a specific disguise, players will be allowed to use cow if animal is negated + *

+ * Options on a permission limits the player, if the options start with a - then only those options can't be used + * on a disguise + * If they're using multiple permissions targetting the same disguise, it attempts to check for a permission that + * can be used with the provided requirements + * If a permission is negated, then unless specifically permitted, those permissions can't be used. It obeys the + * laws of ranges and specific disguises + */ + private void loadPermissions(Permissible sender, String commandName) { + String permissionNode = "libsdisguises." + commandName + "."; + Map permissions = new HashMap<>(); + + // If the command sender is OP, then this will work even as the below code doesn't + for (String perm : new String[]{permissionNode + "*", "libsdisguises.*.*"}) { + if (!sender.hasPermission(perm)) { + continue; + } + + permissions.put(perm, true); + } + + for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) { + String perm = permission.getPermission().toLowerCase(); + + String[] split = perm.split("\\."); + + // If there are not enough arguments + if (split.length < 3) { + continue; + } + + // If this is not a lib's disguises permission + if (!split[0].equals("libsdisguises")) { + continue; + } + + // If the command name does not match + if (!split[1].equals("*") && !split[1].equals(commandName)) { + continue; + } + + // If it's already contained in the map, and is true. Allow negating permissions to continue + if (permissions.containsKey(perm) && permission.getValue()) { + continue; + } + + permissions.put(perm, permission.getValue()); + } + + // First get all the disguises that can be affected + // Then load all the permissions we can + // Each time there's a parent permission set, the child inherits unless specified in a child of that parent + + // DisguisePerm[] + // Option[] + // Negated + + List list = new ArrayList<>(); + + for (Map.Entry entry : permissions.entrySet()) { + ParsedPermission temp = parsePermission(entry.getKey()); + + if (temp == null) { + continue; + } + + temp.setNegated(!entry.getValue()); + + list.add(temp); + } + + // Sorted from 5 to 0 where "*" is first and "Cow" is last + // Negated permissions are last in each inheritance, so false, false, true, true + + list.sort((t1, t2) -> { + // Wilcard commands have little say, so they go first so they can be negated by following permissions + if (t1.isWildcardCommand() != t2.isWildcardCommand()) { + return Boolean.compare(t2.isWildcardCommand(), t1.isWildcardCommand()); + } + + if (t1.getInheritance() == t2.getInheritance()) { + return Boolean.compare(t1.isNegated(), t2.isNegated()); + } + + return t2.getInheritance() - t1.getInheritance(); + }); + + for (DisguisePerm disguisePerm : DisguiseParser.getDisguisePerms()) { + // Use boolean instead of setting to null, to inherit + boolean disabled = true; + PermissionStorage storage = new PermissionStorage(disguisePerm); + + for (ParsedPermission parsedPermission : list) { + // If this parsed permission doesn't handle this disguise type + if (!parsedPermission.isDisguise(disguisePerm)) { + continue; + } + + // A negated permission with no options, disables the disguise + if (parsedPermission.isNegated() && parsedPermission.options.isEmpty()) { + // Remove disguise + disabled = true; + continue; + } + + // The permission is negated, and only has negated options. Should mean something, but to most people + // it's nonsense and should be ignored. + if (parsedPermission.isNegated() && !parsedPermission.options.values().contains(true)) { + continue; + } + + if (!parsedPermission.isNegated()) { + // Enable the disguise if permission isn't negated + // A negated permission cannot enable access + if (disabled) { + disabled = false; + } + + // If the child disguise does not have any options defined, give them wildcard by default + if (parsedPermission.options.isEmpty()) { + storage.wildcardAllow = true; + // If this disguise has options defined, unless wildcard was explictly given then remove it + } else if (!storage.permittedOptions.contains("*")) { + storage.wildcardAllow = false; + } + } + + for (Map.Entry entry : parsedPermission.options.entrySet()) { + // If permission is negated, reverse the option from 'allowed' to 'denied' or vice versa + boolean allowUse = parsedPermission.isNegated() ? !entry.getValue() : entry.getValue(); + + storage.permittedOptions.remove(entry.getKey()); + storage.negatedOptions.remove(entry.getKey()); + + // Handle wildcard options + if (entry.getKey().equals("*")) { + // If it's a negated wildcard, then they don't want the user to use anything + // If it's a permitted wildcard, then they want the user to use everything + + // Both want to clear the existing restrictions + storage.permittedOptions.clear(); + storage.negatedOptions.clear(); + + // Add wildcard allow so if the user later defines "setBaby" just to be sure, it doesn't + // limit them to setbaby + storage.wildcardAllow = allowUse; + + // Negated wants to prevent the use of all options + if (!allowUse) { + storage.permittedOptions.add("nooptions"); + } + } + + if (allowUse) { + storage.permittedOptions.add(entry.getKey()); + } else { + storage.negatedOptions.add(entry.getKey()); + } + } + } + + // Disguise is not allowed, continue + if (disabled) { + continue; + } + + // If invisibility was disabled in the config, ignore permissions and make sure it's disabled + if (DisguiseConfig.isDisabledInvisibility()) { + storage.permittedOptions.remove("setinvisible"); + storage.negatedOptions.add("setinvisible"); + } + + disguises.add(storage); + } + } + + private int getInheritance(DisguisePerm disguisePerm, String permissionName) { + DisguiseType disguiseType = disguisePerm.getType(); + + if (permissionName.equals("ageable")) { + if (Ageable.class.isAssignableFrom(disguiseType.getEntityClass())) { + return 1; + } + } else if (permissionName.equals("monster") || permissionName.equals("monsters")) { + if (Monster.class.isAssignableFrom(disguiseType.getEntityClass())) { + return 2; + } + } else if (permissionName.equals("animal") || permissionName.equals("animals")) { + if (Animals.class.isAssignableFrom(disguiseType.getEntityClass())) { + return 2; + } + } else if (permissionName.equals("mob")) { + if (disguiseType.isMob()) { + return 3; + } + } else if (permissionName.equals("misc")) { + if (disguiseType.isMisc()) { + return 3; + } + } else if (permissionName.equals("*")) { + return 4; + } + + return -1; + } + + private HashMap getOptions(String perm) { + HashMap options = new HashMap<>(); + String[] split = perm.split("\\."); + + for (int i = 3; i < split.length; i++) { + String option = split[i]; + boolean negated = option.startsWith("-"); + + if (negated) { + option = option.substring(1); + } + + if (option.equals("baby")) { + option = "setbaby"; + } + + options.put(option, !negated); + } + + return options; + } + + /** + * If this DisguisePermission can use the provided disguise and options + * + * @param disguisePerm + * @param disguiseOptions + * @return true if permitted + */ + public boolean isAllowedDisguise(DisguisePerm disguisePerm, Collection disguiseOptions) { + PermissionStorage storage = getStorage(disguisePerm); + + if (storage == null) { + return false; + } + + // If the disguise doesn't have a wildcard allow on it + // If the user is limited to a select range of options, and not all the options were found in the allowed + // options + if (!storage.wildcardAllow && !storage.permittedOptions.isEmpty() && + !disguiseOptions.stream().allMatch(option -> storage.permittedOptions.contains(option.toLowerCase()))) { + return false; + } + + // If the user is using a forbidden option, return false. Otherwise true + return disguiseOptions.stream().noneMatch(option -> storage.negatedOptions.contains(option.toLowerCase())); + } + + public boolean isAllowedDisguise(DisguisePerm disguisePerm) { + return getStorage(disguisePerm) != null; + } + + private PermissionStorage getStorage(DisguisePerm disguisePerm) { + return disguises.stream().filter(disguise -> disguise.getDisguise().equals(disguisePerm)).findAny() + .orElse(null); + } +} diff --git a/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java b/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java new file mode 100644 index 00000000..427b4419 --- /dev/null +++ b/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java @@ -0,0 +1,303 @@ +package me.libraryaddict.disguise.utilities.parser; + +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; +import org.junit.Assert; +import org.junit.Test; + +import java.util.*; + +/** + * Created by libraryaddict on 21/10/2018. + */ +public class DisguisePermissionsTest { + @Test + public void testDisguisesExist() { + Assert.assertNull("There should not be a reindeer disguise", DisguiseParser.getDisguisePerm("Reindeer")); + + Assert.assertNotNull("There should be a cow disguise", DisguiseParser.getDisguisePerm("Cow")); + + Assert.assertNotNull("There should be a firework disguise", DisguiseParser.getDisguisePerm("Firework")); + } + + @Test + public void testPermissionNames() { + Assert.assertFalse("There should not be permissions", createPermissions("Disguise", false).hasPermissions()); + + Assert.assertFalse("The commands should not match", + createPermissions("Disguise", false, "libsdisguises.disguiseentity.cow").hasPermissions()); + + Assert.assertFalse("The commands should not match", + createPermissions("Disguised", false, "libsdisguises.disguise.cow").hasPermissions()); + + Assert.assertTrue("There should be permissions", + createPermissions("Disguise", false, "libsdisguises.*.animal").hasPermissions()); + } + + @Test + public void testOperatorPermissions() { + DisguisePermissions permissions = createPermissions("Disguise", true, "-libsdisguises.disguise.sheep", + "-libsdisguises.disguise.horse.setBaby"); + + Assert.assertTrue("There should be permissions", permissions.hasPermissions()); + + Assert.assertTrue("The disguise cow should be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"))); + + Assert.assertFalse("The disguise sheep should not be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Sheep"))); + + Assert.assertTrue("The disguise horse should be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Horse"))); + + Assert.assertFalse("The disguise horse should not be allowed with setBaby", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Horse"), Collections.singletonList("setBaby"))); + } + + @Test + public void testWildcardsPermissions() { + Assert.assertTrue("The cow disguise should be allowed", + createPermissions("Disguise", false, "libsdisguises.*.animal") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"))); + + Assert.assertFalse("The firework disguise should not be allowed", + createPermissions("Disguise", false, "libsdisguises.*.animal") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + + Assert.assertTrue("The firework disguise should be allowed", + createPermissions("Disguise", false, "libsdisguises.*.*") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + + Assert.assertTrue("The firework disguise should be allowed", + createPermissions("Disguise", false, "libsdisguises.disguise.*") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + + Assert.assertTrue("The firework disguise should be allowed", + createPermissions("Disguise", false, "libsdisguises.*.Firework") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + + Assert.assertFalse("The firework disguise should not be allowed", + createPermissions("Disguise", false, "libsdisguises.*.*", "-libsdisguises.*.misc") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + + Assert.assertTrue("The firework disguise should be allowed", + createPermissions("Disguise", false, "libsdisguises.disguise.*", "-libsdisguises.*.*") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + + Assert.assertTrue("The firework disguise should be allowed", + createPermissions("Disguise", false, "libsdisguises.disguise.firework", "-libsdisguises.disguise.misc") + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + } + + @Test + public void testInheritedPermissions() { + testInheritedPermissions(createPermissions("Disguise", false, "libsdisguises.disguise.animal.setBaby", + "-libsdisguises.disguise.sheep.setBaby")); + + testInheritedPermissions(createPermissions("Disguise", false, "libsdisguises.disguise.animal.setBaby", + "libsdisguises.disguise.sheep.-setBaby")); + } + + private void testInheritedPermissions(DisguisePermissions permissions) { + Assert.assertTrue("The sheep disguise should be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Sheep"))); + + Assert.assertTrue("The cow disguise should be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"))); + + Assert.assertTrue("The cow disguise should be allowed with setBaby", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Collections.singletonList("setBaby"))); + + Assert.assertFalse("The sheep disguise should not be allowed with setBaby", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Sheep"), Collections.singletonList("setBaby"))); + + Assert.assertFalse("The firework disguise should not be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Firework"))); + } + + @Test + public void testNegatedPermissions() { + DisguisePermissions permissions = createPermissions("Disguise", false, "libsdisguises.disguise.sheep", + "-libsdisguises.disguise.cow.setSprinting", "-libsdisguises.disguise.donkey", + "-libsdisguises.disguise.horse.setRearing", "libsdisguises.disguise.horse"); + + Assert.assertFalse("The cow disguise should not be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"))); + + Assert.assertTrue("The sheep disguise should be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Sheep"))); + + Assert.assertFalse("The donkey disguise should not be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Donkey"))); + + Assert.assertTrue("The horse disguise should be allowed", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Horse"))); + + Assert.assertTrue("The horse disguise should be allowed with options", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Horse"), Collections.singletonList("setBaby"))); + + Assert.assertFalse("The horse disguise should not be allowed setRearing", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Horse"), Collections.singletonList("setRearing"))); + } + + @Test + public void testMultiDisguises() { + DisguisePermissions permissions = createPermissions("Disguise", false, "libsdisguises.disguise.cow.setBaby", + "libsdisguises.disguise.cow.setHealth", "libsdisguises.disguise.cow.-setBurning"); + + Assert.assertTrue("The cow disguise should be able to use setBaby", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Collections.singletonList("setBaby"))); + + Assert.assertTrue("The cow disguise should be able to use setHealth", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Collections.singletonList("setHealth"))); + + Assert.assertTrue("The cow disguise should be able to use setBaby and setHealth", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Arrays.asList("setBaby", "setHealth"))); + + Assert.assertFalse("The cow disguise should not be able to use setBurning", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Collections.singletonList("setBurning"))); + + Assert.assertFalse("The cow disguise should not be able to use setSprinting", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Collections.singletonList("setSprinting"))); + + Assert.assertFalse("The cow disguise should not be able to use setSprinting with setBaby", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Arrays.asList("setSprinting", "setBaby"))); + } + + @Test + public void testOptions() { + Assert.assertFalse("The disguise should not be valid", + createPermissions("Disguise", false, "libsdisguises.disguise.cow", "-libsdisguises.disguise.cow") + .hasPermissions()); + + DisguisePermissions permissions = createPermissions("Disguise", false, "libsdisguises.disguise.cow", + "libsdisguises.disguise.sheep.setColor.setSprinting", "libsdisguises.disguise.animal.-setSprinting"); + + Assert.assertTrue("There should be a valid disguise", permissions.hasPermissions()); + + DisguisePerm cow = DisguiseParser.getDisguisePerm("Cow"); + + Assert.assertTrue("The cow disguise should be allowed", permissions.isAllowedDisguise(cow)); + + Assert.assertTrue("The cow disguise should be allowed with options", + permissions.isAllowedDisguise(cow, Arrays.asList("setBaby", "setBurning"))); + + Assert.assertFalse("The cow disguise should not be allowed with options setSprinting", + permissions.isAllowedDisguise(cow, Arrays.asList("setBaby", "setSprinting"))); + + Assert.assertFalse("The cow disguise should not be allowed with options", + permissions.isAllowedDisguise(cow, Collections.singletonList("setSprinting"))); + + DisguisePerm sheep = DisguiseParser.getDisguisePerm("Sheep"); + + Assert.assertFalse("The sheep disguise should not be allowed with options", + permissions.isAllowedDisguise(sheep, Arrays.asList("setBaby", "setBurning"))); + + Assert.assertTrue("The sheep disguise should be allowed setColor", + permissions.isAllowedDisguise(sheep, Collections.singletonList("setColor"))); + + Assert.assertTrue("The sheep disguise should be allowed setSprinting", + permissions.isAllowedDisguise(sheep, Collections.singletonList("setSprinting"))); + + Assert.assertFalse("The sheep disguise should not be allowed setColor and setBaby", + permissions.isAllowedDisguise(sheep, Arrays.asList("setColor", "setBaby"))); + + DisguisePerm firework = DisguiseParser.getDisguisePerm("Firework"); + + Assert.assertFalse("The firework disguise should not be allowed", permissions.isAllowedDisguise(firework)); + + Assert.assertFalse("The disguise should not be allowed even with options", + permissions.isAllowedDisguise(firework, Arrays.asList("setBaby", "setBurning"))); + } + + private DisguisePermissions createPermissions(String commandName, boolean isOp, String... perms) { + List permitted = new ArrayList<>(); + List negated = new ArrayList<>(); + Set attachments = new HashSet<>(); + + Permissible permissible = new Permissible() { + @Override + public boolean isPermissionSet(String s) { + return permitted.contains(s) || negated.contains(s); + } + + @Override + public boolean isPermissionSet(Permission permission) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public boolean hasPermission(String s) { + return permitted.contains(s) || (isOp() && !negated.contains(s)); + } + + @Override + public boolean hasPermission(Permission permission) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b, int i) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int i) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public void removeAttachment(PermissionAttachment permissionAttachment) { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public void recalculatePermissions() { + throw new UnsupportedOperationException("Not Supported"); + } + + @Override + public Set getEffectivePermissions() { + return attachments; + } + + @Override + public boolean isOp() { + return isOp; + } + + @Override + public void setOp(boolean b) { + throw new UnsupportedOperationException("Not Supported"); + } + }; + + // If permission starts with a - then it was negated + Arrays.stream(perms).forEach(perm -> { + boolean setTrue = !perm.startsWith("-"); + + if (setTrue) { + permitted.add(perm); + } else { + negated.add(perm = perm.substring(1)); + } + + attachments.add(new PermissionAttachmentInfo(permissible, perm, null, setTrue)); + }); + + return new DisguisePermissions(permissible, commandName); + } +}