Browse Source

Merge branch 'master' into v2ray-geosite

tags/4.2.0.0
Student Main 4 years ago
parent
commit
46f25355b0
7 changed files with 365 additions and 204 deletions
  1. +39
    -0
      .github/ISSUE_TEMPLATE/bug_report_en.md
  2. +39
    -0
      .github/ISSUE_TEMPLATE/bug_report_zh.md
  3. +20
    -0
      .github/ISSUE_TEMPLATE/feature_request.md
  4. +0
    -29
      .github/issue_template.md
  5. +207
    -123
      shadowsocks-csharp/Controller/Service/TCPRelay.cs
  6. +28
    -20
      shadowsocks-csharp/Controller/ShadowsocksController.cs
  7. +32
    -32
      shadowsocks-csharp/Data/i18n.csv

+ 39
- 0
.github/ISSUE_TEMPLATE/bug_report_en.md View File

@@ -0,0 +1,39 @@
---
name: Bug report (English)
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

<!--
- Shadowsocks is a non-profit open source project. If you bought the service from a provider, please contact them.
- If you have questions rather than Shadowsocks Windows client, please go to https://github.com/shadowsocks
- Please read Wiki carefully, especially https://github.com/shadowsocks/shadowsocks-windows/wiki/Troubleshooting
- And search from Issue Board https://github.com/shadowsocks/shadowsocks-windows/issues?utf8=%E2%9C%93&q=is%3Aissue
- Please include the following information. Questions lacking details will be closed.
-->

### Describe the bug

### Environment

- Shadowsocks client version:
- OS version:
- .NET version:

### Steps you have tried


### What did you expect to see?


### What did you see instead?


### Config and error log in detail (with all sensitive info masked)

```
PASTE LOG HERE
```

+ 39
- 0
.github/ISSUE_TEMPLATE/bug_report_zh.md View File

@@ -0,0 +1,39 @@
---
name: Bug报告 (中文)
about: 反馈Bug
title: ''
labels: bug report
assignees: ''

---

<!--
- 影梭(Shadowsocks)是一个开源非盈利项目,不提供任何托管服务。如果你是从服务提供商购买的服务,请联系他们。
- 如果你有非影梭Windows客户端相关的问题,请去 https://github.com/shadowsocks
- 提问前请先阅读wiki https://github.com/shadowsocks/shadowsocks-windows/wiki/Troubleshooting.
- 并在Issue Board中搜索 https://github.com/shadowsocks/shadowsocks-windows/issues?utf8=%E2%9C%93&q=is%3Aissue
- 请按照以下格式描述你的问题,描述不清的问题将会被关闭。
-->

### 简要描述问题

### 环境

- Shadowsocks客户端版本:
- 操作系统版本:
- .NET版本:

### 操作步骤


### 期望的结果


### 实际结果


### 配置文件和日志文件(请隐去敏感信息)

```
在此粘贴日志
```

+ 20
- 0
.github/ISSUE_TEMPLATE/feature_request.md View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.

+ 0
- 29
.github/issue_template.md View File

@@ -1,29 +0,0 @@
<!--
- Shadowsocks is a non-profit open source project. If you bought the service from a provider, please contact them.
影梭(Shadowsocks)是一个开源非盈利项目,不提供任何托管服务。如果你是从服务提供商购买的服务,请联系他们。
- If you have questions rather than Shadowsocks Windows client, please go to https://github.com/shadowsocks
如果你有非影梭Windows客户端相关的问题,请去 https://github.com/shadowsocks
- Please read Wiki carefully, especially https://github.com/shadowsocks/shadowsocks-windows/wiki/Troubleshooting
提问前请先阅读wiki https://github.com/shadowsocks/shadowsocks-windows/wiki/Troubleshooting.
- And search from Issue Board https://github.com/shadowsocks/shadowsocks-windows/issues?utf8=%E2%9C%93&q=is%3Aissue
并在Issue Board中搜索 https://github.com/shadowsocks/shadowsocks-windows/issues?utf8=%E2%9C%93&q=is%3Aissue
- Please include the following information. Questions lacking details will be closed.
请按照以下格式描述你的问题,描述不清的问题将会被关闭。
-->
### Shadowsocks version / 影梭版本
### Environment (Operating system, .NET Framework, etc) / 使用环境(操作系统,.NET Framework等)
### Steps you have tried / 操作步骤
### What did you expect to see? / 期望的结果
### What did you see instead? / 实际结果
### Config and error log in detail (with all sensitive info masked) / 配置文件和日志文件(请隐去敏感信息)

+ 207
- 123
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -1,10 +1,12 @@
using NLog;
using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Timers; using System.Timers;
using NLog;
using Shadowsocks.Controller.Strategy; using Shadowsocks.Controller.Strategy;
using Shadowsocks.Encryption; using Shadowsocks.Encryption;
using Shadowsocks.Encryption.AEAD; using Shadowsocks.Encryption.AEAD;
@@ -12,16 +14,22 @@ using Shadowsocks.Encryption.Exception;
using Shadowsocks.Model; using Shadowsocks.Model;
using Shadowsocks.Proxy; using Shadowsocks.Proxy;
using Shadowsocks.Util.Sockets; using Shadowsocks.Util.Sockets;
using static Shadowsocks.Encryption.EncryptorBase; using static Shadowsocks.Encryption.EncryptorBase;
namespace Shadowsocks.Controller namespace Shadowsocks.Controller
{ {
class TCPRelay : Listener.Service
internal class TCPRelay : Listener.Service
{ {
private static Logger logger = LogManager.GetCurrentClassLogger();
private ShadowsocksController _controller;
public event EventHandler<SSTCPConnectedEventArgs> OnConnected;
public event EventHandler<SSTransmitEventArgs> OnInbound;
public event EventHandler<SSTransmitEventArgs> OnOutbound;
public event EventHandler<SSRelayEventArgs> OnFailed;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly ShadowsocksController _controller;
private DateTime _lastSweepTime; private DateTime _lastSweepTime;
private Configuration _config;
private readonly Configuration _config;
public ISet<TCPHandler> Handlers { get; set; } public ISet<TCPHandler> Handlers { get; set; }
@@ -37,9 +45,24 @@ namespace Shadowsocks.Controller
{ {
if (socket.ProtocolType != ProtocolType.Tcp if (socket.ProtocolType != ProtocolType.Tcp
|| (length < 2 || firstPacket[0] != 5)) || (length < 2 || firstPacket[0] != 5))
{
return false; return false;
}
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
TCPHandler handler = new TCPHandler(_controller, _config, this, socket);
TCPHandler handler = new TCPHandler(_controller, _config, socket);
handler.OnConnected += OnConnected;
handler.OnInbound += OnInbound;
handler.OnOutbound += OnOutbound;
handler.OnFailed += OnFailed;
handler.OnClosed += (h, arg) =>
{
lock (Handlers)
{
Handlers.Remove(handler);
}
};
IList<TCPHandler> handlersToClose = new List<TCPHandler>(); IList<TCPHandler> handlersToClose = new List<TCPHandler>();
lock (Handlers) lock (Handlers)
@@ -50,8 +73,12 @@ namespace Shadowsocks.Controller
{ {
_lastSweepTime = now; _lastSweepTime = now;
foreach (TCPHandler handler1 in Handlers) foreach (TCPHandler handler1 in Handlers)
{
if (now - handler1.lastActivity > TimeSpan.FromSeconds(900)) if (now - handler1.lastActivity > TimeSpan.FromSeconds(900))
{
handlersToClose.Add(handler1); handlersToClose.Add(handler1);
}
}
} }
} }
foreach (TCPHandler handler1 in handlersToClose) foreach (TCPHandler handler1 in handlersToClose)
@@ -80,26 +107,46 @@ namespace Shadowsocks.Controller
} }
handlersToClose.ForEach(h => h.Close()); handlersToClose.ForEach(h => h.Close());
} }
}
public void UpdateInboundCounter(Server server, long n)
public class SSRelayEventArgs : EventArgs
{
public readonly Server server;
public SSRelayEventArgs(Server server)
{ {
_controller.UpdateInboundCounter(server, n);
this.server = server;
} }
}
public void UpdateOutboundCounter(Server server, long n)
public class SSTransmitEventArgs : SSRelayEventArgs
{
public readonly long length;
public SSTransmitEventArgs(Server server, long length) : base(server)
{ {
_controller.UpdateOutboundCounter(server, n);
this.length = length;
} }
}
public class SSTCPConnectedEventArgs : SSRelayEventArgs
{
public readonly TimeSpan latency;
public void UpdateLatency(Server server, TimeSpan latency)
public SSTCPConnectedEventArgs(Server server, TimeSpan latency) : base(server)
{ {
_controller.UpdateLatency(server, latency);
this.latency = latency;
} }
} }
internal class TCPHandler internal class TCPHandler
{ {
class AsyncSession
public event EventHandler<SSTCPConnectedEventArgs> OnConnected;
public event EventHandler<SSTransmitEventArgs> OnInbound;
public event EventHandler<SSTransmitEventArgs> OnOutbound;
public event EventHandler<SSRelayEventArgs> OnClosed;
public event EventHandler<SSRelayEventArgs> OnFailed;
private class AsyncSession
{ {
public IProxy Remote { get; } public IProxy Remote { get; }
@@ -109,7 +156,7 @@ namespace Shadowsocks.Controller
} }
} }
class AsyncSession<T> : AsyncSession
private class AsyncSession<T> : AsyncSession
{ {
public T State { get; set; } public T State { get; set; }
@@ -124,7 +171,7 @@ namespace Shadowsocks.Controller
} }
} }
private static Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly int _serverTimeout; private readonly int _serverTimeout;
private readonly int _proxyTimeout; private readonly int _proxyTimeout;
@@ -143,10 +190,9 @@ namespace Shadowsocks.Controller
public DateTime lastActivity; public DateTime lastActivity;
private ShadowsocksController _controller;
private Configuration _config;
private TCPRelay _tcprelay;
private Socket _connection;
private readonly ShadowsocksController _controller;
private readonly ProxyConfig _config;
private readonly Socket _connection;
private IEncryptor _encryptor; private IEncryptor _encryptor;
private Server _server; private Server _server;
@@ -170,16 +216,16 @@ namespace Shadowsocks.Controller
private int _totalWrite = 0; private int _totalWrite = 0;
// remote -> local proxy (ciphertext, before decrypt) // remote -> local proxy (ciphertext, before decrypt)
private byte[] _remoteRecvBuffer = new byte[BufferSize];
private readonly byte[] _remoteRecvBuffer = new byte[BufferSize];
// client -> local proxy (plaintext, before encrypt) // client -> local proxy (plaintext, before encrypt)
private byte[] _connetionRecvBuffer = new byte[BufferSize];
private readonly byte[] _connetionRecvBuffer = new byte[BufferSize];
// local proxy -> remote (plaintext, after decrypt) // local proxy -> remote (plaintext, after decrypt)
private byte[] _remoteSendBuffer = new byte[BufferSize];
private readonly byte[] _remoteSendBuffer = new byte[BufferSize];
// local proxy -> client (ciphertext, before decrypt) // local proxy -> client (ciphertext, before decrypt)
private byte[] _connetionSendBuffer = new byte[BufferSize];
private readonly byte[] _connetionSendBuffer = new byte[BufferSize];
private bool _connectionShutdown = false; private bool _connectionShutdown = false;
private bool _remoteShutdown = false; private bool _remoteShutdown = false;
@@ -197,11 +243,11 @@ namespace Shadowsocks.Controller
private EndPoint _destEndPoint = null; private EndPoint _destEndPoint = null;
public TCPHandler(ShadowsocksController controller, Configuration config, TCPRelay tcprelay, Socket socket)
// TODO: decouple controller
public TCPHandler(ShadowsocksController controller, Configuration config, Socket socket)
{ {
_controller = controller; _controller = controller;
_config = config;
_tcprelay = tcprelay;
_config = config.proxy;
_connection = socket; _connection = socket;
_proxyTimeout = config.proxy.proxyTimeout * 1000; _proxyTimeout = config.proxy.proxyTimeout * 1000;
_serverTimeout = config.GetCurrentServer().timeout * 1000; _serverTimeout = config.GetCurrentServer().timeout * 1000;
@@ -214,11 +260,13 @@ namespace Shadowsocks.Controller
Server server = _controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)_connection.RemoteEndPoint, Server server = _controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)_connection.RemoteEndPoint,
_destEndPoint); _destEndPoint);
if (server == null || server.server == "") if (server == null || server.server == "")
{
throw new ArgumentException("No server configured"); throw new ArgumentException("No server configured");
}
_encryptor = EncryptorFactory.GetEncryptor(server.method, server.password); _encryptor = EncryptorFactory.GetEncryptor(server.method, server.password);
this._server = server;
_server = server;
/* prepare address buffer length for AEAD */ /* prepare address buffer length for AEAD */
Logger.Trace($"_addrBufLength={_addrBufLength}"); Logger.Trace($"_addrBufLength={_addrBufLength}");
@@ -235,20 +283,31 @@ namespace Shadowsocks.Controller
private void CheckClose() private void CheckClose()
{ {
if (_connectionShutdown && _remoteShutdown) if (_connectionShutdown && _remoteShutdown)
{
Close(); Close();
}
}
private void ErrorClose(Exception e)
{
Logger.LogUsefulException(e);
Close();
} }
public void Close() public void Close()
{ {
lock (_closeConnLock) lock (_closeConnLock)
{ {
if (_closed) return;
if (_closed)
{
return;
}
_closed = true; _closed = true;
} }
lock (_tcprelay.Handlers)
{
_tcprelay.Handlers.Remove(this);
}
OnClosed?.Invoke(this, new SSRelayEventArgs(_server));
try try
{ {
_connection.Shutdown(SocketShutdown.Both); _connection.Shutdown(SocketShutdown.Both);
@@ -263,7 +322,7 @@ namespace Shadowsocks.Controller
{ {
try try
{ {
var remote = _currentRemoteSession.Remote;
IProxy remote = _currentRemoteSession.Remote;
remote.Shutdown(SocketShutdown.Both); remote.Shutdown(SocketShutdown.Both);
remote.Close(); remote.Close();
} }
@@ -284,7 +343,11 @@ namespace Shadowsocks.Controller
private void HandshakeReceive() private void HandshakeReceive()
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
int bytesRead = _firstPacketLength; int bytesRead = _firstPacketLength;
@@ -301,18 +364,23 @@ namespace Shadowsocks.Controller
HandshakeSendCallback, null); HandshakeSendCallback, null);
} }
else else
{
Close(); Close();
}
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void HandshakeSendCallback(IAsyncResult ar) private void HandshakeSendCallback(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
_connection.EndSend(ar); _connection.EndSend(ar);
@@ -324,27 +392,30 @@ namespace Shadowsocks.Controller
// +-----+-----+-------+------+----------+----------+ // +-----+-----+-------+------+----------+----------+
// Skip first 3 bytes, and read 2 more bytes to analysis the address. // Skip first 3 bytes, and read 2 more bytes to analysis the address.
// 2 more bytes is designed if address is domain then we don't need to read once more to get the addr length. // 2 more bytes is designed if address is domain then we don't need to read once more to get the addr length.
// TODO validate
// validate is unnecessary, we did it in first packet, but we can do it in future version
_connection.BeginReceive(_connetionRecvBuffer, 0, 3 + ADDR_ATYP_LEN + 1, SocketFlags.None, _connection.BeginReceive(_connetionRecvBuffer, 0, 3 + ADDR_ATYP_LEN + 1, SocketFlags.None,
HandshakeReceive2Callback, null);
AddressReceiveCallback, null);
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void HandshakeReceive2Callback(IAsyncResult ar)
private void AddressReceiveCallback(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
int bytesRead = _connection.EndReceive(ar); int bytesRead = _connection.EndReceive(ar);
if (bytesRead >= 5) if (bytesRead >= 5)
{ {
_command = _connetionRecvBuffer[1]; _command = _connetionRecvBuffer[1];
switch(_command)
switch (_command)
{ {
case CMD_CONNECT: case CMD_CONNECT:
@@ -355,7 +426,7 @@ namespace Shadowsocks.Controller
// +----+-----+-------+------+----------+----------+ // +----+-----+-------+------+----------+----------+
byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
_connection.BeginSend(response, 0, response.Length, SocketFlags.None, _connection.BeginSend(response, 0, response.Length, SocketFlags.None,
ResponseCallback, null);
ConnectResponseCallback, null);
break; break;
case CMD_UDP_ASSOC: case CMD_UDP_ASSOC:
ReadAddress(HandleUDPAssociate); ReadAddress(HandleUDPAssociate);
@@ -376,12 +447,11 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void ResponseCallback(IAsyncResult ar)
private void ConnectResponseCallback(IAsyncResult ar)
{ {
try try
{ {
@@ -391,8 +461,7 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
@@ -431,15 +500,19 @@ namespace Shadowsocks.Controller
private void OnAddressFullyRead(IAsyncResult ar) private void OnAddressFullyRead(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
int bytesRead = _connection.EndReceive(ar); int bytesRead = _connection.EndReceive(ar);
var states = (object[])ar.AsyncState;
object[] states = (object[])ar.AsyncState;
int bytesRemain = (int)states[0]; int bytesRemain = (int)states[0];
var onSuccess = (Action)states[1];
Action onSuccess = (Action)states[1];
if (bytesRead >= bytesRemain) if (bytesRead >= bytesRemain)
{ {
@@ -472,7 +545,7 @@ namespace Shadowsocks.Controller
break; break;
} }
Logger.Debug($"connect to {dstAddr}:{dstPort}");
Logger.Debug($"connect to {dstAddr}:{dstPort}");
_destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort); _destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort);
@@ -486,8 +559,7 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
@@ -515,7 +587,11 @@ namespace Shadowsocks.Controller
private void ReadAll(IAsyncResult ar) private void ReadAll(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
if (ar.AsyncState != null) if (ar.AsyncState != null)
@@ -533,13 +609,14 @@ namespace Shadowsocks.Controller
ReadAll, null); ReadAll, null);
} }
else else
{
Close(); Close();
}
} }
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
@@ -584,9 +661,9 @@ namespace Shadowsocks.Controller
serverEP = pluginEP; serverEP = pluginEP;
remote = new DirectConnect(); remote = new DirectConnect();
} }
else if (_config.proxy.useProxy)
else if (_config.useProxy)
{ {
switch (_config.proxy.proxyType)
switch (_config.proxyType)
{ {
case ProxyConfig.PROXY_SOCKS5: case ProxyConfig.PROXY_SOCKS5:
remote = new Socks5Proxy(); remote = new Socks5Proxy();
@@ -597,14 +674,14 @@ namespace Shadowsocks.Controller
default: default:
throw new NotSupportedException("Unknown forward proxy."); throw new NotSupportedException("Unknown forward proxy.");
} }
proxyEP = SocketUtil.GetEndPoint(_config.proxy.proxyServer, _config.proxy.proxyPort);
proxyEP = SocketUtil.GetEndPoint(_config.proxyServer, _config.proxyPort);
} }
else else
{ {
remote = new DirectConnect(); remote = new DirectConnect();
} }
var session = new AsyncSession(remote);
AsyncSession session = new AsyncSession(remote);
lock (_closeConnLock) lock (_closeConnLock)
{ {
if (_closed) if (_closed)
@@ -632,14 +709,13 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void ProxyConnectTimer_Elapsed(object sender, ElapsedEventArgs e) private void ProxyConnectTimer_Elapsed(object sender, ElapsedEventArgs e)
{ {
var timer = (ProxyTimer)sender;
ProxyTimer timer = (ProxyTimer)sender;
timer.Elapsed -= ProxyConnectTimer_Elapsed; timer.Elapsed -= ProxyConnectTimer_Elapsed;
timer.Enabled = false; timer.Enabled = false;
timer.Dispose(); timer.Dispose();
@@ -649,7 +725,7 @@ namespace Shadowsocks.Controller
{ {
return; return;
} }
var proxy = timer.Session.Remote;
IProxy proxy = timer.Session.Remote;
Logger.Info($"Proxy {proxy.ProxyEndPoint} timed out"); Logger.Info($"Proxy {proxy.ProxyEndPoint} timed out");
proxy.Close(); proxy.Close();
@@ -664,15 +740,15 @@ namespace Shadowsocks.Controller
} }
try try
{ {
var session = (AsyncSession<ProxyTimer>)ar.AsyncState;
AsyncSession<ProxyTimer> session = (AsyncSession<ProxyTimer>)ar.AsyncState;
ProxyTimer timer = session.State; ProxyTimer timer = session.State;
var destEndPoint = timer.DestEndPoint;
var server = timer.Server;
EndPoint destEndPoint = timer.DestEndPoint;
Server server = timer.Server;
timer.Elapsed -= ProxyConnectTimer_Elapsed; timer.Elapsed -= ProxyConnectTimer_Elapsed;
timer.Enabled = false; timer.Enabled = false;
timer.Dispose(); timer.Dispose();
var remote = session.Remote;
IProxy remote = session.Remote;
// Complete the connection. // Complete the connection.
remote.EndConnectProxy(ar); remote.EndConnectProxy(ar);
@@ -694,9 +770,9 @@ namespace Shadowsocks.Controller
_destConnected = false; _destConnected = false;
NetworkCredential auth = null; NetworkCredential auth = null;
if (_config.proxy.useAuth)
if (_config.useAuth)
{ {
auth = new NetworkCredential(_config.proxy.authUser, _config.proxy.authPwd);
auth = new NetworkCredential(_config.authUser, _config.authPwd);
} }
// Connect to the remote endpoint. // Connect to the remote endpoint.
@@ -708,14 +784,13 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void DestConnectTimer_Elapsed(object sender, ElapsedEventArgs e) private void DestConnectTimer_Elapsed(object sender, ElapsedEventArgs e)
{ {
var timer = (ServerTimer)sender;
ServerTimer timer = (ServerTimer)sender;
timer.Elapsed -= DestConnectTimer_Elapsed; timer.Elapsed -= DestConnectTimer_Elapsed;
timer.Enabled = false; timer.Enabled = false;
timer.Dispose(); timer.Dispose();
@@ -725,10 +800,9 @@ namespace Shadowsocks.Controller
return; return;
} }
var session = timer.Session;
AsyncSession session = timer.Session;
Server server = timer.Server; Server server = timer.Server;
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.SetFailure(server);
OnFailed?.Invoke(this, new SSRelayEventArgs(_server));
Logger.Info($"{server.FriendlyName()} timed out"); Logger.Info($"{server.FriendlyName()} timed out");
session.Remote.Close(); session.Remote.Close();
Close(); Close();
@@ -736,17 +810,21 @@ namespace Shadowsocks.Controller
private void ConnectCallback(IAsyncResult ar) private void ConnectCallback(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
var session = (AsyncSession<ServerTimer>)ar.AsyncState;
AsyncSession<ServerTimer> session = (AsyncSession<ServerTimer>)ar.AsyncState;
ServerTimer timer = session.State; ServerTimer timer = session.State;
_server = timer.Server; _server = timer.Server;
timer.Elapsed -= DestConnectTimer_Elapsed; timer.Elapsed -= DestConnectTimer_Elapsed;
timer.Enabled = false; timer.Enabled = false;
timer.Dispose(); timer.Dispose();
var remote = session.Remote;
IProxy remote = session.Remote;
// Complete the connection. // Complete the connection.
remote.EndConnectDest(ar); remote.EndConnectDest(ar);
@@ -754,10 +832,9 @@ namespace Shadowsocks.Controller
Logger.Debug($"Socket connected to ss server: {_server.FriendlyName()}"); Logger.Debug($"Socket connected to ss server: {_server.FriendlyName()}");
var latency = DateTime.Now - _startConnectTime;
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.UpdateLatency(_server, latency);
_tcprelay.UpdateLatency(_server, latency);
TimeSpan latency = DateTime.Now - _startConnectTime;
OnConnected?.Invoke(this, new SSTCPConnectedEventArgs(_server, latency));
StartPipe(session); StartPipe(session);
} }
@@ -768,11 +845,9 @@ namespace Shadowsocks.Controller
{ {
if (_server != null) if (_server != null)
{ {
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.SetFailure(_server);
OnFailed?.Invoke(this, new SSRelayEventArgs(_server));
} }
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
@@ -781,7 +856,7 @@ namespace Shadowsocks.Controller
int available = Math.Min(_connection.Available, RecvSize - _firstPacketLength); int available = Math.Min(_connection.Available, RecvSize - _firstPacketLength);
if (available > 0) if (available > 0)
{ {
var size = _connection.Receive(_connetionRecvBuffer, _firstPacketLength, available,
int size = _connection.Receive(_connetionRecvBuffer, _firstPacketLength, available,
SocketFlags.None); SocketFlags.None);
_firstPacketLength += size; _firstPacketLength += size;
@@ -790,7 +865,11 @@ namespace Shadowsocks.Controller
private void StartPipe(AsyncSession session) private void StartPipe(AsyncSession session)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
_startReceivingTime = DateTime.Now; _startReceivingTime = DateTime.Now;
@@ -803,20 +882,24 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void PipeRemoteReceiveCallback(IAsyncResult ar) private void PipeRemoteReceiveCallback(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
var session = (AsyncSession)ar.AsyncState;
AsyncSession session = (AsyncSession)ar.AsyncState;
int bytesRead = session.Remote.EndReceive(ar); int bytesRead = session.Remote.EndReceive(ar);
_totalRead += bytesRead; _totalRead += bytesRead;
_tcprelay.UpdateInboundCounter(_server, bytesRead);
OnInbound?.Invoke(this, new SSTransmitEventArgs(_server, bytesRead));
if (bytesRead > 0) if (bytesRead > 0)
{ {
lastActivity = DateTime.Now; lastActivity = DateTime.Now;
@@ -845,8 +928,6 @@ namespace Shadowsocks.Controller
Logger.Trace($"start sending {bytesToSend}"); Logger.Trace($"start sending {bytesToSend}");
_connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, _connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None,
PipeConnectionSendCallback, new object[] { session, bytesToSend }); PipeConnectionSendCallback, new object[] { session, bytesToSend });
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.UpdateLastRead(_server);
} }
else else
{ {
@@ -857,20 +938,23 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
private void PipeConnectionReceiveCallback(IAsyncResult ar) private void PipeConnectionReceiveCallback(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
int bytesRead = _connection.EndReceive(ar); int bytesRead = _connection.EndReceive(ar);
var session = (AsyncSession)ar.AsyncState;
var remote = session.Remote;
AsyncSession session = (AsyncSession)ar.AsyncState;
IProxy remote = session.Remote;
if (bytesRead > 0) if (bytesRead > 0)
{ {
@@ -885,8 +969,7 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
@@ -907,22 +990,25 @@ namespace Shadowsocks.Controller
return; return;
} }
} }
_tcprelay.UpdateOutboundCounter(_server, bytesToSend);
OnOutbound?.Invoke(this, new SSTransmitEventArgs(_server, bytesToSend));
_startSendingTime = DateTime.Now; _startSendingTime = DateTime.Now;
session.Remote.BeginSend(_connetionSendBuffer, 0, bytesToSend, SocketFlags.None, session.Remote.BeginSend(_connetionSendBuffer, 0, bytesToSend, SocketFlags.None,
PipeRemoteSendCallback, new object[] { session, bytesToSend }); PipeRemoteSendCallback, new object[] { session, bytesToSend });
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.UpdateLastWrite(_server);
} }
private void PipeRemoteSendCallback(IAsyncResult ar) private void PipeRemoteSendCallback(IAsyncResult ar)
{ {
if (_closed) return;
if (_closed)
{
return;
}
try try
{ {
var container = (object[])ar.AsyncState;
var session = (AsyncSession)container[0];
var bytesShouldSend = (int)container[1];
object[] container = (object[])ar.AsyncState;
AsyncSession session = (AsyncSession)container[0];
int bytesShouldSend = (int)container[1];
int bytesSent = session.Remote.EndSend(ar); int bytesSent = session.Remote.EndSend(ar);
if (bytesSent > 0) if (bytesSent > 0)
@@ -944,8 +1030,7 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
@@ -954,11 +1039,11 @@ namespace Shadowsocks.Controller
{ {
try try
{ {
var container = (object[])ar.AsyncState;
var session = (AsyncSession)container[0];
var bytesShouldSend = (int)container[1];
var bytesSent = _connection.EndSend(ar);
var bytesRemaining = bytesShouldSend - bytesSent;
object[] container = (object[])ar.AsyncState;
AsyncSession session = (AsyncSession)container[0];
int bytesShouldSend = (int)container[1];
int bytesSent = _connection.EndSend(ar);
int bytesRemaining = bytesShouldSend - bytesSent;
if (bytesRemaining > 0) if (bytesRemaining > 0)
{ {
Logger.Info("reconstruct _remoteSendBuffer to re-send"); Logger.Info("reconstruct _remoteSendBuffer to re-send");
@@ -972,8 +1057,7 @@ namespace Shadowsocks.Controller
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogUsefulException(e);
Close();
ErrorClose(e);
} }
} }
} }

+ 28
- 20
shadowsocks-csharp/Controller/ShadowsocksController.cs View File

@@ -217,25 +217,25 @@ namespace Shadowsocks.Controller
StatisticsStrategyConfiguration.Save(configuration); StatisticsStrategyConfiguration.Save(configuration);
} }
public bool AskAddServerBySSURL(string ssURL)
{
var dr = MessageBox.Show(I18N.GetString("Import from URL: {0} ?", ssURL), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
{
public bool AskAddServerBySSURL(string ssURL)
{
var dr = MessageBox.Show(I18N.GetString("Import from URL: {0} ?", ssURL), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
{
if (AddServerBySSURL(ssURL)) if (AddServerBySSURL(ssURL))
{ {
MessageBox.Show(I18N.GetString("Successfully imported from {0}", ssURL)); MessageBox.Show(I18N.GetString("Successfully imported from {0}", ssURL));
return true; return true;
}
}
else else
{ {
MessageBox.Show(I18N.GetString("Failed to import. Please check if the link is valid.")); MessageBox.Show(I18N.GetString("Failed to import. Please check if the link is valid."));
}
}
return false;
}
}
}
return false;
}
public bool AddServerBySSURL(string ssURL) public bool AddServerBySSURL(string ssURL)
{ {
try try
@@ -486,29 +486,32 @@ namespace Shadowsocks.Controller
ConfigChanged?.Invoke(this, new EventArgs()); ConfigChanged?.Invoke(this, new EventArgs());
} }
public void UpdateLatency(Server server, TimeSpan latency)
public void UpdateLatency(object sender, SSTCPConnectedEventArgs args)
{ {
GetCurrentStrategy()?.UpdateLatency(args.server, args.latency);
if (_config.availabilityStatistics) if (_config.availabilityStatistics)
{ {
availabilityStatistics.UpdateLatency(server, (int)latency.TotalMilliseconds);
availabilityStatistics.UpdateLatency(args.server, (int)args.latency.TotalMilliseconds);
} }
} }
public void UpdateInboundCounter(Server server, long n)
public void UpdateInboundCounter(object sender, SSTransmitEventArgs args)
{ {
Interlocked.Add(ref _inboundCounter, n);
GetCurrentStrategy()?.UpdateLastRead(args.server);
Interlocked.Add(ref _inboundCounter, args.length);
if (_config.availabilityStatistics) if (_config.availabilityStatistics)
{ {
availabilityStatistics.UpdateInboundCounter(server, n);
availabilityStatistics.UpdateInboundCounter(args.server, args.length);
} }
} }
public void UpdateOutboundCounter(Server server, long n)
public void UpdateOutboundCounter(object sender, SSTransmitEventArgs args)
{ {
Interlocked.Add(ref _outboundCounter, n);
GetCurrentStrategy()?.UpdateLastWrite(args.server);
Interlocked.Add(ref _outboundCounter, args.length);
if (_config.availabilityStatistics) if (_config.availabilityStatistics)
{ {
availabilityStatistics.UpdateOutboundCounter(server, n);
availabilityStatistics.UpdateOutboundCounter(args.server, args.length);
} }
} }
@@ -552,6 +555,11 @@ namespace Shadowsocks.Controller
privoxyRunner.Start(_config); privoxyRunner.Start(_config);
TCPRelay tcpRelay = new TCPRelay(this, _config); TCPRelay tcpRelay = new TCPRelay(this, _config);
tcpRelay.OnConnected += UpdateLatency;
tcpRelay.OnInbound += UpdateInboundCounter;
tcpRelay.OnOutbound += UpdateOutboundCounter;
tcpRelay.OnFailed += (o, e) => GetCurrentStrategy()?.SetFailure(e.server);
UDPRelay udpRelay = new UDPRelay(this); UDPRelay udpRelay = new UDPRelay(this);
List<Listener.IService> services = new List<Listener.IService> List<Listener.IService> services = new List<Listener.IService>
{ {


+ 32
- 32
shadowsocks-csharp/Data/i18n.csv View File

@@ -12,22 +12,22 @@ Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowso
,,,,,, ,,,,,,
System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,Proxy système System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ,시스템 프록시,Proxy système
Disable,Отключен,禁用,禁用,無効,비활성화,Désactiver Disable,Отключен,禁用,禁用,無効,비활성화,Désactiver
PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PAC,PAC,PAC
PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PAC,프록시 자동 구성 (PAC),PAC
Global,Для всей системы,全局模式,全局模式,全般,전역,Global Global,Для всей системы,全局模式,全局模式,全般,전역,Global
Servers,Серверы,服务器,伺服器,サーバー,서버,Serveurs Servers,Серверы,服务器,伺服器,サーバー,서버,Serveurs
Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集...,서버 수정…,Éditer serveurs… Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集...,서버 수정…,Éditer serveurs…
Statistics Config...,Настройки статистики…,统计配置...,統計設定檔...,統計情報の設定...,통계 설정,Configuration des statistiques… Statistics Config...,Настройки статистики…,统计配置...,統計設定檔...,統計情報の設定...,통계 설정,Configuration des statistiques…
Start on Boot,Автозагрузка,开机启动,開機啟動,システムと同時に起動,시스템 시작 시에 시작하기,Démarrage automatique Start on Boot,Автозагрузка,开机启动,開機啟動,システムと同時に起動,시스템 시작 시에 시작하기,Démarrage automatique
Associate ss:// Links,Ассоциированный ss:// Ссылки,关联 ss:// 链接,關聯 ss:// 鏈接,,,
Associate ss:// Links,Ассоциированный ss:// Ссылки,关联 ss:// 链接,關聯 ss:// 鏈接,,ss:// 링크 연결,
Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定...,포워드 프록시,Forward-proxy… Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定...,포워드 프록시,Forward-proxy…
Allow other Devices to connect,Общий доступ к подключению,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する,다른 기기에서 연결 허용,Autoriser d'autres appareils à se connecter Allow other Devices to connect,Общий доступ к подключению,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する,다른 기기에서 연결 허용,Autoriser d'autres appareils à se connecter
Local PAC,Локальный PAC,使用本地 PAC,使用本機 PAC,ローカル PAC,로컬 PAC,PAC local
Online PAC,Удаленный PAC,使用在线 PAC,使用線上 PAC,オンライン PAC,온라인 PAC,PAC en ligne
Edit Local PAC File...,Редактировать локальный PAC…,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集...,로컬 PAC 파일 수정,Modifier le fichier PAC local ...
Update Local PAC from Geosite,Обновить локальный PAC из Geosite,从 Geosite 更新本地 PAC,從 Geosite 更新本機 PAC,Geosite からローカル PAC を更新,Geosite에서 로컬 PAC 파일 업데이트,Mettre à jour le PAC local à partir de Geosite
Local PAC,Локальный PAC,使用本地 PAC,使用本機 PAC,ローカル PAC,로컬 프록시 자동 구성,PAC local
Online PAC,Удаленный PAC,使用在线 PAC,使用線上 PAC,オンライン PAC,온라인 프록시 자동 구성,PAC en ligne
Edit Local PAC File...,Редактировать локальный PAC…,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集...,로컬 프록시 자동 구성 파일 수정,Modifier le fichier PAC local ...
Update Local PAC from Geosite,Обновить локальный PAC из Geosite,从 Geosite 更新本地 PAC,從 Geosite 更新本機 PAC,Geosite からローカル PAC を更新,Geosite에서 로컬 프록시 자동 구성 파일 업데이트,Mettre à jour le PAC local à partir de Geosite
Edit User Rule for Geosite...,Редактировать свои правила для Geosite,编辑 Geosite 的用户规则...,編輯 Geosite 的使用者規則...,ユーザールールの編集...,Geosite 사용자 수정,Modifier la règle utilisateur pour Geosite ... Edit User Rule for Geosite...,Редактировать свои правила для Geosite,编辑 Geosite 的用户规则...,編輯 Geosite 的使用者規則...,ユーザールールの編集...,Geosite 사용자 수정,Modifier la règle utilisateur pour Geosite ...
Secure Local PAC,Безопасный URL локального PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護,로컬 PAC 암호화,Sécuriser PAC local
Copy Local PAC URL,Копировать URL локального PAC,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー,로컬 PAC 파일 URL 복사,Copier l'URL du PAC local
Secure Local PAC,Безопасный URL локального PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護,로컬 프록시 자동 구성 파일 암호화,Sécuriser PAC local
Copy Local PAC URL,Копировать URL локального PAC,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー,로컬 프록시 자동 구성 파일 URL 복사,Copier l'URL du PAC local
Share Server Config...,Поделиться конфигурацией сервера…,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有...,서버 설정 공유,Partager la configuration du serveur ... Share Server Config...,Поделиться конфигурацией сервера…,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有...,서버 설정 공유,Partager la configuration du serveur ...
Scan QRCode from Screen...,Сканировать QRCode с экрана…,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン...,화면에서 QR코드 스캔,Scanner le QRCode à partir de l'écran ... Scan QRCode from Screen...,Сканировать QRCode с экрана…,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン...,화면에서 QR코드 스캔,Scanner le QRCode à partir de l'écran ...
Import URL from Clipboard...,Импорт адреса из буфера обмена…,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート...,클립보드에서 URL 가져오기…,Importer l'URL du presse-papiers ... Import URL from Clipboard...,Импорт адреса из буфера обмена…,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート...,클립보드에서 URL 가져오기…,Importer l'URL du presse-papiers ...
@@ -66,17 +66,17 @@ Plugin Options,Опции плагина,插件选项,外掛程式選項,プラ
Need Plugin Argument,Требуются аргументы,需要命令行参数,,,플러그인 인자가 필요함,Besoin d'un argument de plugin Need Plugin Argument,Требуются аргументы,需要命令行参数,,,플러그인 인자가 필요함,Besoin d'un argument de plugin
Plugin Arguments,Аргументы,插件参数,外掛程式參數,プラグインの引数,플러그인 인자,Arguments du plugin Plugin Arguments,Аргументы,插件参数,外掛程式參數,プラグインの引数,플러그인 인자,Arguments du plugin
Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート,프록시 포트,Port proxy Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート,프록시 포트,Port proxy
Portable Mode,Переносимый режим,便携模式,便攜模式,ポータブルモード,포터블(Portable) 모드,Mode portable
Restart required,Требуется перезапуск программы,需要重新启动SS,需要重新啟動SS,再起動SSが必要,재시작 필요함,Redémarrage nécessaire
Portable Mode,Переносимый режим,便携模式,便攜模式,ポータブルモード,포터블 모드,Mode portable
Restart required,Требуется перезапуск программы,需要重新启动SS,需要重新啟動SS,再起動SSが必要,재시작이 필요합니다,Redémarrage nécessaire
Remarks,Примечания,备注,註解,付記,알림,Remarques Remarks,Примечания,备注,註解,付記,알림,Remarques
Timeout(Sec),Таймаут(сек),超时(秒),逾時 (秒),タイムアウト (秒),시간초과(Timeout) (초),Délai d'attente(sec)
Timeout(Sec),Таймаут(сек),超时(秒),逾時 (秒),タイムアウト (秒),시간 초과 (초),Délai d'attente(sec)
OK,ОК,确定,確定,OK,확인,OK OK,ОК,确定,確定,OK,확인,OK
Cancel,Отмена,取消,取消,キャンセル,취소,Annuler Cancel,Отмена,取消,取消,キャンセル,취소,Annuler
Apply,Применить,应用,應用,適用,적용,Appliquer Apply,Применить,应用,應用,適用,적용,Appliquer
New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー,새 서버,Nouveau serveur New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー,새 서버,Nouveau serveur
Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U),위로 (&U),Monter Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U),위로 (&U),Monter
Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O),아래로 (&O),Descendre Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O),아래로 (&O),Descendre
deprecated,Устаревшее,不推荐,不推薦,非推奨,폐기됨(deprecated),Obsolète
deprecated,Устаревшее,不推荐,不推薦,非推奨,더 이상 사용되지 않음,Obsolète
"Encryption method {0} not exist, will replace with {1}",,加密方法{0}不存在,将使用{1}代替,,,{0} 암호화 방식이 존재하지 않으므로 {1}로 대체될 것입니다.,"Méthode de chiffrement {0} n'existe pas, sera remplacée par {1}" "Encryption method {0} not exist, will replace with {1}",,加密方法{0}不存在,将使用{1}代替,,,{0} 암호화 방식이 존재하지 않으므로 {1}로 대체될 것입니다.,"Méthode de chiffrement {0} n'existe pas, sera remplacée par {1}"
,,,,,, ,,,,,,
#Statistics Config,,,,,, #Statistics Config,,,,,,
@@ -116,8 +116,8 @@ Use Proxy,Использовать прокси,使用代理,使用 Proxy,プロ
Proxy Type,Тип прокси,代理类型,Proxy 類型,プロキシの種類,프록시 종류,Type de proxy Proxy Type,Тип прокси,代理类型,Proxy 類型,プロキシの種類,프록시 종류,Type de proxy
Proxy Addr,Адрес прокси,代理地址,Proxy 位址,プロキシアドレス,프록시 주소,Adresse de proxy Proxy Addr,Адрес прокси,代理地址,Proxy 位址,プロキシアドレス,프록시 주소,Adresse de proxy
Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート,프록시 포트,Port de proxy Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート,프록시 포트,Port de proxy
"If server has a plugin, proxy will not be used","Если сервер использует плагины, прокси НЕ будет использоваться",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません,"만약 서버가 플러그인이 있다면, 프록시는용되지 않을 것입니다.","Si le serveur a un plugin, le proxy ne sera pas utilisé"
Use Auth,Требуется авторизация,使用认证,使用認證,認証を利用する,서버 증명(Auth) 사용,Utiliser l'authentification
"If server has a plugin, proxy will not be used","Если сервер использует плагины, прокси НЕ будет использоваться",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません,서버에 플러그인이 설치 되어 있는 경우 프록시를 사용할 수 없습니다.,"Si le serveur a un plugin, le proxy ne sera pas utilisé"
Use Auth,Требуется авторизация,使用认证,使用認證,認証を利用する,서버 증 사용,Utiliser l'authentification
User Name,Пользователь,用户名,認證用戶,認証ユーザ,사용자 이름,Nom d'utilisateur User Name,Пользователь,用户名,認證用戶,認証ユーザ,사용자 이름,Nom d'utilisateur
Auth Pwd,Пароль,认证密码,認證口令,認証パスワード,비밀번호,Mot de passe d'authentification Auth Pwd,Пароль,认证密码,認證口令,認証パスワード,비밀번호,Mot de passe d'authentification
,,,,,, ,,,,,,
@@ -142,9 +142,9 @@ QRCode and URL,QRCode и URL,二维码与 URL,QR 碼與 URL,QR コードと URL,
,,,,,, ,,,,,,
# PAC Url Form,,,,,, # PAC Url Form,,,,,,
,,,,,, ,,,,,,
Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集,온라인 PAC URL 수정,Modifier l'URL du PAC en ligne
Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集...,온라인 PAC URL 수정…,Modifier l'URL du PAC en ligne ...
Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい,PAC URL을 입력하세요,Veuillez saisir l'URL PAC
Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集,온라인 프록시 자동 구성 URL 수정,Modifier l'URL du PAC en ligne
Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集...,온라인 프록시 자동 구성 URL 수정…,Modifier l'URL du PAC en ligne ...
Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい,프록시 자동 구성 URL을 입력하세요,Veuillez saisir l'URL PAC
,,,,,, ,,,,,,
# HotkeySettings Form,,,,,, # HotkeySettings Form,,,,,,
,,,,,, ,,,,,,
@@ -164,7 +164,7 @@ Port {0} already in use,Порт {0} уже используется,端口 {0}
Port {0} is reserved by system,Порт {0} зарезервирован системой,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています,{0}번 포트는 시스템에서 사용 중입니다.,Port {0} réservé par le système Port {0} is reserved by system,Порт {0} зарезервирован системой,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています,{0}번 포트는 시스템에서 사용 중입니다.,Port {0} réservé par le système
Invalid server address,Неверный адрес сервера,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。,올바르지 않은 서버 주소입니다.,Adresse de serveur non valide Invalid server address,Неверный адрес сервера,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。,올바르지 않은 서버 주소입니다.,Adresse de serveur non valide
Illegal port number format,Неверный числовой формат порта,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。,올바르지 않은 포트 번호 형식입니다.,Format de numéro de port illégal Illegal port number format,Неверный числовой формат порта,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。,올바르지 않은 포트 번호 형식입니다.,Format de numéro de port illégal
Illegal timeout format,Неверный формат таймаута,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。,올바르지 않은 시간초과(Timeout) 형식입니다.,Format de délai d'attente illégal
Illegal timeout format,Неверный формат таймаута,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。,올바르지 않은 시간 초과 형식입니다.,Format de délai d'attente illégal
Server IP can not be blank,IP-адрес сервера не может быть пустым,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。,서버 IP는 비어있으면 안됩니다.,L'adresse IP du serveur ne peut pas être vide Server IP can not be blank,IP-адрес сервера не может быть пустым,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。,서버 IP는 비어있으면 안됩니다.,L'adresse IP du serveur ne peut pas être vide
Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。,비밀번호는 비어있으면 안됩니다.,Le mot de passe ne peut pas être vide Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。,비밀번호는 비어있으면 안됩니다.,Le mot de passe ne peut pas être vide
Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。,올바른 포트 범위가 아닙니다.,Port hors de portée Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。,올바른 포트 범위가 아닙니다.,Port hors de portée
@@ -176,8 +176,8 @@ Shadowsocks is here,Shadowsocks находится здесь,Shadowsocks 在这
You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。,프로그램 메뉴에서 Shadowsocks를 끄고 켤 수 있습니다.,Vous pouvez activer / désactiver Shadowsocks dans le menu contextuel You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。,프로그램 메뉴에서 Shadowsocks를 끄고 켤 수 있습니다.,Vous pouvez activer / désactiver Shadowsocks dans le menu contextuel
System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。,시스템 프록시가 활성화되었습니다.,Proxy système activé System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。,시스템 프록시가 활성화되었습니다.,Proxy système activé
System Proxy Disabled,Системный прокси отключен,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。,시스템 프록시가 비활성화되었습니다.,Proxy système désactivé System Proxy Disabled,Системный прокси отключен,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。,시스템 프록시가 비활성화되었습니다.,Proxy système désactivé
Failed to update PAC file ,Не удалось обновить PAC файл,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。,PAC 파일을 업데이트하는데 실패했습니다.,Impossible de mettre à jour le fichier PAC
PAC updated,PAC файл обновлен,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。,PAC 파일이 업데이트되었습니다.,PAC mis à jour
Failed to update PAC file ,Не удалось обновить PAC файл,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。,프록시 자동 구성 파일을 업데이트하는데 실패했습니다.,Impossible de mettre à jour le fichier PAC
PAC updated,PAC файл обновлен,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。,프록시 자동 구성 파일이 업데이트되었습니다.,PAC mis à jour
No updates found. Please report to Geosite if you have problems with it.,Обновлений не найдено. Сообщите авторам Geosite если у вас возникли проблемы.,未发现更新。如有问题请提交给 Geosite。,未發現更新。如有問題請報告至 Geosite。,お使いのバージョンは最新です。問題がある場合は、Geosite に報告して下さい。,사용 가능한 업데이트를 찾지 못했습니다. 문제가 있다면 Geosite로 전송해주세요.,Aucune mise à jour trouvée. Veuillez signaler à Geosite si vous avez des problèmes concernant. No updates found. Please report to Geosite if you have problems with it.,Обновлений не найдено. Сообщите авторам Geosite если у вас возникли проблемы.,未发现更新。如有问题请提交给 Geosite。,未發現更新。如有問題請報告至 Geosite。,お使いのバージョンは最新です。問題がある場合は、Geosite に報告して下さい。,사용 가능한 업데이트를 찾지 못했습니다. 문제가 있다면 Geosite로 전송해주세요.,Aucune mise à jour trouvée. Veuillez signaler à Geosite si vous avez des problèmes concernant.
No QRCode found. Try to zoom in or move it to the center of the screen.,QRCode не обнаружен. Попробуйте увеличить изображение или переместить его в центр экрана.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。,QR코드를 찾을 수 없습니다. 가운데로 화면을 이동시키거나 확대해보세요.,Aucun QRCode trouvé. Essayez de zoomer ou de le déplacer vers le centre de l'écran. No QRCode found. Try to zoom in or move it to the center of the screen.,QRCode не обнаружен. Попробуйте увеличить изображение или переместить его в центр экрана.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。,QR코드를 찾을 수 없습니다. 가운데로 화면을 이동시키거나 확대해보세요.,Aucun QRCode trouvé. Essayez de zoomer ou de le déplacer vers le centre de l'écran.
Shadowsocks is already running.,Shadowsocks уже запущен.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中,Shadowsocks가 이미 실행 중입니다.,Shadowsocks est déjà en cours d'exécution. Shadowsocks is already running.,Shadowsocks уже запущен.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中,Shadowsocks가 이미 실행 중입니다.,Shadowsocks est déjà en cours d'exécution.
@@ -190,25 +190,25 @@ Successfully imported from {0},Успешно импортировано из {0
Failed to import. Please check if the link is valid.,,导入失败,请检查链接是否有效。,導入失敗,請檢查鏈接是否有效。,,, Failed to import. Please check if the link is valid.,,导入失败,请检查链接是否有效。,導入失敗,請檢查鏈接是否有效。,,,
System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:,시스템 프록시 활성화됨: ,Proxy système activé: System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:,시스템 프록시 활성화됨: ,Proxy système activé:
Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0},실행 중: 포트 {0}번,En cours d'exécution: port {0} Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0},실행 중: 포트 {0}번,En cours d'exécution: port {0}
"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:,알 수 없는 오류로 Shadowsocks가 종료될 것입니다. 오류를 제보해주세요:,Shadowsocks va quitter en présence d/érreur inattendue. Veuillez signaler à
"Unsupported operating system, use Windows Vista at least.","Операционная система не поддерживается, минимальные системные требования: Windows Vista или выше.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。,"지원하지 않는 운영체제입니다, 최소한 Windows Vista가 필요합니다.","Système d'exploitation incompatible, veuillez utiliser Windows Vista ou ultérieure."
"Unsupported .NET Framework, please update to {0} or later.","Версия .NET Framework не поддерживается, минимальные системные требования: {0} или выше.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。,"지원하지 않는 .NET 프레임워크입니다, {0} 또는 상위 버전으로 업데이트해주세요.",".NET Framework incompatible, veuillez mettre à jour vers {0} ou ultérieure."
"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:,알 수 없는 오류로 Shadowsocks가 종료될 것입니다. 오류를 여기로 제보해주세요:,Shadowsocks va quitter en présence d/érreur inattendue. Veuillez signaler à
"Unsupported operating system, use Windows Vista at least.","Операционная система не поддерживается, минимальные системные требования: Windows Vista или выше.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。,지원하지 않는 운영체제입니다. 최소 Windows Vista가 필요합니다.,"Système d'exploitation incompatible, veuillez utiliser Windows Vista ou ultérieure."
"Unsupported .NET Framework, please update to {0} or later.","Версия .NET Framework не поддерживается, минимальные системные требования: {0} или выше.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。,지원하지 않는 .NET 프레임워크입니다. {0} 또는 상위 버전으로 업데이트해주세요.,".NET Framework incompatible, veuillez mettre à jour vers {0} ou ultérieure."
Proxy request failed,Не удалось выполнить запрос,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。,프록시 요청에 실패했습니다.,Échec de la demande de proxy Proxy request failed,Не удалось выполнить запрос,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。,프록시 요청에 실패했습니다.,Échec de la demande de proxy
Proxy handshake failed,Не удалось выполнить хэндшейк,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。,프록시 핸드쉐이크에 실패했습니다.,Échec de la prise de contact par proxy Proxy handshake failed,Не удалось выполнить хэндшейк,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。,프록시 핸드쉐이크에 실패했습니다.,Échec de la prise de contact par proxy
Register hotkey failed,Не удалось применить настройки горячих клавиш,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。,단축키 등록에 실패했습니다.,Échec de l'enregistrement du raccourci clavier Register hotkey failed,Не удалось применить настройки горячих клавиш,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。,단축키 등록에 실패했습니다.,Échec de l'enregistrement du raccourci clavier
Cannot parse hotkey: {0},Не удалось распознать следующие горячие клавиши: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0},단축키를 해석할 수 없습니다: {0},Impossible d'analyser le raccourci clavier: {0} Cannot parse hotkey: {0},Не удалось распознать следующие горячие клавиши: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0},단축키를 해석할 수 없습니다: {0},Impossible d'analyser le raccourci clavier: {0}
"Timeout is invalid, it should not exceed {0}",Таймаут не может превышать значение {0},超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。,"올바르지 않은 시간초과(Timeout) 설정입니다, {0}을 초과하지 않아야 합니다.","Le délai d'attente invalide, il ne doit pas dépasser {0}"
"Timeout is invalid, it should not exceed {0}",Таймаут не может превышать значение {0},超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。,올바르지 않은 시간 초과 설정입니다. {0}을 초과하지 않아야 합니다.,"Le délai d'attente invalide, il ne doit pas dépasser {0}"
Cannot find the plugin program file,Файл плагина не найден,找不到插件程序文件,找不到外掛程式文件,,플러그인 프로그램 파일을 찾을 수 없습니다.,Impossible de trouver le fichier du programme du plugin Cannot find the plugin program file,Файл плагина не найден,找不到插件程序文件,找不到外掛程式文件,,플러그인 프로그램 파일을 찾을 수 없습니다.,Impossible de trouver le fichier du programme du plugin
,,,,,, ,,,,,,
Operation failure,Операция завершилась неудачей,操作失败,,,작업에 실패했습니다.,Operation failure Operation failure,Операция завершилась неудачей,操作失败,,,작업에 실패했습니다.,Operation failure
Auto save failed,Автоматическое сохранение не удалось,自动保存失败,,,자동 저장에 실패했습니다.,Échec de l'enregistrement automatique Auto save failed,Автоматическое сохранение не удалось,自动保存失败,,,자동 저장에 실패했습니다.,Échec de l'enregistrement automatique
Whether to discard unconfigured servers,Внесенные изменения будут утеряны,是否丢弃未配置的服务器,,,완전하지 않은 서버 설정 변경 사항을 폐기하시겠습니까?,Eliminer les serveurs non configurés ou non
"Invalid server address, Cannot automatically save or discard changes",Неверный адрес сервера. Невозможно сохранить или отменить изменения,非法服务器地址,无法自动保存,是否丢弃修改,,,"서버 주소가 올바르지 않아 자동저장할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Adresse de serveur invalide, impossible d'enregistrer ou d'annuler automatiquement les modifications"
"Illegal port number format, Cannot automatically save or discard changes",Неверный числовой адрес порта. Невозможно сохранить или отменить изменения,非法端口格式,无法自动保存,是否丢弃修改,,,"포트 번호가 올바르지 않아 자동저장할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Format de numéro de port illégal, impossible d'enregistrer ou d'annuler automatiquement les modifications"
"Password can not be blank, Cannot automatically save or discard changes",Пароль не может быть пустым. Невозможно сохранить или отменить изменения,密码不能为空,无法自动保存,是否丢弃修改,,,"비밀번호가 비어있어 자동저장할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Le mot de passe ne peut pas être vide, impossible d'enregistrer ou d'annuler automatiquement les modifications"
"Illegal timeout format, Cannot automatically save or discard changes",Неверный формат таймаута. Невозможно сохранить или отменить изменения,非法超时格式,无法自动保存,是否丢弃修改,,,"시간초과(Timeout) 형식이 올바르지 않아 자동저장할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Format de délai d'attente illégal, impossible d'enregistrer ou d'annuler automatiquement les modifications"
Whether to discard unconfigured servers,Внесенные изменения будут утеряны,是否丢弃未配置的服务器,,,구성되지 않은 서버 설정 변경 사항을 폐기하시겠습니까?,Eliminer les serveurs non configurés ou non
"Invalid server address, Cannot automatically save or discard changes",Неверный адрес сервера. Невозможно сохранить или отменить изменения,非法服务器地址,无法自动保存,是否丢弃修改,,,"서버 주소가 올바르지 않아 자동 저장 할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Adresse de serveur invalide, impossible d'enregistrer ou d'annuler automatiquement les modifications"
"Illegal port number format, Cannot automatically save or discard changes",Неверный числовой адрес порта. Невозможно сохранить или отменить изменения,非法端口格式,无法自动保存,是否丢弃修改,,,"포트 번호가 올바르지 않아 자동 저장 할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Format de numéro de port illégal, impossible d'enregistrer ou d'annuler automatiquement les modifications"
"Password can not be blank, Cannot automatically save or discard changes",Пароль не может быть пустым. Невозможно сохранить или отменить изменения,密码不能为空,无法自动保存,是否丢弃修改,,,"비밀번호를 입력하지 않아 자동 저장 할 수 없습니다, 변경 사항을 폐기하시겠습니까?","Le mot de passe ne peut pas être vide, impossible d'enregistrer ou d'annuler automatiquement les modifications"
"Illegal timeout format, Cannot automatically save or discard changes",Неверный формат таймаута. Невозможно сохранить или отменить изменения,非法超时格式,无法自动保存,是否丢弃修改,,,시간 초과 형식이 올바르지 않아 자동 저장 할 수 없습니다. 변경 사항을 폐기하시겠습니까?,"Format de délai d'attente illégal, impossible d'enregistrer ou d'annuler automatiquement les modifications"
,,,,,, ,,,,,,
"Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,,,프록시 설정을 처리하는데에 오류가 발생했습니다. 현재 설정을 폐기하고 다시시도하시겠습니까?,Une erreur s'est produite lors du processus de configuration du proxy. Voulez-vous réinitialiser le paramètre actuel et réessayer?
"Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,,,프록시 설정을 처리하는데에 오류가 발생했습니다. 현재 설정을 폐기하고 다시 시도하시겠습니까?,Une erreur s'est produite lors du processus de configuration du proxy. Voulez-vous réinitialiser le paramètre actuel et réessayer?
"Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,,,복구 불가능한 프록시 설정 오류가 발생했습니다. 자세한 정보는 로그를 참조하세요.,"Une erreur de paramètre de proxy irrécupérable s'est produite, consultez le journal pour plus de détails" "Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,,,복구 불가능한 프록시 설정 오류가 발생했습니다. 자세한 정보는 로그를 참조하세요.,"Une erreur de paramètre de proxy irrécupérable s'est produite, consultez le journal pour plus de détails"
Auth user can not be blank,Пользователь не может быть пустым,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。,증 정보의 사용자 이름은 비어있을 수 없습니다.,L'utilisateur d'authentification ne peut pas être vide
Auth pwd can not be blank,Пароль не может быть пустым,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。,증 정보의 비밀번호는 비어있을 수 없습니다.,Le mot de passe d'authentification ne peut pas être vide
Auth user can not be blank,Пользователь не может быть пустым,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。,증 정보의 사용자 이름은 비어있을 수 없습니다.,L'utilisateur d'authentification ne peut pas être vide
Auth pwd can not be blank,Пароль не может быть пустым,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。,증 정보의 비밀번호는 비어있을 수 없습니다.,Le mot de passe d'authentification ne peut pas être vide

Loading…
Cancel
Save