mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-24 09:29:33 +00:00
refactor translation
This commit is contained in:
@@ -54,7 +54,6 @@ command.search_usage.not_found: "<red>No usage found for this item</red>"
|
||||
command.search_recipe.no_item: "<red>Please hold an item before running this command</red>"
|
||||
command.search_usage.no_item: "<red>Please hold an item before running this command</red>"
|
||||
command.totem.not_totem: "<red>'<arg:0>' is not type of totem_of_undying</red>"
|
||||
|
||||
warning.config.image.lack_height: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is missing the required 'height' argument.</yellow>"
|
||||
warning.config.image.height_smaller_than_ascent: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' violates the bitmap image rule: 'height' should be no lower than 'ascent'.</yellow>"
|
||||
warning.config.image.no_file: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is missing the required 'file' argument.</yellow>"
|
||||
@@ -64,4 +63,5 @@ warning.config.image.lack_char: "<yellow>Issue found in file <arg:0> - The image
|
||||
warning.config.image.codepoint_in_use: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is using a character[<arg:3>(<arg:4>)] in font <arg:2> that has been used by another image '<arg:5>'.</yellow>"
|
||||
warning.config.image.invalid_codepoint_grid: "<yellow>Issue found in file <arg:0> - Image '<arg:1>' has an invalid 'chars' codepoint grind.</yellow>"
|
||||
warning.config.image.file_not_exist: "<yellow>Issue found in file <arg:0> - PNG file <arg:2> not found for image '<arg:1>'.</yellow>"
|
||||
warning.config.recipe.duplicated: "<yellow>Issue found in file <arg:0> - Duplicated recipe '<arg:1>'.</yellow>"
|
||||
warning.config.recipe.duplicated: "<yellow>Issue found in file <arg:0> - Duplicated recipe '<arg:1>'.</yellow>"
|
||||
warning.config.i18n.unknown_locale: "<yellow>Issue found in file <arg:0> - Unknown locale '<arg:1>'.</yellow>"
|
||||
@@ -603,7 +603,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
private void generateClientLang(Path generatedPackPath) {
|
||||
for (Map.Entry<String, I18NData> entry : this.plugin.translationManager().clientLangManager().langData().entrySet()) {
|
||||
for (Map.Entry<String, I18NData> entry : this.plugin.translationManager().clientLangData().entrySet()) {
|
||||
JsonObject json = new JsonObject();
|
||||
for (Map.Entry<String, String> pair : entry.getValue().translations.entrySet()) {
|
||||
json.addProperty(pair.getKey(), pair.getValue());
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ObfC {
|
||||
}
|
||||
|
||||
private static String normalizeCharset(String input) {
|
||||
return input.toLowerCase(Locale.ROOT);
|
||||
return input.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
private static String generateDefaultCharset() {
|
||||
|
||||
@@ -201,8 +201,7 @@ public abstract class CraftEngine implements Plugin {
|
||||
// register category parser
|
||||
this.packManager.registerConfigSectionParser(this.itemBrowserManager);
|
||||
// register translation parser
|
||||
this.packManager.registerConfigSectionParser(this.translationManager);
|
||||
this.packManager.registerConfigSectionParser(this.translationManager.clientLangManager());
|
||||
this.packManager.registerConfigSectionParsers(this.translationManager.parsers());
|
||||
// register sound parser
|
||||
this.packManager.registerConfigSectionParser(this.soundManager);
|
||||
this.packManager.registerConfigSectionParser(this.soundManager.jukeboxSongManager());
|
||||
|
||||
@@ -55,7 +55,7 @@ public class Dependency {
|
||||
}
|
||||
|
||||
public String fileName(String classifier) {
|
||||
String name = customArtifactID.toLowerCase(Locale.ROOT).replace('_', '-');
|
||||
String name = customArtifactID.toLowerCase(Locale.ENGLISH).replace('_', '-');
|
||||
String extra = classifier == null || classifier.isEmpty()
|
||||
? ""
|
||||
: "-" + classifier;
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package net.momirealms.craftengine.core.plugin.locale;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.plugin.Reloadable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface ClientLangManager extends Reloadable, ConfigSectionParser {
|
||||
Set<String> ALL_LANG = Set.of(
|
||||
"af_za", "ar_sa", "ast_es", "az_az", "ba_ru", "bar", "be_by", "be_latn",
|
||||
"bg_bg", "br_fr", "brb", "bs_ba", "ca_es", "cs_cz", "cy_gb", "da_dk",
|
||||
"de_at", "de_ch", "de_de", "el_gr", "en_au", "en_ca", "en_gb", "en_nz",
|
||||
"en_pt", "en_ud", "en_us", "enp", "enws", "eo_uy", "es_ar", "es_cl",
|
||||
"es_ec", "es_es", "es_mx", "es_uy", "es_ve", "esan", "et_ee", "eu_es",
|
||||
"fa_ir", "fi_fi", "fil_ph", "fo_fo", "fr_ca", "fr_fr", "fra_de", "fur_it",
|
||||
"fy_nl", "ga_ie", "gd_gb", "gl_es", "haw_us", "he_il", "hi_in", "hn_no",
|
||||
"hr_hr", "hu_hu", "hy_am", "id_id", "ig_ng", "io_en", "is_is", "isv",
|
||||
"it_it", "ja_jp", "jbo_en", "ka_ge", "kk_kz", "kn_in", "ko_kr", "ksh",
|
||||
"kw_gb", "ky_kg", "la_la", "lb_lu", "li_li", "lmo", "lo_la", "lol_us", "lt_lt",
|
||||
"lv_lv", "lzh", "mk_mk", "mn_mn", "ms_my", "mt_mt", "nah", "nds_de",
|
||||
"nl_be", "nl_nl", "nn_no", "no_no", "oc_fr", "ovd", "pl_pl", "pls",
|
||||
"pt_br", "pt_pt", "qya_aa", "ro_ro", "rpr", "ru_ru", "ry_ua", "sah_sah",
|
||||
"se_no", "sk_sk", "sl_si", "so_so", "sq_al", "sr_cs", "sr_sp", "sv_se",
|
||||
"sxu", "szl", "ta_in", "th_th", "tl_ph", "tlh_aa", "tok", "tr_tr",
|
||||
"tt_ru", "tzo_mx", "uk_ua", "val_es", "vec_it", "vi_vn", "vp_vl", "yi_de",
|
||||
"yo_ng", "zh_cn", "zh_hk", "zh_tw", "zlm_arab"
|
||||
);
|
||||
|
||||
Map<String, List<String>> LOCALE_2_COUNTRIES = ALL_LANG.stream()
|
||||
.map(lang -> lang.split("_"))
|
||||
.filter(split -> split.length >= 2)
|
||||
.collect(Collectors.groupingBy(
|
||||
split -> split[0],
|
||||
Collectors.mapping(split -> split[1], Collectors.toUnmodifiableList())
|
||||
));
|
||||
|
||||
String[] CONFIG_SECTION_NAME = new String[] {"lang", "language", "languages"};
|
||||
|
||||
Map<String, I18NData> langData();
|
||||
|
||||
@Override
|
||||
default int loadingSequence() {
|
||||
return LoadingSequence.LANG;
|
||||
}
|
||||
|
||||
@Override
|
||||
default String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
void addTranslation(String langId, Map<String, String> translations);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package net.momirealms.craftengine.core.plugin.locale;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ClientLangMangerImpl implements ClientLangManager {
|
||||
private final Map<String, I18NData> i18nData = new HashMap<>();
|
||||
|
||||
protected ClientLangMangerImpl() {}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
this.i18nData.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) {
|
||||
String langId = id.value().toLowerCase(Locale.ROOT);
|
||||
|
||||
Map<String, String> sectionData = section.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> String.valueOf(entry.getValue())
|
||||
));
|
||||
|
||||
addTranslation(langId, sectionData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, I18NData> langData() {
|
||||
return Collections.unmodifiableMap(this.i18nData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTranslation(String langId, Map<String, String> translations) {
|
||||
if ("all".equals(langId)) {
|
||||
ALL_LANG.forEach(lang -> this.i18nData.computeIfAbsent(lang, k -> new I18NData())
|
||||
.addTranslations(translations));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ALL_LANG.contains(langId)) {
|
||||
this.i18nData.computeIfAbsent(langId, k -> new I18NData())
|
||||
.addTranslations(translations);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> langCountries = LOCALE_2_COUNTRIES.getOrDefault(langId, Collections.emptyList());
|
||||
for (String lang : langCountries) {
|
||||
this.i18nData.computeIfAbsent(langId + "_" + lang, k -> new I18NData())
|
||||
.addTranslations(translations);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayedLoad() {
|
||||
this.i18nData.values().forEach(I18NData::processTranslations);
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,45 @@ import net.momirealms.craftengine.core.plugin.Reloadable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface TranslationManager extends Reloadable, ConfigSectionParser {
|
||||
String[] CONFIG_SECTION_NAME = new String[] {"i18n", "internationalization", "translation", "translations"};
|
||||
public interface TranslationManager extends Reloadable {
|
||||
Set<String> ALL_LANG = Set.of(
|
||||
"af_za", "ar_sa", "ast_es", "az_az", "ba_ru", "bar", "be_by", "be_latn",
|
||||
"bg_bg", "br_fr", "brb", "bs_ba", "ca_es", "cs_cz", "cy_gb", "da_dk",
|
||||
"de_at", "de_ch", "de_de", "el_gr", "en_au", "en_ca", "en_gb", "en_nz",
|
||||
"en_pt", "en_ud", "en_us", "enp", "enws", "eo_uy", "es_ar", "es_cl",
|
||||
"es_ec", "es_es", "es_mx", "es_uy", "es_ve", "esan", "et_ee", "eu_es",
|
||||
"fa_ir", "fi_fi", "fil_ph", "fo_fo", "fr_ca", "fr_fr", "fra_de", "fur_it",
|
||||
"fy_nl", "ga_ie", "gd_gb", "gl_es", "haw_us", "he_il", "hi_in", "hn_no",
|
||||
"hr_hr", "hu_hu", "hy_am", "id_id", "ig_ng", "io_en", "is_is", "isv",
|
||||
"it_it", "ja_jp", "jbo_en", "ka_ge", "kk_kz", "kn_in", "ko_kr", "ksh",
|
||||
"kw_gb", "ky_kg", "la_la", "lb_lu", "li_li", "lmo", "lo_la", "lol_us", "lt_lt",
|
||||
"lv_lv", "lzh", "mk_mk", "mn_mn", "ms_my", "mt_mt", "nah", "nds_de",
|
||||
"nl_be", "nl_nl", "nn_no", "no_no", "oc_fr", "ovd", "pl_pl", "pls",
|
||||
"pt_br", "pt_pt", "qya_aa", "ro_ro", "rpr", "ru_ru", "ry_ua", "sah_sah",
|
||||
"se_no", "sk_sk", "sl_si", "so_so", "sq_al", "sr_cs", "sr_sp", "sv_se",
|
||||
"sxu", "szl", "ta_in", "th_th", "tl_ph", "tlh_aa", "tok", "tr_tr",
|
||||
"tt_ru", "tzo_mx", "uk_ua", "val_es", "vec_it", "vi_vn", "vp_vl", "yi_de",
|
||||
"yo_ng", "zh_cn", "zh_hk", "zh_tw", "zlm_arab"
|
||||
);
|
||||
Map<String, List<String>> LOCALE_2_COUNTRIES = ALL_LANG.stream()
|
||||
.map(lang -> lang.split("_"))
|
||||
.filter(split -> split.length >= 2)
|
||||
.collect(Collectors.groupingBy(
|
||||
split -> split[0],
|
||||
Collectors.mapping(split -> split[1], Collectors.toUnmodifiableList())
|
||||
));
|
||||
|
||||
static TranslationManager instance() {
|
||||
return TranslationManagerImpl.instance;
|
||||
}
|
||||
|
||||
ClientLangManager clientLangManager();
|
||||
ConfigSectionParser[] parsers();
|
||||
|
||||
default String miniMessageTranslation(String key) {
|
||||
return miniMessageTranslation(key, null);
|
||||
@@ -36,15 +65,9 @@ public interface TranslationManager extends Reloadable, ConfigSectionParser {
|
||||
return locale == null || locale.isEmpty() ? null : Translator.parseLocale(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
default int loadingSequence() {
|
||||
return LoadingSequence.TRANSLATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
default String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
void log(String id, String... args);
|
||||
|
||||
Map<String, I18NData> clientLangData();
|
||||
|
||||
void addClientTranslation(String langId, Map<String, String> translations);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ package net.momirealms.craftengine.core.plugin.locale;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.Plugin;
|
||||
import net.momirealms.craftengine.core.plugin.PluginProperties;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser;
|
||||
import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor;
|
||||
import net.momirealms.craftengine.core.plugin.text.minimessage.IndexedArgumentTag;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
@@ -34,22 +36,24 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
private final Plugin plugin;
|
||||
private final Set<Locale> installed = ConcurrentHashMap.newKeySet();
|
||||
private final Path translationsDirectory;
|
||||
private final ClientLangManager clientLangManager;
|
||||
private final String langVersion;
|
||||
private final String[] supportedLanguages;
|
||||
private final Map<String, Object> translationFallback = new LinkedHashMap<>();
|
||||
private Locale forcedLocale = null;
|
||||
private Locale selectedLocale = DEFAULT_LOCALE;
|
||||
private MiniMessageTranslationRegistry registry;
|
||||
private final Map<String, I18NData> clientLangData = new HashMap<>();
|
||||
private final LangParser langParser;
|
||||
private final I18NParser i18nParser;
|
||||
|
||||
public TranslationManagerImpl(Plugin plugin) {
|
||||
instance = this;
|
||||
this.plugin = plugin;
|
||||
this.translationsDirectory = this.plugin.dataFolderPath().resolve("translations");
|
||||
this.clientLangManager = new ClientLangMangerImpl();
|
||||
this.langVersion = PluginProperties.getValue("lang-version");
|
||||
this.supportedLanguages = PluginProperties.getValue("supported-languages").split(",");
|
||||
instance = this;
|
||||
|
||||
this.langParser = new LangParser();
|
||||
this.i18nParser = new I18NParser();
|
||||
Yaml yaml = new Yaml(new StringKeyConstructor(new LoaderOptions()));
|
||||
try (InputStream is = plugin.resourceStream("translations/en.yml")) {
|
||||
this.translationFallback.putAll(yaml.load(is));
|
||||
@@ -58,6 +62,11 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigSectionParser[] parsers() {
|
||||
return new ConfigSectionParser[] {this.langParser, this.i18nParser};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forcedLocale(Locale locale) {
|
||||
this.forcedLocale = locale;
|
||||
@@ -65,13 +74,13 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
|
||||
@Override
|
||||
public void delayedLoad() {
|
||||
this.clientLangManager.delayedLoad();
|
||||
this.clientLangData.values().forEach(I18NData::processTranslations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
// clear old data
|
||||
this.clientLangManager.reload();
|
||||
this.clientLangData.clear();
|
||||
|
||||
// remove any previous registry
|
||||
if (this.registry != null) {
|
||||
@@ -109,7 +118,7 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.plugin.logger().warn(localLocale.toString().toLowerCase(Locale.ENGLISH) + ".yml not exists, using " + DEFAULT_LOCALE.toString().toLowerCase(Locale.ENGLISH) + ".yml as default locale.");
|
||||
this.plugin.logger().warn("translations/" + localLocale.toString().toLowerCase(Locale.ENGLISH) + ".yml not exists, using " + DEFAULT_LOCALE.toString().toLowerCase(Locale.ENGLISH) + ".yml as default locale.");
|
||||
this.selectedLocale = DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
@@ -214,28 +223,6 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
return Pair.of(locale, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, net.momirealms.craftengine.core.util.Key id, Map<String, Object> section) {
|
||||
Locale locale = TranslationManager.parseLocale(id.value());
|
||||
if (locale == null) {
|
||||
throw new IllegalStateException("Unknown locale '" + id.value() + "' - unable to register.");
|
||||
}
|
||||
|
||||
Map<String, String> bundle = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : section.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
bundle.put(key, entry.getValue().toString());
|
||||
}
|
||||
|
||||
this.registry.registerAll(locale, bundle);
|
||||
this.installed.add(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientLangManager clientLangManager() {
|
||||
return clientLangManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String id, String... args) {
|
||||
String translation = miniMessageTranslation(id);
|
||||
@@ -263,4 +250,87 @@ public class TranslationManagerImpl implements TranslationManager {
|
||||
return newFileContents;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, I18NData> clientLangData() {
|
||||
return Collections.unmodifiableMap(this.clientLangData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClientTranslation(String langId, Map<String, String> translations) {
|
||||
if ("all".equals(langId)) {
|
||||
ALL_LANG.forEach(lang -> this.clientLangData.computeIfAbsent(lang, k -> new I18NData())
|
||||
.addTranslations(translations));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ALL_LANG.contains(langId)) {
|
||||
this.clientLangData.computeIfAbsent(langId, k -> new I18NData())
|
||||
.addTranslations(translations);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> langCountries = LOCALE_2_COUNTRIES.getOrDefault(langId, Collections.emptyList());
|
||||
for (String lang : langCountries) {
|
||||
this.clientLangData.computeIfAbsent(langId + "_" + lang, k -> new I18NData())
|
||||
.addTranslations(translations);
|
||||
}
|
||||
}
|
||||
|
||||
public class I18NParser implements ConfigSectionParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"i18n", "internationalization", "translation", "translations"};
|
||||
|
||||
@Override
|
||||
public int loadingSequence() {
|
||||
return LoadingSequence.TRANSLATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, net.momirealms.craftengine.core.util.Key id, Map<String, Object> section) {
|
||||
Locale locale = TranslationManager.parseLocale(id.value());
|
||||
if (locale == null) {
|
||||
log("warning.config.i18n.unknown_locale", path.toString(), id.value());
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> bundle = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : section.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
bundle.put(key, entry.getValue().toString());
|
||||
}
|
||||
|
||||
TranslationManagerImpl.this.registry.registerAll(locale, bundle);
|
||||
TranslationManagerImpl.this.installed.add(locale);
|
||||
}
|
||||
}
|
||||
|
||||
public class LangParser implements ConfigSectionParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"lang", "language", "languages"};
|
||||
|
||||
@Override
|
||||
public int loadingSequence() {
|
||||
return LoadingSequence.LANG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, net.momirealms.craftengine.core.util.Key id, Map<String, Object> section) {
|
||||
String langId = id.value().toLowerCase(Locale.ENGLISH);
|
||||
Map<String, String> sectionData = section.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> String.valueOf(entry.getValue())
|
||||
));
|
||||
TranslationManagerImpl.this.addClientTranslation(langId, sectionData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user