优化对于 ISO 639-3 语言代码的支持 (#4455)

This commit is contained in:
Glavo
2025-09-11 19:13:17 +08:00
committed by GitHub
parent c65e4d83a2
commit 9ded2e489d
5 changed files with 145 additions and 96 deletions

View File

@@ -111,36 +111,27 @@ public final class HMCLGameLauncher extends DefaultLauncher {
}
private static String normalizedLanguageTag(Locale locale, GameVersionNumber gameVersion) {
String language = locale.getLanguage();
String region = locale.getCountry();
switch (language) {
case "ru":
return "ru_RU";
case "uk":
return "uk_UA";
case "es":
return "es_ES";
case "ja":
return "ja_JP";
case "lzh":
return gameVersion.compareTo("1.16") >= 0
? "lzh"
: "";
case "zh":
default:
if (LocaleUtils.isChinese(locale)) {
String script = LocaleUtils.getScript(locale);
if ("Hant".equals(script)) {
if ((region.equals("HK") || region.equals("MO") && gameVersion.compareTo("1.16") >= 0))
return "zh_HK";
return "zh_TW";
}
return "zh_CN";
}
return switch (LocaleUtils.getISO1Language(locale)) {
case "es" -> "es_ES";
case "ja" -> "ja_JP";
case "ru" -> "ru_RU";
case "uk" -> "uk_UA";
case "zh" -> {
if ("lzh".equals(locale.getLanguage()) && gameVersion.compareTo("1.16") >= 0)
yield "lzh";
return "";
}
String script = LocaleUtils.getScript(locale);
if ("Hant".equals(script)) {
if ((region.equals("HK") || region.equals("MO") && gameVersion.compareTo("1.16") >= 0))
yield "zh_HK";
yield "zh_TW";
}
yield "zh_CN";
}
default -> "";
};
}
@Override

View File

@@ -34,45 +34,39 @@ public final class Locales {
private Locales() {
}
private static Locale getDefaultLocale() {
String language = System.getenv("HMCL_LANGUAGE");
if (StringUtils.isNotBlank(language))
return Locale.forLanguageTag(language);
else
return LocaleUtils.SYSTEM_DEFAULT;
}
public static final SupportedLocale DEFAULT = new SupportedLocale("def", getDefaultLocale()) {
@Override
public boolean isDefault() {
return true;
}
};
public static final SupportedLocale DEFAULT;
static {
String language = System.getenv("HMCL_LANGUAGE");
DEFAULT = new SupportedLocale(true, "def",
StringUtils.isBlank(language) ? LocaleUtils.SYSTEM_DEFAULT : Locale.forLanguageTag(language));
}
/**
* English
*/
public static final SupportedLocale EN = new SupportedLocale("en", Locale.ENGLISH);
public static final SupportedLocale EN = new SupportedLocale("en");
/**
* Spanish
*/
public static final SupportedLocale ES = new SupportedLocale("es", Locale.forLanguageTag("es"));
public static final SupportedLocale ES = new SupportedLocale("es");
/**
* Russian
*/
public static final SupportedLocale RU = new SupportedLocale("ru", Locale.forLanguageTag("ru"));
public static final SupportedLocale RU = new SupportedLocale("ru");
/**
* Ukrainian
*/
public static final SupportedLocale UK = new SupportedLocale("uk", Locale.forLanguageTag("uk"));
public static final SupportedLocale UK = new SupportedLocale("uk");
/**
* Japanese
*/
public static final SupportedLocale JA = new SupportedLocale("ja", Locale.JAPANESE);
public static final SupportedLocale JA = new SupportedLocale("ja");
/**
* Chinese (Simplified)
@@ -87,7 +81,7 @@ public final class Locales {
/**
* Wenyan (Classical Chinese)
*/
public static final SupportedLocale WENYAN = new SupportedLocale("lzh", Locale.forLanguageTag("lzh"));
public static final SupportedLocale WENYAN = new SupportedLocale("lzh");
public static final List<SupportedLocale> LOCALES = List.of(DEFAULT, EN, ES, JA, RU, UK, ZH_HANS, ZH_HANT, WENYAN);
@@ -103,20 +97,30 @@ public final class Locales {
}
@JsonAdapter(SupportedLocale.TypeAdapter.class)
public static class SupportedLocale {
public static final class SupportedLocale {
private final boolean isDefault;
private final String name;
private final Locale locale;
private ResourceBundle resourceBundle;
private DateTimeFormatter dateTimeFormatter;
private List<Locale> candidateLocales;
SupportedLocale(String name, Locale locale) {
SupportedLocale(boolean isDefault, String name, Locale locale) {
this.isDefault = isDefault;
this.name = name;
this.locale = locale;
}
SupportedLocale(String name) {
this(false, name, Locale.forLanguageTag(name));
}
SupportedLocale(String name, Locale locale) {
this(false, name, locale);
}
public boolean isDefault() {
return false;
return isDefault;
}
public String getName() {
@@ -128,9 +132,6 @@ public final class Locales {
}
public String getDisplayName(SupportedLocale inLocale) {
if (inLocale.locale.getLanguage().equals("lzh"))
inLocale = ZH_HANT;
if (isDefault()) {
try {
return inLocale.getResourceBundle().getString("lang.default");
@@ -140,17 +141,32 @@ public final class Locales {
}
}
Locale inJavaLocale = inLocale.getLocale();
if (LocaleUtils.isISO3Language(inJavaLocale.getLanguage())) {
String iso1 = LocaleUtils.getISO1Language(inJavaLocale);
if (LocaleUtils.isISO1Language(iso1)) {
Locale.Builder builder = new Locale.Builder()
.setLocale(inJavaLocale)
.setLanguage(iso1);
if (inJavaLocale.getScript().isEmpty())
builder.setScript(LocaleUtils.getScript(inJavaLocale));
inJavaLocale = builder.build();
}
}
if (this.locale.getLanguage().equals("lzh")) {
if (LocaleUtils.isChinese(inLocale.locale))
if (inJavaLocale.getLanguage().equals("zh"))
return "文言";
String name = locale.getDisplayName(inLocale.getLocale());
String name = locale.getDisplayName(inJavaLocale);
return name.equals("lzh") || name.equals("Literary Chinese")
? "Chinese (Classical)"
: name;
}
return locale.getDisplayName(inLocale.getLocale());
return locale.getDisplayName(inJavaLocale);
}
public ResourceBundle getResourceBundle() {
@@ -237,8 +253,8 @@ public final class Locales {
}
public boolean isSameLanguage(SupportedLocale other) {
return (this.getLocale().getLanguage().equals(other.getLocale().getLanguage()))
|| (LocaleUtils.isChinese(this.getLocale()) && LocaleUtils.isChinese(other.getLocale()));
return LocaleUtils.getISO1Language(this.getLocale())
.equals(LocaleUtils.getISO1Language(other.getLocale()));
}
public static final class TypeAdapter extends com.google.gson.TypeAdapter<SupportedLocale> {