mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-31 21:48:08 +01:00
Initial command syntaxes tree attempt
This commit is contained in:
parent
22eb5c6bcd
commit
dfcf908abc
@ -1,11 +1,10 @@
|
||||
package net.minestom.server.command.builder;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.command.builder.arguments.Argument;
|
||||
import net.minestom.server.command.builder.arguments.ArgumentDynamicStringArray;
|
||||
import net.minestom.server.command.builder.arguments.ArgumentDynamicWord;
|
||||
import net.minestom.server.command.builder.arguments.ArgumentType;
|
||||
import net.minestom.server.command.builder.arguments.*;
|
||||
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
|
||||
import net.minestom.server.command.builder.condition.CommandCondition;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -15,6 +14,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
@ -330,6 +331,78 @@ public class Command {
|
||||
return syntaxes;
|
||||
}
|
||||
|
||||
@Beta
|
||||
public @NotNull String getSyntaxesTree() {
|
||||
Node commandNode = new Node();
|
||||
commandNode.names.addAll(Arrays.asList(getNames()));
|
||||
|
||||
// current node, literal = returned node
|
||||
BiFunction<Node, Set<String>, Node> findNode = (currentNode, literals) -> {
|
||||
|
||||
for (Node node : currentNode.nodes) {
|
||||
final var names = node.names;
|
||||
|
||||
// Verify if at least one literal is shared
|
||||
final boolean shared = names.stream().anyMatch(literals::contains);
|
||||
if (shared) {
|
||||
names.addAll(literals);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new node
|
||||
Node node = new Node();
|
||||
node.names.addAll(literals);
|
||||
currentNode.nodes.add(node);
|
||||
return node;
|
||||
};
|
||||
|
||||
BiConsumer<CommandSyntax, Node> syntaxProcessor = (syntax, node) -> {
|
||||
List<String> arguments = new ArrayList<>();
|
||||
BiConsumer<Node, List<String>> addArguments = (n, args) -> {
|
||||
if (!args.isEmpty()) {
|
||||
n.arguments.add(args);
|
||||
}
|
||||
};
|
||||
|
||||
for (Argument<?> argument : syntax.getArguments()) {
|
||||
if (argument instanceof ArgumentLiteral) {
|
||||
final String literal = argument.getId();
|
||||
|
||||
addArguments.accept(node, arguments);
|
||||
arguments = new ArrayList<>();
|
||||
|
||||
node = findNode.apply(node, Collections.singleton(literal));
|
||||
} else if (argument instanceof ArgumentWord) {
|
||||
ArgumentWord argumentWord = (ArgumentWord) argument;
|
||||
if (argumentWord.hasRestrictions()) {
|
||||
|
||||
addArguments.accept(node, arguments);
|
||||
arguments = new ArrayList<>();
|
||||
|
||||
node = findNode.apply(node, Set.of(argumentWord.getRestrictions()));
|
||||
}
|
||||
} else {
|
||||
arguments.add(argument.toString());
|
||||
}
|
||||
}
|
||||
addArguments.accept(node, arguments);
|
||||
};
|
||||
|
||||
// Subcommands
|
||||
this.subcommands.forEach(command -> {
|
||||
final Node node = findNode.apply(commandNode, Set.of(command.getNames()));
|
||||
command.getSyntaxes().forEach(syntax -> syntaxProcessor.accept(syntax, node));
|
||||
});
|
||||
|
||||
// Syntaxes
|
||||
this.syntaxes.forEach(syntax -> syntaxProcessor.accept(syntax, commandNode));
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
processNode(commandNode, jsonObject);
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
public static boolean isValidName(@NotNull Command command, @NotNull String name) {
|
||||
for (String commandName : command.getNames()) {
|
||||
if (commandName.equals(name)) {
|
||||
@ -339,4 +412,40 @@ public class Command {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processNode(@NotNull Node node, @NotNull JsonObject jsonObject) {
|
||||
BiConsumer<String, Consumer<JsonArray>> processor = (s, consumer) -> {
|
||||
JsonArray array = new JsonArray();
|
||||
consumer.accept(array);
|
||||
if (array.size() != 0) {
|
||||
jsonObject.add(s, array);
|
||||
}
|
||||
};
|
||||
|
||||
// Names
|
||||
{
|
||||
processor.accept("names", array -> node.names.forEach(array::add));
|
||||
}
|
||||
// Nodes
|
||||
{
|
||||
processor.accept("nodes", array ->
|
||||
node.nodes.forEach(n -> {
|
||||
JsonObject nodeObject = new JsonObject();
|
||||
processNode(n, nodeObject);
|
||||
array.add(nodeObject);
|
||||
}));
|
||||
}
|
||||
// Arguments
|
||||
{
|
||||
processor.accept("arguments", array ->
|
||||
node.arguments.forEach(arguments ->
|
||||
array.add(String.join(StringUtils.SPACE, arguments))));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Node {
|
||||
private final Set<String> names = new HashSet<>();
|
||||
private final Set<Node> nodes = new HashSet<>();
|
||||
private final List<List<String>> arguments = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user