Add mixin to localize item names in chat components on the client (#480)

This commit is contained in:
Discreater authored and GitHub committed 2026-10-13 16:29:42 +02:00
1 parent 343a327dc7
commit 4604aaa85b
3 files changed
+54

No files matched your search

@@ -36,6 +36,11 @@ public class GTNHLibConfig {
@Config.DefaultBoolean(true)
public static boolean enableTranslucentItemRenders;
@Config.Comment("Replace item names in chat components (death messages, /give feedback, NEI item linking) with GTNHLib custom components so they are localized on the client. Disable this if vanilla (non-GTNHLib) clients connect to your server, as they cannot deserialize GTNHLib custom chat components.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableLocalizedItemChatComponents;
@Config.Comment("Enable client-side resource pack update checking for active packs")
@Config.DefaultBoolean(true)
public static boolean enableResourcePackUpdateCheck;
@@ -57,6 +57,9 @@ public enum Mixins implements IMixins {
.setApplyIf(() -> GTNHLibConfig.enableTranslucentItemRenders)),
CUSTOM_CHAT_COMPONENT_REGISTRATION(new MixinBuilder("Custom chat component registration")
.addCommonMixins("MixinIChatComponentSerializer").setPhase(Phase.EARLY)),
ITEM_CHAT_COMPONENT(new MixinBuilder("Localize item names in chat components on the client")
.addCommonMixins("MixinItemStack_GetChatComponent").setPhase(Phase.EARLY)
.setApplyIf(() -> GTNHLibConfig.enableLocalizedItemChatComponents)),
MULTI_RELEASE_JAR_FILTER(new MixinBuilder("Skip multi-release JAR entries in mod discovery")
.addCommonMixins("fml.MixinJarDiscoverer").setPhase(Phase.EARLY).addExcludedMod(TargetMods.LWJGL3IFY)),
PICK_BLOCK_TRAP(Side.CLIENT, "MixinMinecraft_PickBlockTrap"),
@@ -0,0 +1,46 @@
package com.gtnewhorizon.gtnhlib.mixins.early;
import net.minecraft.event.HoverEvent;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IChatComponent;
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 com.gtnewhorizon.gtnhlib.chat.customcomponents.ChatComponentItemName;
/**
* Vanilla {@code ItemStack.func_151000_E()} bakes the already-translated {@code getDisplayName()} into a
* {@link ChatComponentText} before the component is sent to the client. Because that translation happens on the server,
* clients end up rendering the server's language instead of their own for death messages, {@code /give} feedback,
* statistics, etc.
*
* <p>
* This mixin replaces the name text with a {@link ChatComponentItemName}, which carries the raw {@link ItemStack}. The
* stack is serialized as-is and only resolved via {@code getDisplayName()} on the client, using the client's locale.
*/
@Mixin(ItemStack.class)
public class MixinItemStack_GetChatComponent {
@Inject(method = "func_151000_E", at = @At("HEAD"), cancellable = true)
private void gtnhlib$localizeItemNameOnClient(CallbackInfoReturnable<IChatComponent> cir) {
ItemStack stack = (ItemStack) (Object) this;
// ChatComponentItemName already renders as "[name]" (with brackets) like vanilla func_151000_E().
IChatComponent ichatcomponent = new ChatComponentItemName(stack);
if (stack.getItem() != null) {
NBTTagCompound nbttagcompound = new NBTTagCompound();
stack.writeToNBT(nbttagcompound);
ichatcomponent.getChatStyle().setChatHoverEvent(
new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ChatComponentText(nbttagcompound.toString())));
ichatcomponent.getChatStyle().setColor(stack.getRarity().rarityColor);
}
cir.setReturnValue(ichatcomponent);
}
}