From 57c457e2e3b9d8c6f673033c178d73f421dbae75 Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Tue, 2 Sep 2025 16:25:21 +0800 Subject: [PATCH 1/6] Custom action start # Conflicts: # leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java # leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java # Conflicts: # leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java --- .../leaves/entity/bot/BotManager.java | 10 ++++ .../bot/action/custom/CustomAction.java | 10 ++++ .../custom/CustomAction_QUESTION_MARK.java | 21 +++++++ .../leavesmc/leaves/bot/agent/Actions.java | 23 +++++++- .../actions/custom/ServerCustomAction.java | 41 +++++++++++++ .../bot/subcommands/action/StartCommand.java | 59 +++++++++++++++++++ .../leaves/entity/bot/CraftBotManager.java | 23 ++++++++ .../entity/bot/actions/CraftCustomAction.java | 21 +++++++ 8 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction.java create mode 100644 leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java create mode 100644 leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java create mode 100644 leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java index c434364ff..8bc552fb4 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java @@ -1,11 +1,15 @@ package org.leavesmc.leaves.entity.bot; import org.bukkit.Location; +import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.entity.bot.action.BotAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; import java.util.Collection; +import java.util.List; import java.util.UUID; /** @@ -44,5 +48,11 @@ public interface BotManager { */ > T newAction(@NotNull Class type); + CustomAction newCustomAction(String actionId); + + void registerAction(CustomAction_QUESTION_MARK executor); + + List getCustomActions(); + BotCreator botCreator(@NotNull String realName, @NotNull Location location); } diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction.java new file mode 100644 index 000000000..94a70e164 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction.java @@ -0,0 +1,10 @@ +package org.leavesmc.leaves.entity.bot.action.custom; + +import org.leavesmc.leaves.entity.bot.action.BotAction; + +public interface CustomAction extends BotAction { + + T getMeta(String key); + + void setMeta(String key, T meta); +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java new file mode 100644 index 000000000..f68d66a58 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java @@ -0,0 +1,21 @@ +package org.leavesmc.leaves.entity.bot.action.custom; + +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.leavesmc.leaves.entity.bot.Bot; + +import java.util.List; + +// I don't know how to name it, meow~ +public interface CustomAction_QUESTION_MARK { + + String id(); + + Plugin provider(); + + boolean doTick(Bot bot); + + List getSuggestion(CommandSender sender, String[] args); + + void loadAction(CommandSender sender, String[] args, CustomAction action); +} 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 214165eb4..b7833842d 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 @@ -5,9 +5,11 @@ import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.agent.actions.*; import org.leavesmc.leaves.entity.bot.action.*; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -16,7 +18,10 @@ public class Actions { private static final Map> actionsByName = new HashMap<>(); private static final Map, AbstractBotAction> actionsByClass = new HashMap<>(); - static { + + private static final Map customActionsById = new HashMap<>(); + + static { register(new ServerAttackAction(), AttackAction.class); register(new ServerBreakBlockAction(), BreakBlockAction.class); register(new ServerDropAction(), DropAction.class); @@ -60,6 +65,22 @@ public static boolean unregister(@NotNull String name) { return false; } + public static void addCustom(CustomAction_QUESTION_MARK questionMark) { + customActionsById.put(questionMark.id(), questionMark); + } + + public static @Nullable CustomAction_QUESTION_MARK getCustom(String id) { + return customActionsById.get(id); + } + + public static void removeCustom(String id) { + customActionsById.remove(id); + } + + public static Collection getCustomActions() { + return customActionsById.keySet(); + } + @NotNull @Contract(pure = true) public static Collection> getAll() { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java new file mode 100644 index 000000000..16c0a1f77 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java @@ -0,0 +1,41 @@ +package org.leavesmc.leaves.bot.agent.actions.custom; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import org.leavesmc.leaves.entity.bot.actions.CraftCustomAction; + +import java.util.HashMap; +import java.util.Map; + +public class ServerCustomAction extends AbstractBotAction { + + private final CustomAction_QUESTION_MARK customAction_QUESTION_MARK; + + private final Map metaMap = new HashMap<>(); + + public ServerCustomAction(CustomAction_QUESTION_MARK customAction_QUESTION_MARK) { + super(customAction_QUESTION_MARK.id(), null); // Don't create here + this.customAction_QUESTION_MARK = customAction_QUESTION_MARK; + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + return customAction_QUESTION_MARK.doTick(bot.getBukkitEntity()); + } + + @Override + public Object asCraft() { + return new CraftCustomAction(this); + } + + @SuppressWarnings("unchecked") + public T getMeta(String key) { + return (T) metaMap.get(key); + } + + public void setMeta(String key, T meta) { + metaMap.put(key, meta); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java index 126c8ea2b..c22967c27 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java @@ -1,9 +1,13 @@ package org.leavesmc.leaves.command.bot.subcommands.action; import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Contract; @@ -11,12 +15,18 @@ import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.bot.agent.Actions; import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction; +import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction; +import org.leavesmc.leaves.command.ArgumentNode; import org.leavesmc.leaves.command.CommandContext; import org.leavesmc.leaves.command.LiteralNode; import org.leavesmc.leaves.command.WrappedArgument; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import static io.papermc.paper.adventure.PaperAdventure.asAdventure; @@ -33,6 +43,7 @@ public class StartCommand extends LiteralNode { public StartCommand() { super("start"); Actions.getAll().stream().map(this::actionNodeCreator).forEach(this::children); + this.children.add(new CustomActionNode()); } private boolean handleStartCommand(CommandContext context, @NotNull AbstractBotAction action) throws CommandSyntaxException { @@ -109,4 +120,52 @@ private ActionLiteralNode(@NotNull AbstractBotAction action) { return builder; } } + + private static class CustomActionNode extends ArgumentNode { + + protected CustomActionNode() { + super("custom", StringArgumentType.greedyString()); + } + + @Override + protected boolean execute(CommandContext context) throws CommandSyntaxException { + ServerBot bot = getBot(context); + CommandSender sender = context.getSender(); + String[] args = StringUtils.split(context.getInput(), ' '); + CustomAction_QUESTION_MARK questionMark = Actions.getCustom(args[0]); + if (questionMark == null) { + throw new IllegalArgumentException(args[0] + " is not a valid custom action"); + } + String[] realArg = Arrays.copyOfRange(args, 1, args.length); + ServerCustomAction action = new ServerCustomAction(questionMark); + questionMark.loadAction(sender, realArg, (CustomAction) action.asCraft()); + if (bot.addBotAction(action, sender)) { + sender.sendMessage(join(spaces(), + text("Action", GRAY), + text(action.getName(), AQUA).hoverEvent(showText(text(action.getActionDataString()))), + text("has been issued to", GRAY), + asAdventure(bot.getDisplayName()) + )); + } + return true; + } + + @Override + protected CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { + String[] args = StringUtils.split(context.getInput(), ' '); + if (args.length == 1) { + Actions.getCustomActions().forEach(builder::suggest); + } else { + CustomAction_QUESTION_MARK questionMark = Actions.getCustom(args[0]); + if (questionMark == null) { + return builder.buildFuture(); + } + String[] realArg = Arrays.copyOfRange(args, 1, args.length); + List suggestion = questionMark.getSuggestion(context.getSender(), realArg); + builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); + suggestion.forEach(builder::suggest); + } + return builder.buildFuture(); + } + } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java index 550985c48..c65b971c0 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java @@ -10,11 +10,15 @@ import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.bot.agent.Actions; import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction; +import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction; import org.leavesmc.leaves.entity.bot.action.BotAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; import org.leavesmc.leaves.event.bot.BotCreateEvent; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.UUID; public class CraftBotManager implements BotManager { @@ -67,6 +71,25 @@ public > T newAction(@NotNull Class type) { } } + @Override + public CustomAction newCustomAction(String actionId) { + CustomAction_QUESTION_MARK questionMark = Actions.getCustom(actionId); + if (questionMark == null) { + throw new IllegalArgumentException("Can't find custom action " + actionId); + } + return (CustomAction) new ServerCustomAction(questionMark).asCraft(); + } + + @Override + public void registerAction(CustomAction_QUESTION_MARK executor) { + + } + + @Override + public List getCustomActions() { + return List.of(); + } + @Override public BotCreator botCreator(@NotNull String realName, @NotNull Location location) { return BotCreateState.builder(realName, location).createReason(BotCreateEvent.CreateReason.PLUGIN); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java new file mode 100644 index 000000000..c1119f2a9 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java @@ -0,0 +1,21 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; + +public class CraftCustomAction extends CraftBotAction implements CustomAction { + + public CraftCustomAction(ServerCustomAction serverAction) { + super(serverAction, CraftCustomAction::new); + } + + @Override + public T getMeta(String key) { + return serverAction.getMeta(key); + } + + @Override + public void setMeta(String key, T meta) { + serverAction.setMeta(key, meta); + } +} From 87fe56d909f2fd0efd183e8679d9173109302368 Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Sun, 7 Sep 2025 14:39:33 +0800 Subject: [PATCH 2/6] Fix build issue and zzz --- .../entity/bot/action/custom/CustomAction_QUESTION_MARK.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java index f68d66a58..48b778868 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java @@ -17,5 +17,5 @@ public interface CustomAction_QUESTION_MARK { List getSuggestion(CommandSender sender, String[] args); - void loadAction(CommandSender sender, String[] args, CustomAction action); + void loadAction(CommandSender sender, String[] args, CustomAction action); } From 94f5db67f27866120470f91cc48de07b19d68d89 Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Tue, 23 Sep 2025 06:24:45 -0700 Subject: [PATCH 3/6] Named provider --- .../org/leavesmc/leaves/entity/bot/BotManager.java | 5 ++--- ..._QUESTION_MARK.java => CustomActionProvider.java} | 4 ++-- .../java/org/leavesmc/leaves/bot/agent/Actions.java | 9 ++++----- .../bot/agent/actions/custom/ServerCustomAction.java | 12 ++++++------ .../command/bot/subcommands/action/StartCommand.java | 6 +++--- .../leavesmc/leaves/entity/bot/CraftBotManager.java | 6 +++--- 6 files changed, 20 insertions(+), 22 deletions(-) rename leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/{CustomAction_QUESTION_MARK.java => CustomActionProvider.java} (89%) diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java index 8bc552fb4..222240288 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java @@ -1,12 +1,11 @@ package org.leavesmc.leaves.entity.bot; import org.bukkit.Location; -import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.entity.bot.action.BotAction; import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; -import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; import java.util.Collection; import java.util.List; @@ -50,7 +49,7 @@ public interface BotManager { CustomAction newCustomAction(String actionId); - void registerAction(CustomAction_QUESTION_MARK executor); + void registerAction(CustomActionProvider executor); List getCustomActions(); diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java similarity index 89% rename from leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java rename to leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java index 48b778868..dc1c9f8c2 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomAction_QUESTION_MARK.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java @@ -7,12 +7,12 @@ import java.util.List; // I don't know how to name it, meow~ -public interface CustomAction_QUESTION_MARK { +public interface CustomActionProvider { String id(); Plugin provider(); - + boolean doTick(Bot bot); List getSuggestion(CommandSender sender, String[] args); 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 b7833842d..e3c8a020a 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 @@ -5,11 +5,10 @@ import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.agent.actions.*; import org.leavesmc.leaves.entity.bot.action.*; -import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; @@ -19,7 +18,7 @@ public class Actions { private static final Map, AbstractBotAction> actionsByClass = new HashMap<>(); - private static final Map customActionsById = new HashMap<>(); + private static final Map customActionsById = new HashMap<>(); static { register(new ServerAttackAction(), AttackAction.class); @@ -65,11 +64,11 @@ public static boolean unregister(@NotNull String name) { return false; } - public static void addCustom(CustomAction_QUESTION_MARK questionMark) { + public static void addCustom(CustomActionProvider questionMark) { customActionsById.put(questionMark.id(), questionMark); } - public static @Nullable CustomAction_QUESTION_MARK getCustom(String id) { + public static @Nullable CustomActionProvider getCustom(String id) { return customActionsById.get(id); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java index 16c0a1f77..b66c8de67 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java @@ -3,7 +3,7 @@ import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction; -import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; import org.leavesmc.leaves.entity.bot.actions.CraftCustomAction; import java.util.HashMap; @@ -11,18 +11,18 @@ public class ServerCustomAction extends AbstractBotAction { - private final CustomAction_QUESTION_MARK customAction_QUESTION_MARK; + private final CustomActionProvider customActionProvider; private final Map metaMap = new HashMap<>(); - public ServerCustomAction(CustomAction_QUESTION_MARK customAction_QUESTION_MARK) { - super(customAction_QUESTION_MARK.id(), null); // Don't create here - this.customAction_QUESTION_MARK = customAction_QUESTION_MARK; + public ServerCustomAction(CustomActionProvider customActionProvider) { + super(customActionProvider.id(), null); // Don't create here + this.customActionProvider = customActionProvider; } @Override public boolean doTick(@NotNull ServerBot bot) { - return customAction_QUESTION_MARK.doTick(bot.getBukkitEntity()); + return customActionProvider.doTick(bot.getBukkitEntity()); } @Override diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java index c22967c27..b420b2532 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java @@ -21,7 +21,7 @@ import org.leavesmc.leaves.command.LiteralNode; import org.leavesmc.leaves.command.WrappedArgument; import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; -import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; import java.util.Arrays; import java.util.List; @@ -132,7 +132,7 @@ protected boolean execute(CommandContext context) throws CommandSyntaxException ServerBot bot = getBot(context); CommandSender sender = context.getSender(); String[] args = StringUtils.split(context.getInput(), ' '); - CustomAction_QUESTION_MARK questionMark = Actions.getCustom(args[0]); + CustomActionProvider questionMark = Actions.getCustom(args[0]); if (questionMark == null) { throw new IllegalArgumentException(args[0] + " is not a valid custom action"); } @@ -156,7 +156,7 @@ protected CompletableFuture getSuggestions(CommandContext context, if (args.length == 1) { Actions.getCustomActions().forEach(builder::suggest); } else { - CustomAction_QUESTION_MARK questionMark = Actions.getCustom(args[0]); + CustomActionProvider questionMark = Actions.getCustom(args[0]); if (questionMark == null) { return builder.buildFuture(); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java index c65b971c0..9a7639bdf 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java @@ -13,7 +13,7 @@ import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction; import org.leavesmc.leaves.entity.bot.action.BotAction; import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; -import org.leavesmc.leaves.entity.bot.action.custom.CustomAction_QUESTION_MARK; +import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; import org.leavesmc.leaves.event.bot.BotCreateEvent; import java.util.Collection; @@ -73,7 +73,7 @@ public > T newAction(@NotNull Class type) { @Override public CustomAction newCustomAction(String actionId) { - CustomAction_QUESTION_MARK questionMark = Actions.getCustom(actionId); + CustomActionProvider questionMark = Actions.getCustom(actionId); if (questionMark == null) { throw new IllegalArgumentException("Can't find custom action " + actionId); } @@ -81,7 +81,7 @@ public CustomAction newCustomAction(String actionId) { } @Override - public void registerAction(CustomAction_QUESTION_MARK executor) { + public void registerAction(CustomActionProvider executor) { } From dfe9bc2a4bcf22ce391acdc1c88beb4d24a8456f Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Wed, 24 Sep 2025 06:45:31 -0700 Subject: [PATCH 4/6] Make custom action work --- .../leaves/entity/bot/BotManager.java | 2 + .../action/custom/CustomActionProvider.java | 3 +- .../leavesmc/leaves/bot/agent/Actions.java | 4 +- .../actions/custom/ServerCustomAction.java | 3 +- .../bot/subcommands/action/StartCommand.java | 67 +++++++++++-------- .../leaves/entity/bot/CraftBotManager.java | 8 ++- 6 files changed, 52 insertions(+), 35 deletions(-) diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java index 222240288..8c8d1034d 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java @@ -51,6 +51,8 @@ public interface BotManager { void registerAction(CustomActionProvider executor); + void unregisterAction(String id); + List getCustomActions(); BotCreator botCreator(@NotNull String realName, @NotNull Location location); diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java index dc1c9f8c2..15e4ce569 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java @@ -6,14 +6,13 @@ import java.util.List; -// I don't know how to name it, meow~ public interface CustomActionProvider { String id(); Plugin provider(); - boolean doTick(Bot bot); + boolean doTick(Bot bot, CustomAction action); List getSuggestion(CommandSender sender, String[] args); 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 e3c8a020a..c0742248a 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 @@ -64,8 +64,8 @@ public static boolean unregister(@NotNull String name) { return false; } - public static void addCustom(CustomActionProvider questionMark) { - customActionsById.put(questionMark.id(), questionMark); + public static void addCustom(CustomActionProvider provider) { + customActionsById.put(provider.id(), provider); } public static @Nullable CustomActionProvider getCustom(String id) { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java index b66c8de67..848df5aa9 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/custom/ServerCustomAction.java @@ -3,6 +3,7 @@ import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction; +import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; import org.leavesmc.leaves.entity.bot.actions.CraftCustomAction; @@ -22,7 +23,7 @@ public ServerCustomAction(CustomActionProvider customActionProvider) { @Override public boolean doTick(@NotNull ServerBot bot) { - return customActionProvider.doTick(bot.getBukkitEntity()); + return customActionProvider.doTick(bot.getBukkitEntity(), (CustomAction) this.asCraft()); } @Override diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java index b420b2532..1b1780329 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java @@ -129,41 +129,50 @@ protected CustomActionNode() { @Override protected boolean execute(CommandContext context) throws CommandSyntaxException { - ServerBot bot = getBot(context); - CommandSender sender = context.getSender(); - String[] args = StringUtils.split(context.getInput(), ' '); - CustomActionProvider questionMark = Actions.getCustom(args[0]); - if (questionMark == null) { - throw new IllegalArgumentException(args[0] + " is not a valid custom action"); - } - String[] realArg = Arrays.copyOfRange(args, 1, args.length); - ServerCustomAction action = new ServerCustomAction(questionMark); - questionMark.loadAction(sender, realArg, (CustomAction) action.asCraft()); - if (bot.addBotAction(action, sender)) { - sender.sendMessage(join(spaces(), - text("Action", GRAY), - text(action.getName(), AQUA).hoverEvent(showText(text(action.getActionDataString()))), - text("has been issued to", GRAY), - asAdventure(bot.getDisplayName()) - )); + try { + ServerBot bot = getBot(context); + CommandSender sender = context.getSender(); + String[] args = StringUtils.split(context.getArgument("custom", String.class), ' '); + CustomActionProvider provider = Actions.getCustom(args[0]); + if (provider == null) { + return false; + } + String[] realArg = Arrays.copyOfRange(args, 1, args.length); + ServerCustomAction action = new ServerCustomAction(provider); + provider.loadAction(sender, realArg, (CustomAction) action.asCraft()); + if (bot.addBotAction(action, sender)) { + sender.sendMessage(join(spaces(), + text("Action", GRAY), + text(action.getName(), AQUA).hoverEvent(showText(text(action.getActionDataString()))), + text("has been issued to", GRAY), + asAdventure(bot.getDisplayName()) + )); + } + return true; + } catch (Exception e) { + e.printStackTrace(); } - return true; + return false; } @Override protected CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { - String[] args = StringUtils.split(context.getInput(), ' '); - if (args.length == 1) { - Actions.getCustomActions().forEach(builder::suggest); - } else { - CustomActionProvider questionMark = Actions.getCustom(args[0]); - if (questionMark == null) { - return builder.buildFuture(); + try { + String[] args = builder.getRemaining().split(" ", -1); + if (args.length <= 1) { + Actions.getCustomActions().forEach(builder::suggest); + } else { + CustomActionProvider provider = Actions.getCustom(args[0]); + if (provider == null) { + return builder.buildFuture(); + } + String[] realArg = Arrays.copyOfRange(args, 1, args.length); + List suggestion = provider.getSuggestion(context.getSender(), realArg); + builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); + suggestion.forEach(builder::suggest); } - String[] realArg = Arrays.copyOfRange(args, 1, args.length); - List suggestion = questionMark.getSuggestion(context.getSender(), realArg); - builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); - suggestion.forEach(builder::suggest); + } catch (Exception e) { + e.printStackTrace(); } return builder.buildFuture(); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java index 9a7639bdf..fc748a5f5 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java @@ -81,10 +81,16 @@ public CustomAction newCustomAction(String actionId) { } @Override - public void registerAction(CustomActionProvider executor) { + public void registerAction(CustomActionProvider provider) { + Actions.addCustom(provider); + } + @Override + public void unregisterAction(String id) { + Actions.removeCustom(id); } + @Override public List getCustomActions() { return List.of(); From 902ddd139605bce2af7377954a28aea8ff786e6c Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Wed, 24 Sep 2025 08:45:27 -0700 Subject: [PATCH 5/6] Reformat and rename --- .../org/leavesmc/leaves/entity/bot/CraftBotManager.java | 7 +++---- .../leaves/entity/bot/actions/CraftCustomAction.java | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java index fc748a5f5..eb2d4d92f 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java @@ -73,11 +73,11 @@ public > T newAction(@NotNull Class type) { @Override public CustomAction newCustomAction(String actionId) { - CustomActionProvider questionMark = Actions.getCustom(actionId); - if (questionMark == null) { + CustomActionProvider provider = Actions.getCustom(actionId); + if (provider == null) { throw new IllegalArgumentException("Can't find custom action " + actionId); } - return (CustomAction) new ServerCustomAction(questionMark).asCraft(); + return (CustomAction) new ServerCustomAction(provider).asCraft(); } @Override @@ -90,7 +90,6 @@ public void unregisterAction(String id) { Actions.removeCustom(id); } - @Override public List getCustomActions() { return List.of(); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java index c1119f2a9..cf9350813 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftCustomAction.java @@ -3,7 +3,7 @@ import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction; import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; -public class CraftCustomAction extends CraftBotAction implements CustomAction { +public class CraftCustomAction extends CraftBotAction implements CustomAction { public CraftCustomAction(ServerCustomAction serverAction) { super(serverAction, CraftCustomAction::new); From 5354e11484139b19c7b536ecabe5bdcc84f26179 Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Thu, 2 Oct 2025 18:43:18 -0700 Subject: [PATCH 6/6] TEMP-Brigadier like command --- .../action/custom/BrigadierLikeProcessor.java | 10 +++++++++ .../action/custom/BukkitLikeProcessor.java | 12 +++++++++++ .../bot/action/custom/CommandProcessor.java | 12 +++++++++++ .../action/custom/CustomActionProvider.java | 21 ++++++++++++------- .../bot/subcommands/action/StartCommand.java | 11 +++++----- 5 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BrigadierLikeProcessor.java create mode 100644 leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BukkitLikeProcessor.java create mode 100644 leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CommandProcessor.java diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BrigadierLikeProcessor.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BrigadierLikeProcessor.java new file mode 100644 index 000000000..d6bfb39ce --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BrigadierLikeProcessor.java @@ -0,0 +1,10 @@ +package org.leavesmc.leaves.entity.bot.action.custom; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import io.papermc.paper.command.brigadier.CommandSourceStack; + +public interface BrigadierLikeProcessor extends CommandProcessor { + + void buildCommand(LiteralArgumentBuilder root); + +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BukkitLikeProcessor.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BukkitLikeProcessor.java new file mode 100644 index 000000000..c4374f260 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/BukkitLikeProcessor.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action.custom; + +import org.bukkit.command.CommandSender; + +import java.util.List; + +public interface BukkitLikeProcessor extends CommandProcessor { + + List getSuggestion(CommandSender sender, String[] args); + + void loadAction(CommandSender sender, String[] args, CustomAction action); +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CommandProcessor.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CommandProcessor.java new file mode 100644 index 000000000..f822832eb --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CommandProcessor.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action.custom; + +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public interface CommandProcessor { + + @ApiStatus.Internal + CommandProcessor DUMMY_PROCESSOR = new CommandProcessor() { + + }; +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java index 15e4ce569..436228253 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/custom/CustomActionProvider.java @@ -1,20 +1,25 @@ package org.leavesmc.leaves.entity.bot.action.custom; -import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.ApiStatus; import org.leavesmc.leaves.entity.bot.Bot; -import java.util.List; +public abstract class CustomActionProvider { -public interface CustomActionProvider { + private CommandProcessor processor = CommandProcessor.DUMMY_PROCESSOR; - String id(); + public abstract String id(); - Plugin provider(); + public abstract Plugin provider(); - boolean doTick(Bot bot, CustomAction action); + public abstract boolean doTick(Bot bot, CustomAction action); - List getSuggestion(CommandSender sender, String[] args); + public void withProcessor(CommandProcessor processor) { + this.processor = processor; + } - void loadAction(CommandSender sender, String[] args, CustomAction action); + @ApiStatus.Internal + public CommandProcessor processor() { + return processor; + } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java index 1b1780329..adfb32645 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/action/StartCommand.java @@ -20,6 +20,7 @@ import org.leavesmc.leaves.command.CommandContext; import org.leavesmc.leaves.command.LiteralNode; import org.leavesmc.leaves.command.WrappedArgument; +import org.leavesmc.leaves.entity.bot.action.custom.BukkitLikeProcessor; import org.leavesmc.leaves.entity.bot.action.custom.CustomAction; import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider; @@ -128,18 +129,18 @@ protected CustomActionNode() { } @Override - protected boolean execute(CommandContext context) throws CommandSyntaxException { + protected boolean execute(CommandContext context) { try { ServerBot bot = getBot(context); CommandSender sender = context.getSender(); String[] args = StringUtils.split(context.getArgument("custom", String.class), ' '); CustomActionProvider provider = Actions.getCustom(args[0]); - if (provider == null) { + if (provider == null || !(provider.processor() instanceof BukkitLikeProcessor processor)) { return false; } String[] realArg = Arrays.copyOfRange(args, 1, args.length); ServerCustomAction action = new ServerCustomAction(provider); - provider.loadAction(sender, realArg, (CustomAction) action.asCraft()); + processor.loadAction(sender, realArg, (CustomAction) action.asCraft()); if (bot.addBotAction(action, sender)) { sender.sendMessage(join(spaces(), text("Action", GRAY), @@ -163,11 +164,11 @@ protected CompletableFuture getSuggestions(CommandContext context, Actions.getCustomActions().forEach(builder::suggest); } else { CustomActionProvider provider = Actions.getCustom(args[0]); - if (provider == null) { + if (provider == null || !(provider.processor() instanceof BukkitLikeProcessor processor)) { return builder.buildFuture(); } String[] realArg = Arrays.copyOfRange(args, 1, args.length); - List suggestion = provider.getSuggestion(context.getSender(), realArg); + List suggestion = processor.getSuggestion(context.getSender(), realArg); builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); suggestion.forEach(builder::suggest); }