@@ -1,4 +1,5 @@ | |||
using System; | |||
using NLog; | |||
using System; | |||
using System.IO; | |||
using System.IO.Compression; | |||
using System.Text; | |||
@@ -7,6 +8,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
public static class FileManager | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public static bool ByteArrayToFile(string fileName, byte[] content) | |||
{ | |||
try | |||
@@ -17,7 +20,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.Error(ex); | |||
logger.Error(ex); | |||
} | |||
return false; | |||
} | |||
@@ -39,7 +42,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.Error(ex); | |||
logger.Error(ex); | |||
throw ex; | |||
} | |||
} | |||
@@ -1,7 +1,7 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Windows.Forms; | |||
using NLog; | |||
using Shadowsocks.Controller.Hotkeys; | |||
using Shadowsocks.Model; | |||
@@ -9,6 +9,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
static class HotkeyReg | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public static void RegAllHotkeys() | |||
{ | |||
var hotkeyConfig = Configuration.Load().hotkey; | |||
@@ -60,7 +61,7 @@ namespace Shadowsocks.Controller | |||
var hotkey = HotKeys.Str2HotKey(hotkeyStr); | |||
if (hotkey == null) | |||
{ | |||
Logging.Error($"Cannot parse hotkey: {hotkeyStr}"); | |||
logger.Error($"Cannot parse hotkey: {hotkeyStr}"); | |||
onComplete?.Invoke(RegResult.ParseError); | |||
return false; | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using Microsoft.VisualBasic.FileIO; | |||
using NLog; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
using System.Collections.Generic; | |||
@@ -11,6 +12,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
public static class I18N | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public const string I18N_FILE = "i18n.csv"; | |||
private static Dictionary<string, string> _strings = new Dictionary<string, string>(); | |||
@@ -46,12 +49,12 @@ namespace Shadowsocks.Controller | |||
} | |||
if (targetIndex != -1 && enIndex != targetIndex) | |||
{ | |||
Logging.Info($"Using {localeNames[targetIndex]} translation for {locale}"); | |||
logger.Info($"Using {localeNames[targetIndex]} translation for {locale}"); | |||
} | |||
else | |||
{ | |||
// Still not found, exit | |||
Logging.Info($"Translation for {locale} not found"); | |||
logger.Info($"Translation for {locale} not found"); | |||
return; | |||
} | |||
} | |||
@@ -77,7 +80,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
string locale = CultureInfo.CurrentCulture.Name; | |||
string i18n = File.ReadAllText(I18N_FILE, Encoding.UTF8); | |||
Logging.Info("Current language is: " + locale); | |||
logger.Info("Current language is: " + locale); | |||
Init(i18n, locale); | |||
} | |||
@@ -0,0 +1,119 @@ | |||
using System; | |||
using System.ComponentModel; | |||
using System.IO; | |||
using System.Net.Sockets; | |||
using System.Net; | |||
using System.Diagnostics; | |||
using System.Text; | |||
using Shadowsocks.Util.SystemProxy; | |||
namespace NLog | |||
{ | |||
public static class LoggerExtension | |||
{ | |||
public static void Dump(this Logger logger, string tag, byte[] arr, int length) | |||
{ | |||
if (logger.IsTraceEnabled) | |||
{ | |||
var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); | |||
for (int i = 0; i < length - 1; i++) | |||
{ | |||
sb.Append($"0x{arr[i]:X2}, "); | |||
} | |||
sb.Append($"0x{arr[length - 1]:X2}"); | |||
sb.Append(Environment.NewLine); | |||
logger.Trace(sb.ToString()); | |||
} | |||
} | |||
public static void Debug(this Logger logger, EndPoint local, EndPoint remote, int len, string header = null, string tailer = null) | |||
{ | |||
if (logger.IsDebugEnabled) | |||
{ | |||
if (header == null && tailer == null) | |||
logger.Debug($"{local} => {remote} (size={len})"); | |||
else if (header == null && tailer != null) | |||
logger.Debug($"{local} => {remote} (size={len}), {tailer}"); | |||
else if (header != null && tailer == null) | |||
logger.Debug($"{header}: {local} => {remote} (size={len})"); | |||
else | |||
logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); | |||
} | |||
} | |||
public static void Debug(this Logger logger, Socket sock, int len, string header = null, string tailer = null) | |||
{ | |||
if (logger.IsDebugEnabled) | |||
{ | |||
logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); | |||
} | |||
} | |||
public static void LogUsefulException(this Logger logger, Exception e) | |||
{ | |||
// just log useful exceptions, not all of them | |||
if (e is SocketException) | |||
{ | |||
SocketException se = (SocketException)e; | |||
if (se.SocketErrorCode == SocketError.ConnectionAborted) | |||
{ | |||
// closed by browser when sending | |||
// normally happens when download is canceled or a tab is closed before page is loaded | |||
} | |||
else if (se.SocketErrorCode == SocketError.ConnectionReset) | |||
{ | |||
// received rst | |||
} | |||
else if (se.SocketErrorCode == SocketError.NotConnected) | |||
{ | |||
// The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected. | |||
} | |||
else if (se.SocketErrorCode == SocketError.HostUnreachable) | |||
{ | |||
// There is no network route to the specified host. | |||
} | |||
else if (se.SocketErrorCode == SocketError.TimedOut) | |||
{ | |||
// The connection attempt timed out, or the connected host has failed to respond. | |||
} | |||
else | |||
{ | |||
logger.Warn(e); | |||
} | |||
} | |||
else if (e is ObjectDisposedException) | |||
{ | |||
} | |||
else if (e is Win32Exception) | |||
{ | |||
var ex = (Win32Exception)e; | |||
// Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process. | |||
if ((uint)ex.ErrorCode != 0x80004005) | |||
{ | |||
logger.Warn(e); | |||
} | |||
} | |||
else if (e is ProxyException) | |||
{ | |||
var ex = (ProxyException)e; | |||
switch (ex.Type) | |||
{ | |||
case ProxyExceptionType.FailToRun: | |||
case ProxyExceptionType.QueryReturnMalformed: | |||
case ProxyExceptionType.SysproxyExitError: | |||
logger.Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}"); | |||
break; | |||
case ProxyExceptionType.QueryReturnEmpty: | |||
case ProxyExceptionType.Unspecific: | |||
logger.Error($"sysproxy - {ex.Type.ToString()}"); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
logger.Warn(e); | |||
} | |||
} | |||
} | |||
} |
@@ -1,198 +0,0 @@ | |||
using System; | |||
using System.ComponentModel; | |||
using System.IO; | |||
using System.Net.Sockets; | |||
using System.Net; | |||
using System.Diagnostics; | |||
using System.Text; | |||
using Shadowsocks.Util; | |||
using Shadowsocks.Util.SystemProxy; | |||
namespace Shadowsocks.Controller | |||
{ | |||
public class Logging | |||
{ | |||
public static string LogFilePath; | |||
private static FileStream _fs; | |||
private static StreamWriterWithTimestamp _sw; | |||
public static bool OpenLogFile() | |||
{ | |||
try | |||
{ | |||
LogFilePath = Utils.GetTempPath("shadowsocks.log"); | |||
_fs = new FileStream(LogFilePath, FileMode.Append); | |||
_sw = new StreamWriterWithTimestamp(_fs); | |||
_sw.AutoFlush = true; | |||
Console.SetOut(_sw); | |||
Console.SetError(_sw); | |||
return true; | |||
} | |||
catch (IOException e) | |||
{ | |||
Console.WriteLine(e.ToString()); | |||
return false; | |||
} | |||
} | |||
private static void WriteToLogFile(object o) | |||
{ | |||
try { | |||
Console.WriteLine(o); | |||
} catch(ObjectDisposedException) { | |||
} | |||
} | |||
public static void Error(object o) | |||
{ | |||
WriteToLogFile("[E] " + o); | |||
} | |||
public static void Info(object o) | |||
{ | |||
WriteToLogFile(o); | |||
} | |||
public static void Clear() { | |||
_sw.Close(); | |||
_sw.Dispose(); | |||
_fs.Close(); | |||
_fs.Dispose(); | |||
File.Delete(LogFilePath); | |||
OpenLogFile(); | |||
} | |||
[Conditional("DEBUG")] | |||
public static void Debug(object o) | |||
{ | |||
WriteToLogFile("[D] " + o); | |||
} | |||
[Conditional("DEBUG")] | |||
public static void Dump(string tag, byte[] arr, int length) | |||
{ | |||
var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); | |||
for (int i = 0; i < length - 1; i++) { | |||
sb.Append($"0x{arr[i]:X2}, "); | |||
} | |||
sb.Append($"0x{arr[length - 1]:X2}"); | |||
sb.Append(Environment.NewLine); | |||
Debug(sb.ToString()); | |||
} | |||
[Conditional("DEBUG")] | |||
public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null) | |||
{ | |||
if (header == null && tailer == null) | |||
Debug($"{local} => {remote} (size={len})"); | |||
else if (header == null && tailer != null) | |||
Debug($"{local} => {remote} (size={len}), {tailer}"); | |||
else if (header != null && tailer == null) | |||
Debug($"{header}: {local} => {remote} (size={len})"); | |||
else | |||
Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); | |||
} | |||
[Conditional("DEBUG")] | |||
public static void Debug(Socket sock, int len, string header = null, string tailer = null) | |||
{ | |||
Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); | |||
} | |||
public static void LogUsefulException(Exception e) | |||
{ | |||
// just log useful exceptions, not all of them | |||
if (e is SocketException) | |||
{ | |||
SocketException se = (SocketException)e; | |||
if (se.SocketErrorCode == SocketError.ConnectionAborted) | |||
{ | |||
// closed by browser when sending | |||
// normally happens when download is canceled or a tab is closed before page is loaded | |||
} | |||
else if (se.SocketErrorCode == SocketError.ConnectionReset) | |||
{ | |||
// received rst | |||
} | |||
else if (se.SocketErrorCode == SocketError.NotConnected) | |||
{ | |||
// The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected. | |||
} | |||
else if (se.SocketErrorCode == SocketError.HostUnreachable) | |||
{ | |||
// There is no network route to the specified host. | |||
} | |||
else if (se.SocketErrorCode == SocketError.TimedOut) | |||
{ | |||
// The connection attempt timed out, or the connected host has failed to respond. | |||
} | |||
else | |||
{ | |||
Info(e); | |||
} | |||
} | |||
else if (e is ObjectDisposedException) | |||
{ | |||
} | |||
else if (e is Win32Exception) | |||
{ | |||
var ex = (Win32Exception) e; | |||
// Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process. | |||
if ((uint) ex.ErrorCode != 0x80004005) | |||
{ | |||
Info(e); | |||
} | |||
} | |||
else if (e is ProxyException) | |||
{ | |||
var ex = (ProxyException)e; | |||
switch (ex.Type) | |||
{ | |||
case ProxyExceptionType.FailToRun: | |||
case ProxyExceptionType.QueryReturnMalformed: | |||
case ProxyExceptionType.SysproxyExitError: | |||
Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}"); | |||
break; | |||
case ProxyExceptionType.QueryReturnEmpty: | |||
case ProxyExceptionType.Unspecific: | |||
Error($"sysproxy - {ex.Type.ToString()}"); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
Info(e); | |||
} | |||
} | |||
} | |||
// Simply extended System.IO.StreamWriter for adding timestamp workaround | |||
public class StreamWriterWithTimestamp : StreamWriter | |||
{ | |||
public StreamWriterWithTimestamp(Stream stream) : base(stream) | |||
{ | |||
} | |||
private string GetTimestamp() | |||
{ | |||
return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] "; | |||
} | |||
public override void WriteLine(string value) | |||
{ | |||
base.WriteLine(GetTimestamp() + value); | |||
} | |||
public override void Write(string value) | |||
{ | |||
base.Write(GetTimestamp() + value); | |||
} | |||
} | |||
} |
@@ -9,6 +9,7 @@ using System.Net.Sockets; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util; | |||
@@ -18,6 +19,8 @@ namespace Shadowsocks.Controller | |||
public sealed class AvailabilityStatistics : IDisposable | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public const string DateTimePattern = "yyyy-MM-dd HH:mm:ss"; | |||
private const string StatisticsFilesName = "shadowsocks.availability.json"; | |||
public static string AvailabilityStatisticsFile; | |||
@@ -111,7 +114,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -155,7 +158,7 @@ namespace Shadowsocks.Controller | |||
inR.Add(inboundSpeed); | |||
outR.Add(outboundSpeed); | |||
Logging.Debug( | |||
logger.Debug( | |||
$"{id}: current/max inbound {inboundSpeed}/{inR.Max()} KiB/s, current/max outbound {outboundSpeed}/{outR.Max()} KiB/s"); | |||
} | |||
} | |||
@@ -213,7 +216,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.Debug("config changed asynchrously, just ignore this server"); | |||
logger.Debug("config changed asynchrously, just ignore this server"); | |||
} | |||
} | |||
@@ -235,7 +238,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
AppendRecord(server.Identifier(), record); | |||
} | |||
Logging.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms"); | |||
logger.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms"); | |||
if (Interlocked.Decrement(ref state.counter) == 0) | |||
{ | |||
Save(); | |||
@@ -260,13 +263,13 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
private void Save() | |||
{ | |||
Logging.Debug($"save statistics to {AvailabilityStatisticsFile}"); | |||
logger.Debug($"save statistics to {AvailabilityStatisticsFile}"); | |||
if (RawStatistics.Count == 0) | |||
{ | |||
return; | |||
@@ -283,7 +286,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (IOException e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -300,7 +303,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
try | |||
{ | |||
Logging.Debug("filter raw statistics"); | |||
logger.Debug("filter raw statistics"); | |||
if (RawStatistics == null) return; | |||
var filteredStatistics = new Statistics(); | |||
@@ -315,7 +318,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -324,7 +327,7 @@ namespace Shadowsocks.Controller | |||
try | |||
{ | |||
var path = AvailabilityStatisticsFile; | |||
Logging.Debug($"loading statistics from {path}"); | |||
logger.Debug($"loading statistics from {path}"); | |||
if (!File.Exists(path)) | |||
{ | |||
using (File.Create(path)) | |||
@@ -337,7 +340,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Console.WriteLine($"failed to load statistics; use runtime statistics, some data may be lost"); | |||
} | |||
} | |||
@@ -411,6 +414,8 @@ namespace Shadowsocks.Controller | |||
class MyPing | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
//arguments for ICMP tests | |||
public const int TimeoutMilliseconds = 500; | |||
@@ -445,7 +450,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
try | |||
{ | |||
Logging.Debug($"Ping {server.FriendlyName()}"); | |||
logger.Debug($"Ping {server.FriendlyName()}"); | |||
if (ip == null) | |||
{ | |||
ip = Dns.GetHostAddresses(server.server) | |||
@@ -461,8 +466,8 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||
Logging.LogUsefulException(e); | |||
logger.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||
logger.LogUsefulException(e); | |||
FireCompleted(e, userstate); | |||
} | |||
} | |||
@@ -473,20 +478,20 @@ namespace Shadowsocks.Controller | |||
{ | |||
if (e.Reply.Status == IPStatus.Success) | |||
{ | |||
Logging.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms"); | |||
logger.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms"); | |||
RoundtripTime.Add((int?)e.Reply.RoundtripTime); | |||
} | |||
else | |||
{ | |||
Logging.Debug($"Ping {server.FriendlyName()} timeout"); | |||
logger.Debug($"Ping {server.FriendlyName()} timeout"); | |||
RoundtripTime.Add(null); | |||
} | |||
TestNext(e.UserState); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||
Logging.LogUsefulException(ex); | |||
logger.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||
logger.LogUsefulException(ex); | |||
FireCompleted(ex, e.UserState); | |||
} | |||
} | |||
@@ -5,7 +5,7 @@ using System.Net; | |||
using System.Text; | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
@@ -14,6 +14,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
public class GFWListUpdater | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"; | |||
public event EventHandler<ResultEventArgs> UpdateCompleted; | |||
@@ -93,10 +95,10 @@ var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)}; | |||
string gfwListUrl = GFWLIST_URL; | |||
if (!string.IsNullOrWhiteSpace(config.gfwListUrl)) | |||
{ | |||
Logging.Info("Found custom GFWListURL in config file"); | |||
logger.Info("Found custom GFWListURL in config file"); | |||
gfwListUrl = config.gfwListUrl; | |||
} | |||
Logging.Info($"Checking GFWList from {gfwListUrl}"); | |||
logger.Info($"Checking GFWList from {gfwListUrl}"); | |||
WebClient http = new WebClient(); | |||
if (config.enabled) | |||
{ | |||
@@ -4,13 +4,15 @@ using System.Linq; | |||
using System.Net; | |||
using System.Net.NetworkInformation; | |||
using System.Net.Sockets; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
namespace Shadowsocks.Controller | |||
{ | |||
public class Listener | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public interface IService | |||
{ | |||
bool Handle(byte[] firstPacket, int length, Socket socket, object state); | |||
@@ -80,11 +82,8 @@ namespace Shadowsocks.Controller | |||
_tcpSocket.Listen(1024); | |||
// Start an asynchronous socket to listen for connections. | |||
Logging.Info($"Shadowsocks started ({UpdateChecker.Version})"); | |||
if (_config.isVerboseLogging) | |||
{ | |||
Logging.Info(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); | |||
} | |||
logger.Info($"Shadowsocks started ({UpdateChecker.Version})"); | |||
logger.Debug(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); | |||
_tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket); | |||
UDPState udpState = new UDPState(_udpSocket); | |||
_udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState); | |||
@@ -132,7 +131,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.Debug(ex); | |||
logger.Debug(ex); | |||
} | |||
finally | |||
{ | |||
@@ -171,7 +170,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
finally | |||
{ | |||
@@ -187,7 +186,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
} | |||
@@ -218,7 +217,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
conn.Close(); | |||
} | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using Shadowsocks.Properties; | |||
using NLog; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
using System; | |||
using System.Collections.Generic; | |||
@@ -15,6 +16,8 @@ namespace Shadowsocks.Controller | |||
/// </summary> | |||
public class PACDaemon | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public const string PAC_FILE = "pac.txt"; | |||
public const string USER_RULE_FILE = "user-rule.txt"; | |||
public const string USER_ABP_FILE = "abp.txt"; | |||
@@ -101,7 +104,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
if (PACFileChanged != null) | |||
{ | |||
Logging.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); | |||
logger.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); | |||
Task.Factory.StartNew(() => | |||
{ | |||
((FileSystemWatcher)sender).EnableRaisingEvents = false; | |||
@@ -116,7 +119,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
if (UserRuleFileChanged != null) | |||
{ | |||
Logging.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); | |||
logger.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); | |||
Task.Factory.StartNew(() => | |||
{ | |||
((FileSystemWatcher)sender).EnableRaisingEvents = false; | |||
@@ -6,11 +6,14 @@ using System.Net; | |||
using System.Net.Sockets; | |||
using System.Text; | |||
using System.Web; | |||
using NLog; | |||
namespace Shadowsocks.Controller | |||
{ | |||
public class PACServer : Listener.Service | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public const string RESOURCE_NAME = "pac"; | |||
private string PacSecret | |||
@@ -43,7 +46,7 @@ namespace Shadowsocks.Controller | |||
string usedSecret = _config.secureLocalPac ? $"&secret={PacSecret}" : ""; | |||
string contentHash = GetHash(_pacDaemon.GetPACContent()); | |||
PacUrl = $"http://{config.localHost}:{config.localPort}/{RESOURCE_NAME}?hash={contentHash}{usedSecret}"; | |||
Logging.Debug("Set PAC URL:" + PacUrl); | |||
logger.Debug("Set PAC URL:" + PacUrl); | |||
} | |||
private static string GetHash(string content) | |||
@@ -177,7 +180,7 @@ Connection: Close | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
socket.Close(); | |||
} | |||
} | |||
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.Net; | |||
using System.Net.Sockets; | |||
using NLog; | |||
using Shadowsocks.Util.Sockets; | |||
namespace Shadowsocks.Controller | |||
@@ -26,6 +27,8 @@ namespace Shadowsocks.Controller | |||
private class Handler | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private byte[] _firstPacket; | |||
private int _firstPacketLength; | |||
private Socket _local; | |||
@@ -58,7 +61,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -77,7 +80,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -94,7 +97,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -115,7 +118,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -142,7 +145,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -169,7 +172,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -188,7 +191,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -207,7 +210,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -239,7 +242,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
if (_remote != null) | |||
@@ -251,7 +254,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (SocketException e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
} | |||
@@ -6,6 +6,7 @@ using System.Net; | |||
using System.Net.Sockets; | |||
using System.Text; | |||
using System.Windows.Forms; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util; | |||
using Shadowsocks.Util.ProcessManagement; | |||
@@ -14,6 +15,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
class PrivoxyRunner | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private static int _uid; | |||
private static string _uniqueConfigFile; | |||
private static Job _privoxyJob; | |||
@@ -31,7 +34,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (IOException e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -104,7 +107,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -137,7 +140,7 @@ namespace Shadowsocks.Controller | |||
* are already dead, and that will cause exceptions here. | |||
* We could simply ignore those exceptions. | |||
*/ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
return false; | |||
} | |||
} | |||
@@ -157,7 +160,7 @@ namespace Shadowsocks.Controller | |||
catch (Exception e) | |||
{ | |||
// in case access denied | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return defaultPort; | |||
} | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using System; | |||
using NLog; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Net; | |||
@@ -17,6 +18,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
class TCPRelay : Listener.Service | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private ShadowsocksController _controller; | |||
private DateTime _lastSweepTime; | |||
private Configuration _config; | |||
@@ -54,7 +56,7 @@ namespace Shadowsocks.Controller | |||
} | |||
foreach (TCPHandler handler1 in handlersToClose) | |||
{ | |||
Logging.Debug("Closing timed out TCP connection."); | |||
logger.Debug("Closing timed out TCP connection."); | |||
handler1.Close(); | |||
} | |||
@@ -122,6 +124,8 @@ namespace Shadowsocks.Controller | |||
} | |||
} | |||
private static Logger Logger = LogManager.GetCurrentClassLogger(); | |||
private readonly int _serverTimeout; | |||
private readonly int _proxyTimeout; | |||
@@ -217,7 +221,7 @@ namespace Shadowsocks.Controller | |||
this._server = server; | |||
/* prepare address buffer length for AEAD */ | |||
Logging.Debug($"_addrBufLength={_addrBufLength}"); | |||
Logger.Debug($"_addrBufLength={_addrBufLength}"); | |||
_encryptor.AddrBufLength = _addrBufLength; | |||
} | |||
@@ -252,7 +256,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
} | |||
if (_currentRemoteSession != null) | |||
@@ -265,7 +269,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -291,7 +295,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
// reject socks 4 | |||
response = new byte[] { 0, 91 }; | |||
Logging.Error("socks 5 protocol error"); | |||
Logger.Error("socks 5 protocol error"); | |||
} | |||
_connection.BeginSend(response, 0, response.Length, SocketFlags.None, | |||
HandshakeSendCallback, null); | |||
@@ -301,7 +305,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -326,7 +330,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -358,21 +362,21 @@ namespace Shadowsocks.Controller | |||
break; | |||
case CMD_BIND: // not implemented | |||
default: | |||
Logging.Debug("Unsupported CMD=" + _command); | |||
Logger.Debug("Unsupported CMD=" + _command); | |||
Close(); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
Logging.Debug( | |||
Logger.Debug( | |||
"failed to recv data in Shadowsocks.Controller.TCPHandler.handshakeReceive2Callback()"); | |||
Close(); | |||
} | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -387,7 +391,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -409,7 +413,7 @@ namespace Shadowsocks.Controller | |||
ReadAddress(16 + ADDR_PORT_LEN - 1, onSuccess); | |||
break; | |||
default: | |||
Logging.Debug("Unsupported ATYP=" + atyp); | |||
Logger.Debug("Unsupported ATYP=" + atyp); | |||
Close(); | |||
break; | |||
} | |||
@@ -468,10 +472,7 @@ namespace Shadowsocks.Controller | |||
break; | |||
} | |||
if (_config.isVerboseLogging) | |||
{ | |||
Logging.Info($"connect to {dstAddr}:{dstPort}"); | |||
} | |||
Logger.Debug($"connect to {dstAddr}:{dstPort}"); | |||
_destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort); | |||
@@ -479,13 +480,13 @@ namespace Shadowsocks.Controller | |||
} | |||
else | |||
{ | |||
Logging.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()"); | |||
Logger.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()"); | |||
Close(); | |||
} | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -537,7 +538,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -631,7 +632,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -650,7 +651,7 @@ namespace Shadowsocks.Controller | |||
} | |||
var proxy = timer.Session.Remote; | |||
Logging.Info($"Proxy {proxy.ProxyEndPoint} timed out"); | |||
Logger.Info($"Proxy {proxy.ProxyEndPoint} timed out"); | |||
proxy.Close(); | |||
Close(); | |||
} | |||
@@ -678,12 +679,9 @@ namespace Shadowsocks.Controller | |||
_proxyConnected = true; | |||
if (_config.isVerboseLogging) | |||
if (!(remote is DirectConnect)) | |||
{ | |||
if (!(remote is DirectConnect)) | |||
{ | |||
Logging.Info($"Socket connected to proxy {remote.ProxyEndPoint}"); | |||
} | |||
Logger.Debug($"Socket connected to proxy {remote.ProxyEndPoint}"); | |||
} | |||
_startConnectTime = DateTime.Now; | |||
@@ -710,7 +708,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -731,7 +729,7 @@ namespace Shadowsocks.Controller | |||
Server server = timer.Server; | |||
IStrategy strategy = _controller.GetCurrentStrategy(); | |||
strategy?.SetFailure(server); | |||
Logging.Info($"{server.FriendlyName()} timed out"); | |||
Logger.Info($"{server.FriendlyName()} timed out"); | |||
session.Remote.Close(); | |||
Close(); | |||
} | |||
@@ -754,10 +752,7 @@ namespace Shadowsocks.Controller | |||
_destConnected = true; | |||
if (_config.isVerboseLogging) | |||
{ | |||
Logging.Info($"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(); | |||
@@ -776,7 +771,7 @@ namespace Shadowsocks.Controller | |||
IStrategy strategy = _controller.GetCurrentStrategy(); | |||
strategy?.SetFailure(_server); | |||
} | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -803,12 +798,12 @@ namespace Shadowsocks.Controller | |||
PipeRemoteReceiveCallback, session); | |||
TryReadAvailableData(); | |||
Logging.Debug($"_firstPacketLength = {_firstPacketLength}"); | |||
Logger.Debug($"_firstPacketLength = {_firstPacketLength}"); | |||
SendToServer(_firstPacketLength, session); | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -834,7 +829,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (CryptoErrorException) | |||
{ | |||
Logging.Error("decryption error"); | |||
Logger.Error("decryption error"); | |||
Close(); | |||
return; | |||
} | |||
@@ -842,12 +837,12 @@ namespace Shadowsocks.Controller | |||
if (bytesToSend == 0) | |||
{ | |||
// need more to decrypt | |||
Logging.Debug("Need more to decrypt"); | |||
Logger.Debug("Need more to decrypt"); | |||
session.Remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, | |||
PipeRemoteReceiveCallback, session); | |||
return; | |||
} | |||
Logging.Debug($"start sending {bytesToSend}"); | |||
Logger.Debug($"start sending {bytesToSend}"); | |||
_connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, | |||
PipeConnectionSendCallback, new object[] { session, bytesToSend }); | |||
IStrategy strategy = _controller.GetCurrentStrategy(); | |||
@@ -862,7 +857,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -890,7 +885,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -907,7 +902,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (CryptoErrorException) | |||
{ | |||
Logging.Debug("encryption error"); | |||
Logger.Debug("encryption error"); | |||
Close(); | |||
return; | |||
} | |||
@@ -932,7 +927,7 @@ namespace Shadowsocks.Controller | |||
int bytesRemaining = bytesShouldSend - bytesSent; | |||
if (bytesRemaining > 0) | |||
{ | |||
Logging.Info("reconstruct _connetionSendBuffer to re-send"); | |||
Logger.Info("reconstruct _connetionSendBuffer to re-send"); | |||
Buffer.BlockCopy(_connetionSendBuffer, bytesSent, _connetionSendBuffer, 0, bytesRemaining); | |||
session.Remote.BeginSend(_connetionSendBuffer, 0, bytesRemaining, SocketFlags.None, | |||
PipeRemoteSendCallback, new object[] { session, bytesRemaining }); | |||
@@ -943,7 +938,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -960,7 +955,7 @@ namespace Shadowsocks.Controller | |||
var bytesRemaining = bytesShouldSend - bytesSent; | |||
if (bytesRemaining > 0) | |||
{ | |||
Logging.Info("reconstruct _remoteSendBuffer to re-send"); | |||
Logger.Info("reconstruct _remoteSendBuffer to re-send"); | |||
Buffer.BlockCopy(_remoteSendBuffer, bytesSent, _remoteSendBuffer, 0, bytesRemaining); | |||
_connection.BeginSend(_remoteSendBuffer, 0, bytesRemaining, SocketFlags.None, | |||
PipeConnectionSendCallback, new object[] { session, bytesRemaining }); | |||
@@ -971,7 +966,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
Logger.LogUsefulException(e); | |||
Close(); | |||
} | |||
} | |||
@@ -3,6 +3,7 @@ using System.Collections.Generic; | |||
using System.Net; | |||
using System.Net.Sockets; | |||
using System.Runtime.CompilerServices; | |||
using NLog; | |||
using Shadowsocks.Controller.Strategy; | |||
using Shadowsocks.Encryption; | |||
using Shadowsocks.Model; | |||
@@ -49,6 +50,8 @@ namespace Shadowsocks.Controller | |||
public class UDPHandler | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private Socket _local; | |||
private Socket _remote; | |||
@@ -98,14 +101,14 @@ namespace Shadowsocks.Controller | |||
byte[] dataOut = new byte[65536]; // enough space for AEAD ciphers | |||
int outlen; | |||
encryptor.EncryptUDP(dataIn, length - 3, dataOut, out outlen); | |||
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); | |||
logger.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); | |||
_remote?.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint); | |||
} | |||
public void Receive() | |||
{ | |||
EndPoint remoteEndPoint = new IPEndPoint(GetIPAddress(), 0); | |||
Logging.Debug($"++++++Receive Server Port, size:" + _buffer.Length); | |||
logger.Debug($"++++++Receive Server Port, size:" + _buffer.Length); | |||
_remote?.BeginReceiveFrom(_buffer, 0, _buffer.Length, 0, ref remoteEndPoint, new AsyncCallback(RecvFromCallback), null); | |||
} | |||
@@ -126,7 +129,7 @@ namespace Shadowsocks.Controller | |||
byte[] sendBuf = new byte[outlen + 3]; | |||
Array.Copy(dataOut, 0, sendBuf, 3, outlen); | |||
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); | |||
logger.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); | |||
_local?.SendTo(sendBuf, outlen + 3, 0, _localEndPoint); | |||
Receive(); | |||
@@ -4,7 +4,7 @@ using System.Net; | |||
using System.Text.RegularExpressions; | |||
using Newtonsoft.Json.Linq; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util; | |||
@@ -12,6 +12,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
public class UpdateChecker | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases"; | |||
private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"; | |||
@@ -60,14 +62,14 @@ namespace Shadowsocks.Controller | |||
try | |||
{ | |||
Logging.Debug("Checking updates..."); | |||
logger.Debug("Checking updates..."); | |||
WebClient http = CreateWebClient(); | |||
http.DownloadStringCompleted += http_DownloadStringCompleted; | |||
http.DownloadStringAsync(new Uri(UpdateURL)); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
} | |||
} | |||
@@ -117,7 +119,7 @@ namespace Shadowsocks.Controller | |||
} | |||
else | |||
{ | |||
Logging.Debug("No update is available"); | |||
logger.Debug("No update is available"); | |||
if (CheckUpdateCompleted != null) | |||
{ | |||
CheckUpdateCompleted(this, new EventArgs()); | |||
@@ -126,7 +128,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
} | |||
} | |||
@@ -141,7 +143,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
} | |||
} | |||
@@ -151,10 +153,10 @@ namespace Shadowsocks.Controller | |||
{ | |||
if (e.Error != null) | |||
{ | |||
Logging.LogUsefulException(e.Error); | |||
logger.LogUsefulException(e.Error); | |||
return; | |||
} | |||
Logging.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); | |||
logger.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); | |||
if (CheckUpdateCompleted != null) | |||
{ | |||
CheckUpdateCompleted(this, new EventArgs()); | |||
@@ -162,7 +164,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
} | |||
} | |||
@@ -9,7 +9,7 @@ using System.Text; | |||
using System.Threading; | |||
using System.Web; | |||
using System.Windows.Forms; | |||
using NLog; | |||
using Shadowsocks.Controller.Service; | |||
using Shadowsocks.Controller.Strategy; | |||
using Shadowsocks.Model; | |||
@@ -19,6 +19,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
public class ShadowsocksController | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
// controller: | |||
// handle user actions | |||
// manipulates UI | |||
@@ -52,6 +54,12 @@ namespace Shadowsocks.Controller | |||
public string Path; | |||
} | |||
public class UpdatedEventArgs : EventArgs | |||
{ | |||
public string OldVersion; | |||
public string NewVersion; | |||
} | |||
public class TrafficPerSecond | |||
{ | |||
public long inboundCounter; | |||
@@ -78,6 +86,9 @@ namespace Shadowsocks.Controller | |||
public event ErrorEventHandler Errored; | |||
// Invoked when controller.Start(); | |||
public event EventHandler<UpdatedEventArgs> ProgramUpdated; | |||
public ShadowsocksController() | |||
{ | |||
_config = Configuration.Load(); | |||
@@ -86,10 +97,25 @@ namespace Shadowsocks.Controller | |||
_pluginsByServer = new ConcurrentDictionary<Server, Sip003Plugin>(); | |||
StartReleasingMemory(); | |||
StartTrafficStatistics(61); | |||
ProgramUpdated += (o, e) => | |||
{ | |||
logger.Info($"Updated from {e.OldVersion} to {e.NewVersion}"); | |||
}; | |||
} | |||
public void Start(bool regHotkeys = true) | |||
{ | |||
if (_config.updated && regHotkeys) | |||
{ | |||
_config.updated = false; | |||
ProgramUpdated.Invoke(this, new UpdatedEventArgs() | |||
{ | |||
OldVersion = _config.version, | |||
NewVersion = UpdateChecker.Version, | |||
}); | |||
Configuration.Save(_config); | |||
} | |||
Reload(); | |||
if (regHotkeys) | |||
{ | |||
@@ -165,13 +191,13 @@ namespace Shadowsocks.Controller | |||
{ | |||
if (plugin.StartIfNeeded()) | |||
{ | |||
Logging.Info( | |||
logger.Info( | |||
$"Started SIP003 plugin for {server.Identifier()} on {plugin.LocalEndPoint} - PID: {plugin.ProcessId}"); | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.Error("Failed to start SIP003 plugin: " + ex.Message); | |||
logger.Error("Failed to start SIP003 plugin: " + ex.Message); | |||
throw; | |||
} | |||
@@ -213,7 +239,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return false; | |||
} | |||
} | |||
@@ -252,6 +278,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
_config.isVerboseLogging = enabled; | |||
SaveConfig(_config); | |||
NLogConfig.LoadConfiguration(); // reload nlog | |||
VerboseLoggingStatusChanged?.Invoke(this, new EventArgs()); | |||
} | |||
@@ -475,6 +502,9 @@ namespace Shadowsocks.Controller | |||
Encryption.RNG.Reload(); | |||
// some logic in configuration updated the config when saving, we need to read it again | |||
_config = Configuration.Load(); | |||
NLogConfig.LoadConfiguration(); | |||
StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | |||
privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); | |||
@@ -533,7 +563,7 @@ namespace Shadowsocks.Controller | |||
e = new Exception(I18N.GetString("Port {0} is reserved by system", _config.localPort), e); | |||
} | |||
} | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
ReportError(e); | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using Shadowsocks.Model; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Net; | |||
@@ -8,6 +9,8 @@ namespace Shadowsocks.Controller.Strategy | |||
{ | |||
class HighAvailabilityStrategy : IStrategy | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
protected ServerStatus _currentServer; | |||
protected Dictionary<Server, ServerStatus> _serverStatus; | |||
ShadowsocksController _controller; | |||
@@ -111,7 +114,7 @@ namespace Shadowsocks.Controller.Strategy | |||
100 * 1000 * Math.Min(5 * 60, (now - status.lastFailure).TotalSeconds) | |||
-2 * 5 * (Math.Min(2000, status.latency.TotalMilliseconds) / (1 + (now - status.lastTimeDetectLatency).TotalSeconds / 30 / 10) + | |||
-0.5 * 200 * Math.Min(5, (status.lastRead - status.lastWrite).TotalSeconds)); | |||
Logging.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score)); | |||
logger.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score)); | |||
} | |||
ServerStatus max = null; | |||
foreach (var status in servers) | |||
@@ -133,14 +136,14 @@ namespace Shadowsocks.Controller.Strategy | |||
if (_currentServer == null || max.score - _currentServer.score > 200) | |||
{ | |||
_currentServer = max; | |||
Logging.Info($"HA switching to server: {_currentServer.server.FriendlyName()}"); | |||
logger.Info($"HA switching to server: {_currentServer.server.FriendlyName()}"); | |||
} | |||
} | |||
} | |||
public void UpdateLatency(Model.Server server, TimeSpan latency) | |||
{ | |||
Logging.Debug($"latency: {server.FriendlyName()} {latency}"); | |||
logger.Debug($"latency: {server.FriendlyName()} {latency}"); | |||
ServerStatus status; | |||
if (_serverStatus.TryGetValue(server, out status)) | |||
@@ -152,7 +155,7 @@ namespace Shadowsocks.Controller.Strategy | |||
public void UpdateLastRead(Model.Server server) | |||
{ | |||
Logging.Debug($"last read: {server.FriendlyName()}"); | |||
logger.Debug($"last read: {server.FriendlyName()}"); | |||
ServerStatus status; | |||
if (_serverStatus.TryGetValue(server, out status)) | |||
@@ -163,7 +166,7 @@ namespace Shadowsocks.Controller.Strategy | |||
public void UpdateLastWrite(Model.Server server) | |||
{ | |||
Logging.Debug($"last write: {server.FriendlyName()}"); | |||
logger.Debug($"last write: {server.FriendlyName()}"); | |||
ServerStatus status; | |||
if (_serverStatus.TryGetValue(server, out status)) | |||
@@ -174,7 +177,7 @@ namespace Shadowsocks.Controller.Strategy | |||
public void SetFailure(Model.Server server) | |||
{ | |||
Logging.Debug($"failure: {server.FriendlyName()}"); | |||
logger.Debug($"failure: {server.FriendlyName()}"); | |||
ServerStatus status; | |||
if (_serverStatus.TryGetValue(server, out status)) | |||
@@ -5,7 +5,7 @@ using System.Net; | |||
using System.Threading; | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
namespace Shadowsocks.Controller.Strategy | |||
@@ -14,6 +14,8 @@ namespace Shadowsocks.Controller.Strategy | |||
internal class StatisticsStrategy : IStrategy, IDisposable | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private readonly ShadowsocksController _controller; | |||
private Server _currentServer; | |||
private readonly Timer _timer; | |||
@@ -34,7 +36,7 @@ namespace Shadowsocks.Controller.Strategy | |||
private void ReloadStatisticsAndChooseAServer(object obj) | |||
{ | |||
Logging.Debug("Reloading statistics and choose a new server...."); | |||
logger.Debug("Reloading statistics and choose a new server...."); | |||
var servers = _controller.GetCurrentConfiguration().configs; | |||
LoadStatistics(); | |||
ChooseNewServer(servers); | |||
@@ -74,7 +76,7 @@ namespace Shadowsocks.Controller.Strategy | |||
if (score != null) | |||
{ | |||
Logging.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}"); | |||
logger.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}"); | |||
} | |||
return score; | |||
} | |||
@@ -112,7 +114,7 @@ namespace Shadowsocks.Controller.Strategy | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -145,7 +147,7 @@ namespace Shadowsocks.Controller.Strategy | |||
public void SetFailure(Server server) | |||
{ | |||
Logging.Debug($"failure: {server.FriendlyName()}"); | |||
logger.Debug($"failure: {server.FriendlyName()}"); | |||
} | |||
public void UpdateLastRead(Server server) | |||
@@ -5,12 +5,15 @@ using System.Reflection; | |||
using System.Runtime.InteropServices; | |||
using System.Windows.Forms; | |||
using Microsoft.Win32; | |||
using NLog; | |||
using Shadowsocks.Util; | |||
namespace Shadowsocks.Controller | |||
{ | |||
static class AutoStartup | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
// Don't use Application.ExecutablePath | |||
// see https://stackoverflow.com/questions/12945805/odd-c-sharp-path-issue | |||
private static readonly string ExecutablePath = Assembly.GetEntryAssembly().Location; | |||
@@ -25,7 +28,7 @@ namespace Shadowsocks.Controller | |||
runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); | |||
if (runKey == null) | |||
{ | |||
Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); | |||
logger.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); | |||
return false; | |||
} | |||
if (enabled) | |||
@@ -42,7 +45,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return false; | |||
} | |||
finally | |||
@@ -55,7 +58,7 @@ namespace Shadowsocks.Controller | |||
runKey.Dispose(); | |||
} | |||
catch (Exception e) | |||
{ Logging.LogUsefulException(e); } | |||
{ logger.LogUsefulException(e); } | |||
} | |||
} | |||
} | |||
@@ -68,7 +71,7 @@ namespace Shadowsocks.Controller | |||
runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); | |||
if (runKey == null) | |||
{ | |||
Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); | |||
logger.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); | |||
return false; | |||
} | |||
string[] runList = runKey.GetValueNames(); | |||
@@ -91,7 +94,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return false; | |||
} | |||
finally | |||
@@ -104,7 +107,7 @@ namespace Shadowsocks.Controller | |||
runKey.Dispose(); | |||
} | |||
catch (Exception e) | |||
{ Logging.LogUsefulException(e); } | |||
{ logger.LogUsefulException(e); } | |||
} | |||
} | |||
} | |||
@@ -140,13 +143,13 @@ namespace Shadowsocks.Controller | |||
// first parameter is process command line parameter | |||
// needn't include the name of the executable in the command line | |||
RegisterApplicationRestart(cmdline, (int)(ApplicationRestartFlags.RESTART_NO_CRASH | ApplicationRestartFlags.RESTART_NO_HANG)); | |||
Logging.Debug("Register restart after system reboot, command line:" + cmdline); | |||
logger.Debug("Register restart after system reboot, command line:" + cmdline); | |||
} | |||
// requested unregister, which has no side effect | |||
else if (!register) | |||
{ | |||
UnregisterApplicationRestart(); | |||
Logging.Debug("Unregister restart after system reboot"); | |||
logger.Debug("Unregister restart after system reboot"); | |||
} | |||
} | |||
} | |||
@@ -1,5 +1,6 @@ | |||
using System; | |||
using System.Windows.Forms; | |||
using NLog; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util.SystemProxy; | |||
@@ -7,6 +8,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
public static class SystemProxy | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private static string GetTimestamp(DateTime value) | |||
{ | |||
return value.ToString("yyyyMMddHHmmssfff"); | |||
@@ -52,7 +55,7 @@ namespace Shadowsocks.Controller | |||
} | |||
catch (ProxyException ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
if (ex.Type != ProxyExceptionType.Unspecific && !noRetry) | |||
{ | |||
var ret = MessageBox.Show(I18N.GetString("Error occured when process proxy setting, do you want reset current setting and retry?"), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning); | |||
@@ -0,0 +1,13 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<!-- Warning: Configuration may reset after shadowsocks upgrade. --> | |||
<!-- If you messed it up, delete this file and Shadowsocks will create a new one. --> | |||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |||
<targets> | |||
<!-- This line is managed by Shadowsocks. Do not modify it unless you know what you are doing.--> | |||
<target name="file" xsi:type="File" fileName="ss_win_temp\shadowsocks.log" writeBom="false" encoding="utf-8"/> | |||
</targets> | |||
<rules> | |||
<!-- This line is managed by Shadowsocks. Do not modify it unless you know what you are doing. --> | |||
<logger name="*" minlevel="Info" writeTo="file"/> | |||
</rules> | |||
</nlog> |
@@ -1,207 +1,209 @@ | |||
en,zh-CN,zh-TW,ja | |||
#Restart program to apply translation,,, | |||
#This is comment line,,, | |||
#Always keep language name at head of file,,, | |||
#Language name is output in log,,, | |||
"#You can find it by search ""Current language is:""",,, | |||
#Please use UTF-8 with BOM encoding so we can edit it in Excel,,, | |||
,,, | |||
Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks | |||
,,, | |||
#Menu,,, | |||
,,, | |||
System Proxy,系统代理,系統代理,システムプロキシ | |||
Disable,禁用,禁用,無効 | |||
PAC,PAC 模式,PAC 模式,PAC | |||
Global,全局模式,全局模式,全般 | |||
Servers,服务器,伺服器,サーバー | |||
Edit Servers...,编辑服务器...,編輯伺服器...,サーバーの編集... | |||
Statistics Config...,统计配置...,統計設定檔...,統計情報の設定... | |||
Start on Boot,开机启动,開機啟動,システムと同時に起動 | |||
Forward Proxy...,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定... | |||
Allow other Devices to connect,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する | |||
Local PAC,使用本地 PAC,使用本機 PAC,ローカル PAC | |||
Online PAC,使用在线 PAC,使用線上 PAC,オンライン PAC | |||
Edit Local PAC File...,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集... | |||
Update Local PAC from GFWList,从 GFWList 更新本地 PAC,從 GFWList 更新本機 PAC,GFWList からローカル PAC を更新 | |||
Edit User Rule for GFWList...,编辑 GFWList 的用户规则...,編輯 GFWList 的使用者規則...,ユーザールールの編集... | |||
Secure Local PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護 | |||
Copy Local PAC URL,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー | |||
Share Server Config...,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有... | |||
Scan QRCode from Screen...,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン... | |||
Import URL from Clipboard...,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート... | |||
Availability Statistics,统计可用性,統計可用性,可用性の統計 | |||
Show Logs...,显示日志...,顯示記錄檔...,ログの表示... | |||
Verbose Logging,详细记录日志,詳細資訊記錄,詳細なログを記録 | |||
Updates...,更新...,更新...,更新... | |||
Check for Updates...,检查更新,檢查更新,更新プログラムの確認... | |||
Check for Updates at Startup,启动时检查更新,啟動時檢查更新,起動時に更新プログラムを確認 | |||
Check Pre-release Version,检查测试版更新,檢查發行前版本更新,先行開発版も確認 | |||
Edit Hotkeys...,编辑快捷键...,編輯快速鍵...,ホットキーの編集... | |||
About...,关于...,關於...,Shadowsocks について... | |||
Help,帮助,說明,ヘルプ | |||
Quit,退出,結束,終了 | |||
Edit Servers,编辑服务器,編輯伺服器,サーバーの編集 | |||
Load Balance,负载均衡,負載平衡,負荷分散 | |||
High Availability,高可用,高可用性,高可用性 | |||
Choose by statistics,根据统计,根據統計,統計で選ぶ | |||
Show Plugin Output,显示插件输出,, | |||
Write translation template,写入翻译模板,, | |||
,,, | |||
# Config Form,,, | |||
,,, | |||
&Add,添加(&A),新增 (&A),新規 (&A) | |||
&Delete,删除(&D),移除 (&D),削除 (&D) | |||
Dupli&cate,复制(&C),複製 (&C),コピー (&C) | |||
Server,服务器,伺服器,サーバー | |||
Server IP,服务器地址,伺服器位址,サーバーアドレス | |||
Server Port,服务器端口,伺服器連接埠,サーバーポート | |||
Password,密码,密碼,パスワード | |||
Show Password,显示密码,顯示密碼,パスワードを表示する | |||
Encryption,加密,加密,暗号化 | |||
Plugin Program,插件程序,外掛程式,プラグインプログラム | |||
Plugin Options,插件选项,外掛程式選項,プラグインのオプション | |||
Need Plugin Argument,需要命令行参数,, | |||
Plugin Arguments,插件参数,外掛程式參數,プラグインの引数 | |||
Proxy Port,代理端口,Proxy 連接埠,プロキシポート | |||
Portable Mode,便携模式,便攜模式,ポータブルモード | |||
Restart required,需要重新启动SS,需要重新啟動SS,再起動SSが必要 | |||
Remarks,备注,註解,付記 | |||
Timeout(Sec),超时(秒),逾時 (秒),タイムアウト (秒) | |||
OK,确定,確定,OK | |||
Cancel,取消,取消,キャンセル | |||
Apply,应用,應用,適用 | |||
New server,未配置的服务器,新伺服器,新規サーバー | |||
Move &Up,上移(&U),上移 (&U),上に移動 (&U) | |||
Move D&own,下移(&O),下移 (&O),下に移動 (&O) | |||
,,, | |||
#Statistics Config,,, | |||
,,, | |||
Enable Statistics,启用统计,, | |||
Ping Test,Ping测试,, | |||
packages everytime,个包/次,, | |||
By hour of day,按照每天的小时数统计,, | |||
Collect data per,收集数据每,, | |||
Keep choice for,保持选择每,, | |||
minutes,分钟,, | |||
Final Score:,总分:,, | |||
AverageLatency,平均延迟,, | |||
MinLatency,最小延迟,, | |||
MaxLatency,最大延迟,, | |||
AverageInboundSpeed,平均入站速度,, | |||
MinInboundSpeed,最小入站速度,, | |||
MaxInboundSpeed,最大入站速度,, | |||
AverageOutboundSpeed,平均出站速度,, | |||
MinOutboundSpeed,最小出站速度,, | |||
MaxOutboundSpeed,最大出站速度,, | |||
AverageResponse,平均响应速度,, | |||
MinResponse,最小响应速度,, | |||
MaxResponse,最大响应速度,, | |||
PackageLoss,丢包率,, | |||
Speed,速度,, | |||
Package Loss,丢包率,, | |||
Ping,网络延迟,, | |||
Chart Mode,图表模式,, | |||
24h,24小时,, | |||
all,全部,, | |||
,,, | |||
# Proxy Form,,, | |||
,,, | |||
Edit Proxy,代理设置,編輯 Proxy,プロキシの編集 | |||
Use Proxy,使用代理,使用 Proxy,プロキシを利用する | |||
Proxy Type,代理类型,Proxy 類型,プロキシの種類 | |||
Proxy Addr,代理地址,Proxy 位址,プロキシアドレス | |||
Proxy Port,代理端口,Proxy 連接埠,プロキシポート | |||
"If server has a plugin, proxy will not be used",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません | |||
Use Auth,使用认证,使用認證,認証を利用する | |||
User Name,用户名,認證用戶,認証ユーザ | |||
Auth Pwd,认证密码,認證口令,認証パスワード | |||
,,, | |||
# Log Form,,, | |||
,,, | |||
&File,文件(&F),檔案 (&F),ファイル (&F) | |||
&Open Location,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O) | |||
E&xit,退出(&X),結束 (&X),終了 (&X) | |||
&View,视图(&V),檢視 (&V),表示 (&V) | |||
&Clear Logs,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C) | |||
Change &Font,设置字体(&F),變更字型 (&F),フォント (&F) | |||
&Wrap Text,自动换行(&W),自動換行 (&W),右端で折り返す (&W) | |||
&Top Most,置顶(&T),置頂 (&T),常に最前面に表示 (&T) | |||
&Show Toolbar,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S) | |||
Log Viewer,日志查看器,記錄檔檢視器,ログビューア | |||
Inbound,入站,輸入,受信 | |||
Outbound,出站,輸出,送信 | |||
,,, | |||
# QRCode Form,,, | |||
,,, | |||
QRCode and URL,二维码与 URL,QR 碼與 URL,QR コードと URL | |||
,,, | |||
# PAC Url Form,,, | |||
,,, | |||
Edit Online PAC URL,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集 | |||
Edit Online PAC URL...,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集... | |||
Please input PAC Url,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい | |||
,,, | |||
# HotkeySettings Form,,, | |||
,,, | |||
Switch system proxy,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える | |||
Switch system proxy mode,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える | |||
Allow Clients from LAN,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える | |||
Show Logs...,显示日志,顯示記錄檔,ログの表示 | |||
Switch to previous server,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える | |||
Switch to next server,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える | |||
Reg All,注册全部快捷键,註冊所有快速鍵,全部登録する | |||
Reg Hotkeys At Startup,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する | |||
,,, | |||
# Messages,,, | |||
,,, | |||
Shadowsocks Error: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0} | |||
Port {0} already in use,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。 | |||
Port {0} is reserved by system,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています | |||
Invalid server address,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。 | |||
Illegal port number format,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。 | |||
Illegal timeout format,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。 | |||
Server IP can not be blank,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。 | |||
Password can not be blank,密码不能为空,密碼不能為空,パスワードが指定されていません。 | |||
Port out of range,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。 | |||
Port can't be 8123,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。 | |||
Shadowsocks {0} Update Found,Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。 | |||
No update is available,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。 | |||
Click here to update,点击这里升级,點按此處升級,クリックしてアップデートします。 | |||
Shadowsocks is here,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。 | |||
You can turn on/off Shadowsocks in the context menu,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。 | |||
System Proxy Enabled,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。 | |||
System Proxy Disabled,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。 | |||
Failed to update PAC file ,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。 | |||
PAC updated,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。 | |||
No updates found. Please report to GFWList if you have problems with it.,未发现更新。如有问题请提交给 GFWList。,未發現更新。如有問題請報告至 GFWList。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。 | |||
No QRCode found. Try to zoom in or move it to the center of the screen.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。 | |||
Shadowsocks is already running.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中 | |||
Find Shadowsocks icon in your notify tray.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。 | |||
"If you want to start multiple Shadowsocks, make a copy in another directory.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。 | |||
Failed to decode QRCode,无法解析二维码,QR 碼解碼失敗,QR コードの読み取りに失敗しました。 | |||
Failed to update registry,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。 | |||
System Proxy On: ,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効: | |||
Running: Port {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0} | |||
"Unexpected error, shadowsocks will exit. Please report to",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい: | |||
"Unsupported operating system, use Windows Vista at least.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。 | |||
"Unsupported .NET Framework, please update to {0} or later.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。 | |||
Proxy request failed,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。 | |||
Proxy handshake failed,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。 | |||
Register hotkey failed,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。 | |||
Cannot parse hotkey: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0} | |||
"Timeout is invalid, it should not exceed {0}",超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。 | |||
Cannot find the plugin program file,找不到插件程序文件,找不到外掛程式文件, | |||
,,, | |||
Operation failure,操作失败,, | |||
Auto save failed,自动保存失败,, | |||
Whether to discard unconfigured servers,是否丢弃未配置的服务器,, | |||
"Invalid server address, Cannot automatically save or discard changes",非法服务器地址,无法自动保存,是否丢弃修改,, | |||
"Illegal port number format, Cannot automatically save or discard changes",非法端口格式,无法自动保存,是否丢弃修改,, | |||
"Password can not be blank, Cannot automatically save or discard changes",密码不能为空,无法自动保存,是否丢弃修改,, | |||
"Illegal timeout format, Cannot automatically save or discard changes",非法超时格式,无法自动保存,是否丢弃修改,, | |||
,,, | |||
"Error occured when process proxy setting, do you want reset current setting and retry?",处理代理设置时发生错误,是否重置当前代理设置并重试?,, | |||
"Unrecoverable proxy setting error occured, see log for detail",发生不可恢复的代理设置错误,查看日志以取得详情,, | |||
Auth user can not be blank,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。 | |||
Auth pwd can not be blank,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。 | |||
en,ru-RU,zh-CN,zh-TW,ja | |||
#Restart program to apply translation,,,, | |||
#This is comment line,,,, | |||
#Always keep language name at head of file,,,, | |||
#Language name is output in log,,,, | |||
"#You can find it by search ""Current language is:""",,,, | |||
#Please use UTF-8 with BOM encoding so we can edit it in Excel,,,, | |||
,,,, | |||
Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks | |||
,,,, | |||
#Menu,,,, | |||
,,,, | |||
System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ | |||
Disable,Отключен,禁用,禁用,無効 | |||
PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PAC | |||
Global,Для всей системы,全局模式,全局模式,全般 | |||
Servers,Серверы,服务器,伺服器,サーバー | |||
Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集... | |||
Statistics Config...,Настройки статистики…,统计配置...,統計設定檔...,統計情報の設定... | |||
Start on Boot,Автозагрузка,开机启动,開機啟動,システムと同時に起動 | |||
Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定... | |||
Allow other Devices to connect,Общий доступ к подключению,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する | |||
Local PAC,Локальный PAC,使用本地 PAC,使用本機 PAC,ローカル PAC | |||
Online PAC,Удаленный PAC,使用在线 PAC,使用線上 PAC,オンライン PAC | |||
Edit Local PAC File...,Редактировать локальный PAC…,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集... | |||
Update Local PAC from GFWList,Обновить локальный PAC из GFWList,从 GFWList 更新本地 PAC,從 GFWList 更新本機 PAC,GFWList からローカル PAC を更新 | |||
Edit User Rule for GFWList...,Редактировать свои правила для GFWList,编辑 GFWList 的用户规则...,編輯 GFWList 的使用者規則...,ユーザールールの編集... | |||
Secure Local PAC,Безопасный URL локального PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護 | |||
Copy Local PAC URL,Копировать URL локального PAC,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー | |||
Share Server Config...,Поделиться конфигурацией сервера…,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有... | |||
Scan QRCode from Screen...,Сканировать QRCode с экрана…,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン... | |||
Import URL from Clipboard...,Импорт адреса из буфера обмена…,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート... | |||
Availability Statistics,Статистика доступности,统计可用性,統計可用性,可用性の統計 | |||
Show Logs...,Показать журнал…,显示日志...,顯示記錄檔...,ログの表示... | |||
Verbose Logging,Подробный журнал,详细记录日志,詳細資訊記錄,詳細なログを記録 | |||
Updates...,Обновления…,更新...,更新...,更新... | |||
Check for Updates...,Проверить обновления…,检查更新,檢查更新,更新プログラムの確認... | |||
Check for Updates at Startup,Проверять при запуске,启动时检查更新,啟動時檢查更新,起動時に更新プログラムを確認 | |||
Check Pre-release Version,Проверять предрелизные версии,检查测试版更新,檢查發行前版本更新,先行開発版も確認 | |||
Edit Hotkeys...,Горячие клавиши…,编辑快捷键...,編輯快速鍵...,ホットキーの編集... | |||
About...,О программе…,关于...,關於...,Shadowsocks について... | |||
Help,Помощь,帮助,說明,ヘルプ | |||
Quit,Выход,退出,結束,終了 | |||
Edit Servers,Редактирование серверов,编辑服务器,編輯伺服器,サーバーの編集 | |||
Load Balance,Балансировка нагрузки,负载均衡,負載平衡,負荷分散 | |||
High Availability,Высокая доступность,高可用,高可用性,高可用性 | |||
Choose by statistics,На основе статистики,根据统计,根據統計,統計で選ぶ | |||
Show Plugin Output,События плагинов в журнале,显示插件输出,, | |||
Write translation template,Создать шаблон для перевода,写入翻译模板,, | |||
,,,, | |||
# Config Form,,,, | |||
,,,, | |||
Statistics configuration,Настройки статистики,统计配置,, | |||
&Add,Добавить,添加(&A),新增 (&A),新規 (&A) | |||
&Delete,Удалить,删除(&D),移除 (&D),削除 (&D) | |||
Dupli&cate,Дублир-ть,复制(&C),複製 (&C),コピー (&C) | |||
Server,Сервер,服务器,伺服器,サーバー | |||
Server IP,IP-адрес,服务器地址,伺服器位址,サーバーアドレス | |||
Server Port,Порт,服务器端口,伺服器連接埠,サーバーポート | |||
Password,Пароль,密码,密碼,パスワード | |||
Show Password,Показать пароль,显示密码,顯示密碼,パスワードを表示する | |||
Encryption,Шифрование,加密,加密,暗号化 | |||
Plugin Program,Плагин,插件程序,外掛程式,プラグインプログラム | |||
Plugin Options,Опции плагина,插件选项,外掛程式選項,プラグインのオプション | |||
Need Plugin Argument,Требуются аргументы,需要命令行参数,, | |||
Plugin Arguments,Аргументы,插件参数,外掛程式參數,プラグインの引数 | |||
Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート | |||
Portable Mode,Переносимый режим,便携模式,便攜模式,ポータブルモード | |||
Restart required,Требуется перезапуск программы,需要重新启动SS,需要重新啟動SS,再起動SSが必要 | |||
Remarks,Примечания,备注,註解,付記 | |||
Timeout(Sec),Таймаут(сек),超时(秒),逾時 (秒),タイムアウト (秒) | |||
OK,ОК,确定,確定,OK | |||
Cancel,Отмена,取消,取消,キャンセル | |||
Apply,Применить,应用,應用,適用 | |||
New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー | |||
Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U) | |||
Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O) | |||
deprecated,Устаревшее,不推荐,不推薦,非推奨 | |||
,,,, | |||
#Statistics Config,,,, | |||
,,,, | |||
Enable Statistics,Включить сбор статистики,启用统计,, | |||
Ping Test,Проверка связи (Ping),Ping测试,, | |||
packages everytime,пакета на проверку,个包/次,, | |||
By hour of day,Ежечасно,按照每天的小时数统计,, | |||
Collect data per,Собирать данные за,收集数据每,, | |||
Keep choice for,Хранить отбор данных за,保持选择每,, | |||
minutes,мин.,分钟,, | |||
Final Score:,Финальная оценка:,总分:,, | |||
AverageLatency,СредЗадержка,平均延迟,, | |||
MinLatency,МинЗадержка,最小延迟,, | |||
MaxLatency,МаксЗадержка,最大延迟,, | |||
AverageInboundSpeed,СредВходСкорость,平均入站速度,, | |||
MinInboundSpeed,МинВходСкорость,最小入站速度,, | |||
MaxInboundSpeed,СредВходСкорость,最大入站速度,, | |||
AverageOutboundSpeed,СредИсхСкорость,平均出站速度,, | |||
MinOutboundSpeed,МинИсхСкорость,最小出站速度,, | |||
MaxOutboundSpeed,МаксИсхСкорость,最大出站速度,, | |||
AverageResponse,СредВремяОтвета,平均响应速度,, | |||
MinResponse,МинВремяОтвета,最小响应速度,, | |||
MaxResponse,МаксВремяОтвета,最大响应速度,, | |||
PackageLoss,ПотериПакетов,丢包率,, | |||
Speed,Скорость,速度,, | |||
Package Loss,Потери пакетов,丢包率,, | |||
Ping,Ping,网络延迟,, | |||
Chart Mode,График,图表模式,, | |||
24h,24ч,24小时,, | |||
all,За все время,全部,, | |||
,,,, | |||
# Proxy Form,,,, | |||
,,,, | |||
Edit Proxy,Редактирование прокси,代理设置,編輯 Proxy,プロキシの編集 | |||
Use Proxy,Использовать прокси,使用代理,使用 Proxy,プロキシを利用する | |||
Proxy Type,Тип прокси,代理类型,Proxy 類型,プロキシの種類 | |||
Proxy Addr,Адрес прокси,代理地址,Proxy 位址,プロキシアドレス | |||
Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート | |||
"If server has a plugin, proxy will not be used","Если сервер использует плагины, прокси НЕ будет использоваться",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません | |||
Use Auth,Требуется авторизация,使用认证,使用認證,認証を利用する | |||
User Name,Пользователь,用户名,認證用戶,認証ユーザ | |||
Auth Pwd,Пароль,认证密码,認證口令,認証パスワード | |||
,,,, | |||
# Log Form,,,, | |||
,,,, | |||
&File,Файл,文件(&F),檔案 (&F),ファイル (&F) | |||
&Open Location,Расположение файла,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O) | |||
E&xit,Выход,退出(&X),結束 (&X),終了 (&X) | |||
&View,Вид,视图(&V),檢視 (&V),表示 (&V) | |||
&Clear Logs,Очистить журнал,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C) | |||
Change &Font,Шрифт…,设置字体(&F),變更字型 (&F),フォント (&F) | |||
&Wrap Text,Перенос строк,自动换行(&W),自動換行 (&W),右端で折り返す (&W) | |||
&Top Most,Поверх всех окон,置顶(&T),置頂 (&T),常に最前面に表示 (&T) | |||
&Show Toolbar,Панель инструментов,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S) | |||
Log Viewer,Просмотр журнала,日志查看器,記錄檔檢視器,ログビューア | |||
Inbound,Входящая,入站,輸入,受信 | |||
Outbound,Исходящая,出站,輸出,送信 | |||
,,,, | |||
# QRCode Form,,,, | |||
,,,, | |||
QRCode and URL,QRCode и URL,二维码与 URL,QR 碼與 URL,QR コードと URL | |||
,,,, | |||
# PAC Url Form,,,, | |||
,,,, | |||
Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集 | |||
Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集... | |||
Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい | |||
,,,, | |||
# HotkeySettings Form,,,, | |||
,,,, | |||
Switch system proxy,ВКЛ/ВЫКЛ системный прокси-сервер,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える | |||
Switch system proxy mode,Переключение режима прокси-сервера,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える | |||
Allow Clients from LAN,Общий доступ к подключению,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える | |||
Show Logs...,Просмотр журналов,显示日志,顯示記錄檔,ログの表示 | |||
Switch to previous server,Переключить на пред. сервер,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える | |||
Switch to next server,Переключить на след. сервер,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える | |||
Reg All,Применить все,注册全部快捷键,註冊所有快速鍵,全部登録する | |||
Reg Hotkeys At Startup,Применять при запуске программы,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する | |||
,,,, | |||
# Messages,,,, | |||
,,,, | |||
Shadowsocks Error: {0},Ошибка Shadowsocks: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0} | |||
Port {0} already in use,Порт {0} уже используется,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。 | |||
Port {0} is reserved by system,Порт {0} зарезервирован системой,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています | |||
Invalid server address,Неверный адрес сервера,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。 | |||
Illegal port number format,Неверный числовой формат порта,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。 | |||
Illegal timeout format,Неверный формат таймаута,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。 | |||
Server IP can not be blank,IP-адрес сервера не может быть пустым,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。 | |||
Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。 | |||
Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。 | |||
Port can't be 8123,Адрес порта 8123 не может быть использован,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。 | |||
Shadowsocks {0} Update Found,Обнаружена новая версия Shadowsocks: {0},Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。 | |||
No update is available,Обновлений не обнаружено,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。 | |||
Click here to update,Нажмите сюда для обновления,点击这里升级,點按此處升級,クリックしてアップデートします。 | |||
Shadowsocks is here,Shadowsocks находится здесь,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。 | |||
You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。 | |||
System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。 | |||
System Proxy Disabled,Системный прокси отключен,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。 | |||
Failed to update PAC file ,Не удалось обновить PAC файл,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。 | |||
PAC updated,PAC файл обновлен,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。 | |||
No updates found. Please report to GFWList if you have problems with it.,Обновлений не найдено. Сообщите авторам GFWList если у вас возникли проблемы.,未发现更新。如有问题请提交给 GFWList。,未發現更新。如有問題請報告至 GFWList。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。 | |||
No QRCode found. Try to zoom in or move it to the center of the screen.,QRCode не обнаружен. Попробуйте увеличить изображение или переместить его в центр экрана.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。 | |||
Shadowsocks is already running.,Shadowsocks уже запущен.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中 | |||
Find Shadowsocks icon in your notify tray.,Значок Shadowsocks можно найти в области уведомлений.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。 | |||
"If you want to start multiple Shadowsocks, make a copy in another directory.","Если вы хотите запустить несколько копий Shadowsocks одновременно, создайте отдельную папку на каждую копию.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。 | |||
Failed to decode QRCode,Не удалось распознать QRCode,无法解析二维码,QR 碼解碼失敗,QR コードの読み取りに失敗しました。 | |||
Failed to update registry,Не удалось обновить запись в реестре,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。 | |||
System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効: | |||
Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0} | |||
"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい: | |||
"Unsupported operating system, use Windows Vista at least.","Операционная система не поддерживается, минимальные системные требования: Windows Vista или выше.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。 | |||
"Unsupported .NET Framework, please update to {0} or later.","Версия .NET Framework не поддерживается, минимальные системные требования: {0} или выше.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。 | |||
Proxy request failed,Не удалось выполнить запрос,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。 | |||
Proxy handshake failed,Не удалось выполнить хэндшейк,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。 | |||
Register hotkey failed,Не удалось применить настройки горячих клавиш,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。 | |||
Cannot parse hotkey: {0},Не удалось распознать следующие горячие клавиши: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0} | |||
"Timeout is invalid, it should not exceed {0}",Таймаут не может превышать значение {0},超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。 | |||
Cannot find the plugin program file,Файл плагина не найден,找不到插件程序文件,找不到外掛程式文件, | |||
,,,, | |||
Operation failure,Операция завершилась неудачей,操作失败,, | |||
Auto save failed,Автоматическое сохранение не удалось,自动保存失败,, | |||
Whether to discard unconfigured servers,Внесенные изменения будут утеряны,是否丢弃未配置的服务器,, | |||
"Invalid server address, Cannot automatically save or discard changes",Неверный адрес сервера. Невозможно сохранить или отменить изменения,非法服务器地址,无法自动保存,是否丢弃修改,, | |||
"Illegal port number format, Cannot automatically save or discard changes",Неверный числовой адрес порта. Невозможно сохранить или отменить изменения,非法端口格式,无法自动保存,是否丢弃修改,, | |||
"Password can not be blank, Cannot automatically save or discard changes",Пароль не может быть пустым. Невозможно сохранить или отменить изменения,密码不能为空,无法自动保存,是否丢弃修改,, | |||
"Illegal timeout format, Cannot automatically save or discard changes",Неверный формат таймаута. Невозможно сохранить или отменить изменения,非法超时格式,无法自动保存,是否丢弃修改,, | |||
,,,, | |||
"Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,, | |||
"Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,, | |||
Auth user can not be blank,Пользователь не может быть пустым,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。 | |||
Auth pwd can not be blank,Пароль не может быть пустым,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。 |
@@ -1,4 +1,5 @@ | |||
using System; | |||
using NLog; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.Net; | |||
@@ -13,6 +14,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
public abstract class AEADEncryptor | |||
: EncryptorBase | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
// We are using the same saltLen and keyLen | |||
private const string Info = "ss-subkey"; | |||
private static readonly byte[] InfoBytes = Encoding.ASCII.GetBytes(Info); | |||
@@ -122,7 +124,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
_decryptSalt = new byte[saltLen]; | |||
Array.Copy(salt, _decryptSalt, saltLen); | |||
} | |||
Logging.Dump("Salt", salt, saltLen); | |||
logger.Dump("Salt", salt, saltLen); | |||
} | |||
public static void randBytes(byte[] buf, int length) { RNG.GetBytes(buf, length); } | |||
@@ -139,7 +141,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
_encCircularBuffer.Put(buf, 0, length); | |||
outlength = 0; | |||
Logging.Debug("---Start Encryption"); | |||
logger.Debug("---Start Encryption"); | |||
if (! _encryptSaltSent) { | |||
_encryptSaltSent = true; | |||
// Generate salt | |||
@@ -148,7 +150,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
InitCipher(saltBytes, true, false); | |||
Array.Copy(saltBytes, 0, outbuf, 0, saltLen); | |||
outlength = saltLen; | |||
Logging.Debug($"_encryptSaltSent outlength {outlength}"); | |||
logger.Debug($"_encryptSaltSent outlength {outlength}"); | |||
} | |||
if (! _tcpRequestSent) { | |||
@@ -161,7 +163,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
Debug.Assert(encAddrBufLength == AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES); | |||
Array.Copy(encAddrBufBytes, 0, outbuf, outlength, encAddrBufLength); | |||
outlength += encAddrBufLength; | |||
Logging.Debug($"_tcpRequestSent outlength {outlength}"); | |||
logger.Debug($"_tcpRequestSent outlength {outlength}"); | |||
} | |||
// handle other chunks | |||
@@ -176,15 +178,15 @@ namespace Shadowsocks.Encryption.AEAD | |||
Debug.Assert(encChunkLength == chunklength + tagLen * 2 + CHUNK_LEN_BYTES); | |||
Buffer.BlockCopy(encChunkBytes, 0, outbuf, outlength, encChunkLength); | |||
outlength += encChunkLength; | |||
Logging.Debug("chunks enc outlength " + outlength); | |||
logger.Debug("chunks enc outlength " + outlength); | |||
// check if we have enough space for outbuf | |||
if (outlength + TCPHandler.ChunkOverheadSize > TCPHandler.BufferSize) { | |||
Logging.Debug("enc outbuf almost full, giving up"); | |||
logger.Debug("enc outbuf almost full, giving up"); | |||
return; | |||
} | |||
bufSize = (uint)_encCircularBuffer.Size; | |||
if (bufSize <= 0) { | |||
Logging.Debug("No more data to encrypt, leaving"); | |||
logger.Debug("No more data to encrypt, leaving"); | |||
return; | |||
} | |||
} | |||
@@ -199,7 +201,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
// drop all into buffer | |||
_decCircularBuffer.Put(buf, 0, length); | |||
Logging.Debug("---Start Decryption"); | |||
logger.Debug("---Start Decryption"); | |||
if (! _decryptSaltReceived) { | |||
bufSize = _decCircularBuffer.Size; | |||
// check if we get the leading salt | |||
@@ -210,7 +212,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
_decryptSaltReceived = true; | |||
byte[] salt = _decCircularBuffer.Get(saltLen); | |||
InitCipher(salt, false, false); | |||
Logging.Debug("get salt len " + saltLen); | |||
logger.Debug("get salt len " + saltLen); | |||
} | |||
// handle chunks | |||
@@ -218,7 +220,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
bufSize = _decCircularBuffer.Size; | |||
// check if we have any data | |||
if (bufSize <= 0) { | |||
Logging.Debug("No data in _decCircularBuffer"); | |||
logger.Debug("No data in _decCircularBuffer"); | |||
return; | |||
} | |||
@@ -241,13 +243,13 @@ namespace Shadowsocks.Encryption.AEAD | |||
if (chunkLen > CHUNK_LEN_MASK) | |||
{ | |||
// we get invalid chunk | |||
Logging.Error($"Invalid chunk length: {chunkLen}"); | |||
logger.Error($"Invalid chunk length: {chunkLen}"); | |||
throw new CryptoErrorException(); | |||
} | |||
Logging.Debug("Get the real chunk len:" + chunkLen); | |||
logger.Debug("Get the real chunk len:" + chunkLen); | |||
bufSize = _decCircularBuffer.Size; | |||
if (bufSize < CHUNK_LEN_BYTES + tagLen /* we haven't remove them */+ chunkLen + tagLen) { | |||
Logging.Debug("No more data to decrypt one chunk"); | |||
logger.Debug("No more data to decrypt one chunk"); | |||
return; | |||
} | |||
IncrementNonce(false); | |||
@@ -267,16 +269,16 @@ namespace Shadowsocks.Encryption.AEAD | |||
// output to outbuf | |||
Buffer.BlockCopy(decChunkBytes, 0, outbuf, outlength, (int) decChunkLen); | |||
outlength += (int)decChunkLen; | |||
Logging.Debug("aead dec outlength " + outlength); | |||
logger.Debug("aead dec outlength " + outlength); | |||
if (outlength + 100 > TCPHandler.BufferSize) | |||
{ | |||
Logging.Debug("dec outbuf almost full, giving up"); | |||
logger.Debug("dec outbuf almost full, giving up"); | |||
return; | |||
} | |||
bufSize = _decCircularBuffer.Size; | |||
// check if we already done all of them | |||
if (bufSize <= 0) { | |||
Logging.Debug("No data in _decCircularBuffer, already all done"); | |||
logger.Debug("No data in _decCircularBuffer, already all done"); | |||
return; | |||
} | |||
} | |||
@@ -319,7 +321,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
private void ChunkEncrypt(byte[] plaintext, int plainLen, byte[] ciphertext, out int cipherLen) | |||
{ | |||
if (plainLen > CHUNK_LEN_MASK) { | |||
Logging.Error("enc chunk too big"); | |||
logger.Error("enc chunk too big"); | |||
throw new CryptoErrorException(); | |||
} | |||
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Encryption.Exception; | |||
@@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption.AEAD | |||
public class AEADSodiumEncryptor | |||
: AEADEncryptor, IDisposable | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const int CIPHER_CHACHA20IETFPOLY1305 = 1; | |||
private const int CIPHER_XCHACHA20IETFPOLY1305 = 2; | |||
private const int CIPHER_AES256GCM = 3; | |||
@@ -55,9 +58,9 @@ namespace Shadowsocks.Encryption.AEAD | |||
// outbuf: ciphertext + tag | |||
int ret; | |||
ulong encClen = 0; | |||
Logging.Dump("_encNonce before enc", _encNonce, nonceLen); | |||
Logging.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen); | |||
Logging.Dump("before cipherEncrypt: plain", plaintext, (int) plen); | |||
logger.Dump("_encNonce before enc", _encNonce, nonceLen); | |||
logger.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen); | |||
logger.Dump("before cipherEncrypt: plain", plaintext, (int) plen); | |||
switch (_cipher) | |||
{ | |||
case CIPHER_CHACHA20IETFPOLY1305: | |||
@@ -85,7 +88,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
throw new System.Exception("not implemented"); | |||
} | |||
if (ret != 0) throw new CryptoErrorException(String.Format("ret is {0}", ret)); | |||
Logging.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen); | |||
logger.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen); | |||
clen = (uint) encClen; | |||
} | |||
@@ -96,9 +99,9 @@ namespace Shadowsocks.Encryption.AEAD | |||
// outbuf: plaintext | |||
int ret; | |||
ulong decPlen = 0; | |||
Logging.Dump("_decNonce before dec", _decNonce, nonceLen); | |||
Logging.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen); | |||
Logging.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen); | |||
logger.Dump("_decNonce before dec", _decNonce, nonceLen); | |||
logger.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen); | |||
logger.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen); | |||
switch (_cipher) | |||
{ | |||
case CIPHER_CHACHA20IETFPOLY1305: | |||
@@ -127,7 +130,7 @@ namespace Shadowsocks.Encryption.AEAD | |||
} | |||
if (ret != 0) throw new CryptoErrorException(String.Format("ret is {0}", ret)); | |||
Logging.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen); | |||
logger.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen); | |||
plen = (uint) decPlen; | |||
} | |||
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.IO; | |||
using System.Runtime.InteropServices; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
@@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption | |||
{ | |||
public static class MbedTLS | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const string DLLNAME = "libsscrypto.dll"; | |||
public const int MBEDTLS_ENCRYPT = 1; | |||
@@ -3,6 +3,7 @@ using System.IO; | |||
using System.Runtime.InteropServices; | |||
using System.Security; | |||
using System.Text; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Encryption.Exception; | |||
using Shadowsocks.Properties; | |||
@@ -13,6 +14,8 @@ namespace Shadowsocks.Encryption | |||
// XXX: only for OpenSSL 1.1.0 and higher | |||
public static class OpenSSL | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const string DLLNAME = "libsscrypto.dll"; | |||
public const int OPENSSL_ENCRYPT = 1; | |||
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.IO; | |||
using System.Runtime.InteropServices; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
@@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption | |||
{ | |||
public static class Sodium | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const string DLLNAME = "libsscrypto.dll"; | |||
private static bool _initialized = false; | |||
@@ -34,7 +37,7 @@ namespace Shadowsocks.Encryption | |||
} | |||
AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1; | |||
Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}"); | |||
logger.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}"); | |||
} | |||
} | |||
} | |||
@@ -2,6 +2,7 @@ | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
namespace Shadowsocks.Model | |||
@@ -9,6 +10,9 @@ namespace Shadowsocks.Model | |||
[Serializable] | |||
public class Configuration | |||
{ | |||
[JsonIgnore] | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public string version; | |||
public List<Server> configs; | |||
@@ -32,14 +36,23 @@ namespace Shadowsocks.Model | |||
public bool autoCheckUpdate; | |||
public bool checkPreRelease; | |||
public bool isVerboseLogging; | |||
//public NLogConfig.LogLevel logLevel; | |||
public LogViewerConfig logViewer; | |||
public ProxyConfig proxy; | |||
public HotkeyConfig hotkey; | |||
[JsonIgnore] | |||
NLogConfig nLogConfig; | |||
private static readonly string CONFIG_FILE = "gui-config.json"; | |||
[JsonIgnore] | |||
public bool updated = false; | |||
[JsonIgnore] | |||
public string localHost => GetLocalHost(); | |||
private string GetLocalHost() { | |||
private string GetLocalHost() | |||
{ | |||
return isIPv6Enabled ? "[::1]" : "127.0.0.1"; | |||
} | |||
public Server GetCurrentServer() | |||
@@ -78,6 +91,10 @@ namespace Shadowsocks.Model | |||
string configContent = File.ReadAllText(CONFIG_FILE); | |||
Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent); | |||
config.isDefault = false; | |||
if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version ?? "0") > 0) | |||
{ | |||
config.updated = true; | |||
} | |||
if (config.configs == null) | |||
config.configs = new List<Server>(); | |||
@@ -93,19 +110,43 @@ namespace Shadowsocks.Model | |||
config.proxy = new ProxyConfig(); | |||
if (config.hotkey == null) | |||
config.hotkey = new HotkeyConfig(); | |||
if (!System.Net.Sockets.Socket.OSSupportsIPv6) { | |||
if (!System.Net.Sockets.Socket.OSSupportsIPv6) | |||
{ | |||
config.isIPv6Enabled = false; // disable IPv6 if os not support | |||
} | |||
//TODO if remote host(server) do not support IPv6 (or DNS resolve AAAA TYPE record) disable IPv6? | |||
config.proxy.CheckConfig(); | |||
try | |||
{ | |||
config.nLogConfig = NLogConfig.LoadXML(); | |||
switch (config.nLogConfig.GetLogLevel()) | |||
{ | |||
case NLogConfig.LogLevel.Fatal: | |||
case NLogConfig.LogLevel.Error: | |||
case NLogConfig.LogLevel.Warn: | |||
case NLogConfig.LogLevel.Info: | |||
config.isVerboseLogging = false; | |||
break; | |||
case NLogConfig.LogLevel.Debug: | |||
case NLogConfig.LogLevel.Trace: | |||
config.isVerboseLogging = true; | |||
break; | |||
} | |||
} | |||
catch (Exception e) | |||
{ | |||
// todo: route the error to UI since there is no log file in this scenario | |||
logger.Error(e, "Cannot get the log level from NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); | |||
} | |||
return config; | |||
} | |||
catch (Exception e) | |||
{ | |||
if (!(e is FileNotFoundException)) | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return new Configuration | |||
{ | |||
index = 0, | |||
@@ -118,7 +159,7 @@ namespace Shadowsocks.Model | |||
}, | |||
logViewer = new LogViewerConfig(), | |||
proxy = new ProxyConfig(), | |||
hotkey = new HotkeyConfig() | |||
hotkey = new HotkeyConfig(), | |||
}; | |||
} | |||
} | |||
@@ -141,10 +182,20 @@ namespace Shadowsocks.Model | |||
sw.Write(jsonString); | |||
sw.Flush(); | |||
} | |||
try | |||
{ | |||
// apply changs to NLog.config | |||
config.nLogConfig.SetLogLevel(config.isVerboseLogging? NLogConfig.LogLevel.Trace: NLogConfig.LogLevel.Info); | |||
NLogConfig.SaveXML(config.nLogConfig); | |||
} | |||
catch(Exception e) | |||
{ | |||
logger.Error(e, "Cannot set the log level to NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); | |||
} | |||
} | |||
catch (IOException e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -0,0 +1,122 @@ | |||
using NLog; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Xml; | |||
namespace Shadowsocks.Model | |||
{ | |||
public class NLogConfig | |||
{ | |||
public enum LogLevel | |||
{ | |||
Fatal, | |||
Error, | |||
Warn, | |||
Info, | |||
Debug, | |||
Trace, | |||
} | |||
const string NLOG_CONFIG_FILE_NAME = "nLog.config"; | |||
const string TARGET_MIN_LEVEL_ATTRIBUTE = "minlevel"; | |||
const string LOGGER_FILE_NAME_ATTRIBUTE = "fileName"; | |||
XmlDocument doc = new XmlDocument(); | |||
XmlElement logFileNameElement; | |||
XmlElement logLevelElement; | |||
/// <summary> | |||
/// Load the NLog config xml file content | |||
/// </summary> | |||
public static NLogConfig LoadXML() | |||
{ | |||
NLogConfig config = new NLogConfig(); | |||
config.doc.Load(NLOG_CONFIG_FILE_NAME); | |||
config.logLevelElement = (XmlElement)SelectSingleNode(config.doc, "//nlog:logger[@name='*']"); | |||
config.logFileNameElement = (XmlElement)SelectSingleNode(config.doc, "//nlog:target[@name='file']"); | |||
return config; | |||
} | |||
/// <summary> | |||
/// Save the content to NLog config xml file | |||
/// </summary> | |||
public static void SaveXML(NLogConfig nLogConfig) | |||
{ | |||
nLogConfig.doc.Save(NLOG_CONFIG_FILE_NAME); | |||
} | |||
/// <summary> | |||
/// Get the current minLogLevel from xml file | |||
/// </summary> | |||
/// <returns></returns> | |||
public LogLevel GetLogLevel() | |||
{ | |||
LogLevel level = LogLevel.Warn; | |||
string levelStr = logLevelElement.GetAttribute(TARGET_MIN_LEVEL_ATTRIBUTE); | |||
Enum.TryParse(levelStr, out level); | |||
return level; | |||
} | |||
/// <summary> | |||
/// Get the target fileName from xml file | |||
/// </summary> | |||
/// <returns></returns> | |||
public string GetLogFileName() | |||
{ | |||
return logFileNameElement.GetAttribute(LOGGER_FILE_NAME_ATTRIBUTE); | |||
} | |||
/// <summary> | |||
/// Set the minLogLevel to xml file | |||
/// </summary> | |||
/// <param name="logLevel"></param> | |||
public void SetLogLevel(LogLevel logLevel) | |||
{ | |||
logLevelElement.SetAttribute(TARGET_MIN_LEVEL_ATTRIBUTE, logLevel.ToString("G")); | |||
} | |||
/// <summary> | |||
/// Set the target fileName to xml file | |||
/// </summary> | |||
/// <param name="fileName"></param> | |||
public void SetLogFileName(string fileName) | |||
{ | |||
logFileNameElement.SetAttribute(LOGGER_FILE_NAME_ATTRIBUTE, fileName); | |||
} | |||
/// <summary> | |||
/// Select a single XML node/elemant | |||
/// </summary> | |||
/// <param name="doc"></param> | |||
/// <param name="xpath"></param> | |||
/// <returns></returns> | |||
private static XmlNode SelectSingleNode(XmlDocument doc, string xpath) | |||
{ | |||
XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); | |||
manager.AddNamespace("nlog", "http://www.nlog-project.org/schemas/NLog.xsd"); | |||
//return doc.SelectSingleNode("//nlog:logger[(@shadowsocks='managed') and (@name='*')]", manager); | |||
return doc.SelectSingleNode(xpath, manager); | |||
} | |||
/// <summary> | |||
/// Extract the pre-defined NLog configuration file is does not exist. Then reload the Nlog configuration. | |||
/// </summary> | |||
public static void TouchAndApplyNLogConfig() | |||
{ | |||
LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME); | |||
} | |||
/// <summary> | |||
/// NLog reload the config file and apply to current LogManager | |||
/// </summary> | |||
public static void LoadConfiguration() | |||
{ | |||
LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME); | |||
} | |||
} | |||
} |
@@ -5,7 +5,7 @@ using System.Linq; | |||
using System.Reflection; | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
namespace Shadowsocks.Model | |||
@@ -13,6 +13,8 @@ namespace Shadowsocks.Model | |||
[Serializable] | |||
public class StatisticsStrategyConfiguration | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public static readonly string ID = "com.shadowsocks.strategy.statistics"; | |||
public bool StatisticsEnabled { get; set; } = false; | |||
public bool ByHourOfDay { get; set; } = true; | |||
@@ -39,7 +41,7 @@ namespace Shadowsocks.Model | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return new StatisticsStrategyConfiguration(); | |||
} | |||
} | |||
@@ -53,7 +55,7 @@ namespace Shadowsocks.Model | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -3,6 +3,7 @@ using System.Diagnostics; | |||
using System.IO; | |||
using System.Threading; | |||
using System.Windows.Forms; | |||
using NLog; | |||
using Microsoft.Win32; | |||
using Shadowsocks.Controller; | |||
@@ -14,6 +15,7 @@ namespace Shadowsocks | |||
{ | |||
static class Program | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
public static ShadowsocksController MainController { get; private set; } | |||
public static MenuViewController MenuController { get; private set; } | |||
public static string[] Args { get; private set; } | |||
@@ -24,8 +26,11 @@ namespace Shadowsocks | |||
[STAThread] | |||
static void Main(string[] args) | |||
{ | |||
// todo: initialize the NLog configuartion | |||
Model.NLogConfig.TouchAndApplyNLogConfig(); | |||
// .NET Framework 4.7.2 on Win7 compatibility | |||
System.Net.ServicePointManager.SecurityProtocol |= | |||
System.Net.ServicePointManager.SecurityProtocol |= | |||
System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; | |||
// store args for further use | |||
@@ -78,18 +83,16 @@ namespace Shadowsocks | |||
return; | |||
} | |||
Directory.SetCurrentDirectory(Application.StartupPath); | |||
#if DEBUG | |||
Logging.OpenLogFile(); | |||
// truncate privoxy log file while debugging | |||
string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); | |||
if (File.Exists(privoxyLogFilename)) | |||
using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { } | |||
#else | |||
Logging.OpenLogFile(); | |||
#endif | |||
MainController = new ShadowsocksController(); | |||
MenuController = new MenuViewController(MainController); | |||
HotKeys.Init(MainController); | |||
MainController.Start(); | |||
Application.Run(); | |||
@@ -102,7 +105,7 @@ namespace Shadowsocks | |||
if (Interlocked.Increment(ref exited) == 1) | |||
{ | |||
string errMsg = e.ExceptionObject.ToString(); | |||
Logging.Error(errMsg); | |||
logger.Error(errMsg); | |||
MessageBox.Show( | |||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errMsg}", | |||
"Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||
@@ -115,7 +118,7 @@ namespace Shadowsocks | |||
if (Interlocked.Increment(ref exited) == 1) | |||
{ | |||
string errorMsg = $"Exception Detail: {Environment.NewLine}{e.Exception}"; | |||
Logging.Error(errorMsg); | |||
logger.Error(errorMsg); | |||
MessageBox.Show( | |||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}", | |||
"Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||
@@ -128,7 +131,7 @@ namespace Shadowsocks | |||
switch (e.Mode) | |||
{ | |||
case PowerModes.Resume: | |||
Logging.Info("os wake up"); | |||
logger.Info("os wake up"); | |||
if (MainController != null) | |||
{ | |||
System.Threading.Tasks.Task.Factory.StartNew(() => | |||
@@ -137,11 +140,11 @@ namespace Shadowsocks | |||
try | |||
{ | |||
MainController.Start(false); | |||
Logging.Info("controller started"); | |||
logger.Info("controller started"); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
} | |||
}); | |||
} | |||
@@ -150,9 +153,9 @@ namespace Shadowsocks | |||
if (MainController != null) | |||
{ | |||
MainController.Stop(); | |||
Logging.Info("controller stopped"); | |||
logger.Info("controller stopped"); | |||
} | |||
Logging.Info("os suspend"); | |||
logger.Info("os suspend"); | |||
break; | |||
} | |||
} | |||
@@ -4,6 +4,7 @@ using System.Net.Sockets; | |||
using System.Text; | |||
using System.Text.RegularExpressions; | |||
using System.Threading; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Util.Sockets; | |||
@@ -11,6 +12,8 @@ namespace Shadowsocks.Proxy | |||
{ | |||
public class HttpProxy : IProxy | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private class FakeAsyncResult : IAsyncResult | |||
{ | |||
public readonly HttpState innerState; | |||
@@ -179,7 +182,7 @@ namespace Shadowsocks.Proxy | |||
private bool OnLineRead(string line, object state) | |||
{ | |||
Logging.Debug(line); | |||
logger.Debug(line); | |||
if (_respondLineCount == 0) | |||
{ | |||
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.Runtime.InteropServices; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
namespace Shadowsocks.Util.ProcessManagement | |||
@@ -11,6 +12,8 @@ namespace Shadowsocks.Util.ProcessManagement | |||
*/ | |||
public class Job : IDisposable | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private IntPtr handle = IntPtr.Zero; | |||
public Job() | |||
@@ -54,7 +57,7 @@ namespace Shadowsocks.Util.ProcessManagement | |||
if (!succ) | |||
{ | |||
Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error()); | |||
logger.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error()); | |||
} | |||
return succ; | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
@@ -14,6 +15,8 @@ namespace Shadowsocks.Util.SystemProxy | |||
{ | |||
public static class Sysproxy | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private const string _userWininetConfigFile = "user-wininet.json"; | |||
private readonly static string[] _lanIP = { | |||
@@ -70,7 +73,7 @@ namespace Shadowsocks.Util.SystemProxy | |||
} | |||
catch (IOException e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -238,7 +241,7 @@ namespace Shadowsocks.Util.SystemProxy | |||
} | |||
catch (IOException e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
} | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using System; | |||
using NLog; | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.IO.Compression; | |||
@@ -26,6 +27,8 @@ namespace Shadowsocks.Util | |||
public static class Utils | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
private static string _tempPath = null; | |||
// return path to store temporary files | |||
@@ -48,7 +51,7 @@ namespace Shadowsocks.Util | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.Error(e); | |||
logger.Error(e); | |||
throw; | |||
} | |||
} | |||
@@ -58,7 +61,7 @@ namespace Shadowsocks.Util | |||
public enum WindowsThemeMode { Dark, Light } | |||
// Support on Windows 10 1903+ | |||
public static WindowsThemeMode GetWindows10SystemThemeSetting(bool isVerbose) | |||
public static WindowsThemeMode GetWindows10SystemThemeSetting() | |||
{ | |||
WindowsThemeMode themeMode = WindowsThemeMode.Dark; | |||
try | |||
@@ -78,11 +81,10 @@ namespace Shadowsocks.Util | |||
} | |||
catch | |||
{ | |||
if (isVerbose) | |||
{ | |||
Logging.Info( | |||
$"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); | |||
} | |||
logger.Debug( | |||
$"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); | |||
} | |||
return themeMode; | |||
} | |||
@@ -232,7 +234,7 @@ namespace Shadowsocks.Util | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.LogUsefulException(e); | |||
logger.LogUsefulException(e); | |||
return null; | |||
} | |||
} | |||
@@ -106,10 +106,10 @@ | |||
this.tableLayoutPanel1.Controls.Add(this.PluginArgumentsLabel, 0, 8); | |||
this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 10); | |||
this.tableLayoutPanel1.Controls.Add(this.NeedPluginArgCheckBox, 1, 7); | |||
this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); | |||
this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 26); | |||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); | |||
this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | |||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); | |||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4); | |||
this.tableLayoutPanel1.RowCount = 12; | |||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
@@ -123,16 +123,17 @@ | |||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel1.Size = new System.Drawing.Size(279, 292); | |||
this.tableLayoutPanel1.Size = new System.Drawing.Size(394, 357); | |||
this.tableLayoutPanel1.TabIndex = 0; | |||
// | |||
// PluginOptionsLabel | |||
// | |||
this.PluginOptionsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.PluginOptionsLabel.AutoSize = true; | |||
this.PluginOptionsLabel.Location = new System.Drawing.Point(18, 166); | |||
this.PluginOptionsLabel.Location = new System.Drawing.Point(24, 203); | |||
this.PluginOptionsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.PluginOptionsLabel.Name = "PluginOptionsLabel"; | |||
this.PluginOptionsLabel.Size = new System.Drawing.Size(89, 12); | |||
this.PluginOptionsLabel.Size = new System.Drawing.Size(119, 15); | |||
this.PluginOptionsLabel.TabIndex = 6; | |||
this.PluginOptionsLabel.Text = "Plugin Options"; | |||
this.toolTip1.SetToolTip(this.PluginOptionsLabel, "Environment variables for plugin program"); | |||
@@ -140,20 +141,22 @@ | |||
// PluginTextBox | |||
// | |||
this.PluginTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.PluginTextBox.Location = new System.Drawing.Point(113, 135); | |||
this.PluginTextBox.Location = new System.Drawing.Point(151, 165); | |||
this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.PluginTextBox.MaxLength = 256; | |||
this.PluginTextBox.Name = "PluginTextBox"; | |||
this.PluginTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.PluginTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.PluginTextBox.TabIndex = 5; | |||
this.PluginTextBox.WordWrap = false; | |||
// | |||
// RemarksTextBox | |||
// | |||
this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.RemarksTextBox.Location = new System.Drawing.Point(113, 238); | |||
this.RemarksTextBox.Location = new System.Drawing.Point(151, 291); | |||
this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.RemarksTextBox.MaxLength = 32; | |||
this.RemarksTextBox.Name = "RemarksTextBox"; | |||
this.RemarksTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.RemarksTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.RemarksTextBox.TabIndex = 8; | |||
this.RemarksTextBox.WordWrap = false; | |||
// | |||
@@ -161,9 +164,10 @@ | |||
// | |||
this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.IPLabel.AutoSize = true; | |||
this.IPLabel.Location = new System.Drawing.Point(48, 10); | |||
this.IPLabel.Location = new System.Drawing.Point(64, 13); | |||
this.IPLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.IPLabel.Name = "IPLabel"; | |||
this.IPLabel.Size = new System.Drawing.Size(59, 12); | |||
this.IPLabel.Size = new System.Drawing.Size(79, 15); | |||
this.IPLabel.TabIndex = 0; | |||
this.IPLabel.Text = "Server IP"; | |||
// | |||
@@ -171,9 +175,10 @@ | |||
// | |||
this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.ServerPortLabel.AutoSize = true; | |||
this.ServerPortLabel.Location = new System.Drawing.Point(36, 37); | |||
this.ServerPortLabel.Location = new System.Drawing.Point(48, 46); | |||
this.ServerPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.ServerPortLabel.Name = "ServerPortLabel"; | |||
this.ServerPortLabel.Size = new System.Drawing.Size(71, 12); | |||
this.ServerPortLabel.Size = new System.Drawing.Size(95, 15); | |||
this.ServerPortLabel.TabIndex = 1; | |||
this.ServerPortLabel.Text = "Server Port"; | |||
// | |||
@@ -181,9 +186,10 @@ | |||
// | |||
this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.PasswordLabel.AutoSize = true; | |||
this.PasswordLabel.Location = new System.Drawing.Point(54, 64); | |||
this.PasswordLabel.Location = new System.Drawing.Point(72, 79); | |||
this.PasswordLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.PasswordLabel.Name = "PasswordLabel"; | |||
this.PasswordLabel.Size = new System.Drawing.Size(53, 12); | |||
this.PasswordLabel.Size = new System.Drawing.Size(71, 15); | |||
this.PasswordLabel.TabIndex = 2; | |||
this.PasswordLabel.Text = "Password"; | |||
this.PasswordLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
@@ -191,30 +197,34 @@ | |||
// IPTextBox | |||
// | |||
this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.IPTextBox.Location = new System.Drawing.Point(113, 6); | |||
this.IPTextBox.Location = new System.Drawing.Point(151, 8); | |||
this.IPTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.IPTextBox.MaxLength = 512; | |||
this.IPTextBox.Name = "IPTextBox"; | |||
this.IPTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.IPTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.IPTextBox.TabIndex = 0; | |||
this.IPTextBox.WordWrap = false; | |||
// | |||
// ServerPortTextBox | |||
// | |||
this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.ServerPortTextBox.Location = new System.Drawing.Point(113, 33); | |||
this.ServerPortTextBox.Location = new System.Drawing.Point(151, 41); | |||
this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.ServerPortTextBox.MaxLength = 10; | |||
this.ServerPortTextBox.Name = "ServerPortTextBox"; | |||
this.ServerPortTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.ServerPortTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.ServerPortTextBox.TabIndex = 1; | |||
this.ServerPortTextBox.WordWrap = false; | |||
// | |||
// PasswordTextBox | |||
// | |||
this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.PasswordTextBox.Location = new System.Drawing.Point(113, 60); | |||
this.PasswordTextBox.Font = new System.Drawing.Font("Consolas", 9F); | |||
this.PasswordTextBox.Location = new System.Drawing.Point(151, 74); | |||
this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.PasswordTextBox.MaxLength = 256; | |||
this.PasswordTextBox.Name = "PasswordTextBox"; | |||
this.PasswordTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.PasswordTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.PasswordTextBox.TabIndex = 2; | |||
this.PasswordTextBox.UseSystemPasswordChar = true; | |||
this.PasswordTextBox.WordWrap = false; | |||
@@ -223,9 +233,10 @@ | |||
// | |||
this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.EncryptionLabel.AutoSize = true; | |||
this.EncryptionLabel.Location = new System.Drawing.Point(42, 113); | |||
this.EncryptionLabel.Location = new System.Drawing.Point(56, 138); | |||
this.EncryptionLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.EncryptionLabel.Name = "EncryptionLabel"; | |||
this.EncryptionLabel.Size = new System.Drawing.Size(65, 12); | |||
this.EncryptionLabel.Size = new System.Drawing.Size(87, 15); | |||
this.EncryptionLabel.TabIndex = 4; | |||
this.EncryptionLabel.Text = "Encryption"; | |||
// | |||
@@ -236,69 +247,54 @@ | |||
this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |||
this.EncryptionSelect.FormattingEnabled = true; | |||
this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; | |||
this.EncryptionSelect.ItemHeight = 12; | |||
this.EncryptionSelect.Items.AddRange(new object[] { | |||
"rc4-md5", | |||
"salsa20", | |||
"chacha20", | |||
"chacha20-ietf", | |||
"aes-256-cfb", | |||
"aes-192-cfb", | |||
"aes-128-cfb", | |||
"aes-256-ctr", | |||
"aes-192-ctr", | |||
"aes-128-ctr", | |||
"bf-cfb", | |||
"camellia-128-cfb", | |||
"camellia-192-cfb", | |||
"camellia-256-cfb", | |||
"aes-128-gcm", | |||
"aes-192-gcm", | |||
"aes-256-gcm", | |||
"chacha20-ietf-poly1305", | |||
"xchacha20-ietf-poly1305"}); | |||
this.EncryptionSelect.Location = new System.Drawing.Point(113, 109); | |||
this.EncryptionSelect.ItemHeight = 15; | |||
this.EncryptionSelect.Location = new System.Drawing.Point(151, 134); | |||
this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4); | |||
this.EncryptionSelect.Name = "EncryptionSelect"; | |||
this.EncryptionSelect.Size = new System.Drawing.Size(160, 20); | |||
this.EncryptionSelect.Size = new System.Drawing.Size(235, 23); | |||
this.EncryptionSelect.TabIndex = 4; | |||
// | |||
// TimeoutLabel | |||
// | |||
this.TimeoutLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.TimeoutLabel.AutoSize = true; | |||
this.TimeoutLabel.Location = new System.Drawing.Point(30, 269); | |||
this.TimeoutLabel.Location = new System.Drawing.Point(40, 329); | |||
this.TimeoutLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.TimeoutLabel.Name = "TimeoutLabel"; | |||
this.TimeoutLabel.RightToLeft = System.Windows.Forms.RightToLeft.No; | |||
this.TimeoutLabel.Size = new System.Drawing.Size(77, 12); | |||
this.TimeoutLabel.Size = new System.Drawing.Size(103, 15); | |||
this.TimeoutLabel.TabIndex = 9; | |||
this.TimeoutLabel.Text = "Timeout(Sec)"; | |||
// | |||
// TimeoutTextBox | |||
// | |||
this.TimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.TimeoutTextBox.Location = new System.Drawing.Point(113, 265); | |||
this.TimeoutTextBox.Location = new System.Drawing.Point(151, 324); | |||
this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.TimeoutTextBox.MaxLength = 5; | |||
this.TimeoutTextBox.Name = "TimeoutTextBox"; | |||
this.TimeoutTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.TimeoutTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.TimeoutTextBox.TabIndex = 9; | |||
// | |||
// PluginLabel | |||
// | |||
this.PluginLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.PluginLabel.AutoSize = true; | |||
this.PluginLabel.Location = new System.Drawing.Point(18, 139); | |||
this.PluginLabel.Location = new System.Drawing.Point(24, 170); | |||
this.PluginLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.PluginLabel.Name = "PluginLabel"; | |||
this.PluginLabel.Size = new System.Drawing.Size(89, 12); | |||
this.PluginLabel.Size = new System.Drawing.Size(119, 15); | |||
this.PluginLabel.TabIndex = 5; | |||
this.PluginLabel.Text = "Plugin Program"; | |||
// | |||
// PluginOptionsTextBox | |||
// | |||
this.PluginOptionsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.PluginOptionsTextBox.Location = new System.Drawing.Point(113, 162); | |||
this.PluginOptionsTextBox.Location = new System.Drawing.Point(151, 198); | |||
this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.PluginOptionsTextBox.MaxLength = 256; | |||
this.PluginOptionsTextBox.Name = "PluginOptionsTextBox"; | |||
this.PluginOptionsTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.PluginOptionsTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.PluginOptionsTextBox.TabIndex = 6; | |||
this.PluginOptionsTextBox.WordWrap = false; | |||
// | |||
@@ -307,9 +303,10 @@ | |||
this.ShowPasswdCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | |||
| System.Windows.Forms.AnchorStyles.Left))); | |||
this.ShowPasswdCheckBox.AutoSize = true; | |||
this.ShowPasswdCheckBox.Location = new System.Drawing.Point(113, 87); | |||
this.ShowPasswdCheckBox.Location = new System.Drawing.Point(151, 107); | |||
this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.ShowPasswdCheckBox.Name = "ShowPasswdCheckBox"; | |||
this.ShowPasswdCheckBox.Size = new System.Drawing.Size(102, 16); | |||
this.ShowPasswdCheckBox.Size = new System.Drawing.Size(133, 19); | |||
this.ShowPasswdCheckBox.TabIndex = 3; | |||
this.ShowPasswdCheckBox.Text = "Show Password"; | |||
this.ShowPasswdCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; | |||
@@ -319,10 +316,11 @@ | |||
// PluginArgumentsTextBox | |||
// | |||
this.PluginArgumentsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | |||
this.PluginArgumentsTextBox.Location = new System.Drawing.Point(113, 211); | |||
this.PluginArgumentsTextBox.Location = new System.Drawing.Point(151, 258); | |||
this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.PluginArgumentsTextBox.MaxLength = 512; | |||
this.PluginArgumentsTextBox.Name = "PluginArgumentsTextBox"; | |||
this.PluginArgumentsTextBox.Size = new System.Drawing.Size(160, 21); | |||
this.PluginArgumentsTextBox.Size = new System.Drawing.Size(235, 25); | |||
this.PluginArgumentsTextBox.TabIndex = 7; | |||
this.PluginArgumentsTextBox.WordWrap = false; | |||
// | |||
@@ -330,9 +328,10 @@ | |||
// | |||
this.PluginArgumentsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.PluginArgumentsLabel.AutoSize = true; | |||
this.PluginArgumentsLabel.Location = new System.Drawing.Point(6, 215); | |||
this.PluginArgumentsLabel.Location = new System.Drawing.Point(8, 263); | |||
this.PluginArgumentsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.PluginArgumentsLabel.Name = "PluginArgumentsLabel"; | |||
this.PluginArgumentsLabel.Size = new System.Drawing.Size(101, 12); | |||
this.PluginArgumentsLabel.Size = new System.Drawing.Size(135, 15); | |||
this.PluginArgumentsLabel.TabIndex = 7; | |||
this.PluginArgumentsLabel.Text = "Plugin Arguments"; | |||
this.toolTip1.SetToolTip(this.PluginArgumentsLabel, "Not a SIP003 standard. Used as CLI arguments.\r\nMandatory:\r\n%SS_LOCAL_HOST%, %SS_L" + | |||
@@ -342,18 +341,20 @@ | |||
// | |||
this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.RemarksLabel.AutoSize = true; | |||
this.RemarksLabel.Location = new System.Drawing.Point(60, 242); | |||
this.RemarksLabel.Location = new System.Drawing.Point(80, 296); | |||
this.RemarksLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.RemarksLabel.Name = "RemarksLabel"; | |||
this.RemarksLabel.Size = new System.Drawing.Size(47, 12); | |||
this.RemarksLabel.Size = new System.Drawing.Size(63, 15); | |||
this.RemarksLabel.TabIndex = 8; | |||
this.RemarksLabel.Text = "Remarks"; | |||
// | |||
// NeedPluginArgCheckBox | |||
// | |||
this.NeedPluginArgCheckBox.AutoSize = true; | |||
this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(113, 189); | |||
this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(151, 231); | |||
this.NeedPluginArgCheckBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.NeedPluginArgCheckBox.Name = "NeedPluginArgCheckBox"; | |||
this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(144, 16); | |||
this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(189, 19); | |||
this.NeedPluginArgCheckBox.TabIndex = 10; | |||
this.NeedPluginArgCheckBox.Text = "Need Plugin Argument"; | |||
this.NeedPluginArgCheckBox.UseVisualStyleBackColor = true; | |||
@@ -364,7 +365,8 @@ | |||
this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; | |||
this.panel2.AutoSize = true; | |||
this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||
this.panel2.Location = new System.Drawing.Point(165, 187); | |||
this.panel2.Location = new System.Drawing.Point(206, 234); | |||
this.panel2.Margin = new System.Windows.Forms.Padding(4); | |||
this.panel2.Name = "panel2"; | |||
this.panel2.Size = new System.Drawing.Size(0, 0); | |||
this.panel2.TabIndex = 1; | |||
@@ -373,10 +375,10 @@ | |||
// | |||
this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; | |||
this.OKButton.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.OKButton.Location = new System.Drawing.Point(3, 3); | |||
this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); | |||
this.OKButton.Location = new System.Drawing.Point(4, 4); | |||
this.OKButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0); | |||
this.OKButton.Name = "OKButton"; | |||
this.OKButton.Size = new System.Drawing.Size(75, 23); | |||
this.OKButton.Size = new System.Drawing.Size(94, 29); | |||
this.OKButton.TabIndex = 17; | |||
this.OKButton.Text = "OK"; | |||
this.OKButton.UseVisualStyleBackColor = true; | |||
@@ -386,10 +388,10 @@ | |||
// | |||
this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; | |||
this.MyCancelButton.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.MyCancelButton.Location = new System.Drawing.Point(84, 3); | |||
this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); | |||
this.MyCancelButton.Location = new System.Drawing.Point(106, 4); | |||
this.MyCancelButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0); | |||
this.MyCancelButton.Name = "MyCancelButton"; | |||
this.MyCancelButton.Size = new System.Drawing.Size(75, 23); | |||
this.MyCancelButton.Size = new System.Drawing.Size(94, 29); | |||
this.MyCancelButton.TabIndex = 18; | |||
this.MyCancelButton.Text = "Cancel"; | |||
this.MyCancelButton.UseVisualStyleBackColor = true; | |||
@@ -399,10 +401,10 @@ | |||
// | |||
this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.ApplyButton.Enabled = false; | |||
this.ApplyButton.Location = new System.Drawing.Point(165, 3); | |||
this.ApplyButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); | |||
this.ApplyButton.Location = new System.Drawing.Point(208, 4); | |||
this.ApplyButton.Margin = new System.Windows.Forms.Padding(4, 4, 0, 0); | |||
this.ApplyButton.Name = "ApplyButton"; | |||
this.ApplyButton.Size = new System.Drawing.Size(75, 23); | |||
this.ApplyButton.Size = new System.Drawing.Size(94, 29); | |||
this.ApplyButton.TabIndex = 19; | |||
this.ApplyButton.Text = "Apply"; | |||
this.ApplyButton.UseVisualStyleBackColor = true; | |||
@@ -411,10 +413,10 @@ | |||
// DeleteButton | |||
// | |||
this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.DeleteButton.Location = new System.Drawing.Point(86, 6); | |||
this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); | |||
this.DeleteButton.Location = new System.Drawing.Point(108, 8); | |||
this.DeleteButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4); | |||
this.DeleteButton.Name = "DeleteButton"; | |||
this.DeleteButton.Size = new System.Drawing.Size(80, 23); | |||
this.DeleteButton.Size = new System.Drawing.Size(100, 29); | |||
this.DeleteButton.TabIndex = 13; | |||
this.DeleteButton.Text = "&Delete"; | |||
this.DeleteButton.UseVisualStyleBackColor = true; | |||
@@ -423,10 +425,10 @@ | |||
// AddButton | |||
// | |||
this.AddButton.Dock = System.Windows.Forms.DockStyle.Left; | |||
this.AddButton.Location = new System.Drawing.Point(0, 6); | |||
this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); | |||
this.AddButton.Location = new System.Drawing.Point(0, 8); | |||
this.AddButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); | |||
this.AddButton.Name = "AddButton"; | |||
this.AddButton.Size = new System.Drawing.Size(80, 23); | |||
this.AddButton.Size = new System.Drawing.Size(100, 29); | |||
this.AddButton.TabIndex = 12; | |||
this.AddButton.Text = "&Add"; | |||
this.AddButton.UseVisualStyleBackColor = true; | |||
@@ -437,10 +439,11 @@ | |||
this.ServerGroupBox.AutoSize = true; | |||
this.ServerGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||
this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); | |||
this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); | |||
this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); | |||
this.ServerGroupBox.Location = new System.Drawing.Point(223, 0); | |||
this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0); | |||
this.ServerGroupBox.Name = "ServerGroupBox"; | |||
this.ServerGroupBox.Size = new System.Drawing.Size(290, 330); | |||
this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4); | |||
this.ServerGroupBox.Size = new System.Drawing.Size(408, 405); | |||
this.ServerGroupBox.TabIndex = 0; | |||
this.ServerGroupBox.TabStop = false; | |||
this.ServerGroupBox.Text = "Server"; | |||
@@ -449,11 +452,11 @@ | |||
// | |||
this.ServersListBox.FormattingEnabled = true; | |||
this.ServersListBox.IntegralHeight = false; | |||
this.ServersListBox.ItemHeight = 12; | |||
this.ServersListBox.ItemHeight = 15; | |||
this.ServersListBox.Location = new System.Drawing.Point(0, 0); | |||
this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); | |||
this.ServersListBox.Name = "ServersListBox"; | |||
this.ServersListBox.Size = new System.Drawing.Size(166, 148); | |||
this.ServersListBox.Size = new System.Drawing.Size(206, 184); | |||
this.ServersListBox.TabIndex = 11; | |||
this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); | |||
// | |||
@@ -470,14 +473,14 @@ | |||
this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0); | |||
this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0); | |||
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 1); | |||
this.tableLayoutPanel2.Location = new System.Drawing.Point(12, 12); | |||
this.tableLayoutPanel2.Location = new System.Drawing.Point(15, 15); | |||
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); | |||
this.tableLayoutPanel2.Name = "tableLayoutPanel2"; | |||
this.tableLayoutPanel2.RowCount = 3; | |||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel2.Size = new System.Drawing.Size(468, 426); | |||
this.tableLayoutPanel2.Size = new System.Drawing.Size(631, 528); | |||
this.tableLayoutPanel2.TabIndex = 7; | |||
// | |||
// tableLayoutPanel6 | |||
@@ -490,21 +493,21 @@ | |||
this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0); | |||
this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0); | |||
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top; | |||
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 394); | |||
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 487); | |||
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); | |||
this.tableLayoutPanel6.Name = "tableLayoutPanel6"; | |||
this.tableLayoutPanel6.RowCount = 1; | |||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel6.Size = new System.Drawing.Size(166, 32); | |||
this.tableLayoutPanel6.Size = new System.Drawing.Size(208, 41); | |||
this.tableLayoutPanel6.TabIndex = 10; | |||
// | |||
// MoveDownButton | |||
// | |||
this.MoveDownButton.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.MoveDownButton.Location = new System.Drawing.Point(86, 6); | |||
this.MoveDownButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); | |||
this.MoveDownButton.Location = new System.Drawing.Point(108, 8); | |||
this.MoveDownButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4); | |||
this.MoveDownButton.Name = "MoveDownButton"; | |||
this.MoveDownButton.Size = new System.Drawing.Size(80, 23); | |||
this.MoveDownButton.Size = new System.Drawing.Size(100, 29); | |||
this.MoveDownButton.TabIndex = 16; | |||
this.MoveDownButton.Text = "Move D&own"; | |||
this.MoveDownButton.UseVisualStyleBackColor = true; | |||
@@ -513,10 +516,10 @@ | |||
// MoveUpButton | |||
// | |||
this.MoveUpButton.Dock = System.Windows.Forms.DockStyle.Left; | |||
this.MoveUpButton.Location = new System.Drawing.Point(0, 6); | |||
this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); | |||
this.MoveUpButton.Location = new System.Drawing.Point(0, 8); | |||
this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); | |||
this.MoveUpButton.Name = "MoveUpButton"; | |||
this.MoveUpButton.Size = new System.Drawing.Size(80, 23); | |||
this.MoveUpButton.Size = new System.Drawing.Size(100, 29); | |||
this.MoveUpButton.TabIndex = 15; | |||
this.MoveUpButton.Text = "Move &Up"; | |||
this.MoveUpButton.UseVisualStyleBackColor = true; | |||
@@ -534,23 +537,24 @@ | |||
this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0); | |||
this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0); | |||
this.tableLayoutPanel5.Controls.Add(this.PortableModeCheckBox, 0, 1); | |||
this.tableLayoutPanel5.Location = new System.Drawing.Point(166, 330); | |||
this.tableLayoutPanel5.Location = new System.Drawing.Point(208, 405); | |||
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); | |||
this.tableLayoutPanel5.Name = "tableLayoutPanel5"; | |||
this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3); | |||
this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(4); | |||
this.tableLayoutPanel5.RowCount = 2; | |||
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel5.Size = new System.Drawing.Size(196, 64); | |||
this.tableLayoutPanel5.Size = new System.Drawing.Size(251, 82); | |||
this.tableLayoutPanel5.TabIndex = 9; | |||
// | |||
// ProxyPortTextBox | |||
// | |||
this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; | |||
this.ProxyPortTextBox.Location = new System.Drawing.Point(77, 6); | |||
this.ProxyPortTextBox.Location = new System.Drawing.Point(103, 8); | |||
this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.ProxyPortTextBox.MaxLength = 10; | |||
this.ProxyPortTextBox.Name = "ProxyPortTextBox"; | |||
this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 21); | |||
this.ProxyPortTextBox.Size = new System.Drawing.Size(140, 25); | |||
this.ProxyPortTextBox.TabIndex = 10; | |||
this.ProxyPortTextBox.WordWrap = false; | |||
// | |||
@@ -558,9 +562,10 @@ | |||
// | |||
this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||
this.ProxyPortLabel.AutoSize = true; | |||
this.ProxyPortLabel.Location = new System.Drawing.Point(6, 10); | |||
this.ProxyPortLabel.Location = new System.Drawing.Point(8, 13); | |||
this.ProxyPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); | |||
this.ProxyPortLabel.Name = "ProxyPortLabel"; | |||
this.ProxyPortLabel.Size = new System.Drawing.Size(65, 12); | |||
this.ProxyPortLabel.Size = new System.Drawing.Size(87, 15); | |||
this.ProxyPortLabel.TabIndex = 10; | |||
this.ProxyPortLabel.Text = "Proxy Port"; | |||
// | |||
@@ -569,9 +574,10 @@ | |||
this.PortableModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; | |||
this.PortableModeCheckBox.AutoSize = true; | |||
this.tableLayoutPanel5.SetColumnSpan(this.PortableModeCheckBox, 2); | |||
this.PortableModeCheckBox.Location = new System.Drawing.Point(6, 37); | |||
this.PortableModeCheckBox.Location = new System.Drawing.Point(8, 48); | |||
this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4); | |||
this.PortableModeCheckBox.Name = "PortableModeCheckBox"; | |||
this.PortableModeCheckBox.Size = new System.Drawing.Size(102, 16); | |||
this.PortableModeCheckBox.Size = new System.Drawing.Size(133, 19); | |||
this.PortableModeCheckBox.TabIndex = 11; | |||
this.PortableModeCheckBox.Text = "Portable Mode"; | |||
this.toolTip1.SetToolTip(this.PortableModeCheckBox, "restart required"); | |||
@@ -585,17 +591,17 @@ | |||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); | |||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F)); | |||
this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); | |||
this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); | |||
this.tableLayoutPanel3.Controls.Add(this.ApplyButton, 2, 0); | |||
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; | |||
this.tableLayoutPanel3.Location = new System.Drawing.Point(228, 397); | |||
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); | |||
this.tableLayoutPanel3.Location = new System.Drawing.Point(329, 491); | |||
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(4, 4, 0, 4); | |||
this.tableLayoutPanel3.Name = "tableLayoutPanel3"; | |||
this.tableLayoutPanel3.RowCount = 1; | |||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel3.Size = new System.Drawing.Size(240, 26); | |||
this.tableLayoutPanel3.Size = new System.Drawing.Size(302, 33); | |||
this.tableLayoutPanel3.TabIndex = 8; | |||
// | |||
// tableLayoutPanel4 | |||
@@ -609,22 +615,22 @@ | |||
this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); | |||
this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); | |||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; | |||
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 330); | |||
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 405); | |||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); | |||
this.tableLayoutPanel4.Name = "tableLayoutPanel4"; | |||
this.tableLayoutPanel4.RowCount = 2; | |||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||
this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 64); | |||
this.tableLayoutPanel4.Size = new System.Drawing.Size(208, 82); | |||
this.tableLayoutPanel4.TabIndex = 8; | |||
// | |||
// DuplicateButton | |||
// | |||
this.DuplicateButton.Dock = System.Windows.Forms.DockStyle.Left; | |||
this.DuplicateButton.Location = new System.Drawing.Point(0, 38); | |||
this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); | |||
this.DuplicateButton.Location = new System.Drawing.Point(0, 49); | |||
this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); | |||
this.DuplicateButton.Name = "DuplicateButton"; | |||
this.DuplicateButton.Size = new System.Drawing.Size(80, 23); | |||
this.DuplicateButton.Size = new System.Drawing.Size(100, 29); | |||
this.DuplicateButton.TabIndex = 14; | |||
this.DuplicateButton.Text = "Dupli&cate"; | |||
this.DuplicateButton.UseVisualStyleBackColor = true; | |||
@@ -633,19 +639,20 @@ | |||
// ConfigForm | |||
// | |||
this.AcceptButton = this.OKButton; | |||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); | |||
this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); | |||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; | |||
this.AutoSize = true; | |||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||
this.CancelButton = this.MyCancelButton; | |||
this.ClientSize = new System.Drawing.Size(491, 438); | |||
this.ClientSize = new System.Drawing.Size(614, 548); | |||
this.Controls.Add(this.tableLayoutPanel2); | |||
this.Controls.Add(this.panel2); | |||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | |||
this.Margin = new System.Windows.Forms.Padding(4); | |||
this.MaximizeBox = false; | |||
this.MinimizeBox = false; | |||
this.Name = "ConfigForm"; | |||
this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9); | |||
this.Padding = new System.Windows.Forms.Padding(15, 15, 15, 11); | |||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |||
this.Text = "Edit Servers"; | |||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); | |||
@@ -2,7 +2,9 @@ using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Drawing; | |||
using System.Linq; | |||
using System.Windows.Forms; | |||
namespace Shadowsocks.View | |||
@@ -17,10 +19,86 @@ namespace Shadowsocks.View | |||
private bool isChange = false; | |||
private class EncryptionMethod | |||
{ | |||
public readonly string name; | |||
public readonly bool deprecated; | |||
// Edit here to add/delete encryption method displayed in UI | |||
private static string[] deprecatedMethod = new string[] | |||
{ | |||
"rc4-md5", | |||
"salsa20", | |||
"chacha20", | |||
"bf-cfb", | |||
"chacha20-ietf", | |||
"aes-256-cfb", | |||
"aes-192-cfb", | |||
"aes-128-cfb", | |||
"aes-256-ctr", | |||
"aes-192-ctr", | |||
"aes-128-ctr", | |||
"camellia-256-cfb", | |||
"camellia-192-cfb", | |||
"camellia-128-cfb", | |||
}; | |||
private static string[] inuseMethod = new string[] | |||
{ | |||
"aes-256-gcm", | |||
"aes-192-gcm", | |||
"aes-128-gcm", | |||
"chacha20-ietf-poly1305", | |||
"xchacha20-ietf-poly1305", | |||
}; | |||
public static EncryptionMethod[] AllMethods | |||
{ | |||
get | |||
{ | |||
if (!init) Init(); | |||
return allMethods; | |||
} | |||
} | |||
private static bool init = false; | |||
private static EncryptionMethod[] allMethods; | |||
private static Dictionary<string, EncryptionMethod> methodByName = new Dictionary<string, EncryptionMethod>(); | |||
private static void Init() | |||
{ | |||
var all = new List<EncryptionMethod>(); | |||
all.AddRange(inuseMethod.Select(i => new EncryptionMethod(i, false))); | |||
all.AddRange(deprecatedMethod.Select(d => new EncryptionMethod(d, true))); | |||
allMethods = all.ToArray(); | |||
foreach (var item in all) | |||
{ | |||
methodByName[item.name] = item; | |||
} | |||
init = true; | |||
} | |||
public static EncryptionMethod GetMethod(string name) | |||
{ | |||
if (!init) Init(); | |||
return methodByName[name]; | |||
} | |||
private EncryptionMethod(string name, bool deprecated) | |||
{ | |||
this.name = name; | |||
this.deprecated = deprecated; | |||
} | |||
public override string ToString() | |||
{ | |||
return deprecated ? $"{name} ({I18N.GetString("deprecated")})" : name; | |||
} | |||
} | |||
public ConfigForm(ShadowsocksController controller) | |||
{ | |||
Font = SystemFonts.MessageBoxFont; | |||
InitializeComponent(); | |||
EncryptionSelect.Items.AddRange(EncryptionMethod.AllMethods); | |||
// a dirty hack | |||
ServersListBox.Dock = DockStyle.Fill; | |||
@@ -115,7 +193,7 @@ namespace Shadowsocks.View | |||
server = address, | |||
server_port = addressPort.Value, | |||
password = serverPassword, | |||
method = EncryptionSelect.Text, | |||
method = ((EncryptionMethod)EncryptionSelect.SelectedItem).name, | |||
plugin = PluginTextBox.Text, | |||
plugin_opts = PluginOptionsTextBox.Text, | |||
plugin_args = PluginArgumentsTextBox.Text, | |||
@@ -316,7 +394,7 @@ namespace Shadowsocks.View | |||
IPTextBox.Text = server.server; | |||
ServerPortTextBox.Text = server.server_port.ToString(); | |||
PasswordTextBox.Text = server.password; | |||
EncryptionSelect.Text = server.method ?? Server.DefaultMethod; | |||
EncryptionSelect.SelectedItem = EncryptionMethod.GetMethod(server.method ?? Server.DefaultMethod); | |||
PluginTextBox.Text = server.plugin; | |||
PluginOptionsTextBox.Text = server.plugin_opts; | |||
PluginArgumentsTextBox.Text = server.plugin_args; | |||
@@ -11,11 +11,14 @@ using Shadowsocks.Properties; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util; | |||
using System.Text; | |||
using NLog; | |||
namespace Shadowsocks.View | |||
{ | |||
public partial class LogForm : Form | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
long lastOffset; | |||
string filename; | |||
Timer timer; | |||
@@ -38,13 +41,27 @@ namespace Shadowsocks.View | |||
TextAnnotation outboundAnnotation = new TextAnnotation(); | |||
#endregion | |||
public LogForm(ShadowsocksController controller, string filename) | |||
public LogForm(ShadowsocksController controller) | |||
{ | |||
this.controller = controller; | |||
this.filename = filename; | |||
InitializeComponent(); | |||
Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||
var nLogConfig = NLogConfig.LoadXML(); | |||
try | |||
{ | |||
this.filename = nLogConfig.GetLogFileName(); | |||
} | |||
catch(Exception) | |||
{ | |||
// failed to get the file name | |||
} | |||
if (string.IsNullOrEmpty(this.filename)) | |||
{ | |||
LogMessageTextBox.AppendText("Cannot get the log file name from NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); | |||
} | |||
LogViewerConfig config = controller.GetConfigurationCopy().logViewer; | |||
topMostTrigger = config.topMost; | |||
@@ -158,6 +175,8 @@ namespace Shadowsocks.View | |||
private void InitContent() | |||
{ | |||
if (string.IsNullOrEmpty(filename) || !File.Exists(filename)) | |||
return; | |||
using (StreamReader reader = new StreamReader(new FileStream(filename, | |||
FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) | |||
{ | |||
@@ -170,7 +189,7 @@ namespace Shadowsocks.View | |||
string line = ""; | |||
StringBuilder appendText = new StringBuilder(1024); | |||
while ((line = reader.ReadLine()) != null) | |||
appendText.Append(line + Environment.NewLine); | |||
appendText.AppendLine(line); | |||
LogMessageTextBox.AppendText(appendText.ToString()); | |||
LogMessageTextBox.ScrollToCaret(); | |||
@@ -181,6 +200,11 @@ namespace Shadowsocks.View | |||
private void UpdateContent() | |||
{ | |||
this.Text = I18N.GetString("Log Viewer") + | |||
$" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]"; | |||
if (string.IsNullOrEmpty(filename) || !File.Exists(filename)) | |||
return; | |||
try | |||
{ | |||
using (StreamReader reader = new StreamReader(new FileStream(filename, | |||
@@ -194,7 +218,7 @@ namespace Shadowsocks.View | |||
while ((line = reader.ReadLine()) != null) | |||
{ | |||
changed = true; | |||
appendText.Append(line + Environment.NewLine); | |||
appendText.AppendLine(line); | |||
} | |||
if (changed) | |||
@@ -209,9 +233,6 @@ namespace Shadowsocks.View | |||
catch (FileNotFoundException) | |||
{ | |||
} | |||
this.Text = I18N.GetString("Log Viewer") + | |||
$" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]"; | |||
} | |||
private void LogForm_Load(object sender, EventArgs e) | |||
@@ -270,7 +291,7 @@ namespace Shadowsocks.View | |||
private void OpenLocationMenuItem_Click(object sender, EventArgs e) | |||
{ | |||
string argument = "/select, \"" + filename + "\""; | |||
Logging.Debug(argument); | |||
logger.Debug(argument); | |||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||
} | |||
@@ -287,7 +308,11 @@ namespace Shadowsocks.View | |||
#region Clean up the content in LogMessageTextBox. | |||
private void DoClearLogs() | |||
{ | |||
Logging.Clear(); | |||
try | |||
{ | |||
File.Delete(filename); | |||
} | |||
catch { } | |||
lastOffset = 0; | |||
LogMessageTextBox.Clear(); | |||
} | |||
@@ -317,7 +342,7 @@ namespace Shadowsocks.View | |||
} | |||
catch (Exception ex) | |||
{ | |||
Logging.LogUsefulException(ex); | |||
logger.LogUsefulException(ex); | |||
MessageBox.Show(ex.Message); | |||
} | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using Shadowsocks.Controller; | |||
using NLog; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
@@ -17,6 +18,7 @@ namespace Shadowsocks.View | |||
{ | |||
public class MenuViewController | |||
{ | |||
private static Logger logger = LogManager.GetCurrentClassLogger(); | |||
// yes this is just a menu view controller | |||
// when config form is closed, it moves away from RAM | |||
// and it should just do anything related to the config form | |||
@@ -220,7 +222,7 @@ namespace Shadowsocks.View | |||
{ | |||
Color colorMask = Color.White; | |||
Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(controller.GetCurrentConfiguration().isVerboseLogging); | |||
Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); | |||
if (isProxyEnabled) | |||
{ | |||
@@ -372,7 +374,7 @@ namespace Shadowsocks.View | |||
{ | |||
string argument = @"/select, " + e.Path; | |||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||
Process.Start("explorer.exe", argument); | |||
} | |||
void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) | |||
@@ -386,7 +388,7 @@ namespace Shadowsocks.View | |||
void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e) | |||
{ | |||
ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); | |||
Logging.LogUsefulException(e.GetException()); | |||
logger.LogUsefulException(e.GetException()); | |||
} | |||
void controller_UpdatePACFromGFWListCompleted(object sender, GFWListUpdater.ResultEventArgs e) | |||
@@ -415,10 +417,10 @@ namespace Shadowsocks.View | |||
if (updateChecker.NewVersionFound) | |||
{ | |||
updateChecker.NewVersionFound = false; /* Reset the flag */ | |||
if (System.IO.File.Exists(updateChecker.LatestVersionLocalName)) | |||
if (File.Exists(updateChecker.LatestVersionLocalName)) | |||
{ | |||
string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; | |||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||
Process.Start("explorer.exe", argument); | |||
} | |||
} | |||
} | |||
@@ -454,30 +456,30 @@ namespace Shadowsocks.View | |||
{ | |||
items.RemoveAt(0); | |||
} | |||
int i = 0; | |||
int strategyCount = 0; | |||
foreach (var strategy in controller.GetStrategies()) | |||
{ | |||
MenuItem item = new MenuItem(strategy.Name); | |||
item.Tag = strategy.ID; | |||
item.Click += AStrategyItem_Click; | |||
items.Add(i, item); | |||
i++; | |||
items.Add(strategyCount, item); | |||
strategyCount++; | |||
} | |||
// user wants a seperator item between strategy and servers menugroup | |||
items.Add(i++, new MenuItem("-")); | |||
items.Add(strategyCount++, new MenuItem("-")); | |||
int strategyCount = i; | |||
int serverCount = 0; | |||
Configuration configuration = controller.GetConfigurationCopy(); | |||
foreach (var server in configuration.configs) | |||
{ | |||
if (Configuration.ChecksServer(server)) | |||
{ | |||
MenuItem item = new MenuItem(server.FriendlyName()); | |||
item.Tag = i - strategyCount; | |||
item.Tag = configuration.configs.FindIndex(s => s == server); | |||
item.Click += AServerItem_Click; | |||
items.Add(i, item); | |||
i++; | |||
items.Add(strategyCount + serverCount, item); | |||
serverCount++; | |||
} | |||
} | |||
@@ -543,7 +545,7 @@ namespace Shadowsocks.View | |||
} | |||
else | |||
{ | |||
logForm = new LogForm(controller, Logging.LogFilePath); | |||
logForm = new LogForm(controller); | |||
logForm.Show(); | |||
logForm.Activate(); | |||
logForm.FormClosed += logForm_FormClosed; | |||
@@ -565,7 +567,12 @@ namespace Shadowsocks.View | |||
if (_isFirstRun) | |||
{ | |||
CheckUpdateForFirstRun(); | |||
ShowFirstTimeBalloon(); | |||
ShowBalloonTip( | |||
I18N.GetString("Shadowsocks is here"), | |||
I18N.GetString("You can turn on/off Shadowsocks in the context menu"), | |||
ToolTipIcon.Info, | |||
0 | |||
); | |||
_isFirstRun = false; | |||
} | |||
} | |||
@@ -604,14 +611,6 @@ namespace Shadowsocks.View | |||
updateChecker.CheckUpdate(config, 3000); | |||
} | |||
private void ShowFirstTimeBalloon() | |||
{ | |||
_notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here"); | |||
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); | |||
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; | |||
_notifyIcon.ShowBalloonTip(0); | |||
} | |||
private void AboutItem_Click(object sender, EventArgs e) | |||
{ | |||
Process.Start("https://github.com/shadowsocks/shadowsocks-windows"); | |||
@@ -481,6 +481,7 @@ | |||
this.MinimumSize = new System.Drawing.Size(1000, 800); | |||
this.Name = "StatisticsStrategyConfigurationForm"; | |||
this.Text = "StatisticsStrategyConfigurationForm"; | |||
this.Text = "Statistics configuration"; | |||
((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).EndInit(); | |||
this.chartModeSelector.ResumeLayout(false); | |||
this.chartModeSelector.PerformLayout(); | |||
@@ -2,6 +2,7 @@ | |||
<packages> | |||
<package id="GlobalHotKey" version="1.1.0" targetFramework="net472" /> | |||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" /> | |||
<package id="NLog" version="4.6.8" targetFramework="net472" /> | |||
<package id="StringEx.CS" version="0.3.1" targetFramework="net472" developmentDependency="true" /> | |||
<package id="ZXing.Net" version="0.16.5" targetFramework="net472" /> | |||
</packages> |
@@ -74,12 +74,21 @@ | |||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> | |||
</Reference> | |||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\NLog.4.6.8\lib\net45\NLog.dll</HintPath> | |||
</Reference> | |||
<Reference Include="PresentationCore" /> | |||
<Reference Include="System" /> | |||
<Reference Include="System.Configuration" /> | |||
<Reference Include="System.Data" /> | |||
<Reference Include="System.Data.DataSetExtensions" /> | |||
<Reference Include="System.Drawing" /> | |||
<Reference Include="System.IO.Compression" /> | |||
<Reference Include="System.Management" /> | |||
<Reference Include="System.Net" /> | |||
<Reference Include="System.Runtime.Serialization" /> | |||
<Reference Include="System.ServiceModel" /> | |||
<Reference Include="System.Transactions" /> | |||
<Reference Include="System.Web" /> | |||
<Reference Include="System.Windows.Forms" /> | |||
<Reference Include="System.Windows.Forms.DataVisualization" /> | |||
@@ -94,6 +103,7 @@ | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="Controller\HotkeyReg.cs" /> | |||
<Compile Include="Controller\LoggerExtension.cs" /> | |||
<Compile Include="Controller\Service\PACDaemon.cs" /> | |||
<Compile Include="Controller\System\Hotkeys\HotkeyCallbacks.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | |||
@@ -114,6 +124,7 @@ | |||
<Compile Include="Encryption\Stream\StreamOpenSSLEncryptor.cs" /> | |||
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" /> | |||
<Compile Include="Model\HotKeyConfig.cs" /> | |||
<Compile Include="Model\NLogConfig.cs" /> | |||
<Compile Include="Model\ProxyConfig.cs" /> | |||
<Compile Include="Model\SysproxyConfig.cs" /> | |||
<Compile Include="Properties\Resources.Designer.cs"> | |||
@@ -137,7 +148,6 @@ | |||
<Compile Include="Controller\Service\GFWListUpdater.cs" /> | |||
<Compile Include="Controller\I18N.cs" /> | |||
<Compile Include="Controller\Service\Listener.cs" /> | |||
<Compile Include="Controller\Logging.cs" /> | |||
<Compile Include="Controller\Service\PortForwarder.cs" /> | |||
<Compile Include="Controller\Service\UDPRelay.cs" /> | |||
<Compile Include="Controller\Service\UpdateChecker.cs" /> | |||
@@ -292,6 +302,10 @@ | |||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
<TargetPath>user-rule.txt</TargetPath> | |||
</ContentWithTargetPath> | |||
<ContentWithTargetPath Include="Data\nlog.config"> | |||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
<TargetPath>nlog.config</TargetPath> | |||
</ContentWithTargetPath> | |||
<Content Include="Resources\ss32Fill.png" /> | |||
<Content Include="Resources\ss32In.png" /> | |||
<Content Include="Resources\ss32Out.png" /> | |||
@@ -1,7 +1,7 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio 15 | |||
VisualStudioVersion = 15.0.26228.10 | |||
# Visual Studio Version 16 | |||
VisualStudioVersion = 16.0.29709.97 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" | |||
EndProject | |||
@@ -12,21 +12,30 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowsocksTest", "test\Sha | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
Debug|x86 = Debug|x86 | |||
Release|Any CPU = Release|Any CPU | |||
Release|x86 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|Any CPU.ActiveCfg = Debug|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|Any CPU.ActiveCfg = Release|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|Any CPU.ActiveCfg = Debug|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|Any CPU.ActiveCfg = Release|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {F7E7D35B-4FDA-4385-95CF-09DADED042EA} | |||
EndGlobalSection | |||
EndGlobal |