mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-16 08:56:04 +01:00
Fix command map
This commit is contained in:
160
src/main/java/emu/grasscutter/command/CommandMap.java
Normal file
160
src/main/java/emu/grasscutter/command/CommandMap.java
Normal file
@@ -0,0 +1,160 @@
|
||||
package emu.grasscutter.command;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.GenshinPlayer;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "unused"})
|
||||
public final class CommandMap {
|
||||
private final Map<String, CommandHandler> commands = new HashMap<>();
|
||||
private final Map<String, Command> annotations = new HashMap<>();
|
||||
public CommandMap() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public CommandMap(boolean scan) {
|
||||
if (scan) this.scan();
|
||||
}
|
||||
|
||||
public static CommandMap getInstance() {
|
||||
return Grasscutter.getGameServer().getCommandMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command handler.
|
||||
*
|
||||
* @param label The command label.
|
||||
* @param command The command handler.
|
||||
* @return Instance chaining.
|
||||
*/
|
||||
public CommandMap registerCommand(String label, CommandHandler command) {
|
||||
Grasscutter.getLogger().debug("Registered command: " + label);
|
||||
|
||||
// Get command data.
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
this.annotations.put(label, annotation);
|
||||
this.commands.put(label, command);
|
||||
|
||||
// Register aliases.
|
||||
if (annotation.aliases().length > 0) {
|
||||
for (String alias : annotation.aliases()) {
|
||||
this.commands.put(alias, command);
|
||||
this.annotations.put(alias, annotation);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a registered command handler.
|
||||
*
|
||||
* @param label The command label.
|
||||
* @return Instance chaining.
|
||||
*/
|
||||
public CommandMap unregisterCommand(String label) {
|
||||
Grasscutter.getLogger().debug("Unregistered command: " + label);
|
||||
CommandHandler handler = this.commands.get(label);
|
||||
if (handler == null) return this;
|
||||
|
||||
Command annotation = handler.getClass().getAnnotation(Command.class);
|
||||
this.annotations.remove(label);
|
||||
this.commands.remove(label);
|
||||
|
||||
// Unregister aliases.
|
||||
if (annotation.aliases().length > 0) {
|
||||
for (String alias : annotation.aliases()) {
|
||||
this.commands.remove(alias);
|
||||
this.annotations.remove(alias);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all registered commands.
|
||||
*
|
||||
* @return All command handlers as a list.
|
||||
*/
|
||||
public List<CommandHandler> getHandlersAsList() {
|
||||
return new LinkedList<>(this.commands.values());
|
||||
}
|
||||
|
||||
public HashMap<String, CommandHandler> getHandlers() {
|
||||
return new LinkedHashMap<>(this.commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler by label/alias.
|
||||
*
|
||||
* @param label The command label.
|
||||
* @return The command handler.
|
||||
*/
|
||||
public CommandHandler getHandler(String label) {
|
||||
return this.commands.get(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a command handler with the given arguments.
|
||||
*
|
||||
* @param player The player invoking the command or null for the server console.
|
||||
* @param rawMessage The messaged used to invoke the command.
|
||||
*/
|
||||
public void invoke(GenshinPlayer player, String rawMessage) {
|
||||
rawMessage = rawMessage.trim();
|
||||
if(rawMessage.length() == 0) {
|
||||
CommandHandler.sendMessage(player, "No command specified."); return;
|
||||
}
|
||||
|
||||
// Remove prefix if present.
|
||||
if (!Character.isLetter(rawMessage.charAt(0)))
|
||||
rawMessage = rawMessage.substring(1);
|
||||
|
||||
// Parse message.
|
||||
String[] split = rawMessage.split(" ");
|
||||
List<String> args = new LinkedList<>(Arrays.asList(split));
|
||||
String label = args.remove(0);
|
||||
|
||||
// Get command handler.
|
||||
CommandHandler handler = this.commands.get(label);
|
||||
if (handler == null) {
|
||||
CommandHandler.sendMessage(player, "Unknown command: " + label);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for permission.
|
||||
if (player != null) {
|
||||
String permissionNode = this.annotations.get(label).permission();
|
||||
Account account = player.getAccount();
|
||||
if(!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) {
|
||||
CommandHandler.sendMessage(player, "You do not have permission to run this command.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke execute method for handler.
|
||||
handler.execute(player, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans for all classes annotated with {@link Command} and registers them.
|
||||
*/
|
||||
private void scan() {
|
||||
Reflections reflector = Grasscutter.reflector;
|
||||
Set<Class<?>> classes = reflector.getTypesAnnotatedWith(Command.class);
|
||||
classes.forEach(annotated -> {
|
||||
try {
|
||||
Command cmdData = annotated.getAnnotation(Command.class);
|
||||
Object object = annotated.newInstance();
|
||||
if (object instanceof CommandHandler)
|
||||
this.registerCommand(cmdData.label(), (CommandHandler) object);
|
||||
else Grasscutter.getLogger().error("Class " + annotated.getName() + " is not a CommandHandler!");
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger().error("Failed to register command handler for " + annotated.getSimpleName(), exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user