diff --git a/README.md b/README.md index ba4a47433..7d0dc3ee2 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge. * **Developer API** - easily integrate LuckPerms into your own projects * **Easy and simple setup and configuration using commands** - no editing yml files, yuck * **Negated permissions and groups** - define special rules for certain users/groups +* **Regex permissions** - define special permissions using regex +* **Shorthand nodes** - add nodes using the LuckPerms shorthand system * **Full support for UUIDs, even in Offline Mode** - users can change their usernames without losing permissions. In offline mode, a single user has the same internal UUID across a network. * **Permission data stored within MySQL in a json format** - easily integrate the LuckPerms backend into your other projects * **Well documented** - API methods have comprehensive Java docs, it's clear what each method does. @@ -37,7 +39,7 @@ You can define the settings for per-server permissions, the storage method and c ### Permission Calculation #### Permissions are calculated based on a priority system as follows. -* **Non wildcard permissions will override wildcard permissions** +* **Non wildcard/regex permissions will be overridden by normal permissions** Example: if a user has a true permission set for "luckperms.\*", and a false permission set for "luckperms.something", the non-wildcard permission will override the wildcard, and "luckperms.something" will be set to false, despite the wildcard. @@ -66,6 +68,40 @@ Temporary permissions are checked each time a user/group is loaded, and when the The only way around this is to decrease the sync interval. +### Shorthand Permissions +LuckPerms has it's own system (although it's quite similar to PermissionsEx :P) that allows you to set permissions in a shorthand format. + +Using the LuckPerms permission nodes as an example, say for instance, you wanted to let a user set and unset permissions for both groups and users. + +Without shorthand, you would have to apply 4 nodes. +``` +luckperms.user.setpermission +luckperms.user.unsetpermission +luckperms.group.setpermission +luckperms.group.unsetpermission +``` +However, with shorthand, you can just apply the following node: + +`luckperms.(user|group).(setpermission|unsetpermission)` + +You use brackets to define part of a node as a shorthand group, and then use the vertical bar `|` to separate entries. + +There are some limitations, firstly, you cannot use shorthand in the first part of the node. (The "luckperms" part in the example above) + +Additionally, you cannot combine shorthand and normal text in the same part of the node. +For example, `luckperms.(user|group).(set|unset)permission` would not work. + +### Regex +LuckPerms has support for regex when defining permission nodes and server/world names. + +Whenever regex is used, it MUST be prefixed with "R=", so LuckPerms knows to treat it as regex, and not as a normal string. + +For example, if you wanted to give all members of the default group, the `essentials.fly` permission on all of your hub servers, where the hub server names are hub1, hub2, hub3, etc. +You would use the command `/perms group default set essentials.fly true R=hub\d+`. + +You can also use regex in permission nodes. +Once again using LuckPerms permissions as an example, if you wanted a user to be able to create both groups and tracks, you would normally just add the two permission nodes. However with regex, you can just add one. `luckperms\.create.*` Remember to escape any characters, specifically dots, as the entire node will be parsed. + ## API LuckPerms has an extensive API, allowing for easy integration with other projects. To use the Api, you need to obtain an instance of the `LuckPermsApi` interface. This can be done in a number of ways. diff --git a/api/src/main/java/me/lucko/luckperms/api/LPConfiguration.java b/api/src/main/java/me/lucko/luckperms/api/LPConfiguration.java index 05b9ae1d4..6de25caab 100644 --- a/api/src/main/java/me/lucko/luckperms/api/LPConfiguration.java +++ b/api/src/main/java/me/lucko/luckperms/api/LPConfiguration.java @@ -64,6 +64,16 @@ public interface LPConfiguration { */ boolean getApplyWildcards(); + /** + * @return if LuckPerms is resolving and applying regex permissions + */ + boolean getApplyRegex(); + + /** + * @return if LuckPerms is expanding shorthand permissions + */ + boolean getApplyShorthand(); + /** * @return the database values set in the configuration */ diff --git a/bukkit/src/main/resources/config.yml b/bukkit/src/main/resources/config.yml index 3da9ad1b8..5a134e9d7 100644 --- a/bukkit/src/main/resources/config.yml +++ b/bukkit/src/main/resources/config.yml @@ -27,6 +27,16 @@ online-mode: true # the wildcard. This will only work for plugins that define all of their permissions to the server. apply-wildcards: true +# If the plugin should parse regex permissions. +# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve & +# apply all registered permissions matching the regex. This will only work for plugins that define all of their +# permissions to the server. +apply-regex: true + +# If the plugin should complete and apply shorthand permissions. +# If set to true, LuckPerms will detect and expand shorthand node patterns. +apply-shorthand: true + # Which storage method the plugin should use. # Currently supported: mysql, sqlite, flatfile # Fill out connection info below if you're using MySQL diff --git a/bungee/src/main/resources/config.yml b/bungee/src/main/resources/config.yml index 97cf85b09..558fdd023 100644 --- a/bungee/src/main/resources/config.yml +++ b/bungee/src/main/resources/config.yml @@ -27,6 +27,16 @@ online-mode: true # the wildcard. This will only work for plugins that define all of their permissions to the server. apply-wildcards: true +# If the plugin should parse regex permissions. +# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve & +# apply all registered permissions matching the regex. This will only work for plugins that define all of their +# permissions to the server. +apply-regex: true + +# If the plugin should complete and apply shorthand permissions. +# If set to true, LuckPerms will detect and expand shorthand node patterns. +apply-shorthand: true + # Which storage method the plugin should use. # Currently supported: mysql & flatfile # Fill out connection info below if you're using MySQL diff --git a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/DatastoreLink.java b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/DatastoreLink.java index 255cb1ea2..9d0bd99d6 100644 --- a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/DatastoreLink.java +++ b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/DatastoreLink.java @@ -24,6 +24,7 @@ package me.lucko.luckperms.api.implementation.internal; import lombok.AllArgsConstructor; import lombok.NonNull; +import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.api.Datastore; import me.lucko.luckperms.api.Group; import me.lucko.luckperms.api.Track; @@ -40,11 +41,13 @@ import static me.lucko.luckperms.api.implementation.internal.Utils.*; @SuppressWarnings({"unused", "WeakerAccess"}) public class DatastoreLink implements Datastore { + private final LuckPermsPlugin plugin; private final me.lucko.luckperms.data.Datastore master; private final Async async; private final Sync sync; - public DatastoreLink(@NonNull me.lucko.luckperms.data.Datastore master) { + public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull me.lucko.luckperms.data.Datastore master) { + this.plugin = plugin; this.master = master; this.async = new Async(master); this.sync = new Sync(master); @@ -122,6 +125,9 @@ public class DatastoreLink implements Datastore { @Override public void deleteGroup(@NonNull Group group, Callback callback) { checkGroup(group); + if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) { + throw new IllegalArgumentException("Cannot delete the default group."); + } master.deleteGroup(((GroupLink) group).getMaster(), checkCallback(callback)); } @@ -207,6 +213,9 @@ public class DatastoreLink implements Datastore { @Override public boolean deleteGroup(@NonNull Group group) { checkGroup(group); + if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) { + throw new IllegalArgumentException("Cannot delete the default group."); + } return master.deleteGroup(((GroupLink) group).getMaster()); } diff --git a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/LPConfigurationLink.java b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/LPConfigurationLink.java index a8d028e78..c5ab7edc6 100644 --- a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/LPConfigurationLink.java +++ b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/LPConfigurationLink.java @@ -27,7 +27,7 @@ import me.lucko.luckperms.api.LPConfiguration; import me.lucko.luckperms.api.data.MySQLConfiguration; /** - * Provides a link between {@link me.lucko.luckperms.api.LPConfiguration} and {@link me.lucko.luckperms.utils.LPConfiguration} + * Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.utils.LPConfiguration} */ @AllArgsConstructor public class LPConfigurationLink implements LPConfiguration { @@ -68,6 +68,16 @@ public class LPConfigurationLink implements LPConfiguration { return master.getApplyWildcards(); } + @Override + public boolean getApplyRegex() { + return master.getApplyRegex(); + } + + @Override + public boolean getApplyShorthand() { + return master.getApplyShorthand(); + } + @Override public MySQLConfiguration getDatabaseValues() { return master.getDatabaseValues(); diff --git a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/Utils.java b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/Utils.java index fb048b389..53a528a1c 100644 --- a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/Utils.java +++ b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/Utils.java @@ -26,8 +26,7 @@ import lombok.experimental.UtilityClass; import me.lucko.luckperms.api.Group; import me.lucko.luckperms.api.Track; import me.lucko.luckperms.api.User; -import me.lucko.luckperms.utils.DateUtil; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; @UtilityClass class Utils { @@ -51,7 +50,7 @@ class Utils { } static String checkUsername(String s) { - if (s.length() > 16 || Patterns.NON_USERNAME.matcher(s).find()) { + if (!ArgumentChecker.checkUsername(s)) { throw new IllegalArgumentException("Invalid username entry '" + s + "'. Usernames must be less than 16 chars" + " and only contain 'a-z A-Z 1-9 _'."); } @@ -59,7 +58,7 @@ class Utils { } static String checkName(String s) { - if (s.length() > 36 || Patterns.NON_ALPHA_NUMERIC.matcher(s).find()) { + if (!ArgumentChecker.checkName(s)) { throw new IllegalArgumentException("Invalid name entry '" + s + "'. Names must be less than 37 chars" + " and only contain 'a-z A-Z 1-9'."); } @@ -67,21 +66,21 @@ class Utils { } static String checkServer(String s) { - if (Patterns.NON_ALPHA_NUMERIC.matcher(s).find()) { + if (!ArgumentChecker.checkServer(s)) { throw new IllegalArgumentException("Invalid server entry '" + s + "'. Server names can only contain alphanumeric characters."); } return s; } static String checkNode(String s) { - if (s.contains("/") || s.contains("$")) { + if (!ArgumentChecker.checkNode(s)) { throw new IllegalArgumentException("Invalid node entry '" + s + "'. Nodes cannot contain '/' or '$' characters."); } return s; } static long checkTime(long l) { - if (DateUtil.shouldExpire(l)) { + if (!ArgumentChecker.checkTime(l)) { throw new IllegalArgumentException("Unix time '" + l + "' is invalid, as it has already passed."); } return l; diff --git a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/UuidCacheLink.java b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/UuidCacheLink.java index cec4f1179..c61eeb8ab 100644 --- a/common/src/main/java/me/lucko/luckperms/api/implementation/internal/UuidCacheLink.java +++ b/common/src/main/java/me/lucko/luckperms/api/implementation/internal/UuidCacheLink.java @@ -28,7 +28,7 @@ import me.lucko.luckperms.api.UuidCache; import java.util.UUID; /** - * Provides a link between {@link me.lucko.luckperms.api.UuidCache} and {@link me.lucko.luckperms.utils.UuidCache} + * Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.utils.UuidCache} */ @AllArgsConstructor public class UuidCacheLink implements UuidCache { diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java b/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java index b7a1395f5..bf540e7f6 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java @@ -27,7 +27,7 @@ import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.commands.SingleMainCommand; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,13 +44,7 @@ public class CreateGroup extends SingleMainCommand { } String groupName = args.get(0).toLowerCase(); - - if (groupName.length() > 36) { - Message.GROUP_NAME_TOO_LONG.send(sender, groupName); - return; - } - - if (Patterns.NON_ALPHA_NUMERIC.matcher(groupName).find()) { + if (!ArgumentChecker.checkName(groupName)) { Message.GROUP_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java b/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java index c6bbaa3e4..7b8b64092 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java @@ -28,7 +28,7 @@ import me.lucko.luckperms.commands.SingleMainCommand; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.ArrayList; import java.util.Collections; @@ -54,7 +54,7 @@ public class DeleteGroup extends SingleMainCommand { return; } - if (Patterns.NON_ALPHA_NUMERIC.matcher(groupName).find()) { + if (!ArgumentChecker.checkName(groupName)) { Message.GROUP_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/GroupMainCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/GroupMainCommand.java index 64b3ddbfe..c7198723b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/GroupMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/GroupMainCommand.java @@ -28,7 +28,7 @@ import me.lucko.luckperms.commands.MainCommand; import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.ArrayList; import java.util.List; @@ -40,7 +40,7 @@ public class GroupMainCommand extends MainCommand { @Override protected void getTarget(String target, LuckPermsPlugin plugin, Sender sender, Callback onSuccess) { - if (Patterns.NON_ALPHA_NUMERIC.matcher(target).find()) { + if (!ArgumentChecker.checkName(target)) { Message.GROUP_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java index 921232325..0dc91a8f1 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.commands.Util; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,7 +44,7 @@ public class GroupHasPerm extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { if (args.size() >= 2) { - if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) { + if (!ArgumentChecker.checkServer(args.get(1))) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java index 5726f0064..b872d6438 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.commands.Util; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,7 +44,7 @@ public class GroupInheritsPerm extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { if (args.size() >= 2) { - if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) { + if (!ArgumentChecker.checkServer(args.get(1))) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java index 015598e82..00bf7c320 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -45,7 +45,7 @@ public class GroupSetInherit extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -57,7 +57,7 @@ public class GroupSetInherit extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java index a38373245..537b52e84 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.groups.Group; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -45,7 +46,7 @@ public class GroupSetPermission extends SubCommand { String node = args.get(0); String bool = args.get(1).toLowerCase(); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -65,7 +66,7 @@ public class GroupSetPermission extends SubCommand { try { if (args.size() >= 3) { final String server = args.get(2).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempInherit.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempInherit.java index 216285eb0..c62a5620b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempInherit.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempInherit.java @@ -30,8 +30,8 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.groups.Group; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.DateUtil; -import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -46,7 +46,7 @@ public class GroupSetTempInherit extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -71,7 +71,7 @@ public class GroupSetTempInherit extends SubCommand { try { if (args.size() >= 3) { final String server = args.get(2).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempPermission.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempPermission.java index f485dccdd..750ef4017 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.groups.Group; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.DateUtil; import me.lucko.luckperms.utils.Patterns; @@ -47,7 +48,7 @@ public class GroupSetTempPermission extends SubCommand { String node = args.get(0); String bool = args.get(1).toLowerCase(); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -80,7 +81,7 @@ public class GroupSetTempPermission extends SubCommand { try { if (args.size() >= 4) { final String server = args.get(3).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java index e1205dd05..8b04a2969 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -44,7 +45,7 @@ public class GroupUnSetPermission extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String node = args.get(0); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -57,7 +58,7 @@ public class GroupUnSetPermission extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java index 2b9c2cd25..724c2ed76 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -45,7 +45,7 @@ public class GroupUnsetInherit extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -53,7 +53,7 @@ public class GroupUnsetInherit extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempInherit.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempInherit.java index 7a2595917..9dd33b29f 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempInherit.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempInherit.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -45,7 +45,7 @@ public class GroupUnsetTempInherit extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -53,7 +53,7 @@ public class GroupUnsetTempInherit extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempPermission.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempPermission.java index a39e6ccb9..fbc375f30 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -45,7 +46,7 @@ public class GroupUnsetTempPermission extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String node = args.get(0); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -58,7 +59,7 @@ public class GroupUnsetTempPermission extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java b/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java index 0a4dc7f46..3a2b884c9 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java @@ -27,7 +27,7 @@ import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.commands.SingleMainCommand; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,13 +44,7 @@ public class CreateTrack extends SingleMainCommand { } String trackName = args.get(0).toLowerCase(); - - if (trackName.length() > 36) { - Message.TRACK_NAME_TOO_LONG.send(sender, trackName); - return; - } - - if (Patterns.NON_ALPHA_NUMERIC.matcher(trackName).find()) { + if (!ArgumentChecker.checkName(trackName)) { Message.TRACK_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java b/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java index ef04e70c2..439143179 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java @@ -28,7 +28,7 @@ import me.lucko.luckperms.commands.SingleMainCommand; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.tracks.Track; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.ArrayList; import java.util.Collections; @@ -48,8 +48,7 @@ public class DeleteTrack extends SingleMainCommand { } String trackName = args.get(0).toLowerCase(); - - if (Patterns.NON_ALPHA_NUMERIC.matcher(trackName).find()) { + if (!ArgumentChecker.checkName(trackName)) { Message.TRACK_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/TrackMainCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/TrackMainCommand.java index 1d933ad9b..743251af1 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/TrackMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/TrackMainCommand.java @@ -28,6 +28,7 @@ import me.lucko.luckperms.commands.MainCommand; import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.tracks.Track; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.ArrayList; import java.util.List; @@ -39,6 +40,10 @@ public class TrackMainCommand extends MainCommand { @Override protected void getTarget(String target, LuckPermsPlugin plugin, Sender sender, Callback onSuccess) { + if (!ArgumentChecker.checkName(target)) { + Message.TRACK_INVALID_ENTRY.send(sender); + return; + } plugin.getDatastore().loadTrack(target, success -> { if (!success) { Message.TRACK_NOT_FOUND.send(sender); diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java index 418b61563..575bc4e56 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java @@ -31,7 +31,7 @@ import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.groups.Group; import me.lucko.luckperms.users.User; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -45,7 +45,7 @@ public class UserAddGroup extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -63,7 +63,7 @@ public class UserAddGroup extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddTempGroup.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddTempGroup.java index 0b4ad9dc3..cfda45fce 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddTempGroup.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddTempGroup.java @@ -31,8 +31,8 @@ import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.groups.Group; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.DateUtil; -import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -47,7 +47,7 @@ public class UserAddTempGroup extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -78,7 +78,7 @@ public class UserAddTempGroup extends SubCommand { try { if (args.size() >= 3) { final String server = args.get(2).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java index e4035b92f..55679b949 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java @@ -34,6 +34,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; import me.lucko.luckperms.tracks.Track; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -46,6 +47,10 @@ public class UserDemote extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { final String trackName = args.get(0).toLowerCase(); + if (!ArgumentChecker.checkName(trackName)) { + Message.TRACK_INVALID_ENTRY.send(sender); + return; + } plugin.getDatastore().loadTrack(trackName, success -> { if (!success) { diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java index ee87a7b49..c5e3c6463 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.commands.Util; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.users.User; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,7 +44,7 @@ public class UserHasPerm extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { if (args.size() >= 2) { - if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) { + if (!ArgumentChecker.checkServer(args.get(1))) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java index 5507acd75..7858d71ac 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.commands.Util; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.users.User; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,7 +44,7 @@ public class UserInheritsPerm extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { if (args.size() >= 2) { - if (Patterns.NON_ALPHA_NUMERIC.matcher(args.get(1)).find()) { + if (!ArgumentChecker.checkServer(args.get(1))) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java index a6cdcc061..18d0203f1 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java @@ -34,6 +34,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; import me.lucko.luckperms.tracks.Track; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -46,6 +47,10 @@ public class UserPromote extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { final String trackName = args.get(0).toLowerCase(); + if (!ArgumentChecker.checkName(trackName)) { + Message.TRACK_INVALID_ENTRY.send(sender); + return; + } plugin.getDatastore().loadTrack(trackName, success -> { if (!success) { diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java index 339faf0d8..67183a343 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.users.User; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -44,7 +44,7 @@ public class UserRemoveGroup extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -58,7 +58,7 @@ public class UserRemoveGroup extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveTempGroup.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveTempGroup.java index 9d9b65f91..63389105f 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveTempGroup.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveTempGroup.java @@ -30,7 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.users.User; -import me.lucko.luckperms.utils.Patterns; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -45,7 +45,7 @@ public class UserRemoveTempGroup extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String groupName = args.get(0).toLowerCase(); - if (groupName.contains("/") || groupName.contains("$")) { + if (!ArgumentChecker.checkNode(groupName)) { sendUsage(sender, label); return; } @@ -53,7 +53,7 @@ public class UserRemoveTempGroup extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java index 6aa99cf41..076e6d4b3 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -46,7 +47,7 @@ public class UserSetPermission extends SubCommand { String node = args.get(0); String bool = args.get(1).toLowerCase(); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -66,7 +67,7 @@ public class UserSetPermission extends SubCommand { try { if (args.size() >= 3) { final String server = args.get(2).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetTempPermission.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetTempPermission.java index 87246f8ad..24c02669c 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetTempPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetTempPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.DateUtil; import me.lucko.luckperms.utils.Patterns; @@ -47,7 +48,7 @@ public class UserSetTempPermission extends SubCommand { String node = args.get(0); String bool = args.get(1).toLowerCase(); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -80,7 +81,7 @@ public class UserSetTempPermission extends SubCommand { try { if (args.size() >= 4) { final String server = args.get(3).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java index 559f7bfe3..438ac5d03 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java @@ -31,6 +31,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.tracks.Track; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import java.util.List; @@ -43,6 +44,10 @@ public class UserShowPos extends SubCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { final String trackName = args.get(0).toLowerCase(); + if (!ArgumentChecker.checkName(trackName)) { + Message.TRACK_INVALID_ENTRY.send(sender); + return; + } plugin.getDatastore().loadTrack(trackName, success -> { if (!success) { diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java index 1010bbb88..631def495 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -44,7 +45,7 @@ public class UserUnSetPermission extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String node = args.get(0); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -57,7 +58,7 @@ public class UserUnSetPermission extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnsetTempPermission.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnsetTempPermission.java index 527173296..7dbdd2b08 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnsetTempPermission.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnsetTempPermission.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.users.User; +import me.lucko.luckperms.utils.ArgumentChecker; import me.lucko.luckperms.utils.Patterns; import java.util.List; @@ -45,7 +46,7 @@ public class UserUnsetTempPermission extends SubCommand { public void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String node = args.get(0); - if (node.contains("/") || node.contains("$")) { + if (!ArgumentChecker.checkNode(node)) { sendUsage(sender, label); return; } @@ -58,7 +59,7 @@ public class UserUnsetTempPermission extends SubCommand { try { if (args.size() >= 2) { final String server = args.get(1).toLowerCase(); - if (Patterns.NON_ALPHA_NUMERIC.matcher(server).find()) { + if (!ArgumentChecker.checkServer(server)) { Message.SERVER_INVALID_ENTRY.send(sender); return; } diff --git a/common/src/main/java/me/lucko/luckperms/constants/Message.java b/common/src/main/java/me/lucko/luckperms/constants/Message.java index d56d99c10..d62245a96 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Message.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Message.java @@ -105,13 +105,11 @@ public enum Message { GROUP_ALREADY_EXISTS("That group already exists!", true), GROUP_DOES_NOT_EXIST("That group does not exist!", true), - GROUP_NAME_TOO_LONG("Group name '%s' exceeds the maximum length of 36 characters.", true), GROUP_LOAD_ERROR("An unexpected error occurred. Group not loaded.", true), GROUPS_LOAD_ERROR("An unexpected error occurred. Unable to load all groups.", true), TRACK_ALREADY_EXISTS("That track already exists!", true), TRACK_DOES_NOT_EXIST("That track does not exist!", true), - TRACK_NAME_TOO_LONG("Track name '%s' exceeds the maximum length of 36 characters.", true), TRACK_LOAD_ERROR("An unexpected error occurred. Track not loaded.", true), TRACKS_LOAD_ERROR("An unexpected error occurred. Unable to load all tracks.", true), TRACK_EMPTY("The track cannot be used as it is empty or contains only one group.", true), diff --git a/common/src/main/java/me/lucko/luckperms/utils/ArgumentChecker.java b/common/src/main/java/me/lucko/luckperms/utils/ArgumentChecker.java new file mode 100644 index 000000000..bbed6fc1d --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/utils/ArgumentChecker.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.utils; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ArgumentChecker { + + public static boolean checkUsername(String s) { + return !(s.length() > 16 || Patterns.NON_USERNAME.matcher(s).find()); + } + + public static boolean checkName(String s) { + return !(s.length() > 36 || Patterns.NON_ALPHA_NUMERIC.matcher(s).find()); + } + + public static boolean checkServer(String s) { + return !s.toLowerCase().startsWith("r=") && !Patterns.NON_ALPHA_NUMERIC.matcher(s).find(); + } + + public static boolean checkNode(String s) { + return !(s.contains("/") || s.contains("$")); + } + + public static boolean checkTime(long l) { + return !DateUtil.shouldExpire(l); + } + + +} diff --git a/common/src/main/java/me/lucko/luckperms/utils/LPConfiguration.java b/common/src/main/java/me/lucko/luckperms/utils/LPConfiguration.java index 9c95b8d03..77d954e66 100644 --- a/common/src/main/java/me/lucko/luckperms/utils/LPConfiguration.java +++ b/common/src/main/java/me/lucko/luckperms/utils/LPConfiguration.java @@ -92,6 +92,14 @@ public abstract class LPConfiguration { return getBoolean("apply-wildcards", true); } + public boolean getApplyRegex() { + return getBoolean("apply-regex", true); + } + + public boolean getApplyShorthand() { + return getBoolean("apply-shorthand", true); + } + public MySQLConfiguration getDatabaseValues() { return new MySQLConfiguration( getString("sql.address", null), diff --git a/common/src/main/java/me/lucko/luckperms/utils/Patterns.java b/common/src/main/java/me/lucko/luckperms/utils/Patterns.java index 3828ae5eb..df9ea7447 100644 --- a/common/src/main/java/me/lucko/luckperms/utils/Patterns.java +++ b/common/src/main/java/me/lucko/luckperms/utils/Patterns.java @@ -24,17 +24,39 @@ package me.lucko.luckperms.utils; import lombok.experimental.UtilityClass; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; @UtilityClass public class Patterns { + private static final Map CACHE = new ConcurrentHashMap<>(); + public static final Pattern SPACE = Pattern.compile(" "); public static final Pattern SERVER_DELIMITER = Pattern.compile("\\/"); public static final Pattern WORLD_DELIMITER = Pattern.compile("\\-"); public static final Pattern TEMP_DELIMITER = Pattern.compile("\\$"); public static final Pattern DOT = Pattern.compile("\\."); + public static final Pattern VERTICAL_BAR = Pattern.compile("\\|"); public static final Pattern GROUP_MATCH = Pattern.compile("group\\..*"); public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[^A-Za-z0-9]"); public static final Pattern NON_USERNAME = Pattern.compile("[^A-Za-z0-9_]"); + public static final Pattern SHORTHAND_NODE = Pattern.compile("\\.\\([^.]+\\)"); + + public static Pattern compile(String regex) throws PatternSyntaxException { + if (!CACHE.containsKey(regex)) { + Pattern p; + try { + p = Pattern.compile(regex); + } catch (PatternSyntaxException e) { + return null; + } + + CACHE.put(regex, p); + } + + return CACHE.get(regex); + } } diff --git a/common/src/main/java/me/lucko/luckperms/utils/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/utils/PermissionHolder.java index 74d55f537..8c3c309bb 100644 --- a/common/src/main/java/me/lucko/luckperms/utils/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/utils/PermissionHolder.java @@ -32,6 +32,7 @@ import me.lucko.luckperms.groups.Group; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -537,12 +538,12 @@ public abstract class PermissionHolder { String[] serverParts = Patterns.WORLD_DELIMITER.split(parts[0], 2); // 0=server 1=world - if ((!serverParts[0].equalsIgnoreCase("global") || !includeGlobal) && (!serverParts[0].equalsIgnoreCase(server))) { + if ((!serverParts[0].equalsIgnoreCase("global") || !includeGlobal) && (!matches(server, serverParts[0]))) { // GLOBAL AND UNWANTED OR SERVER SPECIFIC BUT DOES NOT APPLY :((( continue; } - if (world != null && !serverParts[1].equalsIgnoreCase(world)) { + if (world != null && !matches(world, serverParts[1])) { // WORLD SPECIFIC BUT DOES NOT APPLY continue; } @@ -563,7 +564,7 @@ public abstract class PermissionHolder { break serverSpecific; } - if (!parts[0].equalsIgnoreCase(server)) { + if (!matches(server, parts[0])) { // SERVER SPECIFIC BUT DOES NOT APPLY continue; } @@ -631,6 +632,8 @@ public abstract class PermissionHolder { } } + applyShorthandIfEnabled(perms); + // Apply next priorities: serverSpecificGroups and then serverWorldSpecificGroups for (Map m : Arrays.asList(serverSpecificGroups, serverWorldSpecificGroups)) { for (Map.Entry groupNode : m.entrySet()) { @@ -653,10 +656,12 @@ public abstract class PermissionHolder { } } } + applyShorthandIfEnabled(perms); } // Apply next priority: userNodes perms.putAll(userNodes); + applyShorthandIfEnabled(perms); // Apply final priorities: serverSpecificNodes and then serverWorldSpecificNodes for (Map m : Arrays.asList(serverSpecificNodes, serverWorldSpecificNodes)) { @@ -664,22 +669,60 @@ public abstract class PermissionHolder { final String rawNode = Patterns.SERVER_DELIMITER.split(node.getKey())[1]; perms.put(rawNode, node.getValue()); } + applyShorthandIfEnabled(perms); } + if (plugin.getConfiguration().getApplyRegex()) { + if (possibleNodes != null && !possibleNodes.isEmpty()) { + perms = applyRegex(perms, possibleNodes); + } else { + perms = applyRegex(perms, plugin.getPossiblePermissions()); + } + } + + applyShorthandIfEnabled(perms); + if (plugin.getConfiguration().getApplyWildcards()) { if (possibleNodes != null && !possibleNodes.isEmpty()) { - return applyWildcards(perms, possibleNodes); + perms = applyWildcards(perms, possibleNodes); + } else { + perms = applyWildcards(perms, plugin.getPossiblePermissions()); } - return applyWildcards(perms, plugin.getPossiblePermissions()); } return perms; } - private Map applyWildcards(Map input, List possibleNodes) { - // Add all group nodes, so wildcard group.* and '*' can apply. - plugin.getGroupManager().getGroups().keySet().forEach(s -> possibleNodes.add("group." + s)); + private boolean matches(String entry, String possibleRegex) { + if (!possibleRegex.toLowerCase().startsWith("r=") || !plugin.getConfiguration().getApplyRegex()) { + return entry.equalsIgnoreCase(possibleRegex); + } + Pattern p = Patterns.compile(possibleRegex.substring(2)); + if (p == null) { + return false; + } + return p.matcher(entry).matches(); + } + + private Map applyRegex(Map input, List possibleNodes) { + for (Map.Entry e : input.entrySet()) { + if (!e.getKey().startsWith("r=") && !e.getKey().startsWith("R=")) { + continue; + } + + final Pattern node = Patterns.compile(e.getKey().substring(2)); + if (node == null) continue; + possibleNodes.stream() + .filter(n -> node.matcher(n).matches()) + .filter(n -> !input.containsKey(n)) + .forEach(n -> input.put(n, e.getValue())); + } + + return input; + } + + private static Map applyWildcards(Map input, List possibleNodes) { SortedMap> wildcards = new TreeMap<>(Collections.reverseOrder()); for (Map.Entry e : input.entrySet()) { if (e.getKey().equals("*") || e.getKey().equals("'*'")) { @@ -721,6 +764,57 @@ public abstract class PermissionHolder { return input; } + private void applyShorthandIfEnabled(Map map) { + if (plugin.getConfiguration().getApplyShorthand()) { + applyShorthand(map); + } + } + + private static Map applyShorthand(Map input) { + for (Map.Entry e : input.entrySet()) { + if (!Patterns.SHORTHAND_NODE.matcher(e.getKey()).find()) { + continue; + } + + if (!e.getKey().contains(".")) { + continue; + } + + String[] parts = Patterns.DOT.split(e.getKey()); + List> nodeParts = new ArrayList<>(); + + for (String s : parts) { + if ((!s.startsWith("(") || !s.endsWith(")")) || !s.contains("|")) { + nodeParts.add(Collections.singleton(s)); + continue; + } + + final String bits = s.substring(1, s.length() - 1); + nodeParts.add(new HashSet<>(Arrays.asList(Patterns.VERTICAL_BAR.split(bits)))); + } + + Set nodes = new HashSet<>(); + for (Set set : nodeParts) { + final Set newNodes = new HashSet<>(); + if (nodes.isEmpty()) { + newNodes.addAll(set); + } else { + nodes.forEach(str -> newNodes.addAll(set.stream() + .map(add -> str + "." + add) + .collect(Collectors.toList())) + ); + } + nodes = newNodes; + } + + nodes.stream() + .filter(n -> !input.containsKey(n)) // Don't override existing nodes + .forEach(n -> input.put(n, e.getValue())); + } + + return input; + } + private static String stripTime(String s) { if (s.contains("$")) { return Patterns.TEMP_DELIMITER.split(s)[0]; diff --git a/sponge/src/main/resources/luckperms.conf b/sponge/src/main/resources/luckperms.conf index 6eb0e64b2..840d22b72 100644 --- a/sponge/src/main/resources/luckperms.conf +++ b/sponge/src/main/resources/luckperms.conf @@ -27,6 +27,16 @@ online-mode=true # the wildcard. This will only work for plugins that define all of their permissions to the server. apply-wildcards=true +# If the plugin should parse regex permissions. +# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve & +# apply all registered permissions matching the regex. This will only work for plugins that define all of their +# permissions to the server. +apply-regex=true + +# If the plugin should complete and apply shorthand permissions. +# If set to true, LuckPerms will detect and expand shorthand node patterns. +apply-shorthand=true + # Which storage method the plugin should use. # Currently supported: mysql, sqlite, flatfile # Fill out connection info below if you're using MySQL