From 8f20ca9b5aa0e475f844df75a86f59672270be50 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 29 Oct 2022 22:29:01 +0200 Subject: [PATCH] Integrate SubcommandData with CoreCommandBuilder and document it Also made the sender type nicer in the error message --- .../java/buttondevteam/lib/chat/Command2.java | 13 ++++- .../lib/chat/CoreCommandBuilder.java | 47 +++++++++++++++---- .../lib/chat/CoreCommandNode.java | 9 ++-- .../lib/chat/commands/SubcommandData.java | 26 +++++++++- 4 files changed, 79 insertions(+), 16 deletions(-) diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java index cccc4fb..d27c571 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.java @@ -224,13 +224,24 @@ public abstract class Command2, TP extends Command2Send && cg.getClass() == sendertype) //The command expects a user of our system params.add(cg); 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 return true; } 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 processSubcommand(TC command, Method method) throws Exception { val params = new ArrayList(method.getParameterCount()); Class[] parameterTypes = method.getParameterTypes(); diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandBuilder.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandBuilder.java index cade3e1..5bb97e9 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandBuilder.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandBuilder.java @@ -1,32 +1,59 @@ 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.tree.CommandNode; -public class CoreCommandBuilder extends LiteralArgumentBuilder { - private String[] helpText; +import java.util.Map; +import java.util.function.Function; - protected CoreCommandBuilder(String literal) { +public class CoreCommandBuilder> extends LiteralArgumentBuilder { + private final SubcommandData.SubcommandDataBuilder dataBuilder; + + protected CoreCommandBuilder(String literal, Class senderType, Map arguments, TC command) { super(literal); + dataBuilder = SubcommandData.builder().senderType(senderType).arguments(arguments).command(command); } @Override - protected CoreCommandBuilder getThis() { + protected CoreCommandBuilder getThis() { return this; } - public static CoreCommandBuilder literal(String name) { - return new CoreCommandBuilder<>(name); + public static > CoreCommandBuilder literal(String name, Class senderType, Map arguments, TC command) { + return new CoreCommandBuilder<>(name, senderType, arguments, command); } - public CoreCommandBuilder 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 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 helps(Function getter) { + dataBuilder.helpTextGetter(getter); return this; } @Override - public CoreCommandNode build() { - var result = new CoreCommandNode<>(this.getLiteral(), this.getCommand(), this.getRequirement(), this.getRedirect(), this.getRedirectModifier(), this.isFork(), helpText); + public CoreCommandNode build() { + var result = new CoreCommandNode<>(this.getLiteral(), this.getCommand(), this.getRequirement(), + this.getRedirect(), this.getRedirectModifier(), this.isFork(), + dataBuilder.build()); for (CommandNode node : this.getArguments()) { result.addChild(node); diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandNode.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandNode.java index 8cffd67..ca5d07e 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandNode.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/CoreCommandNode.java @@ -1,5 +1,6 @@ package buttondevteam.lib.chat; +import buttondevteam.lib.chat.commands.SubcommandData; import com.mojang.brigadier.Command; import com.mojang.brigadier.RedirectModifier; import com.mojang.brigadier.tree.CommandNode; @@ -8,12 +9,12 @@ import lombok.Getter; import java.util.function.Predicate; -public class CoreCommandNode extends LiteralCommandNode { +public class CoreCommandNode> extends LiteralCommandNode { @Getter - private final String[] helpText; + private final SubcommandData data; - public CoreCommandNode(String literal, Command command, Predicate requirement, CommandNode redirect, RedirectModifier modifier, boolean forks, String[] helpText) { + public CoreCommandNode(String literal, Command command, Predicate requirement, CommandNode redirect, RedirectModifier modifier, boolean forks, SubcommandData data) { super(literal, command, requirement, redirect, modifier, forks); - this.helpText = helpText; + this.data = data; } } diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/SubcommandData.java b/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/SubcommandData.java index 4715c75..63d3829 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/SubcommandData.java +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/SubcommandData.java @@ -1,16 +1,34 @@ package buttondevteam.lib.chat.commands; import buttondevteam.lib.chat.ICommand2; +import lombok.Builder; import lombok.RequiredArgsConstructor; import java.util.Map; 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 Command class type + */ +@Builder @RequiredArgsConstructor public final class SubcommandData> { - // 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; + /** + * Command arguments collected from the subcommand method. + * Used to construct the arguments for Brigadier and to hold extra information. + */ public final Map arguments; + /** + * The original command class that this data belongs to. + */ public final TC command; /** @@ -24,6 +42,12 @@ public final class SubcommandData> { */ private final Function 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) { return staticHelpText == null ? helpTextGetter.apply(sender) : staticHelpText; }