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

fix: fix custom bot action api, refactor

This commit is contained in:
MC_XiaoHei
2025-07-09 10:10:44 +08:00
parent fe48dce0b3
commit bcfbc1d362
14 changed files with 272 additions and 128 deletions

View File

@@ -40,11 +40,10 @@ public interface BotManager {
/**
* Register a custom bot action.
*
* @param name action name
* @param action action executor
* @return true if success, or false
*/
boolean registerCustomBotAction(String name, CustomBotAction action);
boolean registerCustomBotAction(CustomBotAction<?> action);
/**
* Unregister a custom bot action.

View File

@@ -0,0 +1,54 @@
package org.leavesmc.leaves.entity.bot.action;
import java.util.UUID;
import java.util.function.Consumer;
public abstract class AbstractCustomBotAction implements BotAction<AbstractCustomBotAction>, CustomBotAction<AbstractCustomBotAction> {
private boolean cancelled = false;
private Consumer<AbstractCustomBotAction> onFail = null, onSuccess = null, onStop = null;
@Override
public final UUID getUUID() {
throw new UnsupportedOperationException("getUUID() is not supported in CustomBotAction");
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setOnFail(Consumer<AbstractCustomBotAction> onFail) {
this.onFail = onFail;
}
@Override
public Consumer<AbstractCustomBotAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<AbstractCustomBotAction> onSuccess) {
this.onSuccess = onSuccess;
}
@Override
public Consumer<AbstractCustomBotAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<AbstractCustomBotAction> onStop) {
this.onStop = onStop;
}
@Override
public Consumer<AbstractCustomBotAction> getOnStop() {
return onStop;
}
}

View File

@@ -0,0 +1,54 @@
package org.leavesmc.leaves.entity.bot.action;
import java.util.UUID;
import java.util.function.Consumer;
public abstract class AbstractCustomStateBotAction implements StateBotAction<AbstractCustomStateBotAction>, CustomBotAction<AbstractCustomStateBotAction> {
private boolean cancelled = false;
private Consumer<AbstractCustomStateBotAction> onFail = null, onSuccess = null, onStop = null;
@Override
public final UUID getUUID() {
throw new UnsupportedOperationException("getUUID() is not supported in CustomBotAction");
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setOnFail(Consumer<AbstractCustomStateBotAction> onFail) {
this.onFail = onFail;
}
@Override
public Consumer<AbstractCustomStateBotAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<AbstractCustomStateBotAction> onSuccess) {
this.onSuccess = onSuccess;
}
@Override
public Consumer<AbstractCustomStateBotAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<AbstractCustomStateBotAction> onStop) {
this.onStop = onStop;
}
@Override
public Consumer<AbstractCustomStateBotAction> getOnStop() {
return onStop;
}
}

View File

@@ -0,0 +1,95 @@
package org.leavesmc.leaves.entity.bot.action;
import java.util.UUID;
import java.util.function.Consumer;
public abstract class AbstractCustomTimerBotAction implements TimerBotAction<AbstractCustomTimerBotAction>, CustomBotAction<AbstractCustomTimerBotAction> {
private boolean cancelled = false;
private int startDelayTick = 0, doIntervalTick = 0, doNumber = 0;
private Consumer<AbstractCustomTimerBotAction> onFail = null, onSuccess = null, onStop = null;
@Override
public final UUID getUUID() {
throw new UnsupportedOperationException("getUUID() is not supported in CustomTimerBotAction");
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setOnFail(Consumer<AbstractCustomTimerBotAction> onFail) {
this.onFail = onFail;
}
@Override
public Consumer<AbstractCustomTimerBotAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<AbstractCustomTimerBotAction> onSuccess) {
this.onSuccess = onSuccess;
}
@Override
public Consumer<AbstractCustomTimerBotAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<AbstractCustomTimerBotAction> onStop) {
this.onStop = onStop;
}
@Override
public Consumer<AbstractCustomTimerBotAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
this.startDelayTick = delayTick;
}
@Override
public int getStartDelayTick() {
return startDelayTick;
}
@Override
public void setDoIntervalTick(int intervalTick) {
this.doIntervalTick = intervalTick;
}
@Override
public int getDoIntervalTick() {
return doIntervalTick;
}
@Override
public void setDoNumber(int doNumber) {
this.doNumber = doNumber;
}
@Override
public int getDoNumber() {
return doNumber;
}
@Override
public int getTickToNext() {
return startDelayTick;
}
@Override
public int getDoNumberRemaining() {
return doNumber;
}
}

View File

@@ -7,10 +7,11 @@ import org.leavesmc.leaves.entity.bot.Bot;
import java.util.List;
/**
* Represents a class which contains methods for a custom bot action
*/
public interface CustomBotAction extends BotAction<CustomBotAction> {
public interface CustomBotAction<T> extends BotAction<T> {
/**
* Executes the action, returning its success.
@@ -27,7 +28,7 @@ public interface CustomBotAction extends BotAction<CustomBotAction> {
* @param args passed action arguments
* @return a new action instance with given args
*/
@Nullable CustomBotAction getNew(@Nullable Player player, String[] args);
@Nullable T getNew(@Nullable Player player, String[] args);
/**
* Requests a list of possible completions for a action argument.

View File

@@ -1,28 +0,0 @@
package org.leavesmc.leaves.entity.bot.action;
public interface CustomStateBotAction extends StateBotAction<CustomStateBotAction> {
/**
* Executes the action, returning its success.
*
* @param bot bot of the action
* @return true if once action finish, otherwise false
*/
boolean doTick(org.leavesmc.leaves.entity.bot.Bot bot);
/**
* Created a new action instance.
*
* @param player player who create this action
* @param args passed action arguments
* @return a new action instance with given args
*/
@org.jetbrains.annotations.Nullable CustomStateBotAction getNew(@org.jetbrains.annotations.Nullable org.bukkit.entity.Player player, String[] args);
/**
* Requests a list of possible completions for a action argument.
*
* @return A List of a List of possible completions for the argument.
*/
@org.jetbrains.annotations.NotNull java.util.List<java.util.List<String>> getTabComplete();
}

View File

@@ -1,38 +0,0 @@
package org.leavesmc.leaves.entity.bot.action;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.List;
/**
* Represents a class which contains methods for a custom timer bot action
*/
public interface CustomTimerBotAction extends TimerBotAction<CustomTimerBotAction> {
/**
* Executes the action, returning its success.
*
* @param bot bot of the action
* @return true if once action finish, otherwise false
*/
boolean doTick(Bot bot);
/**
* Created a new action instance.
*
* @param player player who create this action
* @param args passed action arguments
* @return a new action instance with given args
*/
@Nullable CustomTimerBotAction getNew(@Nullable Player player, String[] args);
/**
* Requests a list of possible completions for a action argument.
*
* @return A List of a List of possible completions for the argument.
*/
@NotNull List<List<String>> getTabComplete();
}

View File

@@ -4,5 +4,5 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
public interface CraftCustomAction<E> {
public E createCraft(@Nullable Player player, String[] args);
E createCraft(@Nullable Player player, String[] args);
}

View File

@@ -5,20 +5,20 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.action.CustomBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomBotAction;
public class CraftCustomBotAction extends CraftBotAction<CustomBotAction> implements CraftCustomAction<CraftCustomBotAction> {
public class CraftCustomBotAction extends CraftBotAction<AbstractCustomBotAction> implements CraftCustomAction<CraftCustomBotAction> {
private final CustomBotAction realAction;
private final AbstractCustomBotAction realAction;
public CraftCustomBotAction(String name, @NotNull CustomBotAction realAction) {
public CraftCustomBotAction(String name, @NotNull AbstractCustomBotAction realAction) {
super(name, CommandArgument.EMPTY, null);
this.realAction = realAction;
}
@Override
public CraftCustomBotAction createCraft(@Nullable Player player, String[] args) {
CustomBotAction newRealAction = realAction.getNew(player, args);
AbstractCustomBotAction newRealAction = realAction.getNew(player, args);
if (newRealAction != null) {
return new CraftCustomBotAction(this.getName(), newRealAction);
}
@@ -31,7 +31,7 @@ public class CraftCustomBotAction extends CraftBotAction<CustomBotAction> implem
}
@Override
public Class<CustomBotAction> getInterfaceClass() {
public Class<AbstractCustomBotAction> getInterfaceClass() {
return null;
}
}

View File

@@ -5,20 +5,20 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.action.CustomStateBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomStateBotAction;
public class CraftCustomStateBotAction extends CraftStateBotAction<CustomStateBotAction> implements CraftCustomAction<CraftCustomStateBotAction> {
public class CraftCustomStateBotAction extends CraftStateBotAction<AbstractCustomStateBotAction> implements CraftCustomAction<CraftCustomStateBotAction> {
private final CustomStateBotAction realAction;
private final AbstractCustomStateBotAction realAction;
public CraftCustomStateBotAction(String name, @NotNull CustomStateBotAction realAction) {
public CraftCustomStateBotAction(String name, @NotNull AbstractCustomStateBotAction realAction) {
super(name, CommandArgument.EMPTY, null);
this.realAction = realAction;
}
@Override
public CraftCustomStateBotAction createCraft(@Nullable Player player, String[] args) {
CustomStateBotAction newRealAction = realAction.getNew(player, args);
AbstractCustomStateBotAction newRealAction = realAction.getNew(player, args);
if (newRealAction != null) {
return new CraftCustomStateBotAction(this.getName(), newRealAction);
}
@@ -26,7 +26,7 @@ public class CraftCustomStateBotAction extends CraftStateBotAction<CustomStateBo
}
@Override
public Class<CustomStateBotAction> getInterfaceClass() {
public Class<AbstractCustomStateBotAction> getInterfaceClass() {
return null;
}

View File

@@ -4,47 +4,31 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.action.CustomTimerBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomTimerBotAction;
public class CraftCustomTimerBotAction extends CraftTimerBotAction<CustomTimerBotAction> implements CraftCustomAction<CraftCustomTimerBotAction> {
public class CraftCustomTimerBotAction extends CraftTimerBotAction<AbstractCustomTimerBotAction> implements CraftCustomAction<CraftCustomTimerBotAction> {
private final CustomTimerBotAction realAction;
private final AbstractCustomTimerBotAction realAction;
public CraftCustomTimerBotAction(String name, @NotNull CustomTimerBotAction realAction) {
super(name, CommandArgument.EMPTY, null);
public CraftCustomTimerBotAction(String name, @NotNull AbstractCustomTimerBotAction realAction) {
super(name, null);
this.realAction = realAction;
}
@Override
public Class<CustomTimerBotAction> getInterfaceClass() {
public Class<AbstractCustomTimerBotAction> getInterfaceClass() {
return null;
}
@Override
public CraftCustomTimerBotAction createCraft(@Nullable Player player, String[] args) {
CustomTimerBotAction newRealAction = realAction.getNew(player, args);
AbstractCustomTimerBotAction newRealAction = realAction.getNew(player, args);
if (newRealAction != null) {
return new CraftCustomTimerBotAction(this.getName(), newRealAction);
}
return null;
}
@Override
public int getDoNumber() {
return realAction.getDoNumber();
}
@Override
public int getStartDelayTick() {
return realAction.getStartDelayTick();
}
@Override
public int getDoIntervalTick() {
return realAction.getDoIntervalTick();
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
return realAction.doTick(bot.getBukkitEntity());

View File

@@ -1,10 +1,6 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.entity.bot.action.StateBotAction;
import java.util.function.Supplier;

View File

@@ -16,9 +16,9 @@ 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.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.entity.bot.action.AbstractCustomBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomStateBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomTimerBotAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import org.leavesmc.leaves.event.bot.BotRemoveEvent;
@@ -49,28 +49,48 @@ public class CraftBot extends CraftPlayer implements Bot {
@SuppressWarnings("unchecked")
@Override
public <T extends BotAction<T>> void addAction(@NotNull T action) {
CraftBotAction<?> result;
Supplier<T> getRegAction = () -> (T) Actions.getForClass(action.getClass());
switch (action) {
case CustomBotAction act -> {
case AbstractCustomBotAction act -> {
CraftBotAction<AbstractCustomBotAction> result;
T regAction = getRegAction.get();
if (regAction == null) throw new IllegalStateException("Action " + action.getClass().getName() + " is not registered!");
result = new CraftCustomBotAction(regAction.getName(), act);
result.setCancelled(act.isCancelled());
result.setOnFail(act.getOnFail());
result.setOnSuccess(act.getOnSuccess());
result.setOnStop(act.getOnStop());
this.getHandle().addBotAction(result, null);
}
case CustomTimerBotAction act -> {
case AbstractCustomTimerBotAction act -> {
CraftBotAction<AbstractCustomTimerBotAction> result;
T regAction = getRegAction.get();
if (regAction == null) throw new IllegalStateException("Action " + action.getClass().getName() + " is not registered!");
result = new CraftCustomTimerBotAction(regAction.getName(), act);
result.setCancelled(act.isCancelled());
result.setOnFail(act.getOnFail());
result.setOnSuccess(act.getOnSuccess());
result.setOnStop(act.getOnStop());
result.setDoNumber0(act.getDoNumber());
result.setDoIntervalTick0(act.getDoIntervalTick());
result.setStartDelayTick0(act.getStartDelayTick());
this.getHandle().addBotAction(result, null);
}
case CustomStateBotAction act -> {
case AbstractCustomStateBotAction act -> {
CraftBotAction<AbstractCustomStateBotAction> result;
T regAction = getRegAction.get();
if (regAction == null) throw new IllegalStateException("Action " + action.getClass().getName() + " is not registered!");
result = new CraftCustomStateBotAction(regAction.getName(), act);
result.setCancelled(act.isCancelled());
result.setOnFail(act.getOnFail());
result.setOnSuccess(act.getOnSuccess());
result.setOnStop(act.getOnStop());
this.getHandle().addBotAction(result, null);
}
case CraftBotAction<?> craftBotAction -> result = craftBotAction;
case CraftBotAction<?> craftBotAction -> this.getHandle().addBotAction(craftBotAction, null);
default -> throw new IllegalArgumentException("Action " + action.getClass().getName() + " is not a valid BotAction type!");
}
this.getHandle().addBotAction(result, null);
}
@Override

View File

@@ -10,14 +10,18 @@ import org.leavesmc.leaves.bot.BotList;
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.CraftCustomAction;
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.AbstractCustomBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomStateBotAction;
import org.leavesmc.leaves.entity.bot.action.AbstractCustomTimerBotAction;
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;
import java.lang.reflect.InvocationTargetException;
@@ -61,14 +65,20 @@ public class CraftBotManager implements BotManager {
}
@Override
public boolean registerCustomBotAction(String name, CustomBotAction action) {
return Actions.register(new CraftCustomBotAction(name, action));
public boolean registerCustomBotAction(CustomBotAction<?> action) {
return switch (action) {
case AbstractCustomBotAction act -> Actions.register(new CraftCustomBotAction(act.getName(), act));
case AbstractCustomStateBotAction act -> Actions.register(new CraftCustomStateBotAction(act.getName(), act));
case AbstractCustomTimerBotAction act -> Actions.register(new CraftCustomTimerBotAction(act.getName(), act));
case CraftCustomBotAction craftAction -> Actions.register(craftAction);
case null, default -> throw new IllegalArgumentException("Unsupported action type: " + action);
};
}
@Override
public boolean unregisterCustomBotAction(String name) {
CraftBotAction<?> action = Actions.getForName(name);
if (action instanceof CraftCustomBotAction) {
if (action instanceof CraftCustomAction) {
return Actions.unregister(name);
}
return false;
@@ -77,10 +87,7 @@ 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)
|| type.isAssignableFrom(CustomStateBotAction.class)
) try {
if (type.isAssignableFrom(CustomBotAction.class)) try {
return type.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);