Improve & consolidate permission check commands

This commit is contained in:
Luck 2021-01-13 16:40:57 +00:00
parent 489c09ddfc
commit c904ede972
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
10 changed files with 215 additions and 267 deletions

View File

@ -29,11 +29,6 @@ luckperms {
search {
permission brigadier:string quotable_phrase;
}
check {
user brigadier:string single_word {
permission brigadier:string quotable_phrase;
}
}
networksync;
import {
file brigadier:string quotable_phrase;
@ -114,14 +109,7 @@ luckperms {
}
}
check {
node brigadier:string quotable_phrase {
context brigadier:string greedy_phrase;
}
}
checkinherits {
node brigadier:string quotable_phrase {
context brigadier:string greedy_phrase;
}
node brigadier:string quotable_phrase;
}
clear {
context brigadier:string greedy_phrase;
@ -362,14 +350,7 @@ luckperms {
}
}
check {
node brigadier:string quotable_phrase {
context brigadier:string greedy_phrase;
}
}
checkinherits {
node brigadier:string quotable_phrase {
context brigadier:string greedy_phrase;
}
node brigadier:string quotable_phrase;
}
clear {
context brigadier:string greedy_phrase;

View File

@ -40,7 +40,6 @@ import me.lucko.luckperms.common.commands.group.ListGroups;
import me.lucko.luckperms.common.commands.log.LogParentCommand;
import me.lucko.luckperms.common.commands.misc.ApplyEditsCommand;
import me.lucko.luckperms.common.commands.misc.BulkUpdateCommand;
import me.lucko.luckperms.common.commands.misc.CheckCommand;
import me.lucko.luckperms.common.commands.misc.EditorCommand;
import me.lucko.luckperms.common.commands.misc.ExportCommand;
import me.lucko.luckperms.common.commands.misc.ImportCommand;
@ -107,7 +106,6 @@ public class CommandManager {
.add(new VerboseCommand())
.add(new TreeCommand())
.add(new SearchCommand())
.add(new CheckCommand())
.add(new NetworkSyncCommand())
.add(new ImportCommand())
.add(new ExportCommand())

View File

@ -39,7 +39,6 @@ public enum CommandPermission {
VERBOSE_COMMAND_OTHERS("verbose.command.others", Type.NONE),
TREE("tree", Type.NONE),
SEARCH("search", Type.NONE),
CHECK("check", Type.NONE),
IMPORT("import", Type.NONE),
EXPORT("export", Type.NONE),
RELOAD_CONFIG("reloadconfig", Type.NONE),
@ -62,7 +61,6 @@ public enum CommandPermission {
USER_PERM_SET_TEMP("permission.settemp", Type.USER),
USER_PERM_UNSET_TEMP("permission.unsettemp", Type.USER),
USER_PERM_CHECK("permission.check", Type.USER),
USER_PERM_CHECK_INHERITS("permission.checkinherits", Type.USER),
USER_PERM_CLEAR("permission.clear", Type.USER),
USER_PARENT_INFO("parent.info", Type.USER),
USER_PARENT_SET("parent.set", Type.USER),
@ -106,7 +104,6 @@ public enum CommandPermission {
GROUP_PERM_SET_TEMP("permission.settemp", Type.GROUP),
GROUP_PERM_UNSET_TEMP("permission.unsettemp", Type.GROUP),
GROUP_PERM_CHECK("permission.check", Type.GROUP),
GROUP_PERM_CHECK_INHERITS("permission.checkinherits", Type.GROUP),
GROUP_PERM_CLEAR("permission.clear", Type.GROUP),
GROUP_PARENT_INFO("parent.info", Type.GROUP),
GROUP_PARENT_SET("parent.set", Type.GROUP),

View File

@ -62,10 +62,6 @@ public enum CommandSpec {
arg("permission", true),
arg("page", false)
),
CHECK("/%s check <user> <permission>",
arg("user", true),
arg("permission", true)
),
NETWORK_SYNC("/%s networksync"),
IMPORT("/%s import <file>",
arg("file", true),
@ -184,12 +180,7 @@ public enum CommandSpec {
arg("context...", false)
),
PERMISSION_CHECK(
arg("node", true),
arg("context...", false)
),
PERMISSION_CHECK_INHERITS(
arg("node", true),
arg("context...", false)
arg("node", true)
),
PERMISSION_CLEAR(
arg("context...", false)

View File

@ -42,7 +42,6 @@ public class CommandPermission<T extends PermissionHolder> extends GenericParent
.add(new PermissionSetTemp())
.add(new PermissionUnsetTemp())
.add(new PermissionCheck())
.add(new PermissionCheckInherits())
.add(new PermissionClear())
.build());
}

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.generic.permission;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.command.CommandResult;
import me.lucko.luckperms.common.command.abstraction.CommandException;
import me.lucko.luckperms.common.command.abstraction.GenericChildCommand;
@ -36,16 +37,22 @@ import me.lucko.luckperms.common.command.tabcomplete.TabCompletions;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.node.factory.NodeBuilders;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import net.luckperms.api.context.MutableContextSet;
import net.luckperms.api.model.data.DataType;
import net.luckperms.api.node.NodeEqualityPredicate;
import net.kyori.adventure.text.Component;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.PermissionHolder.Identifier;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import net.luckperms.api.node.types.RegexPermissionNode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import java.util.ArrayList;
import java.util.List;
public class PermissionCheck extends GenericChildCommand {
@ -61,10 +68,77 @@ public class PermissionCheck extends GenericChildCommand {
}
String node = args.get(0);
MutableContextSet context = args.getContextOrDefault(1, plugin);
Tristate result = target.hasNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(node).withContext(context).build(), NodeEqualityPredicate.IGNORE_VALUE_OR_IF_TEMPORARY);
Message.CHECK_PERMISSION.send(sender, target, node, result, context);
// accumulate nodes
List<Node> own = new ArrayList<>();
List<Node> inherited = new ArrayList<>();
List<Node> resolved = target.resolveInheritedNodes(QueryOptionsImpl.DEFAULT_NON_CONTEXTUAL);
for (Node n : resolved) {
if (!matches(node, n)) {
continue;
}
Identifier origin = n.getMetadata(InheritanceOriginMetadata.KEY)
.map(InheritanceOriginMetadata::getOrigin)
.orElse(null);
if (origin == null || target.getIdentifier().equals(origin)) {
own.add(n);
} else {
inherited.add(n);
}
}
// send results
Message.PERMISSION_CHECK_INFO_HEADER.send(sender, node);
if (own.isEmpty()) {
Message.PERMISSION_CHECK_INFO_NOT_DIRECTLY.send(sender, target, node);
} else {
for (Node n : own) {
Message.PERMISSION_CHECK_INFO_DIRECTLY.send(sender, target, node, Tristate.of(n.getValue()), n.getContexts());
}
}
if (inherited.isEmpty()) {
Message.PERMISSION_CHECK_INFO_NOT_INHERITED.send(sender, target, node);
} else {
for (Node n : inherited) {
String origin = n.metadata(InheritanceOriginMetadata.KEY).getOrigin().getName();
Message.PERMISSION_CHECK_INFO_INHERITED.send(sender, target, node, Tristate.of(n.getValue()), n.getContexts(), origin);
}
}
// blank line
sender.sendMessage(Message.prefixed(Component.empty()));
// perform a "real" check
QueryOptions queryOptions = target.getQueryOptions();
TristateResult checkResult = target.getCachedData().getPermissionData(queryOptions).checkPermission(node, PermissionCheckEvent.Origin.INTERNAL);
Tristate result = checkResult.result();
String processor;
String cause;
ImmutableContextSet context = queryOptions.context();
if (result != Tristate.UNDEFINED) {
Class<?> processorClass = checkResult.processorClass();
if (processorClass.getName().startsWith("me.lucko.luckperms.")) {
String simpleName = processorClass.getSimpleName();
String platform = processorClass.getName().split("\\.")[3];
processor = platform + "." + simpleName;
} else {
processor = processorClass.getName();
}
cause = checkResult.cause();
} else {
processor = null;
cause = null;
}
// send results
Message.PERMISSION_CHECK_RESULT.send(sender, node, result, processor, cause, context);
return CommandResult.SUCCESS;
}
@ -72,7 +146,12 @@ public class PermissionCheck extends GenericChildCommand {
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, ArgumentList args) {
return TabCompleter.create()
.at(0, TabCompletions.permissions(plugin))
.from(1, TabCompletions.contexts(plugin))
.complete(args);
}
private static boolean matches(String permission, Node node) {
return node.getKey().equals(permission) ||
node.resolveShorthand().contains(permission) ||
node instanceof RegexPermissionNode && ((RegexPermissionNode) node).getPattern().map(p -> p.matcher(permission).matches()).orElse(false);
}
}

View File

@ -1,89 +0,0 @@
/*
* 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.common.command.CommandResult;
import me.lucko.luckperms.common.command.abstraction.CommandException;
import me.lucko.luckperms.common.command.abstraction.GenericChildCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.command.tabcomplete.TabCompleter;
import me.lucko.luckperms.common.command.tabcomplete.TabCompletions;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import net.luckperms.api.context.MutableContextSet;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import net.luckperms.api.util.Tristate;
import java.util.List;
import java.util.Optional;
public class PermissionCheckInherits extends GenericChildCommand {
public PermissionCheckInherits() {
super(CommandSpec.PERMISSION_CHECK_INHERITS, "checkinherits", CommandPermission.USER_PERM_CHECK_INHERITS, CommandPermission.GROUP_PERM_CHECK_INHERITS, Predicates.is(0));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder target, ArgumentList args, String label, CommandPermission permission) throws CommandException {
if (ArgumentPermissions.checkViewPerms(plugin, sender, permission, target)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return CommandResult.NO_PERMISSION;
}
String node = args.get(0);
MutableContextSet context = args.getContextOrDefault(1, plugin);
Optional<Node> match = target.resolveInheritedNodes(QueryOptionsImpl.DEFAULT_NON_CONTEXTUAL).stream()
.filter(n -> n.getKey().equalsIgnoreCase(node) && n.getContexts().equals(context))
.findFirst();
String location = match.map(n -> n.metadata(InheritanceOriginMetadata.KEY).getOrigin().getName()).orElse(null);
if (location == null || location.equalsIgnoreCase(target.getObjectName())) {
location = "self";
}
Tristate result = match.map(n -> Tristate.of(n.getValue())).orElse(Tristate.UNDEFINED);
Message.CHECK_INHERITS_PERMISSION.send(sender, target, node, result, context, location);
return CommandResult.SUCCESS;
}
@Override
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, ArgumentList args) {
return TabCompleter.create()
.at(0, TabCompletions.permissions(plugin))
.from(1, TabCompletions.contexts(plugin))
.complete(args);
}
}

View File

@ -1,84 +0,0 @@
/*
* 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.misc;
import me.lucko.luckperms.common.command.CommandResult;
import me.lucko.luckperms.common.command.abstraction.SingleCommand;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.command.tabcomplete.CompletionSupplier;
import me.lucko.luckperms.common.command.tabcomplete.TabCompleter;
import me.lucko.luckperms.common.command.tabcomplete.TabCompletions;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.util.Uuids;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import net.luckperms.api.util.Tristate;
import java.util.List;
import java.util.UUID;
public class CheckCommand extends SingleCommand {
public CheckCommand() {
super(CommandSpec.CHECK, "Check", CommandPermission.CHECK, Predicates.not(2));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, ArgumentList args, String label) {
String target = args.get(0);
String permission = args.get(1);
User user;
UUID u = Uuids.parse(target);
if (u != null) {
user = plugin.getUserManager().getIfLoaded(u);
} else {
user = plugin.getUserManager().getByUsername(target);
}
if (user == null) {
Message.USER_NOT_ONLINE.send(sender, target);
return CommandResult.STATE_ERROR;
}
Tristate tristate = user.getCachedData().getPermissionData(user.getQueryOptions()).checkPermission(permission, PermissionCheckEvent.Origin.INTERNAL).result();
Message.CHECK_RESULT.send(sender, user, permission, tristate);
return CommandResult.SUCCESS;
}
@Override
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, ArgumentList args) {
return TabCompleter.create()
.at(0, CompletionSupplier.startsWith(() -> plugin.getBootstrap().getPlayerList().stream()))
.at(1, TabCompletions.permissions(plugin))
.complete(args);
}
}

View File

@ -1044,18 +1044,6 @@ public interface Message {
.append(FULL_STOP)
);
Args3<User, String, Tristate> CHECK_RESULT = (user, permission, result) -> prefixed(translatable()
// "&aPermission check result on user &b{}&a for permission &b{}&a: &f{}"
.color(GREEN)
.key("luckperms.command.check.result")
.args(
text().color(AQUA).append(user.getFormattedDisplayName()),
text(permission, AQUA)
)
.append(text(": "))
.append(formatTristate(result))
);
Args1<Component> CREATE_SUCCESS = name -> prefixed(translatable()
// "&b{}&a was successfully created."
.color(GREEN)
@ -1727,41 +1715,129 @@ public interface Message {
.append(FULL_STOP)
);
Args4<PermissionHolder, String, Tristate, ContextSet> CHECK_PERMISSION = (holder, permission, value, context) -> prefixed(translatable()
// "&b{}&a has permission &b{}&a set to {}&a in context {}&a."
.key("luckperms.command.generic.permission.check-inherits")
Args1<String> PERMISSION_CHECK_INFO_HEADER = permission -> prefixed(translatable()
// &aPermission information for &b{}&a:
.key("luckperms.command.generic.permission.check.info.title")
.color(GREEN)
.args(
text().color(AQUA).append(holder.getFormattedDisplayName()),
text(permission, AQUA),
formatTristate(value),
formatContextSet(context)
)
.append(FULL_STOP)
.args(text(permission, AQUA))
.append(text(':'))
);
Args5<PermissionHolder, String, Tristate, ContextSet, String> CHECK_INHERITS_PERMISSION = (holder, permission, value, context, inheritedFrom) -> prefixed(translatable()
// "&b{}&a has permission &b{}&a set to {}&a in context {}&a. &7(inherited from &a{}&7)"
.key("luckperms.command.generic.permission.check-inherits")
.color(GREEN)
.args(
text().color(AQUA).append(holder.getFormattedDisplayName()),
text(permission, AQUA),
formatTristate(value),
formatContextSet(context)
)
.append(FULL_STOP)
Args4<PermissionHolder, String, Tristate, ContextSet> PERMISSION_CHECK_INFO_DIRECTLY = (holder, permission, value, context) -> prefixed(text()
// &f- &b{}&3 has &b{}&3 set to {}&3 in context {}&3.
.append(text('-', WHITE))
.append(space())
.append(text()
.append(translatable()
.key("luckperms.command.generic.permission.check.info.directly")
.color(GRAY)
.append(OPEN_BRACKET)
.append(translatable("luckperms.command.generic.info.inherited-from"))
.append(space())
.append(text(inheritedFrom, GREEN))
.append(CLOSE_BRACKET)
.args(
text().color(AQUA).append(holder.getFormattedDisplayName()),
text(permission, AQUA),
formatTristate(value),
formatContextSet(context)
)
.append(FULL_STOP)
)
);
Args5<PermissionHolder, String, Tristate, ContextSet, String> PERMISSION_CHECK_INFO_INHERITED = (holder, permission, value, context, inheritedFrom) -> prefixed(text()
// &f- &b{}&3 inherits &b{}&3 set to {}&3 from &a{}&3 in context {}&3.
.append(text('-', WHITE))
.append(space())
.append(translatable()
.key("luckperms.command.generic.permission.check.info.inherited")
.color(GRAY)
.args(
text().color(AQUA).append(holder.getFormattedDisplayName()),
text(permission, AQUA),
formatTristate(value),
text(inheritedFrom, GREEN),
formatContextSet(context)
)
.append(FULL_STOP)
)
);
Args2<PermissionHolder, String> PERMISSION_CHECK_INFO_NOT_DIRECTLY = (holder, permission) -> prefixed(text()
// &f- &b{}&3 does not have &b{}&3 set.
.append(text('-', WHITE))
.append(space())
.append(translatable()
.key("luckperms.command.generic.permission.check.info.not-directly")
.color(GRAY)
.args(
text().color(AQUA).append(holder.getFormattedDisplayName()),
text(permission, AQUA)
)
.append(FULL_STOP)
)
);
Args2<PermissionHolder, String> PERMISSION_CHECK_INFO_NOT_INHERITED = (holder, permission) -> prefixed(text()
// &f- &b{}&3 does not inherit &b{}&3.
.append(text('-', WHITE))
.append(space())
.append(translatable()
.key("luckperms.command.generic.permission.check.info.not-inherited")
.color(GRAY)
.args(
text().color(AQUA).append(holder.getFormattedDisplayName()),
text(permission, AQUA)
)
.append(FULL_STOP)
)
);
Args5<String, Tristate, String, String, ContextSet> PERMISSION_CHECK_RESULT = (permission, result, processor, cause, context) -> join(newline(),
// &aPermission check for &b{}&a:
// &3Result: {}
// &3Processor: &f{}
// &3Cause: &f{}
// &3Context: {}
prefixed(translatable()
.key("luckperms.command.generic.permission.check.result.title")
.color(GREEN)
.args(text(permission, AQUA))
.append(text(':'))),
prefixed(text()
.color(DARK_AQUA)
.append(text(" "))
.append(translatable("luckperms.command.generic.permission.check.result.result-key"))
.append(text(": "))
.append(formatTristate(result))),
prefixed(text()
.color(DARK_AQUA)
.append(text(" "))
.append(translatable("luckperms.command.generic.permission.check.result.processor-key"))
.append(text(": "))
.apply(builder -> {
if (processor == null) {
builder.append(translatable("luckperms.command.misc.none", AQUA));
} else {
builder.append(text(processor, WHITE));
}
})),
prefixed(text()
.color(DARK_AQUA)
.append(text(" "))
.append(translatable("luckperms.command.generic.permission.check.result.cause-key"))
.append(text(": "))
.apply(builder -> {
if (cause == null) {
builder.append(translatable("luckperms.command.misc.none", AQUA));
} else {
builder.append(text(cause, WHITE));
}
})),
prefixed(text()
.color(DARK_AQUA)
.append(text(" "))
.append(translatable("luckperms.command.generic.permission.check.result.context-key"))
.append(text(": "))
.append(formatContextSetBracketed(context, translatable("luckperms.command.misc.none", AQUA))))
);
Args4<String, Boolean, PermissionHolder, ContextSet> SETPERMISSION_SUCCESS = (permission, value, holder, context) -> prefixed(translatable()
// "&aSet &b{}&a to &b{}&a for &b{}&a in context {}&a."
.key("luckperms.command.generic.permission.set")

View File

@ -78,7 +78,6 @@ luckperms.command.misc.loading.error.all-tracks=Unable to load all tracks
luckperms.command.misc.loading.error.track-not-found=A track named {0} could not be found
luckperms.command.misc.loading.error.track-save-error=There was an error whilst saving track data for {0}
luckperms.command.misc.loading.error.track-invalid={0} is not a valid track name
luckperms.command.check.result=Permission check result on user {0} for permission {1}
luckperms.command.editor.no-match=Unable to open editor, no objects matched the desired type
luckperms.command.editor.start=Preparing a new editor session, please wait...
luckperms.command.editor.url=Click the link below to open the editor
@ -155,8 +154,16 @@ luckperms.command.generic.clear={0}''s nodes were cleared in context {1}
luckperms.command.generic.permission.info.title={0}''s Permissions
luckperms.command.generic.permission.info.empty={0} does not have any permissions set
luckperms.command.generic.permission.info.click-to-remove=Click to remove this node from {0}
luckperms.command.generic.permission.check={0} has permission {1} set to {2} in context {3}
luckperms.command.generic.permission.check-inherits={0} has permission {1} set to {2} in context {3}
luckperms.command.generic.permission.check.info.title=Permission information for {0}
luckperms.command.generic.permission.check.info.directly={0} has {1} set to {2} in context {3}
luckperms.command.generic.permission.check.info.inherited={0} inherits {1} set to {2} from {3} in context {4}
luckperms.command.generic.permission.check.info.not-directly={0} does not have {1} set
luckperms.command.generic.permission.check.info.not-inherited={0} does not inherit {1}
luckperms.command.generic.permission.check.result.title=Permission check for {0}
luckperms.command.generic.permission.check.result.result-key=Result
luckperms.command.generic.permission.check.result.processor-key=Processor
luckperms.command.generic.permission.check.result.cause-key=Cause
luckperms.command.generic.permission.check.result.context-key=Context
luckperms.command.generic.permission.set=Set {0} to {1} for {2} in context {3}
luckperms.command.generic.permission.already-has={0} already has {1} set in context {2}
luckperms.command.generic.permission.set-temp=Set {0} to {1} for {2} for a duration of {3} in context {4}
@ -364,9 +371,6 @@ luckperms.usage.tree.argument.player=the name of an online player to check again
luckperms.usage.search.description=Searchs for all of the users/groups with a specific permission
luckperms.usage.search.argument.permission=the permission to search for
luckperms.usage.search.argument.page=the page to view
luckperms.usage.check.description=Performs a ''mock'' permission check for an online player
luckperms.usage.check.argument.user=the user to check
luckperms.usage.check.argument.permission=the permission to check for
luckperms.usage.network-sync.description=Sync changes with the storage and request that all other servers on the network do the same
luckperms.usage.import.description=Imports data from a (previously created) export file
luckperms.usage.import.argument.file=the file to import from
@ -455,10 +459,6 @@ luckperms.usage.permission-unsettemp.argument.duration=the duration to subtract
luckperms.usage.permission-unsettemp.argument.context=the contexts to remove the permission in
luckperms.usage.permission-check.description=Checks to see if the object has a certain permission node
luckperms.usage.permission-check.argument.node=the permission node to check for
luckperms.usage.permission-check.argument.context=the contexts to check in
luckperms.usage.permission-check-inherits.description=Checks to see if the object inherits a certain permission node
luckperms.usage.permission-check-inherits.argument.node=the permission node to check for
luckperms.usage.permission-check-inherits.argument.context=the contexts to check in
luckperms.usage.permission-clear.description=Clears all permissions
luckperms.usage.permission-clear.argument.context=the contexts to filter by
luckperms.usage.parent-info.description=Lists the groups that this object inherits from