9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-30 04:19:30 +00:00

fix: fix custom bot action api, refactor

This commit is contained in:
MC_XiaoHei
2025-07-08 12:08:12 +08:00
parent 90a5a1d450
commit afefaec186
9 changed files with 68 additions and 17 deletions

View File

@@ -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

View File

@@ -21,13 +21,13 @@ public interface CustomBotAction extends BotAction<CustomBotAction> {
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.

View File

@@ -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;
}

View File

@@ -1,8 +1,9 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
public interface CraftCustomAction<E> {
public E createCraft(@Nullable Player player, String[] args);
E createCraft(Player player, String[] args);
E createEmptyCraft();
}

View File

@@ -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<CustomBotAction> implements CraftCustomAction<CraftCustomBotAction> {
private final CustomBotAction realAction;
@@ -18,13 +20,23 @@ public class CraftCustomBotAction extends CraftBotAction<CustomBotAction> 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());

View File

@@ -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<CustomStateBotAction> implements CraftCustomAction<CraftCustomStateBotAction> {
private final CustomStateBotAction realAction;
@@ -25,6 +27,16 @@ public class CraftCustomStateBotAction extends CraftStateBotAction<CustomStateBo
return null;
}
@Override
public CraftCustomStateBotAction createEmptyCraft() {
try {
CustomStateBotAction newRealAction = realAction.getClass().getConstructor().newInstance();
return new CraftCustomStateBotAction(this.getName(), newRealAction);
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public Class<CustomStateBotAction> getInterfaceClass() {
return null;

View File

@@ -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<CustomTimerBotAction> implements CraftCustomAction<CraftCustomTimerBotAction> {
private final CustomTimerBotAction realAction;
@@ -30,6 +32,16 @@ public class CraftCustomTimerBotAction extends CraftTimerBotAction<CustomTimerBo
return null;
}
@Override
public CraftCustomTimerBotAction createEmptyCraft() {
try {
CustomTimerBotAction newRealAction = realAction.getClass().getConstructor().newInstance();
return new CraftCustomTimerBotAction(this.getName(), newRealAction);
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public int getDoNumber() {
return realAction.getDoNumber();

View File

@@ -39,12 +39,15 @@ public class CraftBot extends CraftPlayer implements Bot {
}
@Override
public void addAction(@NotNull BotAction action) {
this.getHandle().addBotAction((CraftBotAction<?>) 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);

View File

@@ -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 extends BotAction<T>> T newAction(@NotNull Class<T> 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);