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:
commit
0030020e20
24
build.gradle
24
build.gradle
@ -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")
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
|
40
src/main/java/net/wurstclient/ai/PlayerAbilities.java
Normal file
40
src/main/java/net/wurstclient/ai/PlayerAbilities.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<>();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
{
|
||||
|
130
src/main/java/net/wurstclient/settings/AimAtSetting.java
Normal file
130
src/main/java/net/wurstclient/settings/AimAtSetting.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) + "%";
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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": "缩放"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user