Integrate SubcommandData with CoreCommandBuilder and document it
Also made the sender type nicer in the error message
This commit is contained in:
parent
b59a090e13
commit
8f20ca9b5a
4 changed files with 79 additions and 16 deletions
|
@ -224,13 +224,24 @@ public abstract class Command2<TC extends ICommand2<TP>, TP extends Command2Send
|
||||||
&& cg.getClass() == sendertype) //The command expects a user of our system
|
&& cg.getClass() == sendertype) //The command expects a user of our system
|
||||||
params.add(cg);
|
params.add(cg);
|
||||||
else {
|
else {
|
||||||
sender.sendMessage("§cYou need to be a " + sendertype.getSimpleName() + " to use this command.");
|
String type = sendertype.getSimpleName().chars().mapToObj(ch -> Character.isUpperCase(ch)
|
||||||
|
? " " + Character.toLowerCase(ch)
|
||||||
|
: ch + "").collect(Collectors.joining());
|
||||||
|
sender.sendMessage("§cYou need to be a " + type + " to use this command.");
|
||||||
sender.sendMessage(sd.getHelpText(sender)); //Send what the command is about, could be useful for commands like /member where some subcommands aren't player-only
|
sender.sendMessage(sd.getHelpText(sender)); //Send what the command is about, could be useful for commands like /member where some subcommands aren't player-only
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a command node for the given subcommand that can be used for a custom registering logic (Discord).
|
||||||
|
*
|
||||||
|
* @param command The command object
|
||||||
|
* @param method The subcommand method
|
||||||
|
* @return The processed command node
|
||||||
|
* @throws Exception Something broke
|
||||||
|
*/
|
||||||
protected LiteralCommandNode<TP> processSubcommand(TC command, Method method) throws Exception {
|
protected LiteralCommandNode<TP> processSubcommand(TC command, Method method) throws Exception {
|
||||||
val params = new ArrayList<Object>(method.getParameterCount());
|
val params = new ArrayList<Object>(method.getParameterCount());
|
||||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||||
|
|
|
@ -1,32 +1,59 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
|
import buttondevteam.lib.chat.commands.CommandArgument;
|
||||||
|
import buttondevteam.lib.chat.commands.SubcommandData;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
|
|
||||||
public class CoreCommandBuilder<S> extends LiteralArgumentBuilder<S> {
|
import java.util.Map;
|
||||||
private String[] helpText;
|
import java.util.function.Function;
|
||||||
|
|
||||||
protected CoreCommandBuilder(String literal) {
|
public class CoreCommandBuilder<S, TC extends ICommand2<?>> extends LiteralArgumentBuilder<S> {
|
||||||
|
private final SubcommandData.SubcommandDataBuilder<TC> dataBuilder;
|
||||||
|
|
||||||
|
protected CoreCommandBuilder(String literal, Class<?> senderType, Map<String, CommandArgument> arguments, TC command) {
|
||||||
super(literal);
|
super(literal);
|
||||||
|
dataBuilder = SubcommandData.<TC>builder().senderType(senderType).arguments(arguments).command(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CoreCommandBuilder<S> getThis() {
|
protected CoreCommandBuilder<S, TC> getThis() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <S> CoreCommandBuilder<S> literal(String name) {
|
public static <S, TC extends ICommand2<?>> CoreCommandBuilder<S, TC> literal(String name, Class<?> senderType, Map<String, CommandArgument> arguments, TC command) {
|
||||||
return new CoreCommandBuilder<>(name);
|
return new CoreCommandBuilder<>(name, senderType, arguments, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CoreCommandBuilder<S> helps(String[] helpText) {
|
/**
|
||||||
this.helpText = helpText;
|
* Static help text added through annotations. May be overwritten with the getter.
|
||||||
|
*
|
||||||
|
* @param helpText Help text shown to the user
|
||||||
|
* @return This instance
|
||||||
|
*/
|
||||||
|
public CoreCommandBuilder<S, TC> helps(String[] helpText) {
|
||||||
|
dataBuilder.staticHelpText(helpText);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom help text that depends on the context. Overwrites the static one.
|
||||||
|
* The function receives the sender but its type is not guaranteed to match the one at the subcommand.
|
||||||
|
* It will either match or be a Command2Sender, however.
|
||||||
|
*
|
||||||
|
* @param getter The getter function receiving the sender and returning the help text
|
||||||
|
* @return This instance
|
||||||
|
*/
|
||||||
|
public CoreCommandBuilder<S, TC> helps(Function<Object, String[]> getter) {
|
||||||
|
dataBuilder.helpTextGetter(getter);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CoreCommandNode<S> build() {
|
public CoreCommandNode<S, TC> build() {
|
||||||
var result = new CoreCommandNode<>(this.getLiteral(), this.getCommand(), this.getRequirement(), this.getRedirect(), this.getRedirectModifier(), this.isFork(), helpText);
|
var result = new CoreCommandNode<>(this.getLiteral(), this.getCommand(), this.getRequirement(),
|
||||||
|
this.getRedirect(), this.getRedirectModifier(), this.isFork(),
|
||||||
|
dataBuilder.build());
|
||||||
|
|
||||||
for (CommandNode<S> node : this.getArguments()) {
|
for (CommandNode<S> node : this.getArguments()) {
|
||||||
result.addChild(node);
|
result.addChild(node);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
|
import buttondevteam.lib.chat.commands.SubcommandData;
|
||||||
import com.mojang.brigadier.Command;
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.RedirectModifier;
|
import com.mojang.brigadier.RedirectModifier;
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
|
@ -8,12 +9,12 @@ import lombok.Getter;
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class CoreCommandNode<T> extends LiteralCommandNode<T> {
|
public class CoreCommandNode<T, TC extends ICommand2<?>> extends LiteralCommandNode<T> {
|
||||||
@Getter
|
@Getter
|
||||||
private final String[] helpText;
|
private final SubcommandData<TC> data;
|
||||||
|
|
||||||
public CoreCommandNode(String literal, Command<T> command, Predicate<T> requirement, CommandNode<T> redirect, RedirectModifier<T> modifier, boolean forks, String[] helpText) {
|
public CoreCommandNode(String literal, Command<T> command, Predicate<T> requirement, CommandNode<T> redirect, RedirectModifier<T> modifier, boolean forks, SubcommandData<TC> data) {
|
||||||
super(literal, command, requirement, redirect, modifier, forks);
|
super(literal, command, requirement, redirect, modifier, forks);
|
||||||
this.helpText = helpText;
|
this.data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,34 @@
|
||||||
package buttondevteam.lib.chat.commands;
|
package buttondevteam.lib.chat.commands;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.ICommand2;
|
import buttondevteam.lib.chat.ICommand2;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores information about the subcommand that can be used to construct the Brigadier setup and to get information while executing the command.
|
||||||
|
*
|
||||||
|
* @param <TC> Command class type
|
||||||
|
*/
|
||||||
|
@Builder
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class SubcommandData<TC extends ICommand2<?>> {
|
public final class SubcommandData<TC extends ICommand2<?>> {
|
||||||
// The actual sender type may not be represented by Command2Sender (TP)
|
/**
|
||||||
|
* The type of the sender running the command.
|
||||||
|
* The actual sender type may not be represented by Command2Sender (TP).
|
||||||
|
* In that case it has to match the expected type.
|
||||||
|
*/
|
||||||
public final Class<?> senderType;
|
public final Class<?> senderType;
|
||||||
|
/**
|
||||||
|
* Command arguments collected from the subcommand method.
|
||||||
|
* Used to construct the arguments for Brigadier and to hold extra information.
|
||||||
|
*/
|
||||||
public final Map<String, CommandArgument> arguments;
|
public final Map<String, CommandArgument> arguments;
|
||||||
|
/**
|
||||||
|
* The original command class that this data belongs to.
|
||||||
|
*/
|
||||||
public final TC command;
|
public final TC command;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +42,12 @@ public final class SubcommandData<TC extends ICommand2<?>> {
|
||||||
*/
|
*/
|
||||||
private final Function<Object, String[]> helpTextGetter;
|
private final Function<Object, String[]> helpTextGetter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get help text for this subcommand.
|
||||||
|
*
|
||||||
|
* @param sender The sender running the command
|
||||||
|
* @return Help text shown to the user
|
||||||
|
*/
|
||||||
public String[] getHelpText(Object sender) {
|
public String[] getHelpText(Object sender) {
|
||||||
return staticHelpText == null ? helpTextGetter.apply(sender) : staticHelpText;
|
return staticHelpText == null ? helpTextGetter.apply(sender) : staticHelpText;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue