2020-04-24 03:25:58 +02:00
|
|
|
package net.minestom.server.command;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2022-07-02 05:39:39 +02:00
|
|
|
import net.minestom.server.command.builder.Command;
|
|
|
|
import net.minestom.server.command.builder.CommandDispatcher;
|
|
|
|
import net.minestom.server.command.builder.CommandResult;
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.entity.Player;
|
2021-06-04 03:48:51 +02:00
|
|
|
import net.minestom.server.event.EventDispatcher;
|
2020-05-07 15:46:21 +02:00
|
|
|
import net.minestom.server.event.player.PlayerCommandEvent;
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
2020-11-02 04:13:43 +01:00
|
|
|
import net.minestom.server.utils.callback.CommandCallback;
|
2020-05-23 04:20:01 +02:00
|
|
|
import net.minestom.server.utils.validate.Check;
|
2020-10-24 16:58:27 +02:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-10-11 18:35:32 +02:00
|
|
|
/**
|
2021-03-18 02:47:10 +01:00
|
|
|
* Manager used to register {@link Command commands}.
|
2020-10-11 18:35:32 +02:00
|
|
|
* <p>
|
|
|
|
* It is also possible to simulate a command using {@link #execute(CommandSender, String)}.
|
|
|
|
*/
|
|
|
|
public final class CommandManager {
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-08-04 04:21:11 +02:00
|
|
|
public static final String COMMAND_PREFIX = "/";
|
|
|
|
|
2021-02-08 03:42:35 +01:00
|
|
|
private final ServerSender serverSender = new ServerSender();
|
2020-10-22 12:55:53 +02:00
|
|
|
private final ConsoleSender consoleSender = new ConsoleSender();
|
2020-06-21 14:01:03 +02:00
|
|
|
|
2020-10-22 12:55:53 +02:00
|
|
|
private final CommandDispatcher dispatcher = new CommandDispatcher();
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-11-02 04:13:43 +01:00
|
|
|
private CommandCallback unknownCommandCallback;
|
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
public CommandManager() {
|
2020-07-01 21:03:53 +02:00
|
|
|
}
|
|
|
|
|
2020-07-21 18:04:02 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Registers a {@link Command}.
|
2020-07-21 18:04:02 +02:00
|
|
|
*
|
|
|
|
* @param command the command to register
|
2020-11-14 07:06:46 +01:00
|
|
|
* @throws IllegalStateException if a command with the same name already exists
|
2020-07-21 18:04:02 +02:00
|
|
|
*/
|
2020-11-14 01:39:51 +01:00
|
|
|
public synchronized void register(@NotNull Command command) {
|
|
|
|
Check.stateCondition(commandExists(command.getName()),
|
|
|
|
"A command with the name " + command.getName() + " is already registered!");
|
2021-02-09 15:26:53 +01:00
|
|
|
if (command.getAliases() != null) {
|
|
|
|
for (String alias : command.getAliases()) {
|
|
|
|
Check.stateCondition(commandExists(alias),
|
|
|
|
"A command with the name " + alias + " is already registered!");
|
|
|
|
}
|
2020-11-14 01:39:51 +01:00
|
|
|
}
|
2020-04-05 10:15:21 +02:00
|
|
|
this.dispatcher.register(command);
|
|
|
|
}
|
|
|
|
|
2020-11-06 16:03:08 +01:00
|
|
|
/**
|
|
|
|
* Removes a command from the currently registered commands.
|
|
|
|
* Does nothing if the command was not registered before
|
|
|
|
*
|
|
|
|
* @param command the command to remove
|
|
|
|
*/
|
|
|
|
public void unregister(@NotNull Command command) {
|
|
|
|
this.dispatcher.unregister(command);
|
|
|
|
}
|
|
|
|
|
2020-08-04 06:14:42 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the {@link Command} registered by {@link #register(Command)}.
|
2020-08-04 06:14:42 +02:00
|
|
|
*
|
|
|
|
* @param commandName the command name
|
|
|
|
* @return the command associated with the name, null if not any
|
|
|
|
*/
|
2021-05-01 20:27:41 +02:00
|
|
|
public @Nullable Command getCommand(@NotNull String commandName) {
|
2020-08-04 06:14:42 +02:00
|
|
|
return dispatcher.findCommand(commandName);
|
|
|
|
}
|
|
|
|
|
2020-11-14 01:39:51 +01:00
|
|
|
/**
|
2021-11-06 18:33:48 +01:00
|
|
|
* Gets if a command with the name {@code commandName} already exists or not.
|
2020-11-14 01:39:51 +01:00
|
|
|
*
|
|
|
|
* @param commandName the command name to check
|
|
|
|
* @return true if the command does exist
|
|
|
|
*/
|
|
|
|
public boolean commandExists(@NotNull String commandName) {
|
|
|
|
commandName = commandName.toLowerCase();
|
2021-05-01 20:27:41 +02:00
|
|
|
return dispatcher.findCommand(commandName) != null;
|
2020-11-14 01:39:51 +01:00
|
|
|
}
|
|
|
|
|
2020-07-21 18:04:02 +02:00
|
|
|
/**
|
2021-11-06 18:33:48 +01:00
|
|
|
* Executes a command for a {@link CommandSender}.
|
2020-07-21 18:04:02 +02:00
|
|
|
*
|
|
|
|
* @param sender the sender of the command
|
|
|
|
* @param command the raw command string (without the command prefix)
|
2021-02-11 00:04:42 +01:00
|
|
|
* @return the execution result
|
2020-07-21 18:04:02 +02:00
|
|
|
*/
|
2021-05-01 20:27:41 +02:00
|
|
|
public @NotNull CommandResult execute(@NotNull CommandSender sender, @NotNull String command) {
|
2020-10-12 02:56:30 +02:00
|
|
|
// Command event
|
2021-10-22 02:19:38 +02:00
|
|
|
if (sender instanceof Player player) {
|
2020-06-21 14:01:03 +02:00
|
|
|
PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(player, command);
|
2021-06-04 03:48:51 +02:00
|
|
|
EventDispatcher.call(playerCommandEvent);
|
2020-06-21 14:01:03 +02:00
|
|
|
if (playerCommandEvent.isCancelled())
|
2021-02-11 03:00:13 +01:00
|
|
|
return CommandResult.of(CommandResult.Type.CANCELLED, command);
|
2020-06-21 14:01:03 +02:00
|
|
|
command = playerCommandEvent.getCommand();
|
|
|
|
}
|
2020-10-12 02:56:30 +02:00
|
|
|
// Process the command
|
2021-08-19 09:06:24 +02:00
|
|
|
final CommandResult result = dispatcher.execute(sender, command);
|
2021-05-01 20:27:41 +02:00
|
|
|
if (result.getType() == CommandResult.Type.UNKNOWN) {
|
|
|
|
if (unknownCommandCallback != null) {
|
|
|
|
this.unknownCommandCallback.apply(sender, command);
|
2020-12-15 09:30:09 +01:00
|
|
|
}
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
2021-05-01 20:27:41 +02:00
|
|
|
return result;
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
|
|
|
|
2021-02-08 03:42:35 +01:00
|
|
|
/**
|
2021-11-06 18:33:48 +01:00
|
|
|
* Executes the command using a {@link ServerSender}. This can be used
|
|
|
|
* to run a silent command (nothing is printed to console).
|
2021-02-08 04:08:22 +01:00
|
|
|
*
|
|
|
|
* @see #execute(CommandSender, String)
|
2021-02-08 03:42:35 +01:00
|
|
|
*/
|
2021-05-01 20:27:41 +02:00
|
|
|
public @NotNull CommandResult executeServerCommand(@NotNull String command) {
|
2021-02-08 03:42:35 +01:00
|
|
|
return execute(serverSender, command);
|
|
|
|
}
|
|
|
|
|
2021-05-01 20:27:41 +02:00
|
|
|
public @NotNull CommandDispatcher getDispatcher() {
|
2021-02-11 02:51:42 +01:00
|
|
|
return dispatcher;
|
|
|
|
}
|
|
|
|
|
2020-11-02 04:13:43 +01:00
|
|
|
/**
|
|
|
|
* Gets the callback executed once an unknown command is run.
|
|
|
|
*
|
|
|
|
* @return the unknown command callback, null if not any
|
|
|
|
*/
|
2021-05-01 20:27:41 +02:00
|
|
|
public @Nullable CommandCallback getUnknownCommandCallback() {
|
2020-11-02 04:13:43 +01:00
|
|
|
return unknownCommandCallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the callback executed once an unknown command is run.
|
|
|
|
*
|
|
|
|
* @param unknownCommandCallback the new unknown command callback,
|
|
|
|
* setting it to null mean that nothing will be executed
|
|
|
|
*/
|
|
|
|
public void setUnknownCommandCallback(@Nullable CommandCallback unknownCommandCallback) {
|
|
|
|
this.unknownCommandCallback = unknownCommandCallback;
|
|
|
|
}
|
|
|
|
|
2020-07-21 18:04:02 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the {@link ConsoleSender} (which is used as a {@link CommandSender}).
|
2020-07-21 18:04:02 +02:00
|
|
|
*
|
2020-10-11 18:35:32 +02:00
|
|
|
* @return the {@link ConsoleSender}
|
2020-07-21 18:04:02 +02:00
|
|
|
*/
|
2021-05-01 20:27:41 +02:00
|
|
|
public @NotNull ConsoleSender getConsoleSender() {
|
2020-06-21 14:01:03 +02:00
|
|
|
return consoleSender;
|
|
|
|
}
|
|
|
|
|
2020-07-21 18:04:02 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the {@link DeclareCommandsPacket} for a specific player.
|
2020-07-21 18:04:02 +02:00
|
|
|
* <p>
|
2020-11-04 04:45:46 +01:00
|
|
|
* Can be used to update a player auto-completion list.
|
2020-07-21 18:04:02 +02:00
|
|
|
*
|
|
|
|
* @param player the player to get the commands packet
|
|
|
|
* @return the {@link DeclareCommandsPacket} for {@code player}
|
|
|
|
*/
|
2021-05-01 20:27:41 +02:00
|
|
|
public @NotNull DeclareCommandsPacket createDeclareCommandsPacket(@NotNull Player player) {
|
2022-07-13 22:45:38 +02:00
|
|
|
final Graph merged = Graph.merge(dispatcher.getCommands());
|
|
|
|
return GraphConverter.createPacket(merged, player);
|
2020-07-10 18:12:29 +02:00
|
|
|
}
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|