diff --git a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java index 4ac36795..a4bfac3d 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissions.java @@ -265,6 +265,7 @@ public class DisguisePermissions { // Use boolean instead of setting to null, to inherit boolean disabled = true; PermissionStorage storage = new PermissionStorage(disguisePerm); + byte lastOptionInheritance = -1; for (ParsedPermission parsedPermission : list) { // If this parsed permission doesn't handle this disguise type @@ -292,10 +293,15 @@ public class DisguisePermissions { disabled = false; } - // If the child disguise does not have any options defined, give them wildcard by default if - // config allows - if (parsedPermission.options.isEmpty() && !DisguiseConfig.isExplictDisguisePermissions()) { + // If the child disguise does not have any options defined + // If the config doesn't require them to be given the permissions explictly + // If they already have wildcard (Prevent next if) + // Or this parsed permission is at a higher level than the last + // That prevents 'cow' overriding 'cow.setBurning' + if (parsedPermission.options.isEmpty() && !DisguiseConfig.isExplicitDisguisePermissions() && + (storage.wildcardAllow || lastOptionInheritance != parsedPermission.inheritance)) { 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; @@ -334,6 +340,10 @@ public class DisguisePermissions { storage.negatedOptions.add(entry.getKey()); } } + + if (!parsedPermission.options.isEmpty()) { + lastOptionInheritance = parsedPermission.inheritance; + } } // Disguise is not allowed, continue @@ -417,12 +427,18 @@ public class DisguisePermissions { 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 they are able to use all permitted options by default, why bother checking what they can use + if (!storage.wildcardAllow) { + // If their permitted options are defined, or the denied options are not defined + // If they don't have permitted options defined, but they have denied options defined then they probably + // have an invisible wildcard allow + if (!storage.permittedOptions.isEmpty() || storage.negatedOptions.isEmpty()) { + // Check if they're trying to use anything they shouldn't + if (!disguiseOptions.stream() + .allMatch(option -> storage.permittedOptions.contains(option.toLowerCase()))) { + return false; + } + } } // If the user is using a forbidden option, return false. Otherwise true diff --git a/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java b/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java index 427b4419..1b72c190 100644 --- a/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java +++ b/src/test/java/me/libraryaddict/disguise/utilities/parser/DisguisePermissionsTest.java @@ -1,5 +1,6 @@ package me.libraryaddict.disguise.utilities.parser; +import me.libraryaddict.disguise.DisguiseConfig; import org.bukkit.permissions.Permissible; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionAttachment; @@ -213,6 +214,57 @@ public class DisguisePermissionsTest { permissions.isAllowedDisguise(firework, Arrays.asList("setBaby", "setBurning"))); } + @Test + public void testExplictPermissions() { + DisguiseConfig.setExplicitDisguisePermissions(true); + + DisguisePermissions permissions = createPermissions("Disguise", false, "libsdisguises.disguise.animal", + "libsdisguises.disguise.zombie", "libsdisguises.disguise.skeleton.*", + "libsdisguises.disguise.wither.setburning", "libsdisguises.disguise.silverfish.-setburning"); + + Assert.assertTrue("The cow disguise should be usable", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"))); + + Assert.assertFalse("The cow disguise should not be able to use setBurning", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Cow"), Collections.singletonList("setBurning"))); + + Assert.assertTrue("The zombie disguise should be usable", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Zombie"))); + + Assert.assertFalse("The zombie disguise should not be able to use setBurning", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Zombie"), Collections.singletonList("setBurning"))); + + Assert.assertTrue("The skeleton disguise should be usable", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Skeleton"))); + + Assert.assertTrue("The skeleton disguise should be able to use setBurning", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Skeleton"), + Collections.singletonList("setBurning"))); + + Assert.assertTrue("The wither disguise should be usable", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Wither"))); + + Assert.assertTrue("The wither disguise should be able to use setBurning", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Wither"), Collections.singletonList("setBurning"))); + + Assert.assertFalse("The wither disguise should not be able to use setSprinting", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Wither"), + Collections.singletonList("setSprinting"))); + + Assert.assertTrue("The silverfish disguise should be usable", + permissions.isAllowedDisguise(DisguiseParser.getDisguisePerm("Silverfish"))); + + Assert.assertFalse("The silverfish disguise should not be able to use setBurning", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Silverfish"), + Collections.singletonList("setBurning"))); + + Assert.assertTrue("The silverfish disguise should be able to use setSprinting", permissions + .isAllowedDisguise(DisguiseParser.getDisguisePerm("Silverfish"), + Collections.singletonList("setSprinting"))); + + DisguiseConfig.setExplicitDisguisePermissions(false); + } + private DisguisePermissions createPermissions(String commandName, boolean isOp, String... perms) { List permitted = new ArrayList<>(); List negated = new ArrayList<>();