mirror of
https://github.com/Wurst-Imperium/Wurst7.git
synced 2024-09-20 01:12:13 +02:00
Merge v7.41.1 into 1.20.3
This commit is contained in:
parent
525fb06ea3
commit
2dcb6f8632
@ -13,7 +13,7 @@ loader_version=0.15.7
|
||||
fabric_version=0.91.1+1.20.3
|
||||
|
||||
# Mod Properties
|
||||
mod_version = v7.41-MC1.20.3
|
||||
mod_version = v7.41.1-MC1.20.3
|
||||
maven_group = net.wurstclient
|
||||
archives_base_name = Wurst-Client
|
||||
|
||||
|
@ -11,6 +11,7 @@ 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;
|
||||
|
||||
@ -57,7 +58,7 @@ public enum WurstClient
|
||||
public static MinecraftClient MC;
|
||||
public static IMinecraftClient IMC;
|
||||
|
||||
public static final String VERSION = "7.41";
|
||||
public static final String VERSION = "7.41.1";
|
||||
public static final String MC_VERSION = "1.20.3";
|
||||
|
||||
private WurstAnalytics analytics;
|
||||
@ -175,18 +176,29 @@ public enum WurstClient
|
||||
return wurstFolder;
|
||||
}
|
||||
|
||||
public String translate(String key)
|
||||
public String translate(String key, Object... args)
|
||||
{
|
||||
if(otfs.translationsOtf.getForceEnglish().isChecked())
|
||||
return ILanguageManager.getEnglish().get(key);
|
||||
{
|
||||
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);
|
||||
return I18n.translate(key, args);
|
||||
}
|
||||
|
||||
public WurstAnalytics getAnalytics()
|
||||
|
@ -86,14 +86,15 @@ public final class AltManagerScreen extends Screen
|
||||
public void init()
|
||||
{
|
||||
listGui = new ListGui(client, this, altManager.getList());
|
||||
WurstClient wurst = WurstClient.INSTANCE;
|
||||
|
||||
Exception folderException = altManager.getFolderException();
|
||||
if(folderException != null && shouldAsk)
|
||||
{
|
||||
Text title =
|
||||
Text.translatable("gui.wurst.altmanager.folder_error.title");
|
||||
Text message = Text.translatable(
|
||||
"gui.wurst.altmanager.folder_error.message", folderException);
|
||||
Text title = Text.literal(
|
||||
wurst.translate("gui.wurst.altmanager.folder_error.title"));
|
||||
Text message = Text.literal(wurst.translate(
|
||||
"gui.wurst.altmanager.folder_error.message", folderException));
|
||||
Text buttonText = Text.translatable("gui.done");
|
||||
|
||||
// This just sets shouldAsk to false and closes the message.
|
||||
@ -105,9 +106,10 @@ public final class AltManagerScreen extends Screen
|
||||
|
||||
}else if(altManager.getList().isEmpty() && shouldAsk)
|
||||
{
|
||||
Text title = Text.translatable("gui.wurst.altmanager.empty.title");
|
||||
Text message =
|
||||
Text.translatable("gui.wurst.altmanager.empty.message");
|
||||
Text title = Text
|
||||
.literal(wurst.translate("gui.wurst.altmanager.empty.title"));
|
||||
Text message = Text
|
||||
.literal(wurst.translate("gui.wurst.altmanager.empty.message"));
|
||||
BooleanConsumer callback = this::confirmGenerate;
|
||||
|
||||
ConfirmScreen screen = new ConfirmScreen(callback, title, message);
|
||||
|
@ -46,7 +46,8 @@ public abstract class ClientPlayNetworkHandlerMixin
|
||||
public void onOnServerMetadata(ServerMetadataS2CPacket packet,
|
||||
CallbackInfo ci)
|
||||
{
|
||||
if(!WurstClient.INSTANCE.isEnabled())
|
||||
WurstClient wurst = WurstClient.INSTANCE;
|
||||
if(!wurst.isEnabled())
|
||||
return;
|
||||
|
||||
// Remove Mojang's dishonest warning toast on safe servers
|
||||
@ -58,10 +59,10 @@ public abstract class ClientPlayNetworkHandlerMixin
|
||||
}
|
||||
|
||||
// Add an honest warning toast on unsafe servers
|
||||
MutableText title = Text.literal(ChatUtils.WURST_PREFIX).append(
|
||||
Text.translatable("toast.wurst.nochatreports.unsafe_server.title"));
|
||||
MutableText message = Text
|
||||
.translatable("toast.wurst.nochatreports.unsafe_server.message");
|
||||
MutableText title = Text.literal(ChatUtils.WURST_PREFIX
|
||||
+ wurst.translate("toast.wurst.nochatreports.unsafe_server.title"));
|
||||
MutableText message = Text.literal(
|
||||
wurst.translate("toast.wurst.nochatreports.unsafe_server.message"));
|
||||
|
||||
SystemToast systemToast = SystemToast.create(client,
|
||||
SystemToast.Type.UNSECURE_SERVER_WARNING, title, message);
|
||||
|
@ -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.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.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.option.ControlsListWidget;
|
||||
import net.minecraft.client.gui.widget.ElementListWidget;
|
||||
import net.minecraft.client.gui.widget.EntryListWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableTextContent;
|
||||
import net.wurstclient.WurstClient;
|
||||
|
||||
@Mixin(ControlsListWidget.class)
|
||||
public abstract class ControlsListWidgetMixin
|
||||
extends ElementListWidget<ControlsListWidget.Entry>
|
||||
{
|
||||
public ControlsListWidgetMixin(WurstClient wurst, MinecraftClient client,
|
||||
int width, int height, int y, int itemHeight)
|
||||
{
|
||||
super(client, width, height, y, itemHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents Wurst's zoom keybind from being added to the controls list.
|
||||
*/
|
||||
@WrapOperation(at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/gui/screen/option/ControlsListWidget;addEntry(Lnet/minecraft/client/gui/widget/EntryListWidget$Entry;)I",
|
||||
ordinal = 1),
|
||||
method = "<init>(Lnet/minecraft/client/gui/screen/option/KeybindsScreen;Lnet/minecraft/client/MinecraftClient;)V")
|
||||
private int dontAddZoomEntry(ControlsListWidget instance,
|
||||
EntryListWidget.Entry<?> entry, Operation<Integer> original)
|
||||
{
|
||||
if(!(entry instanceof ControlsListWidget.KeyBindingEntry kbEntry))
|
||||
return original.call(instance, entry);
|
||||
|
||||
Text name = kbEntry.bindingName;
|
||||
if(name == null || !(name
|
||||
.getContent() instanceof TranslatableTextContent trContent))
|
||||
return original.call(instance, entry);
|
||||
|
||||
if(!"key.wurst.zoom".equals(trContent.getKey()))
|
||||
return original.call(instance, entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -47,12 +47,13 @@ public final class ForcedChatReportsScreen extends Screen
|
||||
|
||||
public ForcedChatReportsScreen(Screen prevScreen)
|
||||
{
|
||||
super(Text.literal(ChatUtils.WURST_PREFIX).append(
|
||||
Text.translatable("gui.wurst.nochatreports.unsafe_server.title")));
|
||||
super(Text.literal(ChatUtils.WURST_PREFIX)
|
||||
.append(Text.literal(WurstClient.INSTANCE
|
||||
.translate("gui.wurst.nochatreports.unsafe_server.title"))));
|
||||
this.prevScreen = prevScreen;
|
||||
|
||||
reason =
|
||||
Text.translatable("gui.wurst.nochatreports.unsafe_server.message");
|
||||
reason = Text.literal(WurstClient.INSTANCE
|
||||
.translate("gui.wurst.nochatreports.unsafe_server.message"));
|
||||
|
||||
NoChatReportsOtf ncr = WurstClient.INSTANCE.getOtfs().noChatReportsOtf;
|
||||
sigButtonMsg = () -> WurstClient.INSTANCE
|
||||
|
@ -43,12 +43,12 @@ public final class NcrModRequiredScreen extends Screen
|
||||
|
||||
public NcrModRequiredScreen(Screen prevScreen)
|
||||
{
|
||||
super(Text.literal(ChatUtils.WURST_PREFIX).append(
|
||||
Text.translatable("gui.wurst.nochatreports.ncr_mod_server.title")));
|
||||
super(Text.literal(ChatUtils.WURST_PREFIX + WurstClient.INSTANCE
|
||||
.translate("gui.wurst.nochatreports.ncr_mod_server.title")));
|
||||
this.prevScreen = prevScreen;
|
||||
|
||||
reason =
|
||||
Text.translatable("gui.wurst.nochatreports.ncr_mod_server.message");
|
||||
reason = Text.literal(WurstClient.INSTANCE
|
||||
.translate("gui.wurst.nochatreports.ncr_mod_server.message"));
|
||||
|
||||
OtfList otfs = WurstClient.INSTANCE.getOtfs();
|
||||
|
||||
|
@ -20,7 +20,6 @@ import net.minecraft.text.Text;
|
||||
import net.wurstclient.Category;
|
||||
import net.wurstclient.DontBlock;
|
||||
import net.wurstclient.SearchTags;
|
||||
import net.wurstclient.WurstClient;
|
||||
import net.wurstclient.events.UpdateListener;
|
||||
import net.wurstclient.other_feature.OtherFeature;
|
||||
import net.wurstclient.settings.CheckboxSetting;
|
||||
@ -81,15 +80,15 @@ public final class NoChatReportsOtf extends OtherFeature
|
||||
public MessageIndicator modifyIndicator(Text message,
|
||||
MessageSignatureData signature, MessageIndicator indicator)
|
||||
{
|
||||
if(!WurstClient.INSTANCE.isEnabled() || MC.isInSingleplayer())
|
||||
if(!WURST.isEnabled() || MC.isInSingleplayer())
|
||||
return indicator;
|
||||
|
||||
if(indicator != null || signature == null)
|
||||
return indicator;
|
||||
|
||||
return new MessageIndicator(0xE84F58, Icon.CHAT_MODIFIED,
|
||||
Text.literal(ChatUtils.WURST_PREFIX + "\u00a7cReportable\u00a7r - ")
|
||||
.append(Text.translatable(
|
||||
Text.literal(ChatUtils.WURST_PREFIX + "\u00a7cReportable\u00a7r - "
|
||||
+ WURST.translate(
|
||||
"description.wurst.nochatreports.message_is_reportable")),
|
||||
"Reportable");
|
||||
}
|
||||
@ -102,8 +101,7 @@ public final class NoChatReportsOtf extends OtherFeature
|
||||
|
||||
public boolean isActive()
|
||||
{
|
||||
return isEnabled() && WurstClient.INSTANCE.isEnabled()
|
||||
&& !MC.isInSingleplayer();
|
||||
return isEnabled() && WURST.isEnabled() && !MC.isInSingleplayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -8,6 +8,7 @@ accessible field net/minecraft/client/MinecraftClient itemUseCooldown I
|
||||
accessible field net/minecraft/client/gui/hud/ChatHud visibleMessages Ljava/util/List;
|
||||
accessible field net/minecraft/client/gui/screen/Screen drawables Ljava/util/List;
|
||||
accessible field net/minecraft/client/gui/screen/ingame/CreativeInventoryScreen selectedTab Lnet/minecraft/item/ItemGroup;
|
||||
accessible field net/minecraft/client/gui/screen/option/ControlsListWidget$KeyBindingEntry bindingName Lnet/minecraft/text/Text;
|
||||
accessible field net/minecraft/client/network/ClientPlayNetworkHandler messagePacker Lnet/minecraft/network/message/MessageChain$Packer;
|
||||
accessible field net/minecraft/client/network/ClientPlayNetworkHandler session Lnet/minecraft/network/encryption/ClientPlayerSession;
|
||||
accessible field net/minecraft/client/network/ClientPlayerEntity lastPitch F
|
||||
|
@ -25,6 +25,7 @@
|
||||
"ClientPlayerInteractionManagerMixin",
|
||||
"ClientPlayNetworkHandlerMixin",
|
||||
"ClientWorldMixin",
|
||||
"ControlsListWidgetMixin",
|
||||
"CreativeInventoryScreenMixin",
|
||||
"DeathScreenMixin",
|
||||
"DirectConnectScreenMixin",
|
||||
@ -40,6 +41,7 @@
|
||||
"IngameHudMixin",
|
||||
"InGameOverlayRendererMixin",
|
||||
"KeyBindingMixin",
|
||||
"KeybindTextContentMixin",
|
||||
"KeyboardMixin",
|
||||
"LanguageManagerMixin",
|
||||
"LivingEntityRendererMixin",
|
||||
@ -62,6 +64,7 @@
|
||||
"TelemetryManagerMixin",
|
||||
"TextVisitFactoryMixin",
|
||||
"TitleScreenMixin",
|
||||
"TranslatableTextContentMixin",
|
||||
"WorldMixin",
|
||||
"WorldRendererMixin"
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user