mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-22 10:43:57 -04:00
update
This commit is contained in:
parent
8c2b65c876
commit
746729859a
@ -1,4 +1,5 @@
|
|||||||
import org.jackhuang.hmcl.gradle.l10n.CheckTranslations
|
import org.jackhuang.hmcl.gradle.l10n.CheckTranslations
|
||||||
|
import org.jackhuang.hmcl.gradle.l10n.CreateLocaleNames
|
||||||
import org.jackhuang.hmcl.gradle.l10n.UpsideDownTranslate
|
import org.jackhuang.hmcl.gradle.l10n.UpsideDownTranslate
|
||||||
import org.jackhuang.hmcl.gradle.mod.ParseModDataTask
|
import org.jackhuang.hmcl.gradle.mod.ParseModDataTask
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
@ -205,9 +206,16 @@ tasks.shadowJar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val generatedDir = layout.buildDirectory.dir("generated")
|
||||||
|
|
||||||
val upsideDownTranslate by tasks.registering(UpsideDownTranslate::class) {
|
val upsideDownTranslate by tasks.registering(UpsideDownTranslate::class) {
|
||||||
inputFile.set(layout.projectDirectory.file("src/main/resources/assets/lang/I18N.properties"))
|
inputFile.set(layout.projectDirectory.file("src/main/resources/assets/lang/I18N.properties"))
|
||||||
outputFile.set(layout.buildDirectory.file("generated/i18n/I18N_en_Qabs.properties"))
|
outputFile.set(generatedDir.map { it.file("generated/i18n/I18N_en_Qabs.properties") })
|
||||||
|
}
|
||||||
|
|
||||||
|
val createLocaleNames by tasks.registering(CreateLocaleNames::class) {
|
||||||
|
languagesFile.set(layout.projectDirectory.file("src/main/resources/assets/lang/languages.json"))
|
||||||
|
outputDirectory.set(generatedDir.map { it.dir("generated/LocaleNames") })
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.processResources {
|
tasks.processResources {
|
||||||
@ -221,7 +229,9 @@ tasks.processResources {
|
|||||||
|
|
||||||
into("assets/lang") {
|
into("assets/lang") {
|
||||||
from(upsideDownTranslate.map { it.outputFile })
|
from(upsideDownTranslate.map { it.outputFile })
|
||||||
|
from(createLocaleNames.map { it.outputDirectory })
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val makeExecutables by tasks.registering {
|
val makeExecutables by tasks.registering {
|
||||||
|
@ -42,15 +42,18 @@ public final class Locales {
|
|||||||
public static final SupportedLocale DEFAULT = new SupportedLocale();
|
public static final SupportedLocale DEFAULT = new SupportedLocale();
|
||||||
|
|
||||||
public static List<SupportedLocale> getSupportedLocales() {
|
public static List<SupportedLocale> getSupportedLocales() {
|
||||||
|
List<SupportedLocale> list = new ArrayList<>();
|
||||||
|
list.add(DEFAULT);
|
||||||
|
|
||||||
InputStream locales = Locales.class.getResourceAsStream("/assets/lang/languages.json");
|
InputStream locales = Locales.class.getResourceAsStream("/assets/lang/languages.json");
|
||||||
if (locales != null) {
|
if (locales != null) {
|
||||||
try (locales) {
|
try (locales) {
|
||||||
return JsonUtils.fromNonNullJsonFully(locales, JsonUtils.listTypeOf(SupportedLocale.class));
|
list.addAll(JsonUtils.fromNonNullJsonFully(locales, JsonUtils.listTypeOf(SupportedLocale.class)));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOG.warning("Failed to load languages.json", e);
|
LOG.warning("Failed to load languages.json", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return List.of(DEFAULT);
|
return List.copyOf(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ConcurrentMap<Locale, SupportedLocale> LOCALES = new ConcurrentHashMap<>();
|
private static final ConcurrentMap<Locale, SupportedLocale> LOCALES = new ConcurrentHashMap<>();
|
||||||
@ -60,10 +63,10 @@ public final class Locales {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static SupportedLocale getLocaleByName(String name) {
|
public static SupportedLocale getLocaleByName(String name) {
|
||||||
if (name == null || "def".equals(name) || "default".equals(name))
|
if (name == null || name.isEmpty() || "def".equals(name) || "default".equals(name))
|
||||||
return DEFAULT;
|
return DEFAULT;
|
||||||
|
|
||||||
return getLocale(Locale.forLanguageTag(name));
|
return getLocale(Locale.forLanguageTag(name.trim()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonAdapter(SupportedLocale.TypeAdapter.class)
|
@JsonAdapter(SupportedLocale.TypeAdapter.class)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
[
|
[
|
||||||
"default",
|
|
||||||
"en",
|
"en",
|
||||||
"en-Qabs",
|
"en-Qabs",
|
||||||
"es",
|
"es",
|
||||||
|
@ -17,28 +17,51 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.gradle.l10n;
|
package org.jackhuang.hmcl.gradle.l10n;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import org.gradle.api.DefaultTask;
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.GradleException;
|
||||||
import org.gradle.api.file.DirectoryProperty;
|
import org.gradle.api.file.DirectoryProperty;
|
||||||
|
import org.gradle.api.file.RegularFileProperty;
|
||||||
|
import org.gradle.api.tasks.InputFile;
|
||||||
import org.gradle.api.tasks.OutputDirectory;
|
import org.gradle.api.tasks.OutputDirectory;
|
||||||
import org.gradle.api.tasks.TaskAction;
|
import org.gradle.api.tasks.TaskAction;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.SimpleFileVisitor;
|
import java.nio.file.SimpleFileVisitor;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public abstract class CreateLocaleNames extends DefaultTask {
|
public abstract class CreateLocaleNames extends DefaultTask {
|
||||||
|
|
||||||
|
@InputFile
|
||||||
|
public abstract RegularFileProperty getLanguagesFile();
|
||||||
|
|
||||||
@OutputDirectory
|
@OutputDirectory
|
||||||
public abstract DirectoryProperty getOutputDirectory();
|
public abstract DirectoryProperty getOutputDirectory();
|
||||||
|
|
||||||
|
private static String mapToFileName(String base, String ext, Locale locale) {
|
||||||
|
if (locale.getLanguage().isEmpty() || locale.equals(Locale.ENGLISH))
|
||||||
|
return base + "." + ext;
|
||||||
|
else if (locale.toLanguageTag().equals("zh-Hans"))
|
||||||
|
return base + "_zh." + ext;
|
||||||
|
else
|
||||||
|
return base + "_" + locale.toLanguageTag().replace('-', '_') + "." + ext;
|
||||||
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
|
Path languagesFile = getLanguagesFile().get().getAsFile().toPath();
|
||||||
Path outputDir = getOutputDirectory().get().getAsFile().toPath();
|
Path outputDir = getOutputDirectory().get().getAsFile().toPath();
|
||||||
|
|
||||||
if (Files.isDirectory(outputDir)) {
|
if (Files.isDirectory(outputDir)) {
|
||||||
@ -60,6 +83,95 @@ public abstract class CreateLocaleNames extends DefaultTask {
|
|||||||
Files.deleteIfExists(outputDir);
|
Files.deleteIfExists(outputDir);
|
||||||
Files.createDirectories(outputDir);
|
Files.createDirectories(outputDir);
|
||||||
|
|
||||||
|
List<Locale> supportedLanguages;
|
||||||
|
try (var reader = Files.newBufferedReader(languagesFile)) {
|
||||||
|
supportedLanguages = new Gson().fromJson(reader, new TypeToken<List<String>>() {
|
||||||
|
}).stream()
|
||||||
|
.map(Locale::forLanguageTag)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
SortedSet<String> languages = supportedLanguages.stream()
|
||||||
|
.map(Locale::getLanguage)
|
||||||
|
.filter(it -> !it.isBlank())
|
||||||
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
|
|
||||||
|
SortedSet<String> scripts = supportedLanguages.stream()
|
||||||
|
.map(Locale::getScript)
|
||||||
|
.filter(it -> !it.isBlank())
|
||||||
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
|
|
||||||
|
for (Locale currentLanguage : supportedLanguages) {
|
||||||
|
InputStream overrideFile = CreateLocaleNames.class.getResourceAsStream(
|
||||||
|
mapToFileName("LocaleNamesOverride", "properties", currentLanguage));
|
||||||
|
|
||||||
|
Properties overrideProperties = new Properties();
|
||||||
|
if (overrideFile != null) {
|
||||||
|
try (var reader = new InputStreamReader(overrideFile, StandardCharsets.UTF_8)) {
|
||||||
|
overrideProperties.load(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Path targetFile = outputDir.resolve(mapToFileName("LocaleNames", "properties", currentLanguage));
|
||||||
|
if (Files.exists(targetFile))
|
||||||
|
throw new GradleException(String.format("File %s already exists", targetFile));
|
||||||
|
|
||||||
|
try (var writer = Files.newBufferedWriter(targetFile)) {
|
||||||
|
writer.write("""
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
""");
|
||||||
|
|
||||||
|
writer.write("# Languages\n");
|
||||||
|
for (String language : languages) {
|
||||||
|
String displayName = overrideProperties.getProperty(language);
|
||||||
|
if (displayName == null) {
|
||||||
|
displayName = new Locale.Builder()
|
||||||
|
.setLanguage(language)
|
||||||
|
.build()
|
||||||
|
.getDisplayLanguage(currentLanguage);
|
||||||
|
|
||||||
|
if (displayName.equals(language))
|
||||||
|
continue; // Skip
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.write(language + "=" + displayName + "\n");
|
||||||
|
}
|
||||||
|
writer.write('\n');
|
||||||
|
|
||||||
|
writer.write("# Scripts\n");
|
||||||
|
for (String script : scripts) {
|
||||||
|
String displayName = overrideProperties.getProperty(script);
|
||||||
|
if (displayName == null) {
|
||||||
|
displayName = new Locale.Builder()
|
||||||
|
.setScript(script)
|
||||||
|
.build()
|
||||||
|
.getDisplayScript(currentLanguage);
|
||||||
|
|
||||||
|
if (displayName.equals(script))
|
||||||
|
continue; // Skip
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.write(script + "=" + displayName + "\n");
|
||||||
|
}
|
||||||
|
writer.write('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Languages
|
||||||
|
lzh=Classical Chinese
|
||||||
|
|
||||||
|
# Scripts
|
||||||
|
Qabs=Upside down
|
@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Languages
|
||||||
|
lzh=文言
|
||||||
|
|
||||||
|
# Scripts
|
||||||
|
Qabs=颠倒
|
Loading…
x
Reference in New Issue
Block a user