mirror of
https://github.com/System-End/Discord-MC-Chat.git
synced 2026-04-19 22:05:11 +00:00
命令系统4
This commit is contained in:
parent
38f4839c4f
commit
d6d0307ea0
8 changed files with 268 additions and 13 deletions
|
|
@ -0,0 +1,86 @@
|
|||
package com.xujiayao.discord_mc_chat.commands;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.commands.impl.HelpCommand;
|
||||
import com.xujiayao.discord_mc_chat.commands.impl.ReloadCommand;
|
||||
import com.xujiayao.discord_mc_chat.commands.impl.ShutdownCommand;
|
||||
import com.xujiayao.discord_mc_chat.utils.config.ModeManager;
|
||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.xujiayao.discord_mc_chat.Constants.LOGGER;
|
||||
|
||||
/**
|
||||
* Central registry and dispatcher for DMCC commands.
|
||||
*
|
||||
* @author Xujiayao
|
||||
*/
|
||||
public class CommandManager {
|
||||
|
||||
private static final Map<String, Command> COMMANDS = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Initialize and register built-in commands based on the current operating mode.
|
||||
*/
|
||||
public static void initialize() {
|
||||
COMMANDS.clear();
|
||||
|
||||
register(new HelpCommand());
|
||||
register(new ReloadCommand());
|
||||
|
||||
if ("standalone".equals(ModeManager.getMode())) {
|
||||
register(new ShutdownCommand());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command.
|
||||
*
|
||||
* @param command The command to register
|
||||
*/
|
||||
public static void register(Command command) {
|
||||
COMMANDS.put(command.name().toLowerCase(), command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered commands.
|
||||
*
|
||||
* @return A collection of registered commands
|
||||
*/
|
||||
public static Collection<Command> getCommands() {
|
||||
return new ArrayList<>(COMMANDS.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command line.
|
||||
*
|
||||
* @param sender The command sender
|
||||
* @param rawInput The raw command line
|
||||
*/
|
||||
public static void execute(CommandSender sender, String rawInput) {
|
||||
String line = rawInput == null ? "" : rawInput.trim();
|
||||
if (line.isEmpty()) {
|
||||
sender.reply(I18nManager.getDmccTranslation("terminal.unknown_command", rawInput));
|
||||
return;
|
||||
}
|
||||
|
||||
String[] parts = line.split("\\s+");
|
||||
String name = parts[0].toLowerCase();
|
||||
String[] args = parts.length > 1 ? line.substring(line.indexOf(' ') + 1).split("\\s+") : new String[0];
|
||||
|
||||
Command command = COMMANDS.get(name);
|
||||
if (command == null) {
|
||||
sender.reply(I18nManager.getDmccTranslation("terminal.unknown_command", rawInput));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
command.execute(sender, args);
|
||||
} catch (Exception e) {
|
||||
sender.reply("Command execution failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.xujiayao.discord_mc_chat.commands.impl;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.commands.Command;
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandManager;
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandSender;
|
||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Help command implementation.
|
||||
*
|
||||
* @author Xujiayao
|
||||
*/
|
||||
public class HelpCommand implements Command {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "help";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] args() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return I18nManager.getDmccTranslation("commands.help.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String... args) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(I18nManager.getDmccTranslation("commands.help.description")).append("\n");
|
||||
|
||||
CommandManager.getCommands().stream()
|
||||
.sorted(Comparator.comparing(Command::name))
|
||||
.forEach(cmd -> builder.append("- ")
|
||||
.append(cmd.name())
|
||||
.append(": ")
|
||||
.append(cmd.description())
|
||||
.append("\n"));
|
||||
|
||||
sender.reply(builder.toString().trim());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.xujiayao.discord_mc_chat.commands.impl;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.DMCC;
|
||||
import com.xujiayao.discord_mc_chat.commands.Command;
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandSender;
|
||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||
|
||||
/**
|
||||
* Reload command implementation.
|
||||
*
|
||||
* @author Xujiayao
|
||||
*/
|
||||
public class ReloadCommand implements Command {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] args() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return I18nManager.getDmccTranslation("commands.reload.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String... args) {
|
||||
Thread thread = new Thread(() -> {
|
||||
if (DMCC.reload()) {
|
||||
sender.reply(I18nManager.getDmccTranslation("commands.reload.success"));
|
||||
} else {
|
||||
sender.reply(I18nManager.getDmccTranslation("commands.reload.failure", "See logs for details"));
|
||||
}
|
||||
}, "DMCC-ReloadCommand");
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.xujiayao.discord_mc_chat.commands.impl;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.DMCC;
|
||||
import com.xujiayao.discord_mc_chat.commands.Command;
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandSender;
|
||||
import com.xujiayao.discord_mc_chat.standalone.StandaloneDMCC;
|
||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||
|
||||
/**
|
||||
* Shutdown command implementation (standalone only).
|
||||
*
|
||||
* @author Xujiayao
|
||||
*/
|
||||
public class ShutdownCommand implements Command {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "shutdown";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] args() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return I18nManager.getDmccTranslation("commands.shutdown.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String... args) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.xujiayao.discord_mc_chat.server.discord;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandManager;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.events.session.ReadyEvent;
|
||||
|
|
@ -21,6 +22,9 @@ public class DiscordEventHandler extends ListenerAdapter {
|
|||
@Override
|
||||
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
|
||||
event.deferReply().queue();
|
||||
|
||||
// TODO Confirm whether event.getName() is correct
|
||||
CommandManager.execute(new JdaCommandSender(event), event.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
package com.xujiayao.discord_mc_chat.server.discord;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.utils.config.ConfigManager;
|
||||
import com.xujiayao.discord_mc_chat.utils.config.ModeManager;
|
||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||
import net.dv8tion.jda.api.requests.GatewayIntent;
|
||||
import net.dv8tion.jda.api.utils.MemberCachePolicy;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.xujiayao.discord_mc_chat.Constants.LOGGER;
|
||||
|
||||
|
|
@ -47,10 +51,15 @@ public class DiscordManager {
|
|||
|
||||
LOGGER.info("Discord bot is ready. Logged in as tag: \"{}\"", jda.getSelfUser().getAsTag());
|
||||
|
||||
List<CommandData> commands = new ArrayList<>();
|
||||
commands.add(Commands.slash("help", I18nManager.getDmccTranslation("commands.help.description")));
|
||||
commands.add(Commands.slash("reload", I18nManager.getDmccTranslation("commands.reload.description")));
|
||||
if ("standalone".equals(ModeManager.getMode())) {
|
||||
commands.add(Commands.slash("shutdown", I18nManager.getDmccTranslation("commands.shutdown.description")));
|
||||
}
|
||||
|
||||
jda.updateCommands()
|
||||
.addCommands(Commands.slash("help", I18nManager.getDmccTranslation("commands.help.description")))
|
||||
.addCommands(Commands.slash("reload", I18nManager.getDmccTranslation("commands.reload.description")))
|
||||
.addCommands(Commands.slash("shutdown", I18nManager.getDmccTranslation("commands.shutdown.description")))
|
||||
.addCommands(commands)
|
||||
.queue();
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.xujiayao.discord_mc_chat.server.discord;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandSender;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
|
||||
/**
|
||||
* Command sender implementation for JDA slash commands.
|
||||
*
|
||||
* @author Xujiayao
|
||||
*/
|
||||
public class JdaCommandSender implements CommandSender {
|
||||
|
||||
private final SlashCommandInteractionEvent event;
|
||||
|
||||
public JdaCommandSender(SlashCommandInteractionEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(String message) {
|
||||
event.getHook().sendMessage("```" + message + "```").queue();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.xujiayao.discord_mc_chat.standalone;
|
||||
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandManager;
|
||||
import com.xujiayao.discord_mc_chat.commands.CommandSender;
|
||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
|
@ -33,20 +35,12 @@ public class TerminalManager {
|
|||
if (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
|
||||
// Remove leading slash if present
|
||||
if (line.startsWith("/")) {
|
||||
line = line.substring(1);
|
||||
}
|
||||
|
||||
String command = line.trim().split("\\s+")[0];
|
||||
// Arguments do not include the command itself
|
||||
String[] args = line.trim().split("\\s+").length > 1
|
||||
? line.trim().split("\\s+", 2)[1].split("\\s+")
|
||||
: new String[0];
|
||||
|
||||
// TODO Handle command
|
||||
if (true) {
|
||||
LOGGER.error(I18nManager.getDmccTranslation("terminal.unknown_command", line));
|
||||
}
|
||||
CommandManager.execute(new TerminalCommandSender(), line);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
// This can happen if System.in is closed externally, which signals the end.
|
||||
|
|
@ -61,4 +55,20 @@ public class TerminalManager {
|
|||
terminalThread.setDaemon(true);
|
||||
terminalThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* A CommandSender implementation for terminal commands.
|
||||
*
|
||||
* @author Xujiayao
|
||||
*/
|
||||
private static class TerminalCommandSender implements CommandSender {
|
||||
|
||||
@Override
|
||||
public void reply(String message) {
|
||||
// For each line in the message, send a separate log message
|
||||
for (String line : message.split("\n")) {
|
||||
LOGGER.info(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue