Skip to content

Commit

Permalink
[v3.0] i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
abc123lzf committed Mar 24, 2021
1 parent 6ceb4b6 commit e4e42cc
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 115 deletions.
39 changes: 39 additions & 0 deletions client/src/main/java/com/lzf/flyingsocks/client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;

import javax.swing.JOptionPane;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
Expand All @@ -39,8 +40,11 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Objects;
import java.util.ResourceBundle;

public abstract class Client extends TopLevelComponent
implements Component<VoidComponent>, Environment, ClientOperator {
Expand All @@ -55,6 +59,11 @@ public abstract class Client extends TopLevelComponent
*/
static final String VERSION = "v3.0";


private static final ResourceBundle EXIT_MSG_BUNDLE =
ResourceBundle.getBundle("META-INF/i18n/exitmsg", Locale.getDefault());


/**
* GUI事件处理循环
*/
Expand Down Expand Up @@ -153,4 +162,34 @@ boolean runGUITask() {
return false;
}


public static void exitWithNotify(int status, String message) {
if (Desktop.isDesktopSupported()) {
JOptionPane.showMessageDialog(null, message != null ? message : "", "ERROR", JOptionPane.ERROR_MESSAGE);
}
System.exit(status);
}


public static void exitWithNotify(int status, String string, Object... args) {
if (Desktop.isDesktopSupported()) {
String msg;
if (EXIT_MSG_BUNDLE.containsKey(string)) {
msg = EXIT_MSG_BUNDLE.getString(string);
} else {
msg = string;
}

if (args == null || args.length == 0) {
JOptionPane.showMessageDialog(null, msg,
EXIT_MSG_BUNDLE.getString("exitmsg.title"), JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, MessageFormat.format(msg, args),
EXIT_MSG_BUNDLE.getString("exitmsg.title"), JOptionPane.ERROR_MESSAGE);
}
}

System.exit(status);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static void main(String[] args) {
} catch (ComponentException e) {
log.error("flyingsocks client {} start failure, cause:", VERSION, e);
log.info("submit issue at https://github.com/abc123lzf/flyingsocks");
System.exit(1);
Client.exitWithNotify(1, "exitmsg.client_boot.start_failure", e.getMessage());
}

long ed = System.currentTimeMillis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ public void save() throws Exception {
properties.put("enable-transparent", Boolean.toString(this.enableTransparentProxy));
properties.put("connect-timeout", Integer.toString(this.connectTimeout));

try (FileWriter writer = new FileWriter(path.toFile())) {
Path path = this.path;
try (FileWriter writer = new FileWriter(path.resolve(FILE_NAME).toFile())) {
properties.store(writer, "flyingsocks base configuration");
} catch (IOException e) {
throw new ConfigInitializationException("Can not initialize global config file", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ protected void initInternal() {
p.forEach((k, v) -> setSystemProperties((String) k, (String) v));
} catch (IOException e) {
log.error("Read config.properties occur a exception", e);
System.exit(1);
exitWithNotify(1, "exitmsg.standard_client.config_load_error", e.getMessage());
}

GlobalConfig cfg = new GlobalConfig(getConfigManager());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.lzf.flyingsocks.client.GlobalConfig;
import com.lzf.flyingsocks.client.gui.ResourceManager;
import com.lzf.flyingsocks.client.proxy.http.HttpProxyConfig;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Button;
Expand Down Expand Up @@ -70,21 +71,21 @@ public class HttpProxySettingModule extends AbstractModule<SWTViewComponent> {
throw new Error(e);
}

this.shell = createShell(component.getDisplay(), "HTTP本地代理设置", icon, 600, 280);
this.shell = createShell(component.getDisplay(), "swtui.http.title", icon, 600, 280);
initial();
}

private void initial() {
createLabel(shell, "开关", 20, 5, 80, 30, SWT.CENTER);
createLabel(shell, "代理端口", 20, 40, 80, 30, SWT.CENTER);
createLabel(shell, "认证", 20, 75, 80, 30, SWT.CENTER);
createLabel(shell, "用户名", 20, 110, 80, 30, SWT.CENTER);
createLabel(shell, "密码", 20, 145, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.http.form.label.switch", 20, 5, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.http.form.label.port", 20, 40, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.http.form.label.validate", 20, 75, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.http.form.label.username", 20, 110, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.http.form.label.password", 20, 145, 80, 30, SWT.CENTER);

Composite switchComp = new Composite(shell, SWT.NONE);
switchComp.setBounds(20, 5, 380, 30);
Button openRadio = createRadio(switchComp, "开启", 140, 5, 80, 30);
Button closeRadio = createRadio(switchComp, "关闭", 230, 5, 80, 30);
Button openRadio = createRadio(switchComp, "swtui.http.form.button.switch_open", 140, 5, 80, 30);
Button closeRadio = createRadio(switchComp, "swtui.http.form.button.switch_close", 230, 5, 80, 30);
addButtonSelectionListener(openRadio, e -> {
openRadio.setSelection(true);
closeRadio.setSelection(false);
Expand All @@ -99,8 +100,8 @@ private void initial() {

Composite authComp = new Composite(shell, SWT.NONE);
authComp.setBounds(20, 75, 380, 30);
Button authOpenRadio = createRadio(authComp, "开启", 140, 0, 80, 30);
Button authCloseRadio = createRadio(authComp, "关闭", 230, 0, 80, 30);
Button authOpenRadio = createRadio(authComp, "swtui.http.form.button.validate_open", 140, 0, 80, 30);
Button authCloseRadio = createRadio(authComp, "swtui.http.form.button.validate_close", 230, 0, 80, 30);
addButtonSelectionListener(authCloseRadio, e -> {
authCloseRadio.setSelection(true);
authOpenRadio.setSelection(false);
Expand All @@ -116,23 +117,29 @@ private void initial() {
Text passText = new Text(shell, SWT.BORDER | SWT.PASSWORD);
passText.setBounds(160, 145, 380, 30);

Button enterBtn = createButton(shell, "确认", 140, 180, 150, 35);
Button cancelBtn = createButton(shell, "取消", 330, 180, 150, 35);
Button enterBtn = createButton(shell, "swtui.http.form.button.enter", 140, 180, 150, 35);
Button cancelBtn = createButton(shell, "swtui.http.form.button.cancel", 330, 180, 150, 35);

addButtonSelectionListener(enterBtn, e -> {
boolean open = openRadio.getSelection();
boolean auth = authCloseRadio.getSelection();
boolean auth = authOpenRadio.getSelection();
int port;
try {
port = Integer.parseInt(portText.getText());
} catch (NumberFormatException nfe) {
showMessageBox(shell, "错误", "端口格式错误", SWT.ICON_ERROR | SWT.OK);
showMessageBox(shell, "swtui.http.notice.error.title", "swtui.http.notice.error.port_error", SWT.ICON_ERROR | SWT.OK);
return;
}
String username = userText.getText();
String password = passText.getText();

if (auth && StringUtils.isAnyBlank(username, password)) {
showMessageBox(shell, "swtui.http.notice.error.title", "swtui.http.notice.error.auth_error", SWT.ICON_ERROR | SWT.OK);
return;
}

operator.updateHttpProxyConfig(open, port, auth, username, password);
showMessageBox(shell, "提示", "修改成功", SWT.ICON_INFORMATION | SWT.OK);
showMessageBox(shell, "swtui.http.notice.error.title", "swtui.http.notice.update_success", SWT.ICON_INFORMATION | SWT.OK);
});

if (operator.isHttpProxyOpen()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected void initInternal() {
addModule(this.httpProxySettingModule = new HttpProxySettingModule(this));
} catch (Throwable t) {
log.error("SWT Thread occur a error", t);
System.exit(1);
Client.exitWithNotify(1, "exitmsg.swt_view.init_failure", t.getMessage());
}
}

Expand All @@ -104,7 +104,7 @@ protected void startInternal() {
display.dispose();
} catch (RuntimeException | Error t) {
log.error("An error occur in SWT-UI-Thread", t);
System.exit(1);
Client.exitWithNotify(1, "exitmsg.swt_view.run_error", t.getMessage());
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ final class SocksSettingModule extends AbstractModule<SWTViewComponent> {
}

private void initial() {
createLabel(shell, "验证", 20, 5, 80, 30, SWT.CENTER);
createLabel(shell, "用户名", 20, 40, 80, 30, SWT.CENTER);
createLabel(shell, "密码", 20, 75, 80, 30, SWT.CENTER);
createLabel(shell, "代理端口", 20, 110, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.socks5.form.label.validate", 20, 5, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.socks5.form.label.username", 20, 40, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.socks5.form.label.password", 20, 75, 80, 30, SWT.CENTER);
createLabel(shell, "swtui.socks5.form.label.port", 20, 110, 80, 30, SWT.CENTER);

Button open = createRadio(shell, "打开", 160, 5, 80, 30);
Button off = createRadio(shell, "关闭", 250, 5, 80, 30);
Button open = createRadio(shell, "swtui.socks5.form.button.open", 160, 5, 80, 30);
Button off = createRadio(shell, "swtui.socks5.form.button.close", 250, 5, 80, 30);

Text user = new Text(shell, SWT.BORDER);
user.setBounds(160, 40, 380, 30);
Expand All @@ -88,7 +88,7 @@ private void initial() {
Text port = new Text(shell, SWT.BORDER);
port.setBounds(160, 110, 130, 30);

Button enter = createButton(shell, "确认", 170, 145, 150, 30);
Button enter = createButton(shell, "swtui.socks5.form.button.enter", 170, 145, 150, 30);
addButtonSelectionListener(enter, e -> {
boolean auth = open.getSelection();
String username = user.getText();
Expand All @@ -97,16 +97,18 @@ private void initial() {
if (BaseUtils.isPortString(port.getText())) {
p = Integer.parseInt(port.getText());
} else {
showMessageBox(shell, "提示", "端口不合法", SWT.ICON_ERROR | SWT.OK);
showMessageBox(shell, "swtui.socks5.notice.title", "swtui.socks5.notice.port_error", SWT.ICON_ERROR | SWT.OK);
return;
}

operator.updateSocksProxyAuthentication(p, auth, username, password);
SocksConfig cfg = operator.getSocksConfig();
if (cfg.getPort() != p) {
showMessageBox(shell, "提示", "修改完成, 代理端口的修改需要重启才可生效", SWT.ICON_INFORMATION | SWT.OK);
showMessageBox(shell, "swtui.socks5.notice.title", "swtui.socks5.notice.update_success",
SWT.ICON_INFORMATION | SWT.OK);
} else {
showMessageBox(shell, "提示", "修改完成", SWT.ICON_INFORMATION | SWT.OK);
showMessageBox(shell, "swtui.socks5.notice.title", "swtui.socks5.notice.unchanged",
SWT.ICON_INFORMATION | SWT.OK);
}
});

Expand All @@ -120,7 +122,7 @@ private void initial() {
pass.setEditable(false);
});

Button cancel = createButton(shell, "取消", 360, 145, 150, 30);
Button cancel = createButton(shell, "swtui.socks5.form.button.cancel", 360, 145, 150, 30);
addButtonSelectionListener(cancel, e -> setVisiable(false));

SocksConfig cfg = operator.getSocksConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.lzf.flyingsocks.Config;
import com.lzf.flyingsocks.ConfigInitializationException;
import com.lzf.flyingsocks.ConfigManager;
import com.lzf.flyingsocks.client.Client;
import com.lzf.flyingsocks.client.GlobalConfig;
import com.lzf.flyingsocks.misc.BaseUtils;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -104,7 +105,7 @@ protected void initInternal() throws ConfigInitializationException {
loadGFWListFile(gfwFile);
} catch (IOException e) {
log.error("Read GFWList file occur a exception", e);
System.exit(1);
Client.exitWithNotify(1, "exitmsg.pac.gfw_load_error", e.getMessage());
}

Path cnipv4file = cfg.configPath().resolve(CNIPV4_FILE);
Expand All @@ -116,7 +117,7 @@ protected void initInternal() throws ConfigInitializationException {
loadIPv4CNAddressFile(cnipv4file);
} catch (IOException e) {
log.error("Read CN IPv4 file occur a exception", e);
System.exit(1);
Client.exitWithNotify(1, "exitmsg.pac.ipv4_load_error", e.getMessage());
}

int proxyMode;
Expand Down Expand Up @@ -290,7 +291,7 @@ private void copyGFWListConfig() {
}
} catch (IOException e) {
log.error("Can not find default pac file", e);
System.exit(1);
Client.exitWithNotify(1, "exitmsg.pac.gfw_default_load_error", e.getMessage());
}
}

Expand All @@ -307,7 +308,7 @@ private void copyCNIPv4Config() {
}
} catch (IOException e) {
log.error("Can not find default CN IPv4 file", e);
System.exit(1);
Client.exitWithNotify(1, "exitmsg.pac.ipv4_default_load_error", e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.lzf.flyingsocks.AbstractComponent;
import com.lzf.flyingsocks.ComponentException;
import com.lzf.flyingsocks.Config;
import com.lzf.flyingsocks.client.Client;
import com.lzf.flyingsocks.client.proxy.ProxyComponent;
import com.lzf.flyingsocks.client.proxy.ProxyRequest;
import com.lzf.flyingsocks.misc.BaseUtils;
Expand Down Expand Up @@ -113,6 +114,9 @@ protected void initInternal() {

@Override
protected void startInternal() {
EventLoopGroup eventLoopGroup = this.eventLoopGroup;
String bindAddress = this.bindAddress;
int port = this.port;
try {
ServerBootstrap boot = new ServerBootstrap();
boot.group(eventLoopGroup)
Expand All @@ -130,7 +134,7 @@ protected void initChannel(SocketChannel channel) {
boot.bind(bindAddress, port).addListener(f -> {
if (!f.isSuccess()) {
log.error("Socks server bind failure, address:[{}:{}]", bindAddress, port, f.cause());
System.exit(1);
Client.exitWithNotify(1, "exitmsg.socks.bind_error", port, f.cause().getMessage());
} else {
log.info("Netty socks server complete");
}
Expand Down
10 changes: 10 additions & 0 deletions client/src/main/resources/META-INF/i18n/exitmsg_en.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
exitmsg.title = ERROR
exitmsg.client_boot.start_failure = Startup failure, error message\uFF1A{0}
exitmsg.standard_client.config_load_error = Load config file at classpath://config.properties failure, detail message\uFF1A{0}
exitmsg.swt_view.init_failure = UI component startup failure, detail message: {0}
exitmsg.swt_view.run_error = An error occurred during the operation of the UI component, detail message: {0}
exitmsg.pac.gfw_load_error = An error occurred while reading the GFW list file, detail message: {0}
exitmsg.pac.ipv4_load_error = An error occurred while reading the IPv4 whitelist file, detail message: {0}
exitmsg.pac.gfw_default_load_error = Error reading the default GFW list file, detail message: {0}
exitmsg.pac.ipv4_default_load_error = Error reading the default IPv4 list file, detail message: {0}
exitmsg.socks.bind_error = Unable to bind local SOCKS5 proxy port {0}, error message: {1}
10 changes: 10 additions & 0 deletions client/src/main/resources/META-INF/i18n/exitmsg_zh.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
exitmsg.title = \u9519\u8BEF
exitmsg.client_boot.start_failure = \u542F\u52A8\u9519\u8BEF\uFF0C\u9519\u8BEF\u4FE1\u606F\uFF1A{0}
exitmsg.standard_client.config_load_error = \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6classpath://config.properties\u5931\u8D25\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.swt_view.init_failure = UI\u7EC4\u4EF6\u542F\u52A8\u5931\u8D25\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.swt_view.run_error = UI\u7EC4\u4EF6\u8FD0\u884C\u671F\u95F4\u53D1\u751F\u9519\u8BEF\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.pac.gfw_load_error = \u8BFB\u53D6GFW\u5217\u8868\u6587\u4EF6\u53D1\u751F\u9519\u8BEF\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.pac.ipv4_load_error = \u8BFB\u53D6IPv4\u767D\u540D\u5355\u5217\u8868\u6587\u4EF6\u53D1\u751F\u9519\u8BEF\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.pac.gfw_default_load_error = \u8BFB\u53D6\u9ED8\u8BA4GFW\u5217\u8868\u6587\u4EF6\u53D1\u751F\u9519\u8BEF\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.pac.ipv4_default_load_error = \u8BFB\u53D6\u9ED8\u8BA4IPv4\u5217\u8868\u6587\u4EF6\u53D1\u751F\u9519\u8BEF\uFF0C\u8BE6\u7EC6\u4FE1\u606F\uFF1A{0}
exitmsg.socks.bind_error = \u65E0\u6CD5\u7ED1\u5B9A\u672C\u5730SOCKS5\u4EE3\u7406\u7AEF\u53E3{0}\uFF0C\u9519\u8BEF\u4FE1\u606F\uFF1A{1}
17 changes: 17 additions & 0 deletions client/src/main/resources/META-INF/i18n/swtui_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,20 @@ swtui.socks5.form.button.cancel = Cancel
swtui.socks5.notice.port_error = Port illegal
swtui.socks5.notice.update_success = Update success, you need rebot program so that can be done.
swtui.socks5.notice.unchanged = Update success

swtui.http.title = HTTP proxy setup
swtui.http.form.label.switch = Switch
swtui.http.form.label.port = Port
swtui.http.form.label.validate = Validate
swtui.http.form.label.username = Username
swtui.http.form.label.password = Password
swtui.http.form.button.switch_open = Enable
swtui.http.form.button.switch_close = Close
swtui.http.form.button.validate_open = Enable
swtui.http.form.button.validate_close = Close
swtui.http.form.button.enter = Confirm
swtui.http.form.button.cancel = Cancel
swtui.http.notice.error.title = Error
swtui.http.notice.error.port_error = Incorrect port number (A number between 1 and 65535)
swtui.http.notice.error.auth_error = When authentication is turned on, the username and password must not be empty.
swtui.http.notice.update_success = Update successful, some settings need to restart the program to take effect.
Loading

0 comments on commit e4e42cc

Please sign in to comment.