From 5893d0eb72fb6fd007aa554493a978278f1c0013 Mon Sep 17 00:00:00 2001 From: Christopher Date: Fri, 10 May 2024 07:28:51 +0200 Subject: [PATCH] add first workling version, still without pathfinding --- .../dev/clatza/mcautofight/GlobalData.java | 11 +++ .../clatza/mcautofight/KeyBindingHelper.java | 39 ++++++++ .../clatza/mcautofight/MCAutoFightClient.java | 5 +- .../clatza/mcautofight/MovementHelper.java | 88 ++++++++++++++++++ .../clatza/mcautofight/TeleportMonitor.java | 44 +++++++++ .../mcautofight/Utils/TimedRemovalList.java | 34 +++++++ .../dev/clatza/mcautofight/ViewHelper.java | 93 +++++++++++++++++++ 7 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 src/client/java/dev/clatza/mcautofight/GlobalData.java create mode 100644 src/client/java/dev/clatza/mcautofight/KeyBindingHelper.java create mode 100644 src/client/java/dev/clatza/mcautofight/MovementHelper.java create mode 100644 src/client/java/dev/clatza/mcautofight/TeleportMonitor.java create mode 100644 src/client/java/dev/clatza/mcautofight/Utils/TimedRemovalList.java create mode 100644 src/client/java/dev/clatza/mcautofight/ViewHelper.java diff --git a/src/client/java/dev/clatza/mcautofight/GlobalData.java b/src/client/java/dev/clatza/mcautofight/GlobalData.java new file mode 100644 index 0000000..8c7f9a9 --- /dev/null +++ b/src/client/java/dev/clatza/mcautofight/GlobalData.java @@ -0,0 +1,11 @@ +package dev.clatza.mcautofight; + +import dev.clatza.mcautofight.Utils.TimedRemovalList; +import net.minecraft.entity.Entity; + +public class GlobalData { + public static boolean isAttacking = false; + public static Entity currentTargetEntety = null; + public static long lastEnemyFoundAt = 0; + public static TimedRemovalList entityIgnoreList = new TimedRemovalList(); +} diff --git a/src/client/java/dev/clatza/mcautofight/KeyBindingHelper.java b/src/client/java/dev/clatza/mcautofight/KeyBindingHelper.java new file mode 100644 index 0000000..c234489 --- /dev/null +++ b/src/client/java/dev/clatza/mcautofight/KeyBindingHelper.java @@ -0,0 +1,39 @@ +package dev.clatza.mcautofight; + +import dev.clatza.mcautofight.Utils.TimedRemovalList; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.text.Text; +import org.lwjgl.glfw.GLFW; + +public class KeyBindingHelper { + // Die Variable toggleVariableKeybind ist jetzt als static öffentlich verfügbar + public static KeyBinding toggleVariableKeybind; + + public static void registerGameEvents() { + toggleVariableKeybind = net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper.registerKeyBinding(new KeyBinding( + "Toogle Autoklicker", // Übersetzungsschlüssel für die Beschreibung + InputUtil.Type.KEYSYM, // Typ der Eingabe (KEYSYM für Tastatur) + GLFW.GLFW_KEY_F6, // Standardtaste ist F6 + "Autoklicker" // Übersetzungsschlüssel für die Kategorie + )); + + ClientTickEvents.END_CLIENT_TICK.register(client -> { + while (KeyBindingHelper.toggleVariableKeybind.wasPressed()) { + GlobalData.isAttacking = !GlobalData.isAttacking; + + GlobalData.entityIgnoreList = new TimedRemovalList(); + GlobalData.currentTargetEntety = null; + + KeyBinding forwardKey = client.options.forwardKey; + setKeyBindingPressed(forwardKey, GlobalData.isAttacking); + client.inGameHud.getChatHud().addMessage(Text.literal("Auto Klicker is now " + (GlobalData.isAttacking ? "enabled" : "disabled"))); + } + }); + } + + public static void setKeyBindingPressed(KeyBinding keyBinding, boolean pressed) { + keyBinding.setPressed(pressed); + } +} \ No newline at end of file diff --git a/src/client/java/dev/clatza/mcautofight/MCAutoFightClient.java b/src/client/java/dev/clatza/mcautofight/MCAutoFightClient.java index 2426177..7bd9556 100644 --- a/src/client/java/dev/clatza/mcautofight/MCAutoFightClient.java +++ b/src/client/java/dev/clatza/mcautofight/MCAutoFightClient.java @@ -5,6 +5,9 @@ public class MCAutoFightClient implements ClientModInitializer { @Override public void onInitializeClient() { - // This entrypoint is suitable for setting up client-specific logic, such as rendering. + ViewHelper.registerGameEvents(); + MovementHelper.registerGameEvents(); + KeyBindingHelper.registerGameEvents(); + TeleportMonitor.registerGameEvents(); } } \ No newline at end of file diff --git a/src/client/java/dev/clatza/mcautofight/MovementHelper.java b/src/client/java/dev/clatza/mcautofight/MovementHelper.java new file mode 100644 index 0000000..0caab0b --- /dev/null +++ b/src/client/java/dev/clatza/mcautofight/MovementHelper.java @@ -0,0 +1,88 @@ +package dev.clatza.mcautofight; + +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.entity.Entity; +import net.minecraft.entity.mob.Monster; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Vec3d; + +public class MovementHelper { + private static final double MAX_REACH = 3.0; + + public static void registerGameEvents(){ + WorldRenderEvents.AFTER_ENTITIES.register(context -> { + if (!GlobalData.isAttacking) { + return; + } + + PlayerEntity player = MinecraftClient.getInstance().player; + float cooldownProgress = player.getAttackCooldownProgress(0.0f); + boolean isAttrackReady = cooldownProgress >= 1.0f; + + if (!isAttrackReady) { + return; + } + + MinecraftClient client = MinecraftClient.getInstance(); + HitResult hit = client.crosshairTarget; + + if (hit != null && hit.getType() == HitResult.Type.ENTITY) { + GlobalData.currentTargetEntety = ((EntityHitResult) hit).getEntity(); + if (!GlobalData.currentTargetEntety.isLiving()) return; + if (GlobalData.currentTargetEntety instanceof AnimalEntity || GlobalData.currentTargetEntety instanceof Monster) attackEntity(GlobalData.currentTargetEntety); + GlobalData.currentTargetEntety = null; + } + }); + + ClientTickEvents.END_CLIENT_TICK.register(client -> { + PlayerEntity player = MinecraftClient.getInstance().player; + + if (!GlobalData.isAttacking) return; + if (GlobalData.currentTargetEntety == null) return; + if (player == null) return; + + //if(GlobalData.currentTargetEntety == null){ + //KeyBinding forwardKey = client.options.forwardKey; + //KeyBindingHelper.setKeyBindingPressed(forwardKey, false); + //System.out.println("Stop moving forward; No target"); + //return; + //} + + double distance = player.distanceTo(GlobalData.currentTargetEntety); + + if (distance > 1.0) { + KeyBinding forwardKey = MinecraftClient.getInstance().options.forwardKey; + KeyBindingHelper.setKeyBindingPressed(forwardKey, true); + //System.out.println("Start moving forward; distance: " + distance); + return; + }else{ + KeyBinding forwardKey = MinecraftClient.getInstance().options.forwardKey; + KeyBindingHelper.setKeyBindingPressed(forwardKey, false); + //System.out.println("Stop moving forward: distance: " + distance); + return; + } + }); + } + + public static void attackEntity(Entity entity) { + if(entity.isRemoved()) return; + + PlayerEntity player = MinecraftClient.getInstance().player; + MinecraftClient client = MinecraftClient.getInstance(); + + Vec3d eyePosition = player.getCameraPosVec(1.0F); + double distance = eyePosition.distanceTo(entity.getPos()); + + if (distance < MAX_REACH) { + client.interactionManager.attackEntity(player, entity); + player.swingHand(Hand.MAIN_HAND); + } + } +} diff --git a/src/client/java/dev/clatza/mcautofight/TeleportMonitor.java b/src/client/java/dev/clatza/mcautofight/TeleportMonitor.java new file mode 100644 index 0000000..7e2ace4 --- /dev/null +++ b/src/client/java/dev/clatza/mcautofight/TeleportMonitor.java @@ -0,0 +1,44 @@ +package dev.clatza.mcautofight; + +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.text.Text; +import net.minecraft.util.math.Vec3d; + +public class TeleportMonitor { + private static Vec3d lastPosition = Vec3d.ZERO; + + public static void registerGameEvents(){ + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if(!GlobalData.isAttacking) return; + if (MinecraftClient.getInstance().player == null) return; + + if(lastPosition == Vec3d.ZERO) + lastPosition = MinecraftClient.getInstance().player.getPos(); + + if(MinecraftClient.getInstance().player.getPos().distanceTo(lastPosition) > 20){ + System.out.println("Teleport detected"); + GlobalData.isAttacking = false; + + KeyBinding forwardKey = MinecraftClient.getInstance().options.forwardKey; + KeyBindingHelper.setKeyBindingPressed(forwardKey, false); + client.inGameHud.getChatHud().addMessage(Text.literal("Auto Klicker is now " + (GlobalData.isAttacking ? "enabled" : "disabled"))); + } + + lastPosition = MinecraftClient.getInstance().player.getPos(); + + }); + + ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { + MinecraftClient.getInstance().execute(() -> { + GlobalData.isAttacking = false; + + KeyBinding forwardKey = MinecraftClient.getInstance().options.forwardKey; + KeyBindingHelper.setKeyBindingPressed(forwardKey, false); + System.out.println("Start moving forward; distance: verbindung getrennt"); + }); + }); + } +} diff --git a/src/client/java/dev/clatza/mcautofight/Utils/TimedRemovalList.java b/src/client/java/dev/clatza/mcautofight/Utils/TimedRemovalList.java new file mode 100644 index 0000000..a2ee956 --- /dev/null +++ b/src/client/java/dev/clatza/mcautofight/Utils/TimedRemovalList.java @@ -0,0 +1,34 @@ +package dev.clatza.mcautofight.Utils; + +import java.util.concurrent.*; + +public class TimedRemovalList { + private ConcurrentHashMap> map = new ConcurrentHashMap<>(); + private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); + + public void add(Integer value) { + remove(value); + + ScheduledFuture scheduledFuture = executorService.schedule(() -> { + map.remove(value); + System.out.println("Eintrag entfernt: " + value); + }, 2, TimeUnit.MINUTES); + + map.put(value, scheduledFuture); + } + + public void remove(Integer value) { + ScheduledFuture future = map.remove(value); + if (future != null) { + future.cancel(false); + } + } + + public boolean contains(Integer value) { + return map.containsKey(value); + } + + public void shutdown() { + executorService.shutdownNow(); + } +} \ No newline at end of file diff --git a/src/client/java/dev/clatza/mcautofight/ViewHelper.java b/src/client/java/dev/clatza/mcautofight/ViewHelper.java new file mode 100644 index 0000000..6141072 --- /dev/null +++ b/src/client/java/dev/clatza/mcautofight/ViewHelper.java @@ -0,0 +1,93 @@ +package dev.clatza.mcautofight; + +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +import java.util.Comparator; +import java.util.List; +import java.util.Random; + +public class ViewHelper { + private static final float SMOOTH_FACTOR = 0.05F; + + public static void registerGameEvents(){ + WorldRenderEvents.AFTER_ENTITIES.register(context -> { + if (!GlobalData.isAttacking) return; + + if (GlobalData.currentTargetEntety == null){ + GlobalData.currentTargetEntety = findAnimal(MinecraftClient.getInstance().player, false); + + if(GlobalData.currentTargetEntety != null) System.out.println("New target Enemy: " + GlobalData.currentTargetEntety.getEntityName()); + } + + if (GlobalData.currentTargetEntety == null) return; + if (!GlobalData.currentTargetEntety.isLiving()) {GlobalData.currentTargetEntety = null; return; } + if (GlobalData.currentTargetEntety.isRemoved()) {GlobalData.currentTargetEntety = null; return; } + + changeLookDirection(MinecraftClient.getInstance().player, GlobalData.currentTargetEntety.getPos()); + + if(GlobalData.lastEnemyFoundAt + 10000 < System.currentTimeMillis()){ + GlobalData.entityIgnoreList.add(GlobalData.currentTargetEntety.getId()); + GlobalData.currentTargetEntety = findAnimal(MinecraftClient.getInstance().player, true); + } + }); + } + + private static boolean changeLookDirection(PlayerEntity player, Vec3d targetPos) { + if (player == null) return false; + + player.getWorld().addParticle(ParticleTypes.SMOKE, targetPos.x, targetPos.y, targetPos.z, 0, 0, 0); + + Vec3d eyePos = player.getCameraPosVec(1.0F); + Vec3d toTarget = targetPos.subtract(eyePos).normalize(); + + float targetYaw = (float) Math.toDegrees(MathHelper.atan2(toTarget.z, toTarget.x)) - 90.0F; + float targetPitch = (float) Math.toDegrees(-MathHelper.atan2(toTarget.y, Math.sqrt(toTarget.x * toTarget.x + toTarget.z * toTarget.z))); + + float newYaw = player.getYaw() + getShortestAngle(player.getYaw(), targetYaw) * SMOOTH_FACTOR; + float newPitch = MathHelper.lerp(SMOOTH_FACTOR, player.getPitch(), targetPitch); + + player.setYaw(newYaw % 360.0F); + player.setPitch(newPitch); + return true; + } + + private static Entity findAnimal(PlayerEntity player, boolean random) { + if(player == null) return null; + + Box searchBox = new Box(player.getBlockPos()).expand(60); + List animals = player.getWorld().getEntitiesByClass(AnimalEntity.class, searchBox, + animal -> Math.abs(animal.getY() - player.getY()) <= 3 && !GlobalData.entityIgnoreList.contains(animal.getId())); + + if (animals.isEmpty()) return null; + + GlobalData.lastEnemyFoundAt = System.currentTimeMillis(); + + if (random) { + Random rand = new Random(); + return animals.get(rand.nextInt(animals.size())); + } else { + return animals.stream() + .min(Comparator.comparingDouble(a -> a.squaredDistanceTo(player))) + .orElse(null); + } + } + + //Helper Methoden + public static float getShortestAngle(float current, float target) { + float difference = target - current; + if (difference < -180.0F) { + difference += 360.0F; + } else if (difference > 180.0F) { + difference -= 360.0F; + } + return difference; + } +}