diff --git a/README.creole b/README.creole index 4837c9be..f8bdfa5c 100644 --- a/README.creole +++ b/README.creole @@ -1,8 +1,10 @@ = LuckPerms A (fairly bad) permissions implementation for Bukkit/BungeeCord. -=== Features +== Features * **Group inheritance** - users can be members of multiple groups, groups can inherit other groups +* **Temporary permissions** - users/groups can be given permissions that expire after a given time +* **Temporary groups** - users/groups can be added to/inherit other groups temporarily * **Multi-server support** - data is synced across all servers/platforms * **Per-server permissions/groups** - define user/group permissions that only apply on certain servers * **Server-specific groups** - define groups that only apply on certain servers @@ -17,16 +19,37 @@ A (fairly bad) permissions implementation for Bukkit/BungeeCord. * Currently only supports MySQL, SQLite & Flatfile (JSON) (support for more methods might come in the future) * Not at all tested and could produce unexpected/buggy results and errors -=== Setup +== Setup All configuration options are in the **config.yml** file, which is generated automagically when the plugin first starts. You can define the settings for per-server permissions, the storage method and credentials within this file. -=== Commands +== Info +=== Permission Calculation +Permissions are calculated based on a priority system as follows. + +* Temporary permissions will override non-temporary permissions. + +Example: if a user has a false permission set for "test.node", and a temporary true permission set for "test.node", the temporary permission will override the permanent one, and the user will be granted the true node. + +* Server specific permissions will override generic/global permissions. + +Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission on the "factions" server, the server specific permission will override the globally defined one, and the user will be granted the negated node. + +* Inherited permissions will be overridden by an objects own permissions. + +Example: A user is a member of the default group, which grants "some.thing.perm", but the users own permissions has "some.thing.perm" set to false. The inherited permission will be overridden by the users own permissions, and the user will be granted the negative node. + +=== Temporary Permissions +Temporary permissions are checked each time a user/group is loaded, and when the sync task runs. This means if you set a temporary permission to expire after 30 seconds, it won't actually be removed until the sync task runs. + +The only way around this is to decrease the sync interval. + +== Commands Command usage is printed to the console/chat whenever invalid arguments are provided. Simply typing /perms will list all commands a user has permission to use. -==== Aliases +=== Aliases | Bukkit | /luckperms | | | /perms | | | /permissions | @@ -78,6 +101,10 @@ Additionally, you can use wildcards to grant users access to a selection of comm | /perms user unset [server] | Unsets a permission for the user | luckperms.user.unsetpermission | | /perms user addgroup [server] | Adds the user to a group | luckperms.user.addgroup | | /perms user removegroup [server] | Removes the user from a group | luckperms.user.removegroup | +| /perms user settemp [server]| Sets a temporary permission for the user | luckperms.user.settemppermission | +| /perms user unsettemp [server] | Unsets a temporary permission for the user | luckperms.user.unsettemppermission | +| /perms user addtempgroup [server] | Adds the user to a group temporarily | luckperms.user.addtempgroup | +| /perms user removetempgroup [server] | Removes the user from a temporary group | luckperms.user.removetempgroup | | /perms user setprimarygroup | Sets the users primary group | luckperms.user.setprimarygroup | | /perms user showtracks | Shows a list of the tracks the user can be promoted/demoted on | luckperms.user.showtracks | | /perms user promote | Promotes the user along a given track | luckperms.user.promote | @@ -94,7 +121,11 @@ Additionally, you can use wildcards to grant users access to a selection of comm | /perms group set [server]| Sets a permission for the group | luckperms.group.setpermission | | /perms group unset [server] | Unsets a permission for the group | luckperms.group.unsetpermission | | /perms group setinherit [server]| Sets the group to inherit all permissions from another group | luckperms.group.setinherit | -| /perms group unsetinherit [server] | Unsets a perviously defined inheritance rule | luckperms.group.unsetinherit | +| /perms group unsetinherit [server] | Unsets a previously defined inheritance rule | luckperms.group.unsetinherit | +| /perms group settemp [server] | Sets a temporary permission for the group | luckperms.group.settemppermission | +| /perms group unsettemp [server] | Unsets a temporary permission for the group | luckperms.group.unsettemppermission | +| /perms group settempinherit [server] | Sets the group to inherit all permissions from another group temporarily | luckperms.group.settempinherit | +| /perms group unsettempinherit [server] | Unsets a previously defined temporary inheritance rule | luckperms.group.unsettempinherit | | /perms group showtracks | Shows a list of the tracks that the users in the group can be promoted/demoted on | luckperms.group.showtracks | | /perms group clear | Clears all permissions the group has | luckperms.group.clear | | | | | @@ -107,5 +138,5 @@ Additionally, you can use wildcards to grant users access to a selection of comm | /perms track clear | Clears all groups on the track | luckperms.track.clear | -=== License +== License See LICENSE.md. \ No newline at end of file diff --git a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java index ff9de86d..a5dd6eeb 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java +++ b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java @@ -2,17 +2,17 @@ package me.lucko.luckperms.commands; import lombok.Getter; import me.lucko.luckperms.LuckPermsPlugin; -import me.lucko.luckperms.commands.group.CreateGroupCommand; -import me.lucko.luckperms.commands.group.DeleteGroupCommand; +import me.lucko.luckperms.commands.group.CreateGroup; +import me.lucko.luckperms.commands.group.DeleteGroup; import me.lucko.luckperms.commands.group.GroupMainCommand; -import me.lucko.luckperms.commands.group.ListGroupsCommand; +import me.lucko.luckperms.commands.group.ListGroups; import me.lucko.luckperms.commands.group.subcommands.*; import me.lucko.luckperms.commands.misc.DebugCommand; import me.lucko.luckperms.commands.misc.InfoCommand; import me.lucko.luckperms.commands.misc.SyncCommand; -import me.lucko.luckperms.commands.track.CreateTrackCommand; -import me.lucko.luckperms.commands.track.DeleteTrackCommand; -import me.lucko.luckperms.commands.track.ListTracksCommand; +import me.lucko.luckperms.commands.track.CreateTrack; +import me.lucko.luckperms.commands.track.DeleteTrack; +import me.lucko.luckperms.commands.track.ListTracks; import me.lucko.luckperms.commands.track.TrackMainCommand; import me.lucko.luckperms.commands.track.subcommands.*; import me.lucko.luckperms.commands.user.UserMainCommand; @@ -37,52 +37,60 @@ public class CommandManager { UserMainCommand userCommand = new UserMainCommand(); this.registerMainCommand(userCommand); - userCommand.registerSubCommand(new UserAddGroupCommand()); - userCommand.registerSubCommand(new UserClearCommand()); - userCommand.registerSubCommand(new UserDemoteCommand()); - userCommand.registerSubCommand(new UserGetUUIDCommand()); - userCommand.registerSubCommand(new UserHasPermCommand()); - userCommand.registerSubCommand(new UserInfoCommand()); - userCommand.registerSubCommand(new UserInheritsPermCommand()); - userCommand.registerSubCommand(new UserListNodesCommand()); - userCommand.registerSubCommand(new UserPromoteCommand()); - userCommand.registerSubCommand(new UserRemoveGroupCommand()); - userCommand.registerSubCommand(new UserSetPermissionCommand()); - userCommand.registerSubCommand(new UserSetPrimaryGroupCommand()); - userCommand.registerSubCommand(new UserShowPosCommand()); - userCommand.registerSubCommand(new UserShowTracksCommand()); - userCommand.registerSubCommand(new UserUnSetPermissionCommand()); + userCommand.registerSubCommand(new UserInfo()); + userCommand.registerSubCommand(new UserGetUUID()); + userCommand.registerSubCommand(new UserListNodes()); + userCommand.registerSubCommand(new UserHasPerm()); + userCommand.registerSubCommand(new UserInheritsPerm()); + userCommand.registerSubCommand(new UserSetPermission()); + userCommand.registerSubCommand(new UserUnSetPermission()); + userCommand.registerSubCommand(new UserAddGroup()); + userCommand.registerSubCommand(new UserRemoveGroup()); + userCommand.registerSubCommand(new UserSetTempPermission()); + userCommand.registerSubCommand(new UserUnsetTempPermission()); + userCommand.registerSubCommand(new UserAddTempGroup()); + userCommand.registerSubCommand(new UserRemoveTempGroup()); + userCommand.registerSubCommand(new UserSetPrimaryGroup()); + userCommand.registerSubCommand(new UserShowTracks()); + userCommand.registerSubCommand(new UserPromote()); + userCommand.registerSubCommand(new UserDemote()); + userCommand.registerSubCommand(new UserShowPos()); + userCommand.registerSubCommand(new UserClear()); GroupMainCommand groupCommand = new GroupMainCommand(); this.registerMainCommand(groupCommand); - groupCommand.registerSubCommand(new GroupClearCommand()); - groupCommand.registerSubCommand(new GroupHasPermCommand()); - groupCommand.registerSubCommand(new GroupInfoCommand()); - groupCommand.registerSubCommand(new GroupInheritsPermCommand()); - groupCommand.registerSubCommand(new GroupListNodesCommand()); - groupCommand.registerSubCommand(new GroupSetInheritCommand()); - groupCommand.registerSubCommand(new GroupSetPermissionCommand()); - groupCommand.registerSubCommand(new GroupShowTracksCommand()); - groupCommand.registerSubCommand(new GroupUnsetInheritCommand()); - groupCommand.registerSubCommand(new GroupUnSetPermissionCommand()); + groupCommand.registerSubCommand(new GroupInfo()); + groupCommand.registerSubCommand(new GroupListNodes()); + groupCommand.registerSubCommand(new GroupHasPerm()); + groupCommand.registerSubCommand(new GroupInheritsPerm()); + groupCommand.registerSubCommand(new GroupSetPermission()); + groupCommand.registerSubCommand(new GroupUnSetPermission()); + groupCommand.registerSubCommand(new GroupSetInherit()); + groupCommand.registerSubCommand(new GroupUnsetInherit()); + groupCommand.registerSubCommand(new GroupSetTempPermission()); + groupCommand.registerSubCommand(new GroupUnsetTempPermission()); + groupCommand.registerSubCommand(new GroupSetTempInherit()); + groupCommand.registerSubCommand(new GroupUnsetTempInherit()); + groupCommand.registerSubCommand(new GroupShowTracks()); + groupCommand.registerSubCommand(new GroupClear()); TrackMainCommand trackCommand = new TrackMainCommand(); this.registerMainCommand(trackCommand); - trackCommand.registerSubCommand(new TrackAppendCommand()); - trackCommand.registerSubCommand(new TrackClearCommand()); - trackCommand.registerSubCommand(new TrackInfoCommand()); - trackCommand.registerSubCommand(new TrackInsertCommand()); - trackCommand.registerSubCommand(new TrackRemoveCommand()); + trackCommand.registerSubCommand(new TrackInfo()); + trackCommand.registerSubCommand(new TrackAppend()); + trackCommand.registerSubCommand(new TrackInsert()); + trackCommand.registerSubCommand(new TrackRemove()); + trackCommand.registerSubCommand(new TrackClear()); - this.registerMainCommand(new CreateGroupCommand()); - this.registerMainCommand(new DeleteGroupCommand()); - this.registerMainCommand(new ListGroupsCommand()); - this.registerMainCommand(new CreateTrackCommand()); - this.registerMainCommand(new DeleteTrackCommand()); - this.registerMainCommand(new ListTracksCommand()); - this.registerMainCommand(new DebugCommand()); - this.registerMainCommand(new InfoCommand()); this.registerMainCommand(new SyncCommand()); + this.registerMainCommand(new InfoCommand()); + this.registerMainCommand(new DebugCommand()); + this.registerMainCommand(new CreateGroup()); + this.registerMainCommand(new DeleteGroup()); + this.registerMainCommand(new ListGroups()); + this.registerMainCommand(new CreateTrack()); + this.registerMainCommand(new DeleteTrack()); + this.registerMainCommand(new ListTracks()); } /** diff --git a/common/src/main/java/me/lucko/luckperms/commands/Util.java b/common/src/main/java/me/lucko/luckperms/commands/Util.java index 6bf97b68..3d8b6352 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/Util.java +++ b/common/src/main/java/me/lucko/luckperms/commands/Util.java @@ -1,6 +1,7 @@ package me.lucko.luckperms.commands; import me.lucko.luckperms.constants.Message; +import me.lucko.luckperms.utils.DateUtil; import java.util.List; import java.util.Map; @@ -86,7 +87,7 @@ public class Util { return sb.delete(sb.length() - 6, sb.length()).toString(); } - public static String nodesToString(Map nodes) { + public static String permNodesToString(Map nodes) { if (nodes.isEmpty()) return "&6None"; StringBuilder sb = new StringBuilder(); @@ -102,6 +103,24 @@ public class Util { return sb.delete(sb.length() - 2, sb.length()).toString(); } + public static String tempNodesToString(Map, Long> nodes) { + if (nodes.isEmpty()) return "&6None"; + + StringBuilder sb = new StringBuilder(); + + for (Map.Entry, Long> e : nodes.entrySet()) { + if (e.getKey().getValue()) { + sb.append("&a").append(e.getKey().getKey()).append("&6 - expires in ") + .append(DateUtil.formatDateDiff(e.getValue())).append("\n"); + } else { + sb.append("&c").append(e.getKey().getKey()).append("&6 - expires in ") + .append(DateUtil.formatDateDiff(e.getValue())).append("\n"); + } + } + + return sb.toString(); + } + public static UUID parseUuid(String s) { try { return UUID.fromString(s); diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroupCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java similarity index 95% rename from common/src/main/java/me/lucko/luckperms/commands/group/CreateGroupCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java index a7ef54d5..a0d812f9 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroupCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/CreateGroup.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.utils.Patterns; import java.util.Collections; import java.util.List; -public class CreateGroupCommand extends MainCommand { - public CreateGroupCommand() { +public class CreateGroup extends MainCommand { + public CreateGroup() { super("CreateGroup", "/%s creategroup ", 1); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroupCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java similarity index 96% rename from common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroupCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java index 583ac095..ec656f5c 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroupCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/DeleteGroup.java @@ -13,8 +13,8 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -public class DeleteGroupCommand extends MainCommand { - public DeleteGroupCommand() { +public class DeleteGroup extends MainCommand { + public DeleteGroup() { super("DeleteGroup", "/%s deletegroup ", 1); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/ListGroupsCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/ListGroups.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/group/ListGroupsCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/ListGroups.java index 0a0dcc41..5117a7c3 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/ListGroupsCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/ListGroups.java @@ -12,8 +12,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class ListGroupsCommand extends MainCommand { - public ListGroupsCommand() { +public class ListGroups extends MainCommand { + public ListGroups() { super("ListGroups", "/%s listgroups", 0); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupClearCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupClear.java similarity index 90% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupClearCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupClear.java index 27d60a0b..264bbb42 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupClearCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupClear.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupClearCommand extends GroupSubCommand { - public GroupClearCommand() { +public class GroupClear extends GroupSubCommand { + public GroupClear() { super("clear", "Clears a groups permissions", "/%s group clear", Permission.GROUP_CLEAR); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPermCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java similarity index 92% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPermCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java index 6b1b032f..92a030ba 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPermCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupHasPerm.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupHasPermCommand extends GroupSubCommand { - public GroupHasPermCommand() { +public class GroupHasPerm extends GroupSubCommand { + public GroupHasPerm() { super("haspermission", "Checks to see if a group has a certain permission node", "/%s group haspermission [server]", Permission.GROUP_HASPERMISSION); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInfoCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInfo.java similarity index 79% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInfoCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInfo.java index 87feb015..5f2d01c4 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInfoCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInfo.java @@ -9,14 +9,15 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupInfoCommand extends GroupSubCommand { - public GroupInfoCommand() { +public class GroupInfo extends GroupSubCommand { + public GroupInfo() { super("info", "Gives info about the group", "/%s group info", Permission.GROUP_INFO); } @Override protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { - Message.GROUP_INFO.send(sender, group.getName(), group.getNodes().keySet().size(), label, group.getName()); + Message.GROUP_INFO.send(sender, group.getName(), group.getPermanentNodes().keySet().size(), + group.getTemporaryNodes().keySet().size(), label, group.getName()); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPermCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java similarity index 91% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPermCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java index 05f6bc50..c69de9df 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPermCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupInheritsPerm.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupInheritsPermCommand extends GroupSubCommand { - public GroupInheritsPermCommand() { +public class GroupInheritsPerm extends GroupSubCommand { + public GroupInheritsPerm() { super("inheritspermission", "Checks to see if a group inherits a certain permission node", "/%s group inheritspermission [server]", Permission.GROUP_INHERITSPERMISSION); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupListNodesCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupListNodes.java similarity index 72% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupListNodesCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupListNodes.java index 0023c4fb..267992fd 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupListNodesCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupListNodes.java @@ -10,15 +10,16 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupListNodesCommand extends GroupSubCommand { - public GroupListNodesCommand() { +public class GroupListNodes extends GroupSubCommand { + public GroupListNodes() { super("listnodes", "Lists the permission nodes the group has", "/%s group listnodes", Permission.GROUP_LISTNODES); } @Override protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { - Message.LISTNODES.send(sender, group.getName(), Util.nodesToString(group.getNodes())); + Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(group.getPermanentNodes())); + Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getTemporaryNodes())); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInheritCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java similarity index 90% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInheritCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java index 355ea927..354e90b1 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInheritCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetInherit.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupSetInheritCommand extends GroupSubCommand { - public GroupSetInheritCommand() { +public class GroupSetInherit extends GroupSubCommand { + public GroupSetInherit() { super("setinherit", "Sets another group for this group to inherit permissions from", "/%s group setinherit [server]", Permission.GROUP_SETINHERIT); } @@ -20,6 +20,11 @@ public class GroupSetInheritCommand extends GroupSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String groupName = args.get(0).toLowerCase(); + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + plugin.getDatastore().loadGroup(groupName, success -> { if (!success) { Message.GROUP_LOAD_ERROR.send(sender); diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermissionCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermissionCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java index b7731f8a..9cc26480 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermissionCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetPermission.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.utils.Patterns; import java.util.List; -public class GroupSetPermissionCommand extends GroupSubCommand { - public GroupSetPermissionCommand() { +public class GroupSetPermission extends GroupSubCommand { + public GroupSetPermission() { super("set", "Sets a permission for a group", "/%s group set [server]", Permission.GROUP_SETPERMISSION); } @@ -22,7 +22,7 @@ public class GroupSetPermissionCommand extends GroupSubCommand { String node = args.get(0); String bool = args.get(1).toLowerCase(); - if (node.contains("/")) { + if (node.contains("/") || node.contains("$")) { sendUsage(sender, label); 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 new file mode 100644 index 00000000..40b31c7a --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempInherit.java @@ -0,0 +1,74 @@ +package me.lucko.luckperms.commands.group.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.group.GroupSubCommand; +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.DateUtil; + +import java.util.List; + +public class GroupSetTempInherit extends GroupSubCommand { + public GroupSetTempInherit() { + super("settempinherit", "Sets another group for this group to inherit permissions from temporarily", + "/%s group settempinherit [server]", Permission.GROUP_SET_TEMP_INHERIT); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { + String groupName = args.get(0).toLowerCase(); + + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + + long duration; + try { + duration = DateUtil.parseDateDiff(args.get(1), true); + } catch (DateUtil.IllegalDateException e) { + Message.ILLEGAL_DATE_ERROR.send(sender, args.get(1)); + return; + } + + if (DateUtil.shouldExpire(duration)) { + Message.PAST_DATE_ERROR.send(sender); + return; + } + + plugin.getDatastore().loadGroup(groupName, success -> { + if (!success) { + Message.GROUP_LOAD_ERROR.send(sender); + } else { + try { + if (args.size() == 3) { + final String server = args.get(2).toLowerCase(); + group.setPermission("group." + groupName, true, server, duration); + Message.GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server, + DateUtil.formatDateDiff(duration)); + } else { + group.setPermission("group." + groupName, true, duration); + Message.GROUP_SET_TEMP_INHERIT_SUCCESS.send(sender, group.getName(), groupName, DateUtil.formatDateDiff(duration)); + } + + saveGroup(group, sender, plugin); + } catch (ObjectAlreadyHasException e) { + Message.GROUP_ALREADY_TEMP_INHERITS.send(sender, group.getName(), groupName); + } + } + }); + } + + @Override + public List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + return getGroupTabComplete(args, plugin); + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return argLength != 2 && argLength != 3; + } +} 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 new file mode 100644 index 00000000..6e0bd645 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupSetTempPermission.java @@ -0,0 +1,81 @@ +package me.lucko.luckperms.commands.group.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.group.GroupSubCommand; +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.DateUtil; +import me.lucko.luckperms.utils.Patterns; + +import java.util.List; + +public class GroupSetTempPermission extends GroupSubCommand { + public GroupSetTempPermission() { + super("settemp", "Sets a temporary permission for a group", "/%s group settemp [server]", + Permission.GROUP_SET_TEMP_PERMISSION); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { + String node = args.get(0); + String bool = args.get(1).toLowerCase(); + + if (node.contains("/") || node.contains("$")) { + sendUsage(sender, label); + return; + } + + if (Patterns.GROUP_MATCH.matcher(node).matches()) { + Message.GROUP_USE_INHERIT.send(sender); + return; + } + + if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) { + sendUsage(sender, label); + return; + } + + boolean b = Boolean.parseBoolean(bool); + + long duration; + try { + duration = DateUtil.parseDateDiff(args.get(2), true); + } catch (DateUtil.IllegalDateException e) { + Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2)); + return; + } + + if (DateUtil.shouldExpire(duration)) { + Message.PAST_DATE_ERROR.send(sender); + return; + } + + try { + if (args.size() == 4) { + final String server = args.get(3).toLowerCase(); + group.setPermission(node, b, server, duration); + Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server, DateUtil.formatDateDiff(duration)); + } else { + group.setPermission(node, b, duration); + Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, group.getName(), DateUtil.formatDateDiff(duration)); + } + + saveGroup(group, sender, plugin); + } catch (ObjectAlreadyHasException e) { + Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, group.getName()); + } + } + + @Override + public List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + return getBoolTabComplete(args); + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return argLength != 3 && argLength != 4; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupShowTracksCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupShowTracks.java similarity index 92% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupShowTracksCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupShowTracks.java index 3454ac7e..4848928b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupShowTracksCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupShowTracks.java @@ -12,8 +12,8 @@ import me.lucko.luckperms.tracks.Track; import java.util.List; import java.util.stream.Collectors; -public class GroupShowTracksCommand extends GroupSubCommand { - public GroupShowTracksCommand() { +public class GroupShowTracks extends GroupSubCommand { + public GroupShowTracks() { super("showtracks", "Lists the tracks that this group features on", "/%s group showtracks", Permission.GROUP_SHOWTRACKS); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermissionCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java similarity index 91% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermissionCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java index 7a674874..598882a7 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermissionCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnSetPermission.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.utils.Patterns; import java.util.List; -public class GroupUnSetPermissionCommand extends GroupSubCommand { - public GroupUnSetPermissionCommand() { +public class GroupUnSetPermission extends GroupSubCommand { + public GroupUnSetPermission() { super("unset", "Unsets a permission for a group", "/%s group unset [server]", Permission.GROUP_UNSETPERMISSION); } @@ -21,7 +21,7 @@ public class GroupUnSetPermissionCommand extends GroupSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String node = args.get(0); - if (node.contains("/")) { + if (node.contains("/") || node.contains("$")) { sendUsage(sender, label); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInheritCommand.java b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java similarity index 88% rename from common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInheritCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java index 2160ed57..d4d3025c 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInheritCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetInherit.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.groups.Group; import java.util.List; -public class GroupUnsetInheritCommand extends GroupSubCommand { - public GroupUnsetInheritCommand() { +public class GroupUnsetInherit extends GroupSubCommand { + public GroupUnsetInherit() { super("unsetinherit", "Unsets another group for this group to inherit permissions from", "/%s group unsetinherit [server]", Permission.GROUP_UNSETINHERIT); } @@ -20,6 +20,11 @@ public class GroupUnsetInheritCommand extends GroupSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { String groupName = args.get(0).toLowerCase(); + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + try { if (args.size() == 2) { final String server = args.get(1).toLowerCase(); 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 new file mode 100644 index 00000000..7e839d0c --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempInherit.java @@ -0,0 +1,53 @@ +package me.lucko.luckperms.commands.group.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.group.GroupSubCommand; +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 java.util.List; + +public class GroupUnsetTempInherit extends GroupSubCommand { + public GroupUnsetTempInherit() { + super("unsettempinherit", "Unsets another group for this group to inherit permissions from", + "/%s group unsettempinherit [server]", Permission.GROUP_UNSET_TEMP_INHERIT); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { + String groupName = args.get(0).toLowerCase(); + + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + + try { + if (args.size() == 2) { + final String server = args.get(1).toLowerCase(); + group.unsetPermission("group." + groupName, server, true); + Message.GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server); + } else { + group.unsetPermission("group." + groupName, true); + Message.GROUP_UNSET_TEMP_INHERIT_SUCCESS.send(sender, group.getName(), groupName); + } + + saveGroup(group, sender, plugin); + } catch (ObjectLacksException e) { + Message.GROUP_DOES_NOT_TEMP_INHERIT.send(sender, group.getName(), groupName); + } + } + + @Override + public List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + return getGroupTabComplete(args, plugin); + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return argLength != 1 && argLength != 2; + } +} 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 new file mode 100644 index 00000000..dfb6ce2d --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/group/subcommands/GroupUnsetTempPermission.java @@ -0,0 +1,54 @@ +package me.lucko.luckperms.commands.group.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.group.GroupSubCommand; +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 java.util.List; + +public class GroupUnsetTempPermission extends GroupSubCommand { + public GroupUnsetTempPermission() { + super("unsettemp", "Unsets a temporary permission for a group", + "/%s group unsettemp [server]", Permission.GROUP_UNSET_TEMP_PERMISSION); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) { + String node = args.get(0); + + if (node.contains("/") || node.contains("$")) { + sendUsage(sender, label); + return; + } + + if (Patterns.GROUP_MATCH.matcher(node).matches()) { + Message.GROUP_USE_UNINHERIT.send(sender); + return; + } + + try { + if (args.size() == 2) { + final String server = args.get(1).toLowerCase(); + group.unsetPermission(node, server); + Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), server, true); + } else { + group.unsetPermission(node, true); + Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, group.getName()); + } + + saveGroup(group, sender, plugin); + } catch (ObjectLacksException e) { + Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, group.getName()); + } + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return argLength != 1 && argLength != 2; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrackCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java similarity index 95% rename from common/src/main/java/me/lucko/luckperms/commands/track/CreateTrackCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java index 071d24c4..e294899b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrackCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/CreateTrack.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.utils.Patterns; import java.util.Collections; import java.util.List; -public class CreateTrackCommand extends MainCommand { - public CreateTrackCommand() { +public class CreateTrack extends MainCommand { + public CreateTrack() { super("CreateTrack", "/%s createtrack ", 1); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrackCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java similarity index 96% rename from common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrackCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java index 3b924222..0bae5c32 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrackCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/DeleteTrack.java @@ -13,8 +13,8 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -public class DeleteTrackCommand extends MainCommand { - public DeleteTrackCommand() { +public class DeleteTrack extends MainCommand { + public DeleteTrack() { super("DeleteTrack", "/%s deletetrack ", 1); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/ListTracksCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/ListTracks.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/track/ListTracksCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/ListTracks.java index 99d390fc..304e1d63 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/ListTracksCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/ListTracks.java @@ -12,8 +12,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class ListTracksCommand extends MainCommand { - public ListTracksCommand() { +public class ListTracks extends MainCommand { + public ListTracks() { super("ListTracks", "/%s listtracks", 0); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackAppendCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackAppend.java similarity index 95% rename from common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackAppendCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackAppend.java index a119e6a1..ecd5bfcb 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackAppendCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackAppend.java @@ -12,8 +12,8 @@ import me.lucko.luckperms.tracks.Track; import java.util.List; -public class TrackAppendCommand extends TrackSubCommand { - public TrackAppendCommand() { +public class TrackAppend extends TrackSubCommand { + public TrackAppend() { super("append", "Appends a group onto the end of the track", "/%s track append ", Permission.TRACK_APPEND); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackClearCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackClear.java similarity index 90% rename from common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackClearCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackClear.java index a1c2afa6..09ad610b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackClearCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackClear.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.tracks.Track; import java.util.List; -public class TrackClearCommand extends TrackSubCommand { - public TrackClearCommand() { +public class TrackClear extends TrackSubCommand { + public TrackClear() { super("clear", "Clears the groups on the track", "/%s track clear", Permission.TRACK_CLEAR); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInfoCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInfo.java similarity index 90% rename from common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInfoCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInfo.java index 13bd7f62..576df3de 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInfoCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInfo.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.tracks.Track; import java.util.List; -public class TrackInfoCommand extends TrackSubCommand { - public TrackInfoCommand() { +public class TrackInfo extends TrackSubCommand { + public TrackInfo() { super("info", "Gives info about the track", "/%s track info", Permission.TRACK_INFO); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInsertCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInsert.java similarity index 96% rename from common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInsertCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInsert.java index 802709e1..7523df6d 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInsertCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackInsert.java @@ -12,8 +12,8 @@ import me.lucko.luckperms.tracks.Track; import java.util.List; -public class TrackInsertCommand extends TrackSubCommand { - public TrackInsertCommand() { +public class TrackInsert extends TrackSubCommand { + public TrackInsert() { super("insert", "Inserts a group at a given position along the track", "/%s track insert ", Permission.TRACK_INSERT); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackRemoveCommand.java b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackRemove.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackRemoveCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackRemove.java index 527e6cf3..abd168e3 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackRemoveCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/track/subcommands/TrackRemove.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.tracks.Track; import java.util.List; -public class TrackRemoveCommand extends TrackSubCommand { - public TrackRemoveCommand() { +public class TrackRemove extends TrackSubCommand { + public TrackRemove() { super("remove", "Removes a group from the track", "/%s track remove ", Permission.TRACK_REMOVE); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroupCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java similarity index 91% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroupCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java index 85c18677..03d3a3d9 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroupCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddGroup.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserAddGroupCommand extends UserSubCommand { - public UserAddGroupCommand() { +public class UserAddGroup extends UserSubCommand { + public UserAddGroup() { super("addgroup", "Adds the user to a group", "/%s user addgroup [server]", Permission.USER_ADDGROUP); } @@ -20,6 +20,11 @@ public class UserAddGroupCommand extends UserSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String groupName = args.get(0).toLowerCase(); + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + plugin.getDatastore().loadGroup(groupName, success -> { if (!success) { Message.GROUP_DOES_NOT_EXIST.send(sender); 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 new file mode 100644 index 00000000..f1023984 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserAddTempGroup.java @@ -0,0 +1,81 @@ +package me.lucko.luckperms.commands.user.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.user.UserSubCommand; +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.users.User; +import me.lucko.luckperms.utils.DateUtil; + +import java.util.List; + +public class UserAddTempGroup extends UserSubCommand { + public UserAddTempGroup() { + super("addtempgroup", "Adds the user to a group temporarily", "/%s user addtempgroup [server]", + Permission.USER_ADDTEMPGROUP); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { + String groupName = args.get(0).toLowerCase(); + + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + + long duration; + try { + duration = DateUtil.parseDateDiff(args.get(1), true); + } catch (DateUtil.IllegalDateException e) { + Message.ILLEGAL_DATE_ERROR.send(sender, args.get(1)); + return; + } + + if (DateUtil.shouldExpire(duration)) { + Message.PAST_DATE_ERROR.send(sender); + return; + } + + plugin.getDatastore().loadGroup(groupName, success -> { + if (!success) { + Message.GROUP_DOES_NOT_EXIST.send(sender); + } else { + Group group = plugin.getGroupManager().getGroup(groupName); + if (group == null) { + Message.GROUP_DOES_NOT_EXIST.send(sender); + return; + } + + try { + if (args.size() == 3) { + final String server = args.get(2).toLowerCase(); + user.addGroup(group, server, duration); + Message.USER_ADDTEMPGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server, + DateUtil.formatDateDiff(duration)); + } else { + user.addGroup(group, duration); + Message.USER_ADDTEMPGROUP_SUCCESS.send(sender, user.getName(), groupName, DateUtil.formatDateDiff(duration)); + } + + saveUser(user, sender, plugin); + } catch (ObjectAlreadyHasException e) { + Message.USER_ALREADY_TEMP_MEMBER_OF.send(sender, user.getName(), group.getName()); + } + } + }); + } + + @Override + public List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + return getGroupTabComplete(args, plugin); + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return (argLength != 2 && argLength != 3); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserClearCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserClear.java similarity index 91% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserClearCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserClear.java index e08a4367..5e949ad0 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserClearCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserClear.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserClearCommand extends UserSubCommand { - public UserClearCommand() { +public class UserClear extends UserSubCommand { + public UserClear() { super("clear", "Clears a users permissions and groups", "/%s user clear", Permission.USER_CLEAR); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemoteCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java similarity index 97% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemoteCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java index fcb988b8..d11cdb1b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemoteCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserDemote.java @@ -14,8 +14,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserDemoteCommand extends UserSubCommand { - public UserDemoteCommand() { +public class UserDemote extends UserSubCommand { + public UserDemote() { super("demote", "Demotes a user along a track", "/%s user demote ", Permission.USER_DEMOTE); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserGetUUIDCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserGetUUID.java similarity index 89% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserGetUUIDCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserGetUUID.java index 732ac2be..63da5333 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserGetUUIDCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserGetUUID.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserGetUUIDCommand extends UserSubCommand { - public UserGetUUIDCommand() { +public class UserGetUUID extends UserSubCommand { + public UserGetUUID() { super("getuuid", "Get the UUID of a user", "/%s user getuuid", Permission.USER_GETUUID); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPermCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java similarity index 92% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPermCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java index f330c92d..0c5b57cd 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPermCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserHasPerm.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserHasPermCommand extends UserSubCommand { - public UserHasPermCommand() { +public class UserHasPerm extends UserSubCommand { + public UserHasPerm() { super("haspermission", "Checks to see if a user has a certain permission node", "/%s user haspermission [server]", Permission.USER_HASPERMISSION); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInfoCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInfo.java similarity index 82% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInfoCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInfo.java index 6c9daa99..0f6c232f 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInfoCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInfo.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserInfoCommand extends UserSubCommand { - public UserInfoCommand() { +public class UserInfo extends UserSubCommand { + public UserInfo() { super("info", "Gives info about the user", "/%s user info", Permission.USER_INFO); } @@ -19,7 +19,7 @@ public class UserInfoCommand extends UserSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { Message.USER_INFO.send(sender, user.getName(), user.getUuid(), plugin.getPlayerStatus(user.getUuid()), Util.listToCommaSep(user.getGroupNames()), user.getPrimaryGroup(), - (user.getNodes().keySet().size() - user.getGroupNames().size()), label, user.getName() + user.getPermanentNodes().keySet().size(), user.getTemporaryNodes().keySet().size(), label, user.getName() ); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPermCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java similarity index 91% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPermCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java index b41b3082..d34e88b5 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPermCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserInheritsPerm.java @@ -9,8 +9,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserInheritsPermCommand extends UserSubCommand { - public UserInheritsPermCommand() { +public class UserInheritsPerm extends UserSubCommand { + public UserInheritsPerm() { super("inheritspermission", "Checks to see if a user inherits a certain permission node", "/%s user inheritspermission [server]", Permission.USER_INHERITSPERMISSION); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserListNodesCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserListNodes.java similarity index 71% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserListNodesCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserListNodes.java index 410b3a2f..6b414786 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserListNodesCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserListNodes.java @@ -10,14 +10,15 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserListNodesCommand extends UserSubCommand { - public UserListNodesCommand() { +public class UserListNodes extends UserSubCommand { + public UserListNodes() { super("listnodes", "Lists the permission nodes the user has", "/%s user listnodes", Permission.USER_LISTNODES); } @Override protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { - Message.LISTNODES.send(sender, user.getName(), Util.nodesToString(user.getNodes())); + Message.LISTNODES.send(sender, user.getName(), Util.permNodesToString(user.getPermanentNodes())); + Message.LISTNODES_TEMP.send(sender, user.getName(), Util.tempNodesToString(user.getTemporaryNodes())); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromoteCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java similarity index 97% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromoteCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java index 1ad07c04..56f3a9be 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromoteCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserPromote.java @@ -14,8 +14,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserPromoteCommand extends UserSubCommand { - public UserPromoteCommand() { +public class UserPromote extends UserSubCommand { + public UserPromote() { super("promote", "Promotes the user along a track", "/%s user promote ", Permission.USER_PROMOTE); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroupCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java similarity index 89% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroupCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java index c89345d9..879c99dc 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroupCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveGroup.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserRemoveGroupCommand extends UserSubCommand { - public UserRemoveGroupCommand() { +public class UserRemoveGroup extends UserSubCommand { + public UserRemoveGroup() { super("removegroup", "Removes a user from a group", "/%s user removegroup [server]", Permission.USER_REMOVEGROUP); } @@ -19,6 +19,11 @@ public class UserRemoveGroupCommand extends UserSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String groupName = args.get(0).toLowerCase(); + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + if ((args.size() == 1 || (args.size() == 2 && args.get(1).equalsIgnoreCase("global"))) && user.getPrimaryGroup().equalsIgnoreCase(groupName)) { Message.USER_REMOVEGROUP_ERROR_PRIMARY.send(sender); 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 new file mode 100644 index 00000000..3ba1009c --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserRemoveTempGroup.java @@ -0,0 +1,52 @@ +package me.lucko.luckperms.commands.user.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.user.UserSubCommand; +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 java.util.List; + +public class UserRemoveTempGroup extends UserSubCommand { + public UserRemoveTempGroup() { + super("removetempgroup", "Removes a user from a temporary group", "/%s user removetempgroup [server]", Permission.USER_REMOVETEMPGROUP); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { + String groupName = args.get(0).toLowerCase(); + + if (groupName.contains("/") || groupName.contains("$")) { + sendUsage(sender, label); + return; + } + + try { + if (args.size() == 2) { + final String server = args.get(1).toLowerCase(); + user.unsetPermission("group." + groupName, server, true); + Message.USER_REMOVETEMPGROUP_SERVER_SUCCESS.send(sender, user.getName(), groupName, server); + } else { + user.unsetPermission("group." + groupName, true); + Message.USER_REMOVETEMPGROUP_SUCCESS.send(sender, user.getName(), groupName); + } + + saveUser(user, sender, plugin); + } catch (ObjectLacksException e) { + Message.USER_NOT_TEMP_MEMBER_OF.send(sender, user.getName(), groupName); + } + } + + @Override + public List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + return getGroupTabComplete(args, plugin); + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return (argLength != 1 && argLength != 2); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermissionCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermissionCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java index 7528ceff..ef7b4e7c 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermissionCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPermission.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.utils.Patterns; import java.util.List; -public class UserSetPermissionCommand extends UserSubCommand { - public UserSetPermissionCommand() { +public class UserSetPermission extends UserSubCommand { + public UserSetPermission() { super("set", "Sets a permission for a user", "/%s user set [server]", Permission.USER_SETPERMISSION); } @@ -22,7 +22,7 @@ public class UserSetPermissionCommand extends UserSubCommand { String node = args.get(0); String bool = args.get(1).toLowerCase(); - if (node.contains("/")) { + if (node.contains("/") || node.contains("$")) { sendUsage(sender, label); return; } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPrimaryGroupCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPrimaryGroup.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPrimaryGroupCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPrimaryGroup.java index 1519ce12..50487ffd 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPrimaryGroupCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetPrimaryGroup.java @@ -10,8 +10,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserSetPrimaryGroupCommand extends UserSubCommand { - public UserSetPrimaryGroupCommand() { +public class UserSetPrimaryGroup extends UserSubCommand { + public UserSetPrimaryGroup() { super("setprimarygroup", "Sets a users primary group", "/%s user setprimarygroup ", Permission.USER_SETPRIMARYGROUP); } 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 new file mode 100644 index 00000000..8287c026 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserSetTempPermission.java @@ -0,0 +1,81 @@ +package me.lucko.luckperms.commands.user.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.user.UserSubCommand; +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.DateUtil; +import me.lucko.luckperms.utils.Patterns; + +import java.util.List; + +public class UserSetTempPermission extends UserSubCommand { + public UserSetTempPermission() { + super("settemp", "Sets a temporary permission for a user", + "/%s user settemp [server]", Permission.USER_SET_TEMP_PERMISSION); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { + String node = args.get(0); + String bool = args.get(1).toLowerCase(); + + if (node.contains("/") || node.contains("$")) { + sendUsage(sender, label); + return; + } + + if (Patterns.GROUP_MATCH.matcher(node).matches()) { + Message.USER_USE_ADDGROUP.send(sender); + return; + } + + if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) { + sendUsage(sender, label); + return; + } + + boolean b = Boolean.parseBoolean(bool); + + long duration; + try { + duration = DateUtil.parseDateDiff(args.get(2), true); + } catch (DateUtil.IllegalDateException e) { + Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2)); + return; + } + + if (DateUtil.shouldExpire(duration)) { + Message.PAST_DATE_ERROR.send(sender); + return; + } + + try { + if (args.size() == 4) { + final String server = args.get(3).toLowerCase(); + user.setPermission(node, b, server, duration); + Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, user.getName(), server, DateUtil.formatDateDiff(duration)); + } else { + user.setPermission(node, b, duration); + Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, user.getName(), DateUtil.formatDateDiff(duration)); + } + + saveUser(user, sender, plugin); + } catch (ObjectAlreadyHasException e) { + Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, user.getName()); + } + } + + @Override + public List onTabComplete(Sender sender, List args, LuckPermsPlugin plugin) { + return getBoolTabComplete(args); + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return argLength != 3 && argLength != 4; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPosCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java similarity index 95% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPosCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java index 538d0696..0404bcba 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPosCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowPos.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.users.User; import java.util.List; -public class UserShowPosCommand extends UserSubCommand { - public UserShowPosCommand() { +public class UserShowPos extends UserSubCommand { + public UserShowPos() { super("showpos", "Shows a users position on a track", "/%s user showpos ", Permission.USER_SHOWPOS); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowTracksCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowTracks.java similarity index 93% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowTracksCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowTracks.java index 26f88820..e35b3e49 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowTracksCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserShowTracks.java @@ -12,8 +12,8 @@ import me.lucko.luckperms.users.User; import java.util.List; import java.util.stream.Collectors; -public class UserShowTracksCommand extends UserSubCommand { - public UserShowTracksCommand() { +public class UserShowTracks extends UserSubCommand { + public UserShowTracks() { super("showtracks", "Lists the tracks that this user's primary group features on", "/%s user showtracks", Permission.USER_SHOWTRACKS); } diff --git a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermissionCommand.java b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java similarity index 92% rename from common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermissionCommand.java rename to common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java index 097534d0..91118555 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermissionCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnSetPermission.java @@ -11,8 +11,8 @@ import me.lucko.luckperms.utils.Patterns; import java.util.List; -public class UserUnSetPermissionCommand extends UserSubCommand { - public UserUnSetPermissionCommand() { +public class UserUnSetPermission extends UserSubCommand { + public UserUnSetPermission() { super("unset", "Unsets a permission for a user", "/%s user unset [server]", Permission.USER_UNSETPERMISSION); } @@ -21,7 +21,7 @@ public class UserUnSetPermissionCommand extends UserSubCommand { protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { String node = args.get(0); - if (node.contains("/")) { + if (node.contains("/") || node.contains("$")) { sendUsage(sender, label); 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 new file mode 100644 index 00000000..902d5116 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/user/subcommands/UserUnsetTempPermission.java @@ -0,0 +1,54 @@ +package me.lucko.luckperms.commands.user.subcommands; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.user.UserSubCommand; +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 java.util.List; + +public class UserUnsetTempPermission extends UserSubCommand { + public UserUnsetTempPermission() { + super("unsettemp", "Unsets a temporary permission for a user", + "/%s user unsettemp [server]", Permission.USER_UNSET_TEMP_PERMISSION); + } + + @Override + protected void execute(LuckPermsPlugin plugin, Sender sender, User user, List args, String label) { + String node = args.get(0); + + if (node.contains("/") || node.contains("$")) { + sendUsage(sender, label); + return; + } + + if (Patterns.GROUP_MATCH.matcher(node).matches()) { + Message.USER_USE_REMOVEGROUP.send(sender); + return; + } + + try { + if (args.size() == 2) { + final String server = args.get(1).toLowerCase(); + user.unsetPermission(node, server, true); + Message.UNSET_TEMP_PERMISSION_SERVER_SUCCESS.send(sender, node, user.getName(), server); + } else { + user.unsetPermission(node, true); + Message.UNSET_TEMP_PERMISSION_SUCCESS.send(sender, node, user.getName()); + } + + saveUser(user, sender, plugin); + } catch (ObjectLacksException e) { + Message.DOES_NOT_HAVE_TEMP_PERMISSION.send(sender, user.getName()); + } + } + + @Override + public boolean isArgLengthInvalid(int argLength) { + return argLength != 1 && argLength != 2; + } +} 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 f7cea23a..d08569b6 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Message.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Message.java @@ -20,6 +20,8 @@ public enum Message { ALREADY_HASPERMISSION("%s already has this permission!", true), DOES_NOT_HAVEPERMISSION("%s does not have this permission set.", true), + ALREADY_HAS_TEMP_PERMISSION("%s already has this permission set temporarily!", true), + DOES_NOT_HAVE_TEMP_PERMISSION("%s does not have this permission set temporarily.", true), @@ -65,6 +67,12 @@ public enum Message { USER_NOT_MEMBER_OF("%s is not a member of '%s'.", true), GROUP_ALREADY_INHERITS("%s already inherits '%s'.", true), GROUP_DOES_NOT_INHERIT("%s does not inherit '%s'.", true), + + USER_ALREADY_TEMP_MEMBER_OF("%s is already a temporary member of '%s'.", true), + USER_NOT_TEMP_MEMBER_OF("%s is not a temporary member of '%s'.", true), + GROUP_ALREADY_TEMP_INHERITS("%s already temporarily inherits '%s'.", true), + GROUP_DOES_NOT_TEMP_INHERIT("%s does not temporarily inherit '%s'.", true), + TRACK_ALREADY_CONTAINS("Track %s already contains the group '%s'.", true), TRACK_DOES_NOT_CONTAIN("Track %s does not contain the group '%s'.", true), @@ -107,11 +115,18 @@ public enum Message { TRACKS_LIST("&aTracks: %s", true), LISTNODES("&e%s's Nodes:" + "\n" + "%s", true), + LISTNODES_TEMP("&e%s's Temporary Nodes:" + "\n" + "%s", true), SETPERMISSION_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a.", true), SETPERMISSION_SERVER_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a.", true), + SETPERMISSION_TEMP_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a for a duration of &b%s&a.", true), + SETPERMISSION_TEMP_SERVER_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a for a duration of &b%s&a.", true), UNSETPERMISSION_SUCCESS("&aUnset &b%s&a for &b%s&a.", true), UNSETPERMISSION_SERVER_SUCCESS("&aUnset &b%s&a for &b%s&a on server &b%$s&a.", true), + UNSET_TEMP_PERMISSION_SUCCESS("&aUnset temporary permission &b%s&a for &b%s&a.", true), + UNSET_TEMP_PERMISSION_SERVER_SUCCESS("&aUnset temporary permission &b%s&a for &b%s&a on server &b%$s&a.", true), CLEAR_SUCCESS("&b%s&a's permissions were cleared.", true), + ILLEGAL_DATE_ERROR("Could not parse date '%s'.", true), + PAST_DATE_ERROR("You cannot set a date in the past!", true), USER_INFO( PREFIX + "&d-> &eUser: &6%s" + "\n" + @@ -120,14 +135,19 @@ public enum Message { PREFIX + "&d-> &eGroups: &6%s" + "\n" + PREFIX + "&d-> &ePrimary Group: &6%s" + "\n" + PREFIX + "&d-> &ePermissions: &6%s" + "\n" + + PREFIX + "&d-> &eTemporary Permissions: &6%s" + "\n" + PREFIX + "&d-> &bUse &a/%s user %s listnodes &bto see all permissions.", false ), USER_GETUUID("&bThe UUID of &e%s&b is &e%s&b.", true), USER_ADDGROUP_SUCCESS("&b%s&a successfully added to group &b%s&a.", true), USER_ADDGROUP_SERVER_SUCCESS("&b%s&a successfully added to group &b%s&a on server &b%s&a.", true), + USER_ADDTEMPGROUP_SUCCESS("&b%s&a successfully added to group &b%s&a for a duration of &b%s&a.", true), + USER_ADDTEMPGROUP_SERVER_SUCCESS("&b%s&a successfully added to group &b%s&a on server &b%s&a for a duration of &b%s&a.", true), USER_REMOVEGROUP_SUCCESS("&b%s&a was removed from group &b%s&a.", true), USER_REMOVEGROUP_SERVER_SUCCESS("&b%s&a was removed from group &b%s&a on server &b%s&a.", true), + USER_REMOVETEMPGROUP_SUCCESS("&b%s&a was removed from temproary group &b%s&a.", true), + USER_REMOVETEMPGROUP_SERVER_SUCCESS("&b%s&a was removed from temporary group &b%s&a on server &b%s&a.", true), USER_REMOVEGROUP_ERROR_PRIMARY("You cannot remove a user from their primary group.", true), USER_PRIMARYGROUP_SUCCESS("&b%s&a's primary group was set to &b%s&a.", true), USER_PRIMARYGROUP_ERROR_ALREADYHAS("The user already has this group set as their primary group.", true), @@ -156,13 +176,18 @@ public enum Message { GROUP_INFO( PREFIX + "&d-> &eGroup: &6%s" + "\n" + PREFIX + "&d-> &ePermissions: &6%s" + "\n" + + PREFIX + "&d-> &eTemporary Permissions: &6%s" + "\n" + PREFIX + "&d-> &bUse &a/%s group %s listnodes &bto see all permissions.", false ), GROUP_SETINHERIT_SUCCESS("&b%s&a now inherits permissions from &b%s&a.", true), GROUP_SETINHERIT_SERVER_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a.", true), + GROUP_SET_TEMP_INHERIT_SUCCESS("&b%s&a now inherits permissions from &b%s&a for a duration of &b%s&a.", true), + GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a for a duration of &b%s&a.", true), GROUP_UNSETINHERIT_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a.", true), GROUP_UNSETINHERIT_SERVER_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a on server &b%s&a.", true), + GROUP_UNSET_TEMP_INHERIT_SUCCESS("&b%s&a no longer temporarily inherits permissions from &b%s&a.", true), + GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS("&b%s&a no longer temporarily inherits permissions from &b%s&a on server &b%s&a.", true), TRACK_INFO( PREFIX + "&d-> &eTrack: &6%s" + "\n" + diff --git a/common/src/main/java/me/lucko/luckperms/constants/Permission.java b/common/src/main/java/me/lucko/luckperms/constants/Permission.java index 19ffd819..7e46557f 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Permission.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Permission.java @@ -29,6 +29,10 @@ public enum Permission { USER_UNSETPERMISSION("unsetpermission", PermissionGroup.USER), USER_ADDGROUP("addgroup", PermissionGroup.USER), USER_REMOVEGROUP("removegroup", PermissionGroup.USER), + USER_SET_TEMP_PERMISSION("settemppermission", PermissionGroup.USER), + USER_UNSET_TEMP_PERMISSION("unsettemppermission", PermissionGroup.USER), + USER_ADDTEMPGROUP("addtempgroup", PermissionGroup.USER), + USER_REMOVETEMPGROUP("removetempgroup", PermissionGroup.USER), USER_SETPRIMARYGROUP("setprimarygroup", PermissionGroup.USER), USER_SHOWTRACKS("showtracks", PermissionGroup.USER), USER_PROMOTE("promote", PermissionGroup.USER), @@ -44,6 +48,10 @@ public enum Permission { GROUP_UNSETPERMISSION("unsetpermission", PermissionGroup.GROUP), GROUP_SETINHERIT("setinherit", PermissionGroup.GROUP), GROUP_UNSETINHERIT("unsetinherit", PermissionGroup.GROUP), + GROUP_SET_TEMP_PERMISSION("settemppermission", PermissionGroup.GROUP), + GROUP_UNSET_TEMP_PERMISSION("unsettemppermission", PermissionGroup.GROUP), + GROUP_SET_TEMP_INHERIT("settempinherit", PermissionGroup.GROUP), + GROUP_UNSET_TEMP_INHERIT("unsettempinherit", PermissionGroup.GROUP), GROUP_SHOWTRACKS("showtracks", PermissionGroup.GROUP), GROUP_CLEAR("clear", PermissionGroup.GROUP), diff --git a/common/src/main/java/me/lucko/luckperms/users/User.java b/common/src/main/java/me/lucko/luckperms/users/User.java index 2727b55b..6b42eba7 100644 --- a/common/src/main/java/me/lucko/luckperms/users/User.java +++ b/common/src/main/java/me/lucko/luckperms/users/User.java @@ -93,6 +93,31 @@ public abstract class User extends PermissionObject { setPermission("group." + group.getName(), true, server); } + /** + * Add a user to a group on a specific server + * @param group The group to add the user to + * @param expireAt when the group should expire + * @throws ObjectAlreadyHasException if the user is already a member of the group on that server + */ + public void addGroup(Group group, long expireAt) throws ObjectAlreadyHasException { + setPermission("group." + group.getName(), true, expireAt); + } + + /** + * Add a user to a group on a specific server + * @param group The group to add the user to + * @param server The server to add the group on + * @param expireAt when the group should expire + * @throws ObjectAlreadyHasException if the user is already a member of the group on that server + */ + public void addGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException { + if (server == null) { + server = "global"; + } + + setPermission("group." + group.getName(), true, server, expireAt); + } + /** * Remove the user from a group * @param group the group to remove the user from @@ -102,6 +127,16 @@ public abstract class User extends PermissionObject { removeGroup(group, "global"); } + /** + * Remove the user from a group + * @param group the group to remove the user from + * @param temporary if the group being removed is temporary + * @throws ObjectLacksException if the user isn't a member of the group + */ + public void removeGroup(Group group, boolean temporary) throws ObjectLacksException { + removeGroup(group, "global", temporary); + } + /** * Remove the user from a group * @param group The group to remove the user from @@ -116,6 +151,21 @@ public abstract class User extends PermissionObject { unsetPermission("group." + group.getName(), server); } + /** + * Remove the user from a group + * @param group The group to remove the user from + * @param server The server to remove the group on + * @param temporary if the group being removed is temporary + * @throws ObjectLacksException if the user isn't a member of the group + */ + public void removeGroup(Group group, String server, boolean temporary) throws ObjectLacksException { + if (server == null) { + server = "global"; + } + + unsetPermission("group." + group.getName(), server, temporary); + } + /** * Clear all of the users permission nodes */ @@ -172,10 +222,10 @@ public abstract class User extends PermissionObject { final Map groupNodes = new HashMap<>(); // Sorts the permissions and puts them into a priority order - for (Map.Entry node : getNodes().entrySet()) { + for (Map.Entry node : convertTemporaryPerms().entrySet()) { serverSpecific: if (node.getKey().contains("/")) { - String[] parts = node.getKey().split("\\/", 2); + String[] parts = Patterns.SERVER_SPLIT.split(node.getKey(), 2); if (parts[0].equalsIgnoreCase("global")) { // REGULAR diff --git a/common/src/main/java/me/lucko/luckperms/utils/DateUtil.java b/common/src/main/java/me/lucko/luckperms/utils/DateUtil.java new file mode 100644 index 00000000..551f6e21 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/utils/DateUtil.java @@ -0,0 +1,170 @@ +package me.lucko.luckperms.utils; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * All credit to Essentials / EssentialsX for this class + * https://github.com/drtshock/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java + * https://github.com/essentials/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java + */ +public class DateUtil { + private static final Pattern TIME_PATTERN = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE); + private static final int MAX_YEARS = 100000; + + private DateUtil() {} + + public static boolean shouldExpire(long unixTime) { + return unixTime < (System.currentTimeMillis() / 1000); + } + + /** + * Converts a time string to a unix timestamp + * @param time the time string + * @return a unix timestamp + * @throws IllegalDateException if the date input was invalid + */ + public static long parseDateDiff(String time, boolean future) throws IllegalDateException { + Matcher m = TIME_PATTERN.matcher(time); + int years = 0; + int months = 0; + int weeks = 0; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + boolean found = false; + while (m.find()) { + if (m.group() == null || m.group().isEmpty()) { + continue; + } + for (int i = 0; i < m.groupCount(); i++) { + if (m.group(i) != null && !m.group(i).isEmpty()) { + found = true; + break; + } + } + if (found) { + if (m.group(1) != null && !m.group(1).isEmpty()) { + years = Integer.parseInt(m.group(1)); + } + if (m.group(2) != null && !m.group(2).isEmpty()) { + months = Integer.parseInt(m.group(2)); + } + if (m.group(3) != null && !m.group(3).isEmpty()) { + weeks = Integer.parseInt(m.group(3)); + } + if (m.group(4) != null && !m.group(4).isEmpty()) { + days = Integer.parseInt(m.group(4)); + } + if (m.group(5) != null && !m.group(5).isEmpty()) { + hours = Integer.parseInt(m.group(5)); + } + if (m.group(6) != null && !m.group(6).isEmpty()) { + minutes = Integer.parseInt(m.group(6)); + } + if (m.group(7) != null && !m.group(7).isEmpty()) { + seconds = Integer.parseInt(m.group(7)); + } + break; + } + } + if (!found) { + throw new IllegalDateException(); + } + Calendar c = new GregorianCalendar(); + if (years > 0) { + if (years > MAX_YEARS) { + years = MAX_YEARS; + } + c.add(Calendar.YEAR, years * (future ? 1 : -1)); + } + if (months > 0) { + c.add(Calendar.MONTH, months * (future ? 1 : -1)); + } + if (weeks > 0) { + c.add(Calendar.WEEK_OF_YEAR, weeks * (future ? 1 : -1)); + } + if (days > 0) { + c.add(Calendar.DAY_OF_MONTH, days * (future ? 1 : -1)); + } + if (hours > 0) { + c.add(Calendar.HOUR_OF_DAY, hours * (future ? 1 : -1)); + } + if (minutes > 0) { + c.add(Calendar.MINUTE, minutes * (future ? 1 : -1)); + } + if (seconds > 0) { + c.add(Calendar.SECOND, seconds * (future ? 1 : -1)); + } + Calendar max = new GregorianCalendar(); + max.add(Calendar.YEAR, 10); + if (c.after(max)) { + return (max.getTimeInMillis() / 1000) + 1; + } + return (c.getTimeInMillis() / 1000) + 1; + } + + private static int dateDiff(int type, Calendar fromDate, Calendar toDate, boolean future) { + int year = Calendar.YEAR; + + int fromYear = fromDate.get(year); + int toYear = toDate.get(year); + if (Math.abs(fromYear - toYear) > MAX_YEARS) { + toDate.set(year, fromYear + + (future ? MAX_YEARS : -MAX_YEARS)); + } + + int diff = 0; + long savedDate = fromDate.getTimeInMillis(); + while ((future && !fromDate.after(toDate)) || (!future && !fromDate.before(toDate))) { + savedDate = fromDate.getTimeInMillis(); + fromDate.add(type, future ? 1 : -1); + diff++; + } + diff--; + fromDate.setTimeInMillis(savedDate); + return diff; + } + + public static String formatDateDiff(long unixTime) { + Calendar c = new GregorianCalendar(); + c.setTimeInMillis(unixTime * 1000); + Calendar now = new GregorianCalendar(); + return DateUtil.formatDateDiff(now, c); + } + + private static String formatDateDiff(Calendar fromDate, Calendar toDate) { + boolean future = false; + if (toDate.equals(fromDate)) { + return "now"; + } + if (toDate.after(fromDate)) { + future = true; + } + StringBuilder sb = new StringBuilder(); + int[] types = new int[]{Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND}; + String[] names = new String[]{"year", "years", "month", "months", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds"}; + int accuracy = 0; + for (int i = 0; i < types.length; i++) { + if (accuracy > 2) { + break; + } + int diff = dateDiff(types[i], fromDate, toDate, future); + if (diff > 0) { + accuracy++; + sb.append(" ").append(diff).append(" ").append(names[i * 2 + (diff > 1 ? 1 : 0)]); + } + } + if (sb.length() == 0) { + return "now"; + } + return sb.toString().trim(); + } + + public static class IllegalDateException extends Exception { + + } +} \ No newline at end of file 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 f09c6dc4..03cc727d 100644 --- a/common/src/main/java/me/lucko/luckperms/utils/Patterns.java +++ b/common/src/main/java/me/lucko/luckperms/utils/Patterns.java @@ -5,6 +5,7 @@ import java.util.regex.Pattern; public class Patterns { public static final Pattern SERVER_SPLIT = Pattern.compile("\\/"); + public static final Pattern TEMP_SPLIT = Pattern.compile("\\$"); public static final Pattern DOT_SPLIT = Pattern.compile("\\."); public static final Pattern GROUP_MATCH = Pattern.compile("group\\..*"); public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[^A-Za-z0-9]"); diff --git a/common/src/main/java/me/lucko/luckperms/utils/PermissionObject.java b/common/src/main/java/me/lucko/luckperms/utils/PermissionObject.java index 71b2a49b..1c8dd49f 100644 --- a/common/src/main/java/me/lucko/luckperms/utils/PermissionObject.java +++ b/common/src/main/java/me/lucko/luckperms/utils/PermissionObject.java @@ -7,10 +7,8 @@ import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.groups.Group; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * Represents an object that can hold permissions @@ -39,7 +37,6 @@ public abstract class PermissionObject { /** * The user/group's permissions */ - @Setter private Map nodes = new HashMap<>(); protected PermissionObject(LuckPermsPlugin plugin, String objectName) { @@ -48,15 +45,43 @@ public abstract class PermissionObject { this.includeGlobalPermissions = plugin.getConfiguration().getIncludeGlobalPerms(); } + public void setNodes(Map nodes) { + this.nodes = nodes; + auditTemporaryPermissions(); + } + + /** + * Utility method for checking if a map has a certain permission. Used by both #hasPermission and #inheritsPermission + */ + private static boolean hasPermission(Map toQuery, String node, boolean b) { + // Not temporary + if (!node.contains("$")) { + return b ? toQuery.containsKey(node) && toQuery.get(node) : toQuery.containsKey(node) && !toQuery.get(node); + } + + node = Patterns.TEMP_SPLIT.split(node)[0]; + + for (Map.Entry e : toQuery.entrySet()) { + if (e.getKey().contains("$")) { + String[] parts = Patterns.TEMP_SPLIT.split(e.getKey()); + if (parts[0].equalsIgnoreCase(node)) { + return b ? e.getValue() : !e.getValue(); + } + } + } + + return false; + } + /** * Checks to see if the object has a certain permission * @param node The permission node * @param b If the node is true/false(negated) * @return true if the user has the permission */ - public boolean hasPermission(String node, Boolean b) { + public boolean hasPermission(String node, boolean b) { if (node.startsWith("global/")) node = node.replace("global/", ""); - return b ? getNodes().containsKey(node) && getNodes().get(node) : getNodes().containsKey(node) && !getNodes().get(node); + return hasPermission(getNodes(), node, b); } /** @@ -66,17 +91,28 @@ public abstract class PermissionObject { * @param server The server * @return true if the user has the permission */ - public boolean hasPermission(String node, Boolean b, String server) { + public boolean hasPermission(String node, boolean b, String server) { return hasPermission(server + "/" + node, b); } + /** + * Checks to see the the object has a permission on a certain server + * @param node The permission node + * @param b If the node is true/false(negated) + * @param temporary if the permission is temporary + * @return true if the user has the permission + */ + public boolean hasPermission(String node, boolean b, boolean temporary) { + return hasPermission(node + (temporary ? "$a" : ""), b); + } + /** * Checks to see if the object inherits a certain permission * @param node The permission node * @param b If the node is true/false(negated) * @return true if the user inherits the permission */ - public boolean inheritsPermission(String node, Boolean b) { + public boolean inheritsPermission(String node, boolean b) { if (node.contains("/")) { // Use other method final String[] parts = Patterns.SERVER_SPLIT.split(node, 2); @@ -93,9 +129,20 @@ public abstract class PermissionObject { * @param server The server * @return true if the user inherits the permission */ - public boolean inheritsPermission(String node, Boolean b, String server) { + public boolean inheritsPermission(String node, boolean b, String server) { final Map local = getLocalPermissions(server, null); - return b ? local.containsKey(node) && local.get(node) : local.containsKey(node) && !local.get(node); + return hasPermission(local, node, b); + } + + /** + * Checks to see if the object inherits a certain permission + * @param node The permission node + * @param b If the node is true/false(negated) + * @param temporary if the permission is temporary + * @return true if the user inherits the permission + */ + public boolean inheritsPermission(String node, boolean b, boolean temporary) { + return inheritsPermission(node + (temporary ? "$a" : ""), b); } /** @@ -104,7 +151,7 @@ public abstract class PermissionObject { * @param value What to set the node to - true/false(negated) * @throws ObjectAlreadyHasException if the object already has the permission */ - public void setPermission(String node, Boolean value) throws ObjectAlreadyHasException { + public void setPermission(String node, boolean value) throws ObjectAlreadyHasException { if (node.startsWith("global/")) node = node.replace("global/", ""); if (hasPermission(node, value)) { throw new ObjectAlreadyHasException(); @@ -119,21 +166,73 @@ public abstract class PermissionObject { * @param server The server to set the permission on * @throws ObjectAlreadyHasException if the object already has the permission */ - public void setPermission(String node, Boolean value, String server) throws ObjectAlreadyHasException { + public void setPermission(String node, boolean value, String server) throws ObjectAlreadyHasException { setPermission(server + "/" + node, value); } + /** + * Sets a permission for the object + * @param node The node to set + * @param value What to set the node to - true/false(negated) + * @param expireAt The time in unixtime when the permission will expire + * @throws ObjectAlreadyHasException if the object already has the permission + */ + public void setPermission(String node, boolean value, long expireAt) throws ObjectAlreadyHasException { + setPermission(node + "$" + expireAt, value); + } + + /** + * Sets a permission for the object + * @param node The node to set + * @param value What to set the node to - true/false(negated) + * @param server The server to set the permission on + * @param expireAt The time in unixtime when the permission will expire + * @throws ObjectAlreadyHasException if the object already has the permission + */ + public void setPermission(String node, boolean value, String server, long expireAt) throws ObjectAlreadyHasException { + setPermission(node + "$" + expireAt, value, server); + } + + /** + * Unsets a permission for the object + * @param node The node to be unset + * @param temporary if the permission being removed is temporary + * @throws ObjectLacksException if the node wasn't already set + */ + public void unsetPermission(String node, boolean temporary) throws ObjectLacksException { + if (node.startsWith("global/")) node = node.replace("global/", ""); + String match = null; + + if (!temporary) { + if (getNodes().containsKey(node)) { + match = node; + } + } else { + for (String n : getNodes().keySet()) { + if (n.contains("$")) { + String[] parts = Patterns.TEMP_SPLIT.split(n); + if (parts[0].equalsIgnoreCase(node)) { + match = n; + break; + } + } + } + } + + if (match != null) { + getNodes().remove(match); + } else { + throw new ObjectLacksException(); + } + } + /** * Unsets a permission for the object * @param node The node to be unset * @throws ObjectLacksException if the node wasn't already set */ public void unsetPermission(String node) throws ObjectLacksException { - if (node.startsWith("global/")) node = node.replace("global/", ""); - if (!getNodes().containsKey(node)) { - throw new ObjectLacksException(); - } - getNodes().remove(node); + unsetPermission(node, node.contains("$")); } /** @@ -146,6 +245,17 @@ public abstract class PermissionObject { unsetPermission(server + "/" + node); } + /** + * Unsets a permission for the object + * @param node The node to be unset + * @param server The server to unset the node on + * @param temporary if the permission being unset is temporary + * @throws ObjectLacksException if the node wasn't already set + */ + public void unsetPermission(String node, String server, boolean temporary) throws ObjectLacksException { + unsetPermission(server + "/" + node, temporary); + } + /** * Gets the permissions and inherited permissions that apply to a specific server * @param server The server to get nodes for @@ -156,6 +266,83 @@ public abstract class PermissionObject { return getPermissions(server, excludedGroups, includeGlobalPermissions); } + /** + * Processes the objects and returns the temporary ones. + * @return a map of temporary nodes + */ + public Map, Long> getTemporaryNodes() { + Map, Long> temps = new HashMap<>(); + + for (Map.Entry e : getNodes().entrySet()) { + if (!e.getKey().contains("$")) { + continue; + } + + String[] parts = Patterns.TEMP_SPLIT.split(e.getKey()); + final long expiry = Long.parseLong(parts[1]); + temps.put(new AbstractMap.SimpleEntry<>(parts[0], e.getValue()), expiry); + } + + return temps; + } + + /** + * Processes the objects and returns the non-temporary ones. + * @return a map of permanent nodes + */ + public Map getPermanentNodes() { + Map permas = new HashMap<>(); + + for (Map.Entry e : getNodes().entrySet()) { + if (e.getKey().contains("$")) { + continue; + } + + permas.put(e.getKey(), e.getValue()); + } + + return permas; + } + + /** + * Removes temporary permissions that have expired + * @return true if permissions had expired and had to be removed + */ + public boolean auditTemporaryPermissions() { + Set toRemove = getNodes().keySet().stream() + .filter(s -> s.contains("$")) + .filter(s -> DateUtil.shouldExpire(Long.parseLong(Patterns.TEMP_SPLIT.split(s)[1]))) + .collect(Collectors.toSet()); + toRemove.forEach(s -> getNodes().remove(s)); + return !toRemove.isEmpty(); + } + + private String stripTime(String s) { + if (s.contains("$")) { + return Patterns.TEMP_SPLIT.split(s)[0]; + } + return s; + } + + protected Map convertTemporaryPerms() { + auditTemporaryPermissions(); + + Map nodes = new HashMap<>(); + Map tempNodes = new HashMap<>(); + + for (Map.Entry e : getNodes().entrySet()) { + if (e.getKey().contains("$")) { + tempNodes.put(e.getKey(), e.getValue()); + } else { + nodes.put(e.getKey(), e.getValue()); + } + } + + // temporary permissions override non-temporary permissions + tempNodes.entrySet().forEach(e -> nodes.put(stripTime(e.getKey()), e.getValue())); + return nodes; + } + private Map getPermissions(String server, List excludedGroups, boolean includeGlobal) { if (excludedGroups == null) { excludedGroups = new ArrayList<>(); @@ -183,7 +370,7 @@ public abstract class PermissionObject { final Map groupNodes = new HashMap<>(); // Sorts the permissions and puts them into a priority order - for (Map.Entry node : getNodes().entrySet()) { + for (Map.Entry node : convertTemporaryPerms().entrySet()) { serverSpecific: if (node.getKey().contains("/")) { String[] parts = Patterns.SERVER_SPLIT.split(node.getKey(), 2); diff --git a/common/src/test/DateTest.java b/common/src/test/DateTest.java new file mode 100644 index 00000000..7fc598e1 --- /dev/null +++ b/common/src/test/DateTest.java @@ -0,0 +1,17 @@ +import me.lucko.luckperms.utils.DateUtil; + +public class DateTest { + + public static void main(String[] args) { + + try { + System.out.println("" + DateUtil.parseDateDiff("1m", true)); + System.out.println(DateUtil.formatDateDiff(DateUtil.parseDateDiff("1 hour, 1 second", true))); + + } catch (DateUtil.IllegalDateException e) { + e.printStackTrace(); + } + + } + +}