9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-19 14:59:32 +00:00
Files
LeavesMC/patches/server/0011-Add-fakeplayer-action-support.patch
2022-06-14 07:49:46 +00:00

845 lines
28 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: violetc <58360096+s-yh-china@users.noreply.github.com>
Date: Wed, 16 Feb 2022 12:42:14 +0800
Subject: [PATCH] Add fakeplayer action support
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index cd9cbfa5ef94994b3f7f2ecdde843620e7e6c071..7bd5a106028958c829ef9e161d5c287ff36c3f6c 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1290,7 +1290,7 @@ public abstract class Player extends LivingEntity {
boolean flag3 = false;
double d0 = (double) (this.walkDist - this.walkDistO);
- if (flag && !flag2 && !flag1 && this.onGround && d0 < (double) this.getSpeed()) {
+ if (flag && !flag2 && !flag1 && this.isOnGround() && d0 < (double) this.getSpeed()) { // Leaves - use isOnGround method
ItemStack itemstack = this.getItemInHand(InteractionHand.MAIN_HAND);
if (itemstack.getItem() instanceof SwordItem) {
diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
index 898c61c25675232e203ee2c872ca25804c41358c..4d6d025c78086f186da710ae46f65eda5426464d 100644
--- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java
+++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
@@ -68,6 +68,7 @@ public final class LeavesConfig {
if (top.leavesmc.leaves.LeavesConfig.fakeplayerSupport) {
commands.put("bot", new BotCommand("bot"));
+ top.leavesmc.leaves.bot.agent.Actions.registerAll();
}
}
diff --git a/src/main/java/top/leavesmc/leaves/bot/Bot.java b/src/main/java/top/leavesmc/leaves/bot/Bot.java
index 40ee486cdd3939b4d42e6dac042cd252dc07a001..fd7b88845fb2a03fe94dfbb3bad0c6705ba56b31 100644
--- a/src/main/java/top/leavesmc/leaves/bot/Bot.java
+++ b/src/main/java/top/leavesmc/leaves/bot/Bot.java
@@ -1,9 +1,12 @@
package top.leavesmc.leaves.bot;
+import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
+import com.mojang.datafixers.util.Pair;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
+import net.minecraft.Util;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
@@ -12,6 +15,7 @@ import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
+import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.server.MinecraftServer;
@@ -22,11 +26,14 @@ import net.minecraft.server.level.TicketType;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.util.Mth;
+import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.MoverType;
+import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.level.ChunkPos;
-import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
@@ -46,10 +53,14 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.Vector;
+import top.leavesmc.leaves.bot.agent.BotAction;
import top.leavesmc.leaves.util.MathUtils;
import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
@@ -58,12 +69,17 @@ public class Bot extends ServerPlayer {
private Vector velocity;
private Vector oldVelocity;
+ private BotAction action;
+ private BotAction newAction;
private boolean removeOnDeath;
- private byte fireTicks;
- private byte groundTicks;
- private byte jumpTicks;
- private byte noFallTicks;
+ private int fireTicks;
+ private int groundTicks;
+ private int jumpTicks;
+ private int noFallTicks;
+ private int noActionTicks;
+
+ private final ItemStack defaultItem;
private static final Set<Bot> bots = new HashSet<>();
private static final Plugin MINECRAFT_PLUGIN = new MinecraftInternalPlugin();
@@ -73,9 +89,12 @@ public class Bot extends ServerPlayer {
this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.INT), 0xFF);
this.velocity = new Vector(0, 0, 0);
+ this.action = null;
this.oldVelocity = velocity.clone();
this.noFallTicks = 60;
this.fireTicks = 0;
+ this.noActionTicks = 0;
+ this.defaultItem = new ItemStack(Material.AIR);
this.removeOnDeath = true;
}
@@ -164,12 +183,17 @@ public class Bot extends ServerPlayer {
}
}
+ private void removeTab() {
+ sendPacket(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, this));
+ }
+
private void setDead() {
sendPacket(new ClientboundRemoveEntitiesPacket(getId()));
this.dead = true;
this.inventoryMenu.removed(this);
this.containerMenu.removed(this);
}
+
// die check end
@Override
@@ -177,10 +201,6 @@ public class Bot extends ServerPlayer {
return groundTicks != 0;
}
- private void removeTab() {
- sendPacket(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, this));
- }
-
public static boolean solidAt(Location loc) {
Block block = loc.getBlock();
BoundingBox box = block.getBoundingBox();
@@ -269,12 +289,24 @@ public class Bot extends ServerPlayer {
public void tick() {
loadChunks(); // Load chunks
super.tick();
+ this.doTick();
- if (!isAlive()) return;
+ if (!isAlive()) {
+ return;
+ }
- if (fireTicks > 0) --fireTicks;
- if (jumpTicks > 0) --jumpTicks;
- if (noFallTicks > 0) --noFallTicks;
+ if (fireTicks > 0) {
+ --fireTicks;
+ }
+ if (jumpTicks > 0) {
+ --jumpTicks;
+ }
+ if (noFallTicks > 0) {
+ --noFallTicks;
+ }
+ if (noActionTicks > 0) {
+ --noActionTicks;
+ }
if (checkGround()) {
if (groundTicks < 5) groundTicks++;
@@ -302,7 +334,88 @@ public class Bot extends ServerPlayer {
checkOutOfWorld();
+ ++this.attackStrengthTicker;
+
+ if (this.getHealth() > 0.0F) {
+ AABB axisalignedbb;
+
+ if (this.isPassenger() && !this.getVehicle().isRemoved()) {
+ axisalignedbb = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0D, 0.0D, 1.0D);
+ } else {
+ axisalignedbb = this.getBoundingBox().inflate(1.0D, 0.5D, 1.0D);
+ }
+
+ List<Entity> list = this.level.getEntities(this, axisalignedbb);
+ List<Entity> list1 = Lists.newArrayList();
+
+ for (Entity entity : list) {
+ if (entity.getType() == EntityType.EXPERIENCE_ORB) {
+ list1.add(entity);
+ } else if (!entity.isRemoved()) {
+ this.touch(entity);
+ }
+ }
+
+ if (!list1.isEmpty()) {
+ this.touch((Entity) Util.getRandom((List) list1, this.random));
+ }
+ }
+
oldVelocity = velocity.clone();
+
+ if (newAction != null) {
+ action = newAction;
+ newAction = null;
+ noActionTicks = 0;
+ }
+
+ if (action != null && noActionTicks <= 0) {
+ if (action.isCancel()) {
+ action = null;
+ } else {
+ action.tick(this);
+ noActionTicks = action.getTickDelay();
+ }
+ }
+ }
+
+ private void touch(Entity entity) {
+ entity.playerTouch(this);
+ }
+
+ @Override
+ public void onItemPickup(ItemEntity item) {
+ super.onItemPickup(item);
+ this.updateItemInMainHand();
+ }
+
+ private ItemStack lastItem = new ItemStack(Material.AIR);
+ public void updateItemInMainHand() {
+ ItemStack item = this.getInventory().getSelected().asBukkitCopy();
+ if (!lastItem.isSimilar(item)) {
+ this.setItem(item, EquipmentSlot.MAINHAND);
+ lastItem = item;
+ }
+
+ if (item.getAmount() == 0) {
+ this.setItem(defaultItem, EquipmentSlot.MAINHAND);
+ lastItem = defaultItem;
+ }
+ }
+
+ @Override
+ public void doTick() {
+ if (this.hurtTime > 0) {
+ this.hurtTime -= 1;
+ }
+
+ baseTick();
+ tickEffects();
+
+ this.lerpSteps = (int) this.zza;
+ this.animStep = this.run;
+ this.yRotO = this.getYRot();
+ this.xRotO = this.getXRot();
}
@Override
@@ -335,21 +448,6 @@ public class Bot extends ServerPlayer {
}
}
- @Override
- public void doTick() {
- if (this.hurtTime > 0) {
- this.hurtTime -= 1;
- }
-
- baseTick();
- tickEffects();
-
- this.lerpSteps = (int) this.zza;
- this.animStep = this.run;
- this.yRotO = this.getYRot();
- this.xRotO = this.getXRot();
- }
-
public Location getLocation() {
return getBukkitPlayer().getLocation();
}
@@ -441,6 +539,68 @@ public class Bot extends ServerPlayer {
this.move(MoverType.SELF, new Vec3(velocity.getX(), y, velocity.getZ()));
}
+ public void faceLocation(Location loc) {
+ look(loc.toVector().subtract(getLocation().toVector()), false);
+ }
+
+ private void look(Vector dir, boolean keepYaw) {
+ float yaw, pitch;
+
+ if (keepYaw) {
+ yaw = this.getYHeadRot();
+ pitch = MathUtils.fetchPitch(dir);
+ } else {
+ float[] vals = MathUtils.fetchYawPitch(dir);
+ yaw = vals[0];
+ pitch = vals[1];
+
+ sendPacket(new ClientboundRotateHeadPacket(this, (byte) (yaw * 256 / 360f)));
+ }
+
+ setRot(yaw, pitch);
+ this.getBukkitPlayer().getLocation().setYaw(yaw);
+ this.getBukkitPlayer().getLocation().setPitch(pitch);
+ }
+
+ public void punch() {
+ swing(InteractionHand.MAIN_HAND);
+ }
+
+ public void attack(Entity target) {
+ super.attack(target);
+ punch();
+ }
+
+ public void setItem(org.bukkit.inventory.ItemStack item, EquipmentSlot slot) {
+ if (item == null) {
+ item = defaultItem;
+ }
+
+ this.detectEquipmentUpdates();
+ if (slot == EquipmentSlot.MAINHAND) {
+ getBukkitPlayer().getInventory().setItemInMainHand(item);
+ setItemInHand(InteractionHand.MAIN_HAND, CraftItemStack.asNMSCopy(item));
+ } else if (slot == EquipmentSlot.OFFHAND) {
+ getBukkitPlayer().getInventory().setItemInOffHand(item);
+ setItemInHand(InteractionHand.OFF_HAND, CraftItemStack.asNMSCopy(item));
+ }
+
+ sendPacket(new ClientboundSetEquipmentPacket(getId(), new ArrayList<>(Collections.singletonList(
+ new Pair<>(slot, CraftItemStack.asNMSCopy(item))
+ ))));
+ }
+
+ public void dropAll() {
+ getInventory().dropAll();
+ for (EquipmentSlot slot : EquipmentSlot.values()) {
+ setItem(null, slot);
+ }
+ }
+
+ public void setBotAction(BotAction botAction) {
+ this.newAction = botAction;
+ }
+
public static Bot getBot(ServerPlayer player) {
Bot bot = null;
for (Bot b : bots) {
diff --git a/src/main/java/top/leavesmc/leaves/bot/BotCommand.java b/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
index 3b8d44fb61d504e521e73d3a34f6bd8ad9f13aee..ec1c53e2f98717b648c80ddf7573edad7f29b135 100644
--- a/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
+++ b/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
@@ -5,7 +5,11 @@ import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
+import top.leavesmc.leaves.bot.agent.Actions;
+import top.leavesmc.leaves.bot.agent.BotAction;
+import top.leavesmc.leaves.util.MathUtils;
import java.util.ArrayList;
import java.util.List;
@@ -15,7 +19,7 @@ public class BotCommand extends Command {
public BotCommand(String name) {
super(name);
this.description = "FakePlayer Command";
- this.usageMessage = "/bot [create | remove]";
+ this.usageMessage = "/bot [create | remove | action]";
this.setPermission("bukkit.command.bot");
}
@@ -26,13 +30,27 @@ public class BotCommand extends Command {
if (args.length <= 1) {
list.add("create");
list.add("remove");
- } else {
+ list.add("action");
+ }
+
+ if (args.length == 2) {
switch (args[0]) {
- case "create" -> list.add("[BotName]");
- case "remove" -> list.addAll(Bot.getBots().stream().map(e -> e.getName().getString()).toList());
+ case "create" -> list.add("<BotName>");
+ case "remove", "action" -> list.addAll(Bot.getBots().stream().map(e -> e.getName().getString()).toList());
}
}
+ if (args.length == 3) {
+ switch (args[0]) {
+ case "action" -> list.addAll(Actions.getAll().stream().map(BotAction::getName).toList());
+ }
+ }
+
+ if (args.length == 4) {
+ switch (args[0]) {
+ case "action" -> list.add("[tickDelay]");
+ }
+ }
return list;
}
@@ -50,6 +68,8 @@ public class BotCommand extends Command {
case "remove" -> this.onRemove(sender, args);
+ case "action" -> this.onAction(sender, args);
+
default -> {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
@@ -61,7 +81,7 @@ public class BotCommand extends Command {
private void onCreate(CommandSender sender, String[] args) {
if (args.length < 2) {
- sender.sendMessage(ChatColor.RED + "Use /bot create [name] to create a fakeplayer");
+ sender.sendMessage(ChatColor.RED + "Use /bot create <name> to create a fakeplayer");
return;
}
@@ -85,7 +105,7 @@ public class BotCommand extends Command {
private void onRemove(CommandSender sender, String[] args) {
if (args.length < 2) {
- sender.sendMessage(ChatColor.RED + "Use /bot remove [name] to remove a fakeplayer");
+ sender.sendMessage(ChatColor.RED + "Use /bot remove <name> to remove a fakeplayer");
return;
}
@@ -98,4 +118,31 @@ public class BotCommand extends Command {
bot.kill();
}
+
+ private void onAction(CommandSender sender, String[] args) {
+ if (args.length < 3) {
+ sender.sendMessage(ChatColor.RED + "Use /bot action <name> <action> to make fakeplayer do action");
+ return;
+ }
+
+ int tickDelay = 20;
+ if (args.length > 3 && MathUtils.isNumeric(args[3])) {
+ tickDelay = Integer.parseInt(args[3]);
+ }
+
+ Bot bot = Bot.getBot(args[1]);
+ BotAction action = Actions.getForName(args[2]);
+
+ if (bot == null) {
+ sender.sendMessage(ChatColor.RED + "This fakeplayer is null");
+ return;
+ }
+ if (action == null) {
+ sender.sendMessage(ChatColor.RED + "This action is null");
+ return;
+ }
+
+ bot.setBotAction(action.getNew(tickDelay, ((CraftPlayer) sender).getHandle()));
+ sender.sendMessage("Action set");
+ }
}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/Actions.java b/src/main/java/top/leavesmc/leaves/bot/agent/Actions.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccedc7b77bef852b66dfa8c4ee3d69b3c71717a0
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/Actions.java
@@ -0,0 +1,47 @@
+package top.leavesmc.leaves.bot.agent;
+
+import top.leavesmc.leaves.bot.agent.action.AttackAction;
+import top.leavesmc.leaves.bot.agent.action.DropAction;
+import top.leavesmc.leaves.bot.agent.action.RotateAction;
+import top.leavesmc.leaves.bot.agent.action.StopAction;
+import top.leavesmc.leaves.bot.agent.action.UseItemAction;
+import top.leavesmc.leaves.bot.agent.action.UseItemOnAction;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class Actions {
+
+ private static final Set<BotAction> actions = new HashSet<>();
+
+ public static void registerAll() {
+ register(new AttackAction());
+ register(new DropAction());
+ register(new RotateAction());
+ register(new UseItemAction());
+ register(new UseItemOnAction());
+ register(new StopAction());
+ }
+
+ public static void register(BotAction action) {
+ for (BotAction a : actions) {
+ if (a.getName().equals(action.getName())) {
+ return;
+ }
+ }
+ actions.add(action);
+ }
+
+ public static Set<BotAction> getAll() {
+ return actions;
+ }
+
+ public static BotAction getForName(String name) {
+ for (BotAction a : actions) {
+ if (a.getName().equals(name)) {
+ return a;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/BotAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/BotAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..78f04e28afa856c900f84af42f22666bec3ec830
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/BotAction.java
@@ -0,0 +1,42 @@
+package top.leavesmc.leaves.bot.agent;
+
+import net.minecraft.server.level.ServerPlayer;
+import top.leavesmc.leaves.bot.Bot;
+
+public abstract class BotAction {
+
+ private final String name;
+ private boolean cancel;
+ private int tickDelay;
+
+ public BotAction(String name) {
+ this.name = name;
+ this.cancel = false;
+ this.tickDelay = 20;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getTickDelay() {
+ return tickDelay;
+ }
+
+ public BotAction setTickDelay(int tickDelay) {
+ this.tickDelay = tickDelay;
+ return this;
+ }
+
+ public boolean isCancel() {
+ return cancel;
+ }
+
+ public void setCancel(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+ public abstract BotAction getNew(int tickDelay, ServerPlayer player);
+
+ public abstract void tick(Bot bot);
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/action/AttackAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/action/AttackAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..975b45b7ba3107b143577f53c6b54194e3a699b6
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/AttackAction.java
@@ -0,0 +1,26 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.phys.EntityHitResult;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+
+public class AttackAction extends BotAction {
+
+ public AttackAction() {
+ super("attack");
+ }
+
+ @Override
+ public BotAction getNew(int tickDelay, ServerPlayer player) {
+ return new AttackAction().setTickDelay(tickDelay);
+ }
+
+ @Override
+ public void tick(Bot bot) {
+ EntityHitResult result = bot.getTargetEntity(3);
+ if (result != null) {
+ bot.attack(result.getEntity());
+ }
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/action/DropAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/action/DropAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..91da2f89b6937a78a39da2a6f2c346f0ad446001
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/DropAction.java
@@ -0,0 +1,22 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+
+public class DropAction extends BotAction {
+ public DropAction() {
+ super("drop");
+ }
+
+ @Override
+ public BotAction getNew(int tickDelay, ServerPlayer player) {
+ return new DropAction().setTickDelay(tickDelay);
+ }
+
+ @Override
+ public void tick(Bot bot) {
+ bot.dropAll();
+ this.setCancel(true);
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/action/RotateAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/action/RotateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f7263a97f56144e98794eae3e137a3a73a6d909
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/RotateAction.java
@@ -0,0 +1,29 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+
+public class RotateAction extends BotAction {
+ public RotateAction() {
+ super("rotate");
+ }
+
+ private ServerPlayer player;
+
+ public BotAction setPlayer(ServerPlayer player) {
+ this.player = player;
+ return this;
+ }
+
+ @Override
+ public BotAction getNew(int tickDelay, ServerPlayer player) {
+ return new RotateAction().setPlayer(player).setTickDelay(tickDelay);
+ }
+
+ @Override
+ public void tick(Bot bot) {
+ bot.faceLocation(player.getBukkitEntity().getLocation());
+ this.setCancel(true);
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/action/StopAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/action/StopAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..09049b934d34aece15a201473f1cf4ed500a05a7
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/StopAction.java
@@ -0,0 +1,21 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+
+public class StopAction extends BotAction {
+ public StopAction() {
+ super("stop");
+ }
+
+ @Override
+ public BotAction getNew(int tickDelay, ServerPlayer player) {
+ return new StopAction();
+ }
+
+ @Override
+ public void tick(Bot bot) {
+ this.setCancel(true);
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/action/UseItemAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/action/UseItemAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f39161ff8f84392ef57a1ecda3b098a791841e5
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/UseItemAction.java
@@ -0,0 +1,24 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+
+public class UseItemAction extends BotAction {
+ public UseItemAction() {
+ super("use");
+ }
+
+ @Override
+ public BotAction getNew(int tickDelay, ServerPlayer player) {
+ return new UseItemAction().setTickDelay(tickDelay);
+ }
+
+ @Override
+ public void tick(Bot bot) {
+ bot.getInventory().getSelected().use(bot.getLevel(), bot, InteractionHand.MAIN_HAND);
+ bot.punch();
+ bot.updateItemInMainHand();
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/action/UseItemOnAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/action/UseItemOnAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..a58c57e572b5cd952b0b276a8157250170ce6285
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/UseItemOnAction.java
@@ -0,0 +1,29 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.world.phys.HitResult;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+
+public class UseItemOnAction extends BotAction {
+ public UseItemOnAction() {
+ super("use_on");
+ }
+
+ @Override
+ public BotAction getNew(int tickDelay, ServerPlayer player) {
+ return new UseItemOnAction().setTickDelay(tickDelay);
+ }
+
+ @Override
+ public void tick(Bot bot) {
+ HitResult result = bot.getRayTrace(4);
+ if (result != null && result.getType() == HitResult.Type.BLOCK) {
+ bot.gameMode.useItemOn(bot, bot.getLevel(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, (BlockHitResult) result);
+ bot.punch();
+ bot.updateItemInMainHand();
+ }
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/util/MathUtils.java b/src/main/java/top/leavesmc/leaves/util/MathUtils.java
index acdef051d6d4eb4e0d957bfbd7f205827c2f23a9..d6a809569455872d08aeab81b174024d2bc3b53a 100644
--- a/src/main/java/top/leavesmc/leaves/util/MathUtils.java
+++ b/src/main/java/top/leavesmc/leaves/util/MathUtils.java
@@ -3,6 +3,8 @@ package top.leavesmc.leaves.util;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
+import java.util.regex.Pattern;
+
public class MathUtils {
// Lag ?
public static void clean(Vector vector) {
@@ -10,4 +12,67 @@ public class MathUtils {
if (!NumberConversions.isFinite(vector.getY())) vector.setY(0);
if (!NumberConversions.isFinite(vector.getZ())) vector.setZ(0);
}
+
+ private static final Pattern numericPattern = Pattern.compile("[0-9]*");
+ public static boolean isNumeric(String str){
+ return numericPattern.matcher(str).matches();
+ }
+
+ public static float[] fetchYawPitch(Vector dir) {
+ double x = dir.getX();
+ double z = dir.getZ();
+
+ float[] out = new float[2];
+
+ if (x == 0.0D && z == 0.0D) {
+ out[1] = (float) (dir.getY() > 0.0D ? -90 : 90);
+ }
+
+ else {
+ double theta = Math.atan2(-x, z);
+ out[0] = (float) Math.toDegrees((theta + 6.283185307179586D) % 6.283185307179586D);
+
+ double x2 = NumberConversions.square(x);
+ double z2 = NumberConversions.square(z);
+ double xz = Math.sqrt(x2 + z2);
+ out[1] = (float) Math.toDegrees(Math.atan(-dir.getY() / xz));
+ }
+
+ return out;
+ }
+
+ public static float fetchPitch(Vector dir) {
+ double x = dir.getX();
+ double z = dir.getZ();
+
+ float result;
+
+ if (x == 0.0D && z == 0.0D) {
+ result = (float) (dir.getY() > 0.0D ? -90 : 90);
+ }
+
+ else {
+ double x2 = NumberConversions.square(x);
+ double z2 = NumberConversions.square(z);
+ double xz = Math.sqrt(x2 + z2);
+ result = (float) Math.toDegrees(Math.atan(-dir.getY() / xz));
+ }
+
+ return result;
+ }
+
+ public static Vector getDirection(double rotX, double rotY) {
+ Vector vector = new Vector();
+
+ rotX = Math.toRadians(rotX);
+ rotY = Math.toRadians(rotY);
+
+ double xz = Math.abs(Math.cos(rotY));
+
+ vector.setX(-Math.sin(rotX) * xz);
+ vector.setZ(Math.cos(rotX) * xz);
+ vector.setY(-Math.sin(rotY));
+
+ return vector;
+ }
}