From b06dc685d486bed1c3758fe8122e499147373ea8 Mon Sep 17 00:00:00 2001 From: Jerry <isjerryxiao@outlook.com> Date: Wed, 26 Jan 2022 19:40:34 +0800 Subject: [PATCH] new hack: AutoMLGHack (refined) --- .../java/net/wurstclient/hack/HackList.java | 1 + .../net/wurstclient/hacks/AutoEatHack.java | 7 + .../net/wurstclient/hacks/AutoMLGHack.java | 228 ++++++++++++++++++ .../ClientPlayerInteractionManagerMixin.java | 6 + .../IClientPlayerInteractionManager.java | 2 + .../resources/assets/wurst/lang/en_us.json | 1 + .../resources/assets/wurst/lang/zh_cn.json | 1 + 7 files changed, 246 insertions(+) create mode 100644 src/main/java/net/wurstclient/hacks/AutoMLGHack.java diff --git a/src/main/java/net/wurstclient/hack/HackList.java b/src/main/java/net/wurstclient/hack/HackList.java index ab0b471e62..3bb2819695 100644 --- a/src/main/java/net/wurstclient/hack/HackList.java +++ b/src/main/java/net/wurstclient/hack/HackList.java @@ -44,6 +44,7 @@ public final class HackList implements UpdateListener public final AutoEatHack autoEatHack = new AutoEatHack(); public final AutoFarmHack autoFarmHack = new AutoFarmHack(); public final AutoFishHack autoFishHack = new AutoFishHack(); + public final AutoMLGHack autoMLGHack = new AutoMLGHack(); public final AutoMineHack autoMineHack = new AutoMineHack(); public final AutoPotionHack autoPotionHack = new AutoPotionHack(); public final AutoReconnectHack autoReconnectHack = new AutoReconnectHack(); diff --git a/src/main/java/net/wurstclient/hacks/AutoEatHack.java b/src/main/java/net/wurstclient/hacks/AutoEatHack.java index ffb4c68f30..4e6e41607e 100644 --- a/src/main/java/net/wurstclient/hacks/AutoEatHack.java +++ b/src/main/java/net/wurstclient/hacks/AutoEatHack.java @@ -64,6 +64,8 @@ public final class AutoEatHack extends Hack implements UpdateListener private int oldSlot = -1; + public int pauseEat = 0; + public AutoEatHack() { super("AutoEat"); @@ -166,6 +168,11 @@ private boolean isAllowedFood(FoodComponent food) private boolean shouldEat() { + if (pauseEat > 0) { + pauseEat--; + return false; + } + if(MC.player.getAbilities().creativeMode) return false; diff --git a/src/main/java/net/wurstclient/hacks/AutoMLGHack.java b/src/main/java/net/wurstclient/hacks/AutoMLGHack.java new file mode 100644 index 0000000000..318c51c88c --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/AutoMLGHack.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2014-2022 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.hacks; + +import com.google.common.collect.Lists; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.FluidBlock; +import net.minecraft.block.SeaPickleBlock; +import net.minecraft.block.SeagrassBlock; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; +import net.minecraft.util.Hand; +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.MathHelper; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.RaycastContext; +import net.wurstclient.Category; +import net.wurstclient.SearchTags; +import net.wurstclient.events.UpdateListener; +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; +import net.wurstclient.util.BlockUtils; +import net.wurstclient.util.RotationUtils; +import net.wurstclient.util.RotationUtils.Rotation; + +import java.util.Arrays; +import java.util.List; + +@SearchTags({ "mlg", "water", "mlg water", "mlg powder snow"}) +public final class AutoMLGHack extends Hack implements UpdateListener { + + private final SliderSetting minFall = new SliderSetting("Minimum fall", "Minimum fall distance", 3, 3, 15, 1, ValueDisplay.INTEGER); + private final CheckboxSetting anchor = new CheckboxSetting("Anchor", "Teleport you to the middle of a block", true); + private final CheckboxSetting doSneak = new CheckboxSetting("Do sneak", "Sneak to avoid interacting with the block underneath", false); + private final CheckboxSetting allowInv = new CheckboxSetting("Allow inventory", "Allow taking buckets out of your inventory", false); + private final CheckboxSetting snowFirst = new CheckboxSetting("Snow first", "Try powder snow first, which is less reliable", false); + private final CheckboxSetting checkElytra = new CheckboxSetting("Check elytra", "Disable the hack when flying with an elytra", false); + + private boolean placedWater = false; + + private boolean waterBucket = true; + private boolean offHand = false; + private int pickupRetry = 0; + + private BlockPos targetBlock = null; + private Vec2f lastRot = null; + private Vec3d lastPlayerPos = null; + private static final List<ItemStack> BUCKETS = Arrays.asList( + new ItemStack(Items.WATER_BUCKET), + new ItemStack(Items.POWDER_SNOW_BUCKET) + ); + + public AutoMLGHack() { + super("AutoMLG"); + setCategory(Category.MOVEMENT); + addSetting(minFall); + addSetting(anchor); + addSetting(doSneak); + addSetting(allowInv); + addSetting(snowFirst); + addSetting(checkElytra); + } + + @Override + public void onEnable() { + placedWater = false; + EVENTS.add(UpdateListener.class, this); + } + + @Override + public void onDisable() { + EVENTS.remove(UpdateListener.class, this); + } + + private boolean rightClickBlock(BlockPos pos, boolean pickup) { + Vec3d hitVec = Vec3d.ofCenter(pos).add(Vec3d.of(Direction.UP.getVector()).multiply(0.5)); + + Rotation rotation = RotationUtils.getNeededRotations(hitVec); + MC.player.setYaw(rotation.getYaw()); + MC.player.setPitch(rotation.getPitch()); + PlayerMoveC2SPacket.LookAndOnGround packet = new PlayerMoveC2SPacket.LookAndOnGround(rotation.getYaw(), + rotation.getPitch(), MC.player.isOnGround()); + MC.player.networkHandler.sendPacket(packet); + + if (!placedWater && !waterBucket) { + MC.interactionManager.interactBlock(MC.player, MC.world, offHand ? Hand.OFF_HAND : Hand.MAIN_HAND, + new BlockHitResult(new Vec3d(pos.getX() + 0.5, pos.getY() + 1.0, pos.getZ() + 0.5), Direction.UP, pos, false)); + } + else { + Vec3d eyesPos = new Vec3d(MC.player.getX(), MC.player.getY() + MC.player.getEyeHeight( + MC.player.getPose()), MC.player.getZ()); + // check if hitVec is within range (4.25 blocks) + if (eyesPos.squaredDistanceTo(hitVec) > 18.0625) + return false; + MC.interactionManager.interactItem(MC.player, MC.world, offHand ? Hand.OFF_HAND : Hand.MAIN_HAND); + } + return true; + } + + private void restoreRotation() { + if (lastRot == null) return; + MC.player.setPitch(lastRot.x); + MC.player.setYaw(lastRot.y); + lastRot = null; + } + + @Override + public void onUpdate() { + if (MC.player.getAbilities().creativeMode) return; + if (!placedWater) { + float minfallDistance = minFall.getValueF(); + if (MC.player.fallDistance > minfallDistance - 2.0f && !MC.player.hasStatusEffect(StatusEffects.SLOW_FALLING) + && !(checkElytra.isChecked() && MC.player.isFallFlying())) { + Vec3d playerPos = MC.player.getPos(); + if (lastPlayerPos == null) lastPlayerPos = playerPos; + if (playerPos.y - lastPlayerPos.y < 0.0D) { + WURST.getHax().autoEatHack.pauseEat = 20; + BlockHitResult result = MC.world.raycast(new RaycastContext(MC.player.getPos(), playerPos.subtract(0, 5, 0), RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, MC.player)); + BlockPos bp = result.getBlockPos(); + if (result != null && result.getType() == HitResult.Type.BLOCK + && Math.max(0.0, (float)playerPos.y - (float)(bp.getY())) - 1.3f + MC.player.fallDistance > minfallDistance + && causeFallDamage(BlockUtils.getState(result.getBlockPos())) + && causeFallDamage(BlockUtils.getState(result.getBlockPos().up())) + ) { + for (ItemStack bucket : (snowFirst.isChecked() ? Lists.reverse(BUCKETS) : BUCKETS)) { + if (MC.world.getDimension().isUltrawarm() && bucket.getItem().equals(Items.WATER_BUCKET)) + continue; + int location = takeStackOut(bucket); + if (location == 0) continue; + offHand = location < 0; + waterBucket = bucket.getItem().equals(Items.WATER_BUCKET); + if (anchor.isChecked()) { + double x = MathHelper.floor(MC.player.getX()) + 0.5; + double z = MathHelper.floor(MC.player.getZ()) + 0.5; + if ((Math.abs(MC.player.getX() - x) > 1e-5) || (Math.abs(MC.player.getZ() - z) > 1e-5)) { + MC.player.setPosition(x, MC.player.getY(), z); + MC.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(MC.player.getX(), MC.player.getY(), MC.player.getZ(), MC.player.isOnGround())); + } + MC.player.setVelocity(0, MC.player.getVelocity().y, 0); + } + if (lastRot == null) lastRot = MC.player.getRotationClient(); + if (rightClickBlock(bp, false)) { + placedWater = true; + targetBlock = bp; + pickupRetry = 0; + } + break; + } + } + } + lastPlayerPos = playerPos; + } + else { + lastRot = null; + } + } else { + if (MC.player.isOnGround() || MC.player.isTouchingWater() && IMC.getItemUseCooldown() < 1) { + int location = takeStackOut(new ItemStack(Items.BUCKET)); + if (location != 0) { + offHand = location < 0; + rightClickBlock(targetBlock, true); + if ((offHand ? MC.player.getOffHandStack() : MC.player.getInventory().getMainHandStack()).getItem().equals(Items.BUCKET)) { + pickupRetry++; + if (pickupRetry <= 10) { + return; + } + } + } + if (doSneak.isChecked()) { + IKeyBinding sneakKey = (IKeyBinding) MC.options.sneakKey; + ((KeyBinding) sneakKey).setPressed(sneakKey.isActallyPressed()); + } + restoreRotation(); + lastPlayerPos = null; + placedWater = false; + } + } + } + private boolean causeFallDamage(BlockState bs) { + if (bs.isAir()) return true; + Block block = bs.getBlock(); + if (block instanceof FluidBlock || block instanceof SeaPickleBlock || block instanceof SeagrassBlock) return false; + // todo slabs and more? + return true; + } + + private int takeStackOut(ItemStack stack) { + PlayerInventory inv = MC.player.getInventory(); + int slot = inv.getSlotWithStack(stack); + if (slot >= 0 && slot <= 8) { + // bucket in hotbar + inv.selectedSlot = slot; + return 1; + } + else if (slot >= 9 && slot <= 35) { + // bucket in inventory + if (allowInv.isChecked()) { + IMC.getInteractionManager().windowClick_SWAP(slot, inv.selectedSlot); + return 1; + } + } + else { + // no bucket in inventory + if (MC.player.getOffHandStack().isItemEqual(stack)) { + // use bucket in offhand + return -1; + } + } + return 0; + } +} diff --git a/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java b/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java index d41ca16bf7..fdc15bcf6f 100644 --- a/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java +++ b/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java @@ -121,6 +121,12 @@ public void windowClick_QUICK_MOVE(int slot) clickSlot(0, slot, 0, SlotActionType.QUICK_MOVE, client.player); } + @Override + public void windowClick_SWAP(int slot, int swapWith) + { + clickSlot(0, slot, swapWith, SlotActionType.SWAP, client.player); + } + @Override public void windowClick_THROW(int slot) { diff --git a/src/main/java/net/wurstclient/mixinterface/IClientPlayerInteractionManager.java b/src/main/java/net/wurstclient/mixinterface/IClientPlayerInteractionManager.java index 2767bf9c32..c44fa1898d 100644 --- a/src/main/java/net/wurstclient/mixinterface/IClientPlayerInteractionManager.java +++ b/src/main/java/net/wurstclient/mixinterface/IClientPlayerInteractionManager.java @@ -22,6 +22,8 @@ public interface IClientPlayerInteractionManager public void windowClick_QUICK_MOVE(int slot); + public void windowClick_SWAP(int slot, int swapWith); + public void windowClick_THROW(int slot); public void rightClickItem(); diff --git a/src/main/resources/assets/wurst/lang/en_us.json b/src/main/resources/assets/wurst/lang/en_us.json index d869013f8e..fe1a472bc5 100644 --- a/src/main/resources/assets/wurst/lang/en_us.json +++ b/src/main/resources/assets/wurst/lang/en_us.json @@ -17,6 +17,7 @@ "description.wurst.hack.autoeat": "Automatically eats food when necessary.", "description.wurst.hack.autofarm": "Harvests and replants crops automatically.\nWorks with wheat, carrots, potatoes, beetroots, pumpkins, melons, cacti, sugar canes, kelp, bamboo, nether warts, and cocoa beans.", "description.wurst.hack.autofish": "Automatically catches fish using your best fishing rod. If it finds a better rod while fishing, it will automatically switch to it.", + "description.wurst.hack.automlg": "Automatic MLG water bucket or powder snow.\n\n§lNote:§r The current implementation is not legit.", "description.wurst.hack.automine": "Automatically mines any block that you look at.", "description.wurst.hack.autopotion": "Automatically throws splash potions of instant health when your health is low.", "description.wurst.hack.autoreconnect": "Automatically reconnects when you get kicked from the server.", diff --git a/src/main/resources/assets/wurst/lang/zh_cn.json b/src/main/resources/assets/wurst/lang/zh_cn.json index dce0972cf0..f5e3946b1d 100644 --- a/src/main/resources/assets/wurst/lang/zh_cn.json +++ b/src/main/resources/assets/wurst/lang/zh_cn.json @@ -14,6 +14,7 @@ "description.wurst.hack.autoeat": "当必要的时候将会自动进食。", "description.wurst.hack.autofarm": "自动收获与种植农作物。\n有效作物为小麦、胡萝卜、马铃薯、甜菜根、南瓜、西瓜、仙人掌、甘蔗、海带、竹子、 地狱疣和可可豆。", "description.wurst.hack.autofish": "当你在钓鱼的时候,自动钓鱼同时使用你最好的鱼竿,如果有更好的鱼竿将会自动使用。", + "description.wurst.hack.automlg": "自动落地水,或落地细雪。\n\n§l注意:§r 当前实现并未考虑反作弊。", "description.wurst.hack.automine": "自动挖掘你眼前所指的方块。", "description.wurst.hack.autopotion": "当你的生命值过低时候,自动扔一瓶喷溅型瞬间恢复。", "description.wurst.hack.autoreconnect": "当你被服务器踢出时候,自动重连。",