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

Merge v7.44 into 1.20.6

This commit is contained in:
Alexander01998 2024-08-07 16:00:21 +02:00
parent 6f6d767474
commit 4044a301c4
29 changed files with 286 additions and 242 deletions

View File

@ -1,6 +1,6 @@
buildscript {
dependencies {
classpath "org.kohsuke:github-api:1.322"
classpath "org.kohsuke:github-api:1.323"
}
}

View File

@ -13,7 +13,7 @@ loader_version=0.15.11
fabric_version=0.100.8+1.20.6
# Mod Properties
mod_version = v7.44pre2-MC1.20.6
mod_version = v7.44-MC1.20.6
maven_group = net.wurstclient
archives_base_name = Wurst-Client

View File

@ -11,17 +11,10 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.IllegalFormatException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.lwjgl.glfw.GLFW;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.InputUtil;
import net.wurstclient.altmanager.AltManager;
import net.wurstclient.altmanager.Encryption;
import net.wurstclient.analytics.WurstAnalytics;
@ -41,7 +34,6 @@ import net.wurstclient.hack.HackList;
import net.wurstclient.hud.IngameHUD;
import net.wurstclient.keybinds.KeybindList;
import net.wurstclient.keybinds.KeybindProcessor;
import net.wurstclient.mixinterface.ILanguageManager;
import net.wurstclient.mixinterface.IMinecraftClient;
import net.wurstclient.navigator.Navigator;
import net.wurstclient.other_feature.OtfList;
@ -58,7 +50,7 @@ public enum WurstClient
public static MinecraftClient MC;
public static IMinecraftClient IMC;
public static final String VERSION = "7.44pre2";
public static final String VERSION = "7.44";
public static final String MC_VERSION = "1.20.6";
private WurstAnalytics analytics;
@ -76,6 +68,7 @@ public enum WurstClient
private IngameHUD hud;
private RotationFaker rotationFaker;
private FriendsList friends;
private WurstTranslator translator;
private boolean enabled = true;
private static boolean guiInitialized;
@ -83,8 +76,6 @@ public enum WurstClient
private ProblematicResourcePackDetector problematicPackDetector;
private Path wurstFolder;
private KeyBinding zoomKey;
public void initialize()
{
System.out.println("Starting Wurst Client...");
@ -126,6 +117,8 @@ public enum WurstClient
friends = new FriendsList(friendsFile);
friends.load();
translator = new WurstTranslator();
cmdProcessor = new CmdProcessor(cmds);
eventManager.add(ChatOutputListener.class, cmdProcessor);
@ -150,10 +143,6 @@ public enum WurstClient
Path encFolder = Encryption.chooseEncryptionFolder();
altManager = new AltManager(altsFile, encFolder);
zoomKey = new KeyBinding("key.wurst.zoom", InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_V, KeyBinding.MISC_CATEGORY);
KeyBindingHelper.registerKeyBinding(zoomKey);
analytics.trackPageView("/mc" + MC_VERSION + "/v" + VERSION,
"Wurst " + VERSION + " MC" + MC_VERSION);
}
@ -178,27 +167,7 @@ public enum WurstClient
public String translate(String key, Object... args)
{
if(otfs.translationsOtf.getForceEnglish().isChecked())
{
String string = ILanguageManager.getEnglish().get(key);
try
{
return String.format(string, args);
}catch(IllegalFormatException e)
{
return key;
}
}
// This extra check is necessary because I18n.translate() doesn't
// always return the key when the translation is missing. If the key
// contains a '%', it will return "Format Error: key" instead.
if(!I18n.hasTranslation(key))
return key;
return I18n.translate(key, args);
return translator.translate(key, args);
}
public WurstAnalytics getAnalytics()
@ -314,6 +283,11 @@ public enum WurstClient
return friends;
}
public WurstTranslator getTranslator()
{
return translator;
}
public boolean isEnabled()
{
return enabled;
@ -345,11 +319,6 @@ public enum WurstClient
return wurstFolder;
}
public KeyBinding getZoomKey()
{
return zoomKey;
}
public AltManager getAltManager()
{
return altManager;

View File

@ -0,0 +1,183 @@
/*
* 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;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.function.BiConsumer;
import com.google.common.collect.Lists;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.SynchronousResourceReloader;
import net.minecraft.util.Identifier;
import net.minecraft.util.Language;
public class WurstTranslator implements SynchronousResourceReloader
{
private final WurstClient wurst = WurstClient.INSTANCE;
private TranslationStorage mcEnglish;
private final HashMap<String, String> englishOnlyStrings = new HashMap<>();
private final HashMap<String, String> currentLangStrings = new HashMap<>();
@Override
public void reload(ResourceManager manager)
{
mcEnglish = TranslationStorage.load(manager,
Lists.newArrayList("en_us"), false);
currentLangStrings.clear();
loadTranslations(manager, getCurrentLangCodes(),
currentLangStrings::put);
englishOnlyStrings.clear();
loadTranslations(manager, List.of("en_us"), englishOnlyStrings::put);
}
/**
* Translates the given key with the given args into the current language,
* or into English if the "Force English" setting is enabled. Both Wurst and
* vanilla translations are supported.
*/
public String translate(String key, Object... args)
{
// Forced English
if(isForcedEnglish())
return translateEnglish(key, args);
// Wurst translation
String string = currentLangStrings.get(key);
if(string != null)
try
{
return String.format(string, args);
}catch(IllegalFormatException e)
{
return key;
}
// Vanilla translation
return translateMc(key, args);
}
/**
* Translates the given key with the given args into English, regardless of
* the current language. Both Wurst and vanilla translations are supported.
*/
public String translateEnglish(String key, Object... args)
{
String string = englishOnlyStrings.get(key);
if(string == null)
string = mcEnglish.get(key);
try
{
return String.format(string, args);
}catch(IllegalFormatException e)
{
return key;
}
}
/**
* Translates the given key with the given args into the current language,
* or into English if the "Force English" setting is enabled, using only
* Minecraft's own translations.
*
* @apiNote This method differs from
* {@link I18n#translate(String, Object...)} in that it does not
* return "Format error" if the key contains a percent sign.
*/
public String translateMc(String key, Object... args)
{
if(I18n.hasTranslation(key))
return I18n.translate(key, args);
return key;
}
/**
* Translates the given key with the given args into English, regardless of
* the current language, using only Minecraft's own translations.
*
* @apiNote This method differs from
* {@link I18n#translate(String, Object...)} in that it does not
* return "Format error" if the key contains a percent sign.
*/
public String translateMcEnglish(String key, Object... args)
{
try
{
return String.format(mcEnglish.get(key), args);
}catch(IllegalFormatException e)
{
return key;
}
}
public boolean isForcedEnglish()
{
return wurst.getOtfs().translationsOtf.getForceEnglish().isChecked();
}
/**
* Returns a translation storage for Minecraft's English strings, regardless
* of the current language. Does not include any of Wurst's translations.
*/
public TranslationStorage getMcEnglish()
{
return mcEnglish;
}
private ArrayList<String> getCurrentLangCodes()
{
String mainLangCode =
MinecraftClient.getInstance().getLanguageManager().getLanguage();
ArrayList<String> langCodes = new ArrayList<>();
langCodes.add("en_us");
if(!"en_us".equals(mainLangCode))
langCodes.add(mainLangCode);
return langCodes;
}
private void loadTranslations(ResourceManager manager,
Iterable<String> langCodes, BiConsumer<String, String> entryConsumer)
{
for(String langCode : langCodes)
{
String langFilePath = "translations/" + langCode + ".json";
Identifier langId = Identifier.of("wurst", langFilePath);
for(Resource resource : manager.getAllResources(langId))
try(InputStream stream = resource.getInputStream())
{
Language.load(stream, entryConsumer);
}catch(IOException e)
{
System.out.println("Failed to load translations for "
+ langCode + " from pack " + resource.getPackId());
e.printStackTrace();
}
}
}
}

View File

@ -9,11 +9,11 @@ package net.wurstclient.hacks.autolibrarian;
import java.util.Objects;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import net.wurstclient.mixinterface.ILanguageManager;
import net.wurstclient.WurstClient;
import net.wurstclient.WurstTranslator;
public record BookOffer(String id, int level, int price)
implements Comparable<BookOffer>
@ -31,19 +31,21 @@ public record BookOffer(String id, int level, int price)
public String getEnchantmentName()
{
TranslationStorage english = ILanguageManager.getEnglish();
WurstTranslator translator = WurstClient.INSTANCE.getTranslator();
Enchantment enchantment = getEnchantment();
return english.get(enchantment.getTranslationKey());
return translator.translateMcEnglish(enchantment.getTranslationKey());
}
public String getEnchantmentNameWithLevel()
{
TranslationStorage english = ILanguageManager.getEnglish();
WurstTranslator translator = WurstClient.INSTANCE.getTranslator();
Enchantment enchantment = getEnchantment();
String name = english.get(enchantment.getTranslationKey());
String name =
translator.translateMcEnglish(enchantment.getTranslationKey());
if(enchantment.getMaxLevel() > 1)
name += " " + english.get("enchantment.level." + level);
name += " "
+ translator.translateMcEnglish("enchantment.level." + level);
return name;
}

View File

@ -9,10 +9,12 @@ 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.CallbackInfo;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.network.ClientCommonNetworkHandler;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientCommonPacketListener;
import net.minecraft.network.packet.Packet;
import net.wurstclient.event.EventManager;
@ -22,15 +24,16 @@ import net.wurstclient.events.PacketOutputListener.PacketOutputEvent;
public abstract class ClientCommonNetworkHandlerMixin
implements ClientCommonPacketListener
{
@Inject(at = @At("HEAD"),
method = "sendPacket(Lnet/minecraft/network/packet/Packet;)V",
cancellable = true)
private void onSendPacket(Packet<?> packet, CallbackInfo ci)
@WrapOperation(at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/ClientConnection;send(Lnet/minecraft/network/packet/Packet;)V"),
method = "sendPacket(Lnet/minecraft/network/packet/Packet;)V")
private void wrapSendPacket(ClientConnection connection, Packet<?> packet,
Operation<Void> original)
{
PacketOutputEvent event = new PacketOutputEvent(packet);
EventManager.fire(event);
if(event.isCancelled())
ci.cancel();
if(!event.isCancelled())
original.call(connection, event.getPacket());
}
}

View File

@ -1,56 +0,0 @@
/*
* 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.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.text.KeybindTextContent;
import net.minecraft.text.Text;
import net.minecraft.text.TextContent;
@Mixin(KeybindTextContent.class)
public abstract class KeybindTextContentMixin implements TextContent
{
@Shadow
@Final
private String key;
/**
* Ensures that any chat messages, written books, signs, etc. cannot resolve
* Wurst-related keybinds.
*
* <p>
* Fixes at least one security vulnerability affecting Minecraft 1.20 and
* later versions, where the server can detect the presence of Wurst by
* abusing Minecraft's sign editing feature. When a player edits a sign, any
* translated text and keybind text components on that sign are resolved by
* the client and sent back to the server as plain text. This allows the
* server to detect the presence of non-vanilla keybinds, such as Wurst's
* zoom keybind.
*
* <p>
* It is likely that similar vulnerabilities exist or will exist in other
* parts of the game, such as chat messages and written books. Mojang has a
* long history of failing to properly secure their text component system
* (see BookHack, OP-Sign, BookDupe). Therefore it's best to cut off this
* entire attack vector at the source.
*/
@Inject(at = @At("RETURN"),
method = "getTranslated()Lnet/minecraft/text/Text;",
cancellable = true)
private void onGetTranslated(CallbackInfoReturnable<Text> cir)
{
if(key != null && key.contains("wurst"))
cir.setReturnValue(Text.literal(key));
}
}

View File

@ -12,31 +12,21 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.google.common.collect.Lists;
import net.minecraft.client.resource.language.LanguageManager;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.SynchronousResourceReloader;
import net.wurstclient.mixinterface.ILanguageManager;
import net.wurstclient.WurstClient;
@Mixin(LanguageManager.class)
public abstract class LanguageManagerMixin
implements SynchronousResourceReloader, ILanguageManager
implements SynchronousResourceReloader
{
private TranslationStorage wurstEnglish;
@Inject(at = @At("HEAD"),
method = "reload(Lnet/minecraft/resource/ResourceManager;)V")
private void onReload(ResourceManager manager, CallbackInfo ci)
{
wurstEnglish = TranslationStorage.load(manager,
Lists.newArrayList("en_us"), false);
}
@Override
public TranslationStorage wurst_getEnglish()
{
return wurstEnglish;
// Using a mixin for this because WurstClient.initialize() runs too
// early to call ResourceManager.registerReloader()
WurstClient.INSTANCE.getTranslator().reload(manager);
}
}

View File

@ -10,9 +10,11 @@ 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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.entity.Entity;
@ -25,16 +27,17 @@ public abstract class LivingEntityRendererMixin
/**
* Disables the distance limit in hasLabel() if configured in NameTags.
*/
@Redirect(at = @At(value = "INVOKE",
@WrapOperation(at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/render/entity/EntityRenderDispatcher;getSquaredDistanceToCamera(Lnet/minecraft/entity/Entity;)D",
ordinal = 0), method = "hasLabel(Lnet/minecraft/entity/LivingEntity;)Z")
private double adjustDistance(EntityRenderDispatcher render, Entity entity)
private double adjustDistance(EntityRenderDispatcher render, Entity entity,
Operation<Double> original)
{
// pretend the distance is 1 so the check always passes
if(WurstClient.INSTANCE.getHax().nameTagsHack.isUnlimitedRange())
return 1;
return render.getSquaredDistanceToCamera(entity);
return original.call(render, entity);
}
/**

View File

@ -65,7 +65,14 @@ public abstract class MinecraftClientMixin
super(name);
}
@Inject(at = @At("HEAD"), method = "handleInputEvents()V")
/**
* Runs just before {@link MinecraftClient#handleInputEvents()}, bypassing
* the <code>overlay == null && currentScreen == null</code> check in
* {@link MinecraftClient#tick()}.
*/
@Inject(at = @At(value = "FIELD",
target = "Lnet/minecraft/client/MinecraftClient;overlay:Lnet/minecraft/client/gui/screen/Overlay;",
ordinal = 0), method = "tick()V")
private void onHandleInputEvents(CallbackInfo ci)
{
EventManager.fire(HandleInputEvent.INSTANCE);

View File

@ -1,68 +0,0 @@
/*
* 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 com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.text.TextContent;
import net.minecraft.text.TranslatableTextContent;
import net.minecraft.util.Language;
@Mixin(TranslatableTextContent.class)
public abstract class TranslatableTextContentMixin implements TextContent
{
/**
* Ensures that any chat messages, written books, signs, etc. cannot resolve
* Wurst-related translation keys.
*
* <p>
* Fixes at least one security vulnerability affecting Minecraft 1.20 and
* later versions, where the server can detect the presence of Wurst by
* abusing Minecraft's sign editing feature. When a player edits a sign, any
* translated text and keybind text components on that sign are resolved by
* the client and sent back to the server as plain text. This allows the
* server to detect the presence of non-vanilla translation keys.
*
* <p>
* It is likely that similar vulnerabilities exist or will exist in other
* parts of the game, such as chat messages and written books. Mojang has a
* long history of failing to properly secure their text component system
* (see BookHack, OP-Sign, BookDupe). Therefore it's best to cut off this
* entire attack vector at the source.
*/
@WrapOperation(at = @At(value = "INVOKE",
target = "Lnet/minecraft/util/Language;get(Ljava/lang/String;)Ljava/lang/String;",
ordinal = 0), method = "updateTranslations()V")
private String translate(Language instance, String key,
Operation<String> original)
{
if(key != null && key.contains("wurst"))
return key;
return original.call(instance, key);
}
/**
* Same as above, but for translatable text components with a fallback.
*/
@WrapOperation(at = @At(value = "INVOKE",
target = "Lnet/minecraft/util/Language;get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
ordinal = 0), method = "updateTranslations()V")
private String translateWithFallback(Language instance, String key,
String fallback, Operation<String> original)
{
if(key != null && key.contains("wurst"))
return fallback;
return original.call(instance, key, fallback);
}
}

View File

@ -1,22 +0,0 @@
/*
* 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.mixinterface;
import net.minecraft.client.resource.language.TranslationStorage;
import net.wurstclient.WurstClient;
public interface ILanguageManager
{
public TranslationStorage wurst_getEnglish();
public static TranslationStorage getEnglish()
{
return ((ILanguageManager)WurstClient.MC.getLanguageManager())
.wurst_getEnglish();
}
}

View File

@ -11,8 +11,6 @@ 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.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.Text;
import net.wurstclient.WurstClient;
import net.wurstclient.other_features.ZoomOtf;
@ -22,7 +20,6 @@ import net.wurstclient.settings.SliderSetting;
public class ZoomManagerScreen extends Screen implements PressAKeyCallback
{
private Screen prevScreen;
private ButtonWidget keyButton;
private ButtonWidget scrollButton;
public ZoomManagerScreen(Screen par1GuiScreen)
@ -38,15 +35,16 @@ public class ZoomManagerScreen extends Screen implements PressAKeyCallback
ZoomOtf zoom = wurst.getOtfs().zoomOtf;
SliderSetting level = zoom.getLevelSetting();
CheckboxSetting scroll = zoom.getScrollSetting();
Text zoomKeyName = wurst.getZoomKey().getBoundKeyLocalizedText();
addDrawableChild(ButtonWidget
.builder(Text.literal("Back"), b -> client.setScreen(prevScreen))
.dimensions(width / 2 - 100, height / 4 + 144 - 16, 200, 20)
.build());
addDrawableChild(keyButton = ButtonWidget
.builder(Text.literal("Zoom Key: ").append(zoomKeyName),
addDrawableChild(ButtonWidget
.builder(
Text.literal("Zoom Key: ")
.append(zoom.getTranslatedKeybindName()),
b -> client.setScreen(new PressAKeyScreen(this)))
.dimensions(width / 2 - 79, height / 4 + 24 - 16, 158, 20).build());
@ -115,10 +113,8 @@ public class ZoomManagerScreen extends Screen implements PressAKeyCallback
@Override
public void setKey(String key)
{
WurstClient.INSTANCE.getZoomKey()
.setBoundKey(InputUtil.fromTranslationKey(key));
client.options.write();
KeyBinding.updateKeysByCode();
keyButton.setMessage(Text.literal("Zoom Key: " + key));
WurstClient.INSTANCE.getOtfs().zoomOtf.setBoundKey(key);
// Button text updates automatically because going back to this screen
// calls init(). Might be different in older MC versions.
}
}

View File

@ -8,6 +8,8 @@
package net.wurstclient.other_features;
import net.minecraft.client.option.SimpleOption;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.Text;
import net.wurstclient.DontBlock;
import net.wurstclient.SearchTags;
import net.wurstclient.events.MouseScrollListener;
@ -15,6 +17,7 @@ import net.wurstclient.other_feature.OtherFeature;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;
import net.wurstclient.settings.TextFieldSetting;
import net.wurstclient.util.MathUtils;
@SearchTags({"telescope", "optifine"})
@ -25,10 +28,16 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener
50, 0.1, ValueDisplay.DECIMAL.withSuffix("x"));
private final CheckboxSetting scroll = new CheckboxSetting(
"Use mouse wheel",
"If enabled, you can use the mouse wheel while zooming to zoom in even further.",
"Use mouse wheel", "If enabled, you can use the mouse wheel while"
+ " zooming to zoom in even further.",
true);
private final TextFieldSetting keybind = new TextFieldSetting("Keybind",
"Determines the zoom keybind.\n\n"
+ "Instead of editing this value manually, you should go to Wurst"
+ " Options -> Zoom and set it there.",
"key.keyboard.v", this::isValidKeybind);
private Double currentLevel;
private Double defaultMouseSensitivity;
@ -39,6 +48,7 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener
+ "Go to Wurst Options -> Zoom to change this keybind.");
addSetting(level);
addSetting(scroll);
addSetting(keybind);
EVENTS.add(MouseScrollListener.class, this);
}
@ -50,7 +60,7 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener
if(currentLevel == null)
currentLevel = level.getValue();
if(!WURST.getZoomKey().isPressed())
if(!isZoomKeyPressed())
{
currentLevel = level.getValue();
@ -78,7 +88,7 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener
@Override
public void onMouseScroll(double amount)
{
if(!WURST.getZoomKey().isPressed() || !scroll.isChecked())
if(!isZoomKeyPressed() || !scroll.isChecked())
return;
if(currentLevel == null)
@ -95,7 +105,36 @@ public final class ZoomOtf extends OtherFeature implements MouseScrollListener
public boolean shouldPreventHotbarScrolling()
{
return WURST.getZoomKey().isPressed() && scroll.isChecked();
return isZoomKeyPressed() && scroll.isChecked();
}
public Text getTranslatedKeybindName()
{
return InputUtil.fromTranslationKey(keybind.getValue())
.getLocalizedText();
}
public void setBoundKey(String translationKey)
{
keybind.setValue(translationKey);
}
private boolean isZoomKeyPressed()
{
return InputUtil.isKeyPressed(MC.getWindow().getHandle(),
InputUtil.fromTranslationKey(keybind.getValue()).getCode());
}
private boolean isValidKeybind(String keybind)
{
try
{
return InputUtil.fromTranslationKey(keybind) != null;
}catch(IllegalArgumentException e)
{
return false;
}
}
public SliderSetting getLevelSetting()

View File

@ -40,7 +40,6 @@
"IngameHudMixin",
"InGameOverlayRendererMixin",
"KeyBindingMixin",
"KeybindTextContentMixin",
"KeyboardMixin",
"LanguageManagerMixin",
"LivingEntityRendererMixin",
@ -63,7 +62,6 @@
"TelemetryManagerMixin",
"TextVisitFactoryMixin",
"TitleScreenMixin",
"TranslatableTextContentMixin",
"WorldMixin",
"WorldRendererMixin"
],