mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-19 14:59:32 +00:00
786 lines
26 KiB
Diff
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;
|
|
+ }
|
|
}
|