9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-29 11:59:17 +00:00

feat: add bot remove, fix stupid me

This commit is contained in:
MC_XiaoHei
2025-08-24 12:09:21 +08:00
parent 58500b9568
commit 3e2b63c99d
6 changed files with 174 additions and 26 deletions

View File

@@ -54,7 +54,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.function.Predicate;
@@ -127,13 +126,6 @@ public final class LeavesConfig {
MinecraftServer.getServer().server.syncCommands();
}
public static void unregisterCommand(String name) {
name = name.toLowerCase(Locale.ENGLISH).trim();
MinecraftServer.getServer().server.getCommandMap().getKnownCommands().remove(name);
MinecraftServer.getServer().server.getCommandMap().getKnownCommands().remove("leaves:" + name);
MinecraftServer.getServer().server.syncCommands();
}
public static ModifyConfig modify = new ModifyConfig();
@GlobalConfigCategory("modify")
@@ -152,10 +144,9 @@ public final class LeavesConfig {
@Override
public void verify(Boolean old, Boolean value) throws IllegalArgumentException {
if (value) {
BotCommand.INSTANCE.register();
Actions.registerAll();
BotCommand.INSTANCE.register();
} else {
unregisterCommand("bot");
BotCommand.INSTANCE.unregister();
}
if (old != null && !old.equals(value)) {

View File

@@ -191,7 +191,7 @@ public class BotList {
this.server.server.getPluginManager().callEvent(event);
if (event.isCancelled() && event.getReason() != BotRemoveEvent.RemoveReason.INTERNAL) {
return true;
return false;
}
if (bot.removeTaskId != -1) {

View File

@@ -70,8 +70,7 @@ public class CraftBot extends CraftPlayer implements Bot {
@Override
public boolean remove(boolean save) {
BotList.INSTANCE.removeBot(this.getHandle(), BotRemoveEvent.RemoveReason.PLUGIN, null, save);
return true;
return BotList.INSTANCE.removeBot(this.getHandle(), BotRemoveEvent.RemoveReason.PLUGIN, null, save);
}
@Override

View File

@@ -12,6 +12,7 @@ import org.leavesmc.leaves.neo_command.bot.subcommands.ConfigCommand;
import org.leavesmc.leaves.neo_command.bot.subcommands.CreateCommand;
import org.leavesmc.leaves.neo_command.bot.subcommands.ListCommand;
import org.leavesmc.leaves.neo_command.bot.subcommands.LoadCommand;
import org.leavesmc.leaves.neo_command.bot.subcommands.RemoveCommand;
import org.leavesmc.leaves.neo_command.bot.subcommands.SaveCommand;
import java.util.ArrayList;
@@ -24,12 +25,13 @@ public class BotCommand extends LiteralNode {
private BotCommand() {
super("bot");
this.children(
ActionCommand::new,
ListCommand::new,
CreateCommand::new,
ConfigCommand::new,
RemoveCommand::new,
LoadCommand::new,
SaveCommand::new,
ConfigCommand::new
ActionCommand::new,
CreateCommand::new
);
}

View File

@@ -0,0 +1,155 @@
package org.leavesmc.leaves.neo_command.bot.subcommands;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import io.papermc.paper.adventure.PaperAdventure;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.event.bot.BotRemoveEvent;
import org.leavesmc.leaves.neo_command.ArgumentNode;
import org.leavesmc.leaves.neo_command.CommandContext;
import org.leavesmc.leaves.neo_command.CustomArgumentNode;
import org.leavesmc.leaves.neo_command.bot.BotSubcommand;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static net.kyori.adventure.text.Component.join;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.JoinConfiguration.spaces;
import static net.kyori.adventure.text.format.NamedTextColor.*;
import static net.minecraft.network.chat.Component.literal;
public class RemoveCommand extends BotSubcommand {
public RemoveCommand() {
super("remove");
children(BotArgument::new);
}
private static boolean removeBot(@NotNull ServerBot bot, @Nullable CommandSender sender) {
boolean success = BotList.INSTANCE.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, false);
if (!success) {
sender = sender == null ? Bukkit.getConsoleSender() : sender;
sender.sendMessage(text("Bot remove canceled by a plugin", RED));
}
return success;
}
private static class BotArgument extends CustomArgumentNode<ServerBot, String> {
public BotArgument() {
super("bot", new org.leavesmc.leaves.neo_command.bot.BotArgument());
children(RemoveTimeArgument::new);
}
@Override
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
ServerBot bot = context.getCustomArgument(BotArgument.class);
return removeBot(bot, context.getSender());
}
}
private static class RemoveTimeArgument extends ArgumentNode<String> {
private RemoveTimeArgument() {
super("remove_time", StringArgumentType.word());
}
@Override
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
String removeTimeStr = context.getArgument("remove_time", String.class);
int removeTimeSeconds = parseRemoveTime(removeTimeStr);
ServerBot bot = context.getCustomArgument(BotArgument.class);
CommandSender sender = context.getSender();
boolean isReschedule = bot.removeTaskId != -1;
if (isReschedule) {
Bukkit.getScheduler().cancelTask(bot.removeTaskId);
}
bot.removeTaskId = Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> {
bot.removeTaskId = -1;
removeBot(bot, sender);
}, removeTimeSeconds * 20L).getTaskId();
sender.sendMessage(join(spaces(),
text("Bot", GRAY),
PaperAdventure.asAdventure(bot.getDisplayName()),
text("scheduled for removal in", GRAY),
text(formatSeconds(removeTimeSeconds), AQUA),
text(isReschedule ? "(rescheduled)" : "", GRAY)
));
return true;
}
private static int parseRemoveTime(String timeStr) throws CommandSyntaxException {
if (timeStr == null || timeStr.trim().isEmpty()) {
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
}
if (!timeStr.matches("^[\\d\\shmsHMS]+$")) {
throw new CommandSyntaxException(
CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException(),
literal("Invalid time format: " + timeStr)
);
}
String remaining = timeStr.replaceAll("\\d+[hmsHMS]", "").trim();
if (!remaining.isEmpty() && remaining.matches(".*\\d+.*")) {
throw new CommandSyntaxException(
CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException(),
literal("Found trailing numbers without unit: " + timeStr)
);
}
Matcher matcher = Pattern.compile("(\\d+)([hmsHMS])").matcher(timeStr);
int seconds = 0;
boolean foundMatch = false;
while (matcher.find()) {
foundMatch = true;
int value = Integer.parseInt(matcher.group(1));
switch (matcher.group(2).toLowerCase()) {
case "h": seconds += value * 3600; break;
case "m": seconds += value * 60; break;
case "s": seconds += value; break;
}
}
if (!foundMatch) {
throw new CommandSyntaxException(
CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException(),
literal("No valid time units found in: " + timeStr)
);
}
return seconds;
}
private static @NotNull String formatSeconds(int totalSeconds) {
int h = totalSeconds / 3600;
int m = (totalSeconds % 3600) / 60;
int s = totalSeconds % 60;
StringBuilder sb = new StringBuilder();
if (h > 0) {
sb.append(h).append("h");
}
if (m > 0) {
sb.append(m).append("m");
}
if (s > 0) {
sb.append(s).append("s");
}
if (sb.isEmpty()) {
sb.append("0s");
}
return sb.toString();
}
}
}

View File

@@ -32,7 +32,7 @@ public class SaveCommand extends BotSubcommand {
private static class BotArgument extends CustomArgumentNode<ServerBot, String> {
public BotArgument() {
private BotArgument() {
super("bot", new org.leavesmc.leaves.neo_command.bot.BotArgument());
}
@@ -42,16 +42,17 @@ public class SaveCommand extends BotSubcommand {
CommandSender sender = context.getSender();
BotList botList = BotList.INSTANCE;
if (!botList.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, true)) {
sender.sendMessage(text("Failed to save bot, please check log", NamedTextColor.RED));
return false;
boolean success = botList.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, true);
if (success) {
sender.sendMessage(join(spaces(),
text("Successfully saved bot", NamedTextColor.GRAY),
asAdventure(bot.getDisplayName()),
text("as " + bot.createState.realName(), NamedTextColor.GRAY)
));
} else {
sender.sendMessage(text("Bot save canceled by a plugin", NamedTextColor.RED));
}
sender.sendMessage(join(spaces(),
text("Successfully saved bot", NamedTextColor.GRAY),
asAdventure(bot.getDisplayName()),
text("as " + bot.createState.realName(), NamedTextColor.GRAY)
));
return true;
return success;
}
}
}