From ffdeadac8a97ab3f906ebfb61d54d3db09954e98 Mon Sep 17 00:00:00 2001 From: Luck Date: Wed, 5 Sep 2018 15:15:15 +0100 Subject: [PATCH] Add flag to prevent users from being added/removed to/from the first group on a track (#1151) --- .../common/api/delegates/model/ApiTrack.java | 4 ++-- .../luckperms/common/commands/user/UserDemote.java | 9 ++++++++- .../common/commands/user/UserPromote.java | 9 ++++++++- .../common/locale/command/CommandSpec.java | 6 ++++-- .../luckperms/common/locale/message/Message.java | 2 ++ .../me/lucko/luckperms/common/model/Track.java | 14 +++++++++++--- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiTrack.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiTrack.java index 98371fd78..bc996e48b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiTrack.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiTrack.java @@ -98,13 +98,13 @@ public final class ApiTrack implements me.lucko.luckperms.api.Track { @Nonnull @Override public PromotionResult promote(@Nonnull User user, @Nonnull ContextSet contextSet) { - return this.handle.promote(ApiUser.cast(user), contextSet, Predicates.alwaysTrue(), null); + return this.handle.promote(ApiUser.cast(user), contextSet, Predicates.alwaysTrue(), null, true); } @Nonnull @Override public DemotionResult demote(@Nonnull User user, @Nonnull ContextSet contextSet) { - return this.handle.demote(ApiUser.cast(user), contextSet, Predicates.alwaysTrue(), null); + return this.handle.demote(ApiUser.cast(user), contextSet, Predicates.alwaysTrue(), null, true); } @Nonnull diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserDemote.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserDemote.java index f29fb4a68..f5ec0f4fd 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserDemote.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserDemote.java @@ -62,6 +62,8 @@ public class UserDemote extends SubCommand { return CommandResult.NO_PERMISSION; } + boolean removeFromFirst = !args.remove("--dont-remove-from-first"); + final String trackName = args.get(0).toLowerCase(); if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) { Message.TRACK_INVALID_ENTRY.send(sender, trackName); @@ -86,7 +88,7 @@ public class UserDemote extends SubCommand { return CommandResult.NO_PERMISSION; } - DemotionResult result = track.demote(user, context, s -> !ArgumentPermissions.checkArguments(plugin, sender, getPermission().get(), track.getName(), s), sender); + DemotionResult result = track.demote(user, context, s -> !ArgumentPermissions.checkArguments(plugin, sender, getPermission().get(), track.getName(), s), sender, removeFromFirst); switch (result.getStatus()) { case NOT_ON_TRACK: Message.USER_TRACK_ERROR_NOT_CONTAIN_GROUP.send(sender, user.getFriendlyName(), track.getName()); @@ -102,6 +104,11 @@ public class UserDemote extends SubCommand { return CommandResult.LOADING_ERROR; case REMOVED_FROM_FIRST_GROUP: { + if (!removeFromFirst && !result.getGroupFrom().isPresent()) { + Message.USER_DEMOTE_ENDOFTRACK_NOT_REMOVED.send(sender, track.getName(), user.getFriendlyName()); + return CommandResult.STATE_ERROR; + } + Message.USER_DEMOTE_ENDOFTRACK.send(sender, track.getName(), user.getFriendlyName(), result.getGroupFrom().get()); ExtendedLogEntry.build().actor(sender).acted(user) diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserPromote.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserPromote.java index 77d029950..861942696 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserPromote.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserPromote.java @@ -62,6 +62,8 @@ public class UserPromote extends SubCommand { return CommandResult.NO_PERMISSION; } + boolean addToFirst = !args.remove("--dont-add-to-first"); + final String trackName = args.get(0).toLowerCase(); if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) { Message.TRACK_INVALID_ENTRY.send(sender, trackName); @@ -86,7 +88,7 @@ public class UserPromote extends SubCommand { return CommandResult.NO_PERMISSION; } - PromotionResult result = track.promote(user, context, s -> !ArgumentPermissions.checkArguments(plugin, sender, getPermission().get(), track.getName(), s), sender); + PromotionResult result = track.promote(user, context, s -> !ArgumentPermissions.checkArguments(plugin, sender, getPermission().get(), track.getName(), s), sender, addToFirst); switch (result.getStatus()) { case MALFORMED_TRACK: Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, result.getGroupTo().get()); @@ -102,6 +104,11 @@ public class UserPromote extends SubCommand { return CommandResult.STATE_ERROR; case ADDED_TO_FIRST_GROUP: { + if (!addToFirst && !result.getGroupTo().isPresent()) { + Message.USER_PROMOTE_NOT_ON_TRACK.send(sender, track.getName(), user.getFriendlyName()); + return CommandResult.STATE_ERROR; + } + Message.USER_TRACK_ADDED_TO_FIRST.send(sender, user.getFriendlyName(), result.getGroupTo().get(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)); ExtendedLogEntry.build().actor(sender).acted(user) diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java b/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java index c2b36852f..0f89a2518 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java @@ -148,13 +148,15 @@ public enum CommandSpec { USER_PROMOTE("Promotes the user up a track", Argument.list( Argument.create("track", true, "the track to promote the user up"), - Argument.create("context...", false, "the contexts to promote the user in") + Argument.create("context...", false, "the contexts to promote the user in"), + Argument.create("--dont-add-to-first", false, "only promote the user if they're already on the track") ) ), USER_DEMOTE("Demotes the user down a track", Argument.list( Argument.create("track", true, "the track to demote the user down"), - Argument.create("context...", false, "the contexts to demote the user in") + Argument.create("context...", false, "the contexts to demote the user in"), + Argument.create("--dont-remove-from-first", false, "prevent the user from being removed from the first group") ) ), USER_CLONE("Clone the user", diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java index 9ef0cc21c..dccc6da90 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java @@ -374,6 +374,7 @@ public enum Message { USER_TRACK_ERROR_NOT_CONTAIN_GROUP("&b{}&a isn't already in any groups on &b{}&a.", true), USER_TRACK_ADDED_TO_FIRST("&b{}&a isn't in any groups on this track, so they were added to the first group, &b{}&a in context {}&a.", true), + USER_PROMOTE_NOT_ON_TRACK("&b{}&a isn't in any groups on this track, so was not promoted.", true), USER_PROMOTE_SUCCESS("&aPromoting &b{}&a along track &b{}&a from &b{}&a to &b{}&a in context {}&a.", true), USER_PROMOTE_ERROR_ENDOFTRACK("&aThe end of track &b{}&a was reached. Unable to promote &b{}&a.", true), @@ -384,6 +385,7 @@ public enum Message { ), USER_DEMOTE_SUCCESS("&aDemoting &b{}&a along track &b{}&a from &b{}&a to &b{}&a in context {}&a.", true), USER_DEMOTE_ENDOFTRACK("&aThe end of track &b{}&a was reached, so &b{}&a was removed from &b{}&a.", true), + USER_DEMOTE_ENDOFTRACK_NOT_REMOVED("&aThe end of track &b{}&a was reached, but &b{}&a was not removed from the first group.", true), USER_DEMOTE_ERROR_MALFORMED( "{PREFIX}&aThe previous group on the track, &b{}&a, no longer exists. Unable to demote user." + "\n" + "{PREFIX}&aEither create the group, or remove it from the track and try again.", diff --git a/common/src/main/java/me/lucko/luckperms/common/model/Track.java b/common/src/main/java/me/lucko/luckperms/common/model/Track.java index aeb0e1e3f..e40d66c7d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/Track.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/Track.java @@ -270,7 +270,7 @@ public final class Track implements Identifiable { this.plugin.getEventFactory().handleTrackClear(this, before); } - public PromotionResult promote(User user, ContextSet context, Predicate nextGroupPermissionChecker, @Nullable Sender sender) { + public PromotionResult promote(User user, ContextSet context, Predicate nextGroupPermissionChecker, @Nullable Sender sender, boolean addToFirst) { if (getSize() <= 1) { throw new IllegalStateException("Track contains one or fewer groups, unable to promote"); } @@ -284,6 +284,10 @@ public final class Track implements Identifiable { .collect(Collectors.toList()); if (nodes.isEmpty()) { + if (!addToFirst) { + return PromotionResults.addedToFirst(null); + } + String first = getGroups().get(0); Group nextGroup = this.plugin.getGroupManager().getIfLoaded(first); @@ -332,7 +336,7 @@ public final class Track implements Identifiable { return PromotionResults.success(old, nextGroup.getName()); } - public DemotionResult demote(User user, ContextSet context, Predicate previousGroupPermissionChecker, @Nullable Sender sender) { + public DemotionResult demote(User user, ContextSet context, Predicate previousGroupPermissionChecker, @Nullable Sender sender, boolean removeFromFirst) { if (getSize() <= 1) { throw new IllegalStateException("Track contains one or fewer groups, unable to demote"); } @@ -340,7 +344,7 @@ public final class Track implements Identifiable { // find all groups that are inherited by the user in the exact contexts given and applicable to this track List nodes = user.enduringData().immutable().get(context.makeImmutable()).stream() .filter(Node::isGroupNode) - .filter(node -> node.getValue()) + .filter(Node::getValue) .filter(node -> containsGroup(node.getGroupName())) .distinct() .collect(Collectors.toList()); @@ -362,6 +366,10 @@ public final class Track implements Identifiable { } if (previous == null) { + if (!removeFromFirst) { + return DemotionResults.removedFromFirst(null); + } + user.unsetPermission(oldNode); this.plugin.getEventFactory().handleUserDemote(user, this, old, null, sender); return DemotionResults.removedFromFirst(old);