Can't register new commands!
spacefluff432 opened this issue ยท 4 comments
Annoyingly, the bukkit developers decided to make org.bukkit.command.Command
a protected class. See "Constructor Summary" at the following URL: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/command/Command.html
It would be nice if we could register commands from within the game, like so:
// generate a new commandMap
var commandMap = new org.bukkit.command.SimpleCommandMap(server);
// generate a new command (currently impossible)
var command = new org.bukkit.command.Command('command');
// register the command to our commandMap
commandMap.register('plugin', command);
// add listener for command execution
command.on('execute', function (player, args) {
return 'Your username is ' + player.name + ' and you typed ' + args;
});
// tab-completer
command.on('tab', function (player, args) => {
if (args.join(' ') === 'secret completions are') {
return [
"I'm a tab completion!",
"And I'm a tab completion!",
"Oh, and I'm a tab completion!"
]
}
});
The resulting commands registered would be:
/command
/plugin:command
The alternative is to build the jar with a custom class that can create new commands, like AbstractCommand
by Goblom
: https://github.com/Goblom/Bukkit-Libraries/blob/master/src/main/java/command/AbstractCommand.java
In the past 2 years, I've tried countless times to crack this issue, and I've finally done it. The following code must be ran at plugin load time to work properly.
const Command = Java.extend(org.bukkit.command.Command);
const commandMap = server.getClass().getDeclaredField('commandMap');
commandMap.setAccessible(true);
const registry = commandMap.get(server);
registry.register(
'prefix',
new Command('test', {
execute: (...args) => {
console.log(...args);
console.log('hello world');
return true;
},
tabComplete: (...args) => {
console.log(...args);
return [ 'tab 1', 'tab 2', 'tab 3' ];
}
})
);
This script will add the commands /test
and /prefix:test
to the server.
Don't "new" an abstract class. Get an instance of one of the concrete classes that already derives from that base. If they are inadequate, just inherit from one of them and add your own customizations, or derive a new class from Command and copy in details as required. For your purposes, look for examples for instantiating from class PluginCommand -- that's the one you want. This thread should be helpful.
https://bukkit.org/threads/tutorial-registering-commands-at-runtime.158461/
If you receive an object of type Command, that's just means the object must be from a class that derives from Command, and it is guaranteed to support the abstract class members. But it won't be an instance of 'Command'. When you receive an object of type Command, decide what it is and then cast it so that you can work with it properly. Again, in your case you should be receiving a PluginCommand to your event handler.
I'm getting the feeling that I am misunderstanding your intent. Do you want to create a command outside of initialization, like a dynamic command that changes depending on what you're doing?