# Source code
source: package: co.aikar.commands, class: ACFBrigadierManager

    001package co.aikar.commands;
    002
    003import com.mojang.brigadier.Command;
    004import com.mojang.brigadier.arguments.ArgumentType;
    005import com.mojang.brigadier.arguments.BoolArgumentType;
    006import com.mojang.brigadier.arguments.DoubleArgumentType;
    007import com.mojang.brigadier.arguments.FloatArgumentType;
    008import com.mojang.brigadier.arguments.IntegerArgumentType;
    009import com.mojang.brigadier.arguments.StringArgumentType;
    010import com.mojang.brigadier.builder.LiteralArgumentBuilder;
    011import com.mojang.brigadier.builder.RequiredArgumentBuilder;
    012import com.mojang.brigadier.suggestion.SuggestionProvider;
    013import com.mojang.brigadier.tree.CommandNode;
    014import com.mojang.brigadier.tree.LiteralCommandNode;
    015
    016import java.util.HashMap;
    017import java.util.Map;
    018import java.util.function.BiPredicate;
    019import java.util.function.Predicate;
    020
    021/**
    022 * Handles registering of commands into brigadier
    023 *
    024 * @param <S>
    025 * @author MiniDigger
    026 * @deprecated Unstable API
    027 */
    028@Deprecated
    029@UnstableAPI
    030public class ACFBrigadierManager<S> {
    031
    032    protected final CommandManager<?, ?, ?, ?, ?, ?> manager;
    033
    034    private final Map<Class<?>, ArgumentType<?>> arguments = new HashMap<>();
    035
    036    /**
    037     * Constructs a new brigadier manager, utilizing the currently active command manager
    038     *
    039     * @param manager
    040     */
    041    ACFBrigadierManager(CommandManager<?, ?, ?, ?, ?, ?> manager) {
    042        manager.verifyUnstableAPI("brigadier");
    043
    044        this.manager = manager;
    045
    046        // TODO support stuff like min max via brigadier?
    047        registerArgument(String.class, StringArgumentType.word());
    048        registerArgument(float.class, FloatArgumentType.floatArg());
    049        registerArgument(Float.class, FloatArgumentType.floatArg());
    050        registerArgument(double.class, DoubleArgumentType.doubleArg());
    051        registerArgument(Double.class, DoubleArgumentType.doubleArg());
    052        registerArgument(boolean.class, BoolArgumentType.bool());
    053        registerArgument(Boolean.class, BoolArgumentType.bool());
    054        registerArgument(int.class, IntegerArgumentType.integer());
    055        registerArgument(Integer.class, IntegerArgumentType.integer());
    056        // We use integer for long due to Bungee bug, plus should really be considered same on client
    057        registerArgument(long.class, IntegerArgumentType.integer());
    058        registerArgument(Long.class, IntegerArgumentType.integer());
    059    }
    060
    061    <T> void registerArgument(Class<T> clazz, ArgumentType<?> type) {
    062        arguments.put(clazz, type);
    063    }
    064
    065    ArgumentType<Object> getArgumentTypeByClazz(CommandParameter param) {
    066        if (param.consumesRest) {
    067            //noinspection unchecked
    068            return (ArgumentType<Object>) (ArgumentType<?>) StringArgumentType.greedyString();
    069        }
    070        //noinspection unchecked
    071        return (ArgumentType<Object>) arguments.getOrDefault(param.getType(), StringArgumentType.string());
    072    }
    073
    074    /**
    075     * Registers the given RootCommand into the given brigadir command node, utilizing the provided suggestion provider, executor and permission predicate.<br>
    076     * <p>
    077     * It recreates the root command node!
    078     */
    079    LiteralCommandNode<S> register(RootCommand rootCommand,
    080                                   LiteralCommandNode<S> root,
    081                                   SuggestionProvider<S> suggestionProvider,
    082                                   Command<S> executor,
    083                                   BiPredicate<RootCommand, S> permCheckerRoot,
    084                                   BiPredicate<RegisteredCommand, S> permCheckerSub) {
    085        // recreate root to get rid of bukkits default arg
    086        LiteralArgumentBuilder<S> rootBuilder = LiteralArgumentBuilder.<S>literal(root.getLiteral())
    087                .requires(sender -> permCheckerRoot.test(rootCommand, sender));
    088
    089        RegisteredCommand defaultCommand = rootCommand.getDefaultRegisteredCommand();
    090        if (defaultCommand != null) {
    091            if (defaultCommand.requiredResolvers == 0) {
    092                rootBuilder.executes(executor);
    093            }
    094        }
    095
    096        root = rootBuilder.build();
    097        boolean isForwardingCommand = rootCommand.getDefCommand() instanceof ForwardingCommand;
    098
    099        if (defaultCommand != null) {
    100            registerParameters(defaultCommand, root, suggestionProvider, executor, permCheckerSub);
    101        }
    102
    103        for (Map.Entry<String, RegisteredCommand> subCommand : rootCommand.getSubCommands().entries()) {
    104            if ((BaseCommand.isSpecialSubcommand(subCommand.getKey()) && !isForwardingCommand) || (!subCommand.getKey().equals("help") && subCommand.getValue().prefSubCommand.equals("help"))) {
    105                // don't register stuff like __catchunknown and don't help command aliases
    106                continue;
    107            }
    108
    109            // handle sub sub commands
    110            String commandName = subCommand.getKey();
    111            CommandNode<S> currentParent = root;
    112            CommandNode<S> subCommandNode;
    113            Predicate<S> subPermChecker = sender -> permCheckerSub.test(subCommand.getValue(), sender);
    114            if (!isForwardingCommand) {
    115                if (commandName.contains(" ")) {
    116                    String[] split = ACFPatterns.SPACE.split(commandName);
    117                    for (int i = 0; i < split.length - 1; i++) {
    118                        if (currentParent.getChild(split[i]) == null) {
    119                            LiteralCommandNode<S> sub = LiteralArgumentBuilder.<S>literal(split[i])
    120                                    .requires(subPermChecker).build();
    121                            currentParent.addChild(sub);
    122                            currentParent = sub;
    123                        } else {
    124                            currentParent = currentParent.getChild(split[i]);
    125                        }
    126                    }
    127                    commandName = split[split.length - 1];
    128                }
    129
    130                subCommandNode = currentParent.getChild(commandName);
    131                if (subCommandNode == null) {
    132                    LiteralArgumentBuilder<S> argumentBuilder = LiteralArgumentBuilder.<S>literal(commandName)
    133                            .requires(subPermChecker);
    134
    135                    // if we have no required params, this command is actually executable
    136                    if (subCommand.getValue().requiredResolvers == 0) {
    137                        argumentBuilder.executes(executor);
    138                    }
    139                    subCommandNode = argumentBuilder.build();
    140                }
    141            } else {
    142                subCommandNode = root;
    143            }
    144
    145            registerParameters(subCommand.getValue(), subCommandNode, suggestionProvider, executor, permCheckerSub);
    146
    147            if (!isForwardingCommand) {
    148                currentParent.addChild(subCommandNode);
    149            }
    150        }
    151
    152        return root;
    153    }
    154
    155    void registerParameters(RegisteredCommand command,
    156                            CommandNode<S> node,
    157                            SuggestionProvider<S> suggestionProvider,
    158                            Command<S> executor,
    159                            BiPredicate<RegisteredCommand, S> permChecker) {
    160        for (int i = 0; i < command.parameters.length; i++) {
    161            CommandParameter param = command.parameters[i];
    162            CommandParameter nextParam = param.getNextParam();
    163            if (param.isCommandIssuer() || (param.canExecuteWithoutInput() && nextParam != null && !nextParam.canExecuteWithoutInput())) {
    164                continue;
    165            }
    166            RequiredArgumentBuilder<S, Object> builder = RequiredArgumentBuilder
    167                    .<S, Object>argument(param.getName(), getArgumentTypeByClazz(param))
    168                    .suggests(suggestionProvider)
    169                    .requires(sender -> permChecker.test(command, sender));
    170
    171            if (nextParam == null || nextParam.canExecuteWithoutInput()) {
    172                builder.executes(executor);
    173            }
    174
    175            CommandNode<S> subSubCommand = builder.build();
    176            node.addChild(subSubCommand);
    177            node = subSubCommand;
    178        }
    179    }
    180
    181}