From afefaec186a7f2ec98c01de3eeb7b4e6104317be Mon Sep 17 00:00:00 2001 From: MC_XiaoHei Date: Tue, 8 Jul 2025 12:08:12 +0800 Subject: [PATCH] fix: fix custom bot action api, refactor --- .../java/org/leavesmc/leaves/entity/bot/Bot.java | 4 ++-- .../leaves/entity/bot/action/CustomBotAction.java | 4 ++-- .../org/leavesmc/leaves/bot/agent/Actions.java | 8 ++++++-- .../bot/agent/actions/CraftCustomAction.java | 5 +++-- .../bot/agent/actions/CraftCustomBotAction.java | 14 +++++++++++++- .../agent/actions/CraftCustomStateBotAction.java | 12 ++++++++++++ .../agent/actions/CraftCustomTimerBotAction.java | 12 ++++++++++++ .../java/org/leavesmc/leaves/entity/CraftBot.java | 11 +++++++---- .../leavesmc/leaves/entity/CraftBotManager.java | 15 +++++++++++---- 9 files changed, 68 insertions(+), 17 deletions(-) diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java index 479ea83e..da4b5cac 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java @@ -39,7 +39,7 @@ public interface Bot extends Player { * @param action bot action */ @org.jetbrains.annotations.ApiStatus.Experimental - void addAction(@NotNull BotAction action); + void addAction(@NotNull BotAction action); /** * Get the copy action in giving index @@ -48,7 +48,7 @@ public interface Bot extends Player { * @return Action of that index */ @org.jetbrains.annotations.ApiStatus.Experimental - BotAction getAction(int index); + BotAction getAction(int index); /** * Get action size diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/CustomBotAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/CustomBotAction.java index 713cbc0f..c8bffe37 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/CustomBotAction.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/CustomBotAction.java @@ -21,13 +21,13 @@ public interface CustomBotAction extends BotAction { boolean doTick(Bot bot); /** - * Created a new action instance. + * Created a new action instance from command. * * @param player player who create this action * @param args passed action arguments * @return a new action instance with given args */ - @Nullable CustomBotAction getNew(@Nullable Player player, String[] args); + @Nullable CustomBotAction fromCommand(Player player, String[] args); /** * Requests a list of possible completions for a action argument. diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java index e7c381d8..fb1f52fa 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java @@ -28,6 +28,7 @@ import org.leavesmc.leaves.entity.bot.action.BotAction; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.Set; public class Actions { @@ -60,7 +61,8 @@ public class Actions { public static boolean register(@NotNull CraftBotAction action) { if (!actionsByName.containsKey(action.getName())) { actionsByName.put(action.getName(), action); - actionsByClass.put(action.getInterfaceClass(), action); + Class interfaceClass = action.getInterfaceClass(); + actionsByClass.put(Objects.requireNonNullElseGet(interfaceClass, action::getClass), action); return true; } return false; @@ -68,7 +70,9 @@ public class Actions { public static boolean unregister(@NotNull String name) { if (actionsByName.containsKey(name)) { - actionsByClass.remove(actionsByName.get(name).getInterfaceClass()); + CraftBotAction action = actionsByName.get(name); + Class interfaceClass = action.getInterfaceClass(); + actionsByClass.remove(Objects.requireNonNullElseGet(interfaceClass, action::getClass)); actionsByName.remove(name); return true; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomAction.java index a3411668..a850464d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomAction.java @@ -1,8 +1,9 @@ package org.leavesmc.leaves.bot.agent.actions; import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; public interface CraftCustomAction { - public E createCraft(@Nullable Player player, String[] args); + E createCraft(Player player, String[] args); + + E createEmptyCraft(); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java index a405176a..931bd01d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java @@ -7,6 +7,8 @@ import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.entity.bot.action.CustomBotAction; +import java.lang.reflect.InvocationTargetException; + public class CraftCustomBotAction extends CraftBotAction implements CraftCustomAction { private final CustomBotAction realAction; @@ -18,13 +20,23 @@ public class CraftCustomBotAction extends CraftBotAction implem @Override public CraftCustomBotAction createCraft(@Nullable Player player, String[] args) { - CustomBotAction newRealAction = realAction.getNew(player, args); + CustomBotAction newRealAction = realAction.fromCommand(player, args); if (newRealAction != null) { return new CraftCustomBotAction(this.getName(), newRealAction); } return null; } + @Override + public CraftCustomBotAction createEmptyCraft() { + try { + CustomBotAction newRealAction = realAction.getClass().getConstructor().newInstance(); + return new CraftCustomBotAction(this.getName(), newRealAction); + } catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + @Override public boolean doTick(@NotNull ServerBot bot) { return realAction.doTick(bot.getBukkitEntity()); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomStateBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomStateBotAction.java index d17ad4a3..65e3a6d0 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomStateBotAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomStateBotAction.java @@ -7,6 +7,8 @@ import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.entity.bot.action.CustomStateBotAction; +import java.lang.reflect.InvocationTargetException; + public class CraftCustomStateBotAction extends CraftStateBotAction implements CraftCustomAction { private final CustomStateBotAction realAction; @@ -25,6 +27,16 @@ public class CraftCustomStateBotAction extends CraftStateBotAction getInterfaceClass() { return null; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomTimerBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomTimerBotAction.java index ee6c60e8..d0ff4a50 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomTimerBotAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomTimerBotAction.java @@ -7,6 +7,8 @@ import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.entity.bot.action.CustomTimerBotAction; +import java.lang.reflect.InvocationTargetException; + public class CraftCustomTimerBotAction extends CraftTimerBotAction implements CraftCustomAction { private final CustomTimerBotAction realAction; @@ -30,6 +32,16 @@ public class CraftCustomTimerBotAction extends CraftTimerBotAction) action, null); + public void addAction(@NotNull BotAction action) { + if (!(action instanceof CraftBotAction craftBotAction)) { + throw new IllegalArgumentException("Action must be an instance of CraftBotAction! Are you forget to use `BotManager#newAction`?"); + } + this.getHandle().addBotAction(craftBotAction, null); } @Override - public BotAction getAction(int index) { + public BotAction getAction(int index) { return this.getHandle().getBotActions().get(index); } @@ -72,7 +75,7 @@ public class CraftBot extends CraftPlayer implements Bot { } @Override - public boolean teleport(Location location, PlayerTeleportEvent.@NotNull TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) { + public boolean teleport(Location location, PlayerTeleportEvent.@NotNull TeleportCause cause, io.papermc.paper.entity.TeleportFlag @NotNull ... flags) { Preconditions.checkArgument(location != null, "location cannot be null"); Preconditions.checkState(location.getWorld().equals(this.getWorld()), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!"); return super.teleport(location, cause, flags); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java index 2c4e9cb6..5e8da690 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java @@ -11,11 +11,14 @@ import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.bot.agent.Actions; import org.leavesmc.leaves.bot.agent.actions.CraftBotAction; import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction; +import org.leavesmc.leaves.bot.agent.actions.CraftCustomStateBotAction; +import org.leavesmc.leaves.bot.agent.actions.CraftCustomTimerBotAction; import org.leavesmc.leaves.entity.bot.Bot; import org.leavesmc.leaves.entity.bot.BotCreator; import org.leavesmc.leaves.entity.bot.BotManager; import org.leavesmc.leaves.entity.bot.action.BotAction; import org.leavesmc.leaves.entity.bot.action.CustomBotAction; +import org.leavesmc.leaves.entity.bot.action.CustomStateBotAction; import org.leavesmc.leaves.entity.bot.action.CustomTimerBotAction; import org.leavesmc.leaves.event.bot.BotCreateEvent; @@ -30,7 +33,7 @@ public class CraftBotManager implements BotManager { public CraftBotManager() { this.botList = MinecraftServer.getServer().getBotList(); - this.botViews = Collections.unmodifiableList(Lists.transform(botList.bots, bot -> bot.getBukkitEntity())); + this.botViews = Collections.unmodifiableList(Lists.transform(botList.bots, ServerBot::getBukkitEntity)); } @Override @@ -75,14 +78,18 @@ public class CraftBotManager implements BotManager { @SuppressWarnings("unchecked") @Override public > T newAction(@NotNull Class type) { - if (type.isAssignableFrom(CustomBotAction.class) || type.isAssignableFrom(CustomTimerBotAction.class)) { - throw new IllegalArgumentException("Custom bot action should create by yourself."); - } T action = Actions.getForClass(type); if (action == null) { throw new IllegalArgumentException("No action registered for type: " + type.getName()); } try { + if (type.isAssignableFrom(CustomBotAction.class)) { + return (T) ((CraftCustomBotAction) action).createEmptyCraft(); + } else if (type.isAssignableFrom(CustomTimerBotAction.class)) { + return (T) ((CraftCustomTimerBotAction) action).createEmptyCraft(); + } else if (type.isAssignableFrom(CustomStateBotAction.class)) { + return (T) ((CraftCustomStateBotAction) action).createEmptyCraft(); + } return (T) ((CraftBotAction) action).create(); } catch (Exception e) { throw new RuntimeException("Failed to create action of type: " + type.getName(), e);