All Downloads are FREE. Search and download functionalities are using the official Maven repository.

personthecat.catlib.command.CommandUtils Maven / Gradle / Ivy

Go to download

Utilities for serialization, commands, noise generation, IO, and some new data types.

The newest version!
package personthecat.catlib.command;

import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.ParsedCommandNode;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.tree.ArgumentCommandNode;
import lombok.experimental.UtilityClass;
import net.minecraft.class_2168;
import net.minecraft.class_2170;
import net.minecraft.class_2247;
import net.minecraft.class_2257;
import net.minecraft.class_2558;
import net.minecraft.class_2568;
import net.minecraft.class_2585;
import org.jetbrains.annotations.Nullable;
import personthecat.catlib.command.arguments.FileArgument;
import personthecat.catlib.command.arguments.JsonArgument;
import personthecat.catlib.command.arguments.PathArgument;
import personthecat.catlib.serialization.json.JsonPath;
import personthecat.catlib.data.ModDescriptor;
import personthecat.catlib.util.McUtils;

import javax.annotation.ParametersAreNonnullByDefault;
import java.io.File;
import java.util.Optional;

import static personthecat.catlib.command.CommandSuggestions.ANY_INT;
import static personthecat.catlib.command.CommandSuggestions.ANY_DECIMAL;

@UtilityClass
@SuppressWarnings("unused")
@ParametersAreNonnullByDefault
public class CommandUtils {

    /**
     * Gets the most recent argument of the given type without needing to search by name.
     *
     * @param ctx The standard {@link CommandContext} for the current command.
     * @param type The type of argument being queried for.
     * @param t The return type of the argument being queried for.
     * @param  The type of object being wrapped by the command context.
     * @param  The type of value stored in the command context.
     * @return The requested value, or else {@link Optional#empty}.
     */
    public static  Optional getLastArg(final CommandContext ctx, final Class> type, final Class t) {
        for (int i = ctx.getNodes().size() - 1; i >= 0; i--) {
            final ParsedCommandNode node = ctx.getNodes().get(i);
            if (node.getNode() instanceof ArgumentCommandNode) {
                final ArgumentCommandNode argument = (ArgumentCommandNode) node.getNode();
                if (type.isInstance(argument.getType())) {
                    return Optional.of(ctx.getArgument(argument.getName(), t));
                }
            }
        }
        return Optional.empty();
    }

    /**
     * Shorthand method for creating a ranged integer argument.
     *
     * @param name The name of the argument node.
     * @param min The minimum allowed value.
     * @param max The maximum allowed value.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder arg(final String name, final int min, final int max) {
        return class_2170.method_9244(name, IntegerArgumentType.integer(min, max)).suggests(ANY_INT);
    }

    /**
     * Shorthand method for creating a decimal argument
     *
     * @param name The name of the argument node.
     * @param min The minimum allowed value.
     * @param max The maximum allowed value.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder arg(final String name, final double min, final double max) {
        return class_2170.method_9244(name, DoubleArgumentType.doubleArg(min, max)).suggests(ANY_DECIMAL);
    }

    /**
     * Shorthand method for creating a string argument.
     *
     * @param name The name of the argument node.
     * @param suggests The suggestion provider to be used by the output command node.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder arg(final String name, final SuggestionProvider suggests) {
        return class_2170.method_9244(name, StringArgumentType.string()).suggests(suggests);
    }

    /**
     * Variant of {@link #arg(String, SuggestionProvider)} which returns a greedy string.
     *
     * @param name The name of the argument node.
     * @param suggests The suggestion provider to be used by the output command node.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder greedyArg(final String name, final SuggestionProvider suggests) {
        return class_2170.method_9244(name, StringArgumentType.greedyString()).suggests(suggests);
    }

    /**
     * Shorthand method for creating a block argument.
     *
     * @param name The name of the output argument node.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder blkArg(final String name) {
        return class_2170.method_9244(name, class_2257.method_9653());
    }

    /**
     * Generates a {@link FileArgument} for the given name. The root folder of this
     * argument will be provided by the {@link ModDescriptor} stored in the current
     * {@link CommandRegistrationContext}. If no context is active, the root folder
     * will default to the main conflg folder.
     *
     * @param name The name of the output argument node.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder fileArg(final String name) {
        return fileArg(name, getDefaultRoot());
    }

    /**
     * Variant of {@link #fileArg(String)} which provides an explicit {@link ModDescriptor}.
     *
     * @param name The name of the output argument node.
     * @param mod The descriptor providing the root config folder for the current mod.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder fileArg(final String name, final ModDescriptor mod) {
        return fileArg(name, mod.getConfigFolder(), mod.getPreferredDirectory());
    }

    /**
     * Variant of {@link #fileArg(String)} which directly supplies a root folder.
     *
     * @param name The name of the output argument node.
     * @param root The root folder to be used by the file argument parser.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder fileArg(final String name, final File root) {
        return class_2170.method_9244(name, new FileArgument(root));
    }

    /**
     * Variant of {@link #fileArg(String)} which directly supplies a root folder
     * and the preferred directory for recursion.
     *
     * @param name      The name of the output argument node.
     * @param root      The root folder to be used by the file argument parser.
     * @param preferred The first directory to search through for recursive searches.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder fileArg(final String name, final File root, final @Nullable File preferred) {
        return class_2170.method_9244(name, new FileArgument(root, preferred, true));
    }

    /**
     * Generates a {@link JsonArgument} when provided a name. As with {@link #fileArg(String)},
     * the root folder of this argument will be supplied by the active {@link ModDescriptor}.
     *
     * @param name The name of the output argument node.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder jsonFileArg(final String name) {
        return jsonFileArg(name, getDefaultRoot());
    }

    /**
     * Variant of {@link #jsonFileArg(String)} which provides an explicit {@link ModDescriptor}.
     *
     * @param name The name of the output argument node.
     * @param mod The descriptor providing the root config folder for the current mod.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder jsonFileArg(final String name, final ModDescriptor mod) {
        return jsonFileArg(name, mod.getConfigFolder(), mod.getPreferredDirectory());
    }

    /**
     * Variant of {@link #jsonFileArg(String)} which directly supplies the root folder.
     *
     * @param name The name of the output argument node.
     * @param root The root folder to be used by the file argument parser.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder jsonFileArg(final String name, final File root) {
        return class_2170.method_9244(name, new JsonArgument(root));
    }

    /**
     * Variant of {@link #jsonFileArg(String)} which directly supplies the root folder
     * and the preferred directory for recursion.
     *
     * @param name      The name of the output argument node.
     * @param root      The root folder to be used by the file argument parser.
     * @param preferred The first directory to search through for recursive searches.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder jsonFileArg(final String name, final File root, final @Nullable File preferred) {
        return class_2170.method_9244(name, new JsonArgument(root, preferred, true));
    }

    /**
     * Shorthand method for creating a JSON path argument.
     *
     * @param name The name of the output argument node.
     * @return An argument builder for the given specs.
     */
    public static RequiredArgumentBuilder jsonPathArg(final String name) {
        return class_2170.method_9244(name, new PathArgument());
    }

    /**
     * Shorthand method for creating a {@link class_2568} which displays some text.
     *
     * @param txt The text to display on hover.
     * @return A {@link class_2568} to display the given text.
     */
    public static class_2568 displayOnHover(final String txt) {
        return displayOnHover(new class_2585(txt));
    }

    /**
     * Shorthand method for creating a {@link class_2568} which displays a text component.
     *
     * @param txt The text component to display on hover.
     * @return A {@link class_2568} to display the given component.
     */
    public static class_2568 displayOnHover(final class_2585 txt) {
        return new class_2568(class_2568.class_5247.field_24342, txt);
    }

    /**
     * Shorthand method for creating a {@link class_2558} which runs the given command.
     *
     * @param cmd The raw command text to be executed by the command manager.
     * @return A {@link class_2558} to run the given command.
     */
    public static class_2558 clickToRun(final String cmd) {
        return new class_2558(class_2558.class_2559.field_11750, cmd);
    }

    /**
     * Shorthand method for creating a {@link class_2558} which opens the given file.
     *
     * @param file The file to be opened when this event runs.
     * @return A {@link class_2558} to open the given file.
     */
    public static class_2558 clickToOpen(final File file) {
        return new class_2558(class_2558.class_2559.field_11749, file.getPath());
    }

    /**
     * Shorthand method for creating a {@link class_2558} which opens the given URL.
     *
     * @param url The url to be opened when this event runs.
     * @return A {@link class_2558} to open the given URL.
     */
    public static class_2558 clickToGo(final String url) {
        return new class_2558(class_2558.class_2559.field_11749, url);
    }

    /**
     * Shorthand method for creating a {@link class_2558} which suggests the given command.
     *
     * @param cmd The command to be suggested when this event runs.
     * @return A {@link class_2558} to suggest the given command.
     */
    public static class_2558 clickToSuggest(final String cmd) {
        return new class_2558(class_2558.class_2559.field_11745, cmd);
    }

    /**
     * Shorthand method for creating a {@link class_2558} which copies the given text.
     *
     * @param txt The text to be copied into the clipboard.
     * @return A {@link class_2558} to copy the given text.
     */
    public static class_2558 clickToCopy(final String txt) {
        return new class_2558(class_2558.class_2559.field_21462, txt);
    }

    private static File getDefaultRoot() {
        final ModDescriptor activeMod = CommandRegistrationContext.getActiveMod();
        return activeMod != null ? activeMod.getConfigFolder() : McUtils.getConfigDir();
    }
}