From 2f8f05331c83fbc072404330afff98b7c8a2d1c1 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:05:28 -0500 Subject: [PATCH 01/14] add error message when IOExcepting during en_us --- .../meteorclient/utils/misc/MeteorTranslations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 3b449ac3c7..e4b396f522 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -60,7 +60,7 @@ public static void loadLanguage(String languageCode) { MeteorClient.LOG.info("Loaded language: {}", languageCode); } } catch (IOException e) { - if (languageCode.equals("en_us")) throw new RuntimeException(e); + if (languageCode.equals("en_us")) throw new RuntimeException("Error loading default language", e); else MeteorClient.LOG.error("Error loading language: {}", languageCode, e); } From 9aed686bb70054a3651bac147d4e40e7d40f2a0f Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:06:14 -0500 Subject: [PATCH 02/14] always use utf8 for translations --- .../meteorclient/utils/misc/MeteorTranslations.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index e4b396f522..17233e495d 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.IllegalFormatException; import java.util.List; @@ -54,7 +55,7 @@ public static void loadLanguage(String languageCode) { } else { // noinspection unchecked - Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream), Object2ObjectOpenHashMap.class); + Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), Object2ObjectOpenHashMap.class); languages.put(languageCode, new MeteorLanguage(map)); MeteorClient.LOG.info("Loaded language: {}", languageCode); @@ -72,7 +73,7 @@ public static void loadLanguage(String languageCode) { MeteorLanguage lang = languages.getOrDefault(languageCode, new MeteorLanguage()); // noinspection unchecked - Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream), Object2ObjectOpenHashMap.class); + Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), Object2ObjectOpenHashMap.class); lang.addCustomTranslation(map); languages.put(languageCode, lang); From 6408e378b65f98a1dd8069a35b2401bdadd20057 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:18:41 -0500 Subject: [PATCH 03/14] set default lang as a constant --- .../utils/misc/MeteorTranslations.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 17233e495d..82f713810c 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -30,18 +30,22 @@ @SuppressWarnings("unused") public class MeteorTranslations { + private static final String EN_US_CODE = "en_us"; private static final Gson GSON = new Gson(); private static final Map languages = new Object2ObjectOpenHashMap<>(); + private static MeteorLanguage defaultLanguage; @PreInit public static void preInit() { List toLoad = new ArrayList<>(2); - toLoad.add("en_us"); - if (!mc.options.language.equalsIgnoreCase("en_us")) toLoad.add(mc.options.language); + toLoad.add(EN_US_CODE); + if (!mc.options.language.equalsIgnoreCase(EN_US_CODE)) toLoad.add(mc.options.language); for (String language : toLoad) { loadLanguage(language); } + + defaultLanguage = getLanguage(EN_US_CODE); } public static void loadLanguage(String languageCode) { @@ -50,7 +54,7 @@ public static void loadLanguage(String languageCode) { try (InputStream stream = MeteorTranslations.class.getResourceAsStream("/assets/meteor-client/language/" + languageCode + ".json")) { if (stream == null) { - if (languageCode.equals("en_us")) throw new RuntimeException("Error loading the default language"); + if (languageCode.equals(EN_US_CODE)) throw new RuntimeException("Error loading the default language"); else MeteorClient.LOG.info("No language file found for '{}'", languageCode); } else { @@ -61,7 +65,7 @@ public static void loadLanguage(String languageCode) { MeteorClient.LOG.info("Loaded language: {}", languageCode); } } catch (IOException e) { - if (languageCode.equals("en_us")) throw new RuntimeException("Error loading default language", e); + if (languageCode.equals(EN_US_CODE)) throw new RuntimeException("Error loading default language", e); else MeteorClient.LOG.error("Error loading language: {}", languageCode, e); } @@ -115,7 +119,7 @@ public static MeteorLanguage getCurrentLanguage() { } public static MeteorLanguage getDefaultLanguage() { - return languages.get("en_us"); + return defaultLanguage; } /** From c15102aa7853769e5fc0f8ccbd8d1ef0a3155abc Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:42:58 -0500 Subject: [PATCH 04/14] add id field to `MeteorAddon` --- .../meteordevelopment/meteorclient/addons/AddonManager.java | 2 ++ .../meteordevelopment/meteorclient/addons/MeteorAddon.java | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/meteordevelopment/meteorclient/addons/AddonManager.java b/src/main/java/meteordevelopment/meteorclient/addons/AddonManager.java index 54af1c4d00..2e1a10668e 100644 --- a/src/main/java/meteordevelopment/meteorclient/addons/AddonManager.java +++ b/src/main/java/meteordevelopment/meteorclient/addons/AddonManager.java @@ -48,6 +48,7 @@ public String getCommit() { ModMetadata metadata = FabricLoader.getInstance().getModContainer(MeteorClient.MOD_ID).get().getMetadata(); + MeteorClient.ADDON.id = metadata.getId(); MeteorClient.ADDON.name = metadata.getName(); MeteorClient.ADDON.authors = new String[metadata.getAuthors().size()]; if (metadata.containsCustomValue(MeteorClient.MOD_ID + ":color")) { @@ -72,6 +73,7 @@ public String getCommit() { throw new RuntimeException("Exception during addon init \"%s\".".formatted(metadata.getName()), throwable); } + addon.id = metadata.getId(); addon.name = metadata.getName(); if (metadata.getAuthors().isEmpty()) throw new RuntimeException("Addon \"%s\" requires at least 1 author to be defined in it's fabric.mod.json. See https://fabricmc.net/wiki/documentation:fabric_mod_json_spec".formatted(addon.name)); diff --git a/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java b/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java index 7ae5918d6f..01286ead0f 100644 --- a/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java +++ b/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java @@ -10,6 +10,10 @@ import java.io.InputStream; public abstract class MeteorAddon { + /** This field is automatically assigned from fabric.mod.json file. + * @since 1.21.11 */ // todo replace with exact version when released + public String id; + /** This field is automatically assigned from fabric.mod.json file. */ public String name; From 109b6ef99e52301396190b040b24c85550718cfc Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:50:09 -0500 Subject: [PATCH 05/14] compute map of localized languages --- .../utils/misc/MeteorTranslations.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 82f713810c..0ce3709542 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -12,6 +12,8 @@ import meteordevelopment.meteorclient.addons.AddonManager; import meteordevelopment.meteorclient.addons.MeteorAddon; import meteordevelopment.meteorclient.utils.PreInit; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.resource.language.LanguageDefinition; import net.minecraft.client.resource.language.ReorderingUtil; import net.minecraft.text.OrderedText; import net.minecraft.text.StringVisitable; @@ -33,10 +35,17 @@ public class MeteorTranslations { private static final String EN_US_CODE = "en_us"; private static final Gson GSON = new Gson(); private static final Map languages = new Object2ObjectOpenHashMap<>(); + private static final Map languageDefinitions = new Object2ObjectOpenHashMap<>(); private static MeteorLanguage defaultLanguage; @PreInit public static void preInit() { + MinecraftClient.getInstance().getLanguageManager().getAllLanguages().forEach((code, definition) -> { + if (hasLocalization(code)) { + languageDefinitions.put(code, definition); + } + }); + List toLoad = new ArrayList<>(2); toLoad.add(EN_US_CODE); if (!mc.options.language.equalsIgnoreCase(EN_US_CODE)) toLoad.add(mc.options.language); @@ -48,6 +57,20 @@ public static void preInit() { defaultLanguage = getLanguage(EN_US_CODE); } + private static boolean hasLocalization(String languageCode) { + if (doesLangFileExist(MeteorClient.ADDON, languageCode)) return true; + + for (MeteorAddon addon : AddonManager.ADDONS) { + if (doesLangFileExist(addon, languageCode)) return true; + } + + return false; + } + + private static boolean doesLangFileExist(MeteorAddon addon, String languageCode) { + return addon.getClass().getResource("/assets/" + addon.id + "/language/" + languageCode + ".json") != null; + } + public static void loadLanguage(String languageCode) { languageCode = languageCode.toLowerCase(); if (languages.containsKey(languageCode)) return; @@ -110,6 +133,10 @@ public static String translate(String key, String fallback, Object... args) { } } + public static Map getLanguageDefinitions() { + return languageDefinitions; + } + public static MeteorLanguage getLanguage(String lang) { return languages.get(lang); } From 9b1cfdba58ef89c0f38bb869debcc197c6f0bc55 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:52:56 -0500 Subject: [PATCH 06/14] add right-to-left support --- .../utils/misc/MeteorTranslations.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 0ce3709542..89a7f86b29 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -75,6 +75,9 @@ public static void loadLanguage(String languageCode) { languageCode = languageCode.toLowerCase(); if (languages.containsKey(languageCode)) return; + LanguageDefinition definition = languageDefinitions.get(languageCode); + if (definition == null) return; + try (InputStream stream = MeteorTranslations.class.getResourceAsStream("/assets/meteor-client/language/" + languageCode + ".json")) { if (stream == null) { if (languageCode.equals(EN_US_CODE)) throw new RuntimeException("Error loading the default language"); @@ -83,7 +86,7 @@ public static void loadLanguage(String languageCode) { else { // noinspection unchecked Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), Object2ObjectOpenHashMap.class); - languages.put(languageCode, new MeteorLanguage(map)); + languages.put(languageCode, new MeteorLanguage(definition.rightToLeft(), map)); MeteorClient.LOG.info("Loaded language: {}", languageCode); } @@ -97,7 +100,7 @@ public static void loadLanguage(String languageCode) { try (InputStream stream = addon.provideLanguage(languageCode)) { if (stream == null) continue; - MeteorLanguage lang = languages.getOrDefault(languageCode, new MeteorLanguage()); + MeteorLanguage lang = languages.getOrDefault(languageCode, new MeteorLanguage(definition.rightToLeft())); // noinspection unchecked Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), Object2ObjectOpenHashMap.class); @@ -157,7 +160,7 @@ public static double percentLocalised() { // translation. Maybe that will change in the future. if (isEnglish()) return 100; - double currentLangSize = languages.getOrDefault(mc.options.language.toLowerCase(), new MeteorLanguage()).translations.size(); + double currentLangSize = languages.getOrDefault(mc.options.language.toLowerCase(), new MeteorLanguage(false)).translations.size(); return (currentLangSize / getDefaultLanguage().translations.size()) * 100; } @@ -168,10 +171,14 @@ public static boolean isEnglish() { public static class MeteorLanguage extends Language { private final Map translations = new Object2ObjectOpenHashMap<>(); private final List> customTranslations = new ObjectArrayList<>(); + private final boolean rightToLeft; - public MeteorLanguage() {} + public MeteorLanguage(boolean rightToLeft) { + this.rightToLeft = rightToLeft; + } - public MeteorLanguage(Map translations) { + public MeteorLanguage(boolean rightToLeft, Map translations) { + this(rightToLeft); this.translations.putAll(translations); } @@ -205,12 +212,12 @@ public boolean hasTranslation(String key) { @Override public boolean isRightToLeft() { - return false; + return this.rightToLeft; } @Override public OrderedText reorder(StringVisitable text) { - return ReorderingUtil.reorder(text, false); + return ReorderingUtil.reorder(text, this.rightToLeft); } } } From 1dd7566498bde476a75cf613101a7feb8c214c15 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 01:08:48 -0500 Subject: [PATCH 07/14] flatten translation maps --- .../utils/misc/MeteorTranslations.java | 45 ++++++------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 89a7f86b29..6c1f314099 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -7,7 +7,6 @@ import com.google.gson.Gson; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.addons.AddonManager; import meteordevelopment.meteorclient.addons.MeteorAddon; @@ -78,6 +77,8 @@ public static void loadLanguage(String languageCode) { LanguageDefinition definition = languageDefinitions.get(languageCode); if (definition == null) return; + Object2ObjectOpenHashMap languageMap = new Object2ObjectOpenHashMap<>(); + try (InputStream stream = MeteorTranslations.class.getResourceAsStream("/assets/meteor-client/language/" + languageCode + ".json")) { if (stream == null) { if (languageCode.equals(EN_US_CODE)) throw new RuntimeException("Error loading the default language"); @@ -86,7 +87,7 @@ public static void loadLanguage(String languageCode) { else { // noinspection unchecked Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), Object2ObjectOpenHashMap.class); - languages.put(languageCode, new MeteorLanguage(definition.rightToLeft(), map)); + languageMap.putAll(map); MeteorClient.LOG.info("Loaded language: {}", languageCode); } @@ -100,18 +101,20 @@ public static void loadLanguage(String languageCode) { try (InputStream stream = addon.provideLanguage(languageCode)) { if (stream == null) continue; - MeteorLanguage lang = languages.getOrDefault(languageCode, new MeteorLanguage(definition.rightToLeft())); // noinspection unchecked Object2ObjectOpenHashMap map = GSON.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), Object2ObjectOpenHashMap.class); - lang.addCustomTranslation(map); - languages.put(languageCode, lang); + languageMap.putAll(map); MeteorClient.LOG.info("Loaded language {} from addon {}", languageCode, addon.name); } catch (IOException e) { MeteorClient.LOG.error("Error loading language {} from addon {}", languageCode, addon.name, e); } } + + if (!languageMap.isEmpty()) { + languages.put(languageCode, new MeteorLanguage(definition.rightToLeft(), languageMap)); + } } public static String translate(String key, Object... args) { @@ -160,7 +163,8 @@ public static double percentLocalised() { // translation. Maybe that will change in the future. if (isEnglish()) return 100; - double currentLangSize = languages.getOrDefault(mc.options.language.toLowerCase(), new MeteorLanguage(false)).translations.size(); + MeteorLanguage currentLang = languages.get(mc.options.language.toLowerCase()); + double currentLangSize = currentLang != null ? currentLang.translations.size() : 0; return (currentLangSize / getDefaultLanguage().translations.size()) * 100; } @@ -170,44 +174,21 @@ public static boolean isEnglish() { public static class MeteorLanguage extends Language { private final Map translations = new Object2ObjectOpenHashMap<>(); - private final List> customTranslations = new ObjectArrayList<>(); private final boolean rightToLeft; - public MeteorLanguage(boolean rightToLeft) { - this.rightToLeft = rightToLeft; - } - public MeteorLanguage(boolean rightToLeft, Map translations) { - this(rightToLeft); + this.rightToLeft = rightToLeft; this.translations.putAll(translations); } - public void addCustomTranslation(Map customTranslation) { - if (customTranslations.contains(customTranslation)) return; - - customTranslations.add(customTranslation); - } - @Override public String get(String key, String fallback) { - if (translations.containsKey(key)) return translations.get(key); - - for (Map customTranslation : customTranslations) { - if (customTranslation.containsKey(key)) return customTranslation.get(key); - } - - return fallback; + return translations.getOrDefault(key, fallback); } @Override public boolean hasTranslation(String key) { - if (translations.containsKey(key)) return true; - - for (Map customTranslation : customTranslations) { - if (customTranslation.containsKey(key)) return true; - } - - return false; + return translations.containsKey(key); } @Override From d0539e2da2b5e1e00ead90dd4eb0c9695c252a81 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 01:13:43 -0500 Subject: [PATCH 08/14] these are actually case sensitive --- .../meteorclient/utils/misc/MeteorTranslations.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 6c1f314099..5d121fb62c 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -47,7 +47,7 @@ public static void preInit() { List toLoad = new ArrayList<>(2); toLoad.add(EN_US_CODE); - if (!mc.options.language.equalsIgnoreCase(EN_US_CODE)) toLoad.add(mc.options.language); + if (!mc.options.language.equals(EN_US_CODE)) toLoad.add(mc.options.language); for (String language : toLoad) { loadLanguage(language); @@ -71,7 +71,6 @@ private static boolean doesLangFileExist(MeteorAddon addon, String languageCode) } public static void loadLanguage(String languageCode) { - languageCode = languageCode.toLowerCase(); if (languages.containsKey(languageCode)) return; LanguageDefinition definition = languageDefinitions.get(languageCode); @@ -148,7 +147,7 @@ public static MeteorLanguage getLanguage(String lang) { } public static MeteorLanguage getCurrentLanguage() { - return languages.getOrDefault(mc.options.language.toLowerCase(), getDefaultLanguage()); + return languages.getOrDefault(mc.options.language, getDefaultLanguage()); } public static MeteorLanguage getDefaultLanguage() { @@ -163,13 +162,13 @@ public static double percentLocalised() { // translation. Maybe that will change in the future. if (isEnglish()) return 100; - MeteorLanguage currentLang = languages.get(mc.options.language.toLowerCase()); + MeteorLanguage currentLang = languages.get(mc.options.language); double currentLangSize = currentLang != null ? currentLang.translations.size() : 0; return (currentLangSize / getDefaultLanguage().translations.size()) * 100; } public static boolean isEnglish() { - return mc.options.language.toLowerCase().startsWith("en"); + return mc.options.language.startsWith("en"); } public static class MeteorLanguage extends Language { From 02e834acb763470e0df62cfac37d3dddbadbf3bf Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 01:15:47 -0500 Subject: [PATCH 09/14] automatic addon language registration --- .../meteorclient/addons/MeteorAddon.java | 24 ------------------- .../utils/misc/MeteorTranslations.java | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java b/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java index 01286ead0f..5c2eb55fff 100644 --- a/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java +++ b/src/main/java/meteordevelopment/meteorclient/addons/MeteorAddon.java @@ -7,8 +7,6 @@ import meteordevelopment.meteorclient.utils.render.color.Color; -import java.io.InputStream; - public abstract class MeteorAddon { /** This field is automatically assigned from fabric.mod.json file. * @since 1.21.11 */ // todo replace with exact version when released @@ -40,26 +38,4 @@ public GithubRepo getRepo() { public String getCommit() { return null; } - - /** - * Example implementation: - *
{@code
-     *  @Override
-     *  public InputStream provideLanguage(String lang) {
-     *      return Addon.class.getResourceAsStream("/assets/addon-name/language/" + lang + ".json")
-     *  }
-     * }
-     * 

- * - * Addons should not store their language files in the /assets/xxx/lang/ path as it opens up users to detection - * by servers via the translation exploit. - * Storing them anywhere else should prevent them from getting picked up via the vanilla resource loader. - * - * @param lang A language code in lowercase - * @return An InputStream for the relevant json translation file, or null if the addon doesn't have - * a file for that language. - */ - public InputStream provideLanguage(String lang) { - return null; - } } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 5d121fb62c..92a97a3f16 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -98,7 +98,7 @@ public static void loadLanguage(String languageCode) { for (MeteorAddon addon : AddonManager.ADDONS) { if (addon == MeteorClient.ADDON) continue; - try (InputStream stream = addon.provideLanguage(languageCode)) { + try (InputStream stream = addon.getClass().getResourceAsStream("/assets/" + addon.id + "/language/" + languageCode + ".json")) { if (stream == null) continue; // noinspection unchecked From 241cbe8ac988cdfebd50cb6d1c8e4b78bacb902f Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 01:37:26 -0500 Subject: [PATCH 10/14] oops turns out you dont have those during `@PreInit` --- .../meteorclient/utils/misc/MeteorTranslations.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 92a97a3f16..e6b460be07 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -34,17 +34,10 @@ public class MeteorTranslations { private static final String EN_US_CODE = "en_us"; private static final Gson GSON = new Gson(); private static final Map languages = new Object2ObjectOpenHashMap<>(); - private static final Map languageDefinitions = new Object2ObjectOpenHashMap<>(); private static MeteorLanguage defaultLanguage; @PreInit public static void preInit() { - MinecraftClient.getInstance().getLanguageManager().getAllLanguages().forEach((code, definition) -> { - if (hasLocalization(code)) { - languageDefinitions.put(code, definition); - } - }); - List toLoad = new ArrayList<>(2); toLoad.add(EN_US_CODE); if (!mc.options.language.equals(EN_US_CODE)) toLoad.add(mc.options.language); @@ -73,7 +66,7 @@ private static boolean doesLangFileExist(MeteorAddon addon, String languageCode) public static void loadLanguage(String languageCode) { if (languages.containsKey(languageCode)) return; - LanguageDefinition definition = languageDefinitions.get(languageCode); + LanguageDefinition definition = MinecraftClient.getInstance().getLanguageManager().getLanguage(languageCode); if (definition == null) return; Object2ObjectOpenHashMap languageMap = new Object2ObjectOpenHashMap<>(); @@ -138,10 +131,6 @@ public static String translate(String key, String fallback, Object... args) { } } - public static Map getLanguageDefinitions() { - return languageDefinitions; - } - public static MeteorLanguage getLanguage(String lang) { return languages.get(lang); } From eb9f969031d2c4452643bf7f20be3b788535effb Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 01:55:00 -0500 Subject: [PATCH 11/14] fix command descriptions --- .../meteorclient/commands/commands/CommandsCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java index ca08d56e89..7f63c4cd26 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/CommandsCommand.java @@ -53,7 +53,7 @@ private MutableText getCommandText(Command command) { } tooltip.append(aliases.formatted(Formatting.GRAY)).append("\n\n"); - tooltip.append(translatable("description")).formatted(Formatting.WHITE); + tooltip.append(command.translatable("description")).formatted(Formatting.WHITE); // Text MutableText text = Text.literal(Utils.nameToTitle(command.getName())); From 9f5fc57143c1328da2b40bd4268b99ea82a1b07e Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 01:55:16 -0500 Subject: [PATCH 12/14] sadly cant use these --- .../utils/misc/MeteorTranslations.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index e6b460be07..8ca54ff676 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -49,20 +49,6 @@ public static void preInit() { defaultLanguage = getLanguage(EN_US_CODE); } - private static boolean hasLocalization(String languageCode) { - if (doesLangFileExist(MeteorClient.ADDON, languageCode)) return true; - - for (MeteorAddon addon : AddonManager.ADDONS) { - if (doesLangFileExist(addon, languageCode)) return true; - } - - return false; - } - - private static boolean doesLangFileExist(MeteorAddon addon, String languageCode) { - return addon.getClass().getResource("/assets/" + addon.id + "/language/" + languageCode + ".json") != null; - } - public static void loadLanguage(String languageCode) { if (languages.containsKey(languageCode)) return; From a94a64b688491c0746e12579b22f5d59f0c49de8 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 02:30:25 -0500 Subject: [PATCH 13/14] dont have like all of the languages --- .../meteorclient/mixin/LanguageManagerMixin.java | 1 + .../meteorclient/utils/misc/MeteorTranslations.java | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/LanguageManagerMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/LanguageManagerMixin.java index 228143cef8..4a1868909c 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/LanguageManagerMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/LanguageManagerMixin.java @@ -17,5 +17,6 @@ public class LanguageManagerMixin { @Inject(method = "setLanguage", at = @At("TAIL")) private void onSetLanguage(String languageCode, CallbackInfo ci) { MeteorTranslations.loadLanguage(languageCode); + MeteorTranslations.clearUnusedLanguages(languageCode); } } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java index 8ca54ff676..c726bb5d4e 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/misc/MeteorTranslations.java @@ -22,10 +22,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.IllegalFormatException; -import java.util.List; -import java.util.Map; +import java.util.*; import static meteordevelopment.meteorclient.MeteorClient.mc; @@ -95,6 +92,10 @@ public static void loadLanguage(String languageCode) { } } + public static void clearUnusedLanguages(String currentLanguageCode) { + languages.keySet().removeIf(languageCode -> !languageCode.equals(EN_US_CODE) && !languageCode.equals(currentLanguageCode)); + } + public static String translate(String key, Object... args) { MeteorLanguage currentLang = getCurrentLanguage(); String translated = currentLang.get(key, getDefaultLanguage().get(key)); From 9db28d9cc583bbe68d9c84ceb4888c96a1facdea Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Tue, 18 Nov 2025 03:25:55 -0500 Subject: [PATCH 14/14] fix wasp target info --- src/main/resources/assets/meteor-client/language/en_us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/meteor-client/language/en_us.json b/src/main/resources/assets/meteor-client/language/en_us.json index 35aa0b8e0c..c27502e5fe 100644 --- a/src/main/resources/assets/meteor-client/language/en_us.json +++ b/src/main/resources/assets/meteor-client/language/en_us.json @@ -69,6 +69,6 @@ "meteor.command.vclip.description": "Lets you clip through blocks vertically.", "meteor.command.wasp.description": "Sets the auto wasp target.", "meteor.command.wasp.exception.cant_wasp_self": "You cannot target yourself!", - "meteor.command.wasp.info.target": "%d set as target.", + "meteor.command.wasp.info.target": "%s set as target.", "meteor.command.waypoint.description": "Manages waypoints." }