Add 'permission clear' command (#893)
This commit is contained in:
parent
96f0f46b3e
commit
f5c6b9e3d4
@ -291,6 +291,14 @@ public interface Node {
|
||||
@Nonnull
|
||||
ContextSet getFullContexts();
|
||||
|
||||
/**
|
||||
* Returns if the node is a "standard" permission node.
|
||||
*
|
||||
* @return true if this is a regular permission node
|
||||
* @since 4.2
|
||||
*/
|
||||
boolean isRegularPermissionNode();
|
||||
|
||||
/**
|
||||
* Returns if this is a group node.
|
||||
*
|
||||
|
@ -70,6 +70,7 @@ public enum CommandPermission {
|
||||
USER_PERM_UNSET_TEMP("permission.unsettemp", USER),
|
||||
USER_PERM_CHECK("permission.check", USER),
|
||||
USER_PERM_CHECK_INHERITS("permission.checkinherits", USER),
|
||||
USER_PERM_CLEAR("permission.clear", USER),
|
||||
USER_PARENT_INFO("parent.info", USER),
|
||||
USER_PARENT_SET("parent.set", USER),
|
||||
USER_PARENT_SET_TRACK("parent.settrack", USER),
|
||||
@ -109,6 +110,7 @@ public enum CommandPermission {
|
||||
GROUP_PERM_UNSET_TEMP("permission.unsettemp", GROUP),
|
||||
GROUP_PERM_CHECK("permission.check", GROUP),
|
||||
GROUP_PERM_CHECK_INHERITS("permission.checkinherits", GROUP),
|
||||
GROUP_PERM_CLEAR("permission.clear", GROUP),
|
||||
GROUP_PARENT_INFO("parent.info", GROUP),
|
||||
GROUP_PARENT_SET("parent.set", GROUP),
|
||||
GROUP_PARENT_SET_TRACK("parent.settrack", GROUP),
|
||||
|
@ -43,6 +43,7 @@ public class CommandPermission<T extends PermissionHolder> extends SharedMainCom
|
||||
.add(new PermissionUnsetTemp(locale))
|
||||
.add(new PermissionCheck(locale))
|
||||
.add(new PermissionCheckInherits(locale))
|
||||
.add(new PermissionClear(locale))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.commands.generic.permission;
|
||||
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
|
||||
import me.lucko.luckperms.common.command.CommandResult;
|
||||
import me.lucko.luckperms.common.command.abstraction.CommandException;
|
||||
import me.lucko.luckperms.common.command.abstraction.SharedSubCommand;
|
||||
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.command.utils.ArgumentParser;
|
||||
import me.lucko.luckperms.common.command.utils.MessageUtils;
|
||||
import me.lucko.luckperms.common.command.utils.StorageAssistant;
|
||||
import me.lucko.luckperms.common.locale.LocaleManager;
|
||||
import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PermissionClear extends SharedSubCommand {
|
||||
public PermissionClear(LocaleManager locale) {
|
||||
super(CommandSpec.PERMISSION_CLEAR.localize(locale), "clear", CommandPermission.USER_PERM_CLEAR, CommandPermission.GROUP_PERM_CLEAR, Predicates.alwaysFalse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label, CommandPermission permission) throws CommandException {
|
||||
if (ArgumentPermissions.checkModifyPerms(plugin, sender, permission, holder)) {
|
||||
Message.COMMAND_NO_PERMISSION.send(sender);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
int before = holder.getEnduringNodes().size();
|
||||
|
||||
MutableContextSet context = ArgumentParser.parseContext(0, args, plugin);
|
||||
|
||||
if (ArgumentPermissions.checkContext(plugin, sender, permission, context)) {
|
||||
Message.COMMAND_NO_PERMISSION.send(sender);
|
||||
return CommandResult.NO_PERMISSION;
|
||||
}
|
||||
|
||||
if (context.isEmpty()) {
|
||||
holder.clearPermissions();
|
||||
} else {
|
||||
holder.clearPermissions(context);
|
||||
}
|
||||
|
||||
int changed = before - holder.getEnduringNodes().size();
|
||||
if (changed == 1) {
|
||||
Message.PERMISSION_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), MessageUtils.contextSetToString(context), changed);
|
||||
} else {
|
||||
Message.PERMISSION_CLEAR_SUCCESS.send(sender, holder.getFriendlyName(), MessageUtils.contextSetToString(context), changed);
|
||||
}
|
||||
|
||||
ExtendedLogEntry.build().actor(sender).acted(holder)
|
||||
.action("permission", "clear", context)
|
||||
.build().submit(plugin, sender);
|
||||
|
||||
StorageAssistant.save(holder, sender, plugin);
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
}
|
@ -240,6 +240,11 @@ public enum CommandSpec {
|
||||
Argument.create("context...", false, "the contexts to check in")
|
||||
)
|
||||
),
|
||||
PERMISSION_CLEAR("Clears all permissions",
|
||||
Argument.list(
|
||||
Argument.create("context...", false, "the contexts to filter by")
|
||||
)
|
||||
),
|
||||
|
||||
PARENT_INFO("Lists the groups that this object inherits from",
|
||||
Argument.list(
|
||||
|
@ -245,8 +245,10 @@ public enum Message {
|
||||
UNSET_INHERIT_SUCCESS("&b{}&a no longer inherits permissions from &b{}&a in context {}&a.", true),
|
||||
UNSET_TEMP_INHERIT_SUCCESS("&b{}&a no longer temporarily inherits permissions from &b{}&a in context {}&a.", true),
|
||||
|
||||
CLEAR_SUCCESS("&b{}&a's permissions were cleared in context {}&a. (&b{}&a nodes were removed.)", true),
|
||||
CLEAR_SUCCESS_SINGULAR("&b{}&a's permissions were cleared in context {}&a. (&b{}&a node was removed.)", true),
|
||||
CLEAR_SUCCESS("&b{}&a's nodes were cleared in context {}&a. (&b{}&a nodes were removed.)", true),
|
||||
CLEAR_SUCCESS_SINGULAR("&b{}&a's nodes were cleared in context {}&a. (&b{}&a node was removed.)", true),
|
||||
PERMISSION_CLEAR_SUCCESS("&b{}&a's permissions were cleared in context {}&a. (&b{}&a nodes were removed.)", true),
|
||||
PERMISSION_CLEAR_SUCCESS_SINGULAR("&b{}&a's permissions were cleared in context {}&a. (&b{}&a node was removed.)", true),
|
||||
PARENT_CLEAR_SUCCESS("&b{}&a's parents were cleared in context {}&a. (&b{}&a nodes were removed.)", true),
|
||||
PARENT_CLEAR_SUCCESS_SINGULAR("&b{}&a's parents were cleared in context {}&a. (&b{}&a node was removed.)", true),
|
||||
|
||||
|
@ -330,10 +330,36 @@ public abstract class PermissionHolder {
|
||||
}
|
||||
|
||||
public boolean removeIf(Predicate<Node> predicate) {
|
||||
return removeIf(predicate, null);
|
||||
}
|
||||
|
||||
public boolean removeIf(Predicate<Node> predicate, Runnable taskIfSuccess) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
if (!this.enduringNodes.removeIf(predicate)) {
|
||||
return false;
|
||||
}
|
||||
if (taskIfSuccess != null) {
|
||||
taskIfSuccess.run();
|
||||
}
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeIf(ContextSet contextSet, Predicate<Node> predicate) {
|
||||
return removeIf(contextSet, predicate, null);
|
||||
}
|
||||
|
||||
public boolean removeIf(ContextSet contextSet, Predicate<Node> predicate, Runnable taskIfSuccess) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
if (!this.enduringNodes.removeIf(contextSet, predicate)) {
|
||||
return false;
|
||||
}
|
||||
if (taskIfSuccess != null) {
|
||||
taskIfSuccess.run();
|
||||
}
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
@ -820,86 +846,44 @@ public abstract class PermissionHolder {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean clearParents(boolean giveDefault) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
|
||||
if (!this.enduringNodes.removeIf(Node::isGroupNode)) {
|
||||
return false;
|
||||
public boolean clearPermissions() {
|
||||
return removeIf(Node::isRegularPermissionNode);
|
||||
}
|
||||
|
||||
public boolean clearPermissions(ContextSet contextSet) {
|
||||
return removeIf(contextSet, Node::isRegularPermissionNode);
|
||||
}
|
||||
|
||||
public boolean clearParents(boolean giveDefault) {
|
||||
return removeIf(Node::isGroupNode, () -> {
|
||||
if (this.getType().isUser() && giveDefault) {
|
||||
this.plugin.getUserManager().giveDefaultIfNeeded((User) this, false);
|
||||
}
|
||||
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean clearParents(ContextSet contextSet, boolean giveDefault) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
|
||||
if (!this.enduringNodes.removeIf(contextSet, Node::isGroupNode)) {
|
||||
return false;
|
||||
}
|
||||
return removeIf(contextSet, Node::isGroupNode, () -> {
|
||||
if (this.getType().isUser() && giveDefault) {
|
||||
this.plugin.getUserManager().giveDefaultIfNeeded((User) this, false);
|
||||
}
|
||||
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean clearMeta(MetaType type) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
if (!this.enduringNodes.removeIf(type::matches)) {
|
||||
return false;
|
||||
}
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
return removeIf(type::matches);
|
||||
}
|
||||
|
||||
public boolean clearMeta(MetaType type, ContextSet contextSet) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
if (!this.enduringNodes.removeIf(contextSet, type::matches)) {
|
||||
return false;
|
||||
}
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
return removeIf(contextSet, type::matches);
|
||||
}
|
||||
|
||||
public boolean clearMetaKeys(String key, boolean temp) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
if (!this.enduringNodes.removeIf(n -> n.isMeta() && (n.isTemporary() == temp) && n.getMeta().getKey().equalsIgnoreCase(key))) {
|
||||
return false;
|
||||
}
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
return removeIf(n -> n.isMeta() && (n.isTemporary() == temp) && n.getMeta().getKey().equalsIgnoreCase(key));
|
||||
}
|
||||
|
||||
public boolean clearMetaKeys(String key, ContextSet contextSet, boolean temp) {
|
||||
ImmutableCollection<Node> before = getEnduringNodes().values();
|
||||
if (!this.enduringNodes.removeIf(contextSet, n -> n.isMeta() && (n.isTemporary() == temp) && n.getMeta().getKey().equalsIgnoreCase(key))) {
|
||||
return false;
|
||||
}
|
||||
invalidateCache();
|
||||
ImmutableCollection<Node> after = getEnduringNodes().values();
|
||||
|
||||
this.plugin.getEventFactory().handleNodeClear(this, before, after);
|
||||
return true;
|
||||
return removeIf(contextSet, n -> n.isMeta() && (n.isTemporary() == temp) && n.getMeta().getKey().equalsIgnoreCase(key));
|
||||
}
|
||||
|
||||
public boolean clearTransientNodes() {
|
||||
|
@ -171,6 +171,11 @@ public abstract class ForwardingNode implements Node {
|
||||
return delegate().getFullContexts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegularPermissionNode() {
|
||||
return delegate().isRegularPermissionNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupNode() {
|
||||
return delegate().isGroupNode();
|
||||
|
@ -255,6 +255,11 @@ public final class ImmutableNode implements Node {
|
||||
return isTemporary() && this.expireAt < System.currentTimeMillis() / 1000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegularPermissionNode() {
|
||||
return !isGroupNode() && !isPrefix() && !isSuffix() && !isMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupNode() {
|
||||
return this.groupName != null;
|
||||
|
Loading…
Reference in New Issue
Block a user