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-03-15 07:10:03 +00:00

786 lines
26 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 2483d7df7f1bf94344afd38b37602c645a4a2dff..4ef275139b0f1340238fbc48e9f522dd87067435 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1247,7 +1247,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 1931114944847708ba9e82ce3b82675f1d477446..578ef971b3684e64e116b486672b6bc2c9edbe0b 100644
--- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java
+++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
@@ -67,6 +67,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 ebea5607956b1328f928d905e4f35424e5c21546..77713ce098be75aab5ebbeabc324298ded4392f5 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,9 +26,13 @@ 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;
@@ -38,14 +46,20 @@ import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.inventory.ItemStack;
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;
@@ -54,12 +68,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<>();
@@ -68,9 +87,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;
}
@@ -156,12 +178,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
@@ -169,10 +196,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();
@@ -259,12 +282,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++;
@@ -292,7 +327,83 @@ 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;
+ }
+ }
+
+ @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
@@ -325,21 +436,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();
}
@@ -431,6 +527,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 17c1db261165bfa22a7e91189f926e0adf8e43f9..e65e4980665211ce170c78afb8dd431f80e73779 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;
}
@@ -80,7 +100,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;
}
@@ -93,4 +113,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..c2a5e344745a0966d57cebce893d80c26dce0f83
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/Actions.java
@@ -0,0 +1,43 @@
+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.UseItemAction;
+
+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());
+ }
+
+ 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..78cf21fc321d3d3d13b2db315897acdf386c696f
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/action/AttackAction.java
@@ -0,0 +1,34 @@
+package top.leavesmc.leaves.bot.agent.action;
+
+import net.minecraft.server.level.ServerPlayer;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.util.RayTraceResult;
+import org.bukkit.util.Vector;
+import top.leavesmc.leaves.bot.Bot;
+import top.leavesmc.leaves.bot.agent.BotAction;
+import top.leavesmc.leaves.util.MathUtils;
+
+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) {
+ Vector vector = MathUtils.getDirection(bot.getYRot(), bot.getXRot()).normalize();
+ Location loc = bot.getBukkitPlayer().getEyeLocation().add(vector);
+
+ RayTraceResult result = loc.getWorld().rayTraceEntities(loc, vector, 5);
+
+ if (result != null && result.getHitEntity() != null) {
+ bot.attack(((CraftEntity) result.getHitEntity()).getHandle());
+ }
+ }
+}
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/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/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;
+ }
}