Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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')
}

Expand Down
3 changes: 3 additions & 0 deletions libraries/localization/README.md
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions libraries/localization/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
setUpLibrary(project)
8 changes: 8 additions & 0 deletions libraries/localization/gradle.properties
Original file line number Diff line number Diff line change
@@ -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-
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
setUpModule(project,
'entrypoints-mc13w16a-mc1.14.4',
'lifecycle-events-mc19w04a-mc1.14.4',
'resource-loader-mc19w08a-mc1.14.4'
)
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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<String, String> translations;

@Shadow
private void load(List<Resource> 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<String> 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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it supposed to be toUpperCase for 1.12+ as lowercase is the default in those versions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah converting to lowercase is pointless here. But converting to uppercase format isn't trivial as e.g. en_us becomes en_US, not EN_US. There are more complicated region codes too, but I don't know them off the top of my head.

};

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<String> 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<Void> original, @Local Resource resource) throws IOException{
if (resource.getLocation().getPath().endsWith(".lang")){
Translations.loadFromLang(is, translations::put);
} else {
original.call(instance, is); // load .json
}
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
setUpModule(project,
'entrypoints-mcin-20091223-1459-mc1.5.2',
'resource-loader-mca1.2.2-mc11w48a'
)
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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 = "<init>",
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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading