diff --git a/README.md b/README.md index 10645cfc..25544574 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,13 @@ Pull requests are welcome, but please make sure to read the [contributing guidel ## Translations -We have a [Crowdin project](https://crowdin.com/project/wurst7) for translations. You can also submit translations here on GitHub, but Crowdin is preferred since it makes it much easier to resolve issues. +The preferred way to submit translations is through a Pull Request here on GitHub. To enable translations in-game, go to Wurst Options > Translations > ON. Names of features (hacks/commands/etc.) should always be kept in English. This ensures that everyone can use the same commands, keybinds, etc. regardless of their language setting. It also makes it easier to communicate with someone who uses Wurst in a different language. -The translation files are located in [this folder](https://github.com/Wurst-Imperium/Wurst7/tree/master/src/main/resources/assets/wurst/lang), in case you need them. +The translation files are located in [this folder](https://github.com/Wurst-Imperium/Wurst7/tree/master/src/main/resources/assets/wurst/translations), in case you need them. ## License diff --git a/gradle.properties b/gradle.properties index 964c45eb..e6026c48 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ loader_version=0.16.0 fabric_version=0.102.0+1.21.1 # Mod Properties -mod_version = v7.44-MC1.21.1 +mod_version = v7.45-MC1.21.1 maven_group = net.wurstclient archives_base_name = Wurst-Client diff --git a/src/main/java/net/wurstclient/WurstClient.java b/src/main/java/net/wurstclient/WurstClient.java index 6c05cab2..9205e981 100644 --- a/src/main/java/net/wurstclient/WurstClient.java +++ b/src/main/java/net/wurstclient/WurstClient.java @@ -50,7 +50,7 @@ public enum WurstClient public static MinecraftClient MC; public static IMinecraftClient IMC; - public static final String VERSION = "7.44"; + public static final String VERSION = "7.45"; public static final String MC_VERSION = "1.21.1"; private WurstAnalytics analytics; diff --git a/src/main/java/net/wurstclient/WurstTranslator.java b/src/main/java/net/wurstclient/WurstTranslator.java index 380125cc..610a88db 100644 --- a/src/main/java/net/wurstclient/WurstTranslator.java +++ b/src/main/java/net/wurstclient/WurstTranslator.java @@ -148,8 +148,10 @@ public class WurstTranslator implements SynchronousResourceReloader private ArrayList getCurrentLangCodes() { - String mainLangCode = - MinecraftClient.getInstance().getLanguageManager().getLanguage(); + // Weird bug: Some users have their language set to "en_US" instead of + // "en_us" for some reason. Last seen in 1.21. + String mainLangCode = MinecraftClient.getInstance().getLanguageManager() + .getLanguage().toLowerCase(); ArrayList langCodes = new ArrayList<>(); langCodes.add("en_us"); diff --git a/src/main/java/net/wurstclient/events/PlayerAttacksEntityListener.java b/src/main/java/net/wurstclient/events/PlayerAttacksEntityListener.java new file mode 100644 index 00000000..5fa49c76 --- /dev/null +++ b/src/main/java/net/wurstclient/events/PlayerAttacksEntityListener.java @@ -0,0 +1,57 @@ +/* + * 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.network.ClientPlayerInteractionManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.wurstclient.event.Event; +import net.wurstclient.event.Listener; + +/** + * Fired at the beginning of + * {@link ClientPlayerInteractionManager#attackEntity(PlayerEntity, Entity)}. + */ +public interface PlayerAttacksEntityListener extends Listener +{ + /** + * Fired at the beginning of + * {@link ClientPlayerInteractionManager#attackEntity(PlayerEntity, Entity)}. + */ + public void onPlayerAttacksEntity(Entity target); + + /** + * Fired at the beginning of + * {@link ClientPlayerInteractionManager#attackEntity(PlayerEntity, Entity)}. + */ + public static class PlayerAttacksEntityEvent + extends Event + { + private final Entity target; + + public PlayerAttacksEntityEvent(Entity target) + { + this.target = target; + } + + @Override + public void fire(ArrayList listeners) + { + for(PlayerAttacksEntityListener listener : listeners) + listener.onPlayerAttacksEntity(target); + } + + @Override + public Class getListenerType() + { + return PlayerAttacksEntityListener.class; + } + } +} diff --git a/src/main/java/net/wurstclient/hack/HackList.java b/src/main/java/net/wurstclient/hack/HackList.java index 2cb14067..d7504295 100644 --- a/src/main/java/net/wurstclient/hack/HackList.java +++ b/src/main/java/net/wurstclient/hack/HackList.java @@ -172,6 +172,7 @@ public final class HackList implements UpdateListener public final SpeedNukerHack speedNukerHack = new SpeedNukerHack(); public final SpiderHack spiderHack = new SpiderHack(); public final StepHack stepHack = new StepHack(); + public final TemplateToolHack templateToolHack = new TemplateToolHack(); public final ThrowHack throwHack = new ThrowHack(); public final TillauraHack tillauraHack = new TillauraHack(); public final TimerHack timerHack = new TimerHack(); diff --git a/src/main/java/net/wurstclient/hacks/AimAssistHack.java b/src/main/java/net/wurstclient/hacks/AimAssistHack.java index 4b883b4c..35b21e01 100644 --- a/src/main/java/net/wurstclient/hacks/AimAssistHack.java +++ b/src/main/java/net/wurstclient/hacks/AimAssistHack.java @@ -45,6 +45,11 @@ public final class AimAssistHack extends Hack private final AimAtSetting aimAt = new AimAtSetting( "What point in the target's hitbox AimAssist should aim at."); + private final SliderSetting ignoreMouseInput = + new SliderSetting("Ignore mouse input", + "description.wurst.setting.aimassist.ignore_mouse_input", 0, 0, 1, + 0.01, ValueDisplay.PERCENTAGE); + private final CheckboxSetting checkLOS = new CheckboxSetting("Check line of sight", "description.wurst.setting.aimassist.check_line_of_sight", true); @@ -95,6 +100,7 @@ public final class AimAssistHack extends Hack addSetting(rotationSpeed); addSetting(fov); addSetting(aimAt); + addSetting(ignoreMouseInput); addSetting(checkLOS); addSetting(aimWhileBlocking); @@ -201,7 +207,11 @@ public final class AimAssistHack extends Hack diffPitch = nextPitch < curPitch ? -1 : 1; } - event.setDeltaX(event.getDefaultDeltaX() + diffYaw); - event.setDeltaY(event.getDefaultDeltaY() + diffPitch); + double inputFactor = 1 - ignoreMouseInput.getValue(); + int mouseInputX = (int)(event.getDefaultDeltaX() * inputFactor); + int mouseInputY = (int)(event.getDefaultDeltaY() * inputFactor); + + event.setDeltaX(mouseInputX + diffYaw); + event.setDeltaY(mouseInputY + diffPitch); } } diff --git a/src/main/java/net/wurstclient/hacks/AntiBlindHack.java b/src/main/java/net/wurstclient/hacks/AntiBlindHack.java index b0b8218c..30082ea9 100644 --- a/src/main/java/net/wurstclient/hacks/AntiBlindHack.java +++ b/src/main/java/net/wurstclient/hacks/AntiBlindHack.java @@ -23,6 +23,6 @@ public final class AntiBlindHack extends Hack setCategory(Category.RENDER); } - // See BackgroundRendererMixin, WorldRendererMixin, - // ClientPlayerEntityMixin.hasStatusEffect() + // See BackgroundRendererMixin, LightmapTextureManagerMixin, + // WorldRendererMixin, ClientPlayerEntityMixin.hasStatusEffect() } diff --git a/src/main/java/net/wurstclient/hacks/AntiHungerHack.java b/src/main/java/net/wurstclient/hacks/AntiHungerHack.java index 98a3f957..3b6bca6a 100644 --- a/src/main/java/net/wurstclient/hacks/AntiHungerHack.java +++ b/src/main/java/net/wurstclient/hacks/AntiHungerHack.java @@ -12,8 +12,10 @@ import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; import net.wurstclient.Category; import net.wurstclient.SearchTags; import net.wurstclient.events.PacketOutputListener; +import net.wurstclient.hack.DontSaveState; import net.wurstclient.hack.Hack; +@DontSaveState @SearchTags({"anti hunger"}) public final class AntiHungerHack extends Hack implements PacketOutputListener { @@ -26,6 +28,7 @@ public final class AntiHungerHack extends Hack implements PacketOutputListener @Override protected void onEnable() { + WURST.getHax().noFallHack.setEnabled(false); EVENTS.add(PacketOutputListener.class, this); } diff --git a/src/main/java/net/wurstclient/hacks/AutoArmorHack.java b/src/main/java/net/wurstclient/hacks/AutoArmorHack.java index 964b04f3..8cc5edb1 100644 --- a/src/main/java/net/wurstclient/hacks/AutoArmorHack.java +++ b/src/main/java/net/wurstclient/hacks/AutoArmorHack.java @@ -19,6 +19,7 @@ import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.AnimalArmorItem; import net.minecraft.item.ArmorItem; import net.minecraft.item.ArmorItem.Type; import net.minecraft.item.ItemStack; @@ -114,10 +115,10 @@ public final class AutoArmorHack extends Hack bestArmorSlots[type] = -1; ItemStack stack = inventory.getArmorStack(type); - if(stack.isEmpty() || !(stack.getItem() instanceof ArmorItem)) + if(!(stack.getItem() instanceof ArmorItem item) + || item instanceof AnimalArmorItem) continue; - ArmorItem item = (ArmorItem)stack.getItem(); bestArmorValues[type] = getArmorValue(item, stack); } @@ -126,10 +127,10 @@ public final class AutoArmorHack extends Hack { ItemStack stack = inventory.getStack(slot); - if(stack.isEmpty() || !(stack.getItem() instanceof ArmorItem)) + if(!(stack.getItem() instanceof ArmorItem item) + || item instanceof AnimalArmorItem) continue; - ArmorItem item = (ArmorItem)stack.getItem(); int armorType = item.getSlotType().getEntitySlotId(); int armorValue = getArmorValue(item, stack); diff --git a/src/main/java/net/wurstclient/hacks/AutoBuildHack.java b/src/main/java/net/wurstclient/hacks/AutoBuildHack.java index 27c6fbc3..61592a69 100644 --- a/src/main/java/net/wurstclient/hacks/AutoBuildHack.java +++ b/src/main/java/net/wurstclient/hacks/AutoBuildHack.java @@ -9,20 +9,20 @@ package net.wurstclient.hacks; import java.io.IOException; import java.nio.file.Path; -import java.util.Iterator; +import java.util.ArrayList; import java.util.LinkedHashSet; +import java.util.stream.Collectors; import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.block.BlockState; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.util.math.MatrixStack; -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.Box; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.wurstclient.Category; @@ -30,18 +30,13 @@ import net.wurstclient.events.RenderListener; import net.wurstclient.events.RightClickListener; import net.wurstclient.events.UpdateListener; import net.wurstclient.hack.Hack; -import net.wurstclient.mixinterface.IClientPlayerInteractionManager; import net.wurstclient.settings.CheckboxSetting; import net.wurstclient.settings.FileSetting; import net.wurstclient.settings.SliderSetting; import net.wurstclient.settings.SliderSetting.ValueDisplay; -import net.wurstclient.util.AutoBuildTemplate; -import net.wurstclient.util.BlockUtils; -import net.wurstclient.util.ChatUtils; -import net.wurstclient.util.DefaultAutoBuildTemplates; -import net.wurstclient.util.RegionPos; -import net.wurstclient.util.RenderUtils; -import net.wurstclient.util.RotationUtils; +import net.wurstclient.settings.SwingHandSetting.SwingHand; +import net.wurstclient.util.*; +import net.wurstclient.util.BlockPlacer.BlockPlacingParams; import net.wurstclient.util.json.JsonException; public final class AutoBuildHack extends Hack @@ -119,6 +114,8 @@ public final class AutoBuildHack extends Hack @Override protected void onEnable() { + WURST.getHax().templateToolHack.setEnabled(false); + EVENTS.add(UpdateListener.class, this); EVENTS.add(RightClickListener.class, this); EVENTS.add(RenderListener.class, this); @@ -139,6 +136,31 @@ public final class AutoBuildHack extends Hack status = Status.IDLE; } + @Override + public void onRightClick(RightClickEvent event) + { + if(status != Status.IDLE) + return; + + HitResult hitResult = MC.crosshairTarget; + if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK + || !(hitResult instanceof BlockHitResult blockHitResult)) + return; + + BlockPos hitResultPos = blockHitResult.getBlockPos(); + if(!BlockUtils.canBeClicked(hitResultPos)) + return; + + BlockPos startPos = hitResultPos.offset(blockHitResult.getSide()); + Direction direction = MC.player.getHorizontalFacing(); + remainingBlocks = template.getPositions(startPos, direction); + + if(instaBuild.isChecked() && template.size() <= 64) + buildInstantly(); + else + status = Status.BUILDING; + } + @Override public void onUpdate() { @@ -162,6 +184,108 @@ public final class AutoBuildHack extends Hack } } + @Override + public void onRender(MatrixStack matrixStack, float partialTicks) + { + if(status != Status.BUILDING) + return; + + // GL settings + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_CULL_FACE); + + matrixStack.push(); + + RegionPos region = RenderUtils.getCameraRegion(); + RenderUtils.applyRegionalRenderOffset(matrixStack, region); + + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderSystem.setShader(GameRenderer::getPositionProgram); + + double boxStart = 1 / 16.0; + double boxEnd = 15 / 16.0; + Box box = new Box(boxStart, boxStart, boxStart, boxEnd, boxEnd, boxEnd) + .offset(region.negate().toBlockPos()); + + ArrayList blocksToDraw = remainingBlocks.stream() + .filter(pos -> BlockUtils.getState(pos).isReplaceable()).limit(1024) + .collect(Collectors.toCollection(ArrayList::new)); + + GL11.glDepthMask(false); + RenderSystem.setShaderColor(0, 1, 0, 0.15F); + + Vec3d eyesPos = RotationUtils.getEyesPos(); + double rangeSq = range.getValueSq(); + blocksToDraw.stream() + .filter(pos -> pos.getSquaredDistance(eyesPos) <= rangeSq) + .map(pos -> box.offset(pos)).forEach( + offsetBox -> RenderUtils.drawSolidBox(offsetBox, matrixStack)); + + GL11.glDepthMask(true); + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + + blocksToDraw.stream().map(pos -> box.offset(pos)).forEach( + offsetBox -> RenderUtils.drawOutlinedBox(offsetBox, matrixStack)); + + matrixStack.pop(); + + // GL resets + GL11.glDisable(GL11.GL_BLEND); + RenderSystem.setShaderColor(1, 1, 1, 1); + } + + private void buildNormally() + { + remainingBlocks + .removeIf(pos -> !BlockUtils.getState(pos).isReplaceable()); + + if(remainingBlocks.isEmpty()) + { + status = Status.IDLE; + return; + } + + if(!fastPlace.isChecked() && MC.itemUseCooldown > 0) + return; + + double rangeSq = range.getValueSq(); + for(BlockPos pos : remainingBlocks) + { + BlockPlacingParams params = BlockPlacer.getBlockPlacingParams(pos); + if(params == null || params.distanceSq() > rangeSq) + continue; + if(checkLOS.isChecked() && !params.lineOfSight()) + continue; + + MC.itemUseCooldown = 4; + RotationUtils.getNeededRotations(params.hitVec()) + .sendPlayerLookPacket(); + InteractionSimulator.rightClickBlock(params.toHitResult()); + break; + } + } + + private void buildInstantly() + { + double rangeSq = range.getValueSq(); + + for(BlockPos pos : remainingBlocks) + { + if(!BlockUtils.getState(pos).isReplaceable()) + continue; + + BlockPlacingParams params = BlockPlacer.getBlockPlacingParams(pos); + if(params == null || params.distanceSq() > rangeSq) + continue; + + InteractionSimulator.rightClickBlock(params.toHitResult(), + SwingHand.OFF); + } + + remainingBlocks.clear(); + } + private void loadSelectedTemplate() { status = Status.LOADING; @@ -186,218 +310,9 @@ public final class AutoBuildHack extends Hack } } - private void buildNormally() + public Path getFolder() { - updateRemainingBlocks(); - - if(remainingBlocks.isEmpty()) - { - status = Status.IDLE; - return; - } - - if(!fastPlace.isChecked() && MC.itemUseCooldown > 0) - return; - - placeNextBlock(); - } - - private void updateRemainingBlocks() - { - for(Iterator itr = remainingBlocks.iterator(); itr.hasNext();) - { - BlockPos pos = itr.next(); - BlockState state = BlockUtils.getState(pos); - - if(!state.isReplaceable()) - itr.remove(); - } - } - - private void placeNextBlock() - { - Vec3d eyesPos = RotationUtils.getEyesPos(); - double rangeSq = Math.pow(range.getValue(), 2); - - for(BlockPos pos : remainingBlocks) - if(tryToPlace(pos, eyesPos, rangeSq)) - break; - } - - private boolean tryToPlace(BlockPos pos, Vec3d eyesPos, double rangeSq) - { - Vec3d posVec = Vec3d.ofCenter(pos); - double distanceSqPosVec = eyesPos.squaredDistanceTo(posVec); - - for(Direction side : Direction.values()) - { - BlockPos neighbor = pos.offset(side); - - // check if neighbor can be right clicked - if(!BlockUtils.canBeClicked(neighbor) - || BlockUtils.getState(neighbor).isReplaceable()) - continue; - - Vec3d dirVec = Vec3d.of(side.getVector()); - Vec3d hitVec = posVec.add(dirVec.multiply(0.5)); - - // check if hitVec is within range - if(eyesPos.squaredDistanceTo(hitVec) > rangeSq) - continue; - - // check if side is visible (facing away from player) - if(distanceSqPosVec > eyesPos.squaredDistanceTo(posVec.add(dirVec))) - continue; - - // check line of sight - if(checkLOS.isChecked() - && !BlockUtils.hasLineOfSight(eyesPos, hitVec)) - continue; - - // face block - RotationUtils.getNeededRotations(hitVec).sendPlayerLookPacket(); - - // place block - IMC.getInteractionManager().rightClickBlock(neighbor, - side.getOpposite(), hitVec); - MC.player.swingHand(Hand.MAIN_HAND); - MC.itemUseCooldown = 4; - return true; - } - - return false; - } - - @Override - public void onRightClick(RightClickEvent event) - { - if(status != Status.IDLE) - return; - - HitResult hitResult = MC.crosshairTarget; - if(hitResult == null || hitResult.getPos() == null - || hitResult.getType() != HitResult.Type.BLOCK - || !(hitResult instanceof BlockHitResult)) - return; - - BlockHitResult blockHitResult = (BlockHitResult)hitResult; - - BlockPos hitResultPos = blockHitResult.getBlockPos(); - if(!BlockUtils.canBeClicked(hitResultPos)) - return; - - BlockPos startPos = hitResultPos.offset(blockHitResult.getSide()); - Direction direction = MC.player.getHorizontalFacing(); - remainingBlocks = template.getPositions(startPos, direction); - - if(instaBuild.isChecked() && template.size() <= 64) - buildInstantly(); - else - status = Status.BUILDING; - } - - private void buildInstantly() - { - Vec3d eyesPos = RotationUtils.getEyesPos(); - IClientPlayerInteractionManager im = IMC.getInteractionManager(); - double rangeSq = Math.pow(range.getValue(), 2); - - for(BlockPos pos : remainingBlocks) - { - if(!BlockUtils.getState(pos).isReplaceable()) - continue; - - Vec3d posVec = Vec3d.ofCenter(pos); - - for(Direction side : Direction.values()) - { - BlockPos neighbor = pos.offset(side); - - // check if neighbor can be right-clicked - if(!BlockUtils.canBeClicked(neighbor)) - continue; - - Vec3d sideVec = Vec3d.of(side.getVector()); - Vec3d hitVec = posVec.add(sideVec.multiply(0.5)); - - // check if hitVec is within range - if(eyesPos.squaredDistanceTo(hitVec) > rangeSq) - continue; - - // place block - im.rightClickBlock(neighbor, side.getOpposite(), hitVec); - - break; - } - } - - remainingBlocks.clear(); - } - - @Override - public void onRender(MatrixStack matrixStack, float partialTicks) - { - if(status != Status.BUILDING) - return; - - float scale = 1F * 7F / 8F; - double offset = (1D - scale) / 2D; - Vec3d eyesPos = RotationUtils.getEyesPos(); - double rangeSq = Math.pow(range.getValue(), 2); - - // GL settings - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glDisable(GL11.GL_CULL_FACE); - RenderSystem.setShaderColor(0F, 0F, 0F, 0.5F); - - matrixStack.push(); - - RegionPos region = RenderUtils.getCameraRegion(); - RenderUtils.applyRegionalRenderOffset(matrixStack, region); - - int blocksDrawn = 0; - RenderSystem.setShader(GameRenderer::getPositionProgram); - for(Iterator itr = remainingBlocks.iterator(); itr.hasNext() - && blocksDrawn < 1024;) - { - BlockPos pos = itr.next(); - if(!BlockUtils.getState(pos).isReplaceable()) - continue; - - matrixStack.push(); - matrixStack.translate(pos.getX() - region.x(), pos.getY(), - pos.getZ() - region.z()); - matrixStack.translate(offset, offset, offset); - matrixStack.scale(scale, scale, scale); - - Vec3d posVec = Vec3d.ofCenter(pos); - - if(eyesPos.squaredDistanceTo(posVec) <= rangeSq) - drawGreenBox(matrixStack); - else - RenderUtils.drawOutlinedBox(matrixStack); - - matrixStack.pop(); - blocksDrawn++; - } - - matrixStack.pop(); - - // GL resets - GL11.glDisable(GL11.GL_BLEND); - RenderSystem.setShaderColor(1, 1, 1, 1); - } - - private void drawGreenBox(MatrixStack matrixStack) - { - GL11.glDepthMask(false); - RenderSystem.setShaderColor(0F, 1F, 0F, 0.15F); - RenderUtils.drawSolidBox(matrixStack); - GL11.glDepthMask(true); - - RenderSystem.setShaderColor(0F, 0F, 0F, 0.5F); - RenderUtils.drawOutlinedBox(matrixStack); + return templateSetting.getFolder(); } private enum Status diff --git a/src/main/java/net/wurstclient/hacks/BowAimbotHack.java b/src/main/java/net/wurstclient/hacks/BowAimbotHack.java index f2b130b8..418448ef 100644 --- a/src/main/java/net/wurstclient/hacks/BowAimbotHack.java +++ b/src/main/java/net/wurstclient/hacks/BowAimbotHack.java @@ -99,6 +99,7 @@ public final class BowAimbotHack extends Hack { // disable conflicting hacks WURST.getHax().excavatorHack.setEnabled(false); + WURST.getHax().templateToolHack.setEnabled(false); // register event listeners EVENTS.add(GUIRenderListener.class, this); diff --git a/src/main/java/net/wurstclient/hacks/ChatTranslatorHack.java b/src/main/java/net/wurstclient/hacks/ChatTranslatorHack.java index a827eed3..2e80bc4e 100644 --- a/src/main/java/net/wurstclient/hacks/ChatTranslatorHack.java +++ b/src/main/java/net/wurstclient/hacks/ChatTranslatorHack.java @@ -7,171 +7,142 @@ */ package net.wurstclient.hacks; -import net.minecraft.text.Text; import net.wurstclient.Category; import net.wurstclient.SearchTags; import net.wurstclient.events.ChatInputListener; +import net.wurstclient.events.ChatOutputListener; import net.wurstclient.hack.Hack; -import net.wurstclient.settings.EnumSetting; +import net.wurstclient.hacks.chattranslator.FilterOwnMessagesSetting; +import net.wurstclient.hacks.chattranslator.GoogleTranslate; +import net.wurstclient.hacks.chattranslator.LanguageSetting; +import net.wurstclient.hacks.chattranslator.LanguageSetting.Language; +import net.wurstclient.hacks.chattranslator.WhatToTranslateSetting; +import net.wurstclient.settings.CheckboxSetting; import net.wurstclient.util.ChatUtils; -import net.wurstclient.util.GoogleTranslate; @SearchTags({"chat translator", "ChatTranslate", "chat translate", "ChatTranslation", "chat translation", "AutoTranslate", "auto translate", "AutoTranslator", "auto translator", "AutoTranslation", "auto translation", "GoogleTranslate", "google translate", "GoogleTranslator", "google translator", "GoogleTranslation", "google translation"}) -public final class ChatTranslatorHack extends Hack implements ChatInputListener +public final class ChatTranslatorHack extends Hack + implements ChatInputListener, ChatOutputListener { - private final EnumSetting langFrom = new EnumSetting<>( - "Translate from", FromLanguage.values(), FromLanguage.AUTO_DETECT); + private final WhatToTranslateSetting whatToTranslate = + new WhatToTranslateSetting(); - private final EnumSetting langTo = new EnumSetting<>( - "Translate to", ToLanguage.values(), ToLanguage.ENGLISH); + private final LanguageSetting playerLanguage = + LanguageSetting.withoutAutoDetect("Your language", + "description.wurst.setting.chattranslator.your_language", + Language.ENGLISH); + + private final LanguageSetting otherLanguage = + LanguageSetting.withoutAutoDetect("Other language", + "description.wurst.setting.chattranslator.other_language", + Language.CHINESE_SIMPLIFIED); + + private final CheckboxSetting autoDetectReceived = + new CheckboxSetting("Detect received language", + "description.wurst.setting.chattranslator.detect_received_language", + true); + + private final CheckboxSetting autoDetectSent = new CheckboxSetting( + "Detect sent language", + "description.wurst.setting.chattranslator.detect_sent_language", true); + + private final FilterOwnMessagesSetting filterOwnMessages = + new FilterOwnMessagesSetting(); public ChatTranslatorHack() { super("ChatTranslator"); setCategory(Category.CHAT); - - addSetting(langFrom); - addSetting(langTo); + addSetting(whatToTranslate); + addSetting(playerLanguage); + addSetting(otherLanguage); + addSetting(autoDetectReceived); + addSetting(autoDetectSent); + addSetting(filterOwnMessages); } @Override protected void onEnable() { EVENTS.add(ChatInputListener.class, this); + EVENTS.add(ChatOutputListener.class, this); } @Override protected void onDisable() { EVENTS.remove(ChatInputListener.class, this); + EVENTS.remove(ChatOutputListener.class, this); } @Override public void onReceivedMessage(ChatInputEvent event) { - new Thread(() -> { - try - { - translate(event); - - }catch(Exception e) - { - e.printStackTrace(); - } - }, "ChatTranslator").start(); - } - - private void translate(ChatInputEvent event) - { - String incomingMsg = event.getComponent().getString(); - - String translatorPrefix = - "\u00a7a[\u00a7b" + langTo.getSelected().name + "\u00a7a]:\u00a7r "; - - if(incomingMsg.startsWith(ChatUtils.WURST_PREFIX) - || incomingMsg.startsWith(translatorPrefix)) + if(!whatToTranslate.includesReceived()) return; - String translated = GoogleTranslate.translate(incomingMsg, - langFrom.getSelected().value, langTo.getSelected().value); + String message = event.getComponent().getString(); + Language fromLang = autoDetectReceived.isChecked() + ? Language.AUTO_DETECT : otherLanguage.getSelected(); + Language toLang = playerLanguage.getSelected(); + + if(message.startsWith(ChatUtils.WURST_PREFIX) + || message.startsWith(toLang.getPrefix())) + return; + + if(filterOwnMessages.isChecked() + && filterOwnMessages.isOwnMessage(message)) + return; + + Thread.ofVirtual().name("ChatTranslator") + .uncaughtExceptionHandler((t, e) -> e.printStackTrace()) + .start(() -> showTranslated(message, fromLang, toLang)); + } + + private void showTranslated(String message, Language fromLang, + Language toLang) + { + String translated = GoogleTranslate.translate(message, + fromLang.getValue(), toLang.getValue()); + + if(translated != null) + MC.inGameHud.getChatHud().addMessage(toLang.prefixText(translated)); + } + + @Override + public void onSentMessage(ChatOutputEvent event) + { + if(!whatToTranslate.includesSent()) + return; + + String message = event.getMessage(); + Language fromLang = autoDetectSent.isChecked() ? Language.AUTO_DETECT + : playerLanguage.getSelected(); + Language toLang = otherLanguage.getSelected(); + + if(message.startsWith("/") || message.startsWith(".")) + return; + + event.cancel(); + + Thread.ofVirtual().name("ChatTranslator") + .uncaughtExceptionHandler((t, e) -> e.printStackTrace()) + .start(() -> sendTranslated(message, fromLang, toLang)); + } + + private void sendTranslated(String message, Language fromLang, + Language toLang) + { + String translated = GoogleTranslate.translate(message, + fromLang.getValue(), toLang.getValue()); if(translated == null) - return; + translated = message; - Text translationMsg = - Text.literal(translatorPrefix).append(Text.literal(translated)); - - MC.inGameHud.getChatHud().addMessage(translationMsg); - } - - public static enum FromLanguage - { - AUTO_DETECT("Detect Language", "auto"), - AFRIKAANS("Afrikaans", "af"), - ARABIC("Arabic", "ar"), - CZECH("Czech", "cs"), - CHINESE_SIMPLIFIED("Chinese (simplified)", "zh-CN"), - CHINESE_TRADITIONAL("Chinese (traditional)", "zh-TW"), - DANISH("Danish", "da"), - DUTCH("Dutch", "nl"), - ENGLISH("English", "en"), - FINNISH("Finnish", "fi"), - FRENCH("French", "fr"), - GERMAN("Deutsch!", "de"), - GREEK("Greek", "el"), - HINDI("Hindi", "hi"), - ITALIAN("Italian", "it"), - JAPANESE("Japanese", "ja"), - KOREAN("Korean", "ko"), - NORWEGIAN("Norwegian", "no"), - POLISH("Polish", "pl"), - PORTUGUESE("Portugese", "pt"), - RUSSIAN("Russian", "ru"), - SPANISH("Spanish", "es"), - SWAHILI("Swahili", "sw"), - SWEDISH("Swedish", "sv"), - TURKISH("Turkish", "tr"); - - private final String name; - private final String value; - - private FromLanguage(String name, String value) - { - this.name = name; - this.value = value; - } - - @Override - public String toString() - { - return name; - } - } - - public static enum ToLanguage - { - AFRIKAANS("Afrikaans", "af"), - ARABIC("Arabic", "ar"), - CZECH("Czech", "cs"), - CHINESE_SIMPLIFIED("Chinese (simplified)", "zh-CN"), - CHINESE_TRADITIONAL("Chinese (traditional)", "zh-TW"), - DANISH("Danish", "da"), - DUTCH("Dutch", "nl"), - ENGLISH("English", "en"), - FINNISH("Finnish", "fi"), - FRENCH("French", "fr"), - GERMAN("Deutsch!", "de"), - GREEK("Greek", "el"), - HINDI("Hindi", "hi"), - ITALIAN("Italian", "it"), - JAPANESE("Japanese", "ja"), - KOREAN("Korean", "ko"), - NORWEGIAN("Norwegian", "no"), - POLISH("Polish", "pl"), - PORTUGUESE("Portugese", "pt"), - RUSSIAN("Russian", "ru"), - SPANISH("Spanish", "es"), - SWAHILI("Swahili", "sw"), - SWEDISH("Swedish", "sv"), - TURKISH("Turkish", "tr"); - - private final String name; - private final String value; - - private ToLanguage(String name, String value) - { - this.name = name; - this.value = value; - } - - @Override - public String toString() - { - return name; - } + MC.getNetworkHandler().sendChatMessage(translated); } } diff --git a/src/main/java/net/wurstclient/hacks/ClickAuraHack.java b/src/main/java/net/wurstclient/hacks/ClickAuraHack.java index d57e2689..f3b5349c 100644 --- a/src/main/java/net/wurstclient/hacks/ClickAuraHack.java +++ b/src/main/java/net/wurstclient/hacks/ClickAuraHack.java @@ -136,7 +136,6 @@ public final class ClickAuraHack extends Hack .sendPlayerLookPacket(); // attack entity - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(player, target); player.swingHand(Hand.MAIN_HAND); speed.resetTimer(); diff --git a/src/main/java/net/wurstclient/hacks/CriticalsHack.java b/src/main/java/net/wurstclient/hacks/CriticalsHack.java index d4851935..efe59d23 100644 --- a/src/main/java/net/wurstclient/hacks/CriticalsHack.java +++ b/src/main/java/net/wurstclient/hacks/CriticalsHack.java @@ -7,19 +7,19 @@ */ package net.wurstclient.hacks; +import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.item.Items; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; +import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.PositionAndOnGround; import net.wurstclient.Category; import net.wurstclient.SearchTags; -import net.wurstclient.events.LeftClickListener; +import net.wurstclient.events.PlayerAttacksEntityListener; import net.wurstclient.hack.Hack; import net.wurstclient.settings.EnumSetting; @SearchTags({"Crits"}) -public final class CriticalsHack extends Hack implements LeftClickListener +public final class CriticalsHack extends Hack + implements PlayerAttacksEntityListener { private final EnumSetting mode = new EnumSetting<>("Mode", "\u00a7lPacket\u00a7r mode sends packets to server without actually moving you at all.\n\n" @@ -43,30 +43,19 @@ public final class CriticalsHack extends Hack implements LeftClickListener @Override protected void onEnable() { - EVENTS.add(LeftClickListener.class, this); + EVENTS.add(PlayerAttacksEntityListener.class, this); } @Override protected void onDisable() { - EVENTS.remove(LeftClickListener.class, this); + EVENTS.remove(PlayerAttacksEntityListener.class, this); } @Override - public void onLeftClick(LeftClickEvent event) + public void onPlayerAttacksEntity(Entity target) { - if(MC.crosshairTarget == null - || MC.crosshairTarget.getType() != HitResult.Type.ENTITY - || !(((EntityHitResult)MC.crosshairTarget) - .getEntity() instanceof LivingEntity)) - return; - - doCritical(); - } - - public void doCritical() - { - if(!isEnabled()) + if(!(target instanceof LivingEntity)) return; if(WURST.getHax().maceDmgHack.isEnabled() @@ -97,20 +86,17 @@ public final class CriticalsHack extends Hack implements LeftClickListener private void doPacketJump() { - double posX = MC.player.getX(); - double posY = MC.player.getY(); - double posZ = MC.player.getZ(); - - sendPos(posX, posY + 0.0625D, posZ, true); - sendPos(posX, posY, posZ, false); - sendPos(posX, posY + 1.1E-5D, posZ, false); - sendPos(posX, posY, posZ, false); + sendFakeY(0.0625, true); + sendFakeY(0, false); + sendFakeY(1.1e-5, false); + sendFakeY(0, false); } - private void sendPos(double x, double y, double z, boolean onGround) + private void sendFakeY(double offset, boolean onGround) { - MC.player.networkHandler.sendPacket( - new PlayerMoveC2SPacket.PositionAndOnGround(x, y, z, onGround)); + MC.player.networkHandler + .sendPacket(new PositionAndOnGround(MC.player.getX(), + MC.player.getY() + offset, MC.player.getZ(), onGround)); } private void doMiniJump() diff --git a/src/main/java/net/wurstclient/hacks/ExcavatorHack.java b/src/main/java/net/wurstclient/hacks/ExcavatorHack.java index 184cfcd1..acc2eaa8 100644 --- a/src/main/java/net/wurstclient/hacks/ExcavatorHack.java +++ b/src/main/java/net/wurstclient/hacks/ExcavatorHack.java @@ -102,7 +102,7 @@ public final class ExcavatorHack extends Hack WURST.getHax().nukerHack.setEnabled(false); WURST.getHax().nukerLegitHack.setEnabled(false); WURST.getHax().speedNukerHack.setEnabled(false); - // WURST.getHax().templateToolHack.setEnabled(false); + WURST.getHax().templateToolHack.setEnabled(false); WURST.getHax().tunnellerHack.setEnabled(false); step = Step.START_POS; diff --git a/src/main/java/net/wurstclient/hacks/FightBotHack.java b/src/main/java/net/wurstclient/hacks/FightBotHack.java index c36ac153..1346b591 100644 --- a/src/main/java/net/wurstclient/hacks/FightBotHack.java +++ b/src/main/java/net/wurstclient/hacks/FightBotHack.java @@ -216,7 +216,6 @@ public final class FightBotHack extends Hack return; // attack entity - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(MC.player, entity); swingHand.swing(Hand.MAIN_HAND); speed.resetTimer(); diff --git a/src/main/java/net/wurstclient/hacks/KillauraHack.java b/src/main/java/net/wurstclient/hacks/KillauraHack.java index 7e21b0f4..c3fafc5d 100644 --- a/src/main/java/net/wurstclient/hacks/KillauraHack.java +++ b/src/main/java/net/wurstclient/hacks/KillauraHack.java @@ -192,7 +192,6 @@ public final class KillauraHack extends Hack if(target == null) return; - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(MC.player, target); swingHand.swing(Hand.MAIN_HAND); diff --git a/src/main/java/net/wurstclient/hacks/KillauraLegitHack.java b/src/main/java/net/wurstclient/hacks/KillauraLegitHack.java index 9d9cf86e..d1eca3cb 100644 --- a/src/main/java/net/wurstclient/hacks/KillauraLegitHack.java +++ b/src/main/java/net/wurstclient/hacks/KillauraLegitHack.java @@ -224,7 +224,6 @@ public final class KillauraLegitHack extends Hack implements UpdateListener, return; // attack entity - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(MC.player, target); swingHand.swing(Hand.MAIN_HAND); speed.resetTimer(speedRandMS.getValue()); diff --git a/src/main/java/net/wurstclient/hacks/MaceDmgHack.java b/src/main/java/net/wurstclient/hacks/MaceDmgHack.java index 8ecf4b8e..32102251 100644 --- a/src/main/java/net/wurstclient/hacks/MaceDmgHack.java +++ b/src/main/java/net/wurstclient/hacks/MaceDmgHack.java @@ -7,17 +7,18 @@ */ package net.wurstclient.hacks; -import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.entity.Entity; import net.minecraft.item.Items; import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.PositionAndOnGround; import net.minecraft.util.hit.HitResult; import net.wurstclient.Category; import net.wurstclient.SearchTags; -import net.wurstclient.events.LeftClickListener; +import net.wurstclient.events.PlayerAttacksEntityListener; import net.wurstclient.hack.Hack; @SearchTags({"mace dmg", "MaceDamage", "mace damage"}) -public final class MaceDmgHack extends Hack implements LeftClickListener +public final class MaceDmgHack extends Hack + implements PlayerAttacksEntityListener { public MaceDmgHack() { @@ -28,17 +29,17 @@ public final class MaceDmgHack extends Hack implements LeftClickListener @Override protected void onEnable() { - EVENTS.add(LeftClickListener.class, this); + EVENTS.add(PlayerAttacksEntityListener.class, this); } @Override protected void onDisable() { - EVENTS.remove(LeftClickListener.class, this); + EVENTS.remove(PlayerAttacksEntityListener.class, this); } @Override - public void onLeftClick(LeftClickEvent event) + public void onPlayerAttacksEntity(Entity target) { if(MC.crosshairTarget == null || MC.crosshairTarget.getType() != HitResult.Type.ENTITY) @@ -58,12 +59,8 @@ public final class MaceDmgHack extends Hack implements LeftClickListener private void sendFakeY(double offset) { - ClientPlayNetworkHandler netHandler = MC.player.networkHandler; - double posX = MC.player.getX(); - double posY = MC.player.getY(); - double posZ = MC.player.getZ(); - - netHandler.sendPacket( - new PositionAndOnGround(posX, posY + offset, posZ, false)); + MC.player.networkHandler + .sendPacket(new PositionAndOnGround(MC.player.getX(), + MC.player.getY() + offset, MC.player.getZ(), false)); } } diff --git a/src/main/java/net/wurstclient/hacks/MultiAuraHack.java b/src/main/java/net/wurstclient/hacks/MultiAuraHack.java index 2809c7cc..a1b836fd 100644 --- a/src/main/java/net/wurstclient/hacks/MultiAuraHack.java +++ b/src/main/java/net/wurstclient/hacks/MultiAuraHack.java @@ -122,7 +122,6 @@ public final class MultiAuraHack extends Hack implements UpdateListener .getNeededRotations(entity.getBoundingBox().getCenter()) .sendPlayerLookPacket(); - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(MC.player, entity); } diff --git a/src/main/java/net/wurstclient/hacks/NoFallHack.java b/src/main/java/net/wurstclient/hacks/NoFallHack.java index ceac661a..7e2805b2 100644 --- a/src/main/java/net/wurstclient/hacks/NoFallHack.java +++ b/src/main/java/net/wurstclient/hacks/NoFallHack.java @@ -56,6 +56,7 @@ public final class NoFallHack extends Hack implements UpdateListener @Override protected void onEnable() { + WURST.getHax().antiHungerHack.setEnabled(false); EVENTS.add(UpdateListener.class, this); } diff --git a/src/main/java/net/wurstclient/hacks/NukerHack.java b/src/main/java/net/wurstclient/hacks/NukerHack.java index 45399f2e..52ed87dd 100644 --- a/src/main/java/net/wurstclient/hacks/NukerHack.java +++ b/src/main/java/net/wurstclient/hacks/NukerHack.java @@ -11,7 +11,6 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.function.BiPredicate; import java.util.function.Function; @@ -20,13 +19,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.block.Blocks; -import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.Vec3i; import net.wurstclient.Category; import net.wurstclient.events.LeftClickListener; import net.wurstclient.events.RenderListener; @@ -148,63 +145,70 @@ public final class NukerHack extends Hack if(mode.getSelected() == Mode.ID && id.getBlock() == Blocks.AIR) return; - ClientPlayerEntity player = MC.player; - Vec3d eyesPos = RotationUtils.getEyesPos().subtract(0.5, 0.5, 0.5); - BlockPos eyesBlock = BlockPos.ofFloored(RotationUtils.getEyesPos()); - double rangeSq = Math.pow(range.getValue(), 2); - int blockRange = (int)Math.ceil(range.getValue()); + Vec3d eyesVec = RotationUtils.getEyesPos(); + BlockPos eyesBlock = BlockPos.ofFloored(eyesVec); + double rangeSq = range.getValueSq(); + int blockRange = range.getValueCeil(); - Vec3i rangeVec = new Vec3i(blockRange, blockRange, blockRange); - BlockPos min = eyesBlock.subtract(rangeVec); - BlockPos max = eyesBlock.add(rangeVec); + Stream stream = + BlockUtils.getAllInBoxStream(eyesBlock, blockRange) + .filter(pos -> pos.getSquaredDistance(eyesVec) <= rangeSq) + .filter(BlockUtils::canBeClicked) + .filter(mode.getSelected().getValidator(this)).sorted(Comparator + .comparingDouble(pos -> pos.getSquaredDistance(eyesVec))); - ArrayList blocks = BlockUtils.getAllInBox(min, max); - Stream stream = blocks.parallelStream(); - - List blocks2 = stream - .filter(pos -> eyesPos.squaredDistanceTo(Vec3d.of(pos)) <= rangeSq) - .filter(BlockUtils::canBeClicked) - .filter(mode.getSelected().getValidator(this)) - .sorted(Comparator.comparingDouble( - pos -> eyesPos.squaredDistanceTo(Vec3d.of(pos)))) - .collect(Collectors.toList()); - - if(player.getAbilities().creativeMode) + // Break all blocks in creative mode + if(MC.player.getAbilities().creativeMode) { - Stream stream2 = blocks2.parallelStream(); - for(Set set : prevBlocks) - stream2 = stream2.filter(pos -> !set.contains(pos)); - List blocks3 = stream2.collect(Collectors.toList()); - - prevBlocks.addLast(new HashSet<>(blocks3)); - while(prevBlocks.size() > 5) - prevBlocks.removeFirst(); - - if(!blocks3.isEmpty()) - currentBlock = blocks3.get(0); - MC.interactionManager.cancelBlockBreaking(); renderer.resetProgress(); - BlockBreaker.breakBlocksWithPacketSpam(blocks3); + + ArrayList blocks = filterOutRecentBlocks(stream); + if(blocks.isEmpty()) + return; + + currentBlock = blocks.get(0); + BlockBreaker.breakBlocksWithPacketSpam(blocks); return; } - for(BlockPos pos : blocks2) - if(BlockBreaker.breakOneBlock(pos)) - { - currentBlock = pos; - break; - } + // Break the first valid block in survival mode + currentBlock = + stream.filter(BlockBreaker::breakOneBlock).findFirst().orElse(null); if(currentBlock == null) + { MC.interactionManager.cancelBlockBreaking(); + renderer.resetProgress(); + return; + } - if(currentBlock != null && BlockUtils.getHardness(currentBlock) < 1) + if(BlockUtils.getHardness(currentBlock) < 1) renderer.updateProgress(); else renderer.resetProgress(); } + /* + * Waits 5 ticks before trying to break the same block again, which + * makes it much more likely that the server will accept the block + * breaking packets. + */ + private ArrayList filterOutRecentBlocks(Stream stream) + { + for(Set set : prevBlocks) + stream = stream.filter(pos -> !set.contains(pos)); + + ArrayList blocks = + stream.collect(Collectors.toCollection(ArrayList::new)); + + prevBlocks.addLast(new HashSet<>(blocks)); + while(prevBlocks.size() > 5) + prevBlocks.removeFirst(); + + return blocks; + } + @Override public void onLeftClick(LeftClickEvent event) { diff --git a/src/main/java/net/wurstclient/hacks/ProtectHack.java b/src/main/java/net/wurstclient/hacks/ProtectHack.java index b3d3132b..7e1fe6d7 100644 --- a/src/main/java/net/wurstclient/hacks/ProtectHack.java +++ b/src/main/java/net/wurstclient/hacks/ProtectHack.java @@ -285,7 +285,6 @@ public final class ProtectHack extends Hack return; // attack enemy - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(MC.player, enemy); swingHand.swing(Hand.MAIN_HAND); speed.resetTimer(); diff --git a/src/main/java/net/wurstclient/hacks/TemplateToolHack.java b/src/main/java/net/wurstclient/hacks/TemplateToolHack.java new file mode 100644 index 00000000..d35cace9 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/TemplateToolHack.java @@ -0,0 +1,512 @@ +/* + * 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.hacks; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +import org.joml.Matrix4f; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.opengl.GL11; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.BufferRenderer; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormat; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.InputUtil; +import net.minecraft.client.util.Window; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.wurstclient.Category; +import net.wurstclient.events.GUIRenderListener; +import net.wurstclient.events.RenderListener; +import net.wurstclient.events.UpdateListener; +import net.wurstclient.hack.Hack; +import net.wurstclient.hacks.templatetool.Area; +import net.wurstclient.hacks.templatetool.ChooseNameScreen; +import net.wurstclient.hacks.templatetool.Step; +import net.wurstclient.hacks.templatetool.Template; +import net.wurstclient.util.BlockUtils; +import net.wurstclient.util.ChatUtils; +import net.wurstclient.util.RegionPos; +import net.wurstclient.util.RenderUtils; +import net.wurstclient.util.json.JsonUtils; + +public final class TemplateToolHack extends Hack + implements UpdateListener, RenderListener, GUIRenderListener +{ + private Step step; + private BlockPos posLookingAt; + private Area area; + private Template template; + private File file; + + public TemplateToolHack() + { + super("TemplateTool"); + setCategory(Category.BLOCKS); + } + + @Override + public void onEnable() + { + // disable conflicting hacks + WURST.getHax().autoBuildHack.setEnabled(false); + WURST.getHax().bowAimbotHack.setEnabled(false); + WURST.getHax().excavatorHack.setEnabled(false); + + step = Step.START_POS; + + EVENTS.add(UpdateListener.class, this); + EVENTS.add(RenderListener.class, this); + EVENTS.add(GUIRenderListener.class, this); + } + + @Override + public void onDisable() + { + EVENTS.remove(UpdateListener.class, this); + EVENTS.remove(RenderListener.class, this); + EVENTS.remove(GUIRenderListener.class, this); + + for(Step step : Step.values()) + step.setPos(null); + posLookingAt = null; + area = null; + template = null; + file = null; + } + + @Override + public void onUpdate() + { + // select position steps + if(step.doesSelectPos()) + { + // continue with next step + if(step.getPos() != null && InputUtil + .isKeyPressed(MC.getWindow().getHandle(), GLFW.GLFW_KEY_ENTER)) + { + step = Step.values()[step.ordinal() + 1]; + + // delete posLookingAt + if(!step.doesSelectPos()) + posLookingAt = null; + + return; + } + + if(MC.crosshairTarget instanceof BlockHitResult bHitResult) + { + // set posLookingAt + posLookingAt = bHitResult.getBlockPos(); + + // offset if sneaking + if(MC.options.sneakKey.isPressed()) + posLookingAt = posLookingAt.offset(bHitResult.getSide()); + + }else + posLookingAt = null; + + // set selected position + if(posLookingAt != null && MC.options.useKey.isPressed()) + step.setPos(posLookingAt); + + // scanning area step + }else if(step == Step.SCAN_AREA) + { + // initialize area + if(area == null) + { + area = new Area(Step.START_POS.getPos(), Step.END_POS.getPos()); + Step.START_POS.setPos(null); + Step.END_POS.setPos(null); + } + + // scan area + for(int i = 0; i < area.getScanSpeed() + && area.getIterator().hasNext(); i++) + { + area.setScannedBlocks(area.getScannedBlocks() + 1); + BlockPos pos = area.getIterator().next(); + + if(!BlockUtils.getState(pos).isReplaceable()) + area.getBlocksFound().add(pos); + } + + // update progress + area.setProgress( + (float)area.getScannedBlocks() / (float)area.getTotalBlocks()); + + // continue with next step + if(!area.getIterator().hasNext()) + step = Step.values()[step.ordinal() + 1]; + + // creating template step + }else if(step == Step.CREATE_TEMPLATE) + { + // initialize template + if(template == null) + template = new Template(Step.FIRST_BLOCK.getPos(), + area.getBlocksFound().size()); + + // sort blocks by distance + if(!area.getBlocksFound().isEmpty()) + { + // move blocks to TreeSet + int min = Math.max(0, + area.getBlocksFound().size() - template.getScanSpeed()); + for(int i = area.getBlocksFound().size() - 1; i >= min; i--) + { + BlockPos pos = area.getBlocksFound().get(i); + template.getRemainingBlocks().add(pos); + area.getBlocksFound().remove(i); + } + + // update progress + template.setProgress((float)template.getRemainingBlocks().size() + / (float)template.getTotalBlocks()); + + return; + } + + // add closest block first + if(template.getSortedBlocks().isEmpty() + && !template.getRemainingBlocks().isEmpty()) + { + BlockPos first = template.getRemainingBlocks().first(); + template.getSortedBlocks().add(first); + template.getRemainingBlocks().remove(first); + template.setLastAddedBlock(first); + } + + // add remaining blocks + for(int i = 0; i < template.getScanSpeed() + && !template.getRemainingBlocks().isEmpty(); i++) + { + BlockPos current = template.getRemainingBlocks().first(); + double dCurrent = Double.MAX_VALUE; + + for(BlockPos pos : template.getRemainingBlocks()) + { + double dPos = + template.getLastAddedBlock().getSquaredDistance(pos); + if(dPos >= dCurrent) + continue; + + for(Direction facing : Direction.values()) + { + BlockPos next = pos.offset(facing); + if(!template.getSortedBlocks().contains(next)) + continue; + + current = pos; + dCurrent = dPos; + } + } + + template.getSortedBlocks().add(current); + template.getRemainingBlocks().remove(current); + template.setLastAddedBlock(current); + } + + // update progress + template.setProgress((float)template.getRemainingBlocks().size() + / (float)template.getTotalBlocks()); + + // continue with next step + if(template.getSortedBlocks().size() == template.getTotalBlocks()) + { + step = Step.values()[step.ordinal() + 1]; + MC.setScreen(new ChooseNameScreen()); + } + } + } + + @Override + public void onRender(MatrixStack matrixStack, float partialTicks) + { + // scale and offset + float scale = 7F / 8F; + double offset = (1.0 - scale) / 2.0; + + // GL settings + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_DEPTH_TEST); + + matrixStack.push(); + RenderSystem.setShader(GameRenderer::getPositionProgram); + + RegionPos region = RenderUtils.getCameraRegion(); + RenderUtils.applyRegionalRenderOffset(matrixStack, region); + + // area + if(area != null) + { + GL11.glEnable(GL11.GL_DEPTH_TEST); + + // recently scanned blocks + if(step == Step.SCAN_AREA && area.getProgress() < 1) + for(int i = Math.max(0, + area.getBlocksFound().size() + - area.getScanSpeed()); i < area.getBlocksFound() + .size(); i++) + { + BlockPos pos = area.getBlocksFound().get(i) + .subtract(region.toBlockPos()); + + matrixStack.push(); + matrixStack.translate(pos.getX(), pos.getY(), pos.getZ()); + matrixStack.translate(-0.005, -0.005, -0.005); + matrixStack.scale(1.01F, 1.01F, 1.01F); + + RenderSystem.setShaderColor(0, 1, 0, 0.15F); + RenderUtils.drawSolidBox(matrixStack); + + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + } + + matrixStack.push(); + matrixStack.translate(area.getMinX() + offset - region.x(), + area.getMinY() + offset, area.getMinZ() + offset - region.z()); + matrixStack.scale(area.getSizeX() + scale, area.getSizeY() + scale, + area.getSizeZ() + scale); + + // area scanner + if(area.getProgress() < 1) + { + matrixStack.push(); + matrixStack.translate(area.getProgress(), 0, 0); + matrixStack.scale(0, 1, 1); + + RenderSystem.setShaderColor(0, 1, 0, 0.3F); + RenderUtils.drawSolidBox(matrixStack); + + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + + // template scanner + }else if(template != null && template.getProgress() > 0) + { + matrixStack.push(); + matrixStack.translate(template.getProgress(), 0, 0); + matrixStack.scale(0, 1, 1); + + RenderSystem.setShaderColor(0, 1, 0, 0.3F); + RenderUtils.drawSolidBox(matrixStack); + + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + } + + // area box + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + + GL11.glDisable(GL11.GL_DEPTH_TEST); + } + + // sorted blocks + if(template != null) + for(BlockPos pos : template.getSortedBlocks()) + { + matrixStack.push(); + matrixStack.translate(pos.getX() - region.x(), pos.getY(), + pos.getZ() - region.z()); + matrixStack.translate(offset, offset, offset); + matrixStack.scale(scale, scale, scale); + + RenderSystem.setShaderColor(0F, 0F, 0F, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + } + + // selected positions + for(Step step : Step.SELECT_POSITION_STEPS) + { + BlockPos pos = step.getPos(); + if(pos == null) + continue; + + matrixStack.push(); + matrixStack.translate(pos.getX() - region.x(), pos.getY(), + pos.getZ() - region.z()); + matrixStack.translate(offset, offset, offset); + matrixStack.scale(scale, scale, scale); + + RenderSystem.setShaderColor(0, 1, 0, 0.15F); + RenderUtils.drawSolidBox(matrixStack); + + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + } + + // posLookingAt + if(posLookingAt != null) + { + matrixStack.push(); + matrixStack.translate(posLookingAt.getX() - region.x(), + posLookingAt.getY(), posLookingAt.getZ() - region.z()); + matrixStack.translate(offset, offset, offset); + matrixStack.scale(scale, scale, scale); + + RenderSystem.setShaderColor(0.25F, 0.25F, 0.25F, 0.15F); + RenderUtils.drawSolidBox(matrixStack); + + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + RenderUtils.drawOutlinedBox(matrixStack); + + matrixStack.pop(); + } + + matrixStack.pop(); + + // GL resets + RenderSystem.setShaderColor(1, 1, 1, 1); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glDisable(GL11.GL_BLEND); + } + + @Override + public void onRenderGUI(DrawContext context, float partialTicks) + { + // GL settings + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_CULL_FACE); + + MatrixStack matrixStack = context.getMatrices(); + matrixStack.push(); + + Matrix4f matrix = matrixStack.peek().getPositionMatrix(); + Tessellator tessellator = RenderSystem.renderThreadTesselator(); + + String message; + if(step.doesSelectPos() && step.getPos() != null) + message = "Press enter to confirm, or select a different position."; + else if(step == Step.FILE_NAME && file != null && file.exists()) + message = "WARNING: This file already exists."; + else + message = step.getMessage(); + + // 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); + + // background + RenderSystem.setShader(GameRenderer::getPositionProgram); + RenderSystem.setShaderColor(0, 0, 0, 0.5F); + BufferBuilder bufferBuilder = tessellator + .begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION); + bufferBuilder.vertex(matrix, 0, 0, 0); + bufferBuilder.vertex(matrix, msgWidth + 2, 0, 0); + bufferBuilder.vertex(matrix, msgWidth + 2, 10, 0); + bufferBuilder.vertex(matrix, 0, 10, 0); + BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); + + // text + RenderSystem.setShaderColor(1, 1, 1, 1); + context.drawText(tr, message, 2, 1, 0xffffffff, false); + + matrixStack.pop(); + + // GL resets + RenderSystem.setShaderColor(1, 1, 1, 1); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); + } + + public void saveFile() + { + step = Step.values()[step.ordinal() + 1]; + JsonObject json = new JsonObject(); + + // get facings + Direction front = MC.player.getHorizontalFacing(); + Direction left = front.rotateYCounterclockwise(); + + // add sorted blocks + JsonArray jsonBlocks = new JsonArray(); + for(BlockPos pos : template.getSortedBlocks()) + { + // translate + pos = pos.subtract(Step.FIRST_BLOCK.getPos()); + + // rotate + pos = new BlockPos(0, pos.getY(), 0).offset(front, pos.getZ()) + .offset(left, pos.getX()); + + // add to json + jsonBlocks.add(JsonUtils.GSON.toJsonTree( + new int[]{pos.getX(), pos.getY(), pos.getZ()}, int[].class)); + } + json.add("blocks", jsonBlocks); + + try(PrintWriter save = new PrintWriter(new FileWriter(file))) + { + // save file + save.print(JsonUtils.PRETTY_GSON.toJson(json)); + + // show success message + MutableText message = Text.literal("Saved template as "); + ClickEvent event = new ClickEvent(ClickEvent.Action.OPEN_FILE, + file.getParentFile().getAbsolutePath()); + MutableText link = Text.literal(file.getName()) + .styled(s -> s.withUnderline(true).withClickEvent(event)); + message.append(link); + ChatUtils.component(message); + + }catch(IOException e) + { + e.printStackTrace(); + + // show error message + ChatUtils.error("File could not be saved."); + } + + // disable TemplateTool + setEnabled(false); + } + + public void setFile(File file) + { + this.file = file; + } +} diff --git a/src/main/java/net/wurstclient/hacks/TpAuraHack.java b/src/main/java/net/wurstclient/hacks/TpAuraHack.java index 3c547156..cec37a05 100644 --- a/src/main/java/net/wurstclient/hacks/TpAuraHack.java +++ b/src/main/java/net/wurstclient/hacks/TpAuraHack.java @@ -134,7 +134,6 @@ public final class TpAuraHack extends Hack implements UpdateListener RotationUtils.getNeededRotations(entity.getBoundingBox().getCenter()) .sendPlayerLookPacket(); - WURST.getHax().criticalsHack.doCritical(); MC.interactionManager.attackEntity(player, entity); swingHand.swing(Hand.MAIN_HAND); speed.resetTimer(); diff --git a/src/main/java/net/wurstclient/hacks/TriggerBotHack.java b/src/main/java/net/wurstclient/hacks/TriggerBotHack.java index 2c3b66e9..8bc27558 100644 --- a/src/main/java/net/wurstclient/hacks/TriggerBotHack.java +++ b/src/main/java/net/wurstclient/hacks/TriggerBotHack.java @@ -157,7 +157,6 @@ public final class TriggerBotHack extends Hack return; WURST.getHax().autoSwordHack.setSlot(target); - WURST.getHax().criticalsHack.doCritical(); if(simulateMouseClick.isChecked()) { diff --git a/src/main/java/net/wurstclient/hacks/autocomplete/ModelSettings.java b/src/main/java/net/wurstclient/hacks/autocomplete/ModelSettings.java index 1288d1ca..e09a092e 100644 --- a/src/main/java/net/wurstclient/hacks/autocomplete/ModelSettings.java +++ b/src/main/java/net/wurstclient/hacks/autocomplete/ModelSettings.java @@ -24,29 +24,26 @@ public final class ModelSettings public final EnumSetting openAiModel = new EnumSetting<>( "OpenAI model", "The model to use for OpenAI API calls.\nRecommended models:\n\n" - + "\u00a7lGPT-4o-2024-05-13\u00a7r is the world's smartest model at" + + "\u00a7lGPT-4o-2024-08-06\u00a7r is one of the smartest models at" + " the time of writing and will often produce the best completions." + " However, it's meant to be an assistant rather than an" + " auto-completion system, so you will see it produce some odd" + " completions at times.\n\n" + "\u00a7lGPT-3.5-Turbo-Instruct\u00a7r is an older, non-chat model" + " based on GPT-3.5 that works well for auto-completion tasks.", - OpenAiModel.values(), OpenAiModel.GPT_4O_2024_05_13); + OpenAiModel.values(), OpenAiModel.GPT_4O_2024_08_06); public enum OpenAiModel { + GPT_4O_2024_08_06("gpt-4o-2024-08-06", true), GPT_4O_2024_05_13("gpt-4o-2024-05-13", true), + GPT_4O_MINI_2024_07_18("gpt-4o-mini-2024-07-18", true), GPT_4_TURBO_2024_04_09("gpt-4-turbo-2024-04-09", true), GPT_4_0125_PREVIEW("gpt-4-0125-preview", true), GPT_4_1106_PREVIEW("gpt-4-1106-preview", true), GPT_4_0613("gpt-4-0613", true), - GPT_4_0314("gpt-4-0314", true), - GPT_4_32K_0613("gpt-4-32k-0613", true), GPT_3_5_TURBO_0125("gpt-3.5-turbo-0125", true), GPT_3_5_TURBO_1106("gpt-3.5-turbo-1106", true), - GPT_3_5_TURBO_0613("gpt-3.5-turbo-0613", true), - GPT_3_5_TURBO_16K_0613("gpt-3.5-turbo-16k-0613", true), - GPT_3_5_TURBO_0301("gpt-3.5-turbo-0301", true), GPT_3_5_TURBO_INSTRUCT("gpt-3.5-turbo-instruct", false), DAVINCI_002("davinci-002", false), BABBAGE_002("babbage-002", false); diff --git a/src/main/java/net/wurstclient/hacks/chattranslator/FilterOwnMessagesSetting.java b/src/main/java/net/wurstclient/hacks/chattranslator/FilterOwnMessagesSetting.java new file mode 100644 index 00000000..7cbc3d53 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/chattranslator/FilterOwnMessagesSetting.java @@ -0,0 +1,46 @@ +/* + * 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.hacks.chattranslator; + +import java.util.regex.Pattern; + +import net.wurstclient.WurstClient; +import net.wurstclient.settings.CheckboxSetting; + +public class FilterOwnMessagesSetting extends CheckboxSetting +{ + private Pattern ownMessagePattern; + private String lastUsername; + + public FilterOwnMessagesSetting() + { + super("Filter own messages", + "description.wurst.setting.chattranslator.filter_own_messages", + true); + } + + public boolean isOwnMessage(String message) + { + updateOwnMessagePattern(); + return ownMessagePattern.matcher(message).find(); + } + + private void updateOwnMessagePattern() + { + String username = WurstClient.MC.getSession().getUsername(); + if(username.equals(lastUsername)) + return; + + String rankPattern = "(?:\\[[^\\]]+\\] ?){0,2}"; + String namePattern = Pattern.quote(username); + String regex = "^" + rankPattern + "[<\\[]?" + namePattern + "[>\\]:]"; + + ownMessagePattern = Pattern.compile(regex); + lastUsername = username; + } +} diff --git a/src/main/java/net/wurstclient/util/GoogleTranslate.java b/src/main/java/net/wurstclient/hacks/chattranslator/GoogleTranslate.java similarity index 64% rename from src/main/java/net/wurstclient/util/GoogleTranslate.java rename to src/main/java/net/wurstclient/hacks/chattranslator/GoogleTranslate.java index 705ca85b..705004e9 100644 --- a/src/main/java/net/wurstclient/util/GoogleTranslate.java +++ b/src/main/java/net/wurstclient/hacks/chattranslator/GoogleTranslate.java @@ -5,7 +5,7 @@ * 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.util; +package net.wurstclient.hacks.chattranslator; import java.io.BufferedReader; import java.io.IOException; @@ -16,6 +16,7 @@ import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; +import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -23,12 +24,46 @@ public enum GoogleTranslate { ; + private static final HashMap simplifyMap; + static + { + simplifyMap = new HashMap<>(); + simplifyMap.put(' ', ""); + simplifyMap.put('\r', ""); + simplifyMap.put('\n', ""); + simplifyMap.put('\t', ""); + simplifyMap.put('ä', "a"); + simplifyMap.put('ö', "o"); + simplifyMap.put('ü', "u"); + simplifyMap.put('á', "a"); + simplifyMap.put('é', "e"); + simplifyMap.put('í', "i"); + simplifyMap.put('ó', "o"); + simplifyMap.put('ú', "u"); + simplifyMap.put('à', "a"); + simplifyMap.put('è', "e"); + simplifyMap.put('ì', "i"); + simplifyMap.put('ò', "o"); + simplifyMap.put('ù', "u"); + simplifyMap.put('â', "a"); + simplifyMap.put('ê', "e"); + simplifyMap.put('î', "i"); + simplifyMap.put('ô', "o"); + simplifyMap.put('û', "u"); + simplifyMap.put('ã', "a"); + simplifyMap.put('õ', "o"); + simplifyMap.put('ñ', "n"); + simplifyMap.put('ç', "c"); + } + public static String translate(String text, String langFrom, String langTo) { String html = getHTML(text, langFrom, langTo); String translated = parseHTML(html); - if(text.equalsIgnoreCase(translated)) + // Return null if Google Translate just returned the original text, + // ignoring capitalization changes, whitespace, and broken characters + if(simplify(text).equals(simplify(translated))) return null; return translated; @@ -96,9 +131,10 @@ public enum GoogleTranslate Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); Matcher matcher = pattern.matcher(html); - matcher.find(); - String match = matcher.group(1); + if(!matcher.find()) + return null; + String match = matcher.group(1); if(match == null || match.isEmpty()) return null; @@ -106,4 +142,13 @@ public enum GoogleTranslate // which isn't bundled with Minecraft return org.apache.commons.lang3.StringEscapeUtils.unescapeHtml4(match); } + + private static String simplify(String text) + { + StringBuilder sb = new StringBuilder(); + for(char c : text.toLowerCase().toCharArray()) + sb.append(simplifyMap.getOrDefault(c, String.valueOf(c))); + + return sb.toString(); + } } diff --git a/src/main/java/net/wurstclient/hacks/chattranslator/LanguageSetting.java b/src/main/java/net/wurstclient/hacks/chattranslator/LanguageSetting.java new file mode 100644 index 00000000..fab2553f --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/chattranslator/LanguageSetting.java @@ -0,0 +1,116 @@ +/* + * 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.hacks.chattranslator; + +import net.minecraft.text.Text; +import net.wurstclient.settings.EnumSetting; + +public final class LanguageSetting extends EnumSetting +{ + private LanguageSetting(String name, String description, Language[] values, + Language selected) + { + super(name, description, values, selected); + } + + public static LanguageSetting withAutoDetect(String name, + String description, Language selected) + { + return new LanguageSetting(name, description, Language.values(), + selected); + } + + public static LanguageSetting withAutoDetect(String name, Language selected) + { + return new LanguageSetting(name, "", Language.values(), selected); + } + + public static LanguageSetting withoutAutoDetect(String name, + String description, Language selected) + { + Language[] values = Language.valuesWithoutAutoDetect(); + return new LanguageSetting(name, description, values, selected); + } + + public static LanguageSetting withoutAutoDetect(String name, + Language selected) + { + Language[] values = Language.valuesWithoutAutoDetect(); + return new LanguageSetting(name, "", values, selected); + } + + public enum Language + { + AUTO_DETECT("Detect Language", "auto"), + AFRIKAANS("Afrikaans", "af"), + ARABIC("Arabic", "ar"), + CZECH("Czech", "cs"), + CHINESE_SIMPLIFIED("Chinese (simplified)", "zh-CN"), + CHINESE_TRADITIONAL("Chinese (traditional)", "zh-TW"), + DANISH("Danish", "da"), + DUTCH("Dutch", "nl"), + ENGLISH("English", "en"), + FINNISH("Finnish", "fi"), + FRENCH("French", "fr"), + GERMAN("Deutsch!", "de"), + GREEK("Greek", "el"), + HINDI("Hindi", "hi"), + ITALIAN("Italian", "it"), + JAPANESE("Japanese", "ja"), + KOREAN("Korean", "ko"), + NORWEGIAN("Norwegian", "no"), + POLISH("Polish", "pl"), + PORTUGUESE("Portugese", "pt"), + RUSSIAN("Russian", "ru"), + SPANISH("Spanish", "es"), + SWAHILI("Swahili", "sw"), + SWEDISH("Swedish", "sv"), + TURKISH("Turkish", "tr"); + + private final String name; + private final String value; + private final String prefix; + + private Language(String name, String value) + { + this.name = name; + this.value = value; + prefix = "\u00a7a[\u00a7b" + name + "\u00a7a]:\u00a7r "; + } + + public String getValue() + { + return value; + } + + public String getPrefix() + { + return prefix; + } + + public Text prefixText(String s) + { + return Text.literal(prefix + s); + } + + @Override + public String toString() + { + return name; + } + + private static Language[] valuesWithoutAutoDetect() + { + Language[] allValues = values(); + Language[] valuesWithoutAuto = new Language[allValues.length - 1]; + System.arraycopy(allValues, 1, valuesWithoutAuto, 0, + valuesWithoutAuto.length); + return valuesWithoutAuto; + } + } +} diff --git a/src/main/java/net/wurstclient/hacks/chattranslator/WhatToTranslateSetting.java b/src/main/java/net/wurstclient/hacks/chattranslator/WhatToTranslateSetting.java new file mode 100644 index 00000000..bb83cd56 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/chattranslator/WhatToTranslateSetting.java @@ -0,0 +1,54 @@ +/* + * 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.hacks.chattranslator; + +import net.wurstclient.settings.EnumSetting; + +public final class WhatToTranslateSetting + extends EnumSetting +{ + public WhatToTranslateSetting() + { + super("Translate", "", WhatToTranslate.values(), + WhatToTranslate.RECEIVED_MESSAGES); + } + + public boolean includesReceived() + { + return getSelected().received; + } + + public boolean includesSent() + { + return getSelected().sent; + } + + public enum WhatToTranslate + { + RECEIVED_MESSAGES("Received messages", true, false), + SENT_MESSAGES("Sent messages", false, true), + BOTH("Both", true, true); + + private final String name; + private final boolean received; + private final boolean sent; + + private WhatToTranslate(String name, boolean received, boolean sent) + { + this.name = name; + this.received = received; + this.sent = sent; + } + + @Override + public String toString() + { + return name; + } + } +} diff --git a/src/main/java/net/wurstclient/hacks/templatetool/Area.java b/src/main/java/net/wurstclient/hacks/templatetool/Area.java new file mode 100644 index 00000000..98bd7732 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/templatetool/Area.java @@ -0,0 +1,122 @@ +/* + * 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.hacks.templatetool; + +import java.util.ArrayList; +import java.util.Iterator; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.wurstclient.util.BlockUtils; + +public final class Area +{ + private final int minX, minY, minZ; + private final int sizeX, sizeY, sizeZ; + + private final int totalBlocks, scanSpeed; + private final Iterator iterator; + + private int scannedBlocks; + private float progress; + + private final ArrayList blocksFound = new ArrayList<>(); + + public Area(BlockPos start, BlockPos end) + { + int startX = start.getX(); + int startY = start.getY(); + int startZ = start.getZ(); + + int endX = end.getX(); + int endY = end.getY(); + int endZ = end.getZ(); + + minX = Math.min(startX, endX); + minY = Math.min(startY, endY); + minZ = Math.min(startZ, endZ); + + sizeX = Math.abs(startX - endX); + sizeY = Math.abs(startY - endY); + sizeZ = Math.abs(startZ - endZ); + + totalBlocks = (sizeX + 1) * (sizeY + 1) * (sizeZ + 1); + scanSpeed = MathHelper.clamp(totalBlocks / 30, 1, 1024); + iterator = BlockUtils.getAllInBox(start, end).iterator(); + } + + public int getScannedBlocks() + { + return scannedBlocks; + } + + public void setScannedBlocks(int scannedBlocks) + { + this.scannedBlocks = scannedBlocks; + } + + public float getProgress() + { + return progress; + } + + public void setProgress(float progress) + { + this.progress = progress; + } + + public int getMinX() + { + return minX; + } + + public int getMinY() + { + return minY; + } + + public int getMinZ() + { + return minZ; + } + + public int getSizeX() + { + return sizeX; + } + + public int getSizeY() + { + return sizeY; + } + + public int getSizeZ() + { + return sizeZ; + } + + public int getTotalBlocks() + { + return totalBlocks; + } + + public int getScanSpeed() + { + return scanSpeed; + } + + public Iterator getIterator() + { + return iterator; + } + + public ArrayList getBlocksFound() + { + return blocksFound; + } +} diff --git a/src/main/java/net/wurstclient/hacks/templatetool/ChooseNameScreen.java b/src/main/java/net/wurstclient/hacks/templatetool/ChooseNameScreen.java new file mode 100644 index 00000000..2382136c --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/templatetool/ChooseNameScreen.java @@ -0,0 +1,140 @@ +/* + * 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.hacks.templatetool; + +import java.nio.file.Path; + +import org.lwjgl.glfw.GLFW; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Drawable; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.Text; +import net.wurstclient.WurstClient; + +public final class ChooseNameScreen extends Screen +{ + private static final WurstClient WURST = WurstClient.INSTANCE; + + private TextFieldWidget nameField; + private ButtonWidget doneButton; + private ButtonWidget cancelButton; + + public ChooseNameScreen() + { + super(ScreenTexts.EMPTY); + } + + @Override + public void init() + { + TextRenderer tr = client.textRenderer; + int middleX = width / 2; + int middleY = height / 2; + + nameField = new TextFieldWidget(tr, middleX - 99, middleY + 16, 198, 16, + Text.empty()); + nameField.setDrawsBackground(false); + nameField.setMaxLength(32); + nameField.setFocused(true); + nameField.setEditableColor(0xFFFFFF); + addSelectableChild(nameField); + setFocused(nameField); + + doneButton = ButtonWidget.builder(Text.literal("Done"), b -> done()) + .dimensions(middleX - 75, middleY + 38, 150, 20).build(); + addDrawableChild(doneButton); + + cancelButton = + ButtonWidget.builder(Text.literal("Cancel"), b -> cancel()) + .dimensions(middleX - 50, middleY + 62, 100, 15).build(); + addDrawableChild(cancelButton); + } + + private void done() + { + client.setScreen(null); + WURST.getHax().templateToolHack.saveFile(); + } + + private void cancel() + { + client.setScreen(null); + WURST.getHax().templateToolHack.setEnabled(false); + } + + @Override + public void tick() + { + if(nameField.getText().isEmpty()) + return; + + Path folder = WURST.getHax().autoBuildHack.getFolder(); + Path file = folder.resolve(nameField.getText() + ".json"); + WURST.getHax().templateToolHack.setFile(file.toFile()); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) + { + switch(keyCode) + { + case GLFW.GLFW_KEY_ESCAPE: + cancelButton.onPress(); + break; + + case GLFW.GLFW_KEY_ENTER: + doneButton.onPress(); + break; + } + + return super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, + float partialTicks) + { + // super.render(context, mouseX, mouseY, partialTicks); + applyBlur(partialTicks); + for(Drawable drawable : drawables) + drawable.render(context, mouseX, mouseY, partialTicks); + + // middle + int middleX = width / 2; + int middleY = height / 2; + + // background positions + int x1 = middleX - 100; + int y1 = middleY + 15; + int x2 = middleX + 100; + int y2 = middleY + 26; + + // background + context.fill(x1, y1, x2, y2, 0x80000000); + + // name field + nameField.render(context, mouseX, mouseY, partialTicks); + } + + @Override + public boolean shouldPause() + { + return false; + } + + @Override + public boolean shouldCloseOnEsc() + { + return false; + } +} diff --git a/src/main/java/net/wurstclient/hacks/templatetool/Step.java b/src/main/java/net/wurstclient/hacks/templatetool/Step.java new file mode 100644 index 00000000..8f9d7bf1 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/templatetool/Step.java @@ -0,0 +1,61 @@ +/* + * 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.hacks.templatetool; + +import net.minecraft.util.math.BlockPos; + +public enum Step +{ + START_POS("Select start position.", true), + + END_POS("Select end position.", true), + + SCAN_AREA("Scanning area...", false), + + FIRST_BLOCK("Select the first block to be placed by AutoBuild.", true), + + CREATE_TEMPLATE("Creating template...", false), + + FILE_NAME("Choose a name for this template.", false), + + SAVE_FILE("Saving file...", false); + + public static final Step[] SELECT_POSITION_STEPS = + {START_POS, END_POS, FIRST_BLOCK}; + + private final String message; + private final boolean selectPos; + + private BlockPos pos; + + private Step(String message, boolean selectPos) + { + this.message = message; + this.selectPos = selectPos; + } + + public BlockPos getPos() + { + return pos; + } + + public void setPos(BlockPos pos) + { + this.pos = pos; + } + + public String getMessage() + { + return message; + } + + public boolean doesSelectPos() + { + return selectPos; + } +} diff --git a/src/main/java/net/wurstclient/hacks/templatetool/Template.java b/src/main/java/net/wurstclient/hacks/templatetool/Template.java new file mode 100644 index 00000000..12063e31 --- /dev/null +++ b/src/main/java/net/wurstclient/hacks/templatetool/Template.java @@ -0,0 +1,82 @@ +/* + * 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.hacks.templatetool; + +import java.util.LinkedHashSet; +import java.util.TreeSet; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; + +public final class Template +{ + private final int totalBlocks, scanSpeed; + private float progress; + + private final TreeSet remainingBlocks; + private final LinkedHashSet sortedBlocks = new LinkedHashSet<>(); + private BlockPos lastAddedBlock; + + public Template(BlockPos firstBlock, int blocksFound) + { + totalBlocks = blocksFound; + scanSpeed = MathHelper.clamp(blocksFound / 15, 1, 1024); + + remainingBlocks = new TreeSet<>((o1, o2) -> { + + // compare distance to start pos + int distanceDiff = Double.compare(o1.getSquaredDistance(firstBlock), + o2.getSquaredDistance(firstBlock)); + if(distanceDiff != 0) + return distanceDiff; + + // fallback in case of same distance + return o1.compareTo(o2); + }); + } + + public float getProgress() + { + return progress; + } + + public void setProgress(float progress) + { + this.progress = progress; + } + + public BlockPos getLastAddedBlock() + { + return lastAddedBlock; + } + + public void setLastAddedBlock(BlockPos lastAddedBlock) + { + this.lastAddedBlock = lastAddedBlock; + } + + public int getTotalBlocks() + { + return totalBlocks; + } + + public int getScanSpeed() + { + return scanSpeed; + } + + public TreeSet getRemainingBlocks() + { + return remainingBlocks; + } + + public LinkedHashSet getSortedBlocks() + { + return sortedBlocks; + } +} diff --git a/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java b/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java index 7dde6be2..46a2d0e8 100644 --- a/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java +++ b/src/main/java/net/wurstclient/mixin/ClientPlayerInteractionManagerMixin.java @@ -20,6 +20,7 @@ import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.client.network.SequencedPacketCreator; import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action; @@ -33,6 +34,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.wurstclient.event.EventManager; import net.wurstclient.events.BlockBreakingProgressListener.BlockBreakingProgressEvent; +import net.wurstclient.events.PlayerAttacksEntityListener.PlayerAttacksEntityEvent; import net.wurstclient.events.StopUsingItemListener.StopUsingItemEvent; import net.wurstclient.mixinterface.IClientPlayerInteractionManager; @@ -61,6 +63,17 @@ public abstract class ClientPlayerInteractionManagerMixin EventManager.fire(StopUsingItemEvent.INSTANCE); } + @Inject(at = @At("HEAD"), + method = "attackEntity(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/entity/Entity;)V") + private void onAttackEntity(PlayerEntity player, Entity target, + CallbackInfo ci) + { + if(player != client.player) + return; + + EventManager.fire(new PlayerAttacksEntityEvent(target)); + } + @Override public void windowClick_PICKUP(int slot) { diff --git a/src/main/java/net/wurstclient/mixin/DisconnectedScreenMixin.java b/src/main/java/net/wurstclient/mixin/DisconnectedScreenMixin.java index c166585c..dad7da24 100644 --- a/src/main/java/net/wurstclient/mixin/DisconnectedScreenMixin.java +++ b/src/main/java/net/wurstclient/mixin/DisconnectedScreenMixin.java @@ -75,15 +75,14 @@ public class DisconnectedScreenMixin extends Screen private void addReconnectButtons() { - ButtonWidget reconnectButton = grid.add( - ButtonWidget.builder(Text.literal("Reconnect"), - b -> LastServerRememberer.reconnect(parent)).build(), - grid.copyPositioner().margin(2).marginTop(-6)); + ButtonWidget reconnectButton = grid.add(ButtonWidget + .builder(Text.literal("Reconnect"), + b -> LastServerRememberer.reconnect(parent)) + .width(200).build()); - autoReconnectButton = grid.add( - ButtonWidget.builder(Text.literal("AutoReconnect"), - b -> pressAutoReconnect()).build(), - grid.copyPositioner().margin(2)); + autoReconnectButton = grid.add(ButtonWidget + .builder(Text.literal("AutoReconnect"), b -> pressAutoReconnect()) + .width(200).build()); grid.refreshPositions(); Stream.of(reconnectButton, autoReconnectButton) diff --git a/src/main/java/net/wurstclient/mixin/LightmapTextureManagerMixin.java b/src/main/java/net/wurstclient/mixin/LightmapTextureManagerMixin.java new file mode 100644 index 00000000..3174f6d2 --- /dev/null +++ b/src/main/java/net/wurstclient/mixin/LightmapTextureManagerMixin.java @@ -0,0 +1,33 @@ +/* + * 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.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.client.render.LightmapTextureManager; +import net.wurstclient.WurstClient; + +@Mixin(LightmapTextureManager.class) +public class LightmapTextureManagerMixin +{ + /** + * Stops the other darkness effect in caves when AntiBlind is enabled. + */ + @Inject(at = @At("HEAD"), + method = "getDarknessFactor(F)F", + cancellable = true) + private void onGetDarknessFactor(float delta, + CallbackInfoReturnable cir) + { + if(WurstClient.INSTANCE.getHax().antiBlindHack.isEnabled()) + cir.setReturnValue(0F); + } +} diff --git a/src/main/java/net/wurstclient/mixin/MinecraftClientMixin.java b/src/main/java/net/wurstclient/mixin/MinecraftClientMixin.java index 55989b9f..3afc973f 100644 --- a/src/main/java/net/wurstclient/mixin/MinecraftClientMixin.java +++ b/src/main/java/net/wurstclient/mixin/MinecraftClientMixin.java @@ -75,6 +75,10 @@ public abstract class MinecraftClientMixin ordinal = 0), method = "tick()V") private void onHandleInputEvents(CallbackInfo ci) { + // Make sure this event is not fired outside of gameplay + if(player == null) + return; + EventManager.fire(HandleInputEvent.INSTANCE); } diff --git a/src/main/java/net/wurstclient/other_features/NoChatReportsOtf.java b/src/main/java/net/wurstclient/other_features/NoChatReportsOtf.java index 18782ab6..8e5b10f8 100644 --- a/src/main/java/net/wurstclient/other_features/NoChatReportsOtf.java +++ b/src/main/java/net/wurstclient/other_features/NoChatReportsOtf.java @@ -16,10 +16,14 @@ import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.network.encryption.ClientPlayerSession; import net.minecraft.network.message.MessageChain; import net.minecraft.network.message.MessageSignatureData; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; import net.minecraft.text.Text; +import net.minecraft.text.TranslatableTextContent; import net.wurstclient.Category; import net.wurstclient.DontBlock; import net.wurstclient.SearchTags; +import net.wurstclient.events.ChatInputListener; import net.wurstclient.events.UpdateListener; import net.wurstclient.other_feature.OtherFeature; import net.wurstclient.settings.CheckboxSetting; @@ -29,7 +33,7 @@ import net.wurstclient.util.ChatUtils; @SearchTags({"no chat reports", "NoEncryption", "no encryption", "NoChatSigning", "no chat signing"}) public final class NoChatReportsOtf extends OtherFeature - implements UpdateListener + implements UpdateListener, ChatInputListener { private final CheckboxSetting disableSignatures = new CheckboxSetting("Disable signatures", true) @@ -47,6 +51,7 @@ public final class NoChatReportsOtf extends OtherFeature addSetting(disableSignatures); ClientLoginConnectionEvents.INIT.register(this::onLoginStart); + EVENTS.add(ChatInputListener.class, this); } @Override @@ -71,6 +76,33 @@ public final class NoChatReportsOtf extends OtherFeature EVENTS.remove(UpdateListener.class, this); } + @Override + public void onReceivedMessage(ChatInputEvent event) + { + if(!isActive()) + return; + + Text originalText = event.getComponent(); + if(!(originalText + .getContent() instanceof TranslatableTextContent trContent)) + return; + + if(!trContent.getKey().equals("chat.disabled.missingProfileKey")) + return; + + event.cancel(); + + ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, + "https://wurst.wiki/ncr"); + HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, + Text.literal("Original message: ").append(originalText)); + + ChatUtils.component(Text.literal( + "The server is refusing to let you chat without enabling chat reports. See wurst.wiki/ncr") + .styled( + s -> s.withClickEvent(clickEvent).withHoverEvent(hoverEvent))); + } + private void onLoginStart(ClientLoginNetworkHandler handler, MinecraftClient client) { diff --git a/src/main/java/net/wurstclient/other_features/ZoomOtf.java b/src/main/java/net/wurstclient/other_features/ZoomOtf.java index 7e6571e2..a168091d 100644 --- a/src/main/java/net/wurstclient/other_features/ZoomOtf.java +++ b/src/main/java/net/wurstclient/other_features/ZoomOtf.java @@ -32,6 +32,11 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener + " zooming to zoom in even further.", true); + private final CheckboxSetting zoomInScreens = new CheckboxSetting( + "Zoom in screens", "If enabled, you can also zoom while a screen (chat," + + " inventory, etc.) is open.", + false); + private final TextFieldSetting keybind = new TextFieldSetting("Keybind", "Determines the zoom keybind.\n\n" + "Instead of editing this value manually, you should go to Wurst" @@ -48,6 +53,7 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener + "Go to Wurst Options -> Zoom to change this keybind."); addSetting(level); addSetting(scroll); + addSetting(zoomInScreens); addSetting(keybind); EVENTS.add(MouseScrollListener.class, this); } @@ -121,6 +127,9 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener private boolean isZoomKeyPressed() { + if(MC.currentScreen != null && !zoomInScreens.isChecked()) + return false; + return InputUtil.isKeyPressed(MC.getWindow().getHandle(), InputUtil.fromTranslationKey(keybind.getValue()).getCode()); } diff --git a/src/main/resources/assets/wurst/translations/cs_cz.json b/src/main/resources/assets/wurst/translations/cs_cz.json index 02a6acae..cd9f1bbf 100644 --- a/src/main/resources/assets/wurst/translations/cs_cz.json +++ b/src/main/resources/assets/wurst/translations/cs_cz.json @@ -4,7 +4,7 @@ "description.wurst.hack.antiafk": "Prochází se náhodně, aby vás skryl před AFK detektory.", "description.wurst.hack.antiblind": "Zabraňuje blindness a efekty tmy.\nNekompatibilní s OptiFinem.", "description.wurst.hack.anticactus": "Chrání vás před poškozením kaktusem.", - "description.wurst.hack.antihunger": "Zpomalí váš hlad, když chodíte.", + "description.wurst.hack.antihunger": "Zpomalí váš hlad, když chodíte.\n\n§c§lUPOZORNĚNÍ:§r Byly hlášeny případy, kdy tento hack způsobil zvýšené poškození pádem za specifických, neznámých podmínek.", "description.wurst.hack.antiknockback": "Zabraní strkání hráči a moby.", "description.wurst.hack.antispam": "Blokuje spam chatu přidáním čítače k opakovaným zprávám.", "description.wurst.hack.antiwaterpush": "Zabraňuje posouvání vodou.", @@ -51,7 +51,7 @@ "description.wurst.hack.cameradistance": "Umožňuje změnit vzdálenost kamery ve 3. osobě.", "description.wurst.hack.cameranoclip": "Umožňuje kameře ve třetí osobě procházet zdmi.", "description.wurst.hack.cavefinder": "Pomáhá najít jeskyně tím, že je zvýrazní vybranou barvou.", - "description.wurst.hack.chattranslator": "Překládá příchozí zprávy v chatu pomocí Google Translate.", + "description.wurst.hack.chattranslator": "Překládá zprávy v chatu pomocí Google Translate.", "description.wurst.hack.chestesp": "Zvýrazní okolní truhly.", "description.wurst.hack.clickaura": "S každým kliknutím automaticky zaútočí na nejbližší platnou entitu.\n\n§c§lWAROVÁNÍ:§r ClickAury sjou obecně podezřelejší než Killaury a jsou i snadněji rozpoznatelné pro pluginy. Doporučuje se namísto nich používat buďto Killauru, či TriggerBota.", "description.wurst.hack.clickgui": "Okenní rozhraní ClickGUI.", diff --git a/src/main/resources/assets/wurst/translations/de_de.json b/src/main/resources/assets/wurst/translations/de_de.json index 0c95e32b..39bfd0d5 100644 --- a/src/main/resources/assets/wurst/translations/de_de.json +++ b/src/main/resources/assets/wurst/translations/de_de.json @@ -5,7 +5,7 @@ "description.wurst.hack.antiafk": "Läuft zufällig durch die Gegend, um dich vor Anti-AFK Plugins zu verstecken.", "description.wurst.hack.antiblind": "Verhindert Blindheits- und Dunkelheitseffekte.\nNicht kompatibel mit OptiFine.", "description.wurst.hack.anticactus": "Schützt dich vor Kakteen.", - "description.wurst.hack.antihunger": "Verlangsamt deinen Hunger während du läufst.", + "description.wurst.hack.antihunger": "Verlangsamt deinen Hunger während du läufst.\n\n§c§lWARNUNG:§r Nutzer haben berichtet, dass dieser Hack unter bestimmten, unbekannten Bedingungen extra Fallschaden verursachen kann.", "description.wurst.hack.antiknockback": "Verhindert dass du von Mobs und Spielern weggeschubst wirst.", "description.wurst.hack.antispam": "Blockiert Chat-Spam, indem es wiederholte Nachrichten durch einen Zähler ersetzt.", "description.wurst.hack.antiwaterpush": "Verhindert dass du von fließendem Wasser weggeschubst wirst.", @@ -54,7 +54,12 @@ "description.wurst.hack.cameradistance": "Ermöglicht dir, den Kamera-Abstand in der 3rd-Person-Ansicht zu ändern.", "description.wurst.hack.cameranoclip": "Ermöglicht der Kamera in der 3rd-Person-Ansicht, durch Wände zu gehen.", "description.wurst.hack.cavefinder": "Markiert Höhlen in der ausgewählten Farbe, sodass du sie leichter finden kannst.", - "description.wurst.hack.chattranslator": "Übersetzt eingehende Chat-Nachrichten mit dem Google-Übersetzer.", + "description.wurst.hack.chattranslator": "Übersetzt Chat-Nachrichten mit dem Google-Übersetzer.", + "description.wurst.setting.chattranslator.your_language": "Die Sprache, die du am besten verstehen kannst.\n\nDeine empfangenen Nachrichten werden immer in diese Sprache übersetzt (falls aktiviert).\n\nWenn \"Detect sent language\" ausgeschaltet ist, geht der Übersetzer davon aus, dass alle von dir gesendeten Nachrichten in dieser Sprache sind.", + "description.wurst.setting.chattranslator.other_language": "Die Sprache, die von anderen Spielern auf dem Server am meisten benutzt wird.\n\nDeine gesendeten Nachrichten werden immer in diese Sprache übersetzt (falls aktiviert).\n\nWenn \"Detect received language\" ausgeschaltet ist, geht der Übersetzer davon aus, dass alle empfangenen Nachrichten in dieser Sprache sind.", + "description.wurst.setting.chattranslator.detect_received_language": "Erkennt automatisch die Sprache von empfangenen Nachrichten.\n\nNützlich, wenn andere Spieler eine Mischung verschiedener Sprachen benutzen.\n\nWenn alle die gleiche Sprache benutzen, kannst du diese Einstellung ausschalten, um die Genauigkeit der Übersetzungen zu verbessern.", + "description.wurst.setting.chattranslator.detect_sent_language": "Erkennt automatisch die Sprache von gesendeten Nachrichten.\n\nNützlich, wenn du eine Mischung verschiedener Sprachen benutzt.\n\nWenn du immer die gleiche Sprache benutzt, kannst du diese Einstellung ausschalten, um die Genauigkeit der Übersetzungen zu verbessern.", + "description.wurst.setting.chattranslator.filter_own_messages": "Übersetzt keine empfangenen Nachrichten, die so aussehen, als ob sie von dir selbst gesendet wurden.\n\nChatTranslator versucht, deine eigenen Nachrichten anhand gängiger Chat-Formate wie \"\", \"[Name]\" oder \"Name:\" zu erkennen. Auf manchen Servern funktioniert das eventuell nicht richtig.", "description.wurst.hack.chestesp": "Markiert Kisten in deiner Umgebung.", "description.wurst.hack.clickaura": "Greift bei jedem Mausklick automatisch den nächsten Mob oder Spieler an.\n\n§c§lWARNUNG:§r ClickAuras sind generell auffälliger als Killauras und für Plugins leichter zu erkennen. Es ist empfohlen, statt ClickAura Killaura oder TriggerBot zu benutzen.", "description.wurst.hack.clickgui": "Fenster-basierte ClickGUI.", diff --git a/src/main/resources/assets/wurst/translations/en_us.json b/src/main/resources/assets/wurst/translations/en_us.json index 677edaa2..f7aec70c 100644 --- a/src/main/resources/assets/wurst/translations/en_us.json +++ b/src/main/resources/assets/wurst/translations/en_us.json @@ -1,6 +1,7 @@ { "description.wurst.hack.aimassist": "Helps you aim at nearby entities.", "description.wurst.setting.aimassist.fov": "Field Of View - how far away from your crosshair an entity can be before it's ignored.\n360° = aims at entities all around you.", + "description.wurst.setting.aimassist.ignore_mouse_input": "Ignores some of your mouse input while AimAssist is aiming. This makes it harder for you to accidentally aim away from the target.", "description.wurst.setting.aimassist.check_line_of_sight": "Won't aim at entities behind blocks.", "description.wurst.setting.aimassist.aim_while_blocking": "Keeps aiming at entities while you're blocking with a shield or using items.", "description.wurst.hack.airplace": "Allows you to place blocks in mid-air.", @@ -22,7 +23,7 @@ "description.wurst.hack.antiblind": "Prevents blindness and darkness effects.\nIncompatible with OptiFine.", "description.wurst.hack.anticactus": "Protects you from cactus damage.", "description.wurst.hack.antientitypush": "Prevents you from getting pushed by players and mobs.", - "description.wurst.hack.antihunger": "Slows down your hunger when you are walking.", + "description.wurst.hack.antihunger": "Slows down your hunger when you are walking.\n\n§c§lWARNING:§r There have been reports of this hack causing you to take extra fall damage under specific, unknown conditions.", "description.wurst.hack.antiknockback": "Prevents you from taking knockback from players and mobs.", "description.wurst.hack.antispam": "Blocks chat spam by adding a counter to repeated messages.", "description.wurst.hack.antiwaterpush": "Prevents you from getting pushed by water.", @@ -73,7 +74,12 @@ "description.wurst.hack.cameradistance": "Allows you to change the camera distance in 3rd person.", "description.wurst.hack.cameranoclip": "Allows the camera in 3rd person to go through walls.", "description.wurst.hack.cavefinder": "Helps you to find caves by highlighting them in the selected color.", - "description.wurst.hack.chattranslator": "Translates incoming chat messages using Google Translate.", + "description.wurst.hack.chattranslator": "Translates chat messages using Google Translate.", + "description.wurst.setting.chattranslator.your_language": "The main language that you can use and understand.\n\nYour received messages will always be translated into this language (if enabled).\n\nWhen \"Detect sent language\" is turned off, all sent messages are assumed to be in this language.", + "description.wurst.setting.chattranslator.other_language": "The main language used by other players on the server.\n\nYour sent messages will always be translated into this language (if enabled).\n\nWhen \"Detect received language\" is turned off, all received messages are assumed to be in this language.", + "description.wurst.setting.chattranslator.detect_received_language": "Automatically detect the language of received messages.\n\nUseful if other players are using a mix of different languages.\n\nIf everyone is using the same language, turning this off can improve accuracy.", + "description.wurst.setting.chattranslator.detect_sent_language": "Automatically detect the language of sent messages.\n\nUseful if you're using a mix of different languages.\n\nIf you're always using the same language, turning this off can improve accuracy.", + "description.wurst.setting.chattranslator.filter_own_messages": "Won't translate messages that appear to be sent by you.\n\nIt tries to detect your messages based on common chat formats like \"\", \"[name]\", or \"name:\". This might not work correctly on some servers.", "description.wurst.hack.chestesp": "Highlights nearby chests.", "description.wurst.hack.clickaura": "Automatically attacks the closest valid entity whenever you click.\n\n§c§lWARNING:§r ClickAuras generally look more suspicious than Killauras and are easier for plugins to detect. It is recommended to use Killaura or TriggerBot instead.", "description.wurst.hack.clickgui": "Window-based ClickGUI.", @@ -201,6 +207,7 @@ "description.wurst.hack.speednuker": "Faster version of Nuker that cannot bypass NoCheat+.", "description.wurst.hack.spider": "Allows you to climb up walls like a spider.", "description.wurst.hack.step": "Allows you to step up full blocks.", + "description.wurst.hack.templatetool": "Allows you to create custom templates for AutoBuild by scanning existing buildings.", "description.wurst.hack.throw": "Uses an item multiple times. Can be used to throw snowballs and eggs, spawn mobs, place minecarts, etc. in very large quantities.\n\nThis can cause a lot of lag and even crash a server.", "description.wurst.hack.tillaura": "Automatically turns dirt, grass, etc. into farmland.\nNot to be confused with Killaura.", "description.wurst.hack.timer": "Changes the speed of almost everything.", diff --git a/src/main/resources/assets/wurst/translations/fr_fr.json b/src/main/resources/assets/wurst/translations/fr_fr.json index 23314663..1468dd72 100644 --- a/src/main/resources/assets/wurst/translations/fr_fr.json +++ b/src/main/resources/assets/wurst/translations/fr_fr.json @@ -48,7 +48,7 @@ "description.wurst.hack.bunnyhop": "Vous fait sauter automatiquement.", "description.wurst.hack.cameranoclip": "Permet à la caméra à la 3ème personne de traverser les murs.", "description.wurst.hack.cavefinder": "Vous aide à trouver des grottes en les mettant en surbrillance dans la couleur sélectionnée.", - "description.wurst.hack.chattranslator": "Traduit les messages de chat entrants à l'aide de Google Traduction.", + "description.wurst.hack.chattranslator": "Traduit les messages de chat à l'aide de Google Traduction.", "description.wurst.hack.chestesp": "Met en évidence les coffres à proximité.", "description.wurst.hack.clickaura": "Attaque automatiquement l'entité valide la plus proche chaque fois que vous cliquez.\n\n§c§lATTENTION:§r ClickAuras semble généralement plus suspect que Killauras et est plus facile à détecter pour les plugins. Il est recommandé d'utiliser Killaura ou TriggerBot à la place.", "description.wurst.hack.clickgui": "ClickGUI basé sur une fenêtre.", diff --git a/src/main/resources/assets/wurst/translations/it_it.json b/src/main/resources/assets/wurst/translations/it_it.json index 8b2095eb..b7718c10 100644 --- a/src/main/resources/assets/wurst/translations/it_it.json +++ b/src/main/resources/assets/wurst/translations/it_it.json @@ -4,7 +4,7 @@ "description.wurst.hack.antiafk": "Cammina randomicamente per nasconderti dai detector di player AFK.", "description.wurst.hack.antiblind": "Previene la cecità ed effetti oscurità.\nIncompatibile con OptiFine.", "description.wurst.hack.anticactus": "Ti protegge dai danni causati dai cactus.", - "description.wurst.hack.antihunger": "Rallenta la tua fame quando cammini.", + "description.wurst.hack.antihunger": "Rallenta la tua fame quando cammini.\n\n§c§lATTENZIONE:§r Ci sono state segnalazioni di questo hack che causa danni da caduta extra in condizioni specifiche e sconosciute.", "description.wurst.hack.antiknockback": "Annulla il knockback (non permette alle entità di spingerti).", "description.wurst.hack.antispam": "Blocca gli spammer in chat mettendo un contatore per i messaggi.", "description.wurst.hack.antiwaterpush": "Non permette all'acqua di spingerti.", diff --git a/src/main/resources/assets/wurst/translations/ja_jp.json b/src/main/resources/assets/wurst/translations/ja_jp.json index d8606d22..5062944d 100644 --- a/src/main/resources/assets/wurst/translations/ja_jp.json +++ b/src/main/resources/assets/wurst/translations/ja_jp.json @@ -6,7 +6,7 @@ "description.wurst.hack.antiblind": "盲目や暗闇の効果を防ぎます。\nOptiFineとの互換性はありません。", "description.wurst.hack.anticactus": "サボテンのダメージを無効化する。", "description.wurst.hack.antientitypush": "プレイヤーやモブに押されるのを防ぎます。", - "description.wurst.hack.antihunger": "歩行中に空腹度ゲージの減少を抑える。", + "description.wurst.hack.antihunger": "歩行中に空腹度ゲージの減少を抑える。\n\n§c§l注意:§r 特定の不明な条件下で、このハックが追加の落下ダメージを引き起こす報告があります。", "description.wurst.hack.antiknockback": "プレイヤーやモブからのノックバックを無効化する。", "description.wurst.hack.antispam": "同じ内容のメッセージにカウントを表示し、チャットスパムを防ぐ。", "description.wurst.hack.antiwaterpush": "水に流されるのを防ぐ。", @@ -56,7 +56,7 @@ "description.wurst.hack.cameradistance": "3人称視点でカメラとプレイヤーの距離が変更できるようになる。", "description.wurst.hack.cameranoclip": "三人称視点のカメラがブロックを貫通するようになる。", "description.wurst.hack.cavefinder": "洞窟を選択した色でハイライト表示し、探しやすくする。", - "description.wurst.hack.chattranslator": "受信したメッセージをGoogle翻訳で翻訳する。", + "description.wurst.hack.chattranslator": "チャットメッセージをGoogle翻訳で翻訳する。", "description.wurst.hack.chestesp": "付近のチェストをハイライト表示する。", "description.wurst.hack.clickaura": "クリックすると、自動で一番近い有効なエンティティを攻撃する。\n\n§c§l注意: §rClickAuraはKillauraよりも怪しまれやすく、かつPluginに検知されやすいため、代わりにKillauraやTriggerBotの使用を推奨する。", "description.wurst.hack.clickgui": "ウィンドウタイプのClickGUI。", diff --git a/src/main/resources/assets/wurst/translations/ko_kr.json b/src/main/resources/assets/wurst/translations/ko_kr.json index fcd99e04..3c035a26 100644 --- a/src/main/resources/assets/wurst/translations/ko_kr.json +++ b/src/main/resources/assets/wurst/translations/ko_kr.json @@ -5,7 +5,7 @@ "description.wurst.hack.antiblind": "실명 및 어둠 효과를 방지합니다.\nOptiFine과 호환되지 않습니다.", "description.wurst.hack.anticactus": "선인장 대미지를 받지 않습니다.", "description.wurst.hack.antientitypush": "다른 플레이어나 몹에게 밀려나는 것을 방지합니다.", - "description.wurst.hack.antihunger": "걷는 동안 배고픔 속도를 늦춥니다.", + "description.wurst.hack.antihunger": "걷는 동안 배고픔 속도를 늦춥니다.\n\n§c§l경고:§r 특정한 알려지지 않은 조건에서 이 핵이 추가적인 낙하 대미지를 받게 할 수 있다는 보고가 있습니다.", "description.wurst.hack.antiknockback": "플레이어나 몹으로부터 넉백을 받지 않도록 합니다.", "description.wurst.hack.antispam": "반복된 메시지에 카운터를 추가하여 채팅 스팸을 차단합니다.", "description.wurst.hack.antiwaterpush": "물에 밀리는 것을 방지합니다.", diff --git a/src/main/resources/assets/wurst/translations/pl_pl.json b/src/main/resources/assets/wurst/translations/pl_pl.json index fd68108e..7e77d905 100644 --- a/src/main/resources/assets/wurst/translations/pl_pl.json +++ b/src/main/resources/assets/wurst/translations/pl_pl.json @@ -4,7 +4,7 @@ "description.wurst.hack.antiafk": "Spaceruje losowo dookoła, aby ukryć cię przed wykrywaczami AFK.", "description.wurst.hack.antiblind": "Zapobiega efektom oślepienia i ciemności.\nNiekompatybilny z OptiFine.", "description.wurst.hack.anticactus": "Ochrania cię przed obrażeniami od kaktusa.", - "description.wurst.hack.antihunger": "Spowalnia głód podczas chodzenia.", + "description.wurst.hack.antihunger": "Spowalnia głód podczas chodzenia.\n\n§c§lOSTRZEŻENIE:§r Istnieją doniesienia, że ten hack może powodować dodatkowe obrażenia od upadku w określonych, nieznanych warunkach.", "description.wurst.hack.antiknockback": "Zapobiega popychaniu cię przez innych graczy i moby.", "description.wurst.hack.antispam": "Blokuje spam na czacie, dodając licznik do powtarzających się wiadomości.", "description.wurst.hack.antiwaterpush": "Zapobiega popychaniu cię przez wodę.", @@ -51,7 +51,7 @@ "description.wurst.hack.cameradistance": "Pozwala zmienić odległość kamery w trzeciej osobie.", "description.wurst.hack.cameranoclip": "Umożliwia kamerze trzecio-osobowej na przenikanie przez ściany.", "description.wurst.hack.cavefinder": "Pomaga znaleźć jaskinie, podświetlając je wybranym kolorem.", - "description.wurst.hack.chattranslator": "Tłumaczy przychodzące wiadomości z czatu za pomocą Tłumacza Google.", + "description.wurst.hack.chattranslator": "Tłumaczy wiadomości z czatu za pomocą Tłumacza Google.", "description.wurst.hack.chestesp": "Podświetla pobliskie skrzynie.", "description.wurst.hack.clickaura": "Automatycznie atakuje najbliższy prawidłowy byt za każdym razem, gdy klikniesz.\n\n§c§lOSTRZEŻENIE:§r ClickAury generalnie wyglądają bardziej podejrzanie niż Killaury i są łatwiejsze do wykrycia przez pluginy. Zamiast tego zaleca się użycie Killaury lub TriggerBota.", "description.wurst.hack.clickgui": "ClickGUI oparty na okienkach.", diff --git a/src/main/resources/assets/wurst/translations/ro_ro.json b/src/main/resources/assets/wurst/translations/ro_ro.json index 9d448805..5aaa6c16 100644 --- a/src/main/resources/assets/wurst/translations/ro_ro.json +++ b/src/main/resources/assets/wurst/translations/ro_ro.json @@ -48,7 +48,7 @@ "description.wurst.hack.bunnyhop": "Sari automat.", "description.wurst.hack.cameranoclip": "Permite camerei 3rd person sa vada prin pereti.", "description.wurst.hack.cavefinder": "Te ajuta sa gasesti pesteri conturandu-le in culoarea aleasa.", - "description.wurst.hack.chattranslator": "Traduce mesajele de pe chat folosind Google Translate.", + "description.wurst.hack.chattranslator": "Traduce mesajele din chat folosind Google Translate.", "description.wurst.hack.chestesp": "Contureaza chesturile din apropiere.", "description.wurst.hack.clickaura": "Ataca automat cea mai apropiata entitate atunci cand dai click.\n\n§c§lATENTIE:§r ClickAura este mai suspicios decat Killaura si este mai usor de detectat de catre anumite plugin-uri. Este recomandat in schimb sa folosesti Killaura sau TriggerBot.", "description.wurst.hack.clickgui": "ClickGUI bazat pe windows.", diff --git a/src/main/resources/assets/wurst/translations/ru_ru.json b/src/main/resources/assets/wurst/translations/ru_ru.json index d992d2e4..fc0a6f95 100644 --- a/src/main/resources/assets/wurst/translations/ru_ru.json +++ b/src/main/resources/assets/wurst/translations/ru_ru.json @@ -4,7 +4,7 @@ "description.wurst.hack.antiafk": "Ходит в случайном направлении чтобы сервер не знал что Вы АФК.", "description.wurst.hack.antiblind": "Предотвращает эффекты слепоты и темноты.\nНесовместим с OptiFine.", "description.wurst.hack.anticactus": "Защищает Вас от урона от столкновения с кактусами.", - "description.wurst.hack.antihunger": "Замедляет уменьшение голода, когда вы ходите.", + "description.wurst.hack.antihunger": "Замедляет уменьшение голода, когда вы ходите.\n\n§c§lВНИМАНИЕ:§r Были сообщения о том, что этот чит может вызывать дополнительный урон от падения при определенных, неизвестных условиях.", "description.wurst.hack.antiknockback": "Предотвращает откидывание при получении урона.", "description.wurst.hack.antispam": "Блокирует спам в чате добавляя счетчик повторений у сообщения.", "description.wurst.hack.antiwaterpush": "Убирает снос течением воды.", diff --git a/src/main/resources/assets/wurst/translations/uk_ua.json b/src/main/resources/assets/wurst/translations/uk_ua.json index c82b1931..19e19b42 100644 --- a/src/main/resources/assets/wurst/translations/uk_ua.json +++ b/src/main/resources/assets/wurst/translations/uk_ua.json @@ -47,7 +47,7 @@ "description.wurst.hack.bunnyhop": "Примушує вас постійно стрибати.", "description.wurst.hack.cameranoclip": "Дозволяє камеру від 3-ї особи пройти через стіни.", "description.wurst.hack.cavefinder": "Допомагає знайти печери, підсвічуючи їх вибраним кольором.", - "description.wurst.hack.chattranslator": "Всі вхідні повідомлення в чаті будуть перекладатися Google перекладачем.", + "description.wurst.hack.chattranslator": "Перекладає повідомлення в чаті за допомогою Google перекладача.", "description.wurst.hack.chestesp": "Підсвічує вибраним кольором скрині поблизу.", "description.wurst.hack.clickaura": "Автоматично атакує найближчу сутність, коли ви натискаєте ЛКМ.\n\n§c§lУВАГА:§r ClickAura'и звичайно виглядають більш підозріло, ніж Killaura'и і легше виявляються плагінами. Краще використовувати Killaura або TriggerBot.", "description.wurst.hack.clickgui": "Інтерфейс із панелями.", diff --git a/src/main/resources/assets/wurst/translations/zh_cn.json b/src/main/resources/assets/wurst/translations/zh_cn.json index 7cb3db00..94eaaf71 100644 --- a/src/main/resources/assets/wurst/translations/zh_cn.json +++ b/src/main/resources/assets/wurst/translations/zh_cn.json @@ -6,7 +6,7 @@ "description.wurst.hack.antiblind": "防止失明和黑暗效果。\n与 OptiFine 不兼容。", "description.wurst.hack.anticactus": "保护你免受仙人掌伤害。", "description.wurst.hack.antientitypush": "保护你不会被玩家和其他生物推挤。", - "description.wurst.hack.antihunger": "在你走路时减缓你的饥饿状态。", + "description.wurst.hack.antihunger": "在你走路时减缓你的饥饿状态。\n\n§c§l警告:§r 有报告称在某些特定的、未知的情况下,此功能可能会导致你受到额外的摔落伤害。", "description.wurst.hack.antiknockback": "保护你不被其他生物或玩家推动和用剑击退。", "description.wurst.hack.antispam": "将重复的刷屏改为计数器显示。", "description.wurst.hack.antiwaterpush": "防止你被水流推动。", diff --git a/src/main/resources/assets/wurst/translations/zh_tw.json b/src/main/resources/assets/wurst/translations/zh_tw.json index 2f1c9b1b..e189a0ec 100644 --- a/src/main/resources/assets/wurst/translations/zh_tw.json +++ b/src/main/resources/assets/wurst/translations/zh_tw.json @@ -4,7 +4,7 @@ "description.wurst.hack.antiafk": "隨機走動,用於避免伺服器掛機檢測。", "description.wurst.hack.antiblind": "防止失明和黑暗效果。\n與 OptiFine不相容。", "description.wurst.hack.anticactus": "保護你免受仙人掌傷害。", - "description.wurst.hack.antihunger": "走路時減緩你的飢餓度。", + "description.wurst.hack.antihunger": "走路時減緩你的飢餓度。\n\n§c§l警告:§r 有報告指出,在某些特定但未知的情況下,此功能可能會導致你受到額外的掉落傷害。", "description.wurst.hack.antiknockback": "保護你不會被其他生物或玩家推動和用劍擊退。", "description.wurst.hack.antispam": "預防存在的重複刷屏,改為用計數器顯示。", "description.wurst.hack.antiwaterpush": "防止你被水流推動。", diff --git a/src/main/resources/wurst.mixins.json b/src/main/resources/wurst.mixins.json index 635bbe9e..d98d0cda 100644 --- a/src/main/resources/wurst.mixins.json +++ b/src/main/resources/wurst.mixins.json @@ -42,6 +42,7 @@ "KeyBindingMixin", "KeyboardMixin", "LanguageManagerMixin", + "LightmapTextureManagerMixin", "LivingEntityRendererMixin", "MinecraftClientMixin", "MobEntityRendererMixin",