Initial Commit

This commit is contained in:
Melledy
2025-10-27 02:02:26 -07:00
commit f58951fe2a
378 changed files with 315914 additions and 0 deletions
@@ -0,0 +1,168 @@
package emu.nebula.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.reflections.Reflections;
import emu.nebula.Nebula;
import emu.nebula.game.player.Player;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import lombok.Getter;
@Getter
public class CommandManager {
private Object2ObjectMap<String, CommandHandler> labels;
private Object2ObjectMap<String, CommandHandler> commands;
public CommandManager() {
this.labels = new Object2ObjectOpenHashMap<>();
this.commands = new Object2ObjectOpenHashMap<>();
// Scan for commands
var commandClasses = new Reflections(CommandManager.class.getPackageName()).getTypesAnnotatedWith(Command.class);
for (var cls : commandClasses) {
if (!CommandHandler.class.isAssignableFrom(cls)) {
continue;
}
try {
CommandHandler handler = (CommandHandler) cls.getDeclaredConstructor().newInstance();
this.registerCommand(handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Adds a command that players and server console users can use. Command handlers must have the proper command annotation attached to them.
*/
public CommandManager registerCommand(CommandHandler handler) {
Command command = handler.getClass().getAnnotation(Command.class);
if (command == null) return this;
this.getLabels().put(command.label(), handler);
this.getCommands().put(command.label(), handler);
for (String alias : command.aliases()) {
this.getCommands().put(alias, handler);
}
return this;
}
/**
* Removes a command from use.
* @param label The command name
* @return
*/
public CommandManager unregisterCommand(String label) {
CommandHandler handler = this.getLabels().get(label);
if (handler == null) return this;
Command command = handler.getClass().getAnnotation(Command.class);
if (command == null) {
return this;
}
this.getLabels().remove(command.label());
this.getCommands().remove(command.label());
for (String alias : command.aliases()) {
this.getCommands().remove(alias);
}
return this;
}
/**
* Checks if the sender has permission to use this command. Will always return true if the sender is the server console.
* @param sender The sender of the command.
* @param command
* @return true if the sender has permission to use this command
*/
public boolean checkPermission(Player sender, Command command) {
if (sender == null || command.permission().isEmpty()) {
return true;
}
return sender.getAccount().hasPermission(command.permission());
}
/**
* Checks if the sender has permission to use this command on other players. Will always return true if the sender is the server console.
* @param sender The sender of the command.
* @param command
* @return true if the sender has permission to use this command
*/
private boolean checkTargetPermission(Player sender, Command command) {
if (sender == null || command.permission().isEmpty()) {
return true;
}
return sender.getAccount().hasPermission("target." + command.permission());
}
public void invoke(Player sender, String message) {
// Parse message into arguments
List<String> args = Arrays.stream(message.split(" ")).collect(Collectors.toCollection(ArrayList::new));
// Get command label
String label = args.remove(0).toLowerCase();
// Filter out command prefixes
if (label.startsWith("/") || label.startsWith("!")) {
label = label.substring(1);
}
// Get command handler
CommandHandler handler = this.commands.get(label);
// Execute command
if (handler != null) {
// Get command annotation data
Command command = handler.getData();
// Check if sender has permission to run the command.
if (sender != null && !this.checkPermission(sender, command)) {
// We have a double null check here just in case
sender.sendMessage("You do not have permission to use this command.");
return;
}
// Build command arguments
CommandArgs cmdArgs = new CommandArgs(sender, args);
// Check targeted permission
if (sender != cmdArgs.getTarget() && !this.checkTargetPermission(sender, command)) {
cmdArgs.sendMessage("You do not have permission to use this command on another player.");
return;
}
// Make sure our command has a target
if (command.requireTarget() && cmdArgs.getTarget() == null) {
cmdArgs.sendMessage("Error: Targeted player not found or offline");
return;
}
// Log
if (sender != null && Nebula.getConfig().getLogOptions().commands) {
Nebula.getLogger().info("[UID: " + sender.getUid() + "] " + sender.getName() + " used command: " + message);
}
// Run command
handler.execute(cmdArgs);
} else {
if (sender != null) {
sender.sendMessage("Invalid Command!");
} else {
Nebula.getLogger().info("Invalid Command!");
}
}
}
}