diff --git a/build.gradle b/build.gradle index 34c56c79..ebadbbc6 100644 --- a/build.gradle +++ b/build.gradle @@ -188,6 +188,8 @@ def setUpLibrary(project) { implementation "org.apache.logging.log4j:log4j-api:2.19.0" implementation "org.apache.logging.log4j:log4j-core:2.19.0" + implementation "org.quiltmc.parsers:json:${project.rootProject.quilt_parsers_version}" + implementation project.dependencies.project(path: ':libraries:core', configuration: 'namedElements') } diff --git a/libraries/localization/README.md b/libraries/localization/README.md new file mode 100644 index 00000000..2ff3ca0a --- /dev/null +++ b/libraries/localization/README.md @@ -0,0 +1,3 @@ +# Localization API + +The Localization API provides a consistent access point for localized text, and adds support for localization in versions that do not natively do so. diff --git a/libraries/localization/build.gradle b/libraries/localization/build.gradle new file mode 100644 index 00000000..e98ba2c6 --- /dev/null +++ b/libraries/localization/build.gradle @@ -0,0 +1 @@ +setUpLibrary(project) diff --git a/libraries/localization/gradle.properties b/libraries/localization/gradle.properties new file mode 100644 index 00000000..19578d1e --- /dev/null +++ b/libraries/localization/gradle.properties @@ -0,0 +1,8 @@ +library_id = localization +library_name = Localization +library_description = Localization API and events. +library_version = 0.1.0-alpha.1 + +entrypoint_init = net.ornithemc.osl.resource.loader.impl.ResourceLoader +entrypoint_client_init = net.ornithemc.osl.resource.loader.impl.ResourceLoader +osl_dependencies = core:>=0.7.0-,entrypoints:>=0.5.0-,lifecycle-events:>=0.6.0- diff --git a/libraries/localization/localization-mc17w43a-mc1.14.4/build.gradle b/libraries/localization/localization-mc17w43a-mc1.14.4/build.gradle new file mode 100644 index 00000000..9e50e853 --- /dev/null +++ b/libraries/localization/localization-mc17w43a-mc1.14.4/build.gradle @@ -0,0 +1,5 @@ +setUpModule(project, + 'entrypoints-mc13w16a-mc1.14.4', + 'lifecycle-events-mc19w04a-mc1.14.4', + 'resource-loader-mc19w08a-mc1.14.4' +) diff --git a/libraries/localization/localization-mc17w43a-mc1.14.4/gradle.properties b/libraries/localization/localization-mc17w43a-mc1.14.4/gradle.properties new file mode 100644 index 00000000..ca65bff2 --- /dev/null +++ b/libraries/localization/localization-mc17w43a-mc1.14.4/gradle.properties @@ -0,0 +1,6 @@ +min_mc_version = 19w08a +max_mc_version = 1.14.4 +minecraft_dependency = >=1.13-alpha.17.43.a <=1.14.4 + +minecraft_version = 1.14.4 +feather_build = 1 diff --git a/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/java/net/ornithemc/osl/localization/impl/mixin/client/LocaleMixin.java b/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/java/net/ornithemc/osl/localization/impl/mixin/client/LocaleMixin.java new file mode 100644 index 00000000..07bacd72 --- /dev/null +++ b/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/java/net/ornithemc/osl/localization/impl/mixin/client/LocaleMixin.java @@ -0,0 +1,85 @@ +package net.ornithemc.osl.localization.impl.mixin.client; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +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.CallbackInfo; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; + +import net.minecraft.client.resource.language.Locale; +import net.minecraft.resource.Identifier; +import net.minecraft.resource.Resource; +import net.minecraft.resource.manager.ResourceManager; + +import net.ornithemc.osl.localization.impl.Localization; +import net.ornithemc.osl.localization.impl.language.Translations; + +@Mixin(Locale.class) +public abstract class LocaleMixin { + + @Final + @Shadow + private Map translations; + + @Shadow + private void load(List resources) { } + + @Inject( + method = "load(Lnet/minecraft/resource/manager/ResourceManager;Ljava/util/List;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/resource/manager/ResourceManager;getResources(Lnet/minecraft/resource/Identifier;)Ljava/util/List;" + ) + ) + private void osl$localization$loadLanguage(ResourceManager resourceManager, List languageCodes, CallbackInfo ci, + @Local(ordinal = 0) String languageCode, @Local(ordinal = 2) String namespace) { + String[] paths = new String[] { + String.format("lang/%s.lang", languageCode), + String.format("lang/%s.json", languageCode.toLowerCase(java.util.Locale.ROOT)), + String.format("lang/%s.lang", languageCode.toLowerCase(java.util.Locale.ROOT)) + }; + + for (String path : paths) { + try { + load(resourceManager.getResources(new Identifier(namespace, path))); + } catch (IOException ignored) { + } + } + } + + @Inject( + method = "load(Lnet/minecraft/resource/manager/ResourceManager;Ljava/util/List;)V", + at = @At( + value = "TAIL" + ) + ) + private void osl$localization$languageLoaded(ResourceManager resourceManager, List languageCodes, CallbackInfo ci) { + // create a new translator every time in case another mod messes with the map + Localization.languageLoaded(languageCodes.get(languageCodes.size() - 1), Translations.wrap(translations)); + } + + @WrapOperation( + method = "load(Ljava/util/List;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/resource/language/Locale;load(Ljava/io/InputStream;)V" + ) + ) + private void osl$localization$loadTranslations(Locale instance, InputStream is, Operation original, @Local Resource resource) throws IOException{ + if (resource.getLocation().getPath().endsWith(".lang")){ + Translations.loadFromLang(is, translations::put); + } else { + original.call(instance, is); // load .json + } + } +} diff --git a/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/resources/fabric.mod.json b/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..3d317242 --- /dev/null +++ b/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/resources/fabric.mod.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "id": "osl-resource-loader", + "version": "0.6.0-alpha.1+mc19w08a-mc1.14.4", + "environment": "*", + "entrypoints": { + "init": [ + "net.ornithemc.osl.resource.loader.impl.ResourceLoader" + ], + "client-init": [ + "net.ornithemc.osl.resource.loader.impl.ResourceLoader" + ] + }, + "mixins": [ + "osl.resource-loader.mixins.json" + ], + "depends": { + "fabricloader": "\u003e\u003d0.17.3", + "minecraft": "\u003e\u003d1.14-alpha.19.8.a \u003c\u003d1.14.4", + "osl-core": "\u003e\u003d0.7.0-", + "osl-entrypoints": "\u003e\u003d0.5.0-", + "osl-lifecycle-events": "\u003e\u003d0.6.0-" + }, + "name": "OSL Resource Loader", + "description": "Resource loading API and events.", + "authors": [ + "OrnitheMC" + ], + "contact": { + "homepage": "https://ornithemc.net/", + "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues", + "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries" + }, + "license": "Apache-2.0" +} \ No newline at end of file diff --git a/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/resources/osl.localization.mixins.json b/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/resources/osl.localization.mixins.json new file mode 100644 index 00000000..18895240 --- /dev/null +++ b/libraries/localization/localization-mc17w43a-mc1.14.4/src/main/resources/osl.localization.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.ornithemc.osl.localization.impl.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "client.LocaleMixin" + ], + "server": [ + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/libraries/localization/localization-mca1.2.2-mc11w48a/build.gradle b/libraries/localization/localization-mca1.2.2-mc11w48a/build.gradle new file mode 100644 index 00000000..c772e7a5 --- /dev/null +++ b/libraries/localization/localization-mca1.2.2-mc11w48a/build.gradle @@ -0,0 +1,4 @@ +setUpModule(project, + 'entrypoints-mcin-20091223-1459-mc1.5.2', + 'resource-loader-mca1.2.2-mc11w48a' +) diff --git a/libraries/localization/localization-mca1.2.2-mc11w48a/gradle.properties b/libraries/localization/localization-mca1.2.2-mc11w48a/gradle.properties new file mode 100644 index 00000000..decaf65f --- /dev/null +++ b/libraries/localization/localization-mca1.2.2-mc11w48a/gradle.properties @@ -0,0 +1,8 @@ +environment = client +min_mc_version = a1.2.2 +max_mc_version = 11w48a +minecraft_dependency = >=1.0.0-alpha.2.2 <=1.1-alpha.11.48.a + +minecraft_version = 11w48a +feather_build = 1 +client_nests_build = 11 diff --git a/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/java/net/ornithemc/osl/resource/loader/impl/mixin/client/LanguageMixin.java b/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/java/net/ornithemc/osl/resource/loader/impl/mixin/client/LanguageMixin.java new file mode 100644 index 00000000..24a7c7b6 --- /dev/null +++ b/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/java/net/ornithemc/osl/resource/loader/impl/mixin/client/LanguageMixin.java @@ -0,0 +1,85 @@ +package net.ornithemc.osl.resource.loader.impl.mixin.client; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; +import java.util.Properties; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.locale.Language; + +import net.ornithemc.osl.core.api.util.NamespacedIdentifiers; +import net.ornithemc.osl.localization.impl.Localization; +import net.ornithemc.osl.localization.impl.language.Languages; +import net.ornithemc.osl.localization.impl.language.Translations; +import net.ornithemc.osl.resource.loader.api.ModTexturePack; +import net.ornithemc.osl.resource.loader.impl.ResourceLoader; + +@Mixin(Language.class) +public class LanguageMixin { + + @Shadow + private Properties translations; + + @Inject( + method = "", + at = @At( + value = "TAIL" + ) + ) + private void osl$resource_loader$loadModTranslations(CallbackInfo ci) throws IOException { + String lang = Localization.getLanguage(); + + if (!lang.equals(Languages.FALLBACK)) { + loadLanguage(Languages.FALLBACK); + } + + loadLanguage(lang); + + // create a new translator every time in case another mod messes with the map + Localization.languageLoaded(lang, Translations.wrap(translations)); + } + + @Unique + private void loadLanguage(String language) { + String pathFormat = "/assets/%s/lang/%s.%s"; + + for (ModTexturePack pack : ResourceLoader.getDefaultModResourcePacks()) { + String[] namespaces = new String[] { + NamespacedIdentifiers.MINECRAFT_NAMESPACE, + pack.getModMetadata().getId() + }; + + for (String namespace : namespaces) { + String[] paths = new String[] { + String.format(pathFormat, namespace, language, "lang"), + String.format(pathFormat, namespace, language, "json"), + String.format(pathFormat, namespace, language.toLowerCase(Locale.ROOT), "lang"), + String.format(pathFormat, namespace, language.toLowerCase(Locale.ROOT), "json") + }; + + for (String path : paths) { + try { + loadTranslations(path, pack.getResource(path)); + } catch (IOException ignored) { + } + } + } + } + } + + @Unique + private void loadTranslations(String path, InputStream is) throws IOException { + if (path.endsWith(".lang")) { + Translations.loadFromLang(is, translations::put); + } else { + Translations.loadFromJson(is, translations::put); + } + } +} diff --git a/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/resources/fabric.mod.json b/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..1d44b4dc --- /dev/null +++ b/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/resources/fabric.mod.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "id": "osl-resource-loader", + "version": "0.6.0-alpha.1+mca1.2.2-mc11w48a", + "environment": "client", + "entrypoints": { + "init": [ + "net.ornithemc.osl.resource.loader.impl.ResourceLoader" + ], + "client-init": [ + "net.ornithemc.osl.resource.loader.impl.ResourceLoader" + ] + }, + "mixins": [ + "osl.resource-loader.mixins.json" + ], + "depends": { + "fabricloader": "\u003e\u003d0.17.3", + "minecraft": "\u003e\u003d1.0.0-alpha.2.2 \u003c\u003d1.1-alpha.11.48.a", + "osl-core": "\u003e\u003d0.7.0-", + "osl-entrypoints": "\u003e\u003d0.5.0-", + "osl-lifecycle-events": "\u003e\u003d0.6.0-" + }, + "name": "OSL Resource Loader", + "description": "Resource loading API and events.", + "authors": [ + "OrnitheMC" + ], + "contact": { + "homepage": "https://ornithemc.net/", + "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues", + "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries" + }, + "license": "Apache-2.0" +} \ No newline at end of file diff --git a/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/resources/osl.resource-loader.mixins.json b/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/resources/osl.resource-loader.mixins.json new file mode 100644 index 00000000..59663fcd --- /dev/null +++ b/libraries/localization/localization-mca1.2.2-mc11w48a/src/main/resources/osl.resource-loader.mixins.json @@ -0,0 +1,17 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.ornithemc.osl.resource.loader.impl.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "client.TexturePackMixin", + "client.LanguageMixin" + ], + "server": [ + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/api/L10n.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/api/L10n.java new file mode 100644 index 00000000..1c01813e --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/api/L10n.java @@ -0,0 +1,46 @@ +package net.ornithemc.osl.localization.api; + +import net.ornithemc.osl.localization.impl.Localization; + +/** + * Utility methods for localization. + */ +public class L10n { + + /** + * @return the currently selected language for localization. + */ + public static String getLanguage() { + return Localization.getLanguage(); + } + + /** + * @return the localization of the given translation key. + */ + public static String get(String key) { + return Localization.get(key); + } + + /** + * @return the localization of the given translation key, + * with the given arguments applied. + */ + public static String get(String key, Object... args) { + return Localization.get(key, args); + } + + /** + * @return the localization of the given translation key, + * or the given default value if none exists. + */ + public static String getOrDefault(String key, String defaultLocalization) { + return Localization.getOrDefault(key, defaultLocalization); + } + + /** + * @return whether a localization exists for the given translation key. + */ + public static boolean has(String key) { + return Localization.has(key); + } +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/api/LocalizationEvents.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/api/LocalizationEvents.java new file mode 100644 index 00000000..46690f08 --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/api/LocalizationEvents.java @@ -0,0 +1,45 @@ +package net.ornithemc.osl.localization.api; + +import java.util.function.Consumer; + +import net.ornithemc.osl.core.api.events.Event; + +/** + * Events related to localization. + */ +public class LocalizationEvents { + + /** + * This event is invoked before language translations are reloaded. + * + *

+ * Callbacks to this event should be registered in your mod's entrypoint, + * and can be done as follows: + * + *

+	 * {@code
+	 * LocalizationEvents.START_LANGUAGE_RELOAD.register(language -> {
+	 * 	...
+	 * });
+	 * }
+	 * 
+ */ + public static final Event> START_LANGUAGE_RELOAD = Event.consumer(); + + /** + * This event is invoked after language translations are reloaded. + * + *

+ * Callbacks to this event should be registered in your mod's entrypoint, + * and can be done as follows: + * + *

+	 * {@code
+	 * LocalizationEvents.END_LANGUAGE_RELOAD.register(language -> {
+	 * 	...
+	 * });
+	 * }
+	 * 
+ */ + public static final Event> END_LANGUAGE_RELOAD = Event.consumer(); +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/Localization.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/Localization.java new file mode 100644 index 00000000..ec4fb509 --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/Localization.java @@ -0,0 +1,62 @@ +package net.ornithemc.osl.localization.impl; + +import java.util.IllegalFormatException; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import net.ornithemc.osl.localization.impl.language.Languages; +import net.ornithemc.osl.localization.impl.language.TranslationStorage; +import net.ornithemc.osl.localization.impl.language.Translations; + +public class Localization { + + public static final Logger LOGGER = LogManager.getLogger("OSL|Localization"); + + private static LocalizationLoader loader; + + private static String language = Languages.DEFAULT; + private static TranslationStorage translations = Translations.NONE;; + + public static void setLoader(LocalizationLoader loadr) { + loader = loadr; + } + + /** + * @return the currently selected language for localization. + */ + public static String getLanguage() { + return language; + } + + /** + * Select the given language for localization and trigger a language reload. + */ + public static void setLanguage(String lang) { + loader.loadLanguage(lang); + } + + /** + * Update translations after a language reload. + */ + public static void languageLoaded(String lang, TranslationStorage translator) { + language = lang; + translations = translator; + } + + public static String get(String key, Object... args) { + try { + return String.format(translations.get(key), args); + } catch (IllegalFormatException e) { + return "format error: " + key; + } + } + + public static String getOrDefault(String key, String defaultLocalization) { + return translations.getOrDefault(key, defaultLocalization); + } + + public static boolean has(String key) { + return translations.containsKey(key); + } +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/LocalizationLoader.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/LocalizationLoader.java new file mode 100644 index 00000000..48cf6ef3 --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/LocalizationLoader.java @@ -0,0 +1,7 @@ +package net.ornithemc.osl.localization.impl; + +public interface LocalizationLoader { + + void loadLanguage(String language); + +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/Languages.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/Languages.java new file mode 100644 index 00000000..5c2d89ed --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/Languages.java @@ -0,0 +1,10 @@ +package net.ornithemc.osl.localization.impl.language; + +public class Languages { + + public static final String EN_US = "en_US"; + + public static final String DEFAULT = EN_US; + public static final String FALLBACK = EN_US; + +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/TranslationConsumer.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/TranslationConsumer.java new file mode 100644 index 00000000..ce755dd5 --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/TranslationConsumer.java @@ -0,0 +1,7 @@ +package net.ornithemc.osl.localization.impl.language; + +public interface TranslationConsumer { + + void accept(String key, String translation); + +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/TranslationStorage.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/TranslationStorage.java new file mode 100644 index 00000000..7a654b6f --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/TranslationStorage.java @@ -0,0 +1,11 @@ +package net.ornithemc.osl.localization.impl.language; + +public interface TranslationStorage { + + String get(String key); + + String getOrDefault(String key, String defaultValue); + + boolean containsKey(String key); + +} diff --git a/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/Translations.java b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/Translations.java new file mode 100644 index 00000000..8df678fb --- /dev/null +++ b/libraries/localization/src/main/java/net/ornithemc/osl/localization/impl/language/Translations.java @@ -0,0 +1,98 @@ +package net.ornithemc.osl.localization.impl.language; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Map; +import java.util.Properties; + +import org.quiltmc.parsers.json.JsonReader; + +public class Translations { + + public static final TranslationStorage NONE = new TranslationStorage() { + + @Override + public String get(String key) { + return key; + } + + @Override + public String getOrDefault(String key, String defaultValue) { + return key; + } + + @Override + public boolean containsKey(String key) { + return false; + } + }; + + public static TranslationStorage wrap(Map translations) { + return new TranslationStorage() { + + @Override + public String get(String key) { + return translations.get(key); + } + + @Override + public String getOrDefault(String key, String defaultValue) { + return translations.getOrDefault(key, defaultValue); + } + + @Override + public boolean containsKey(String key) { + return translations.containsKey(key); + } + }; + } + + public static TranslationStorage wrap(Properties translations) { + return new TranslationStorage() { + + @Override + public String get(String key) { + return translations.getProperty(key); + } + + @Override + public String getOrDefault(String key, String defaultValue) { + return translations.getProperty(key, defaultValue); + } + + @Override + public boolean containsKey(String key) { + return translations.containsKey(key); + } + }; + } + + public static void loadFromLang(InputStream is, TranslationConsumer translations) throws IOException { + try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) { + String line; + while ((line = br.readLine()) != null) { + line = line.trim(); + if (line.isEmpty() || line.startsWith("#")) { + continue; + } + String[] args = line.split("=", 2); + if (args.length != 2) { + continue; + } + translations.accept(args[0], args[1]); + } + } + } + + public static void loadFromJson(InputStream is, TranslationConsumer translations) throws IOException { + try (JsonReader reader = JsonReader.json(new InputStreamReader(is))) { + reader.beginObject(); + while (reader.hasNext()) { + translations.accept(reader.nextName(), reader.nextString()); + } + reader.endObject(); + } + } +} diff --git a/settings.gradle b/settings.gradle index faa8e033..de20104f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -60,6 +60,10 @@ include ':libraries:lifecycle-events:lifecycle-events-mc13w36a-mc1.13' include ':libraries:lifecycle-events:lifecycle-events-mc18w30a-mc18w50a' include ':libraries:lifecycle-events:lifecycle-events-mc19w04a-mc1.14.4' +include ':libraries:localization' +include ':libraries:localization:localization-mca1.2.2-mc11w48a' +include ':libraries:localization:localization-mc17w43a-mc1.14.4' + include ':libraries:networking' include ':libraries:networking:networking-mca1.0.16-mca1.2.6' include ':libraries:networking:networking-mca0.1.0-mca0.2.1'