0
0
mirror of https://github.com/Wurst-Imperium/Wurst7.git synced 2024-09-19 17:02:13 +02:00

Merge branch 'v7.43'

This commit is contained in:
Alexander01998 2024-06-14 10:53:48 +02:00
commit 0030020e20
33 changed files with 885 additions and 394 deletions

View File

@ -1,13 +1,12 @@
buildscript {
dependencies {
classpath 'org.kohsuke:github-api:1.321'
classpath "org.kohsuke:github-api:1.321"
}
}
plugins {
id 'fabric-loom' version '1.6-SNAPSHOT'
id 'maven-publish'
id 'com.diffplug.spotless' version '6.25.0'
id "fabric-loom" version "1.6-SNAPSHOT"
id "com.diffplug.spotless" version "6.25.0"
}
def ENV = System.getenv()
@ -85,23 +84,6 @@ spotless {
}
}
// configure the maven publication
publishing {
publications {
create("mavenJava", MavenPublication) {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}
task moveDevLibs(dependsOn: [remapJar, remapSourcesJar]) {
doLast {
ant.move(file:"${project.buildDir}/devlibs/${archivesBaseName}-${version}-dev.jar", tofile:"${project.buildDir}/libs/${archivesBaseName}-${version}-dev.jar")

View File

@ -13,7 +13,7 @@ loader_version=0.15.11
fabric_version=0.100.1+1.21
# Mod Properties
mod_version = v7.42-MC1.21
mod_version = v7.43-MC1.21
maven_group = net.wurstclient
archives_base_name = Wurst-Client

View File

@ -58,7 +58,7 @@ public enum WurstClient
public static MinecraftClient MC;
public static IMinecraftClient IMC;
public static final String VERSION = "7.42";
public static final String VERSION = "7.43";
public static final String MC_VERSION = "1.21";
private WurstAnalytics analytics;

View File

@ -18,6 +18,7 @@ import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.LavaFluid;
@ -31,20 +32,9 @@ import net.wurstclient.util.RenderUtils;
public class PathFinder
{
private final WurstClient wurst = WurstClient.INSTANCE;
private static final MinecraftClient MC = WurstClient.MC;
private final boolean invulnerable =
WurstClient.MC.player.getAbilities().creativeMode;
private final boolean creativeFlying =
WurstClient.MC.player.getAbilities().flying;
protected final boolean flying =
creativeFlying || wurst.getHax().flightHack.isEnabled();
private final boolean immuneToFallDamage =
invulnerable || wurst.getHax().noFallHack.isEnabled();
private final boolean noWaterSlowdown =
wurst.getHax().antiWaterPushHack.isPreventingSlowdown();
private final boolean jesus = wurst.getHax().jesusHack.isEnabled();
private final boolean spider = wurst.getHax().spiderHack.isEnabled();
private final PlayerAbilities abilities = PlayerAbilities.get();
protected boolean fallingAllowed = true;
protected boolean divingAllowed = true;
@ -66,13 +56,11 @@ public class PathFinder
public PathFinder(BlockPos goal)
{
if(WurstClient.MC.player.isOnGround())
start = new PathPos(BlockPos.ofFloored(WurstClient.MC.player.getX(),
WurstClient.MC.player.getY() + 0.5,
WurstClient.MC.player.getZ()));
if(MC.player.isOnGround())
start = new PathPos(BlockPos.ofFloored(MC.player.getX(),
MC.player.getY() + 0.5, MC.player.getZ()));
else
start =
new PathPos(BlockPos.ofFloored(WurstClient.MC.player.getPos()));
start = new PathPos(BlockPos.ofFloored(MC.player.getPos()));
this.goal = goal;
costMap.put(start, 0F);
@ -196,7 +184,7 @@ public class PathFinder
}
// up
if(pos.getY() < WurstClient.MC.world.getTopY() && canGoThrough(up.up())
if(pos.getY() < MC.world.getTopY() && canGoThrough(up.up())
&& (flying || onGround || canClimbUpAt(pos))
&& (flying || canClimbUpAt(pos) || goal.equals(up)
|| canSafelyStandOn(north) || canSafelyStandOn(east)
@ -205,7 +193,7 @@ public class PathFinder
neighbors.add(new PathPos(up, onGround));
// down
if(pos.getY() > WurstClient.MC.world.getBottomY() && canGoThrough(down)
if(pos.getY() > MC.world.getBottomY() && canGoThrough(down)
&& canGoAbove(down.down()) && (flying || canFallBelow(pos))
&& (divingAllowed || BlockUtils.getBlock(pos) != Blocks.WATER))
neighbors.add(new PathPos(down));
@ -285,8 +273,8 @@ public class PathFinder
Block block = state.getBlock();
return state.blocksMovement() && !(block instanceof AbstractSignBlock)
|| block instanceof LadderBlock
|| jesus && (block == Blocks.WATER || block == Blocks.LAVA);
|| block instanceof LadderBlock || abilities.jesus()
&& (block == Blocks.WATER || block == Blocks.LAVA);
}
@SuppressWarnings("deprecation")
@ -295,7 +283,7 @@ public class PathFinder
// check if loaded
// Can't see why isChunkLoaded() is deprecated. Still seems to be widely
// used with no replacement.
if(!WurstClient.MC.world.isChunkLoaded(pos))
if(!MC.world.isChunkLoaded(pos))
return false;
// check if solid
@ -310,7 +298,7 @@ public class PathFinder
return false;
// check if safe
if(!invulnerable
if(!abilities.invulnerable()
&& (block == Blocks.LAVA || block instanceof AbstractFireBlock))
return false;
@ -337,7 +325,7 @@ public class PathFinder
// check if safe
BlockState state = BlockUtils.getState(pos);
Fluid fluid = state.getFluidState().getFluid();
if(!invulnerable && (state.getBlock() instanceof CactusBlock
if(!abilities.invulnerable() && (state.getBlock() instanceof CactusBlock
|| fluid instanceof LavaFluid))
return false;
@ -356,7 +344,7 @@ public class PathFinder
return false;
// check if fall damage is off
if(immuneToFallDamage && fallingAllowed)
if(abilities.immuneToFallDamage() && fallingAllowed)
return true;
// check if fall ends with slime block
@ -395,15 +383,15 @@ public class PathFinder
private boolean canFlyAt(BlockPos pos)
{
return flying
|| !noWaterSlowdown && BlockUtils.getBlock(pos) == Blocks.WATER;
return abilities.flying() || !abilities.noWaterSlowdown()
&& BlockUtils.getBlock(pos) == Blocks.WATER;
}
private boolean canClimbUpAt(BlockPos pos)
{
// check if this block works for climbing
Block block = BlockUtils.getBlock(pos);
if(!spider && !(block instanceof LadderBlock)
if(!abilities.spider() && !(block instanceof LadderBlock)
&& !(block instanceof VineBlock))
return false;
@ -448,7 +436,7 @@ public class PathFinder
Block block = BlockUtils.getBlock(pos);
// liquids
if(block == Blocks.WATER && !noWaterSlowdown)
if(block == Blocks.WATER && !abilities.noWaterSlowdown())
costs[i] *= 1.3164437838225804F;
else if(block == Blocks.LAVA)
costs[i] *= 4.539515393656079F;
@ -624,15 +612,7 @@ public class PathFinder
throw new IllegalStateException("Path is not formatted!");
// check player abilities
if(invulnerable != WurstClient.MC.player.getAbilities().creativeMode
|| flying != (creativeFlying
|| wurst.getHax().flightHack.isEnabled())
|| immuneToFallDamage != (invulnerable
|| wurst.getHax().noFallHack.isEnabled())
|| noWaterSlowdown != wurst.getHax().antiWaterPushHack
.isPreventingSlowdown()
|| jesus != wurst.getHax().jesusHack.isEnabled()
|| spider != wurst.getHax().spiderHack.isEnabled())
if(!abilities.equals(PlayerAbilities.get()))
return false;
// if index is zero, check if first pos is safe
@ -654,8 +634,8 @@ public class PathFinder
public PathProcessor getProcessor()
{
if(flying)
return new FlyPathProcessor(path, creativeFlying);
if(abilities.flying())
return new FlyPathProcessor(path, abilities.creativeFlying());
return new WalkPathProcessor(path);
}

View File

@ -70,7 +70,7 @@ public abstract class PathProcessor
key.setPressed(false);
// disable sprinting
WurstClient.MC.player.setSprinting(false);
MC.player.setSprinting(false);
}
public static final void releaseControls()

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.ai;
import net.minecraft.client.MinecraftClient;
import net.wurstclient.WurstClient;
import net.wurstclient.hack.HackList;
public record PlayerAbilities(boolean invulnerable, boolean creativeFlying,
boolean flying, boolean immuneToFallDamage, boolean noWaterSlowdown,
boolean jesus, boolean spider)
{
private static final WurstClient WURST = WurstClient.INSTANCE;
private static final MinecraftClient MC = WurstClient.MC;
public static PlayerAbilities get()
{
HackList hax = WURST.getHax();
net.minecraft.entity.player.PlayerAbilities mcAbilities =
MC.player.getAbilities();
boolean invulnerable =
mcAbilities.invulnerable || mcAbilities.creativeMode;
boolean creativeFlying = mcAbilities.flying;
boolean flying = creativeFlying || hax.flightHack.isEnabled();
boolean immuneToFallDamage = invulnerable || hax.noFallHack.isEnabled();
boolean noWaterSlowdown = hax.antiWaterPushHack.isPreventingSlowdown();
boolean jesus = hax.jesusHack.isEnabled();
boolean spider = hax.spiderHack.isEnabled();
return new PlayerAbilities(invulnerable, creativeFlying, flying,
immuneToFallDamage, noWaterSlowdown, jesus, spider);
}
}

View File

@ -20,7 +20,9 @@ import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -153,7 +155,13 @@ public enum MicrosoftLoginManager
System.out.println("Getting login cookies...");
cookie = "";
for(String c : connection.getHeaderFields().get("Set-Cookie"))
List<String> cookies =
connection.getHeaderFields().get("Set-Cookie");
if(cookies == null)
cookies = Collections.emptyList();
for(String c : cookies)
{
String cookieTrimmed = c.substring(0, c.indexOf(";") + 1);
cookie += cookieTrimmed;

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.events;
import java.util.ArrayList;
import net.minecraft.client.MinecraftClient;
import net.wurstclient.event.Event;
import net.wurstclient.event.Listener;
/**
* Fired at the beginning of {@link MinecraftClient#handleInputEvents()}.
* This is the ideal time to simulate keyboard input.
*/
public interface HandleInputListener extends Listener
{
/**
* Fired at the beginning of {@link MinecraftClient#handleInputEvents()}.
* This is the ideal time to simulate keyboard input.
*/
public void onHandleInput();
/**
* Fired at the beginning of {@link MinecraftClient#handleInputEvents()}.
* This is the ideal time to simulate keyboard input.
*/
public static class HandleInputEvent extends Event<HandleInputListener>
{
public static final HandleInputEvent INSTANCE = new HandleInputEvent();
@Override
public void fire(ArrayList<HandleInputListener> listeners)
{
for(HandleInputListener listener : listeners)
listener.onHandleInput();
}
@Override
public Class<HandleInputListener> getListenerType()
{
return HandleInputListener.class;
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.events;
import java.util.ArrayList;
import net.minecraft.client.Mouse;
import net.wurstclient.event.Event;
import net.wurstclient.event.Listener;
/**
* Fired at the beginning of {@link Mouse#tick()}.
* This is the ideal time to simulate mouse input.
*/
public interface MouseUpdateListener extends Listener
{
/**
* Fired at the beginning of {@link Mouse#tick()}.
* This is the ideal time to simulate mouse input.
*/
public void onMouseUpdate(MouseUpdateEvent event);
/**
* Fired at the beginning of {@link Mouse#tick()}.
* This is the ideal time to simulate mouse input.
*/
public static class MouseUpdateEvent extends Event<MouseUpdateListener>
{
private double deltaX;
private double deltaY;
private final double defaultDeltaX;
private final double defaultDeltaY;
public MouseUpdateEvent(double deltaX, double deltaY)
{
this.deltaX = deltaX;
this.deltaY = deltaY;
defaultDeltaX = deltaX;
defaultDeltaY = deltaY;
}
@Override
public void fire(ArrayList<MouseUpdateListener> listeners)
{
for(MouseUpdateListener listener : listeners)
listener.onMouseUpdate(this);
}
@Override
public Class<MouseUpdateListener> getListenerType()
{
return MouseUpdateListener.class;
}
public double getDeltaX()
{
return deltaX;
}
public void setDeltaX(double deltaX)
{
this.deltaX = deltaX;
}
public double getDeltaY()
{
return deltaY;
}
public void setDeltaY(double deltaY)
{
this.deltaY = deltaY;
}
public double getDefaultDeltaX()
{
return defaultDeltaX;
}
public double getDefaultDeltaY()
{
return defaultDeltaY;
}
}
}

View File

@ -11,15 +11,13 @@ import java.util.Comparator;
import java.util.stream.Stream;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.wurstclient.Category;
import net.wurstclient.events.RenderListener;
import net.wurstclient.events.MouseUpdateListener;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.Hack;
import net.wurstclient.settings.AimAtSetting;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
@ -31,7 +29,7 @@ import net.wurstclient.util.Rotation;
import net.wurstclient.util.RotationUtils;
public final class AimAssistHack extends Hack
implements UpdateListener, RenderListener
implements UpdateListener, MouseUpdateListener
{
private final SliderSetting range =
new SliderSetting("Range", 4.5, 1, 6, 0.05, ValueDisplay.DECIMAL);
@ -45,6 +43,9 @@ public final class AimAssistHack extends Hack
+ "360\u00b0 = aims at entities all around you.",
120, 30, 360, 10, ValueDisplay.DEGREES);
private final AimAtSetting aimAt = new AimAtSetting(
"What point in the target's hitbox AimAssist should aim at.");
private final CheckboxSetting checkLOS = new CheckboxSetting(
"Check line of sight", "Won't aim at entities behind blocks.", true);
@ -94,6 +95,7 @@ public final class AimAssistHack extends Hack
addSetting(range);
addSetting(rotationSpeed);
addSetting(fov);
addSetting(aimAt);
addSetting(checkLOS);
addSetting(aimWhileBlocking);
@ -115,14 +117,14 @@ public final class AimAssistHack extends Hack
WURST.getHax().tpAuraHack.setEnabled(false);
EVENTS.add(UpdateListener.class, this);
EVENTS.add(RenderListener.class, this);
EVENTS.add(MouseUpdateListener.class, this);
}
@Override
protected void onDisable()
{
EVENTS.remove(UpdateListener.class, this);
EVENTS.remove(RenderListener.class, this);
EVENTS.remove(MouseUpdateListener.class, this);
target = null;
}
@ -138,24 +140,11 @@ public final class AimAssistHack extends Hack
if(!aimWhileBlocking.isChecked() && MC.player.isUsingItem())
return;
Stream<Entity> stream = EntityUtils.getAttackableEntities();
double rangeSq = Math.pow(range.getValue(), 2);
stream = stream.filter(e -> MC.player.squaredDistanceTo(e) <= rangeSq);
if(fov.getValue() < 360.0)
stream = stream.filter(e -> RotationUtils.getAngleToLookVec(
e.getBoundingBox().getCenter()) <= fov.getValue() / 2.0);
stream = entityFilters.applyTo(stream);
target = stream
.min(Comparator.comparingDouble(e -> RotationUtils
.getAngleToLookVec(e.getBoundingBox().getCenter())))
.orElse(null);
chooseTarget();
if(target == null)
return;
Vec3d hitVec = target.getBoundingBox().getCenter();
Vec3d hitVec = aimAt.getAimPoint(target);
if(checkLOS.isChecked() && !BlockUtils.hasLineOfSight(hitVec))
{
target = null;
@ -163,40 +152,57 @@ public final class AimAssistHack extends Hack
}
WURST.getHax().autoSwordHack.setSlot(target);
faceEntityClient(target);
}
private boolean faceEntityClient(Entity entity)
{
// get needed rotation
Box box = entity.getBoundingBox();
Rotation needed = RotationUtils.getNeededRotations(box.getCenter());
Rotation needed = RotationUtils.getNeededRotations(hitVec);
// turn towards center of boundingBox
Rotation next = RotationUtils.slowlyTurnTowards(needed,
rotationSpeed.getValueI() / 20F);
nextYaw = next.yaw();
nextPitch = next.pitch();
}
private void chooseTarget()
{
Stream<Entity> stream = EntityUtils.getAttackableEntities();
// check if facing center
if(RotationUtils.isAlreadyFacing(needed))
return true;
double rangeSq = range.getValueSq();
stream = stream.filter(e -> MC.player.squaredDistanceTo(e) <= rangeSq);
// if not facing center, check if facing anything in boundingBox
return RotationUtils.isFacingBox(box, range.getValue());
if(fov.getValue() < 360.0)
stream = stream.filter(e -> RotationUtils.getAngleToLookVec(
aimAt.getAimPoint(e)) <= fov.getValue() / 2.0);
stream = entityFilters.applyTo(stream);
target = stream
.min(Comparator.comparingDouble(
e -> RotationUtils.getAngleToLookVec(aimAt.getAimPoint(e))))
.orElse(null);
}
@Override
public void onRender(MatrixStack matrixStack, float partialTicks)
public void onMouseUpdate(MouseUpdateEvent event)
{
if(target == null)
if(target == null || MC.player == null)
return;
// Not actually rendering anything, just using this method to rotate
// more smoothly.
float oldYaw = MC.player.prevYaw;
float oldPitch = MC.player.prevPitch;
MC.player.setYaw(MathHelper.lerp(partialTicks, oldYaw, nextYaw));
MC.player.setPitch(MathHelper.lerp(partialTicks, oldPitch, nextPitch));
float curYaw = MC.player.getYaw();
float curPitch = MC.player.getPitch();
int diffYaw = (int)(nextYaw - curYaw);
int diffPitch = (int)(nextPitch - curPitch);
// If we are <1 degree off but still missing the hitbox,
// slightly exaggerate the difference to fix that.
if(diffYaw == 0 && diffPitch == 0 && !RotationUtils
.isFacingBox(target.getBoundingBox(), range.getValue()))
{
diffYaw = nextYaw < curYaw ? -1 : 1;
diffPitch = nextPitch < curPitch ? -1 : 1;
}
event.setDeltaX(event.getDefaultDeltaX() + diffYaw);
event.setDeltaY(event.getDefaultDeltaY() + diffPitch);
}
}

View File

@ -8,7 +8,6 @@
package net.wurstclient.hacks;
import java.util.ArrayList;
import java.util.Random;
import com.mojang.blaze3d.systems.RenderSystem;
@ -16,6 +15,7 @@ import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.random.Random;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.ai.PathFinder;
@ -26,7 +26,6 @@ import net.wurstclient.events.RenderListener;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.DontSaveState;
import net.wurstclient.hack.Hack;
import net.wurstclient.mixinterface.IKeyBinding;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
@ -62,8 +61,12 @@ public final class AntiAfkHack extends Hack
0.5, 0, 60, 0.05,
ValueDisplay.DECIMAL.withPrefix("\u00b1").withSuffix("s"));
private final CheckboxSetting showWaitTime =
new CheckboxSetting("Show wait time",
"Displays the remaining wait time in the HackList.", true);
private int timer;
private Random random = new Random();
private Random random = Random.createLocal();
private BlockPos start;
private BlockPos nextBlock;
@ -81,6 +84,16 @@ public final class AntiAfkHack extends Hack
addSetting(nonAiRange);
addSetting(waitTime);
addSetting(waitTimeRand);
addSetting(showWaitTime);
}
@Override
public String getRenderName()
{
if(showWaitTime.isChecked() && timer > 0)
return getName() + " [" + timer * 50 + "ms]";
return getName();
}
@Override
@ -103,22 +116,9 @@ public final class AntiAfkHack extends Hack
{
EVENTS.remove(UpdateListener.class, this);
EVENTS.remove(RenderListener.class, this);
IKeyBinding.get(MC.options.forwardKey).resetPressedState();
IKeyBinding.get(MC.options.jumpKey).resetPressedState();
PathProcessor.releaseControls();
pathFinder = null;
processor = null;
PathProcessor.releaseControls();
}
private void setTimer()
{
int baseTime = (int)(waitTime.getValue() * 20);
int randTime = (int)(waitTimeRand.getValue() * 20);
int randOffset = random.nextInt(randTime * 2 + 1) - randTime;
randOffset = Math.max(randOffset, -baseTime);
timer = baseTime + randOffset;
}
@Override
@ -135,12 +135,18 @@ public final class AntiAfkHack extends Hack
if(useAi.isChecked())
{
// prevent drowning
if(MC.player.isSubmergedInWater()
&& !WURST.getHax().jesusHack.isEnabled())
{
MC.options.jumpKey.setPressed(true);
return;
}
// update timer
if(timer > 0)
{
timer--;
if(!WURST.getHax().jesusHack.isEnabled())
MC.options.jumpKey.setPressed(MC.player.isTouchingWater());
return;
}
@ -162,7 +168,8 @@ public final class AntiAfkHack extends Hack
// check path
if(processor != null
&& !pathFinder.isPathStillValid(processor.getIndex()))
&& !pathFinder.isPathStillValid(processor.getIndex())
|| processor.getTicksOffPath() > 20)
{
pathFinder = new RandomPathFinder(pathFinder);
return;
@ -172,13 +179,11 @@ public final class AntiAfkHack extends Hack
if(!processor.isDone())
processor.process();
else
{
// reset and wait for timer
PathProcessor.releaseControls();
pathFinder = new RandomPathFinder(
randomize(start, aiRange.getValueI(), true));
// wait 2 - 3 seconds (40 - 60 ticks)
if(processor.isDone())
{
PathProcessor.releaseControls();
setTimer();
}
}else
@ -221,6 +226,15 @@ public final class AntiAfkHack extends Hack
pathCmd.isDepthTest());
}
private void setTimer()
{
int baseTime = (int)(waitTime.getValue() * 20);
double randTime = waitTimeRand.getValue() * 20;
int randOffset = (int)(random.nextGaussian() * randTime);
randOffset = Math.max(randOffset, -baseTime);
timer = baseTime + randOffset;
}
private BlockPos randomize(BlockPos pos, int range, boolean includeY)
{
int x = random.nextInt(2 * range + 1) - range;

View File

@ -7,8 +7,8 @@
*/
package net.wurstclient.hacks;
import net.minecraft.item.Items;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.events.UpdateListener;
@ -17,6 +17,7 @@ import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.EnumSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
import net.wurstclient.util.InventoryUtils;
@SearchTags({"auto leave", "AutoDisconnect", "auto disconnect", "AutoQuit",
"auto quit"})
@ -29,11 +30,12 @@ public final class AutoLeaveHack extends Hack implements UpdateListener
public final EnumSetting<Mode> mode = new EnumSetting<>("Mode",
"\u00a7lQuit\u00a7r mode just quits the game normally.\n"
+ "Bypasses NoCheat+ but not CombatLog.\n\n"
+ "\u00a7lChars\u00a7r mode sends a special chat message that causes the server to kick you.\n"
+ "\u00a7lChars\u00a7r mode sends a special chat message that"
+ " causes the server to kick you.\n"
+ "Bypasses NoCheat+ and some versions of CombatLog.\n\n"
+ "\u00a7lTP\u00a7r mode teleports you to an invalid location, causing the server to kick you.\n"
+ "Bypasses CombatLog, but not NoCheat+.\n\n"
+ "\u00a7lSelfHurt\u00a7r mode sends the packet for attacking another player, but with yourself as both the attacker and the target. This causes the server to kick you.\n"
+ "\u00a7lSelfHurt\u00a7r mode sends the packet for attacking"
+ " another player, but with yourself as both the attacker and the"
+ " target, causing the server to kick you.\n"
+ "Bypasses both CombatLog and NoCheat+.",
Mode.values(), Mode.QUIT);
@ -42,6 +44,13 @@ public final class AutoLeaveHack extends Hack implements UpdateListener
+ " AutoLeave makes you leave the server.",
true);
private final SliderSetting totems = new SliderSetting("Totems",
"Won't leave the server until the number of totems you have reaches"
+ " this value or falls below it.\n\n"
+ "11 = always able to leave",
11, 0, 11, 1, ValueDisplay.INTEGER.withSuffix(" totems")
.withLabel(1, "1 totem").withLabel(11, "ignore"));
public AutoLeaveHack()
{
super("AutoLeave");
@ -49,11 +58,15 @@ public final class AutoLeaveHack extends Hack implements UpdateListener
addSetting(health);
addSetting(mode);
addSetting(disableAutoReconnect);
addSetting(totems);
}
@Override
public String getRenderName()
{
if(MC.player.getAbilities().creativeMode)
return getName() + " (paused)";
return getName() + " [" + mode.getSelected() + "]";
}
@ -76,38 +89,18 @@ public final class AutoLeaveHack extends Hack implements UpdateListener
if(MC.player.getAbilities().creativeMode)
return;
// check for other players
if(MC.isInSingleplayer()
&& MC.player.networkHandler.getPlayerList().size() == 1)
return;
// check health
float currentHealth = MC.player.getHealth();
if(currentHealth <= 0F || currentHealth > health.getValueF() * 2F)
return;
// check totems
if(totems.getValueI() < 11 && InventoryUtils
.count(Items.TOTEM_OF_UNDYING, 40, true) > totems.getValueI())
return;
// leave server
switch(mode.getSelected())
{
case QUIT:
MC.world.disconnect();
break;
case CHARS:
MC.getNetworkHandler().sendChatMessage("\u00a7");
break;
case TELEPORT:
MC.player.networkHandler
.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(3.1e7,
100, 3.1e7, false));
break;
case SELFHURT:
MC.player.networkHandler.sendPacket(PlayerInteractEntityC2SPacket
.attack(MC.player, MC.player.isSneaking()));
break;
}
mode.getSelected().leave.run();
// disable
setEnabled(false);
@ -118,19 +111,22 @@ public final class AutoLeaveHack extends Hack implements UpdateListener
public static enum Mode
{
QUIT("Quit"),
QUIT("Quit", () -> MC.world.disconnect()),
CHARS("Chars"),
CHARS("Chars", () -> MC.getNetworkHandler().sendChatMessage("\u00a7")),
TELEPORT("TP"),
SELFHURT("SelfHurt");
SELFHURT("SelfHurt",
() -> MC.getNetworkHandler()
.sendPacket(PlayerInteractEntityC2SPacket.attack(MC.player,
MC.player.isSneaking())));
private final String name;
private final Runnable leave;
private Mode(String name)
private Mode(String name, Runnable leave)
{
this.name = name;
this.leave = leave;
}
@Override

View File

@ -113,7 +113,7 @@ public final class AutoLibrarianHack extends Hack
private final SliderSetting repairMode = new SliderSetting("Repair mode",
"Prevents AutoLibrarian from using your axe when its durability reaches"
+ " the given threshold, so you can repair it before it breaks.\n"
+ "Can be adjusted from 0 (off) to 100.",
+ "Can be adjusted from 0 (off) to 100 remaining uses.",
1, 0, 100, 1, ValueDisplay.INTEGER.withLabel(0, "off"));
private final OverlayRenderer overlay = new OverlayRenderer();

View File

@ -7,22 +7,21 @@
*/
package net.wurstclient.hacks;
import java.util.Arrays;
import net.minecraft.block.BlockState;
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.Hack;
import net.wurstclient.util.BlockBreaker;
import net.wurstclient.mixinterface.IKeyBinding;
@SearchTags({"auto mine", "AutoBreak", "auto break"})
public final class AutoMineHack extends Hack implements UpdateListener
{
private BlockPos currentBlock;
public AutoMineHack()
{
super("AutoMine");
@ -45,46 +44,54 @@ public final class AutoMineHack extends Hack implements UpdateListener
protected void onDisable()
{
EVENTS.remove(UpdateListener.class, this);
stopMiningAndResetProgress();
IKeyBinding.get(MC.options.attackKey).resetPressedState();
MC.interactionManager.cancelBlockBreaking();
}
@Override
public void onUpdate()
{
setCurrentBlockFromHitResult();
ClientPlayerInteractionManager im = MC.interactionManager;
if(currentBlock != null)
breakCurrentBlock();
}
private void setCurrentBlockFromHitResult()
{
if(MC.crosshairTarget == null || MC.crosshairTarget.getPos() == null
|| MC.crosshairTarget.getType() != HitResult.Type.BLOCK
|| !(MC.crosshairTarget instanceof BlockHitResult))
if(MC.attackCooldown > 0)
{
stopMiningAndResetProgress();
im.cancelBlockBreaking();
return;
}
currentBlock = ((BlockHitResult)MC.crosshairTarget).getBlockPos();
}
private void breakCurrentBlock()
{
if(MC.player.getAbilities().creativeMode)
BlockBreaker.breakBlocksWithPacketSpam(Arrays.asList(currentBlock));
else
BlockBreaker.breakOneBlock(currentBlock);
}
private void stopMiningAndResetProgress()
{
if(currentBlock == null)
if(MC.player.isRiding())
{
im.cancelBlockBreaking();
return;
}
HitResult hitResult = MC.crosshairTarget;
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK
|| !(hitResult instanceof BlockHitResult bHitResult))
{
im.cancelBlockBreaking();
return;
}
BlockPos pos = bHitResult.getBlockPos();
BlockState state = MC.world.getBlockState(pos);
Direction side = bHitResult.getSide();
if(state.isAir())
{
im.cancelBlockBreaking();
return;
}
WURST.getHax().autoToolHack.equipIfEnabled(pos);
if(MC.player.isUsingItem())
// This case doesn't cancel block breaking in vanilla Minecraft.
return;
MC.interactionManager.breakingBlock = true;
MC.interactionManager.cancelBlockBreaking();
currentBlock = null;
if(im.updateBlockBreakingProgress(pos, side))
{
MC.particleManager.addBlockBreakingParticles(pos, side);
MC.options.attackKey.setPressed(true);
}
}
}

View File

@ -8,6 +8,8 @@
package net.wurstclient.hacks;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.IntStream;
import net.minecraft.block.BlockState;
import net.minecraft.client.network.ClientPlayerEntity;
@ -21,6 +23,7 @@ import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry.Reference;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
@ -28,10 +31,12 @@ import net.wurstclient.WurstClient;
import net.wurstclient.events.BlockBreakingProgressListener;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.Hack;
import net.wurstclient.mixinterface.IClientPlayerInteractionManager;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
import net.wurstclient.util.BlockUtils;
import net.wurstclient.util.InventoryUtils;
@SearchTags({"auto tool", "AutoSwitch", "auto switch"})
public final class AutoToolHack extends Hack
@ -41,18 +46,20 @@ public final class AutoToolHack extends Hack
"Uses swords to break leaves, cobwebs, etc.", false);
private final CheckboxSetting useHands = new CheckboxSetting("Use hands",
"Uses an empty hand or a non-damageable item when no applicable tool is found.",
"Uses an empty hand or a non-damageable item when no applicable tool is"
+ " found.",
true);
private final SliderSetting repairMode = new SliderSetting("Repair mode",
"Prevents tools from being used when their durability reaches the given threshold, so you can repair them before they break.\n"
+ "Can be adjusted from 0 (off) to 100.",
"Prevents tools from being used when their durability reaches the given"
+ " threshold, so you can repair them before they break.\n"
+ "Can be adjusted from 0 (off) to 100 remaining uses.",
0, 0, 100, 1, ValueDisplay.INTEGER.withLabel(0, "off"));
private final CheckboxSetting switchBack = new CheckboxSetting(
"Switch back",
"After using a tool, automatically switches back to the previously selected slot.",
true);
"Switch back", "After using a tool, automatically switches back to the"
+ " previously selected slot.",
false);
private int prevSelectedSlot;
@ -102,6 +109,10 @@ public final class AutoToolHack extends Hack
if(prevSelectedSlot == -1 || MC.interactionManager.isBreakingBlock())
return;
HitResult hitResult = MC.crosshairTarget;
if(hitResult != null && hitResult.getType() == HitResult.Type.BLOCK)
return;
if(switchBack.isChecked())
MC.player.getInventory().selectedSlot = prevSelectedSlot;
@ -124,20 +135,16 @@ public final class AutoToolHack extends Hack
if(player.getAbilities().creativeMode)
return;
int bestSlot = getBestSlot(pos, useSwords, repairMode);
ItemStack heldItem = player.getMainHandStack();
boolean heldItemDamageable = isDamageable(heldItem);
if(heldItemDamageable && isTooDamaged(heldItem, repairMode))
putAwayDamagedTool(repairMode);
BlockState state = BlockUtils.getState(pos);
int bestSlot = getBestSlot(state, useSwords, repairMode);
if(bestSlot == -1)
{
ItemStack heldItem = player.getMainHandStack();
if(!isDamageable(heldItem))
return;
if(isTooDamaged(heldItem, repairMode))
{
selectFallbackSlot();
return;
}
if(useHands && isWrongTool(heldItem, pos))
if(useHands && heldItemDamageable && isWrongTool(heldItem, state))
selectFallbackSlot();
return;
@ -146,13 +153,12 @@ public final class AutoToolHack extends Hack
player.getInventory().selectedSlot = bestSlot;
}
private int getBestSlot(BlockPos pos, boolean useSwords, int repairMode)
private int getBestSlot(BlockState state, boolean useSwords, int repairMode)
{
ClientPlayerEntity player = MC.player;
PlayerInventory inventory = player.getInventory();
ItemStack heldItem = MC.player.getMainHandStack();
BlockState state = BlockUtils.getState(pos);
float bestSpeed = getMiningSpeed(heldItem, state);
if(isTooDamaged(heldItem, repairMode))
bestSpeed = 1;
@ -215,9 +221,49 @@ public final class AutoToolHack extends Hack
return stack.getMaxDamage() - stack.getDamage() <= repairMode;
}
private boolean isWrongTool(ItemStack heldItem, BlockPos pos)
private void putAwayDamagedTool(int repairMode)
{
PlayerInventory inv = MC.player.getInventory();
int selectedSlot = inv.selectedSlot;
IClientPlayerInteractionManager im = IMC.getInteractionManager();
// If there's an empty slot in the main inventory,
// shift-click the damaged item out of the hotbar
OptionalInt emptySlot = IntStream.range(9, 36)
.filter(i -> !inv.getStack(i).isEmpty()).findFirst();
if(emptySlot.isPresent())
{
im.windowClick_QUICK_MOVE(
InventoryUtils.toNetworkSlot(selectedSlot));
return;
}
// Failing that, swap with a non-damageable item
OptionalInt nonDamageableSlot = IntStream.range(9, 36)
.filter(i -> !isDamageable(inv.getStack(i))).findFirst();
if(nonDamageableSlot.isPresent())
{
im.windowClick_SWAP(nonDamageableSlot.getAsInt(), selectedSlot);
return;
}
// Failing that, swap with a less damaged item
OptionalInt notTooDamagedSlot = IntStream.range(9, 36)
.filter(i -> !isTooDamaged(inv.getStack(i), repairMode))
.findFirst();
if(notTooDamagedSlot.isPresent())
{
im.windowClick_SWAP(notTooDamagedSlot.getAsInt(), selectedSlot);
return;
}
// Failing all of the above (whole inventory full of damaged tools),
// just swap with the top-left slot
im.windowClick_SWAP(0, selectedSlot);
}
private boolean isWrongTool(ItemStack heldItem, BlockState state)
{
BlockState state = BlockUtils.getState(pos);
return getMiningSpeed(heldItem, state) <= 1;
}

View File

@ -9,7 +9,6 @@ package net.wurstclient.hacks;
import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.wurstclient.Category;
@ -20,6 +19,7 @@ import net.wurstclient.mixinterface.IClientPlayerInteractionManager;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
import net.wurstclient.util.InventoryUtils;
@SearchTags({"auto totem", "offhand", "off-hand"})
public final class AutoTotemHack extends Hack implements UpdateListener
@ -32,10 +32,10 @@ public final class AutoTotemHack extends Hack implements UpdateListener
ValueDisplay.INTEGER);
private final SliderSetting health = new SliderSetting("Health",
"Effectively disables AutoTotem until your health reaches this value or falls below it.\n"
+ "0 = always active",
0, 0, 10, 0.5,
ValueDisplay.DECIMAL.withSuffix(" hearts").withLabel(0, "ignore"));
"Won't equip a totem until your health reaches this value or falls"
+ " below it.\n" + "0 = always active",
0, 0, 10, 0.5, ValueDisplay.DECIMAL.withSuffix(" hearts")
.withLabel(1, "1 heart").withLabel(0, "ignore"));
private int nextTickSlot;
private int totems;
@ -57,14 +57,10 @@ public final class AutoTotemHack extends Hack implements UpdateListener
if(!showCounter.isChecked())
return getName();
switch(totems)
{
case 1:
if(totems == 1)
return getName() + " [1 totem]";
default:
return getName() + " [" + totems + " totems]";
}
return getName() + " [" + totems + " totems]";
}
@Override
@ -88,13 +84,10 @@ public final class AutoTotemHack extends Hack implements UpdateListener
{
finishMovingTotem();
PlayerInventory inventory = MC.player.getInventory();
int nextTotemSlot = searchForTotems(inventory);
int nextTotemSlot = searchForTotems();
ItemStack offhandStack = inventory.getStack(40);
if(isTotem(offhandStack))
if(isTotem(MC.player.getOffHandStack()))
{
totems++;
wasTotemInOffhand = true;
return;
}
@ -105,36 +98,37 @@ public final class AutoTotemHack extends Hack implements UpdateListener
wasTotemInOffhand = false;
}
if(nextTotemSlot == -1)
return;
float healthF = health.getValueF();
if(healthF > 0 && MC.player.getHealth() > healthF * 2F)
return;
// don't move items while a container is open
if(MC.currentScreen instanceof HandledScreen
&& !(MC.currentScreen instanceof AbstractInventoryScreen))
return;
if(nextTotemSlot == -1)
return;
if(timer > 0)
{
timer--;
return;
}
moveTotem(nextTotemSlot, offhandStack);
moveToOffhand(nextTotemSlot);
}
private void moveTotem(int nextTotemSlot, ItemStack offhandStack)
private void moveToOffhand(int itemSlot)
{
boolean offhandEmpty = offhandStack.isEmpty();
boolean offhandEmpty = MC.player.getOffHandStack().isEmpty();
IClientPlayerInteractionManager im = IMC.getInteractionManager();
im.windowClick_PICKUP(nextTotemSlot);
im.windowClick_PICKUP(itemSlot);
im.windowClick_PICKUP(45);
if(!offhandEmpty)
nextTickSlot = nextTotemSlot;
nextTickSlot = itemSlot;
}
private void finishMovingTotem()
@ -147,27 +141,18 @@ public final class AutoTotemHack extends Hack implements UpdateListener
nextTickSlot = -1;
}
private int searchForTotems(PlayerInventory inventory)
private int searchForTotems()
{
totems = 0;
int nextTotemSlot = -1;
totems = InventoryUtils.count(this::isTotem, 40, true);
if(totems <= 0)
return -1;
for(int slot = 0; slot <= 36; slot++)
{
if(!isTotem(inventory.getStack(slot)))
continue;
totems++;
if(nextTotemSlot == -1)
nextTotemSlot = slot < 9 ? slot + 36 : slot;
}
return nextTotemSlot;
int totemSlot = InventoryUtils.indexOf(this::isTotem, 40);
return InventoryUtils.toNetworkSlot(totemSlot);
}
private boolean isTotem(ItemStack stack)
{
return stack.getItem() == Items.TOTEM_OF_UNDYING;
return stack.isOf(Items.TOTEM_OF_UNDYING);
}
}

View File

@ -71,7 +71,6 @@ public final class ExcavatorHack extends Hack
public ExcavatorHack()
{
super("Excavator");
setCategory(Category.BLOCKS);
addSetting(range);
addSetting(mode);
@ -83,10 +82,13 @@ public final class ExcavatorHack extends Hack
String name = getName();
if(step == Step.EXCAVATE && area != null)
name += " "
+ (int)((float)(area.blocksList.size() - area.remainingBlocks)
/ (float)area.blocksList.size() * 100)
+ "%";
{
int totalBlocks = area.blocksList.size();
double brokenBlocks = totalBlocks - area.remainingBlocks;
double progress = brokenBlocks / totalBlocks;
int percentage = (int)(progress * 100);
name += " " + percentage + "%";
}
return name;
}
@ -347,10 +349,9 @@ public final class ExcavatorHack extends Hack
else
message = step.message;
TextRenderer tr = MC.textRenderer;
// translate to center
Window sr = MC.getWindow();
TextRenderer tr = MC.textRenderer;
int msgWidth = tr.getWidth(message);
matrixStack.translate(sr.getScaledWidth() / 2 - msgWidth / 2,
sr.getScaledHeight() / 2 + 1, 0);
@ -455,14 +456,23 @@ public final class ExcavatorHack extends Hack
private void excavate()
{
boolean legit = mode.getSelected() == Mode.LEGIT;
currentBlock = null;
// wait for AutoEat to finish eating
if(WURST.getHax().autoEatHack.isEating())
return;
// prioritize the closest block from the top layer
Vec3d eyesVec = RotationUtils.getEyesPos();
Comparator<BlockPos> cNextTargetBlock =
Comparator.comparingInt(BlockPos::getY).reversed()
.thenComparingDouble(pos -> pos.getSquaredDistance(eyesVec));
// get valid blocks
Iterable<BlockPos> validBlocks = getValidBlocks(range.getValue(),
pos -> area.blocksSet.contains(pos));
ArrayList<BlockPos> validBlocks = getValidBlocks();
validBlocks.sort(cNextTargetBlock);
currentBlock = null;
// nuke all
boolean legit = mode.getSelected() == Mode.LEGIT;
if(MC.player.getAbilities().creativeMode && !legit)
{
MC.interactionManager.cancelBlockBreaking();
@ -479,25 +489,15 @@ public final class ExcavatorHack extends Hack
}else
{
ArrayList<BlockPos> blocks = new ArrayList<>();
// break next block
for(BlockPos pos : validBlocks)
blocks.add(pos);
blocks.sort(Comparator.comparingInt((BlockPos pos) -> -pos.getY()));
// find closest valid block
for(BlockPos pos : blocks)
{
boolean successful;
WURST.getHax().autoToolHack.equipIfEnabled(pos);
if(!BlockBreaker.breakOneBlock(pos))
continue;
// break block
successful = BlockBreaker.breakOneBlock(pos);
// set currentBlock if successful
if(successful)
{
currentBlock = pos;
break;
}
currentBlock = pos;
break;
}
// reset if no block was found
@ -506,9 +506,11 @@ public final class ExcavatorHack extends Hack
}
// get remaining blocks
Predicate<BlockPos> pClickable = BlockUtils::canBeClicked;
Predicate<BlockPos> pBreakable = MC.player.isCreative()
? BlockUtils::canBeClicked : pos -> BlockUtils.canBeClicked(pos)
&& !BlockUtils.isUnbreakable(pos);
area.remainingBlocks =
(int)area.blocksList.parallelStream().filter(pClickable).count();
(int)area.blocksList.parallelStream().filter(pBreakable).count();
if(area.remainingBlocks == 0)
{
@ -518,13 +520,8 @@ public final class ExcavatorHack extends Hack
if(pathFinder == null)
{
Comparator<BlockPos> cDistance = Comparator.comparingDouble(
pos -> MC.player.squaredDistanceTo(Vec3d.ofCenter(pos)));
Comparator<BlockPos> cAltitude =
Comparator.comparingInt(pos -> -pos.getY());
BlockPos closestBlock =
area.blocksList.parallelStream().filter(pClickable)
.min(cAltitude.thenComparing(cDistance)).get();
BlockPos closestBlock = area.blocksList.parallelStream()
.filter(pBreakable).min(cNextTargetBlock).get();
pathFinder = new ExcavatorPathFinder(closestBlock);
}
@ -564,22 +561,19 @@ public final class ExcavatorHack extends Hack
}
}
private ArrayList<BlockPos> getValidBlocks(double range,
Predicate<BlockPos> validator)
private ArrayList<BlockPos> getValidBlocks()
{
Vec3d eyesVec = RotationUtils.getEyesPos().subtract(0.5, 0.5, 0.5);
double rangeSq = Math.pow(range + 0.5, 2);
int rangeI = (int)Math.ceil(range);
Vec3d eyesVec = RotationUtils.getEyesPos();
BlockPos eyesBlock = BlockPos.ofFloored(eyesVec);
double rangeSq = Math.pow(range.getValue() + 0.5, 2);
int blockRange = range.getValueCeil();
BlockPos center = BlockPos.ofFloored(RotationUtils.getEyesPos());
BlockPos min = center.add(-rangeI, -rangeI, -rangeI);
BlockPos max = center.add(rangeI, rangeI, rangeI);
return BlockUtils.getAllInBox(min, max).stream()
.filter(pos -> eyesVec.squaredDistanceTo(Vec3d.of(pos)) <= rangeSq)
.filter(BlockUtils::canBeClicked).filter(validator)
.sorted(Comparator.comparingDouble(
pos -> eyesVec.squaredDistanceTo(Vec3d.of(pos))))
return BlockUtils.getAllInBoxStream(eyesBlock, blockRange)
.filter(pos -> pos.getSquaredDistance(eyesVec) <= rangeSq)
.filter(area.blocksSet::contains).filter(BlockUtils::canBeClicked)
.filter(pos -> !BlockUtils.isUnbreakable(pos))
.sorted(Comparator
.comparingDouble(pos -> pos.getSquaredDistance(eyesVec)))
.collect(Collectors.toCollection(ArrayList::new));
}

View File

@ -21,6 +21,7 @@ import net.wurstclient.hack.Hack;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
import net.wurstclient.util.BlockUtils;
@SearchTags({"FastMine", "SpeedMine", "SpeedyGonzales", "fast break",
"fast mine", "speed mine", "speedy gonzales", "NoBreakDelay",
@ -101,7 +102,7 @@ public final class FastBreakHack extends Hack
}
// Ignore unbreakable blocks to avoid slowdown issue
if(MC.world.getBlockState(blockPos).getBlock().getHardness() < 0)
if(BlockUtils.isUnbreakable(blockPos))
return;
if(!fastBreakBlock)

View File

@ -25,7 +25,7 @@ import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.events.PostMotionListener;
import net.wurstclient.events.HandleInputListener;
import net.wurstclient.events.RenderListener;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.Hack;
@ -47,7 +47,7 @@ import net.wurstclient.util.RotationUtils;
@SearchTags({"kill aura", "ForceField", "force field", "CrystalAura",
"crystal aura", "AutoCrystal", "auto crystal"})
public final class KillauraHack extends Hack
implements UpdateListener, PostMotionListener, RenderListener
implements UpdateListener, HandleInputListener, RenderListener
{
private final SliderSetting range = new SliderSetting("Range",
"Determines how far Killaura will reach to attack entities.\n"
@ -57,6 +57,15 @@ public final class KillauraHack extends Hack
private final AttackSpeedSliderSetting speed =
new AttackSpeedSliderSetting();
private final SliderSetting speedRandMS =
new SliderSetting("Speed randomization",
"Helps you bypass anti-cheat plugins by varying the delay between"
+ " attacks.\n\n" + "\u00b1100ms is recommended for Vulcan.\n\n"
+ "0 (off) is fine for NoCheat+, AAC, Grim, Verus, Spartan, and"
+ " vanilla servers.",
100, 0, 1000, 50, ValueDisplay.INTEGER.withPrefix("\u00b1")
.withSuffix("ms").withLabel(0, "off"));
private final EnumSetting<Priority> priority = new EnumSetting<>("Priority",
"Determines which entity will be attacked first.\n"
+ "\u00a7lDistance\u00a7r - Attacks the closest entity.\n"
@ -98,6 +107,7 @@ public final class KillauraHack extends Hack
addSetting(range);
addSetting(speed);
addSetting(speedRandMS);
addSetting(priority);
addSetting(fov);
addSetting(swingHand);
@ -122,9 +132,9 @@ public final class KillauraHack extends Hack
WURST.getHax().triggerBotHack.setEnabled(false);
WURST.getHax().tpAuraHack.setEnabled(false);
speed.resetTimer();
speed.resetTimer(speedRandMS.getValue());
EVENTS.add(UpdateListener.class, this);
EVENTS.add(PostMotionListener.class, this);
EVENTS.add(HandleInputListener.class, this);
EVENTS.add(RenderListener.class, this);
}
@ -132,7 +142,7 @@ public final class KillauraHack extends Hack
protected void onDisable()
{
EVENTS.remove(UpdateListener.class, this);
EVENTS.remove(PostMotionListener.class, this);
EVENTS.remove(HandleInputListener.class, this);
EVENTS.remove(RenderListener.class, this);
target = null;
@ -177,7 +187,7 @@ public final class KillauraHack extends Hack
}
@Override
public void onPostMotion()
public void onHandleInput()
{
if(target == null)
return;
@ -187,7 +197,7 @@ public final class KillauraHack extends Hack
swingHand.swing(Hand.MAIN_HAND);
target = null;
speed.resetTimer();
speed.resetTimer(speedRandMS.getValue());
}
@Override

View File

@ -26,6 +26,8 @@ import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.wurstclient.Category;
import net.wurstclient.events.HandleInputListener;
import net.wurstclient.events.MouseUpdateListener;
import net.wurstclient.events.RenderListener;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.Hack;
@ -45,8 +47,8 @@ import net.wurstclient.util.RenderUtils;
import net.wurstclient.util.Rotation;
import net.wurstclient.util.RotationUtils;
public final class KillauraLegitHack extends Hack
implements UpdateListener, RenderListener
public final class KillauraLegitHack extends Hack implements UpdateListener,
HandleInputListener, MouseUpdateListener, RenderListener
{
private final SliderSetting range =
new SliderSetting("Range", 4.25, 1, 4.25, 0.05, ValueDisplay.DECIMAL);
@ -54,6 +56,15 @@ public final class KillauraLegitHack extends Hack
private final AttackSpeedSliderSetting speed =
new AttackSpeedSliderSetting();
private final SliderSetting speedRandMS =
new SliderSetting("Speed randomization",
"Helps you bypass anti-cheat plugins by varying the delay between"
+ " attacks.\n\n" + "\u00b1100ms is recommended for Vulcan.\n\n"
+ "0 (off) is fine for NoCheat+, AAC, Grim, Verus, Spartan, and"
+ " vanilla servers.",
100, 0, 1000, 50, ValueDisplay.INTEGER.withPrefix("\u00b1")
.withSuffix("ms").withLabel(0, "off"));
private final SliderSetting rotationSpeed =
new SliderSetting("Rotation Speed", 600, 10, 3600, 10,
ValueDisplay.DEGREES.withSuffix("/s"));
@ -122,6 +133,7 @@ public final class KillauraLegitHack extends Hack
addSetting(range);
addSetting(speed);
addSetting(speedRandMS);
addSetting(rotationSpeed);
addSetting(priority);
addSetting(fov);
@ -145,8 +157,10 @@ public final class KillauraLegitHack extends Hack
WURST.getHax().triggerBotHack.setEnabled(false);
WURST.getHax().tpAuraHack.setEnabled(false);
speed.resetTimer();
speed.resetTimer(speedRandMS.getValue());
EVENTS.add(UpdateListener.class, this);
EVENTS.add(HandleInputListener.class, this);
EVENTS.add(MouseUpdateListener.class, this);
EVENTS.add(RenderListener.class, this);
}
@ -154,6 +168,8 @@ public final class KillauraLegitHack extends Hack
protected void onDisable()
{
EVENTS.remove(UpdateListener.class, this);
EVENTS.remove(HandleInputListener.class, this);
EVENTS.remove(MouseUpdateListener.class, this);
EVENTS.remove(RenderListener.class, this);
target = null;
}
@ -161,16 +177,14 @@ public final class KillauraLegitHack extends Hack
@Override
public void onUpdate()
{
speed.updateTimer();
if(!speed.isTimeToAttack())
return;
target = null;
// don't attack when a container/inventory screen is open
if(MC.currentScreen instanceof HandledScreen)
return;
Stream<Entity> stream = EntityUtils.getAttackableEntities();
double rangeSq = Math.pow(range.getValue(), 2);
double rangeSq = range.getValueSq();
stream = stream.filter(e -> MC.player.squaredDistanceTo(e) <= rangeSq);
if(fov.getValue() < 360.0)
@ -183,8 +197,6 @@ public final class KillauraLegitHack extends Hack
if(target == null)
return;
WURST.getHax().autoSwordHack.setSlot(target);
// check line of sight
if(!BlockUtils.hasLineOfSight(target.getBoundingBox().getCenter()))
{
@ -193,14 +205,29 @@ public final class KillauraLegitHack extends Hack
}
// face entity
if(!faceEntityClient(target))
WURST.getHax().autoSwordHack.setSlot(target);
faceEntityClient(target);
}
@Override
public void onHandleInput()
{
if(target == null)
return;
speed.updateTimer();
if(!speed.isTimeToAttack())
return;
if(!RotationUtils.isFacingBox(target.getBoundingBox(),
range.getValue()))
return;
// attack entity
WURST.getHax().criticalsHack.doCritical();
MC.interactionManager.attackEntity(MC.player, target);
swingHand.swing(Hand.MAIN_HAND);
speed.resetTimer();
speed.resetTimer(speedRandMS.getValue());
}
private boolean faceEntityClient(Entity entity)
@ -224,17 +251,24 @@ public final class KillauraLegitHack extends Hack
}
@Override
public void onRender(MatrixStack matrixStack, float partialTicks)
public void onMouseUpdate(MouseUpdateEvent event)
{
if(target == null)
if(target == null || MC.player == null)
return;
float oldYaw = MC.player.prevYaw;
float oldPitch = MC.player.prevPitch;
MC.player.setYaw(MathHelper.lerp(partialTicks, oldYaw, nextYaw));
MC.player.setPitch(MathHelper.lerp(partialTicks, oldPitch, nextPitch));
int diffYaw = (int)(nextYaw - MC.player.getYaw());
int diffPitch = (int)(nextPitch - MC.player.getPitch());
if(MathHelper.abs(diffYaw) < 1 && MathHelper.abs(diffPitch) < 1)
return;
if(!damageIndicator.isChecked())
event.setDeltaX(event.getDefaultDeltaX() + diffYaw);
event.setDeltaY(event.getDefaultDeltaY() + diffPitch);
}
@Override
public void onRender(MatrixStack matrixStack, float partialTicks)
{
if(target == null || !damageIndicator.isChecked())
return;
// GL settings

View File

@ -25,6 +25,7 @@ import net.wurstclient.mixinterface.IClientPlayerInteractionManager;
import net.wurstclient.settings.ItemListSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
import net.wurstclient.util.InventoryUtils;
@SearchTags({"AutoRestock", "auto-restock", "auto restock"})
public final class RestockHack extends Hack implements UpdateListener
@ -50,8 +51,9 @@ public final class RestockHack extends Hack implements UpdateListener
private final SliderSetting repairMode = new SliderSetting(
"Tools repair mode",
"Swaps out tools when their durability reaches the given threshold, so you can repair them before they break.\n"
+ "Can be adjusted from 0 (off) to 100.",
"Swaps out tools when their durability reaches the given threshold, so"
+ " you can repair them before they break.\n"
+ "Can be adjusted from 0 (off) to 100 remaining uses.",
0, 0, 100, 1, ValueDisplay.INTEGER.withLabel(0, "off"));
public RestockHack()
@ -106,10 +108,10 @@ public final class RestockHack extends Hack implements UpdateListener
searchSlotsWithItem(itemName, hotbarSlot);
for(int itemIndex : searchResult)
{
int pickupIndex = dataSlotToNetworkSlot(itemIndex);
int pickupIndex = InventoryUtils.toNetworkSlot(itemIndex);
im.windowClick_PICKUP(pickupIndex);
im.windowClick_PICKUP(dataSlotToNetworkSlot(hotbarSlot));
im.windowClick_PICKUP(InventoryUtils.toNetworkSlot(hotbarSlot));
if(!MC.player.playerScreenHandler.getCursorStack().isEmpty())
im.windowClick_PICKUP(pickupIndex);
@ -135,7 +137,7 @@ public final class RestockHack extends Hack implements UpdateListener
if(stack.isEmpty() || !stack.isDamageable())
{
IMC.getInteractionManager().windowClick_SWAP(i,
dataSlotToNetworkSlot(hotbarSlot));
InventoryUtils.toNetworkSlot(hotbarSlot));
break;
}
}
@ -147,22 +149,6 @@ public final class RestockHack extends Hack implements UpdateListener
.getValueI();
}
private int dataSlotToNetworkSlot(int index)
{
// hotbar
if(index >= 0 && index <= 8)
return index + 36;
// main inventory
if(index >= 9 && index <= 35)
return index;
if(index == OFFHAND_ID)
return OFFHAND_PKT_ID;
throw new IllegalArgumentException("unimplemented data slot");
}
private List<Integer> searchSlotsWithItem(String itemName, int slotToSkip)
{
List<Integer> slots = new ArrayList<>();

View File

@ -14,7 +14,7 @@ import net.minecraft.util.Hand;
import net.minecraft.util.hit.EntityHitResult;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.events.PostMotionListener;
import net.wurstclient.events.HandleInputListener;
import net.wurstclient.events.PreMotionListener;
import net.wurstclient.hack.Hack;
import net.wurstclient.mixinterface.IKeyBinding;
@ -30,7 +30,7 @@ import net.wurstclient.util.EntityUtils;
@SearchTags({"trigger bot", "AutoAttack", "auto attack", "AutoClicker",
"auto clicker"})
public final class TriggerBotHack extends Hack
implements PreMotionListener, PostMotionListener
implements PreMotionListener, HandleInputListener
{
private final SliderSetting range =
new SliderSetting("Range", 4.25, 1, 6, 0.05, ValueDisplay.DECIMAL);
@ -38,6 +38,15 @@ public final class TriggerBotHack extends Hack
private final AttackSpeedSliderSetting speed =
new AttackSpeedSliderSetting();
private final SliderSetting speedRandMS =
new SliderSetting("Speed randomization",
"Helps you bypass anti-cheat plugins by varying the delay between"
+ " attacks.\n\n" + "\u00b1100ms is recommended for Vulcan.\n\n"
+ "0 (off) is fine for NoCheat+, AAC, Grim, Verus, Spartan, and"
+ " vanilla servers.",
100, 0, 1000, 50, ValueDisplay.INTEGER.withPrefix("\u00b1")
.withSuffix("ms").withLabel(0, "off"));
private final SwingHandSetting swingHand = new SwingHandSetting(
"How TriggerBot should swing your hand when attacking.\n\n"
+ "This setting will be ignored if \"Simulate mouse click\" is"
@ -75,6 +84,7 @@ public final class TriggerBotHack extends Hack
addSetting(range);
addSetting(speed);
addSetting(speedRandMS);
addSetting(swingHand);
addSetting(attackWhileBlocking);
addSetting(simulateMouseClick);
@ -95,9 +105,9 @@ public final class TriggerBotHack extends Hack
WURST.getHax().protectHack.setEnabled(false);
WURST.getHax().tpAuraHack.setEnabled(false);
speed.resetTimer();
speed.resetTimer(speedRandMS.getValue());
EVENTS.add(PreMotionListener.class, this);
EVENTS.add(PostMotionListener.class, this);
EVENTS.add(HandleInputListener.class, this);
}
@Override
@ -110,7 +120,7 @@ public final class TriggerBotHack extends Hack
}
EVENTS.remove(PreMotionListener.class, this);
EVENTS.remove(PostMotionListener.class, this);
EVENTS.remove(HandleInputListener.class, this);
}
@Override
@ -124,7 +134,7 @@ public final class TriggerBotHack extends Hack
}
@Override
public void onPostMotion()
public void onHandleInput()
{
speed.updateTimer();
if(!speed.isTimeToAttack())
@ -160,7 +170,7 @@ public final class TriggerBotHack extends Hack
swingHand.swing(Hand.MAIN_HAND);
}
speed.resetTimer();
speed.resetTimer(speedRandMS.getValue());
}
private boolean isCorrectEntity(Entity entity)

View File

@ -122,7 +122,7 @@ public final class AutoFishRodSelector
}
// check if selected rod is still the best one
if(MC.player.getInventory().selectedSlot == bestRodSlot)
if(selectedSlot == bestRodSlot)
return true;
// change selected rod and wait until the next tick

View File

@ -10,6 +10,7 @@ package net.wurstclient.mixin;
import org.joml.Matrix4f;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -35,6 +36,7 @@ import net.wurstclient.hacks.FullbrightHack;
@Mixin(GameRenderer.class)
public abstract class GameRendererMixin implements AutoCloseable
{
@Unique
private boolean cancelNextBobView;
/**

View File

@ -34,6 +34,7 @@ import net.minecraft.util.hit.HitResult;
import net.minecraft.util.thread.ReentrantThreadExecutor;
import net.wurstclient.WurstClient;
import net.wurstclient.event.EventManager;
import net.wurstclient.events.HandleInputListener.HandleInputEvent;
import net.wurstclient.events.LeftClickListener.LeftClickEvent;
import net.wurstclient.events.RightClickListener.RightClickEvent;
import net.wurstclient.mixinterface.IClientPlayerEntity;
@ -64,6 +65,12 @@ public abstract class MinecraftClientMixin
super(name);
}
@Inject(at = @At("HEAD"), method = "handleInputEvents()V")
private void onHandleInputEvents(CallbackInfo ci)
{
EventManager.fire(HandleInputEvent.INSTANCE);
}
@Inject(at = @At(value = "FIELD",
target = "Lnet/minecraft/client/MinecraftClient;crosshairTarget:Lnet/minecraft/util/hit/HitResult;",
ordinal = 0), method = "doAttack()Z", cancellable = true)

View File

@ -8,6 +8,7 @@
package net.wurstclient.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -15,14 +16,30 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.Mouse;
import net.wurstclient.event.EventManager;
import net.wurstclient.events.MouseScrollListener.MouseScrollEvent;
import net.wurstclient.events.MouseUpdateListener.MouseUpdateEvent;
@Mixin(Mouse.class)
public class MouseMixin
{
@Shadow
private double cursorDeltaX;
@Shadow
private double cursorDeltaY;
@Inject(at = @At("RETURN"), method = "onMouseScroll(JDD)V")
private void onOnMouseScroll(long window, double horizontal,
double vertical, CallbackInfo ci)
{
EventManager.fire(new MouseScrollEvent(vertical));
}
@Inject(at = @At("HEAD"), method = "tick()V")
private void onTick(CallbackInfo ci)
{
MouseUpdateEvent event =
new MouseUpdateEvent(cursorDeltaX, cursorDeltaY);
EventManager.fire(event);
cursorDeltaX = event.getDeltaX();
cursorDeltaY = event.getDeltaY();
}
}

View File

@ -14,6 +14,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@ -31,7 +32,10 @@ import net.wurstclient.util.json.WsonObject;
@Mixin(PlayerSkinProvider.class)
public abstract class PlayerSkinProviderMixin
{
@Unique
private static HashMap<String, String> capes;
@Unique
private MinecraftProfileTexture currentCape;
@Inject(at = @At("HEAD"),
@ -79,19 +83,21 @@ public abstract class PlayerSkinProviderMixin
return result;
}
@Unique
private void setupWurstCapes()
{
try
{
// assign map first to prevent endless retries if download fails
capes = new HashMap<>();
Pattern uuidPattern = Pattern.compile(
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
// download cape list from wurstclient.net
WsonObject rawCapes = JsonUtils.parseURLToObject(
"https://www.wurstclient.net/api/v1/capes.json");
Pattern uuidPattern = Pattern.compile(
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
// convert names to offline UUIDs
capes = new HashMap<>();
for(Entry<String, String> entry : rawCapes.getAllStrings()
.entrySet())
{

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.settings;
import java.util.function.Function;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.wurstclient.util.RotationUtils;
public final class AimAtSetting extends EnumSetting<AimAtSetting.AimAt>
{
private static final String FULL_DESCRIPTION_SUFFIX =
buildDescriptionSuffix();
private AimAtSetting(String name, String description, AimAt[] values,
AimAt selected)
{
super(name, description, values, selected);
}
public AimAtSetting(String name, String description, AimAt selected)
{
this(name, description + FULL_DESCRIPTION_SUFFIX, AimAt.values(),
selected);
}
public AimAtSetting(String description, AimAt selected)
{
this("Aim at", description, selected);
}
public AimAtSetting(String description)
{
this(description, AimAt.AUTO);
}
public Vec3d getAimPoint(Entity e)
{
return getSelected().aimFunction.apply(e);
}
private static String buildDescriptionSuffix()
{
StringBuilder builder = new StringBuilder("\n\n");
AimAt[] values = AimAt.values();
for(AimAt value : values)
builder.append("\u00a7l").append(value.name).append("\u00a7r - ")
.append(value.description).append("\n\n");
return builder.toString();
}
private static Vec3d aimAtClosestPoint(Entity e)
{
Box box = e.getBoundingBox();
Vec3d eyes = RotationUtils.getEyesPos();
if(box.contains(eyes))
return eyes;
double clampedX = MathHelper.clamp(eyes.x, box.minX, box.maxX);
double clampedY = MathHelper.clamp(eyes.y, box.minY, box.maxY);
double clampedZ = MathHelper.clamp(eyes.z, box.minZ, box.maxZ);
return new Vec3d(clampedX, clampedY, clampedZ);
}
private static Vec3d aimAtHead(Entity e)
{
float eyeHeight = e.getEyeHeight(e.getPose());
return e.getPos().add(0, eyeHeight, 0);
}
private static Vec3d aimAtCenter(Entity e)
{
return e.getBoundingBox().getCenter();
}
private static Vec3d aimAtFeet(Entity e)
{
return e.getPos().add(0, 0.001, 0);
}
public enum AimAt
{
AUTO("Auto", "Aims at the closest point of the target's hitbox.",
AimAtSetting::aimAtClosestPoint),
HEAD("Head", "Aims at the target's eye position.",
AimAtSetting::aimAtHead),
CENTER("Center", "Aims at the center of the target's hitbox.",
AimAtSetting::aimAtCenter),
FEET("Feet", "Aims at the bottom of the target's hitbox.",
AimAtSetting::aimAtFeet);
private final String name;
private final String description;
private final Function<Entity, Vec3d> aimFunction;
private AimAt(String name, String description,
Function<Entity, Vec3d> aimFunction)
{
this.name = name;
this.description = description;
this.aimFunction = aimFunction;
}
public Vec3d getAimPoint(Entity e)
{
return aimFunction.apply(e);
}
@Override
public String toString()
{
return name;
}
}
}

View File

@ -7,10 +7,12 @@
*/
package net.wurstclient.settings;
import net.minecraft.util.math.random.Random;
import net.wurstclient.WurstClient;
public final class AttackSpeedSliderSetting extends SliderSetting
{
private final Random random = Random.createLocal();
private int tickTimer;
public AttackSpeedSliderSetting()
@ -35,19 +37,43 @@ public final class AttackSpeedSliderSetting extends SliderSetting
public void resetTimer()
{
tickTimer = 0;
double value = getValue();
if(value <= 0)
tickTimer = -1;
else
tickTimer = (int)(1000 / value);
}
public void resetTimer(double maxRandMS)
{
if(maxRandMS <= 0)
{
resetTimer();
return;
}
double value = getValue();
double rand = random.nextGaussian();
int randOffset = (int)(rand * maxRandMS);
if(value <= 0)
tickTimer = randOffset;
else
tickTimer = (int)(1000 / value) + randOffset;
}
public void updateTimer()
{
tickTimer += 50;
if(tickTimer >= 0)
tickTimer -= 50;
}
public boolean isTimeToAttack()
{
if(getValue() > 0)
return tickTimer >= 1000 / getValue();
double value = getValue();
if(value <= 0 && WurstClient.MC.player.getAttackCooldownProgress(0) < 1)
return false;
return WurstClient.MC.player.getAttackCooldownProgress(0) >= 1;
return tickTimer <= 0;
}
}

View File

@ -303,8 +303,10 @@ public class SliderSetting extends Setting implements SliderLock
{
public static final ValueDisplay INTEGER = v -> (int)v + "";
public static final ValueDisplay DECIMAL =
v -> Math.round(v * 1e6) / 1e6 + "";
public static final ValueDisplay DECIMAL = v -> {
String s = Math.round(v * 1e6) / 1e6 + "";
return s.endsWith(".0") ? s.substring(0, s.length() - 2) : s;
};
public static final ValueDisplay PERCENTAGE =
v -> (int)(Math.round(v * 1e8) / 1e6) + "%";

View File

@ -112,6 +112,11 @@ public enum BlockUtils
return getState(pos).calcBlockBreakingDelta(MC.player, MC.world, pos);
}
public static boolean isUnbreakable(BlockPos pos)
{
return getBlock(pos).getHardness() < 0;
}
private static VoxelShape getOutlineShape(BlockPos pos)
{
return getState(pos).getOutlineShape(MC.world, pos);

View File

@ -67,6 +67,59 @@ public enum InventoryUtils
*/
public static int indexOf(Predicate<ItemStack> predicate, int maxInvSlot,
boolean includeOffhand)
{
return getMatchingSlots(predicate, maxInvSlot, includeOffhand)
.findFirst().orElse(-1);
}
public static int count(Item item)
{
return count(stack -> stack.isOf(item), 36, false);
}
public static int count(Item item, int maxInvSlot)
{
return count(stack -> stack.isOf(item), maxInvSlot, false);
}
public static int count(Item item, int maxInvSlot, boolean includeOffhand)
{
return count(stack -> stack.isOf(item), maxInvSlot, includeOffhand);
}
public static int count(Predicate<ItemStack> predicate)
{
return count(predicate, 36, false);
}
public static int count(Predicate<ItemStack> predicate, int maxInvSlot)
{
return count(predicate, maxInvSlot, false);
}
/**
* Counts the number of items in the player's inventory that match the given
* predicate, searching from slot 0 to {@code maxInvSlot-1}.
*
* @param predicate
* checks if an item should be counted
* @param maxInvSlot
* the maximum slot to search (exclusive), usually 9 for the
* hotbar or 36 for the whole inventory
* @param includeOffhand
* also search the offhand (slot 40), even if maxInvSlot is lower
* @return
* the number of matching items in the player's inventory
*/
public static int count(Predicate<ItemStack> predicate, int maxInvSlot,
boolean includeOffhand)
{
return (int)getMatchingSlots(predicate, maxInvSlot, includeOffhand)
.count();
}
private static IntStream getMatchingSlots(Predicate<ItemStack> predicate,
int maxInvSlot, boolean includeOffhand)
{
PlayerInventory inventory = MC.player.getInventory();
@ -75,11 +128,8 @@ public enum InventoryUtils
if(includeOffhand)
stream = IntStream.concat(stream, IntStream.of(40));
// find the slot of the item we want
int slot = stream.filter(i -> predicate.test(inventory.getStack(i)))
.findFirst().orElse(-1);
return slot;
// filter out the slots we don't want
return stream.filter(i -> predicate.test(inventory.getStack(i)));
}
public static boolean selectItem(Item item)
@ -172,7 +222,7 @@ public enum InventoryUtils
return true;
}
private static int toNetworkSlot(int slot)
public static int toNetworkSlot(int slot)
{
// hotbar
if(slot >= 0 && slot < 9)

View File

@ -1,9 +1,11 @@
{
"description.wurst.hack.aimassist": "帮助您瞄准附近的实体。",
"description.wurst.hack.airplace": "允许您在空中放置方块。",
"description.wurst.hack.anchoraura": "自动放置(可选),充能,引爆重生锚并击杀你附近的实体。",
"description.wurst.hack.antiafk": "随机走动,用于避免服务器挂机检测。",
"description.wurst.hack.antiblind": "防止失明和黑暗效果。\n与 OptiFine 不兼容。",
"description.wurst.hack.anticactus": "保护你免受仙人掌伤害。",
"description.wurst.hack.antientitypush": "保护你不会被玩家和其他生物推挤。",
"description.wurst.hack.antihunger": "在你走路时减缓你的饥饿状态。",
"description.wurst.hack.antiknockback": "保护你不被其他生物或玩家推动和用剑击退。",
"description.wurst.hack.antispam": "将重复的刷屏改为计数器显示。",
@ -14,8 +16,10 @@
"description.wurst.setting.arrowdmg.trident_yeet_mode": "打开之后,三叉戟将飞得更远。似乎不影响伤害以及“激流”魔咒。\n\n§c§l警告§r打开这个选项之后你很容易弄丢你的三叉戟",
"description.wurst.hack.autoarmor": "自动管理你的盔甲。",
"description.wurst.hack.autobuild": "自动建筑东西。\n放一个方块就开始自动建造。",
"description.wurst.hack.autocomplete": "使用大型语言模型自动完成您的聊天消息。 需要具有 API 访问权限的 OpenAI 帐户或与 OpenAI 兼容的任何其他语言模型 API。",
"description.wurst.hack.autodrop": "自动丢弃你不想要的物品(可以预设)。",
"description.wurst.hack.autoleave": "血量过低时自动离开服务器。",
"description.wurst.hack.autolibrarian": "自动训练村民成为图书管理员,出售特定的附魔书。 通过这个技术,您可以立即建立一个完整的村民交易所。",
"description.wurst.hack.autoeat": "当必要的时候将会自动进食(可以预设)。",
"description.wurst.setting.autoeat.target_hunger": "在不浪费任何饥饿值的前提下,尝试将饥饿条保持在此水准之上。",
"description.wurst.setting.autoeat.min_hunger": "即便浪费一些补充的饥饿值,也总是将饥饿条保持在此水准之上。\n6.5 - 不会导致任何原版食物所补充饥饿值的浪费。\n10.0 - 完全忽视饥饿值的浪费,总是将饥饿条补满。",
@ -42,6 +46,7 @@
"description.wurst.hack.autotool": "破坏方块时自动切换成快捷栏中最优的破坏工具。",
"description.wurst.hack.autototem": "自动将不死图腾移动到副手上。",
"description.wurst.hack.autowalk": "使你自动走路而无需按住W键。",
"description.wurst.hack.barrieresp": "允许你看到附近的屏障方块。",
"description.wurst.hack.basefinder": "通过寻找人为建造的方块来寻找玩家的基地。\n假如方块被找到将以所选的颜色高亮。\n建议用于寻找帮派基地。",
"description.wurst.hack.blink": "暂停所有动作更新,并在关闭时继续。",
"description.wurst.hack.boatfly": "允许你使用船只和其他载具飞行。\n按冲刺键可以更快地下降。",
@ -110,10 +115,12 @@
"description.wurst.hack.nocomcrash": "利用 Nocom 漏洞使服务器卡顿或崩溃。\n经测试可在 Vanilla、Spigot 和 Fabric 上工作Paper 和一些拥有特定反作弊的服务器无法使用。",
"description.wurst.hack.nofall": "使你免受摔落伤害。",
"description.wurst.hack.nofireoverlay": "关闭第一人称视角下着火时的火焰贴图。\n\n§c§l警告§r这可能会导致你因不知道身上有火而烧伤致死。",
"description.wurst.hack.nofog": "移除世界天边交界处的迷雾。",
"description.wurst.hack.nohurtcam": "关闭因受伤而产生视野摇晃效果。",
"description.wurst.hack.nolevitation": "禁用被潜影贝击中时获得的漂浮效果。\n\n§c§l警告:§r 如果您已经处于漂浮状态下,启用此功能将会使您从高空坠落!",
"description.wurst.hack.nooverlay": "关闭因在水或岩浆中的视野阻挡。",
"description.wurst.hack.nopumpkin": "关闭南瓜头的视野阻挡。",
"description.wurst.hack.noshieldoverlay": "降低盾牌使其覆盖更少的屏幕。",
"description.wurst.hack.noslowdown": "取消在蜂蜜、灵魂沙上或使用物品时产生的减速效果。",
"description.wurst.hack.noweather": "允许你更改本地客户端的天气,时间和月相(仅在本地生效,与服务器无关)。",
"description.wurst.hack.noweb": "使你不会因为蜘蛛网而减速。",
@ -124,6 +131,7 @@
"description.wurst.hack.panic": "瞬间关闭所有的作弊功能。\n请小心使用",
"description.wurst.hack.parkour": "当你到达方块边缘时自动跳起。\n适用于跑酷或部分需要跑跳的场景。",
"description.wurst.hack.playeresp": "高亮透视附近的玩家。\n你的好友会显示蓝色框框。",
"description.wurst.hack.portalesp": "高亮附近的传送门。",
"description.wurst.hack.portalgui": "允许你在传送门内打开 GUI。",
"description.wurst.hack.potionsaver": "当你站着不动时冻结所有的药水效果时间。",
"description.wurst.hack.prophuntesp": "在躲猫猫小游戏中知道哪些是人扮的方块。\n用于 Mineplex 服务器的 Prophunt躲猫猫其他服务器未必奏效。",
@ -173,7 +181,7 @@
"gui.wurst.altmanager.folder_error.title": "无法创建 “.Wurst encryption” 文件夹!",
"gui.wurst.altmanager.folder_error.message": "你也许不小心禁止了 Wurst 访问这个目录,\n因此 AltManager 无法加解密你的备用账户列表。\n你仍然可以使用 AltManager但你新建的备用账户将不会被保存。\n\n完整错误信息如下\n%s",
"gui.wurst.altmanager.empty.title": "你的备用账户列表为空。",
"gui.wurst.altmanager.empty.message": "你希望 Wurst 生成一些離線帳戶嗎",
"gui.wurst.altmanager.empty.message": "你希望 Wurst 生成一些离线账户吗",
"gui.wurst.nochatreports.unsafe_server.title": "§4§l警告:§r 不安全的服务器",
"gui.wurst.nochatreports.unsafe_server.message": "此伺服器需要启用聊天签名,这会使您的帐户面临欺诈性聊天报告的风险。\n\n如果您取消阻止聊天签名然后重新连接则可以加入此服务器。如果这样做请考虑根本不使用聊天。或者使用您不介意丢失的替代帐户进行游戏。\n\n如果这是您的伺服器您可以通过在 server.properties 中将“enforce-secure-profile”设置为 false 来解决此问题。在典型的 Mojang 方法中,这种设置与听起来相反。",
"toast.wurst.nochatreports.unsafe_server.title": "聊天消息可以被报告",
@ -185,4 +193,4 @@
"gui.wurst.generic.allcaps_blocked": "黑名单",
"gui.wurst.generic.allcaps_allowed": "已允许",
"key.wurst.zoom": "缩放"
}
}