9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-29 20:09:23 +00:00

feat: refactor fakeplayer api(#593)

This commit is contained in:
MC_XiaoHei
2025-07-08 10:55:59 +08:00
parent 4f839fbd68
commit 90a5a1d450
97 changed files with 1415 additions and 1051 deletions

View File

@@ -19,7 +19,7 @@ index 3bde4ad79ade5aae18e9073307f637717e8dd9e3..9971ed1347f0f37800911c6cd9d0f8ae
+ *
+ * @return Bot Manager
+ */
+ public static @NotNull org.leavesmc.leaves.entity.BotManager getBotManager() {
+ public static @NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager() {
+ return server.getBotManager();
+ }
+ // Leaves end - Bot API
@@ -39,6 +39,6 @@ index 9bab00ab10c78908090c8a1a12d4c84e9324b08b..3e7aad4ddf573f7c868b7824c4f0f34f
+ *
+ * @return Bot Manager
+ */
+ @NotNull org.leavesmc.leaves.entity.BotManager getBotManager();
+ @NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager();
+ // Leaves end - Bot API
}

View File

@@ -14,7 +14,7 @@ index 9971ed1347f0f37800911c6cd9d0f8ae1a4f100c..803611b793daed2d51ef6ab34d01fc8b
// Leaves end - Bot API
+
+ // Leaves start - Photographer API
+ public static @NotNull org.leavesmc.leaves.entity.PhotographerManager getPhotographerManager() {
+ public static @NotNull org.leavesmc.leaves.entity.photographer.PhotographerManager getPhotographerManager() {
+ return server.getPhotographerManager();
+ }
+ // Leaves end - Photographer API
@@ -25,10 +25,10 @@ index 3e7aad4ddf573f7c868b7824c4f0f34fa08cb1fe..ce128dd8120b75884cb208d7ba7d316e
+++ b/src/main/java/org/bukkit/Server.java
@@ -2732,4 +2732,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
@NotNull org.leavesmc.leaves.entity.BotManager getBotManager();
@NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager();
// Leaves end - Bot API
+
+ // Leaves start - Photographer API
+ @NotNull org.leavesmc.leaves.entity.PhotographerManager getPhotographerManager();
+ @NotNull org.leavesmc.leaves.entity.photographer.PhotographerManager getPhotographerManager();
+ // Leaves end - Photographer API
}

View File

@@ -25,7 +25,7 @@ index ce128dd8120b75884cb208d7ba7d316ee110333b..e63fb4e0c55929f2721e16f69e0c0a4b
+++ b/src/main/java/org/bukkit/Server.java
@@ -2736,4 +2736,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
// Leaves start - Photographer API
@NotNull org.leavesmc.leaves.entity.PhotographerManager getPhotographerManager();
@NotNull org.leavesmc.leaves.entity.photographer.PhotographerManager getPhotographerManager();
// Leaves end - Photographer API
+
+ // Leaves start - Bytebuf API

View File

@@ -1,9 +1,9 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.bot;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.botaction.LeavesBotAction;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import java.util.UUID;
@@ -39,7 +39,7 @@ public interface Bot extends Player {
* @param action bot action
*/
@org.jetbrains.annotations.ApiStatus.Experimental
void addAction(@NotNull LeavesBotAction 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
LeavesBotAction getAction(int index);
BotAction getAction(int index);
/**
* Get action size

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.bot;
import org.bukkit.Bukkit;
import org.bukkit.Location;

View File

@@ -1,9 +1,10 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.bot;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.botaction.CustomBotAction;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import org.leavesmc.leaves.entity.bot.action.CustomBotAction;
import java.util.Collection;
import java.util.UUID;
@@ -55,5 +56,13 @@ public interface BotManager {
@org.jetbrains.annotations.ApiStatus.Experimental
boolean unregisterCustomBotAction(String name);
/**
* Create a bot action by class.
*
* @param type action class
* @return a bot action instance if one was found, null otherwise
*/
<T extends BotAction<T>> T newAction(@NotNull Class<T> type);
BotCreator botCreator(@NotNull String realName, @NotNull Location location);
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface AttackAction extends TimerBotAction<AttackAction> {
}

View File

@@ -0,0 +1,27 @@
package org.leavesmc.leaves.entity.bot.action;
import java.util.UUID;
import java.util.function.Consumer;
public interface BotAction<T> {
String getName();
UUID getUUID();
void setCancelled(boolean cancel);
boolean isCancelled();
void setOnFail(Consumer<T> onFail);
Consumer<T> getOnFail();
void setOnSuccess(Consumer<T> onSuccess);
Consumer<T> getOnSuccess();
void setOnStop(Consumer<T> onStop);
Consumer<T> getOnStop();
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface BreakBlockAction extends TimerBotAction<BreakBlockAction>{
}

View File

@@ -1,17 +1,16 @@
package org.leavesmc.leaves.entity.botaction;
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;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.List;
/**
* Represents a class which contains methods for a custom bot action
*/
@org.jetbrains.annotations.ApiStatus.Experimental
public interface CustomBotAction {
public interface CustomBotAction extends BotAction<CustomBotAction> {
/**
* Executes the action, returning its success.
@@ -36,25 +35,4 @@ public interface CustomBotAction {
* @return A List of a List of possible completions for the argument.
*/
@NotNull List<List<String>> getTabComplete();
/**
* Return the interval between {@link CustomBotAction#doTick(Bot)}
*
* @return the tick interval
*/
int getInitialTickInterval();
/**
* Return the tick delay to the first {@link CustomBotAction#doTick(Bot)}
*
* @return the tick delay
*/
int getInitialTickDelay();
/**
* Return a number of times {@link CustomBotAction#doTick(Bot)} can return true
*
* @return the number of times an action can be executed
*/
int getInitialNumber();
}

View File

@@ -0,0 +1,28 @@
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

@@ -0,0 +1,38 @@
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

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface DropAction extends TimerBotAction<DropAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface FishAction extends TimerBotAction<FishAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface JumpAction extends TimerBotAction<JumpAction> {
}

View File

@@ -0,0 +1,39 @@
package org.leavesmc.leaves.entity.bot.action;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public interface LookAction extends BotAction<LookAction> {
/**
* Sets the position to look at.
*
* @param pos the position to look at
* @return this action instance for method chaining
*/
LookAction setPos(Vector pos);
/**
* Gets the position to look at.
*
* @return the position to look at
*/
Vector getPos();
/**
* Sets the player to look to.
* When set to a player, the bot will look at the player's current position,
* which will override the position set by {@link #setPos(Vector)}.
*
* @param player the player to set
* @return this action instance for method chaining
*/
LookAction setTarget(Player player);
/**
* Gets the player to look to.
*
* @return the player
*/
Player getTarget();
}

View File

@@ -0,0 +1,31 @@
package org.leavesmc.leaves.entity.bot.action;
public interface MoveAction extends StateBotAction<MoveAction> {
/**
* Gets the direction of the move action.
*
* @return the direction of the move action
*/
MoveDirection getDirection();
/**
* Sets the direction of the move action.
*
* @param direction the direction to set
*/
void setDirection(MoveDirection direction);
enum MoveDirection {
FORWARD("forward"),
BACKWARD("backward"),
LEFT("left"),
RIGHT("right");
public final String name;
MoveDirection(String name) {
this.name = name;
}
}
}

View File

@@ -0,0 +1,33 @@
package org.leavesmc.leaves.entity.bot.action;
public interface RotationAction extends BotAction<RotationAction> {
/**
* Sets the yaw of the rotation.
*
* @param yaw the yaw to set
* @return this action instance
*/
RotationAction setYaw(float yaw);
/**
* Sets the pitch of the rotation.
*
* @param pitch the pitch to set
* @return this action instance
*/
RotationAction setPitch(float pitch);
/**
* Gets the yaw of the rotation.
*
* @return the yaw
*/
float getYaw();
/**
* Gets the pitch of the rotation.
*
* @return the pitch
*/
float getPitch();
}

View File

@@ -0,0 +1,18 @@
package org.leavesmc.leaves.entity.bot.action;
public interface ShootAction extends TimerBotAction<ShootAction> {
/**
* Gets the drawing tick for the shoot action.
*
* @return the drawing tick
*/
int getDrawingTick();
/**
* Sets the drawing tick for the shoot action.
*
* @param drawingTick the drawing tick to set
*/
ShootAction setDrawingTick(int drawingTick);
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface SneakAction extends BotAction<SneakAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface StateBotAction<E> extends BotAction<E> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface SwimAction extends StateBotAction<SwimAction> {
}

View File

@@ -0,0 +1,20 @@
package org.leavesmc.leaves.entity.bot.action;
public interface TimerBotAction<E> extends BotAction<E> {
void setStartDelayTick(int delayTick);
int getStartDelayTick();
void setDoIntervalTick(int intervalTick);
int getDoIntervalTick();
void setDoNumber(int doNumber);
int getDoNumber();
int getTickToNext();
int getDoNumberRemaining();
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemAction extends TimerBotAction<UseItemAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemAutoAction extends TimerBotAction<UseItemAutoAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemAutoOffhandAction extends TimerBotAction<UseItemAutoOffhandAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemOffHandAction extends TimerBotAction<UseItemOffHandAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemOnAction extends TimerBotAction<UseItemOnAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemOnOffhandAction extends TimerBotAction<UseItemOnOffhandAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemToAction extends TimerBotAction<UseItemToAction> {
}

View File

@@ -0,0 +1,4 @@
package org.leavesmc.leaves.entity.bot.action;
public interface UseItemToOffhandAction extends TimerBotAction<UseItemToOffhandAction> {
}

View File

@@ -1,38 +0,0 @@
package org.leavesmc.leaves.entity.botaction;
/**
* A Leaves bot action enum
*/
@org.jetbrains.annotations.ApiStatus.Experimental
public enum BotActionType {
ATTACK("attack"),
BREAK("break"),
DROP("drop"),
FISH("fish"),
JUMP("jump"),
LOOK("look"),
ROTATE("rotate"),
ROTATION("rotation"),
SNEAK("sneak"),
SWIM("swim"),
MOVE("move"),
USE("use"),
USE_ON("use_on"),
USE_TO("use_to"),
USE_AUTO("use_auto"),
USE_OFFHAND("use_offhand"),
USE_ON_OFFHAND("use_on_offhand"),
USE_TO_OFFHAND("use_to_offhand"),
USE_AUTO_OFFHAND("use_auto_offhand");
private final String name;
BotActionType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View File

@@ -1,112 +0,0 @@
package org.leavesmc.leaves.entity.botaction;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import java.util.function.Consumer;
@org.jetbrains.annotations.ApiStatus.Experimental
public class LeavesBotAction {
private final String actionName;
private final UUID uuid;
private final int initialTickDelay;
private final int initialTickInterval;
private final int initialNumber;
private final @Nullable Consumer<LeavesBotAction> onSuccess;
private final @Nullable Consumer<LeavesBotAction> onFail;
private Player actionPlayer;
private int tickToNext;
private int numberRemaining;
private boolean cancel;
public LeavesBotAction(@NotNull BotActionType type, int initialTickInterval, int initialNumber) {
this(type.getName(), UUID.randomUUID(), 0, initialTickInterval, initialNumber, null, null);
}
public LeavesBotAction(@NotNull BotActionType type, int initialTickInterval, int initialNumber, @Nullable Consumer<LeavesBotAction> onSuccess, @Nullable Consumer<LeavesBotAction> onFail) {
this(type.getName(), UUID.randomUUID(), 0, initialTickInterval, initialNumber, onSuccess, onFail);
}
public LeavesBotAction(@NotNull BotActionType type, int initialTickDelay, int initialTickInterval, int initialNumber) {
this(type.getName(), UUID.randomUUID(), initialTickDelay, initialTickInterval, initialNumber, null, null);
}
public LeavesBotAction(@NotNull BotActionType type, int initialTickDelay, int initialTickInterval, int initialNumber, @Nullable Consumer<LeavesBotAction> onSuccess, @Nullable Consumer<LeavesBotAction> onFail) {
this(type.getName(), UUID.randomUUID(), initialTickDelay, initialTickInterval, initialNumber, onSuccess, onFail);
}
protected LeavesBotAction(String name, UUID actionUUID, int initialTickDelay, int initialTickInterval, int initialNumber, @Nullable Consumer<LeavesBotAction> onSuccess, @Nullable Consumer<LeavesBotAction> onFail) {
this.actionName = name;
this.uuid = actionUUID;
this.initialTickDelay = initialTickDelay;
this.initialTickInterval = initialTickInterval;
this.initialNumber = initialNumber;
this.onSuccess = onSuccess;
this.onFail = onFail;
}
public String getActionName() {
return actionName;
}
public UUID getUuid() {
return uuid;
}
public int getInitialTickDelay() {
return initialTickDelay;
}
public int getInitialTickInterval() {
return initialTickInterval;
}
public int getInitialNumber() {
return initialNumber;
}
@Nullable
public Player getActionPlayer() {
return actionPlayer;
}
public void setActionPlayer(@Nullable Player actionPlayer) {
this.actionPlayer = actionPlayer;
}
public boolean isCancel() {
return cancel;
}
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
public int getNumberRemaining() {
return numberRemaining;
}
public void setNumberRemaining(int numberRemaining) {
this.numberRemaining = numberRemaining;
}
public int getTickToNext() {
return tickToNext;
}
public void setTickToNext(int tickToNext) {
this.tickToNext = tickToNext;
}
public @Nullable Consumer<LeavesBotAction> getOnSuccess() {
return onSuccess;
}
public @Nullable Consumer<LeavesBotAction> getOnFail() {
return onFail;
}
}

View File

@@ -1,14 +0,0 @@
package org.leavesmc.leaves.entity.botaction;
public enum MoveDirection {
FORWARD("forward"),
BACKWARD("backward"),
LEFT("left"),
RIGHT("right");
public final String name;
MoveDirection(String name) {
this.name = name;
}
}

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.photographer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.photographer;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;

View File

@@ -1,7 +1,7 @@
package org.leavesmc.leaves.event.bot;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.UUID;

View File

@@ -3,7 +3,7 @@ package org.leavesmc.leaves.event.bot;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.UUID;

View File

@@ -5,7 +5,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.UUID;

View File

@@ -5,7 +5,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.UUID;

View File

@@ -4,7 +4,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
public class BotConfigModifyEvent extends BotEvent implements Cancellable {

View File

@@ -6,7 +6,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
public class BotDeathEvent extends BotEvent implements Cancellable {

View File

@@ -2,7 +2,7 @@ package org.leavesmc.leaves.event.bot;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
/**
* Represents a fakeplayer related event

View File

@@ -5,7 +5,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
public class BotInventoryOpenEvent extends BotEvent implements Cancellable {

View File

@@ -5,7 +5,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
/**
* Called when a fakeplayer joins a server

View File

@@ -7,7 +7,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
/**
* Call when a fakeplayer removed

View File

@@ -3,7 +3,7 @@ package org.leavesmc.leaves.event.bot;
import org.bukkit.Location;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
public class BotSpawnLocationEvent extends BotEvent {

View File

@@ -13,7 +13,7 @@ index a589689e3a9de1fffef62e0e3dcd79bb2e848c5b..af9408c990d5ba2cf34d6c64db86a04c
}
+ // Leaves start - skip bot
+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Bot) {
+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.bot.Bot) {
+ return;
+ }
+ // Leaves end - skip bot

View File

@@ -5,15 +5,15 @@ Subject: [PATCH] Replay Mod API
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index a0a6cde96322df8e455b26b32b1c593f332d4db6..b5031ba5c48c7d007a7c05766a2beff422504c3e 100644
index af9408c990d5ba2cf34d6c64db86a04c90165e91..34ebc691b3bd35c7f7457703b1b9a5bea6b3c625 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -42,7 +42,7 @@ class PaperEventManager {
}
// Leaves start - skip bot
- if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Bot) {
+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && (playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Bot || playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Photographer)) { // Leaves - and photographer
- if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.bot.Bot) {
+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && (playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.bot.Bot || playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.photographer.Photographer)) { // Leaves - and photographer
return;
}
// Leaves end - skip bot
@@ -63,7 +63,7 @@ index 656d599060449a4fd53360915378aca177b7e6e7..1e94a2e2f9669c8130a228c440720b42
// Special case complex part, since there is no extra entity type for them
if (entity instanceof EnderDragonPart complexPart) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 1e2e8d81e6d05b9e94fdb40dcdc4a7e0e4ceb0ac..231007b5f7a97e0fa4cc2f259ed8ac9740895298 100644
index 1e2e8d81e6d05b9e94fdb40dcdc4a7e0e4ceb0ac..f2befe2e971386cec71dce7d1592a7a2fffa5afd 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2205,7 +2205,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa
@@ -71,7 +71,7 @@ index 1e2e8d81e6d05b9e94fdb40dcdc4a7e0e4ceb0ac..231007b5f7a97e0fa4cc2f259ed8ac97
@Override
public boolean canSee(Player player) {
- return this.canSee((org.bukkit.entity.Entity) player);
+ return !(player instanceof org.leavesmc.leaves.entity.Photographer) && this.canSee((org.bukkit.entity.Entity) player); // Leaves - skip photographer
+ return !(player instanceof org.leavesmc.leaves.entity.photographer.Photographer) && this.canSee((org.bukkit.entity.Entity) player); // Leaves - skip photographer
}
@Override

View File

@@ -7,9 +7,9 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.BotCreator;
import org.leavesmc.leaves.entity.CraftBot;
import org.leavesmc.leaves.entity.bot.Bot;
import org.leavesmc.leaves.entity.bot.BotCreator;
import org.leavesmc.leaves.event.bot.BotCreateEvent;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;

View File

@@ -53,10 +53,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.LeavesLogger;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.AbstractBotConfig;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.Configs;
import org.leavesmc.leaves.bot.agent.actions.CraftBotAction;
import org.leavesmc.leaves.entity.CraftBot;
import org.leavesmc.leaves.event.bot.BotActionScheduleEvent;
import org.leavesmc.leaves.event.bot.BotCreateEvent;
@@ -76,7 +76,7 @@ import java.util.function.Predicate;
public class ServerBot extends ServerPlayer {
private final List<AbstractBotAction<?>> actions;
private final List<CraftBotAction<?>> actions;
private final Map<Configs<?>, AbstractBotConfig<?>> configs;
public boolean resume = false;
@@ -388,7 +388,7 @@ public class ServerBot extends ServerPlayer {
if (!this.actions.isEmpty()) {
ValueOutput.TypedOutputList<CompoundTag> actionNbt = nbt.list("actions", CompoundTag.CODEC);
for (AbstractBotAction<?> action : this.actions) {
for (CraftBotAction<?> action : this.actions) {
actionNbt.add(action.save(new CompoundTag()));
}
}
@@ -428,9 +428,9 @@ public class ServerBot extends ServerPlayer {
if (nbt.list("actions", CompoundTag.CODEC).isPresent()) {
ValueInput.TypedInputList<CompoundTag> actionNbt = nbt.list("actions", CompoundTag.CODEC).orElseThrow();
actionNbt.forEach(actionTag -> {
AbstractBotAction<?> action = Actions.getForName(actionTag.getString("actionName").orElseThrow());
CraftBotAction<?> action = Actions.getForName(actionTag.getString("actionName").orElseThrow());
if (action != null) {
AbstractBotAction<?> newAction = action.create();
CraftBotAction<?> newAction = (CraftBotAction<?>) action.create();
newAction.load(actionTag);
this.actions.add(newAction);
}
@@ -585,11 +585,11 @@ public class ServerBot extends ServerPlayer {
private void runAction() {
if (LeavesConfig.modify.fakeplayer.canUseAction) {
this.actions.forEach(action -> action.tryTick(this));
this.actions.removeIf(AbstractBotAction::isCancelled);
this.actions.removeIf(CraftBotAction::isCancelled);
}
}
public boolean addBotAction(AbstractBotAction<?> action, CommandSender sender) {
public boolean addBotAction(CraftBotAction<?> action, CommandSender sender) {
if (!LeavesConfig.modify.fakeplayer.canUseAction) {
return false;
}
@@ -603,7 +603,7 @@ public class ServerBot extends ServerPlayer {
return true;
}
public List<AbstractBotAction<?>> getBotActions() {
public List<CraftBotAction<?>> getBotActions() {
return actions;
}

View File

@@ -1,217 +0,0 @@
package org.leavesmc.leaves.bot.agent;
import net.minecraft.core.UUIDUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.CraftBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.entity.botaction.LeavesBotAction;
import org.leavesmc.leaves.event.bot.BotActionExecuteEvent;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.List;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
//TODO onStop for fully terminate action (use, etc.)
public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
private final String name;
private final CommandArgument argument;
private final Supplier<E> creator;
private UUID uuid;
private int initialTickDelay;
private int initialTickInterval;
private int initialNumber;
private int tickToNext;
private int numberRemaining;
private boolean cancel;
private Consumer<LeavesBotAction> onFail;
private Consumer<LeavesBotAction> onSuccess;
public AbstractBotAction(String name, CommandArgument argument, Supplier<E> creator) {
this.name = name;
this.argument = argument;
this.uuid = UUID.randomUUID();
this.creator = creator;
this.cancel = false;
this.initialTickInterval = 20;
this.initialNumber = -1;
}
public void init() {
this.tickToNext = initialTickDelay;
this.numberRemaining = this.getInitialNumber();
this.setCancelled(false);
}
public void tryTick(ServerBot bot) {
if (this.numberRemaining == 0) {
this.stop(bot, BotActionStopEvent.Reason.DONE);
return;
}
if (this.tickToNext <= 0) {
BotActionExecuteEvent event = new BotActionExecuteEvent(bot.getBukkitEntity(), name, uuid);
event.callEvent();
if (event.getResult() == BotActionExecuteEvent.Result.SOFT_CANCEL) {
this.tickToNext = this.getInitialTickInterval() - 1;
return;
} else if (event.getResult() == BotActionExecuteEvent.Result.HARD_CANCEL) {
if (this.numberRemaining > 0) {
this.numberRemaining--;
}
this.tickToNext = this.getInitialTickInterval() - 1;
return;
}
if (this.doTick(bot)) {
if (this.numberRemaining > 0) {
this.numberRemaining--;
}
this.tickToNext = this.getInitialTickInterval() - 1;
if (this.onSuccess != null) {
this.onSuccess.accept(CraftBotAction.asAPICopy(this));
}
} else if (this.onFail != null) {
this.onFail.accept(CraftBotAction.asAPICopy(this));
}
} else {
this.tickToNext--;
}
}
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
if (!this.cancel) {
nbt.putString("actionName", this.name);
nbt.store("actionUUID", UUIDUtil.CODEC, this.uuid);
nbt.putInt("initialTickDelay", this.initialTickDelay);
nbt.putInt("initialTickInterval", this.initialTickInterval);
nbt.putInt("initialNumber", this.initialNumber);
nbt.putInt("tickToNext", this.tickToNext);
nbt.putInt("numberRemaining", this.numberRemaining);
}
return nbt;
}
public void load(@NotNull CompoundTag nbt) {
this.uuid = nbt.read("actionUUID", UUIDUtil.CODEC).orElse(UUID.randomUUID());
this.initialTickDelay = nbt.getInt("initialTickDelay").orElse(0);
this.initialTickInterval = nbt.getInt("initialTickInterval").orElse(0);
this.initialNumber = nbt.getInt("initialNumber").orElse(0);
this.tickToNext = nbt.getInt("tickToNext").orElse(0);
this.numberRemaining = nbt.getInt("numberRemaining").orElse(0);
}
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
new BotActionStopEvent(bot.getBukkitEntity(), this.name, this.uuid, reason, null).callEvent();
this.setCancelled(true);
}
public abstract void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result);
public abstract boolean doTick(@NotNull ServerBot bot);
@SuppressWarnings("unchecked")
public E setSuggestion(int n, BiFunction<CommandSender, String, Pair<List<String>, String>> suggestion) {
this.argument.setSuggestion(n, suggestion);
return (E) this;
}
public E setSuggestion(int n, Pair<List<String>, String> suggestion) {
return this.setSuggestion(n, (sender, arg) -> suggestion);
}
public E setSuggestion(int n, List<String> tabComplete) {
return this.setSuggestion(n, Pair.of(tabComplete, null));
}
public String getName() {
return this.name;
}
public UUID getUUID() {
return uuid;
}
@SuppressWarnings("unchecked")
public E setInitialTickDelay(int initialTickDelay) {
this.initialTickDelay = initialTickDelay;
return (E) this;
}
public int getInitialTickDelay() {
return this.initialTickDelay;
}
public int getInitialTickInterval() {
return this.initialTickInterval;
}
@SuppressWarnings("unchecked")
public E setInitialTickInterval(int initialTickInterval) {
this.initialTickInterval = Math.max(1, initialTickInterval);
return (E) this;
}
public int getInitialNumber() {
return this.initialNumber;
}
@SuppressWarnings("unchecked")
public E setInitialNumber(int initialNumber) {
this.initialNumber = Math.max(-1, initialNumber);
return (E) this;
}
public int getTickToNext() {
return this.tickToNext;
}
public int getNumberRemaining() {
return this.numberRemaining;
}
public boolean isCancelled() {
return cancel;
}
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
public CommandArgument getArgument() {
return this.argument;
}
public void setOnFail(Consumer<LeavesBotAction> onFail) {
this.onFail = onFail;
}
public void setOnSuccess(Consumer<LeavesBotAction> onSuccess) {
this.onSuccess = onSuccess;
}
@NotNull
public E create() {
return this.creator.get();
}
}

View File

@@ -3,26 +3,27 @@ package org.leavesmc.leaves.bot.agent;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.agent.actions.AttackAction;
import org.leavesmc.leaves.bot.agent.actions.BreakBlockAction;
import org.leavesmc.leaves.bot.agent.actions.DropAction;
import org.leavesmc.leaves.bot.agent.actions.FishAction;
import org.leavesmc.leaves.bot.agent.actions.JumpAction;
import org.leavesmc.leaves.bot.agent.actions.LookAction;
import org.leavesmc.leaves.bot.agent.actions.MoveAction;
import org.leavesmc.leaves.bot.agent.actions.RotateAction;
import org.leavesmc.leaves.bot.agent.actions.RotationAction;
import org.leavesmc.leaves.bot.agent.actions.ShootAction;
import org.leavesmc.leaves.bot.agent.actions.SneakAction;
import org.leavesmc.leaves.bot.agent.actions.SwimAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemAutoAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemAutoOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemOffHandAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemOnAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemOnOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemToAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemToOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.CraftAttackAction;
import org.leavesmc.leaves.bot.agent.actions.CraftBotAction;
import org.leavesmc.leaves.bot.agent.actions.CraftBreakBlockAction;
import org.leavesmc.leaves.bot.agent.actions.CraftDropAction;
import org.leavesmc.leaves.bot.agent.actions.CraftFishAction;
import org.leavesmc.leaves.bot.agent.actions.CraftJumpAction;
import org.leavesmc.leaves.bot.agent.actions.CraftLookAction;
import org.leavesmc.leaves.bot.agent.actions.CraftMoveAction;
import org.leavesmc.leaves.bot.agent.actions.CraftRotationAction;
import org.leavesmc.leaves.bot.agent.actions.CraftShootAction;
import org.leavesmc.leaves.bot.agent.actions.CraftSneakAction;
import org.leavesmc.leaves.bot.agent.actions.CraftSwimAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemAutoAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemAutoOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemOffHandAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemOnAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemOnOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemToAction;
import org.leavesmc.leaves.bot.agent.actions.CraftUseItemToOffhandAction;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import java.util.Collection;
import java.util.HashMap;
@@ -31,42 +32,44 @@ import java.util.Set;
public class Actions {
private static final Map<String, AbstractBotAction<?>> actions = new HashMap<>();
private static final Map<String, CraftBotAction<?>> actionsByName = new HashMap<>();
private static final Map<Class<?>, CraftBotAction<?>> actionsByClass = new HashMap<>();
public static void registerAll() {
register(new AttackAction());
register(new BreakBlockAction());
register(new DropAction());
register(new JumpAction());
register(new RotateAction());
register(new SneakAction());
register(new UseItemAction());
register(new UseItemOnAction());
register(new UseItemToAction());
register(new UseItemAutoAction());
register(new UseItemOffHandAction());
register(new UseItemOnOffhandAction());
register(new UseItemToOffhandAction());
register(new UseItemAutoOffhandAction());
register(new LookAction());
register(new FishAction());
register(new SwimAction());
register(new RotationAction());
register(new ShootAction());
register(new MoveAction());
register(new CraftAttackAction());
register(new CraftBreakBlockAction());
register(new CraftDropAction());
register(new CraftJumpAction());
register(new CraftSneakAction());
register(new CraftUseItemAction());
register(new CraftUseItemOnAction());
register(new CraftUseItemToAction());
register(new CraftUseItemAutoAction());
register(new CraftUseItemOffHandAction());
register(new CraftUseItemOnOffhandAction());
register(new CraftUseItemToOffhandAction());
register(new CraftUseItemAutoOffhandAction());
register(new CraftLookAction());
register(new CraftFishAction());
register(new CraftSwimAction());
register(new CraftRotationAction());
register(new CraftShootAction());
register(new CraftMoveAction());
}
public static boolean register(@NotNull AbstractBotAction<?> action) {
if (!actions.containsKey(action.getName())) {
actions.put(action.getName(), action);
public static boolean register(@NotNull CraftBotAction<?> action) {
if (!actionsByName.containsKey(action.getName())) {
actionsByName.put(action.getName(), action);
actionsByClass.put(action.getInterfaceClass(), action);
return true;
}
return false;
}
public static boolean unregister(@NotNull String name) {
if (actions.containsKey(name)) {
actions.remove(name);
if (actionsByName.containsKey(name)) {
actionsByClass.remove(actionsByName.get(name).getInterfaceClass());
actionsByName.remove(name);
return true;
}
return false;
@@ -74,17 +77,23 @@ public class Actions {
@NotNull
@Contract(pure = true)
public static Collection<AbstractBotAction<?>> getAll() {
return actions.values();
public static Collection<CraftBotAction<?>> getAll() {
return actionsByName.values();
}
@NotNull
public static Set<String> getNames() {
return actions.keySet();
return actionsByName.keySet();
}
@Nullable
public static AbstractBotAction<?> getForName(String name) {
return actions.get(name);
public static CraftBotAction<?> getForName(String name) {
return actionsByName.get(name);
}
@SuppressWarnings("unchecked")
@Nullable
public static <T extends BotAction<T>> T getForClass(@NotNull Class<T> type) {
return (T) actionsByClass.get(type);
}
}

View File

@@ -1,33 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
public abstract class AbstractTimerAction<E extends AbstractTimerAction<E>> extends AbstractBotAction<E> {
public AbstractTimerAction(String name, Supplier<E> creator) {
this(name, CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), creator);
}
public AbstractTimerAction(String name, CommandArgument argument, Supplier<E> creator) {
super(name, argument, creator);
this.setSuggestion(0, Pair.of(Collections.singletonList("0"), "[TickDelay]"));
this.setSuggestion(1, Pair.of(Collections.singletonList("20"), "[TickInterval]"));
this.setSuggestion(2, Pair.of(List.of("1", "-1"), "[DoNumber]"));
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setInitialTickDelay(result.readInt(0)).setInitialTickInterval(result.readInt(20)).setInitialNumber(result.readInt(1));
}
}

View File

@@ -3,11 +3,17 @@ package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.AttackAction;
public class AttackAction extends AbstractTimerAction<AttackAction> {
public class CraftAttackAction extends CraftTimerBotAction<AttackAction> implements AttackAction {
public AttackAction() {
super("attack", AttackAction::new);
public CraftAttackAction() {
super("attack", CraftAttackAction::new);
}
@Override
public Class<AttackAction> getInterfaceClass() {
return AttackAction.class;
}
@Override

View File

@@ -1,58 +1,249 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.jetbrains.annotations.Contract;
import net.minecraft.core.UUIDUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.entity.botaction.BotActionType;
import org.leavesmc.leaves.entity.botaction.LeavesBotAction;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import org.leavesmc.leaves.event.bot.BotActionExecuteEvent;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
public class CraftBotAction extends LeavesBotAction {
import java.util.List;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
private final AbstractBotAction<?> handle;
@SuppressWarnings("unchecked")
public abstract class CraftBotAction<E extends BotAction<E>> implements BotAction<E> {
public CraftBotAction(@NotNull AbstractBotAction<?> action) {
super(BotActionType.valueOf(action.getName()), action.getInitialTickInterval(), action.getNumberRemaining());
this.handle = action;
private final String name;
private final CommandArgument argument;
private final Supplier<E> creator;
private UUID uuid;
private int initialTickDelay;
private int initialTickInterval;
private int initialNumber;
private int tickToNext;
private int numberRemaining;
private boolean cancel;
private Consumer<E> onFail;
private Consumer<E> onSuccess;
private Consumer<E> onStop;
public CraftBotAction(String name, CommandArgument argument, Supplier<E> creator) {
this.name = name;
this.argument = argument;
this.uuid = UUID.randomUUID();
this.creator = creator;
this.cancel = false;
this.setStartDelayTick0(0);
this.setDoIntervalTick0(1);
this.setDoNumber0(1);
}
@Contract("_ -> new")
@NotNull
public static LeavesBotAction asAPICopy(AbstractBotAction<?> action) {
return new CraftBotAction(action);
public void init() {
this.tickToNext = initialTickDelay;
this.numberRemaining = this.getDoNumber();
this.setCancelled(false);
}
@NotNull
public static AbstractBotAction<?> asInternalCopy(@NotNull LeavesBotAction action) {
AbstractBotAction<?> act = Actions.getForName(action.getActionName());
if (act == null) {
throw new IllegalArgumentException("Invalid action name!");
public void tryTick(ServerBot bot) {
if (this.numberRemaining == 0) {
this.stop(bot, BotActionStopEvent.Reason.DONE);
return;
}
AbstractBotAction<?> newAction = null;
String[] args = new String[]{String.valueOf(action.getInitialTickDelay()), String.valueOf(action.getInitialTickInterval()), String.valueOf(action.getInitialNumber())};
try {
if (act instanceof CraftCustomBotAction customBotAction) {
newAction = customBotAction.createCraft(action.getActionPlayer(), args);
} else {
newAction = act.create();
newAction.loadCommand(action.getActionPlayer() == null ? null : ((CraftPlayer) action.getActionPlayer()).getHandle(), act.getArgument().parse(0, args));
if (this.cancel) {
this.stop(bot, BotActionStopEvent.Reason.PLUGIN);
return;
}
if (this.tickToNext <= 0) {
BotActionExecuteEvent event = new BotActionExecuteEvent(bot.getBukkitEntity(), name, uuid);
event.callEvent();
if (event.getResult() == BotActionExecuteEvent.Result.SOFT_CANCEL) {
this.tickToNext = this.getDoIntervalTick() - 1;
return;
} else if (event.getResult() == BotActionExecuteEvent.Result.HARD_CANCEL) {
if (this.numberRemaining > 0) {
this.numberRemaining--;
}
this.tickToNext = this.getDoIntervalTick() - 1;
return;
}
} catch (IllegalArgumentException ignore) {
if (this.doTick(bot)) {
if (this.numberRemaining > 0) {
this.numberRemaining--;
}
this.tickToNext = this.getDoIntervalTick() - 1;
if (this.onSuccess != null) {
this.onSuccess.accept((E) this);
}
} else if (this.onFail != null) {
this.onFail.accept((E) this);
}
} else {
this.tickToNext--;
}
if (newAction == null) {
throw new IllegalArgumentException("Invalid action!"); // TODO look action
}
newAction.setOnSuccess(action.getOnSuccess());
newAction.setOnFail(action.getOnFail());
return newAction;
}
public AbstractBotAction<?> getHandle() {
return handle;
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
if (!this.cancel) {
nbt.putString("actionName", this.name);
nbt.store("actionUUID", UUIDUtil.CODEC, this.uuid);
nbt.putInt("initialTickDelay", this.initialTickDelay);
nbt.putInt("initialTickInterval", this.initialTickInterval);
nbt.putInt("initialNumber", this.initialNumber);
nbt.putInt("tickToNext", this.tickToNext);
nbt.putInt("numberRemaining", this.numberRemaining);
}
return nbt;
}
public void load(@NotNull CompoundTag nbt) {
this.uuid = nbt.read("actionUUID", UUIDUtil.CODEC).orElse(UUID.randomUUID());
this.initialTickDelay = nbt.getInt("initialTickDelay").orElse(0);
this.initialTickInterval = nbt.getInt("initialTickInterval").orElse(0);
this.initialNumber = nbt.getInt("initialNumber").orElse(0);
this.tickToNext = nbt.getInt("tickToNext").orElse(0);
this.numberRemaining = nbt.getInt("numberRemaining").orElse(0);
}
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
new BotActionStopEvent(bot.getBukkitEntity(), this.name, this.uuid, reason, null).callEvent();
this.setCancelled(true);
if (this.onStop != null) this.onStop.accept((E) this);
this.onStop(bot, reason);
}
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
}
public abstract boolean doTick(@NotNull ServerBot bot);
public abstract Class<E> getInterfaceClass();
public void onStop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
}
public void setSuggestion(int n, BiFunction<CommandSender, String, Pair<List<String>, String>> suggestion) {
this.argument.setSuggestion(n, suggestion);
}
public void setSuggestion(int n, Pair<List<String>, String> suggestion) {
this.setSuggestion(n, (sender, arg) -> suggestion);
}
public void setSuggestion(int n, List<String> tabComplete) {
this.setSuggestion(n, Pair.of(tabComplete, null));
}
@NotNull
public E create() {
return this.creator.get();
}
public CommandArgument getArgument() {
return this.argument;
}
@Override
public String getName() {
return this.name;
}
@Override
public UUID getUUID() {
return uuid;
}
public void setStartDelayTick0(int initialTickDelay) {
this.initialTickDelay = initialTickDelay;
}
public int getStartDelayTick() {
return this.initialTickDelay;
}
public void setDoIntervalTick0(int initialTickInterval) {
this.initialTickInterval = Math.max(1, initialTickInterval);
}
public int getDoIntervalTick() {
return this.initialTickInterval;
}
public void setDoNumber0(int initialNumber) {
this.initialNumber = Math.max(-1, initialNumber);
}
public int getDoNumber() {
return this.initialNumber;
}
public int getTickToNext() {
return this.tickToNext;
}
public int getDoNumberRemaining() {
return this.numberRemaining;
}
@Override
public boolean isCancelled() {
return cancel;
}
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
public void setOnFail(Consumer<E> onFail) {
this.onFail = onFail;
}
@Override
public Consumer<E> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<E> onSuccess) {
this.onSuccess = onSuccess;
}
@Override
public Consumer<E> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<E> onStop) {
this.onStop = onStop;
}
@Override
public Consumer<E> getOnStop() {
return onStop;
}
}

View File

@@ -7,11 +7,17 @@ import org.bukkit.block.Block;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.BreakBlockAction;
public class BreakBlockAction extends AbstractTimerAction<BreakBlockAction> {
public class CraftBreakBlockAction extends CraftTimerBotAction<BreakBlockAction> implements BreakBlockAction {
public BreakBlockAction() {
super("break", BreakBlockAction::new);
public CraftBreakBlockAction() {
super("break", CraftBreakBlockAction::new);
}
@Override
public Class<BreakBlockAction> getInterfaceClass() {
return BreakBlockAction.class;
}
private BlockPos lastPos = null;

View File

@@ -0,0 +1,8 @@
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);
}

View File

@@ -1,16 +1,13 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
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.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.entity.botaction.CustomBotAction;
import org.leavesmc.leaves.entity.bot.action.CustomBotAction;
public class CraftCustomBotAction extends AbstractBotAction<CraftCustomBotAction> {
public class CraftCustomBotAction extends CraftBotAction<CustomBotAction> implements CraftCustomAction<CraftCustomBotAction> {
private final CustomBotAction realAction;
@@ -20,10 +17,6 @@ public class CraftCustomBotAction extends AbstractBotAction<CraftCustomBotAction
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
throw new UnsupportedOperationException("Not supported.");
}
public CraftCustomBotAction createCraft(@Nullable Player player, String[] args) {
CustomBotAction newRealAction = realAction.getNew(player, args);
if (newRealAction != null) {
@@ -32,23 +25,13 @@ public class CraftCustomBotAction extends AbstractBotAction<CraftCustomBotAction
return null;
}
@Override
public int getInitialNumber() {
return realAction.getInitialNumber();
}
@Override
public int getInitialTickDelay() {
return realAction.getInitialTickDelay();
}
@Override
public int getInitialTickInterval() {
return realAction.getInitialTickInterval();
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
return realAction.doTick(bot.getBukkitEntity());
}
@Override
public Class<CustomBotAction> getInterfaceClass() {
return null;
}
}

View File

@@ -0,0 +1,37 @@
package org.leavesmc.leaves.bot.agent.actions;
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.CustomStateBotAction;
public class CraftCustomStateBotAction extends CraftStateBotAction<CustomStateBotAction> implements CraftCustomAction<CraftCustomStateBotAction> {
private final CustomStateBotAction realAction;
public CraftCustomStateBotAction(String name, @NotNull CustomStateBotAction realAction) {
super(name, CommandArgument.EMPTY, null);
this.realAction = realAction;
}
@Override
public CraftCustomStateBotAction createCraft(@Nullable Player player, String[] args) {
CustomStateBotAction newRealAction = realAction.getNew(player, args);
if (newRealAction != null) {
return new CraftCustomStateBotAction(this.getName(), newRealAction);
}
return null;
}
@Override
public Class<CustomStateBotAction> getInterfaceClass() {
return null;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
return realAction.doTick(bot.getBukkitEntity());
}
}

View File

@@ -0,0 +1,52 @@
package org.leavesmc.leaves.bot.agent.actions;
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;
public class CraftCustomTimerBotAction extends CraftTimerBotAction<CustomTimerBotAction> implements CraftCustomAction<CraftCustomTimerBotAction> {
private final CustomTimerBotAction realAction;
public CraftCustomTimerBotAction(String name, @NotNull CustomTimerBotAction realAction) {
super(name, CommandArgument.EMPTY, null);
this.realAction = realAction;
}
@Override
public Class<CustomTimerBotAction> getInterfaceClass() {
return null;
}
@Override
public CraftCustomTimerBotAction createCraft(@Nullable Player player, String[] args) {
CustomTimerBotAction 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

@@ -0,0 +1,23 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.DropAction;
public class CraftDropAction extends CraftTimerBotAction<DropAction> implements DropAction {
public CraftDropAction() {
super("drop", CraftDropAction::new);
}
@Override
public Class<DropAction> getInterfaceClass() {
return DropAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.dropAll(false);
return true;
}
}

View File

@@ -7,11 +7,17 @@ import net.minecraft.world.item.FishingRodItem;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.FishAction;
public class FishAction extends AbstractTimerAction<FishAction> {
public class CraftFishAction extends CraftTimerBotAction<FishAction> implements FishAction {
public FishAction() {
super("fish", FishAction::new);
public CraftFishAction() {
super("fish", CraftFishAction::new);
}
@Override
public Class<FishAction> getInterfaceClass() {
return FishAction.class;
}
private static final int CATCH_ENTITY_DELAY = 20;
@@ -20,10 +26,9 @@ public class FishAction extends AbstractTimerAction<FishAction> {
private int tickToNextFish = 0;
@Override
public FishAction setInitialTickInterval(int initialTickInterval) {
super.setInitialTickInterval(1);
public void setDoIntervalTick0(int initialTickInterval) {
super.setDoIntervalTick0(1);
this.initialFishInterval = initialTickInterval;
return this;
}
@Override

View File

@@ -2,11 +2,17 @@ package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.JumpAction;
public class JumpAction extends AbstractTimerAction<JumpAction> {
public class CraftJumpAction extends CraftTimerBotAction<JumpAction> implements JumpAction {
public JumpAction() {
super("jump", JumpAction::new);
public CraftJumpAction() {
super("jump", CraftJumpAction::new);
}
@Override
public Class<JumpAction> getInterfaceClass() {
return JumpAction.class;
}
@Override

View File

@@ -0,0 +1,125 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
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.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.action.LookAction;
import java.text.DecimalFormat;
import java.util.List;
public class CraftLookAction extends CraftBotAction<LookAction> implements LookAction {
private static final DecimalFormat DF = new DecimalFormat("0.0");
private static final Vector ZERO_VECTOR = new Vector(0, 0, 0);
public CraftLookAction() {
super("look", CommandArgument.of(CommandArgumentType.STRING, CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE), CraftLookAction::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getX())), "<X>/<Player>") : Pair.of(List.of("0"), "<X>/<Player>"));
this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getY())), "<Y>") : Pair.of(List.of("0"), "<Y>"));
this.setSuggestion(2, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getZ())), "<Z>") : Pair.of(List.of("0"), "<Z>"));
}
@Override
public Class<LookAction> getInterfaceClass() {
return LookAction.class;
}
private Vector pos = ZERO_VECTOR;
private Player target = null;
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) throws IllegalArgumentException {
Object rawFirst = result.readObject();
if (rawFirst == null) {
this.target = player.getBukkitEntity();
return;
}
Double second = result.read(Double.class);
if (second == null) {
this.target = Bukkit.getPlayer(rawFirst.toString());
if (this.target == null) throw new IllegalArgumentException("Player not found: " + rawFirst);
return;
}
Double third = result.read(Double.class);
if (third == null) {
throw new IllegalArgumentException("Missing Z coordinate for look action.");
}
double first;
try {
first = Double.parseDouble(rawFirst.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid number format for X: " + rawFirst, e);
}
this.pos = new Vector(
first,
second,
third
);
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
if (target != null) {
this.pos.setX(this.target.getX());
this.pos.setY(this.target.getY());
this.pos.setZ(this.target.getZ());
}
nbt.putDouble("x", this.pos.getX());
nbt.putDouble("y", this.pos.getY());
nbt.putDouble("z", this.pos.getZ());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.setPos(
new Vector(
nbt.getDouble("x").orElse(0.0),
nbt.getDouble("y").orElse(0.0),
nbt.getDouble("z").orElse(0.0)
)
);
}
@Override
public LookAction setPos(Vector pos) {
this.pos = pos;
return this;
}
@Override
public Vector getPos() {
return this.pos;
}
@Override
public LookAction setTarget(Player player) {
this.target = player;
return this;
}
@Override
public Player getTarget() {
return target;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (target != null) bot.faceLocation(target.getLocation());
else bot.look(pos.subtract(bot.getLocation().toVector()), false);
return true;
}
}

View File

@@ -1,45 +1,44 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.botaction.MoveDirection;
import org.leavesmc.leaves.entity.bot.action.MoveAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.Arrays;
import java.util.List;
public class MoveAction extends AbstractBotAction<MoveAction> {
public class CraftMoveAction extends CraftStateBotAction<MoveAction> implements MoveAction {
private static final Pair<List<String>, String> suggestions = Pair.of(
Arrays.stream(MoveDirection.values()).map((it) -> it.name).toList(),
"<Direction>"
);
private MoveDirection direction;
private MoveDirection direction = MoveDirection.FORWARD;
public MoveAction() {
super("move", CommandArgument.of(CommandArgumentType.ofEnum(MoveDirection.class)), MoveAction::new);
public CraftMoveAction() {
super("move", CommandArgument.of(CommandArgumentType.ofEnum(MoveDirection.class)), CraftMoveAction::new);
this.setSuggestion(0, (sender, arg) -> suggestions);
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
direction = result.read(MoveDirection.class);
if (direction == null) {
throw new IllegalArgumentException("Invalid direction");
}
this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(-1);
public Class<MoveAction> getInterfaceClass() {
return MoveAction.class;
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
direction = result.read(MoveDirection.class);
if (direction == null) throw new IllegalArgumentException("Invalid direction");
}
@Override
public void onStop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
switch (direction) {
case FORWARD, BACKWARD -> bot.zza = 0.0f;
case LEFT, RIGHT -> bot.xxa = 0.0f;
@@ -58,4 +57,14 @@ public class MoveAction extends AbstractBotAction<MoveAction> {
}
return true;
}
@Override
public MoveDirection getDirection() {
return direction;
}
@Override
public void setDirection(MoveDirection direction) {
this.direction = direction;
}
}

View File

@@ -6,46 +6,65 @@ import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.action.RotationAction;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Objects;
public class RotationAction extends AbstractBotAction<RotationAction> {
public class CraftRotationAction extends CraftBotAction<RotationAction> implements RotationAction {
private static final DecimalFormat DF = new DecimalFormat("0.00");
public RotationAction() {
super("rotation", CommandArgument.of(CommandArgumentType.FLOAT, CommandArgumentType.FLOAT), RotationAction::new);
public CraftRotationAction() {
super("rotation", CommandArgument.of(CommandArgumentType.FLOAT, CommandArgumentType.FLOAT), CraftRotationAction::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getYRot())), "[yaw]") : Pair.of(List.of("0"), "<yaw>"));
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getXRot())), "[pitch]") : Pair.of(List.of("0"), "<pitch>"));
}
private float yaw;
private float pitch;
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
if (player == null) {
return;
}
this.setYaw(result.readFloat(player.getYRot())).setPitch(result.readFloat(player.getXRot())).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
public Class<RotationAction> getInterfaceClass() {
return RotationAction.class;
}
private float yaw = 0.0f;
private float pitch = 0.0f;
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
try {
this.yaw = result.readFloat(Objects.requireNonNull(player).getYRot());
this.pitch = result.readFloat(player.getXRot());
} catch (Exception e) {
throw new IllegalArgumentException("No valid rotation specified", e);
}
}
@Override
public RotationAction setYaw(float yaw) {
this.yaw = yaw;
return this;
}
@Override
public RotationAction setPitch(float pitch) {
this.pitch = pitch;
return this;
}
@Override
public float getYaw() {
return this.yaw;
}
@Override
public float getPitch() {
return this.pitch;
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {

View File

@@ -11,19 +11,26 @@ import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.action.ShootAction;
import java.util.Collections;
public class ShootAction extends AbstractTimerAction<ShootAction> {
public class CraftShootAction extends CraftTimerBotAction<ShootAction> implements ShootAction {
private int drawingTick;
private static final int DEFAULT_DRAWING_TICK = 20;
private int drawingTick = DEFAULT_DRAWING_TICK;
private int tickToRelease = -1;
public ShootAction() {
super("shoot", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ShootAction::new);
public CraftShootAction() {
super("shoot", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), CraftShootAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("20"), "[DrawingTick]"));
}
@Override
public Class<ShootAction> getInterfaceClass() {
return ShootAction.class;
}
@Override
public void init() {
super.init();
@@ -48,9 +55,9 @@ public class ShootAction extends AbstractTimerAction<ShootAction> {
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.setDrawingTick(result.readInt(20));
this.drawingTick = result.readInt(DEFAULT_DRAWING_TICK);
}
@Override

View File

@@ -0,0 +1,24 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.action.SneakAction;
public class CraftSneakAction extends CraftBotAction<SneakAction> implements SneakAction {
public CraftSneakAction() {
super("sneak", CommandArgument.EMPTY, CraftSneakAction::new);
}
@Override
public Class<SneakAction> getInterfaceClass() {
return SneakAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.setShiftKeyDown(!bot.isShiftKeyDown());
return true;
}
}

View File

@@ -0,0 +1,17 @@
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;
public abstract class CraftStateBotAction<E extends StateBotAction<E>> extends CraftBotAction<E> implements StateBotAction<E> {
public CraftStateBotAction(String name, CommandArgument argument, Supplier<E> creator) {
super(name, argument, creator);
this.setDoNumber0(-1);
}
}

View File

@@ -0,0 +1,27 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.action.SwimAction;
public class CraftSwimAction extends CraftStateBotAction<SwimAction> implements SwimAction {
public CraftSwimAction() {
super("swim", CommandArgument.EMPTY, CraftSwimAction::new);
}
@Override
public Class<SwimAction> getInterfaceClass() {
return SwimAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isInWater()) {
bot.addDeltaMovement(new Vec3(0, 0.03, 0));
}
return true;
}
}

View File

@@ -0,0 +1,74 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.action.TimerBotAction;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
public abstract class CraftTimerBotAction<E extends TimerBotAction<E>> extends CraftBotAction<E> implements TimerBotAction<E> {
public CraftTimerBotAction(String name, Supplier<E> creator) {
this(name, CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), creator);
}
public CraftTimerBotAction(String name, CommandArgument argument, Supplier<E> creator) {
super(name, argument, creator);
this.setSuggestion(0, Pair.of(Collections.singletonList("0"), "[TickDelay]"));
this.setSuggestion(1, Pair.of(Collections.singletonList("20"), "[TickInterval]"));
this.setSuggestion(2, Pair.of(List.of("1", "-1"), "[DoNumber]"));
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setStartDelayTick0(result.readInt(0));
this.setDoIntervalTick0(result.readInt(20));
this.setDoNumber0(result.readInt(1));
}
@Override
public int getDoNumberRemaining() {
return super.getDoNumberRemaining();
}
@Override
public int getTickToNext() {
return super.getTickToNext();
}
@Override
public int getDoNumber() {
return super.getDoNumber();
}
@Override
public void setDoNumber(int initialNumber) {
super.setDoNumber0(initialNumber);
}
@Override
public int getDoIntervalTick() {
return super.getDoIntervalTick();
}
@Override
public void setDoIntervalTick(int initialTickInterval) {
super.setDoIntervalTick0(initialTickInterval);
}
@Override
public int getStartDelayTick() {
return super.getStartDelayTick();
}
@Override
public void setStartDelayTick(int initialTickDelay) {
super.setStartDelayTick0(initialTickDelay);
}
}

View File

@@ -3,11 +3,17 @@ package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemAction;
public class UseItemAction extends AbstractTimerAction<UseItemAction> {
public class CraftUseItemAction extends CraftTimerBotAction<UseItemAction> implements UseItemAction {
public UseItemAction() {
super("use", UseItemAction::new);
public CraftUseItemAction() {
super("use", CraftUseItemAction::new);
}
@Override
public Class<UseItemAction> getInterfaceClass() {
return UseItemAction.class;
}
@Override
@@ -15,7 +21,7 @@ public class UseItemAction extends AbstractTimerAction<UseItemAction> {
return execute(bot);
}
public static boolean execute(ServerBot bot) {
public static boolean execute(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}

View File

@@ -5,11 +5,17 @@ import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemAutoAction;
public class UseItemAutoAction extends AbstractTimerAction<UseItemAutoAction> {
public class CraftUseItemAutoAction extends CraftTimerBotAction<UseItemAutoAction> implements UseItemAutoAction {
public UseItemAutoAction() {
super("use_auto", UseItemAutoAction::new);
public CraftUseItemAutoAction() {
super("use_auto", CraftUseItemAutoAction::new);
}
@Override
public Class<UseItemAutoAction> getInterfaceClass() {
return UseItemAutoAction.class;
}
@Override
@@ -21,11 +27,11 @@ public class UseItemAutoAction extends AbstractTimerAction<UseItemAutoAction> {
Entity entity = bot.getTargetEntity(3, null);
BlockHitResult blockHitResult = (BlockHitResult) bot.getRayTrace(5, ClipContext.Fluid.NONE);
if (entity != null) {
return UseItemToAction.execute(bot, entity);
return CraftUseItemToAction.execute(bot, entity);
} else if (!bot.level().getBlockState(blockHitResult.getBlockPos()).isAir()) {
return UseItemOnAction.execute(bot, blockHitResult);
return CraftUseItemOnAction.execute(bot, blockHitResult);
} else {
return UseItemAction.execute(bot);
return CraftUseItemAction.execute(bot);
}
}
}

View File

@@ -5,11 +5,17 @@ import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemAutoOffhandAction;
public class UseItemAutoOffhandAction extends AbstractTimerAction<UseItemAutoOffhandAction> {
public class CraftUseItemAutoOffhandAction extends CraftTimerBotAction<UseItemAutoOffhandAction> implements UseItemAutoOffhandAction {
public UseItemAutoOffhandAction() {
super("use_auto_offhand", UseItemAutoOffhandAction::new);
public CraftUseItemAutoOffhandAction() {
super("use_auto_offhand", CraftUseItemAutoOffhandAction::new);
}
@Override
public Class<UseItemAutoOffhandAction> getInterfaceClass() {
return UseItemAutoOffhandAction.class;
}
@Override
@@ -21,11 +27,11 @@ public class UseItemAutoOffhandAction extends AbstractTimerAction<UseItemAutoOff
Entity entity = bot.getTargetEntity(3, null);
BlockHitResult blockHitResult = (BlockHitResult) bot.getRayTrace(5, ClipContext.Fluid.NONE);
if (entity != null) {
return UseItemToOffhandAction.execute(bot, entity);
return CraftUseItemToOffhandAction.execute(bot, entity);
} else if (!bot.level().getBlockState(blockHitResult.getBlockPos()).isAir()) {
return UseItemOnOffhandAction.execute(bot, blockHitResult);
return CraftUseItemOnOffhandAction.execute(bot, blockHitResult);
} else {
return UseItemOffHandAction.execute(bot);
return CraftUseItemOffHandAction.execute(bot);
}
}
}

View File

@@ -3,11 +3,17 @@ package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemOffHandAction;
public class UseItemOffHandAction extends AbstractTimerAction<UseItemOffHandAction> {
public class CraftUseItemOffHandAction extends CraftTimerBotAction<UseItemOffHandAction> implements UseItemOffHandAction {
public UseItemOffHandAction() {
super("use_offhand", UseItemOffHandAction::new);
public CraftUseItemOffHandAction() {
super("use_offhand", CraftUseItemOffHandAction::new);
}
@Override
public Class<UseItemOffHandAction> getInterfaceClass() {
return UseItemOffHandAction.class;
}
@Override
@@ -15,7 +21,7 @@ public class UseItemOffHandAction extends AbstractTimerAction<UseItemOffHandActi
return execute(bot);
}
public static boolean execute(ServerBot bot) {
public static boolean execute(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}

View File

@@ -0,0 +1,50 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemOnAction;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
public class CraftUseItemOnAction extends CraftTimerBotAction<UseItemOnAction> implements UseItemOnAction {
public CraftUseItemOnAction() {
super("use_on", CraftUseItemOnAction::new);
}
@Override
public Class<UseItemOnAction> getInterfaceClass() {
return UseItemOnAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
return execute(bot, result);
}
public static boolean execute(@NotNull ServerBot bot, HitResult result) {
if (!(result instanceof BlockHitResult blockHitResult)) return false;
BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) return false;
bot.swing(InteractionHand.MAIN_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos());
if (!(entity instanceof TrappedChestBlockEntity chestBlockEntity)) return false;
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
} else {
bot.updateItemInHand(InteractionHand.MAIN_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, blockHitResult).consumesAction();
}
}
}

View File

@@ -0,0 +1,50 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemOnOffhandAction;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
public class CraftUseItemOnOffhandAction extends CraftTimerBotAction<UseItemOnOffhandAction> implements UseItemOnOffhandAction {
public CraftUseItemOnOffhandAction() {
super("use_on_offhand", CraftUseItemOnOffhandAction::new);
}
@Override
public Class<UseItemOnOffhandAction> getInterfaceClass() {
return UseItemOnOffhandAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
return execute(bot, result);
}
public static boolean execute(ServerBot bot, HitResult result) {
if (!(result instanceof BlockHitResult blockHitResult)) return false;
BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) return false;
bot.swing(InteractionHand.OFF_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos());
if (!(entity instanceof TrappedChestBlockEntity chestBlockEntity)) return false;
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
} else {
bot.updateItemInHand(InteractionHand.OFF_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, blockHitResult).consumesAction();
}
}
}

View File

@@ -0,0 +1,35 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemToAction;
public class CraftUseItemToAction extends CraftTimerBotAction<UseItemToAction> implements UseItemToAction {
public CraftUseItemToAction() {
super("use_to", CraftUseItemToAction::new);
}
@Override
public Class<UseItemToAction> getInterfaceClass() {
return UseItemToAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, null);
return execute(bot, entity);
}
public static boolean execute(ServerBot bot, Entity entity) {
if (entity == null) return false;
boolean flag = bot.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.MAIN_HAND);
bot.updateItemInHand(InteractionHand.MAIN_HAND);
}
return flag;
}
}

View File

@@ -0,0 +1,36 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.action.UseItemOnOffhandAction;
import org.leavesmc.leaves.entity.bot.action.UseItemToOffhandAction;
public class CraftUseItemToOffhandAction extends CraftTimerBotAction<UseItemToOffhandAction> implements UseItemToOffhandAction {
public CraftUseItemToOffhandAction() {
super("use_to_offhand", CraftUseItemToOffhandAction::new);
}
@Override
public Class<UseItemToOffhandAction> getInterfaceClass() {
return UseItemToOffhandAction.class;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, null);
return execute(bot, entity);
}
public static boolean execute(ServerBot bot, Entity entity) {
if (entity == null) return false;
boolean flag = bot.interactOn(entity, InteractionHand.OFF_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.OFF_HAND);
bot.updateItemInHand(InteractionHand.OFF_HAND);
}
return flag;
}
}

View File

@@ -1,17 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class DropAction extends AbstractTimerAction<DropAction> {
public DropAction() {
super("drop", DropAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.dropAll(false);
return true;
}
}

View File

@@ -1,73 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import java.text.DecimalFormat;
import java.util.List;
public class LookAction extends AbstractBotAction<LookAction> {
private static final DecimalFormat DF = new DecimalFormat("0.0");
public LookAction() {
super("look", CommandArgument.of(CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE), LookAction::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getX())), "<X>") : Pair.of(List.of("0"), "<X>"));
this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getY())), "<Y>") : Pair.of(List.of("0"), "<Y>"));
this.setSuggestion(2, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getZ())), "<Z>") : Pair.of(List.of("0"), "<Z>"));
}
private Vector pos;
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) throws IllegalArgumentException {
Vector pos = result.readVector();
if (pos != null) {
this.setPos(pos).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
} else {
throw new IllegalArgumentException("pos?");
}
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putDouble("x", this.pos.getX());
nbt.putDouble("y", this.pos.getY());
nbt.putDouble("z", this.pos.getZ());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.setPos(
new Vector(
nbt.getDouble("x").orElse(0.0),
nbt.getDouble("y").orElse(0.0),
nbt.getDouble("z").orElse(0.0)
)
);
}
public LookAction setPos(Vector pos) {
this.pos = pos;
return this;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.look(pos.subtract(bot.getLocation().toVector()), false);
return true;
}
}

View File

@@ -1,51 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
public class RotateAction extends AbstractBotAction<RotateAction> {
public RotateAction() {
super("rotate", CommandArgument.EMPTY, RotateAction::new);
}
private ServerPlayer player;
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setPlayer(player).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
}
public RotateAction setPlayer(ServerPlayer player) {
this.player = player;
return this;
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putString("actionName", "look"); // to player loc
nbt.putDouble("x", player.getX());
nbt.putDouble("y", player.getY());
nbt.putDouble("z", player.getZ());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.faceLocation(player.getBukkitEntity().getLocation());
return true;
}
}

View File

@@ -1,27 +0,0 @@
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.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
public class SneakAction extends AbstractBotAction<SneakAction> {
public SneakAction() {
super("sneak", CommandArgument.EMPTY, SneakAction::new);
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.setShiftKeyDown(!bot.isShiftKeyDown());
return true;
}
}

View File

@@ -1,30 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
public class SwimAction extends AbstractBotAction<SwimAction> {
public SwimAction() {
super("swim", CommandArgument.EMPTY, SwimAction::new);
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isInWater()) {
bot.addDeltaMovement(new Vec3(0, 0.03, 0));
}
return true;
}
}

View File

@@ -1,49 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
public class UseItemOnAction extends AbstractTimerAction<UseItemOnAction> {
public UseItemOnAction() {
super("use_on", UseItemOnAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
return execute(bot, result);
}
public static boolean execute(ServerBot bot, HitResult result) {
if (result instanceof BlockHitResult blockHitResult) {
BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) {
return false;
}
bot.swing(InteractionHand.MAIN_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos());
if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
}
} else {
bot.updateItemInHand(InteractionHand.MAIN_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, (BlockHitResult) result).consumesAction();
}
}
return false;
}
}

View File

@@ -1,49 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
public class UseItemOnOffhandAction extends AbstractTimerAction<UseItemOnOffhandAction> {
public UseItemOnOffhandAction() {
super("use_on_offhand", UseItemOnOffhandAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
return execute(bot, result);
}
public static boolean execute(ServerBot bot, HitResult result) {
if (result instanceof BlockHitResult blockHitResult) {
BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) {
return false;
}
bot.swing(InteractionHand.OFF_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos());
if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
}
} else {
bot.updateItemInHand(InteractionHand.OFF_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, (BlockHitResult) result).consumesAction();
}
}
return false;
}
}

View File

@@ -1,31 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class UseItemToAction extends AbstractTimerAction<UseItemToAction> {
public UseItemToAction() {
super("use_to", UseItemToAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, null);
return execute(bot, entity);
}
public static boolean execute(ServerBot bot, Entity entity) {
if (entity != null) {
boolean flag = bot.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.MAIN_HAND);
bot.updateItemInHand(InteractionHand.MAIN_HAND);
}
return flag;
}
return false;
}
}

View File

@@ -1,31 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class UseItemToOffhandAction extends AbstractTimerAction<UseItemToOffhandAction> {
public UseItemToOffhandAction() {
super("use_to_offhand", UseItemToOffhandAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, null);
return execute(bot, entity);
}
public static boolean execute(ServerBot bot, Entity entity) {
if (entity != null) {
boolean flag = bot.interactOn(entity, InteractionHand.OFF_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.OFF_HAND);
bot.updateItemInHand(InteractionHand.OFF_HAND);
}
return flag;
}
return false;
}
}

View File

@@ -10,9 +10,9 @@ import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction;
import org.leavesmc.leaves.bot.agent.actions.CraftBotAction;
import org.leavesmc.leaves.bot.agent.actions.CraftCustomAction;
import org.leavesmc.leaves.command.LeavesSubcommand;
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
@@ -52,7 +52,7 @@ public class BotActionCommand implements LeavesSubcommand {
}
private void executeStart(ServerBot bot, CommandSender sender, String[] args) {
AbstractBotAction<?> action = Actions.getForName(args[2]);
CraftBotAction<?> action = Actions.getForName(args[2]);
if (action == null) {
sender.sendMessage(text("Invalid action", NamedTextColor.RED));
return;
@@ -66,23 +66,19 @@ public class BotActionCommand implements LeavesSubcommand {
}
String[] realArgs = Arrays.copyOfRange(args, 3, args.length);
AbstractBotAction<?> newAction;
CraftBotAction<?> newAction;
try {
if (action instanceof CraftCustomBotAction customBotAction) {
newAction = customBotAction.createCraft(player, realArgs);
if (action instanceof CraftCustomAction<?> customBotAction) {
newAction = (CraftBotAction<?>) customBotAction.createCraft(player, realArgs);
} else {
newAction = action.create();
newAction.loadCommand(player.getHandle(), action.getArgument().parse(0, realArgs));
newAction = (CraftBotAction<?>) action.create();
}
newAction.loadCommand(player.getHandle(), action.getArgument().parse(0, realArgs));
} catch (IllegalArgumentException e) {
sender.sendMessage(text("Action create error, please check your arguments, " + e.getMessage(), NamedTextColor.RED));
return;
}
if (newAction == null) {
return;
}
if (bot.addBotAction(newAction, sender)) {
sender.sendMessage("Action " + action.getName() + " has been issued to " + bot.getName().getString());
}
@@ -96,9 +92,9 @@ public class BotActionCommand implements LeavesSubcommand {
String index = args[2];
if (index.equals("all")) {
Set<AbstractBotAction<?>> forRemoval = new HashSet<>();
Set<CraftBotAction<?>> forRemoval = new HashSet<>();
for (int i = 0; i < bot.getBotActions().size(); i++) {
AbstractBotAction<?> action = bot.getBotActions().get(i);
CraftBotAction<?> action = bot.getBotActions().get(i);
BotActionStopEvent event = new BotActionStopEvent(
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
);
@@ -119,7 +115,7 @@ public class BotActionCommand implements LeavesSubcommand {
return;
}
AbstractBotAction<?> action = bot.getBotActions().get(i);
CraftBotAction<?> action = bot.getBotActions().get(i);
BotActionStopEvent event = new BotActionStopEvent(
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
);
@@ -159,7 +155,7 @@ public class BotActionCommand implements LeavesSubcommand {
}
}
case 4, 5, 6, 7 -> {
AbstractBotAction<?> action = Actions.getForName(args[2]);
CraftBotAction<?> action = Actions.getForName(args[2]);
if (action == null) {
return;
}

View File

@@ -12,7 +12,7 @@ import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.LeavesSubcommand;
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.ArrayList;
import java.util.HashMap;

View File

@@ -54,6 +54,13 @@ public class CommandArgumentResult {
return new Vector(pos[0], pos[1], pos[2]);
}
public Object readObject() {
if (result.isEmpty()) {
return null;
}
return result.removeFirst();
}
public <T> T read(Class<T> tClass, T def) {
return Objects.requireNonNullElse(read(tClass), def);
}

View File

@@ -9,9 +9,9 @@ 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.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.actions.CraftBotAction;
import org.leavesmc.leaves.entity.botaction.LeavesBotAction;
import org.leavesmc.leaves.entity.bot.Bot;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import org.leavesmc.leaves.event.bot.BotRemoveEvent;
@@ -39,13 +39,13 @@ public class CraftBot extends CraftPlayer implements Bot {
}
@Override
public void addAction(@NotNull LeavesBotAction action) {
this.getHandle().addBotAction(CraftBotAction.asInternalCopy(action), null);
public void addAction(@NotNull BotAction action) {
this.getHandle().addBotAction((CraftBotAction<?>) action, null);
}
@Override
public LeavesBotAction getAction(int index) {
return CraftBotAction.asAPICopy(this.getHandle().getBotActions().get(index));
public BotAction getAction(int index) {
return this.getHandle().getBotActions().get(index);
}
@Override
@@ -60,7 +60,7 @@ public class CraftBot extends CraftPlayer implements Bot {
@Override
public void stopAllActions() {
for (AbstractBotAction<?> action : this.getHandle().getBotActions()) {
for (CraftBotAction<?> action : this.getHandle().getBotActions()) {
action.stop(this.getHandle(), BotActionStopEvent.Reason.PLUGIN);
}
}

View File

@@ -8,10 +8,15 @@ import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.BotCreateState;
import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
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.entity.botaction.CustomBotAction;
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.CustomTimerBotAction;
import org.leavesmc.leaves.event.bot.BotCreateEvent;
import java.util.Collection;
@@ -60,13 +65,30 @@ public class CraftBotManager implements BotManager {
@Override
public boolean unregisterCustomBotAction(String name) {
AbstractBotAction<?> action = Actions.getForName(name);
CraftBotAction<?> action = Actions.getForName(name);
if (action instanceof CraftCustomBotAction) {
return Actions.unregister(name);
}
return false;
}
@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 {
return (T) ((CraftBotAction<?>) action).create();
} catch (Exception e) {
throw new RuntimeException("Failed to create action of type: " + type.getName(), e);
}
}
@Override
public BotCreator botCreator(@NotNull String realName, @NotNull Location location) {
return BotCreateState.builder(realName, location).createReason(BotCreateEvent.CreateReason.PLUGIN);

View File

@@ -6,6 +6,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.photographer.Photographer;
import org.leavesmc.leaves.replay.ServerPhotographer;
import java.io.File;

View File

@@ -4,6 +4,8 @@ import com.google.common.collect.Lists;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.photographer.Photographer;
import org.leavesmc.leaves.entity.photographer.PhotographerManager;
import org.leavesmc.leaves.replay.BukkitRecorderOption;
import org.leavesmc.leaves.replay.RecorderOption;
import org.leavesmc.leaves.replay.ServerPhotographer;

View File

@@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesLogger;
import org.leavesmc.leaves.bot.BotStatsCounter;
import org.leavesmc.leaves.entity.CraftPhotographer;
import org.leavesmc.leaves.entity.Photographer;
import org.leavesmc.leaves.entity.photographer.Photographer;
import java.io.File;
import java.io.IOException;