diff --git a/src/main/java/net/wurstclient/hack/HackList.java b/src/main/java/net/wurstclient/hack/HackList.java index 0d879026..d0ac6d95 100644 --- a/src/main/java/net/wurstclient/hack/HackList.java +++ b/src/main/java/net/wurstclient/hack/HackList.java @@ -109,7 +109,7 @@ public final class HackList implements UpdateListener public final NoWeatherHack noWeatherHack = new NoWeatherHack(); public final NoWebHack noWebHack = new NoWebHack(); public final NukerHack nukerHack = new NukerHack(); - // public final NukerLegitHack nukerLegitHack = new NukerLegitHack(); + public final NukerLegitHack nukerLegitHack = new NukerLegitHack(); public final OverlayHack overlayHack = new OverlayHack(); public final PanicHack panicHack = new PanicHack(); public final ParkourHack parkourHack = new ParkourHack(); diff --git a/src/main/java/net/wurstclient/hacks/NukerHack.java b/src/main/java/net/wurstclient/hacks/NukerHack.java index d0389305..6890f630 100644 --- a/src/main/java/net/wurstclient/hacks/NukerHack.java +++ b/src/main/java/net/wurstclient/hacks/NukerHack.java @@ -240,6 +240,16 @@ public final class NukerHack extends Hack GL11.glDisable(GL11.GL_LINE_SMOOTH); } + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + private enum Mode { NORMAL("Normal", n -> n.getName(), (n, p) -> true), diff --git a/src/main/java/net/wurstclient/hacks/NukerLegitHack.java b/src/main/java/net/wurstclient/hacks/NukerLegitHack.java new file mode 100644 index 00000000..23e93714 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/NukerLegitHack.java @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2014 - 2020 | Alexander01998 | All rights reserved. + * + * 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.hacks; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.lwjgl.opengl.GL11; + +import net.minecraft.block.Material; +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.minecraft.util.math.Vec3d; +import net.minecraft.world.RayTraceContext; +import net.wurstclient.Category; +import net.wurstclient.SearchTags; +import net.wurstclient.events.LeftClickListener; +import net.wurstclient.events.RenderListener; +import net.wurstclient.events.UpdateListener; +import net.wurstclient.hack.Hack; +import net.wurstclient.settings.EnumSetting; +import net.wurstclient.settings.SliderSetting; +import net.wurstclient.settings.SliderSetting.ValueDisplay; +import net.wurstclient.util.BlockUtils; +import net.wurstclient.util.RenderUtils; +import net.wurstclient.util.RotationUtils; + +@SearchTags({"LegitNuker", "nuker legit", "legit nuker"}) +public final class NukerLegitHack extends Hack + implements LeftClickListener, RenderListener, UpdateListener +{ + private final SliderSetting range = + new SliderSetting("Range", 4.25, 1, 4.25, 0.05, ValueDisplay.DECIMAL); + + private final EnumSetting mode = new EnumSetting<>("Mode", + "\u00a7lNormal\u00a7r mode simply breaks everything\n" + "around you.\n" + + "\u00a7lID\u00a7r mode only breaks the selected block\n" + + "type. Left-click on a block to select it.\n" + + "\u00a7lFlat\u00a7r mode flattens the area around you,\n" + + "but won't dig down.\n" + + "\u00a7lSmash\u00a7r mode only breaks blocks that\n" + + "can be destroyed instantly (e.g. tall grass).", + Mode.values(), Mode.NORMAL); + + private BlockPos currentBlock; + + public NukerLegitHack() + { + super("NukerLegit", + "Slower Nuker that bypasses all AntiCheat plugins.\n" + + "Not required on normal NoCheat+ servers!"); + + setCategory(Category.BLOCKS); + addSetting(range); + addSetting(mode); + } + + @Override + public String getRenderName() + { + return mode.getSelected().getRenderName(WURST.getHax().nukerHack); + } + + @Override + public void onEnable() + { + // disable other nukers + WURST.getHax().nukerHack.setEnabled(false); + // WURST.getHax().speedNukerHack.setEnabled(false); + WURST.getHax().tunnellerHack.setEnabled(false); + + // add listeners + EVENTS.add(LeftClickListener.class, this); + EVENTS.add(UpdateListener.class, this); + EVENTS.add(RenderListener.class, this); + } + + @Override + public void onDisable() + { + // remove listeners + EVENTS.remove(LeftClickListener.class, this); + EVENTS.remove(UpdateListener.class, this); + EVENTS.remove(RenderListener.class, this); + + // resets + MC.options.keyAttack.setPressed(false); + currentBlock = null; + WURST.getHax().nukerHack.setId(null); + } + + @Override + public void onLeftClick(LeftClickEvent event) + { + // check hitResult + if(MC.crosshairTarget == null + || !(MC.crosshairTarget instanceof BlockHitResult)) + return; + + // check pos + BlockPos pos = ((BlockHitResult)MC.crosshairTarget).getBlockPos(); + if(pos == null + || BlockUtils.getState(pos).getMaterial() == Material.AIR) + return; + + // check mode + if(mode.getSelected() != Mode.ID) + return; + + // set id + WURST.getHax().nukerHack.setId(BlockUtils.getName(pos)); + } + + @Override + public void onUpdate() + { + // abort if using IDNuker without an ID being set + if(mode.getSelected() == Mode.ID + && WURST.getHax().nukerHack.getId() == null) + return; + + currentBlock = null; + + // get valid blocks + Iterable validBlocks = getValidBlocks(range.getValue(), + mode.getSelected().getValidator(WURST.getHax().nukerHack)); + + // find closest valid block + for(BlockPos pos : validBlocks) + { + // break block + if(!breakBlockExtraLegit(pos)) + continue; + + // set currentBlock if successful + currentBlock = pos; + break; + } + + // reset if no block was found + if(currentBlock == null) + MC.options.keyAttack.setPressed(false); + } + + private ArrayList getValidBlocks(double range, + Predicate validator) + { + 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); + + BlockPos center = new BlockPos(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(new Vec3d(pos)) <= rangeSq) + .filter(validator) + .sorted(Comparator.comparingDouble( + pos -> eyesVec.squaredDistanceTo(new Vec3d(pos)))) + .collect(Collectors.toCollection(() -> new ArrayList<>())); + } + + private boolean breakBlockExtraLegit(BlockPos pos) + { + Vec3d eyesPos = RotationUtils.getEyesPos(); + Vec3d posVec = new Vec3d(pos).add(0.5, 0.5, 0.5); + double distanceSqPosVec = eyesPos.squaredDistanceTo(posVec); + + for(Direction side : Direction.values()) + { + Vec3d hitVec = + posVec.add(new Vec3d(side.getVector()).multiply(0.5)); + double distanceSqHitVec = eyesPos.squaredDistanceTo(hitVec); + + // check if hitVec is within range (4.25 blocks) + if(distanceSqHitVec > 18.0625) + continue; + + // check if side is facing towards player + if(distanceSqHitVec >= distanceSqPosVec) + continue; + + // check line of sight + if(MC.world + .rayTrace(new RayTraceContext(eyesPos, hitVec, + RayTraceContext.ShapeType.COLLIDER, + RayTraceContext.FluidHandling.NONE, MC.player)) + .getType() != HitResult.Type.MISS) + continue; + + // face block + WURST.getRotationFaker().faceVectorClient(hitVec); + + // if attack key is down but nothing happens, release it for one + // tick + if(MC.options.keyAttack.isPressed() + && !MC.interactionManager.isBreakingBlock()) + { + MC.options.keyAttack.setPressed(false); + return true; + } + + // damage block + MC.options.keyAttack.setPressed(true); + + return true; + } + + return false; + } + + @Override + public void onRender(float partialTicks) + { + if(currentBlock == null) + return; + + // GL settings + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glEnable(GL11.GL_LINE_SMOOTH); + GL11.glLineWidth(2); + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_DEPTH_TEST); + + GL11.glPushMatrix(); + RenderUtils.applyRenderOffset(); + + // set position + GL11.glTranslated(currentBlock.getX(), currentBlock.getY(), + currentBlock.getZ()); + + // get progress + float progress; + if(BlockUtils.getHardness(currentBlock) < 1) + progress = IMC.getInteractionManager().getCurrentBreakingProgress(); + else + progress = 1; + + // set size + if(progress < 1) + { + GL11.glTranslated(0.5, 0.5, 0.5); + GL11.glScaled(progress, progress, progress); + GL11.glTranslated(-0.5, -0.5, -0.5); + } + + // get color + float red = progress * 2F; + float green = 2 - red; + + // draw box + GL11.glColor4f(red, green, 0, 0.25F); + RenderUtils.drawSolidBox(); + GL11.glColor4f(red, green, 0, 0.5F); + RenderUtils.drawOutlinedBox(); + + GL11.glPopMatrix(); + + // GL resets + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LINE_SMOOTH); + } + + private enum Mode + { + NORMAL("Normal", n -> "NukerLegit", (n, p) -> true), + + ID("ID", n -> "IDNukerLegit [" + n.getId() + "]", + (n, p) -> BlockUtils.getName(p).equals(n.getId())), + + FLAT("Flat", n -> "FlatNukerLegit", + (n, p) -> p.getY() >= MC.player.getPos().getY()), + + SMASH("Smash", n -> "SmashNukerLegit", + (n, p) -> BlockUtils.getHardness(p) >= 1); + + private final String name; + private final Function renderName; + private final BiPredicate validator; + + private Mode(String name, Function renderName, + BiPredicate validator) + { + this.name = name; + this.renderName = renderName; + this.validator = validator; + } + + @Override + public String toString() + { + return name; + } + + public String getRenderName(NukerHack n) + { + return renderName.apply(n); + } + + public Predicate getValidator(NukerHack n) + { + return p -> validator.test(n, p); + } + } +}