mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-24 03:33:46 -04:00
update
This commit is contained in:
parent
b68d8a4be0
commit
7ed3462e92
@ -65,7 +65,7 @@ public final class SettingsPage extends SettingsView {
|
|||||||
FXUtils.smoothScrolling(scroll);
|
FXUtils.smoothScrolling(scroll);
|
||||||
|
|
||||||
// ==== Languages ====
|
// ==== Languages ====
|
||||||
cboLanguage.getItems().setAll(Locales.LOCALES);
|
cboLanguage.getItems().setAll(Locales.getSupportedLocales());
|
||||||
selectedItemPropertyFor(cboLanguage).bindBidirectional(config().localizationProperty());
|
selectedItemPropertyFor(cboLanguage).bindBidirectional(config().localizationProperty());
|
||||||
|
|
||||||
disableAutoGameOptionsPane.selectedProperty().bindBidirectional(config().disableAutoGameOptionsProperty());
|
disableAutoGameOptionsPane.selectedProperty().bindBidirectional(config().disableAutoGameOptionsProperty());
|
||||||
|
@ -19,14 +19,19 @@ package org.jackhuang.hmcl.util.i18n;
|
|||||||
|
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
@ -34,71 +39,31 @@ public final class Locales {
|
|||||||
private Locales() {
|
private Locales() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final SupportedLocale DEFAULT = new SupportedLocale();
|
||||||
|
|
||||||
public static final SupportedLocale DEFAULT;
|
public static List<SupportedLocale> getSupportedLocales() {
|
||||||
|
InputStream locales = Locales.class.getResourceAsStream("/assets/lang/locales.json");
|
||||||
static {
|
if (locales != null) {
|
||||||
String language = System.getenv("HMCL_LANGUAGE");
|
try (locales) {
|
||||||
DEFAULT = new SupportedLocale(true, "def",
|
return JsonUtils.fromNonNullJsonFully(locales, JsonUtils.listTypeOf(SupportedLocale.class));
|
||||||
StringUtils.isBlank(language) ? LocaleUtils.SYSTEM_DEFAULT : Locale.forLanguageTag(language));
|
} catch (Throwable e) {
|
||||||
|
LOG.warning("Failed to load locales.json", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return List.of(DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static final ConcurrentMap<Locale, SupportedLocale> LOCALES = new ConcurrentHashMap<>();
|
||||||
* English
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale EN = new SupportedLocale("en");
|
|
||||||
|
|
||||||
/**
|
public static SupportedLocale getLocale(Locale locale) {
|
||||||
* ɥsᴉꞁᵷuƎ (uʍoᗡ ǝpᴉsd∩)
|
return LOCALES.computeIfAbsent(locale, SupportedLocale::new);
|
||||||
*/
|
}
|
||||||
public static final SupportedLocale EN_QABS = new SupportedLocale("en-Qabs");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spanish
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale ES = new SupportedLocale("es");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Russian
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale RU = new SupportedLocale("ru");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ukrainian
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale UK = new SupportedLocale("uk");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Japanese
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale JA = new SupportedLocale("ja");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chinese (Simplified)
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale ZH_HANS = new SupportedLocale("zh_CN", LocaleUtils.LOCALE_ZH_HANS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chinese (Traditional)
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale ZH_HANT = new SupportedLocale("zh", LocaleUtils.LOCALE_ZH_HANT);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wenyan (Classical Chinese)
|
|
||||||
*/
|
|
||||||
public static final SupportedLocale WENYAN = new SupportedLocale("lzh");
|
|
||||||
|
|
||||||
public static final List<SupportedLocale> LOCALES = List.of(DEFAULT, EN, EN_QABS, ES, JA, RU, UK, ZH_HANS, ZH_HANT, WENYAN);
|
|
||||||
|
|
||||||
public static SupportedLocale getLocaleByName(String name) {
|
public static SupportedLocale getLocaleByName(String name) {
|
||||||
if (name == null) return DEFAULT;
|
if (name == null || "def".equals(name) || "default".equals(name))
|
||||||
|
return DEFAULT;
|
||||||
|
|
||||||
for (SupportedLocale locale : LOCALES) {
|
return getLocale(Locale.forLanguageTag(name));
|
||||||
if (locale.getName().equalsIgnoreCase(name))
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonAdapter(SupportedLocale.TypeAdapter.class)
|
@JsonAdapter(SupportedLocale.TypeAdapter.class)
|
||||||
@ -107,23 +72,26 @@ public final class Locales {
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final Locale locale;
|
private final Locale locale;
|
||||||
private ResourceBundle resourceBundle;
|
private ResourceBundle resourceBundle;
|
||||||
|
private ResourceBundle localeNamesBundle;
|
||||||
private DateTimeFormatter dateTimeFormatter;
|
private DateTimeFormatter dateTimeFormatter;
|
||||||
private List<Locale> candidateLocales;
|
private List<Locale> candidateLocales;
|
||||||
|
|
||||||
SupportedLocale(boolean isDefault, String name, Locale locale) {
|
SupportedLocale() {
|
||||||
this.isDefault = isDefault;
|
this.isDefault = true;
|
||||||
this.name = name;
|
this.name = "def"; // TODO: Change to "default" after updating the Config format
|
||||||
|
|
||||||
|
String language = System.getenv("HMCL_LANGUAGE");
|
||||||
|
this.locale = StringUtils.isBlank(language)
|
||||||
|
? LocaleUtils.SYSTEM_DEFAULT
|
||||||
|
: Locale.forLanguageTag(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportedLocale(Locale locale) {
|
||||||
|
this.isDefault = false;
|
||||||
|
this.name = locale.toLanguageTag();
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
SupportedLocale(String name) {
|
|
||||||
this(false, name, Locale.forLanguageTag(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
SupportedLocale(String name, Locale locale) {
|
|
||||||
this(false, name, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefault() {
|
public boolean isDefault() {
|
||||||
return isDefault;
|
return isDefault;
|
||||||
}
|
}
|
||||||
@ -279,7 +247,16 @@ public final class Locales {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SupportedLocale read(JsonReader in) throws IOException {
|
public SupportedLocale read(JsonReader in) throws IOException {
|
||||||
return getLocaleByName(in.nextString());
|
if (in.peek() == JsonToken.NULL)
|
||||||
|
return DEFAULT;
|
||||||
|
|
||||||
|
String language = in.nextString();
|
||||||
|
return getLocaleByName(switch (language) {
|
||||||
|
// TODO: Remove these compatibility codes after updating the Config format
|
||||||
|
case "zh_CN" -> "zh-Hans"; // For compatibility
|
||||||
|
case "zh" -> "zh-Hant"; // For compatibility
|
||||||
|
default -> language;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public final class MinecraftWiki {
|
|||||||
translatedVersion = WenyanUtils.translateGameVersion(gameVersion);
|
translatedVersion = WenyanUtils.translateGameVersion(gameVersion);
|
||||||
|
|
||||||
if (translatedVersion.equals(gameVersion.toString()) || gameVersion instanceof GameVersionNumber.Old) {
|
if (translatedVersion.equals(gameVersion.toString()) || gameVersion instanceof GameVersionNumber.Old) {
|
||||||
return getWikiLink(Locales.ZH_HANT, version);
|
return getWikiLink(Locales.getLocale(LocaleUtils.LOCALE_ZH_HANT), version);
|
||||||
} else if (SNAPSHOT_PATTERN.matcher(wikiVersion).matches()) {
|
} else if (SNAPSHOT_PATTERN.matcher(wikiVersion).matches()) {
|
||||||
return locale.i18n("wiki.version.game.snapshot", translatedVersion);
|
return locale.i18n("wiki.version.game.snapshot", translatedVersion);
|
||||||
} else {
|
} else {
|
||||||
|
12
HMCL/src/main/resources/assets/lang/locales.json
Normal file
12
HMCL/src/main/resources/assets/lang/locales.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
"default",
|
||||||
|
"en",
|
||||||
|
"en-Qabs",
|
||||||
|
"es",
|
||||||
|
"ru",
|
||||||
|
"uk",
|
||||||
|
"ja",
|
||||||
|
"zh-Hans",
|
||||||
|
"zh-Hant",
|
||||||
|
"lzh"
|
||||||
|
]
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.gradle.l10n;
|
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.file.DirectoryProperty;
|
||||||
|
import org.gradle.api.tasks.OutputDirectory;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
|
||||||
|
public abstract class CreateLocaleNames extends DefaultTask {
|
||||||
|
|
||||||
|
@OutputDirectory
|
||||||
|
public abstract DirectoryProperty getOutputDirectory();
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
public void run() throws IOException {
|
||||||
|
Path outputDir = getOutputDirectory().get().getAsFile().toPath();
|
||||||
|
|
||||||
|
if (Files.isDirectory(outputDir)) {
|
||||||
|
Files.walkFileTree(outputDir, new SimpleFileVisitor<>() {
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult visitFile(@NotNull Path file, @NotNull BasicFileAttributes attrs) throws IOException {
|
||||||
|
Files.deleteIfExists(file);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull FileVisitResult postVisitDirectory(@NotNull Path dir, @Nullable IOException exc) throws IOException {
|
||||||
|
if (!dir.equals(outputDir))
|
||||||
|
Files.deleteIfExists(dir);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Files.deleteIfExists(outputDir);
|
||||||
|
Files.createDirectories(outputDir);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user