diff --git a/landlords-client/src/main/java/org/nico/ratel/landlords/client/SimpleClient.java b/landlords-client/src/main/java/org/nico/ratel/landlords/client/SimpleClient.java index 160db57..32e525a 100644 --- a/landlords-client/src/main/java/org/nico/ratel/landlords/client/SimpleClient.java +++ b/landlords-client/src/main/java/org/nico/ratel/landlords/client/SimpleClient.java @@ -4,14 +4,17 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.List; +import java.util.Locale; import java.util.Objects; import org.nico.noson.Noson; import org.nico.noson.entity.NoType; +import org.nico.noson.util.string.StringUtils; import org.nico.ratel.landlords.client.entity.User; import org.nico.ratel.landlords.client.proxy.ProtobufProxy; import org.nico.ratel.landlords.client.proxy.WebsocketProxy; import org.nico.ratel.landlords.features.Features; +import org.nico.ratel.landlords.helper.I18nHelper; import org.nico.ratel.landlords.print.SimplePrinter; import org.nico.ratel.landlords.print.SimpleWriter; import org.nico.ratel.landlords.utils.StreamUtils; @@ -28,6 +31,8 @@ public class SimpleClient { public static String protocol = "pb"; + public static String language; + private final static String[] serverAddressSource = new String[]{ "https://raw.githubusercontent.com/ainilili/ratel/master/serverlist.json", //Source "https://cdn.jsdelivr.net/gh/ainilili/ratel@master/serverlist.json", //CN CDN @@ -50,23 +55,34 @@ public static void main(String[] args) throws InterruptedException, IOException, if (args[index].equalsIgnoreCase("-ptl") || args[index].equalsIgnoreCase("-protocol")) { protocol = args[index + 1]; } + if (args[index].equalsIgnoreCase("-lang") || args[index].equalsIgnoreCase("-language")) { + language = args[index + 1]; + } } } } + + if (StringUtils.isBlank(language)) { + I18nHelper.enable(); + } else { + Locale locale = getLocale(language); + I18nHelper.enable(locale); + } + if (serverAddress == null) { List serverAddressList = getServerAddressList(); if (serverAddressList == null || serverAddressList.size() == 0) { throw new RuntimeException("Please use '-host' to setting server address."); } - SimplePrinter.printNotice("Please select a server:"); + SimplePrinter.printTranslate("pls_select_srv"); for (int i = 0; i < serverAddressList.size(); i++) { SimplePrinter.printNotice((i + 1) + ". " + serverAddressList.get(i)); } int serverPick = Integer.parseInt(SimpleWriter.write(User.INSTANCE.getNickname(), "option")); while (serverPick < 1 || serverPick > serverAddressList.size()) { try { - SimplePrinter.printNotice("The server address does not exist!"); + SimplePrinter.printTranslate("srv_addr_not_exist"); serverPick = Integer.parseInt(SimpleWriter.write(User.INSTANCE.getNickname(), "option")); } catch (NumberFormatException ignore) {} } @@ -91,10 +107,23 @@ private static List getServerAddressList() { String serverInfo = StreamUtils.convertToString(new URL(serverAddressSource)); return Noson.convert(serverInfo, new NoType>() {}); } catch (IOException e) { - SimplePrinter.printNotice("Try connected " + serverAddressSource + " failed: " + e.getMessage()); + SimplePrinter.printTranslate("try_connect_%s_failed_%s", serverAddressSource, e.getMessage()); } } return null; } + private static Locale getLocale(String langCode) { + switch (langCode) { + case "zh": + case "zh_CN": + return Locale.SIMPLIFIED_CHINESE; + case "en": + case "en_US": + return Locale.US; + default: + System.out.println("[warning] not supported language code: " + langCode + ", set to en_US"); + return Locale.US; + } + } } diff --git a/landlords-common/src/main/java/org/nico/ratel/landlords/helper/I18nHelper.java b/landlords-common/src/main/java/org/nico/ratel/landlords/helper/I18nHelper.java new file mode 100644 index 0000000..eb1418e --- /dev/null +++ b/landlords-common/src/main/java/org/nico/ratel/landlords/helper/I18nHelper.java @@ -0,0 +1,104 @@ +package org.nico.ratel.landlords.helper; + +import java.nio.charset.StandardCharsets; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + + +public class I18nHelper { + + private I18nHelper() { + } + + private static final String I18N_BUNDLE_NAME = "messages"; + + private static ResourceBundle messageBundle; + + private static volatile boolean enabled = false; + + /** + * 启用并加载国际化信息,语言地区使用系统默认 + */ + public static void enable() { + enable(Locale.getDefault()); + } + + /** + * 启用并加载国际化,指定语言地区 + * + * @param locale 语言地区 + */ + public static void enable(Locale locale) { + if (enabled) { + System.err.println("[warning] i18n resource has already loaded."); + return; + } + try { + messageBundle = ResourceBundle.getBundle(I18N_BUNDLE_NAME, locale); + if (locale != messageBundle.getLocale()) { + System.err.printf("[warning] missing i18n resource for %s, set locale to %s\n", + locale, messageBundle.getLocale()); + } + } catch (Exception e) { + System.err.println("[error] load i18n resource error, exception: " + e.getMessage()); + throw e; + } + I18nHelper.enabled = true; + } + + /** + * 更新并重新加载国际化资源 + * + * @param locale 语言地区 + */ + public static void refresh(Locale locale) { + if (!enabled) { + throw new IllegalStateException("i18n not enabled!"); + } + ResourceBundle bundle; + try { + bundle = ResourceBundle.getBundle(I18N_BUNDLE_NAME, locale); + if (locale != bundle.getLocale()) { + throw new IllegalStateException("i18n resource of " + locale + " not found"); + } + } catch (Exception e) { + if (e instanceof IllegalArgumentException) { + throw e; + } + throw new RuntimeException("load i18n resource of " + locale + "failed, exception: " + e.getMessage()); + } + messageBundle = bundle; + } + + /** + * 翻译文本 + *

支持格式化,格式化方式采用String.format(format, Object...args)

+ *

不在字典内的key将原样显示

+ * + * @param key 待翻译语言key + * @param args 参数 + */ + public static String translate(String key, Object... args) { + if (!enabled) { + return format(key, args); + } + try { + String t = messageBundle.getString(key); + return format(new String(t.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8), args); + } catch (MissingResourceException e) { + return format(key, args); + } + } + + /** + * 获取当前地区语言 + */ + public static Locale getCurrentLocale() { + return messageBundle == null ? null : messageBundle.getLocale(); + } + + private static String format(String template, Object... args) { + return String.format(template, args); + } +} diff --git a/landlords-common/src/main/java/org/nico/ratel/landlords/print/SimplePrinter.java b/landlords-common/src/main/java/org/nico/ratel/landlords/print/SimplePrinter.java index 5127458..3170f0b 100644 --- a/landlords-common/src/main/java/org/nico/ratel/landlords/print/SimplePrinter.java +++ b/landlords-common/src/main/java/org/nico/ratel/landlords/print/SimplePrinter.java @@ -7,6 +7,7 @@ import java.util.HashMap; import org.nico.ratel.landlords.entity.Poker; +import org.nico.ratel.landlords.helper.I18nHelper; import org.nico.ratel.landlords.helper.PokerHelper; public class SimplePrinter { @@ -22,6 +23,10 @@ public static void printNotice(String msg) { System.out.println(msg); } + public static void printTranslate(String key, Object... args) { + System.out.println(I18nHelper.translate(key, args)); + } + public static void printNotice(String msgKey, String locale) { //TODO : read locale Map> map = new HashMap<>(); diff --git a/landlords-common/src/main/resources/messages_en_US.properties b/landlords-common/src/main/resources/messages_en_US.properties new file mode 100644 index 0000000..f2f3d2c --- /dev/null +++ b/landlords-common/src/main/resources/messages_en_US.properties @@ -0,0 +1,3 @@ +pls_select_srv=Please select a server: +srv_addr_not_exist=The server address does not exist! +try_connect_%s_failed_%s=Try connected %s failed: %s \ No newline at end of file diff --git a/landlords-common/src/main/resources/messages_zh_CN.properties b/landlords-common/src/main/resources/messages_zh_CN.properties new file mode 100644 index 0000000..0e29766 --- /dev/null +++ b/landlords-common/src/main/resources/messages_zh_CN.properties @@ -0,0 +1,3 @@ +pls_select_srv=请选择一个服务器: +srv_addr_not_exist=服务器地址不存在! +try_connect_%s_failed_%s=尝试连接服务器 %s 失败,原因: %s \ No newline at end of file