diff --git a/.gitignore b/.gitignore index 09cd281f..d0b7fb9b 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ bin/ # fabric run/ +temp/ +gradlew \ No newline at end of file diff --git a/gradlew b/gradlew deleted file mode 100644 index f3b75f3b..00000000 --- a/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/src/main/java/com/nnpg/glazed/GlazedAddon.java b/src/main/java/com/nnpg/glazed/GlazedAddon.java index de3d0a99..964112d6 100644 --- a/src/main/java/com/nnpg/glazed/GlazedAddon.java +++ b/src/main/java/com/nnpg/glazed/GlazedAddon.java @@ -101,6 +101,9 @@ public void onInitialize() { Modules.get().add(new PremiumTunnelBaseFinder()); Modules.get().add(new AdminList()); Modules.get().add(new AutoTreeFarmer()); + Modules.get().add(new STabSprintReset()); + Modules.get().add(new TriggerBot()); + } @EventHandler diff --git a/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java b/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java new file mode 100644 index 00000000..17bd76b9 --- /dev/null +++ b/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java @@ -0,0 +1,217 @@ +package com.nnpg.glazed.modules.pvp; + +import com.nnpg.glazed.utils.glazed.MovementKeys; +import meteordevelopment.meteorclient.events.entity.player.AttackEntityEvent; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.settings.BoolSetting; +import meteordevelopment.meteorclient.settings.DoubleSetting; +import meteordevelopment.meteorclient.settings.IntSetting; +import meteordevelopment.meteorclient.settings.Setting; +import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.orbit.EventHandler; +import meteordevelopment.orbit.EventPriority; +import net.minecraft.entity.LivingEntity; + +import static com.nnpg.glazed.GlazedAddon.pvp; + +public class STabSprintReset extends Module { + + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgTiming = settings.createGroup("Timing"); + + private final Setting skipChance = sgGeneral.add(new DoubleSetting.Builder() + .name("skip-chance") + .description("Chance to skip the reset entirely (mimics human inconsistency)") + .defaultValue(20.0) + .min(0.0) + .max(100.0) + .sliderMax(100.0) + .build() + ); + + private final Setting advancedSettings = sgGeneral.add(new BoolSetting.Builder() + .name("advanced-settings") + .description("Show advanced timing settings") + .defaultValue(false) + .build() + ); + private final Setting preDelayMin = sgTiming.add(new IntSetting.Builder() + .name("pre-delay-min") + .description("Minimum ticks before pressing S (1 = earliest human-possible)") + .defaultValue(1) + .min(1) + .max(5) + .sliderMax(5) + .visible(() -> advancedSettings.get()) + .build() + ); + + private final Setting preDelayMax = sgTiming.add(new IntSetting.Builder() + .name("pre-delay-max") + .description("Maximum ticks before pressing S") + .defaultValue(3) + .min(1) + .max(8) + .sliderMax(8) + .visible(() -> advancedSettings.get()) + .build() + ); + + private final Setting sHoldMin = sgTiming.add(new IntSetting.Builder() + .name("s-hold-min") + .description("Minimum ticks to hold S") + .defaultValue(1) + .min(1) + .max(5) + .sliderMax(5) + .visible(() -> advancedSettings.get()) + .build() + ); + + private final Setting sHoldMax = sgTiming.add(new IntSetting.Builder() + .name("s-hold-max") + .description("Maximum ticks to hold S") + .defaultValue(3) + .min(1) + .max(8) + .sliderMax(8) + .visible(() -> advancedSettings.get()) + .build() + ); + + private boolean sKeyPressed = false; + private int preDelayTicks = 0; + private int sHoldTicks = 0; + private int currentPreDelay = 0; + private int currentSHold = 0; + private boolean waitingForPreDelay = false; + private boolean waitingForSRelease = false; + private long releaseAtMs = -1L; + private long lastResetTimeMs = 0L; + private static final int MIN_RESET_INTERVAL_MS = 150; + private boolean wasSprinting = false; + + public STabSprintReset() { + super(pvp, "s-tab-sprint-reset", "Prevents sprint restart after attack with S-tap"); + } + + @Override + public void onDeactivate() { + if (sKeyPressed) { + MovementKeys.back(false); + sKeyPressed = false; + } + resetState(); + } + + @EventHandler(priority = EventPriority.HIGH) + private void onTick(TickEvent.Pre event) { + if (mc.player == null || mc.player.isDead() || mc.world == null) { + if (sKeyPressed) { + MovementKeys.back(false); + sKeyPressed = false; + } + resetState(); + return; + } + wasSprinting = mc.player.isSprinting(); + if (waitingForSRelease && !mc.player.isOnGround()) { + releaseS(); + return; + } + if (waitingForPreDelay) { + preDelayTicks++; + if (preDelayTicks >= currentPreDelay) { + pressS(); + } + return; + } + if (waitingForSRelease) { + sHoldTicks++; + if (sHoldTicks >= currentSHold && releaseAtMs < 0) { + int jitterMs = (int)(Math.random() * 20); + releaseAtMs = System.currentTimeMillis() + jitterMs; + } + if (releaseAtMs >= 0 && System.currentTimeMillis() >= releaseAtMs) { + releaseAtMs = -1L; + releaseS(); + } + return; + } + if (sKeyPressed) { + releaseS(); + } + } + + @EventHandler(priority = EventPriority.HIGH) + private void onAttack(AttackEntityEvent event) { + if (!(event.entity instanceof LivingEntity)) return; + if (!mc.player.isOnGround()) return; + if (!wasSprinting) return; + long now = System.currentTimeMillis(); + if (now - lastResetTimeMs < MIN_RESET_INTERVAL_MS) return; + if (sKeyPressed) releaseS(); + if (Math.random() * 100 < skipChance.get()) return; + currentPreDelay = rollPreDelay(); + currentSHold = rollSHold(); + preDelayTicks = 0; + sHoldTicks = 0; + releaseAtMs = -1L; + waitingForPreDelay = true; + waitingForSRelease = false; + lastResetTimeMs = now; + } + + private int rollPreDelay() { + int min = preDelayMin.get(); + int max = preDelayMax.get(); + + double r = Math.random(); + int rolled; + if (r < 0.40) rolled = 1; + else if (r < 0.80) rolled = 2; + else rolled = 3; + + return Math.max(min, Math.min(max, rolled)); + } + + private int rollSHold() { + int min = sHoldMin.get(); + int max = sHoldMax.get(); + + double r = Math.random(); + int rolled; + if (r < 0.30) rolled = 1; + else if (r < 0.80) rolled = 2; + else rolled = 3; + + return Math.max(min, Math.min(max, rolled)); + } + + private void pressS() { + MovementKeys.back(true); + sKeyPressed = true; + + waitingForPreDelay = false; + waitingForSRelease = true; + sHoldTicks = 0; + releaseAtMs = -1L; + } + + private void releaseS() { + MovementKeys.back(false); + sKeyPressed = false; + resetState(); + } + + private void resetState() { + waitingForPreDelay = false; + waitingForSRelease = false; + preDelayTicks = 0; + sHoldTicks = 0; + currentPreDelay = 0; + currentSHold = 0; + releaseAtMs = -1L; + } +} \ No newline at end of file diff --git a/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java new file mode 100644 index 00000000..8656ce67 --- /dev/null +++ b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java @@ -0,0 +1,277 @@ +package com.nnpg.glazed.modules.pvp; + +import meteordevelopment.meteorclient.events.render.Render3DEvent; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +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.Box; +import net.minecraft.util.math.Vec3d; +import com.nnpg.glazed.GlazedAddon; + +import java.util.Optional; + +public class TriggerBot extends Module { + + private final SettingGroup sgFilter = settings.createGroup("Filter"); + private final SettingGroup sgAttack = settings.createGroup("Attack"); + + private final Setting target = sgFilter.add(new EnumSetting.Builder() + .name("target") + .description("Which entities to attack.") + .defaultValue(Target.Players) + .build() + ); + + private final Setting range = sgFilter.add(new DoubleSetting.Builder() + .name("range") + .description("Maximum attack range. Warning: high range is easily detectable!") + .defaultValue(3.0) + .min(0.1) + .sliderMax(4.5) + .build() + ); + // test + private final Setting ignoreFriends = sgFilter.add(new BoolSetting.Builder() + .name("ignore-friends") + .description("Won't attack players on your friends list.") + .defaultValue(true) + .build() + ); + + private final Setting ignoreWalls = sgFilter.add(new BoolSetting.Builder() + .name("ignore-walls") + .description("Attack entities through walls.") + .defaultValue(false) + .build() + ); + + private final Setting hitWindowMs = sgAttack.add(new IntSetting.Builder() + .name("hit-window-ms") + .description("How long (ms) after the crosshair last touched a target the attack " + + "is still allowed. Catches fast flick-overs between ticks. " + + "50ms = 1 tick. 0 = disabled.") + .defaultValue(50) + .min(0) + .sliderRange(0, 150) + .build() + ); + + private final Setting onFallMode = sgAttack.add(new EnumSetting.Builder() + .name("on-fall-mode") + .description("Only attack while falling (for critical hits). " + + "None = always attack, Value = fixed velocity threshold, " + + "RandomValue = randomised threshold.") + .defaultValue(OnFallMode.None) + .build() + ); + + private final Setting onFallValue = sgAttack.add(new DoubleSetting.Builder() + .name("on-fall-velocity") + .description("Minimum downward velocity required to attack. " + + "0.1 = just past the jump peak (recommended), " + + "0.3 = deeper into the fall.") + .min(0.0) + .defaultValue(0.1) + .sliderRange(0.0, 1.0) + .visible(() -> onFallMode.get() == OnFallMode.Value) + .build() + ); + + private final Setting onFallMinRandomValue = sgAttack.add(new DoubleSetting.Builder() + .name("on-fall-min-random-velocity") + .description("Minimum of the randomised downward velocity threshold.") + .min(0.0) + .defaultValue(0.1) + .sliderRange(0.0, 1.0) + .visible(() -> onFallMode.get() == OnFallMode.RandomValue) + .build() + ); + + private final Setting onFallMaxRandomValue = sgAttack.add(new DoubleSetting.Builder() + .name("on-fall-max-random-velocity") + .description("Maximum of the randomised downward velocity threshold.") + .min(0.0) + .defaultValue(0.3) + .sliderRange(0.0, 1.0) + .visible(() -> onFallMode.get() == OnFallMode.RandomValue) + .build() + ); + + private final Setting hitSpeedMode = sgAttack.add(new EnumSetting.Builder() + .name("hit-speed-mode") + .description("Minimum attack cooldown required before attacking.") + .defaultValue(HitSpeedMode.RandomValue) + .build() + ); + + private final Setting hitSpeedValue = sgAttack.add(new DoubleSetting.Builder() + .name("hit-speed-value") + .description("Cooldown offset passed to getAttackCooldownProgress. 0 = full cooldown required.") + .defaultValue(0.0) + .sliderRange(-10, 10) + .visible(() -> hitSpeedMode.get() == HitSpeedMode.Value) + .build() + ); + + private final Setting hitSpeedMinRandomValue = sgAttack.add(new DoubleSetting.Builder() + .name("hit-speed-min-random-value") + .description("Minimum randomised cooldown offset value.") + .defaultValue(-0.1) + .sliderRange(-10, 10) + .visible(() -> hitSpeedMode.get() == HitSpeedMode.RandomValue) + .build() + ); + + private final Setting hitSpeedMaxRandomValue = sgAttack.add(new DoubleSetting.Builder() + .name("hit-speed-max-random-value") + .description("Maximum randomised cooldown offset value.") + .defaultValue(0.05) + .sliderRange(-10, 10) + .visible(() -> hitSpeedMode.get() == HitSpeedMode.RandomValue) + .build() + ); + + private float randomOnFallFloat = 0; + private float randomHitSpeedFloat = 0; + private Entity bufferedTarget = null; + private long lastSeenNano = 0L; + + public TriggerBot() { + super(GlazedAddon.pvp, "triggerbot", + "Attacks the entity you are looking at, optionally only when critting."); + } + + @Override + public void onActivate() { + randomOnFallFloat = 0; + randomHitSpeedFloat = 0; + bufferedTarget = null; + lastSeenNano = 0L; + } + @EventHandler + private void onRender(Render3DEvent event) { + if (mc.player == null || mc.world == null) return; + Entity found = getTarget(); + if (found != null) { + bufferedTarget = found; + lastSeenNano = System.nanoTime(); + } + } + + @EventHandler + private void onTick(TickEvent.Pre event) { + if (mc.player == null || mc.player.isDead() + || mc.player.getHealth() <= 0 || mc.world == null) return; + Entity entity = getTarget(); + + if (entity == null) { + long elapsedMs = (System.nanoTime() - lastSeenNano) / 1_000_000L; + if (bufferedTarget == null || elapsedMs > hitWindowMs.get()) return; + entity = bufferedTarget; + if (!entity.isAlive()) { bufferedTarget = null; return; } + if (mc.player.squaredDistanceTo(entity) > range.get() * range.get()) { bufferedTarget = null; return; } + if (!entityCheck(entity)) { bufferedTarget = null; return; } + } + bufferedTarget = null; + OnFallMode currOnFallMode = onFallMode.get(); + if (currOnFallMode != OnFallMode.None) { + float threshold = (currOnFallMode == OnFallMode.Value) + ? onFallValue.get().floatValue() + : randomOnFallFloat; + + double vy = mc.player.getVelocity().y; + float jitter = (mc.world.random.nextFloat() * 0.032f) - 0.016f; + + if (vy >= -(threshold + jitter)) return; + if (mc.player.isOnGround()) return; + if (mc.player.isTouchingWater()) return; + if (mc.player.isClimbing()) return; + if (mc.player.hasVehicle()) return; + } + HitSpeedMode currHitSpeedMode = hitSpeedMode.get(); + if (currHitSpeedMode != HitSpeedMode.None) { + float hitSpeed = (currHitSpeedMode == HitSpeedMode.Value) + ? hitSpeedValue.get().floatValue() + : randomHitSpeedFloat; + if ((mc.player.getAttackCooldownProgress(hitSpeed) * 17.0F) < 16) return; + } + mc.interactionManager.attackEntity(mc.player, entity); + mc.player.swingHand(Hand.MAIN_HAND); + if (currOnFallMode == OnFallMode.RandomValue) { + float min = Math.min(onFallMinRandomValue.get().floatValue(), onFallMaxRandomValue.get().floatValue()); + float max = Math.max(onFallMinRandomValue.get().floatValue(), onFallMaxRandomValue.get().floatValue()); + randomOnFallFloat = min + mc.world.random.nextFloat() * (max - min); + } + + if (currHitSpeedMode == HitSpeedMode.RandomValue) { + float min = Math.min(hitSpeedMinRandomValue.get().floatValue(), hitSpeedMaxRandomValue.get().floatValue()); + float max = Math.max(hitSpeedMinRandomValue.get().floatValue(), hitSpeedMaxRandomValue.get().floatValue()); + randomHitSpeedFloat = min + mc.world.random.nextFloat() * (max - min); + } + } + + private Entity getTarget() { + if (ignoreWalls.get()) return getTargetThroughWalls(); + + if (mc.crosshairTarget == null + || mc.crosshairTarget.getType() != HitResult.Type.ENTITY) return null; + + Entity entity = ((EntityHitResult) mc.crosshairTarget).getEntity(); + if (mc.player.squaredDistanceTo(entity) > range.get() * range.get()) return null; + if (!entityCheck(entity)) return null; + return entity; + } + + private Entity getTargetThroughWalls() { + Vec3d eye = mc.player.getEyePos(); + Vec3d look = mc.player.getRotationVec(1.0F); + Vec3d end = eye.add(look.multiply(range.get())); + + Box searchBox = mc.player.getBoundingBox() + .stretch(look.multiply(range.get())) + .expand(1.0); + + Entity best = null; + double bestD = Double.MAX_VALUE; + + for (Entity candidate : mc.world.getEntitiesByClass( + LivingEntity.class, searchBox, this::entityCheck)) { + Optional hit = candidate.getBoundingBox().raycast(eye, end); + if (hit.isPresent()) { + double d = eye.squaredDistanceTo(hit.get()); + if (d < bestD) { bestD = d; best = candidate; } + } + } + return best; + } + + private boolean entityCheck(Entity entity) { + if (entity == mc.player || entity == mc.getCameraEntity()) return false; + if (!entity.isAlive()) return false; + if (entity instanceof LivingEntity le && (le.isDead() || le.getHealth() <= 0)) return false; + + switch (target.get()) { + case Players -> { if (!(entity instanceof PlayerEntity)) return false; } + case Entities -> { if ( entity instanceof PlayerEntity) return false; } + case All -> {} + } + + if (entity instanceof PlayerEntity player) { + if (ignoreFriends.get() && !Friends.get().shouldAttack(player)) return false; + } + + return true; + } + + public enum Target { Players, Entities, All } + public enum OnFallMode { None, Value, RandomValue } + public enum HitSpeedMode { None, Value, RandomValue } +} \ No newline at end of file diff --git a/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java b/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java new file mode 100644 index 00000000..51e76ee7 --- /dev/null +++ b/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java @@ -0,0 +1,80 @@ +package com.nnpg.glazed.utils.glazed; + +import meteordevelopment.meteorclient.utils.misc.input.Input; +import net.minecraft.client.option.KeyBinding; + +import static meteordevelopment.meteorclient.MeteorClient.mc; + +public class MovementKeys { + + public static void forward(boolean pressed) { + setKey(mc.options.forwardKey, pressed); + } + + public static void back(boolean pressed) { + setKey(mc.options.backKey, pressed); + } + + public static void left(boolean pressed) { + setKey(mc.options.leftKey, pressed); + } + + public static void right(boolean pressed) { + setKey(mc.options.rightKey, pressed); + } + + public static void jump(boolean pressed) { + setKey(mc.options.jumpKey, pressed); + } + + public static void sneak(boolean pressed) { + setKey(mc.options.sneakKey, pressed); + } + + public static void sprint(boolean pressed) { + setKey(mc.options.sprintKey, pressed); + } + + public static void releaseAll() { + forward(false); + back(false); + left(false); + right(false); + jump(false); + sneak(false); + sprint(false); + } + + public static boolean isForwardPressed() { + return mc.options.forwardKey.isPressed(); + } + + public static boolean isBackPressed() { + return mc.options.backKey.isPressed(); + } + + public static boolean isLeftPressed() { + return mc.options.leftKey.isPressed(); + } + + public static boolean isRightPressed() { + return mc.options.rightKey.isPressed(); + } + + public static boolean isJumpPressed() { + return mc.options.jumpKey.isPressed(); + } + + public static boolean isSneakPressed() { + return mc.options.sneakKey.isPressed(); + } + + public static boolean isSprintPressed() { + return mc.options.sprintKey.isPressed(); + } + + private static void setKey(KeyBinding key, boolean pressed) { + key.setPressed(pressed); + Input.setKeyState(key, pressed); + } +}