Add flag to prevent users from being added/removed to/from the first group on a track (#1151)

This commit is contained in:
Luck 2018-09-05 15:15:15 +01:00
parent 9e769904bf
commit ffdeadac8a
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 35 additions and 9 deletions

View File

@ -98,13 +98,13 @@ public final class ApiTrack implements me.lucko.luckperms.api.Track {
@Nonnull @Nonnull
@Override @Override
public PromotionResult promote(@Nonnull User user, @Nonnull ContextSet contextSet) { 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 @Nonnull
@Override @Override
public DemotionResult demote(@Nonnull User user, @Nonnull ContextSet contextSet) { 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 @Nonnull

View File

@ -62,6 +62,8 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.NO_PERMISSION; return CommandResult.NO_PERMISSION;
} }
boolean removeFromFirst = !args.remove("--dont-remove-from-first");
final String trackName = args.get(0).toLowerCase(); final String trackName = args.get(0).toLowerCase();
if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) { if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) {
Message.TRACK_INVALID_ENTRY.send(sender, trackName); Message.TRACK_INVALID_ENTRY.send(sender, trackName);
@ -86,7 +88,7 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.NO_PERMISSION; 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()) { switch (result.getStatus()) {
case NOT_ON_TRACK: case NOT_ON_TRACK:
Message.USER_TRACK_ERROR_NOT_CONTAIN_GROUP.send(sender, user.getFriendlyName(), track.getName()); Message.USER_TRACK_ERROR_NOT_CONTAIN_GROUP.send(sender, user.getFriendlyName(), track.getName());
@ -102,6 +104,11 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.LOADING_ERROR; return CommandResult.LOADING_ERROR;
case REMOVED_FROM_FIRST_GROUP: { 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()); Message.USER_DEMOTE_ENDOFTRACK.send(sender, track.getName(), user.getFriendlyName(), result.getGroupFrom().get());
ExtendedLogEntry.build().actor(sender).acted(user) ExtendedLogEntry.build().actor(sender).acted(user)

View File

@ -62,6 +62,8 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.NO_PERMISSION; return CommandResult.NO_PERMISSION;
} }
boolean addToFirst = !args.remove("--dont-add-to-first");
final String trackName = args.get(0).toLowerCase(); final String trackName = args.get(0).toLowerCase();
if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) { if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) {
Message.TRACK_INVALID_ENTRY.send(sender, trackName); Message.TRACK_INVALID_ENTRY.send(sender, trackName);
@ -86,7 +88,7 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.NO_PERMISSION; 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()) { switch (result.getStatus()) {
case MALFORMED_TRACK: case MALFORMED_TRACK:
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, result.getGroupTo().get()); Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, result.getGroupTo().get());
@ -102,6 +104,11 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.STATE_ERROR; return CommandResult.STATE_ERROR;
case ADDED_TO_FIRST_GROUP: { 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)); Message.USER_TRACK_ADDED_TO_FIRST.send(sender, user.getFriendlyName(), result.getGroupTo().get(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
ExtendedLogEntry.build().actor(sender).acted(user) ExtendedLogEntry.build().actor(sender).acted(user)

View File

@ -148,13 +148,15 @@ public enum CommandSpec {
USER_PROMOTE("Promotes the user up a track", USER_PROMOTE("Promotes the user up a track",
Argument.list( Argument.list(
Argument.create("track", true, "the track to promote the user up"), 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", USER_DEMOTE("Demotes the user down a track",
Argument.list( Argument.list(
Argument.create("track", true, "the track to demote the user down"), 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", USER_CLONE("Clone the user",

View File

@ -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_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_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_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), 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_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("&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( USER_DEMOTE_ERROR_MALFORMED(
"{PREFIX}&aThe previous group on the track, &b{}&a, no longer exists. Unable to demote user." + "\n" + "{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.", "{PREFIX}&aEither create the group, or remove it from the track and try again.",

View File

@ -270,7 +270,7 @@ public final class Track implements Identifiable<String> {
this.plugin.getEventFactory().handleTrackClear(this, before); this.plugin.getEventFactory().handleTrackClear(this, before);
} }
public PromotionResult promote(User user, ContextSet context, Predicate<String> nextGroupPermissionChecker, @Nullable Sender sender) { public PromotionResult promote(User user, ContextSet context, Predicate<String> nextGroupPermissionChecker, @Nullable Sender sender, boolean addToFirst) {
if (getSize() <= 1) { if (getSize() <= 1) {
throw new IllegalStateException("Track contains one or fewer groups, unable to promote"); throw new IllegalStateException("Track contains one or fewer groups, unable to promote");
} }
@ -284,6 +284,10 @@ public final class Track implements Identifiable<String> {
.collect(Collectors.toList()); .collect(Collectors.toList());
if (nodes.isEmpty()) { if (nodes.isEmpty()) {
if (!addToFirst) {
return PromotionResults.addedToFirst(null);
}
String first = getGroups().get(0); String first = getGroups().get(0);
Group nextGroup = this.plugin.getGroupManager().getIfLoaded(first); Group nextGroup = this.plugin.getGroupManager().getIfLoaded(first);
@ -332,7 +336,7 @@ public final class Track implements Identifiable<String> {
return PromotionResults.success(old, nextGroup.getName()); return PromotionResults.success(old, nextGroup.getName());
} }
public DemotionResult demote(User user, ContextSet context, Predicate<String> previousGroupPermissionChecker, @Nullable Sender sender) { public DemotionResult demote(User user, ContextSet context, Predicate<String> previousGroupPermissionChecker, @Nullable Sender sender, boolean removeFromFirst) {
if (getSize() <= 1) { if (getSize() <= 1) {
throw new IllegalStateException("Track contains one or fewer groups, unable to demote"); throw new IllegalStateException("Track contains one or fewer groups, unable to demote");
} }
@ -340,7 +344,7 @@ public final class Track implements Identifiable<String> {
// find all groups that are inherited by the user in the exact contexts given and applicable to this track // find all groups that are inherited by the user in the exact contexts given and applicable to this track
List<Node> nodes = user.enduringData().immutable().get(context.makeImmutable()).stream() List<Node> nodes = user.enduringData().immutable().get(context.makeImmutable()).stream()
.filter(Node::isGroupNode) .filter(Node::isGroupNode)
.filter(node -> node.getValue()) .filter(Node::getValue)
.filter(node -> containsGroup(node.getGroupName())) .filter(node -> containsGroup(node.getGroupName()))
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -362,6 +366,10 @@ public final class Track implements Identifiable<String> {
} }
if (previous == null) { if (previous == null) {
if (!removeFromFirst) {
return DemotionResults.removedFromFirst(null);
}
user.unsetPermission(oldNode); user.unsetPermission(oldNode);
this.plugin.getEventFactory().handleUserDemote(user, this, old, null, sender); this.plugin.getEventFactory().handleUserDemote(user, this, old, null, sender);
return DemotionResults.removedFromFirst(old); return DemotionResults.removedFromFirst(old);