From cb95c1cbb37ff69fbef08ac077ee25f035f9db7e Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Fri, 13 Mar 2026 20:49:29 +0100 Subject: [PATCH 1/8] Add Triggerbot and S-Tab Sprint Reset modules --- .gitignore | 3 + build.gradle.kts | 8 + gradlew | 0 .../java/com/nnpg/glazed/GlazedAddon.java | 6 + .../glazed/modules/pvp/STabSprintReset.java | 332 ++++++++++++++++++ .../nnpg/glazed/modules/pvp/TriggerBot.java | 323 +++++++++++++++++ .../glazed/utils/glazed/MovementKeys.java | 138 ++++++++ 7 files changed, 810 insertions(+) mode change 100644 => 100755 gradlew create mode 100644 src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java create mode 100644 src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java create mode 100644 src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java diff --git a/.gitignore b/.gitignore index 09cd281f..16c658f6 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ bin/ # fabric run/ +# temp files + +temp/ diff --git a/build.gradle.kts b/build.gradle.kts index c592d63f..59c81a5e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,6 +51,14 @@ repositories { + sourceSets { + main { + java { + exclude("**/temp/**") + } + } + } + tasks { processResources { val propertyMap = mapOf( diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/com/nnpg/glazed/GlazedAddon.java b/src/main/java/com/nnpg/glazed/GlazedAddon.java index de3d0a99..5229837c 100644 --- a/src/main/java/com/nnpg/glazed/GlazedAddon.java +++ b/src/main/java/com/nnpg/glazed/GlazedAddon.java @@ -101,6 +101,12 @@ public void onInitialize() { Modules.get().add(new PremiumTunnelBaseFinder()); Modules.get().add(new AdminList()); Modules.get().add(new AutoTreeFarmer()); + // Modules.get().add(new MovementTest()); + Modules.get().add(new STabSprintReset()); + // Modules.get().add(new JumpReset()); + Modules.get().add(new TriggerBot()); + // Modules.get().add(new AttributeSwapper()); + } @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..19ef3a31 --- /dev/null +++ b/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java @@ -0,0 +1,332 @@ +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; + +/** + * S-Tab Sprint Reset + * + * Mechanism: + * Attack stops sprint IMMEDIATELY in the same tick. + * Pressing S prevents sprint from restarting (W+S = net ~0 → no sprint). + * After releasing S, sprint restarts immediately if the sprint key is held. + * + * Timing (verified against Minecraft source / mcpk.wiki): + * Pre-Delay : 1–3 Ticks (50–150ms) — weighted toward lower values + * S-Hold : 1–3 Ticks (50–150ms) — weighted toward center + * Sub-Tick : 0–20ms jitter on release — breaks tick-boundary fingerprint + * + * Design goals for undetectability: + * - Pre-delay is never 0ms (no human reacts in the same tick as their click) + * - Weighted non-uniform distributions instead of flat random ranges + * - Sub-tick jitter on release so key-up never aligns exactly to a tick edge + * - Rate-limit guards against superhuman reset frequency at high CPS + * - Skip chance tuned to reflect a skilled-but-human success rate (~75-80%) + */ +public class STabSprintReset extends Module { + + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgTiming = settings.createGroup("Timing"); + + // ── General Settings ────────────────────────────────────────────────────── + + 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) // 20% skip → ~80% success rate, realistic for a skilled player + .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() + ); + + // ── Timing Settings ─────────────────────────────────────────────────────── + + // Pre-delay: how many ticks to wait after the attack before pressing S. + // Default weighted distribution: 1T=40%, 2T=40%, 3T=20% (see rollPreDelay()). + // User-exposed min/max shifts the weight anchor, not a flat range. + 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) // Never 0 — 0ms reaction is inhuman and directly detectable + .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() + ); + + // ── State ───────────────────────────────────────────────────────────────── + + 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; + + // Sub-tick release jitter: once the hold tick count expires we don't + // release S immediately. Instead we set a real-time target (ms) and + // release when wall-clock time passes it. This means the key-up event + // is no longer aligned to a tick boundary — breaking the tick-edge + // fingerprint that behavioral anticheats look for. + private long releaseAtMs = -1L; + + // Rate-limiting: track the real-time of the last completed reset. + // A human doing S-Tab consistently faster than ~150ms is unrealistic. + private long lastResetTimeMs = 0L; + private static final int MIN_RESET_INTERVAL_MS = 150; + + // FIX 1 – Sprint-state cache. + // isSprinting() in onAttack() can already be false (sprint stops same + // tick as the attack). We cache it at tick-start, before attacks fire. + // isOnGround() is intentionally excluded: strafing (A/D) can briefly + // flip isSprinting() to false; we still want to catch those hits. + private boolean wasSprinting = false; + + // ── Constructor ─────────────────────────────────────────────────────────── + + public STabSprintReset() { + super(pvp, "s-tab-sprint-reset", "Prevents sprint restart after attack with S-tap"); + } + + // ── Lifecycle ───────────────────────────────────────────────────────────── + + @Override + public void onDeactivate() { + if (sKeyPressed) { + MovementKeys.back(false); + sKeyPressed = false; + } + resetState(); + } + + // ── Event Handlers ──────────────────────────────────────────────────────── + + @EventHandler(priority = EventPriority.HIGH) + private void onTick(TickEvent.Pre event) { + // Guard: dead player / world unload. + // onDeactivate() is not guaranteed to fire on death in Meteor Client. + if (mc.player == null || mc.player.isDead() || mc.world == null) { + if (sKeyPressed) { + MovementKeys.back(false); + sKeyPressed = false; + } + resetState(); + return; + } + + // FIX 1: Update sprint cache at tick-start, before AttackEvent fires. + wasSprinting = mc.player.isSprinting(); + + // FIX 3: Player left the ground during S-hold → release immediately. + // S pressed while airborne still blocks sprint technically, but + // produces a visible backward nudge that looks unnatural. + // Pre-delay phase does NOT abort on airborne – S pressed in the air + // after a ground hit still performs the sprint break correctly. + if (waitingForSRelease && !mc.player.isOnGround()) { + releaseS(); + return; + } + + // ── Pre-Delay Phase ─────────────────────────────────────────────────── + if (waitingForPreDelay) { + preDelayTicks++; + if (preDelayTicks >= currentPreDelay) { + pressS(); + } + return; + } + + // ── S-Hold Phase ────────────────────────────────────────────────────── + if (waitingForSRelease) { + sHoldTicks++; + + // Once the hold-tick threshold is reached, schedule a sub-tick + // release rather than releasing instantly on the tick boundary. + if (sHoldTicks >= currentSHold && releaseAtMs < 0) { + int jitterMs = (int)(Math.random() * 20); // 0–20ms sub-tick jitter + releaseAtMs = System.currentTimeMillis() + jitterMs; + } + + // Release only when real-time wall clock has passed the target. + if (releaseAtMs >= 0 && System.currentTimeMillis() >= releaseAtMs) { + releaseAtMs = -1L; + releaseS(); + } + return; + } + + // Safety-net: S is physically held but state machine is idle. + // Caused by: two attacks in the exact same tick, or external corruption. + if (sKeyPressed) { + releaseS(); + } + } + + @EventHandler(priority = EventPriority.HIGH) + private void onAttack(AttackEntityEvent event) { + if (!(event.entity instanceof LivingEntity)) return; + + // Ground check stays here, separate from the sprint cache. + if (!mc.player.isOnGround()) return; + + // FIX 1: Use cached sprint state. + if (!wasSprinting) return; + + // Rate-limit: prevent superhuman reset frequency at high CPS. + // No human consistently S-tabs faster than once every 150ms. + long now = System.currentTimeMillis(); + if (now - lastResetTimeMs < MIN_RESET_INTERVAL_MS) return; + + // FIX 4 (Spam-click safe): abort any running sequence cleanly. + if (sKeyPressed) releaseS(); + + // Skip chance. + if (Math.random() * 100 < skipChance.get()) return; + + // Roll timing using weighted distributions (see helpers below). + currentPreDelay = rollPreDelay(); + currentSHold = rollSHold(); + preDelayTicks = 0; + sHoldTicks = 0; + releaseAtMs = -1L; + waitingForPreDelay = true; + waitingForSRelease = false; + lastResetTimeMs = now; + + // Pre-delay of 1 tick means: press S on the NEXT tick, not this one. + // currentPreDelay is always >= 1 (enforced by rollPreDelay), + // so we never call pressS() here — we always go through the tick counter. + } + + // ── Helpers ─────────────────────────────────────────────────────────────── + + /** + * Weighted pre-delay distribution: + * 1 tick (50ms) → 40% — fast but plausible reaction + * 2 ticks (100ms)→ 40% — average human reaction + * 3 ticks (150ms)→ 20% — slightly slow / distracted hit + * + * Settings shift the anchor: if preDelayMin > 1, the distribution + * is clamped upward. If preDelayMax < 3, the top bucket collapses. + * Never returns 0 — a 0ms reaction is inhuman and directly detectable. + */ + private int rollPreDelay() { + int min = preDelayMin.get(); // always >= 1 + 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)); + } + + /** + * Weighted S-hold distribution: + * 1 tick (50ms) → 30% — quick tap + * 2 ticks (100ms)→ 50% — normal hold + * 3 ticks (150ms)→ 20% — slightly long hold + * + * Combined with the 0–20ms sub-tick release jitter, the actual + * hold duration is continuously distributed, not discretely bucketed. + */ + 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(); + } + + /** + * Resets all state fields. Never touches the S key directly — + * always call releaseS() first if sKeyPressed is true. + */ + 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..d8a2833e --- /dev/null +++ b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java @@ -0,0 +1,323 @@ +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 { + + // ── Groups ──────────────────────────────────────────────────────────────── + + private final SettingGroup sgFilter = settings.createGroup("Filter"); + private final SettingGroup sgAttack = settings.createGroup("Attack"); + + // ── Filter ──────────────────────────────────────────────────────────────── + + 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() + ); + + 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() + ); + + // ── Attack ──────────────────────────────────────────────────────────────── + + 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() + ); + + // ── State ───────────────────────────────────────────────────────────────── + + private float randomOnFallFloat = 0; + private float randomHitSpeedFloat = 0; + + // Sub-tick buffer: Render3DEvent fires every frame (~7ms at 144fps). + // Stores the last valid entity the crosshair touched so fast flick-overs + // between two ticks are not missed. Both Render3DEvent and TickEvent fire + // on the MC main thread – no synchronisation needed. + private Entity bufferedTarget = null; + private long lastSeenNano = 0L; + + // ── Constructor ─────────────────────────────────────────────────────────── + + public TriggerBot() { + super(GlazedAddon.pvp, "triggerbot", + "Attacks the entity you are looking at, optionally only when critting."); + } + + // ── Lifecycle ───────────────────────────────────────────────────────────── + + @Override + public void onActivate() { + randomOnFallFloat = 0; + randomHitSpeedFloat = 0; + bufferedTarget = null; + lastSeenNano = 0L; + } + + // ── Render frame: update sub-tick buffer ────────────────────────────────── + + // Runs every rendered frame. Only updates the buffer – no attack logic here. + @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(); + } + } + + // ── Tick: attack ────────────────────────────────────────────────────────── + + @EventHandler + private void onTick(TickEvent.Pre event) { + if (mc.player == null || mc.player.isDead() + || mc.player.getHealth() <= 0 || mc.world == null) return; + + // ── Resolve target ──────────────────────────────────────────────────── + // Prefer live crosshair, fall back to render-frame buffer (hit window). + Entity entity = getTarget(); + + if (entity == null) { + long elapsedMs = (System.nanoTime() - lastSeenNano) / 1_000_000L; + if (bufferedTarget == null || elapsedMs > hitWindowMs.get()) return; + entity = bufferedTarget; + // Re-validate: entity may have moved/died since last render frame + if (!entity.isAlive()) { bufferedTarget = null; return; } + if (mc.player.squaredDistanceTo(entity) > range.get() * range.get()) { bufferedTarget = null; return; } + if (!entityCheck(entity)) { bufferedTarget = null; return; } + } + + // Clear buffer – attack fires this tick, fresh data needed next tick + bufferedTarget = null; + + // ── On-fall / crit check ────────────────────────────────────────────── + // velocity.y is negative while falling; threshold is stored as positive. + // Jitter of ±0.016 ≈ ±10ms so the exact trigger moment varies slightly. + 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; // not falling fast enough + if (mc.player.isOnGround()) return; // on ground = no crit + if (mc.player.isTouchingWater()) return; // vanilla crit blocker + if (mc.player.isClimbing()) return; // vanilla crit blocker + if (mc.player.hasVehicle()) return; // vanilla crit blocker + } + + // ── Hit-speed / cooldown check ──────────────────────────────────────── + HitSpeedMode currHitSpeedMode = hitSpeedMode.get(); + if (currHitSpeedMode != HitSpeedMode.None) { + float hitSpeed = (currHitSpeedMode == HitSpeedMode.Value) + ? hitSpeedValue.get().floatValue() + : randomHitSpeedFloat; + // Vanilla: (scale * 17) >= 16 → scale >= ~0.941 + if ((mc.player.getAttackCooldownProgress(hitSpeed) * 17.0F) < 16) return; + } + + // ── Attack ──────────────────────────────────────────────────────────── + mc.interactionManager.attackEntity(mc.player, entity); + mc.player.swingHand(Hand.MAIN_HAND); + + // ── Randomise next thresholds ───────────────────────────────────────── + 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); + } + } + + // ── Target resolution ───────────────────────────────────────────────────── + + 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; + } + + // ── Entity filter ───────────────────────────────────────────────────────── + + 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; + } + + // ── Enums ───────────────────────────────────────────────────────────────── + + 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..7c46494e --- /dev/null +++ b/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java @@ -0,0 +1,138 @@ +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; + +/** + * MovementKeys Utility - Vereinfachte Steuerung von Movement-Keys + * + * Verwendung in Modulen: + * MovementKeys.forward(true); // Vorwärts laufen + * MovementKeys.jump(true); // Springen + * MovementKeys.sneak(true); // Schleichen + * MovementKeys.releaseAll(); // Alle Keys loslassen + */ +public class MovementKeys { + + /** + * Setzt den Forward-Key (W) + */ + public static void forward(boolean pressed) { + setKey(mc.options.forwardKey, pressed); + } + + /** + * Setzt den Back-Key (S) + */ + public static void back(boolean pressed) { + setKey(mc.options.backKey, pressed); + } + + /** + * Setzt den Left-Key (A) + */ + public static void left(boolean pressed) { + setKey(mc.options.leftKey, pressed); + } + + /** + * Setzt den Right-Key (D) + */ + public static void right(boolean pressed) { + setKey(mc.options.rightKey, pressed); + } + + /** + * Setzt den Jump-Key (Space) + */ + public static void jump(boolean pressed) { + setKey(mc.options.jumpKey, pressed); + } + + /** + * Setzt den Sneak-Key (Shift) + */ + public static void sneak(boolean pressed) { + setKey(mc.options.sneakKey, pressed); + } + + /** + * Setzt den Sprint-Key (Ctrl) + */ + public static void sprint(boolean pressed) { + setKey(mc.options.sprintKey, pressed); + } + + /** + * Lässt alle Movement-Keys los + */ + public static void releaseAll() { + forward(false); + back(false); + left(false); + right(false); + jump(false); + sneak(false); + sprint(false); + } + + /** + * Prüft ob Forward-Key gedrückt ist + */ + public static boolean isForwardPressed() { + return mc.options.forwardKey.isPressed(); + } + + /** + * Prüft ob Back-Key gedrückt ist + */ + public static boolean isBackPressed() { + return mc.options.backKey.isPressed(); + } + + /** + * Prüft ob Left-Key gedrückt ist + */ + public static boolean isLeftPressed() { + return mc.options.leftKey.isPressed(); + } + + /** + * Prüft ob Right-Key gedrückt ist + */ + public static boolean isRightPressed() { + return mc.options.rightKey.isPressed(); + } + + /** + * Prüft ob Jump-Key gedrückt ist + */ + public static boolean isJumpPressed() { + return mc.options.jumpKey.isPressed(); + } + + /** + * Prüft ob Sneak-Key gedrückt ist + */ + public static boolean isSneakPressed() { + return mc.options.sneakKey.isPressed(); + } + + /** + * Prüft ob Sprint-Key gedrückt ist + */ + public static boolean isSprintPressed() { + return mc.options.sprintKey.isPressed(); + } + + /** + * Zentrale Methode zum Setzen eines Movement-Keys. + * Setzt sowohl KeyBinding als auch Meteor's Input-System. + */ + private static void setKey(KeyBinding key, boolean pressed) { + key.setPressed(pressed); + Input.setKeyState(key, pressed); + } +} From 8364852cd8db02e32235d371d5f234a5cc8aa6f7 Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Tue, 17 Mar 2026 15:40:03 +0100 Subject: [PATCH 2/8] Revert unintended changes to build files and gitignore --- .gitignore | 36 ------- build.gradle.kts | 96 ------------------ gradlew | 251 ----------------------------------------------- 3 files changed, 383 deletions(-) delete mode 100644 .gitignore delete mode 100644 build.gradle.kts delete mode 100755 gradlew diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 16c658f6..00000000 --- a/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# gradle - -.gradle/ -build/ -out/ -classes/ - -# eclipse - -*.launch - -# idea - -.idea/ -*.iml -*.ipr -*.iws - -# vscode - -.settings/ -.vscode/ -bin/ -.classpath -.project - -# macos - -*.DS_Store - -# fabric - -run/ -# temp files - -temp/ diff --git a/build.gradle.kts b/build.gradle.kts deleted file mode 100644 index 59c81a5e..00000000 --- a/build.gradle.kts +++ /dev/null @@ -1,96 +0,0 @@ -plugins { - id("fabric-loom") version "1.10-SNAPSHOT" -} - -base { - archivesName = properties["archives_base_name"] as String - version = properties["mod_version"] as String - group = properties["maven_group"] as String -} - - - -repositories { - maven { - name = "meteor-maven" - url = uri("https://maven.meteordev.org/releases") - } - maven { - name = "meteor-maven-snapshots" - url = uri("https://maven.meteordev.org/snapshots") - } - - maven { - url = uri("https://jitpack.io") - } - maven { - name = "Bawnorton" - url = uri("https://maven.bawnorton.com/releases") - } - - dependencies { - // Fabric - minecraft("com.mojang:minecraft:${properties["minecraft_version"] as String}") - mappings("net.fabricmc:yarn:${properties["yarn_mappings"] as String}:v2") - modImplementation("net.fabricmc:fabric-loader:${properties["loader_version"] as String}") - - // Meteor - modImplementation("meteordevelopment:meteor-client:${properties["minecraft_version"] as String}-SNAPSHOT") - - - // Baritone - modImplementation("meteordevelopment:baritone:${properties["baritone_version"] as String}-SNAPSHOT") - - implementation("com.google.code.gson:gson:2.10.1") - - include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.3.7-beta.1")!!)!!) - - - - } - - - - sourceSets { - main { - java { - exclude("**/temp/**") - } - } - } - - tasks { - processResources { - val propertyMap = mapOf( - "version" to project.version, - "mc_version" to project.property("minecraft_version"), - ) - - inputs.properties(propertyMap) - - filteringCharset = "UTF-8" - - filesMatching("fabric.mod.json") { - expand(propertyMap) - } - } - - jar { - val licenseSuffix = project.base.archivesName.get() - from("LICENSE") { - rename { "${it}_${licenseSuffix}" } - } - } - - java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - } - - withType { - options.encoding = "UTF-8" - options.release = 21 - } - } -} - diff --git a/gradlew b/gradlew deleted file mode 100755 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" "$@" From d2c35d4b354a49505cb378f1b69ab208c1a75b04 Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Tue, 17 Mar 2026 15:41:39 +0100 Subject: [PATCH 3/8] Restore .gitignore, build.gradle.kts and gradlew from upstream --- .gitignore | 33 +++++++ build.gradle.kts | 88 +++++++++++++++++ gradlew | 251 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 372 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle.kts create mode 100644 gradlew diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..09cd281f --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# macos + +*.DS_Store + +# fabric + +run/ diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..c592d63f --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,88 @@ +plugins { + id("fabric-loom") version "1.10-SNAPSHOT" +} + +base { + archivesName = properties["archives_base_name"] as String + version = properties["mod_version"] as String + group = properties["maven_group"] as String +} + + + +repositories { + maven { + name = "meteor-maven" + url = uri("https://maven.meteordev.org/releases") + } + maven { + name = "meteor-maven-snapshots" + url = uri("https://maven.meteordev.org/snapshots") + } + + maven { + url = uri("https://jitpack.io") + } + maven { + name = "Bawnorton" + url = uri("https://maven.bawnorton.com/releases") + } + + dependencies { + // Fabric + minecraft("com.mojang:minecraft:${properties["minecraft_version"] as String}") + mappings("net.fabricmc:yarn:${properties["yarn_mappings"] as String}:v2") + modImplementation("net.fabricmc:fabric-loader:${properties["loader_version"] as String}") + + // Meteor + modImplementation("meteordevelopment:meteor-client:${properties["minecraft_version"] as String}-SNAPSHOT") + + + // Baritone + modImplementation("meteordevelopment:baritone:${properties["baritone_version"] as String}-SNAPSHOT") + + implementation("com.google.code.gson:gson:2.10.1") + + include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.3.7-beta.1")!!)!!) + + + + } + + + + tasks { + processResources { + val propertyMap = mapOf( + "version" to project.version, + "mc_version" to project.property("minecraft_version"), + ) + + inputs.properties(propertyMap) + + filteringCharset = "UTF-8" + + filesMatching("fabric.mod.json") { + expand(propertyMap) + } + } + + jar { + val licenseSuffix = project.base.archivesName.get() + from("LICENSE") { + rename { "${it}_${licenseSuffix}" } + } + } + + java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + + withType { + options.encoding = "UTF-8" + options.release = 21 + } + } +} + diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..f3b75f3b --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/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" "$@" From 5b9b4ac150d1a14cca31a207b33c592628c2cc0c Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Tue, 17 Mar 2026 15:44:32 +0100 Subject: [PATCH 4/8] Initial commit From ac6f427ec134167c046b2724456530bcf46852db Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Tue, 17 Mar 2026 15:48:00 +0100 Subject: [PATCH 5/8] chore: untrack build files --- .gitignore | 33 ------- build.gradle.kts | 88 ----------------- gradlew | 251 ----------------------------------------------- 3 files changed, 372 deletions(-) delete mode 100644 .gitignore delete mode 100644 build.gradle.kts delete mode 100644 gradlew diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 09cd281f..00000000 --- a/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# gradle - -.gradle/ -build/ -out/ -classes/ - -# eclipse - -*.launch - -# idea - -.idea/ -*.iml -*.ipr -*.iws - -# vscode - -.settings/ -.vscode/ -bin/ -.classpath -.project - -# macos - -*.DS_Store - -# fabric - -run/ diff --git a/build.gradle.kts b/build.gradle.kts deleted file mode 100644 index c592d63f..00000000 --- a/build.gradle.kts +++ /dev/null @@ -1,88 +0,0 @@ -plugins { - id("fabric-loom") version "1.10-SNAPSHOT" -} - -base { - archivesName = properties["archives_base_name"] as String - version = properties["mod_version"] as String - group = properties["maven_group"] as String -} - - - -repositories { - maven { - name = "meteor-maven" - url = uri("https://maven.meteordev.org/releases") - } - maven { - name = "meteor-maven-snapshots" - url = uri("https://maven.meteordev.org/snapshots") - } - - maven { - url = uri("https://jitpack.io") - } - maven { - name = "Bawnorton" - url = uri("https://maven.bawnorton.com/releases") - } - - dependencies { - // Fabric - minecraft("com.mojang:minecraft:${properties["minecraft_version"] as String}") - mappings("net.fabricmc:yarn:${properties["yarn_mappings"] as String}:v2") - modImplementation("net.fabricmc:fabric-loader:${properties["loader_version"] as String}") - - // Meteor - modImplementation("meteordevelopment:meteor-client:${properties["minecraft_version"] as String}-SNAPSHOT") - - - // Baritone - modImplementation("meteordevelopment:baritone:${properties["baritone_version"] as String}-SNAPSHOT") - - implementation("com.google.code.gson:gson:2.10.1") - - include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.3.7-beta.1")!!)!!) - - - - } - - - - tasks { - processResources { - val propertyMap = mapOf( - "version" to project.version, - "mc_version" to project.property("minecraft_version"), - ) - - inputs.properties(propertyMap) - - filteringCharset = "UTF-8" - - filesMatching("fabric.mod.json") { - expand(propertyMap) - } - } - - jar { - val licenseSuffix = project.base.archivesName.get() - from("LICENSE") { - rename { "${it}_${licenseSuffix}" } - } - } - - java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - } - - withType { - options.encoding = "UTF-8" - options.release = 21 - } - } -} - 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" "$@" From 5e0935b362ed7365b8a0575516e09382bd44029d Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Tue, 17 Mar 2026 15:49:50 +0100 Subject: [PATCH 6/8] gitignore --- .gitignore | 35 +++++++++++++++++++ build.gradle.kts | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle.kts diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d0b7fb9b --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# macos + +*.DS_Store + +# fabric + +run/ +temp/ +gradlew \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..c592d63f --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,88 @@ +plugins { + id("fabric-loom") version "1.10-SNAPSHOT" +} + +base { + archivesName = properties["archives_base_name"] as String + version = properties["mod_version"] as String + group = properties["maven_group"] as String +} + + + +repositories { + maven { + name = "meteor-maven" + url = uri("https://maven.meteordev.org/releases") + } + maven { + name = "meteor-maven-snapshots" + url = uri("https://maven.meteordev.org/snapshots") + } + + maven { + url = uri("https://jitpack.io") + } + maven { + name = "Bawnorton" + url = uri("https://maven.bawnorton.com/releases") + } + + dependencies { + // Fabric + minecraft("com.mojang:minecraft:${properties["minecraft_version"] as String}") + mappings("net.fabricmc:yarn:${properties["yarn_mappings"] as String}:v2") + modImplementation("net.fabricmc:fabric-loader:${properties["loader_version"] as String}") + + // Meteor + modImplementation("meteordevelopment:meteor-client:${properties["minecraft_version"] as String}-SNAPSHOT") + + + // Baritone + modImplementation("meteordevelopment:baritone:${properties["baritone_version"] as String}-SNAPSHOT") + + implementation("com.google.code.gson:gson:2.10.1") + + include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.3.7-beta.1")!!)!!) + + + + } + + + + tasks { + processResources { + val propertyMap = mapOf( + "version" to project.version, + "mc_version" to project.property("minecraft_version"), + ) + + inputs.properties(propertyMap) + + filteringCharset = "UTF-8" + + filesMatching("fabric.mod.json") { + expand(propertyMap) + } + } + + jar { + val licenseSuffix = project.base.archivesName.get() + from("LICENSE") { + rename { "${it}_${licenseSuffix}" } + } + } + + java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + + withType { + options.encoding = "UTF-8" + options.release = 21 + } + } +} + From 526597dc41290c55e532fc2229c79c31bf931688 Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Mon, 23 Mar 2026 19:51:14 +0100 Subject: [PATCH 7/8] comments --- .../java/com/nnpg/glazed/GlazedAddon.java | 3 - .../glazed/modules/pvp/STabSprintReset.java | 123 +----------------- .../nnpg/glazed/modules/pvp/TriggerBot.java | 56 +------- .../glazed/utils/glazed/MovementKeys.java | 58 --------- 4 files changed, 9 insertions(+), 231 deletions(-) diff --git a/src/main/java/com/nnpg/glazed/GlazedAddon.java b/src/main/java/com/nnpg/glazed/GlazedAddon.java index 5229837c..964112d6 100644 --- a/src/main/java/com/nnpg/glazed/GlazedAddon.java +++ b/src/main/java/com/nnpg/glazed/GlazedAddon.java @@ -101,11 +101,8 @@ public void onInitialize() { Modules.get().add(new PremiumTunnelBaseFinder()); Modules.get().add(new AdminList()); Modules.get().add(new AutoTreeFarmer()); - // Modules.get().add(new MovementTest()); Modules.get().add(new STabSprintReset()); - // Modules.get().add(new JumpReset()); Modules.get().add(new TriggerBot()); - // Modules.get().add(new AttributeSwapper()); } diff --git a/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java b/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java index 19ef3a31..17bd76b9 100644 --- a/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java +++ b/src/main/java/com/nnpg/glazed/modules/pvp/STabSprintReset.java @@ -15,37 +15,15 @@ import static com.nnpg.glazed.GlazedAddon.pvp; -/** - * S-Tab Sprint Reset - * - * Mechanism: - * Attack stops sprint IMMEDIATELY in the same tick. - * Pressing S prevents sprint from restarting (W+S = net ~0 → no sprint). - * After releasing S, sprint restarts immediately if the sprint key is held. - * - * Timing (verified against Minecraft source / mcpk.wiki): - * Pre-Delay : 1–3 Ticks (50–150ms) — weighted toward lower values - * S-Hold : 1–3 Ticks (50–150ms) — weighted toward center - * Sub-Tick : 0–20ms jitter on release — breaks tick-boundary fingerprint - * - * Design goals for undetectability: - * - Pre-delay is never 0ms (no human reacts in the same tick as their click) - * - Weighted non-uniform distributions instead of flat random ranges - * - Sub-tick jitter on release so key-up never aligns exactly to a tick edge - * - Rate-limit guards against superhuman reset frequency at high CPS - * - Skip chance tuned to reflect a skilled-but-human success rate (~75-80%) - */ public class STabSprintReset extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgTiming = settings.createGroup("Timing"); - // ── General Settings ────────────────────────────────────────────────────── - 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) // 20% skip → ~80% success rate, realistic for a skilled player + .defaultValue(20.0) .min(0.0) .max(100.0) .sliderMax(100.0) @@ -58,17 +36,11 @@ public class STabSprintReset extends Module { .defaultValue(false) .build() ); - - // ── Timing Settings ─────────────────────────────────────────────────────── - - // Pre-delay: how many ticks to wait after the attack before pressing S. - // Default weighted distribution: 1T=40%, 2T=40%, 3T=20% (see rollPreDelay()). - // User-exposed min/max shifts the weight anchor, not a flat range. 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) // Never 0 — 0ms reaction is inhuman and directly detectable + .min(1) .max(5) .sliderMax(5) .visible(() -> advancedSettings.get()) @@ -108,8 +80,6 @@ public class STabSprintReset extends Module { .build() ); - // ── State ───────────────────────────────────────────────────────────────── - private boolean sKeyPressed = false; private int preDelayTicks = 0; private int sHoldTicks = 0; @@ -117,34 +87,15 @@ public class STabSprintReset extends Module { private int currentSHold = 0; private boolean waitingForPreDelay = false; private boolean waitingForSRelease = false; - - // Sub-tick release jitter: once the hold tick count expires we don't - // release S immediately. Instead we set a real-time target (ms) and - // release when wall-clock time passes it. This means the key-up event - // is no longer aligned to a tick boundary — breaking the tick-edge - // fingerprint that behavioral anticheats look for. private long releaseAtMs = -1L; - - // Rate-limiting: track the real-time of the last completed reset. - // A human doing S-Tab consistently faster than ~150ms is unrealistic. private long lastResetTimeMs = 0L; private static final int MIN_RESET_INTERVAL_MS = 150; - - // FIX 1 – Sprint-state cache. - // isSprinting() in onAttack() can already be false (sprint stops same - // tick as the attack). We cache it at tick-start, before attacks fire. - // isOnGround() is intentionally excluded: strafing (A/D) can briefly - // flip isSprinting() to false; we still want to catch those hits. private boolean wasSprinting = false; - // ── Constructor ─────────────────────────────────────────────────────────── - public STabSprintReset() { super(pvp, "s-tab-sprint-reset", "Prevents sprint restart after attack with S-tap"); } - // ── Lifecycle ───────────────────────────────────────────────────────────── - @Override public void onDeactivate() { if (sKeyPressed) { @@ -154,12 +105,8 @@ public void onDeactivate() { resetState(); } - // ── Event Handlers ──────────────────────────────────────────────────────── - @EventHandler(priority = EventPriority.HIGH) private void onTick(TickEvent.Pre event) { - // Guard: dead player / world unload. - // onDeactivate() is not guaranteed to fire on death in Meteor Client. if (mc.player == null || mc.player.isDead() || mc.world == null) { if (sKeyPressed) { MovementKeys.back(false); @@ -168,21 +115,11 @@ private void onTick(TickEvent.Pre event) { resetState(); return; } - - // FIX 1: Update sprint cache at tick-start, before AttackEvent fires. wasSprinting = mc.player.isSprinting(); - - // FIX 3: Player left the ground during S-hold → release immediately. - // S pressed while airborne still blocks sprint technically, but - // produces a visible backward nudge that looks unnatural. - // Pre-delay phase does NOT abort on airborne – S pressed in the air - // after a ground hit still performs the sprint break correctly. if (waitingForSRelease && !mc.player.isOnGround()) { releaseS(); return; } - - // ── Pre-Delay Phase ─────────────────────────────────────────────────── if (waitingForPreDelay) { preDelayTicks++; if (preDelayTicks >= currentPreDelay) { @@ -190,28 +127,18 @@ private void onTick(TickEvent.Pre event) { } return; } - - // ── S-Hold Phase ────────────────────────────────────────────────────── if (waitingForSRelease) { sHoldTicks++; - - // Once the hold-tick threshold is reached, schedule a sub-tick - // release rather than releasing instantly on the tick boundary. if (sHoldTicks >= currentSHold && releaseAtMs < 0) { - int jitterMs = (int)(Math.random() * 20); // 0–20ms sub-tick jitter + int jitterMs = (int)(Math.random() * 20); releaseAtMs = System.currentTimeMillis() + jitterMs; } - - // Release only when real-time wall clock has passed the target. if (releaseAtMs >= 0 && System.currentTimeMillis() >= releaseAtMs) { releaseAtMs = -1L; releaseS(); } return; } - - // Safety-net: S is physically held but state machine is idle. - // Caused by: two attacks in the exact same tick, or external corruption. if (sKeyPressed) { releaseS(); } @@ -220,25 +147,12 @@ private void onTick(TickEvent.Pre event) { @EventHandler(priority = EventPriority.HIGH) private void onAttack(AttackEntityEvent event) { if (!(event.entity instanceof LivingEntity)) return; - - // Ground check stays here, separate from the sprint cache. if (!mc.player.isOnGround()) return; - - // FIX 1: Use cached sprint state. if (!wasSprinting) return; - - // Rate-limit: prevent superhuman reset frequency at high CPS. - // No human consistently S-tabs faster than once every 150ms. long now = System.currentTimeMillis(); if (now - lastResetTimeMs < MIN_RESET_INTERVAL_MS) return; - - // FIX 4 (Spam-click safe): abort any running sequence cleanly. if (sKeyPressed) releaseS(); - - // Skip chance. if (Math.random() * 100 < skipChance.get()) return; - - // Roll timing using weighted distributions (see helpers below). currentPreDelay = rollPreDelay(); currentSHold = rollSHold(); preDelayTicks = 0; @@ -247,26 +161,10 @@ private void onAttack(AttackEntityEvent event) { waitingForPreDelay = true; waitingForSRelease = false; lastResetTimeMs = now; - - // Pre-delay of 1 tick means: press S on the NEXT tick, not this one. - // currentPreDelay is always >= 1 (enforced by rollPreDelay), - // so we never call pressS() here — we always go through the tick counter. } - // ── Helpers ─────────────────────────────────────────────────────────────── - - /** - * Weighted pre-delay distribution: - * 1 tick (50ms) → 40% — fast but plausible reaction - * 2 ticks (100ms)→ 40% — average human reaction - * 3 ticks (150ms)→ 20% — slightly slow / distracted hit - * - * Settings shift the anchor: if preDelayMin > 1, the distribution - * is clamped upward. If preDelayMax < 3, the top bucket collapses. - * Never returns 0 — a 0ms reaction is inhuman and directly detectable. - */ private int rollPreDelay() { - int min = preDelayMin.get(); // always >= 1 + int min = preDelayMin.get(); int max = preDelayMax.get(); double r = Math.random(); @@ -278,15 +176,6 @@ private int rollPreDelay() { return Math.max(min, Math.min(max, rolled)); } - /** - * Weighted S-hold distribution: - * 1 tick (50ms) → 30% — quick tap - * 2 ticks (100ms)→ 50% — normal hold - * 3 ticks (150ms)→ 20% — slightly long hold - * - * Combined with the 0–20ms sub-tick release jitter, the actual - * hold duration is continuously distributed, not discretely bucketed. - */ private int rollSHold() { int min = sHoldMin.get(); int max = sHoldMax.get(); @@ -316,10 +205,6 @@ private void releaseS() { resetState(); } - /** - * Resets all state fields. Never touches the S key directly — - * always call releaseS() first if sKeyPressed is true. - */ private void resetState() { waitingForPreDelay = false; waitingForSRelease = false; diff --git a/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java index d8a2833e..6d74dd1e 100644 --- a/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java +++ b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java @@ -20,13 +20,9 @@ public class TriggerBot extends Module { - // ── Groups ──────────────────────────────────────────────────────────────── - private final SettingGroup sgFilter = settings.createGroup("Filter"); private final SettingGroup sgAttack = settings.createGroup("Attack"); - // ── Filter ──────────────────────────────────────────────────────────────── - private final Setting target = sgFilter.add(new EnumSetting.Builder() .name("target") .description("Which entities to attack.") @@ -57,8 +53,6 @@ public class TriggerBot extends Module { .build() ); - // ── Attack ──────────────────────────────────────────────────────────────── - 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 " @@ -145,27 +139,16 @@ public class TriggerBot extends Module { .build() ); - // ── State ───────────────────────────────────────────────────────────────── - private float randomOnFallFloat = 0; private float randomHitSpeedFloat = 0; - - // Sub-tick buffer: Render3DEvent fires every frame (~7ms at 144fps). - // Stores the last valid entity the crosshair touched so fast flick-overs - // between two ticks are not missed. Both Render3DEvent and TickEvent fire - // on the MC main thread – no synchronisation needed. private Entity bufferedTarget = null; private long lastSeenNano = 0L; - // ── Constructor ─────────────────────────────────────────────────────────── - public TriggerBot() { super(GlazedAddon.pvp, "triggerbot", "Attacks the entity you are looking at, optionally only when critting."); } - // ── Lifecycle ───────────────────────────────────────────────────────────── - @Override public void onActivate() { randomOnFallFloat = 0; @@ -173,10 +156,6 @@ public void onActivate() { bufferedTarget = null; lastSeenNano = 0L; } - - // ── Render frame: update sub-tick buffer ────────────────────────────────── - - // Runs every rendered frame. Only updates the buffer – no attack logic here. @EventHandler private void onRender(Render3DEvent event) { if (mc.player == null || mc.world == null) return; @@ -187,33 +166,21 @@ private void onRender(Render3DEvent event) { } } - // ── Tick: attack ────────────────────────────────────────────────────────── - @EventHandler private void onTick(TickEvent.Pre event) { if (mc.player == null || mc.player.isDead() || mc.player.getHealth() <= 0 || mc.world == null) return; - - // ── Resolve target ──────────────────────────────────────────────────── - // Prefer live crosshair, fall back to render-frame buffer (hit window). Entity entity = getTarget(); if (entity == null) { long elapsedMs = (System.nanoTime() - lastSeenNano) / 1_000_000L; if (bufferedTarget == null || elapsedMs > hitWindowMs.get()) return; entity = bufferedTarget; - // Re-validate: entity may have moved/died since last render frame if (!entity.isAlive()) { bufferedTarget = null; return; } if (mc.player.squaredDistanceTo(entity) > range.get() * range.get()) { bufferedTarget = null; return; } if (!entityCheck(entity)) { bufferedTarget = null; return; } } - - // Clear buffer – attack fires this tick, fresh data needed next tick bufferedTarget = null; - - // ── On-fall / crit check ────────────────────────────────────────────── - // velocity.y is negative while falling; threshold is stored as positive. - // Jitter of ±0.016 ≈ ±10ms so the exact trigger moment varies slightly. OnFallMode currOnFallMode = onFallMode.get(); if (currOnFallMode != OnFallMode.None) { float threshold = (currOnFallMode == OnFallMode.Value) @@ -223,28 +190,21 @@ private void onTick(TickEvent.Pre event) { double vy = mc.player.getVelocity().y; float jitter = (mc.world.random.nextFloat() * 0.032f) - 0.016f; - if (vy >= -(threshold + jitter)) return; // not falling fast enough - if (mc.player.isOnGround()) return; // on ground = no crit - if (mc.player.isTouchingWater()) return; // vanilla crit blocker - if (mc.player.isClimbing()) return; // vanilla crit blocker - if (mc.player.hasVehicle()) return; // vanilla crit blocker + 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; } - - // ── Hit-speed / cooldown check ──────────────────────────────────────── HitSpeedMode currHitSpeedMode = hitSpeedMode.get(); if (currHitSpeedMode != HitSpeedMode.None) { float hitSpeed = (currHitSpeedMode == HitSpeedMode.Value) ? hitSpeedValue.get().floatValue() : randomHitSpeedFloat; - // Vanilla: (scale * 17) >= 16 → scale >= ~0.941 if ((mc.player.getAttackCooldownProgress(hitSpeed) * 17.0F) < 16) return; } - - // ── Attack ──────────────────────────────────────────────────────────── mc.interactionManager.attackEntity(mc.player, entity); mc.player.swingHand(Hand.MAIN_HAND); - - // ── Randomise next thresholds ───────────────────────────────────────── if (currOnFallMode == OnFallMode.RandomValue) { float min = Math.min(onFallMinRandomValue.get().floatValue(), onFallMaxRandomValue.get().floatValue()); float max = Math.max(onFallMinRandomValue.get().floatValue(), onFallMaxRandomValue.get().floatValue()); @@ -258,8 +218,6 @@ private void onTick(TickEvent.Pre event) { } } - // ── Target resolution ───────────────────────────────────────────────────── - private Entity getTarget() { if (ignoreWalls.get()) return getTargetThroughWalls(); @@ -295,8 +253,6 @@ private Entity getTargetThroughWalls() { return best; } - // ── Entity filter ───────────────────────────────────────────────────────── - private boolean entityCheck(Entity entity) { if (entity == mc.player || entity == mc.getCameraEntity()) return false; if (!entity.isAlive()) return false; @@ -315,8 +271,6 @@ private boolean entityCheck(Entity entity) { return true; } - // ── Enums ───────────────────────────────────────────────────────────────── - public enum Target { Players, Entities, All } public enum OnFallMode { None, Value, RandomValue } public enum HitSpeedMode { None, Value, RandomValue } diff --git a/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java b/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java index 7c46494e..51e76ee7 100644 --- a/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java +++ b/src/main/java/com/nnpg/glazed/utils/glazed/MovementKeys.java @@ -5,69 +5,36 @@ import static meteordevelopment.meteorclient.MeteorClient.mc; -/** - * MovementKeys Utility - Vereinfachte Steuerung von Movement-Keys - * - * Verwendung in Modulen: - * MovementKeys.forward(true); // Vorwärts laufen - * MovementKeys.jump(true); // Springen - * MovementKeys.sneak(true); // Schleichen - * MovementKeys.releaseAll(); // Alle Keys loslassen - */ public class MovementKeys { - /** - * Setzt den Forward-Key (W) - */ public static void forward(boolean pressed) { setKey(mc.options.forwardKey, pressed); } - /** - * Setzt den Back-Key (S) - */ public static void back(boolean pressed) { setKey(mc.options.backKey, pressed); } - /** - * Setzt den Left-Key (A) - */ public static void left(boolean pressed) { setKey(mc.options.leftKey, pressed); } - /** - * Setzt den Right-Key (D) - */ public static void right(boolean pressed) { setKey(mc.options.rightKey, pressed); } - /** - * Setzt den Jump-Key (Space) - */ public static void jump(boolean pressed) { setKey(mc.options.jumpKey, pressed); } - /** - * Setzt den Sneak-Key (Shift) - */ public static void sneak(boolean pressed) { setKey(mc.options.sneakKey, pressed); } - /** - * Setzt den Sprint-Key (Ctrl) - */ public static void sprint(boolean pressed) { setKey(mc.options.sprintKey, pressed); } - /** - * Lässt alle Movement-Keys los - */ public static void releaseAll() { forward(false); back(false); @@ -78,59 +45,34 @@ public static void releaseAll() { sprint(false); } - /** - * Prüft ob Forward-Key gedrückt ist - */ public static boolean isForwardPressed() { return mc.options.forwardKey.isPressed(); } - /** - * Prüft ob Back-Key gedrückt ist - */ public static boolean isBackPressed() { return mc.options.backKey.isPressed(); } - /** - * Prüft ob Left-Key gedrückt ist - */ public static boolean isLeftPressed() { return mc.options.leftKey.isPressed(); } - /** - * Prüft ob Right-Key gedrückt ist - */ public static boolean isRightPressed() { return mc.options.rightKey.isPressed(); } - /** - * Prüft ob Jump-Key gedrückt ist - */ public static boolean isJumpPressed() { return mc.options.jumpKey.isPressed(); } - /** - * Prüft ob Sneak-Key gedrückt ist - */ public static boolean isSneakPressed() { return mc.options.sneakKey.isPressed(); } - /** - * Prüft ob Sprint-Key gedrückt ist - */ public static boolean isSprintPressed() { return mc.options.sprintKey.isPressed(); } - /** - * Zentrale Methode zum Setzen eines Movement-Keys. - * Setzt sowohl KeyBinding als auch Meteor's Input-System. - */ private static void setKey(KeyBinding key, boolean pressed) { key.setPressed(pressed); Input.setKeyState(key, pressed); From 3d379a995d49558ac896f7e7baa5a231a42e4dde Mon Sep 17 00:00:00 2001 From: HelixCraft Date: Sat, 4 Apr 2026 18:39:46 +0200 Subject: [PATCH 8/8] test commit --- src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java index 6d74dd1e..8656ce67 100644 --- a/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java +++ b/src/main/java/com/nnpg/glazed/modules/pvp/TriggerBot.java @@ -38,7 +38,7 @@ public class TriggerBot extends Module { .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.")