8000 Allow changing namespace of registered commands · Issue #367 · CommandAPI/CommandAPI · GitHub
[go: up one dir, main page]

Skip to content
Allow changing namespace of registered commands #367
Closed
@willkroboth

Description

@willkroboth

Description

This suggestion started as a question by Adixe in discord

Currently, whenever a command is registered, it is automatically registered under the minecraft namespace. So, if you register a command /hello, you can also run it using /minecraft:hello. (https://commandapi.jorel.dev/8.5.1/intro.html#how-the-commandapi-works)

It would be nice if developers could control what namespace their commands get registered under.

Expected code

// default - runnable as /command or /minecraft:command
new CommandAPICommand("command").register();

// plugin namespace - runnable as /command or /pluginname:command
new CommandAPICommand("command").register(Plugin);

// custom namespace - runnable as /command or /custom:command
new CommandAPICommand("command").register("custom");

// no namespace - only runnable as /command
new CommandAPICommand("command").register("");

Extra details

The org.bukkit.SimpleCommandMap class handles tracking, tab-completing, and dispatching all commands on the server, including CommandAPICommands via the VanillaCommandWrapper class.

package org.bukkit.command;

public class SimpleCommandMap implements CommandMap {
    protected final Map<String, Command> knownCommands = new HashMap();

    // Pretty much what registering does
    public register(String name, String nameSpace, Command command) {
         this.knownCommands.put(nameSpace + ":" + name, command);
         this.knownCommands.put(name, command);
     }

    @Nullable
    public Command getCommand(@NotNull String name) {
        Command target = (Command)this.knownCommands.get(name.toLowerCase(Locale.ENGLISH));
        return target;
    }

    public boolean dispatch(@NotNull CommandSender sender, @NotNull String commandLine) throws CommandException {
        String[] args = commandLine.split(" ");
        if (args.length == 0) {
            return false;
        } else {
            String sentCommandLabel = args[0].toLowerCase(Locale.ENGLISH);
            Command target = this.getCommand(sentCommandLabel);
            if (target == null) {
                return false;
            } else {
                 // execute the target Command
            }
        }
    }

    public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String cmdLine, @Nullable Location location) {
        int spaceIndex = cmdLine.indexOf(32);
        if (spaceIndex == -1) {
            ArrayList<String> completions = new ArrayList();
            Map<String, Command> kn
6742
ownCommands = this.knownCommands;
            // tab complete command names based on the knownCommands map
        } else {
            String commandName = cmdLine.substring(0, spaceIndex);
            Command target = this.getCommand(commandName);
            if (target == null) {
                return null;
            } else {
                 // tab complete based on what the target command says
            }
        }
    }
}

The knownCommands HashMap determines which commands can be accessed. If a string exists in the map, there is a Command it can run, and if it is not in the map, Spigot shouldn't think it exists. Adding entries we want and removing entries we don't want (doesn't the removing part already happen when force unregistering commands?) should allow us to register exactly the namespaces we want.

Also, if a developer chooses to register their commands with their Plugin class, there could be a feature for looking up which commands are registered by which plugins.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestimplemented for next releaseThis has been implemented in the current dev build for the next public release

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0