Respect permissions in help queries

This commit is contained in:
jmp 2020-10-05 12:55:11 -07:00 committed by Josh Taylor
parent 7fee9546e5
commit b37706fd97
2 changed files with 35 additions and 8 deletions

View file

@ -26,6 +26,7 @@ package cloud.commandframework;
import cloud.commandframework.arguments.CommandArgument; import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.StaticArgument; import cloud.commandframework.arguments.StaticArgument;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -133,12 +134,27 @@ public final class CommandHelpHandler<C> {
* @return Help topic, will return an empty {@link IndexHelpTopic} if no results were found * @return Help topic, will return an empty {@link IndexHelpTopic} if no results were found
*/ */
public @NonNull HelpTopic<C> queryHelp(final @NonNull String query) { public @NonNull HelpTopic<C> queryHelp(final @NonNull String query) {
return this.queryHelp(null, query);
}
/**
* Query for help
*
* @param recipient The recipient of this help query to check permissions against (if Non-Null)
* @param query Query string
* @return Help topic, will return an empty {@link IndexHelpTopic} if no results were found
*/
public @NonNull HelpTopic<C> queryHelp(final @Nullable C recipient,
final @NonNull String query) {
final List<VerboseHelpEntry<C>> commands = this.getAllCommands();
commands.removeIf(command -> recipient != null && !this.commandManager.hasPermission(recipient,
command.getCommand()
.getCommandPermission()));
if (query.replace(" ", "").isEmpty()) { if (query.replace(" ", "").isEmpty()) {
return new IndexHelpTopic<>(this.getAllCommands()); return new IndexHelpTopic<>(commands);
} }
final String[] queryFragments = query.split(" "); final String[] queryFragments = query.split(" ");
final List<VerboseHelpEntry<C>> verboseEntries = this.getAllCommands();
final String rootFragment = queryFragments[0]; final String rootFragment = queryFragments[0];
/* Determine which command we are querying for */ /* Determine which command we are querying for */
@ -147,7 +163,7 @@ public final class CommandHelpHandler<C> {
boolean exactMatch = false; boolean exactMatch = false;
for (final VerboseHelpEntry<C> entry : verboseEntries) { for (final VerboseHelpEntry<C> entry : commands) {
final Command<C> command = entry.getCommand(); final Command<C> command = entry.getCommand();
@SuppressWarnings("unchecked") final StaticArgument<C> staticArgument = (StaticArgument<C>) command.getArguments() @SuppressWarnings("unchecked") final StaticArgument<C> staticArgument = (StaticArgument<C>) command.getArguments()
.get(0); .get(0);
@ -189,6 +205,8 @@ public final class CommandHelpHandler<C> {
description)); description));
} }
syntaxHints.sort(Comparator.comparing(VerboseHelpEntry::getSyntaxString)); syntaxHints.sort(Comparator.comparing(VerboseHelpEntry::getSyntaxString));
syntaxHints.removeIf(command -> recipient != null
&& !this.commandManager.hasPermission(recipient, command.getCommand().getCommandPermission()));
return new IndexHelpTopic<>(syntaxHints); return new IndexHelpTopic<>(syntaxHints);
} }
@ -207,9 +225,13 @@ public final class CommandHelpHandler<C> {
if (head.getValue() != null && head.getValue().getOwningCommand() != null) { if (head.getValue() != null && head.getValue().getOwningCommand() != null) {
if (head.isLeaf() || index == queryFragments.length) { if (head.isLeaf() || index == queryFragments.length) {
if (recipient == null || this.commandManager.hasPermission(recipient, head.getValue()
.getOwningCommand()
.getCommandPermission())) {
return new VerboseHelpTopic<>(head.getValue().getOwningCommand()); return new VerboseHelpTopic<>(head.getValue().getOwningCommand());
} }
} }
}
if (head.getChildren().size() == 1) { if (head.getChildren().size() == 1) {
head = head.getChildren().get(0); head = head.getChildren().get(0);
@ -235,9 +257,15 @@ public final class CommandHelpHandler<C> {
final List<String> childSuggestions = new LinkedList<>(); final List<String> childSuggestions = new LinkedList<>();
for (final CommandTree.Node<CommandArgument<C, ?>> child : head.getChildren()) { for (final CommandTree.Node<CommandArgument<C, ?>> child : head.getChildren()) {
final List<CommandArgument<C, ?>> traversedNodesSub = new LinkedList<>(traversedNodes); final List<CommandArgument<C, ?>> traversedNodesSub = new LinkedList<>(traversedNodes);
if (recipient == null
|| child.getValue() == null
|| child.getValue().getOwningCommand() == null
|| this.commandManager.hasPermission(recipient,
child.getValue().getOwningCommand().getCommandPermission())) {
traversedNodesSub.add(child.getValue()); traversedNodesSub.add(child.getValue());
childSuggestions.add(this.commandManager.getCommandSyntaxFormatter().apply(traversedNodesSub, child)); childSuggestions.add(this.commandManager.getCommandSyntaxFormatter().apply(traversedNodesSub, child));
} }
}
return new MultiHelpTopic<>(currentDescription, childSuggestions); return new MultiHelpTopic<>(currentDescription, childSuggestions);
} }
} }
@ -258,7 +286,6 @@ public final class CommandHelpHandler<C> {
* *
* @param <C> Command sender type * @param <C> Command sender type
*/ */
@SuppressWarnings("unused")
public interface HelpTopic<C> { public interface HelpTopic<C> {
} }

View file

@ -153,7 +153,7 @@ public final class MinecraftHelp<C> {
final @NonNull C recipient) { final @NonNull C recipient) {
final Audience audience = this.getAudience(recipient); final Audience audience = this.getAudience(recipient);
audience.sendMessage(this.miniMessage.parse(this.messageMap.get(MESSAGE_HELP_HEADER))); audience.sendMessage(this.miniMessage.parse(this.messageMap.get(MESSAGE_HELP_HEADER)));
this.printTopic(recipient, query, this.commandManager.getCommandHelpHandler().queryHelp(query)); this.printTopic(recipient, query, this.commandManager.getCommandHelpHandler().queryHelp(recipient, query));
audience.sendMessage(this.miniMessage.parse(this.messageMap.get(MESSAGE_HELP_FOOTER))); audience.sendMessage(this.miniMessage.parse(this.messageMap.get(MESSAGE_HELP_FOOTER)));
} }