From ee7056c080594ea4958c7578f7df7af3c8154a62 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Fri, 12 Dec 2014 18:59:05 +0800 Subject: [PATCH 01/39] add libsodium --- shadowsocks-csharp/Data/libsodium.dll.gz | Bin 0 -> 9989 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 shadowsocks-csharp/Data/libsodium.dll.gz diff --git a/shadowsocks-csharp/Data/libsodium.dll.gz b/shadowsocks-csharp/Data/libsodium.dll.gz new file mode 100755 index 0000000000000000000000000000000000000000..b4330a35d316e2c530978a0ab3b0080d4c523c70 GIT binary patch literal 9989 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 PY0duxW!TyW*HZuh@=27x literal 0 KcmV+b0RR6000031 From f62c0b92bb3af5482b1236d72f9d4395fabf7e6c Mon Sep 17 00:00:00 2001 From: clowwindy Date: Fri, 12 Dec 2014 23:55:24 +0800 Subject: [PATCH 02/39] refactor --- shadowsocks-csharp/Encrypt/IVEncryptor.cs | 158 ++++++++++++++++ shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs | 201 ++++----------------- shadowsocks-csharp/Encrypt/Sodium.cs | 39 ++++ shadowsocks-csharp/Encrypt/SodiumEncryptor.cs | 63 +++++++ .../Properties/Resources.Designer.cs | 10 + shadowsocks-csharp/Properties/Resources.resx | 3 + shadowsocks-csharp/shadowsocks-csharp.csproj | 4 + 7 files changed, 317 insertions(+), 161 deletions(-) create mode 100755 shadowsocks-csharp/Encrypt/IVEncryptor.cs create mode 100755 shadowsocks-csharp/Encrypt/Sodium.cs create mode 100755 shadowsocks-csharp/Encrypt/SodiumEncryptor.cs diff --git a/shadowsocks-csharp/Encrypt/IVEncryptor.cs b/shadowsocks-csharp/Encrypt/IVEncryptor.cs new file mode 100755 index 00000000..66883918 --- /dev/null +++ b/shadowsocks-csharp/Encrypt/IVEncryptor.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; + +namespace Shadowsocks.Encrypt +{ + public abstract class IVEncryptor + : EncryptorBase + { + protected static byte[] tempbuf = new byte[32768]; + + protected Dictionary ciphers; + + private static readonly Dictionary CachedKeys = new Dictionary(); + protected byte[] _encryptIV; + protected byte[] _decryptIV; + protected bool _decryptIVReceived; + protected bool _encryptIVSent; + protected int _encryptIVOffset = 0; + protected int _decryptIVOffset = 0; + protected string _method; + protected int _cipher; + protected int[] _cipherInfo; + protected byte[] _key; + protected int keyLen; + protected int ivLen; + + + public IVEncryptor(string method, string password) + : base(method, password) + { + InitKey(method, password); + } + + protected abstract Dictionary getCiphers(); + + protected void InitKey(string method, string password) + { + method = method.ToLower(); + _method = method; + string k = method + ":" + password; + ciphers = getCiphers(); + _cipherInfo = ciphers[_method]; + _cipher = _cipherInfo[2]; + if (_cipher == 0) + { + throw new Exception("method not found"); + } + keyLen = ciphers[_method][0]; + ivLen = ciphers[_method][1]; + if (CachedKeys.ContainsKey(k)) + { + _key = CachedKeys[k]; + } + else + { + byte[] passbuf = Encoding.UTF8.GetBytes(password); + _key = new byte[32]; + byte[] iv = new byte[16]; + bytesToKey(passbuf, _key); + CachedKeys[k] = _key; + } + } + + protected void bytesToKey(byte[] password, byte[] key) + { + byte[] result = new byte[password.Length + 16]; + int i = 0; + byte[] md5sum = null; + while (i < key.Length) + { + MD5 md5 = MD5.Create(); + if (i == 0) + { + md5sum = md5.ComputeHash(password); + } + else + { + md5sum.CopyTo(result, 0); + password.CopyTo(result, md5sum.Length); + md5sum = md5.ComputeHash(result); + } + md5sum.CopyTo(key, i); + i += md5sum.Length; + } + } + + protected static void randBytes(byte[] buf, int length) + { + byte[] temp = new byte[length]; + new Random().NextBytes(temp); + temp.CopyTo(buf, 0); + } + + protected virtual void initCipher(byte[] iv, bool isCipher) + { + if (ivLen > 0) + { + if (isCipher) + { + _encryptIV = new byte[ivLen]; + Array.Copy(iv, _encryptIV, ivLen); + } + else + { + _decryptIV = new byte[ivLen]; + Array.Copy(iv, _decryptIV, ivLen); + } + } + } + + protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf); + + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) + { + if (!_encryptIVSent) + { + _encryptIVSent = true; + randBytes(outbuf, ivLen); + initCipher(outbuf, true); + outlength = length + ivLen; + lock (tempbuf) + { + cipherUpdate(true, length, buf, tempbuf); + outlength = length + ivLen; + Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); + } + } + else + { + outlength = length; + cipherUpdate(true, length, buf, outbuf); + } + } + + public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) + { + if (!_decryptIVReceived) + { + _decryptIVReceived = true; + initCipher(buf, false); + outlength = length - ivLen; + lock (tempbuf) + { + // C# could be multi-threaded + Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); + cipherUpdate(false, length - ivLen, tempbuf, outbuf); + } + } + else + { + outlength = length; + cipherUpdate(false, length, buf, outbuf); + } + } + } +} diff --git a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs index 959fa350..c9548acb 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs @@ -8,32 +8,13 @@ using System.Threading; namespace Shadowsocks.Encrypt { public class PolarSSLEncryptor - : EncryptorBase, IDisposable + : IVEncryptor, IDisposable { const int CIPHER_AES = 1; const int CIPHER_RC4 = 2; - static Dictionary ciphers = new Dictionary { - {"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, - {"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, - {"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, - {"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, - {"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, - }; - - private static readonly Dictionary CachedKeys = new Dictionary(); - private int _cipher; - private int[] _cipherInfo; - private byte[] _key; private IntPtr _encryptCtx = IntPtr.Zero; private IntPtr _decryptCtx = IntPtr.Zero; - private byte[] _encryptIV; - private byte[] _decryptIV; - private int _encryptIVOffset = 0; - private int _decryptIVOffset = 0; - private string _method; - private int keyLen; - private int ivLen; public PolarSSLEncryptor(string method, string password) : base(method, password) @@ -41,66 +22,31 @@ namespace Shadowsocks.Encrypt InitKey(method, password); } - private static void randBytes(byte[] buf, int length) + protected override Dictionary getCiphers() { - byte[] temp = new byte[length]; - new Random().NextBytes(temp); - temp.CopyTo(buf, 0); + return new Dictionary { + {"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, + {"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, + {"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, + {"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, + {"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, + }; } - private void bytesToKey(byte[] password, byte[] key) + protected override void initCipher(byte[] iv, bool isCipher) { - byte[] result = new byte[password.Length + 16]; - int i = 0; - byte[] md5sum = null; - while (i < key.Length) - { - MD5 md5 = MD5.Create(); - if (i == 0) - { - md5sum = md5.ComputeHash(password); - } - else - { - md5sum.CopyTo(result, 0); - password.CopyTo(result, md5sum.Length); - md5sum = md5.ComputeHash(result); - } - md5sum.CopyTo(key, i); - i += md5sum.Length; - } - } + base.initCipher(iv, isCipher); - private void InitKey(string method, string password) - { - method = method.ToLower(); - _method = method; - string k = method + ":" + password; - _cipherInfo = ciphers[_method]; - _cipher = _cipherInfo[2]; - if (_cipher == 0) - { - throw new Exception("method not found"); - } - keyLen = ciphers[_method][0]; - ivLen = ciphers[_method][1]; - if (CachedKeys.ContainsKey(k)) + IntPtr ctx; + ctx = Marshal.AllocHGlobal(_cipherInfo[3]); + if (isCipher) { - _key = CachedKeys[k]; + _encryptCtx = ctx; } else { - byte[] passbuf = Encoding.UTF8.GetBytes(password); - _key = new byte[32]; - byte[] iv = new byte[16]; - bytesToKey(passbuf, _key); - CachedKeys[k] = _key; + _decryptCtx = ctx; } - } - - private void InitCipher(ref IntPtr ctx, byte[] iv, bool isCipher) - { - ctx = Marshal.AllocHGlobal(_cipherInfo[3]); byte[] realkey; if (_method == "rc4-md5") { @@ -120,16 +66,6 @@ namespace Shadowsocks.Encrypt // PolarSSL takes key length by bit // since we'll use CFB mode, here we both do enc, not dec PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8); - if (isCipher) - { - _encryptIV = new byte[ivLen]; - Array.Copy(iv, _encryptIV, ivLen); - } - else - { - _decryptIV = new byte[ivLen]; - Array.Copy(iv, _decryptIV, ivLen); - } } else if (_cipher == CIPHER_RC4) { @@ -139,98 +75,41 @@ namespace Shadowsocks.Encrypt } } - - - static byte[] tempbuf = new byte[32768]; - - public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) + protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) { - if (_encryptCtx == IntPtr.Zero) + // C# could be multi-threaded + if (_disposed) { - randBytes(outbuf, ivLen); - InitCipher(ref _encryptCtx, outbuf, true); - outlength = length + ivLen; - lock (tempbuf) - { - // C# could be multi-threaded - if (_disposed) - { - throw new ObjectDisposedException(this.ToString()); - } - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); - break; - case CIPHER_RC4: - PolarSSL.arc4_crypt(_encryptCtx, length, buf, tempbuf); - break; - } - outlength = length + ivLen; - Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); - - } + throw new ObjectDisposedException(this.ToString()); + } + byte[] iv; + int ivOffset; + if (isCipher) + { + iv = _encryptIV; + ivOffset = _encryptIVOffset; } else { - outlength = length; - if (_disposed) - { - throw new ObjectDisposedException(this.ToString()); - } - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); - break; - case CIPHER_RC4: - PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); - break; - } + iv = _decryptIV; + ivOffset = _decryptIVOffset; } - } - - public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) - { - if (_decryptCtx == IntPtr.Zero) + switch (_cipher) { - InitCipher(ref _decryptCtx, buf, false); - outlength = length - ivLen; - lock (tempbuf) - { - // C# could be multi-threaded - Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); - if (_disposed) + case CIPHER_AES: + PolarSSL.aes_crypt_cfb128(_encryptCtx, isCipher ? PolarSSL.AES_ENCRYPT : PolarSSL.AES_DECRYPT, length, ref ivOffset, iv, buf, outbuf); + if (isCipher) { - throw new ObjectDisposedException(this.ToString()); + _encryptIVOffset = ivOffset; } - switch (_cipher) + else { - case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); - break; - case CIPHER_RC4: - PolarSSL.arc4_crypt(_decryptCtx, length - ivLen, tempbuf, outbuf); - break; + _decryptIVOffset = ivOffset; } - } - } - else - { - outlength = length; - if (_disposed) - { - throw new ObjectDisposedException(this.ToString()); - } - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf); - break; - case CIPHER_RC4: - PolarSSL.arc4_crypt(_decryptCtx, length, buf, outbuf); - break; - } + break; + case CIPHER_RC4: + PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); + break; } } diff --git a/shadowsocks-csharp/Encrypt/Sodium.cs b/shadowsocks-csharp/Encrypt/Sodium.cs new file mode 100755 index 00000000..14f75872 --- /dev/null +++ b/shadowsocks-csharp/Encrypt/Sodium.cs @@ -0,0 +1,39 @@ +using Shadowsocks.Controller; +using Shadowsocks.Properties; +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + +namespace Shadowsocks.Encrypt +{ + public class Sodium + { + const string DLLNAME = "libsodium"; + + static Sodium() + { + string tempPath = Path.GetTempPath(); + string dllPath = tempPath + "/libsodium.dll"; + try + { + FileManager.UncompressFile(dllPath, Resources.libsodium_dll); + } + catch (IOException e) + { + Console.WriteLine(e.ToString()); + } + LoadLibrary(dllPath); + } + + [DllImport("Kernel32.dll")] + private static extern IntPtr LoadLibrary(string path); + + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + public extern static void crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); + + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + public extern static void crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); + } +} diff --git a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs new file mode 100755 index 00000000..d08027d7 --- /dev/null +++ b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Shadowsocks.Encrypt +{ + public class SodiumEncryptor + : IVEncryptor, IDisposable + { + const int CIPHER_SALSA20 = 1; + const int CIPHER_CHACHA20 = 2; + + protected uint _encryptBytesRemaining; + protected uint _decryptBytesRemaining; + protected ulong _encryptIC; + protected ulong _decryptIC; + + public SodiumEncryptor(string method, string password) + : base(method, password) + { + InitKey(method, password); + } + + protected override Dictionary getCiphers() + { + return new Dictionary { + {"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}}, + {"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}}, + }; ; + } + + protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) + { + uint bytesRemaining; + ulong ic; + if (isCipher) + { + bytesRemaining = _encryptBytesRemaining; + ic = _encryptIC; + } + else + { + bytesRemaining = _decryptBytesRemaining; + ic = _decryptIC; + } + + if (isCipher) + { + _encryptBytesRemaining = bytesRemaining; + _encryptIC = ic; + } + else + { + _decryptBytesRemaining = bytesRemaining; + _decryptIC = ic; + } + } + + public override void Dispose() + { + } + } +} diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 1af315b5..ffc24b33 100755 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -63,6 +63,16 @@ namespace Shadowsocks.Properties { /// /// Looks up a localized resource of type System.Byte[]. /// + internal static byte[] libsodium_dll { + get { + object obj = ResourceManager.GetObject("libsodium_dll", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// internal static byte[] polarssl_dll { get { object obj = ResourceManager.GetObject("polarssl_dll", resourceCulture); diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index a644b5f9..4b6f8f3e 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\data\libsodium.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Data\polarssl.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 6221c918..06f5bc3a 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -77,8 +77,11 @@ + + + @@ -125,6 +128,7 @@ Designer + From f0920098ad21a6cc7e2913a071f4e0bdb5c30f0b Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 10:15:15 +0800 Subject: [PATCH 03/39] sodium works --- shadowsocks-csharp/Encrypt/EncryptorBase.cs | 2 ++ shadowsocks-csharp/Encrypt/EncryptorFactory.cs | 2 +- shadowsocks-csharp/Encrypt/IVEncryptor.cs | 2 +- shadowsocks-csharp/Encrypt/SodiumEncryptor.cs | 35 +++++++++++++++++++++++--- shadowsocks-csharp/View/ConfigForm.Designer.cs | 2 ++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/shadowsocks-csharp/Encrypt/EncryptorBase.cs b/shadowsocks-csharp/Encrypt/EncryptorBase.cs index eb8c1f37..06779103 100644 --- a/shadowsocks-csharp/Encrypt/EncryptorBase.cs +++ b/shadowsocks-csharp/Encrypt/EncryptorBase.cs @@ -6,6 +6,8 @@ namespace Shadowsocks.Encrypt public abstract class EncryptorBase : IEncryptor { + public const int MAX_INPUT_SIZE = 32768; + protected EncryptorBase(string method, string password) { Method = method; diff --git a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs index 59111a69..e62aed06 100644 --- a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs @@ -10,7 +10,7 @@ namespace Shadowsocks.Encrypt return new TableEncryptor(method, password); } - return new PolarSSLEncryptor(method, password); + return new SodiumEncryptor(method, password); } } } diff --git a/shadowsocks-csharp/Encrypt/IVEncryptor.cs b/shadowsocks-csharp/Encrypt/IVEncryptor.cs index 66883918..bdeae866 100755 --- a/shadowsocks-csharp/Encrypt/IVEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/IVEncryptor.cs @@ -8,7 +8,7 @@ namespace Shadowsocks.Encrypt public abstract class IVEncryptor : EncryptorBase { - protected static byte[] tempbuf = new byte[32768]; + protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; protected Dictionary ciphers; diff --git a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs index d08027d7..277fb80f 100755 --- a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs @@ -10,15 +10,21 @@ namespace Shadowsocks.Encrypt const int CIPHER_SALSA20 = 1; const int CIPHER_CHACHA20 = 2; - protected uint _encryptBytesRemaining; - protected uint _decryptBytesRemaining; + const int SODIUM_BLOCK_SIZE = 64; + + protected int _encryptBytesRemaining; + protected int _decryptBytesRemaining; protected ulong _encryptIC; protected ulong _decryptIC; + protected byte[] _encryptBuf; + protected byte[] _decryptBuf; public SodiumEncryptor(string method, string password) : base(method, password) { InitKey(method, password); + _encryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; + _decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; } protected override Dictionary getCiphers() @@ -31,18 +37,41 @@ namespace Shadowsocks.Encrypt protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) { - uint bytesRemaining; + // TODO write a unidirection cipher so we don't have to if if if + int bytesRemaining; ulong ic; + byte[] sodiumBuf; + byte[] iv; if (isCipher) { bytesRemaining = _encryptBytesRemaining; ic = _encryptIC; + sodiumBuf = _encryptBuf; + iv = _encryptIV; } else { bytesRemaining = _decryptBytesRemaining; ic = _decryptIC; + sodiumBuf = _decryptBuf; + iv = _decryptIV; + } + int padding = bytesRemaining; + Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length); + + switch (_cipher) + { + case CIPHER_SALSA20: + Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key); + break; + case CIPHER_CHACHA20: + Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key); + break; } + Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length); + padding += length; + ic += (ulong)padding / SODIUM_BLOCK_SIZE; + bytesRemaining = padding % SODIUM_BLOCK_SIZE; if (isCipher) { diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 50273d07..03b4a134 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -206,6 +206,8 @@ this.EncryptionSelect.Items.AddRange(new object[] { "table", "rc4-md5", + "salsa20", + "chacha20", "aes-256-cfb", "aes-192-cfb", "aes-128-cfb", From 12047ca70b1df18be8ad031091869e6c4fe731d2 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 10:40:42 +0800 Subject: [PATCH 04/39] refine factory --- shadowsocks-csharp/Encrypt/EncryptorFactory.cs | 35 ++++++++++++++++++++++--- shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs | 15 ++++++++--- shadowsocks-csharp/Encrypt/SodiumEncryptor.cs | 15 ++++++++--- shadowsocks-csharp/Encrypt/TableEncryptor.cs | 6 +++++ 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs index e62aed06..9599adbb 100644 --- a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs @@ -1,16 +1,43 @@  +using System; +using System.Collections.Generic; +using System.Reflection; namespace Shadowsocks.Encrypt { public static class EncryptorFactory { - public static IEncryptor GetEncryptor(string method, string password) + private static Dictionary _registeredEncryptors; + + private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) }; + + static EncryptorFactory() { - if (string.IsNullOrEmpty(method) || method.ToLowerInvariant() == "table") + _registeredEncryptors = new Dictionary(); + foreach (string method in TableEncryptor.SupportedCiphers()) + { + _registeredEncryptors.Add(method, typeof(TableEncryptor)); + } + foreach (string method in PolarSSLEncryptor.SupportedCiphers()) + { + _registeredEncryptors.Add(method, typeof(PolarSSLEncryptor)); + } + foreach (string method in SodiumEncryptor.SupportedCiphers()) { - return new TableEncryptor(method, password); + _registeredEncryptors.Add(method, typeof(SodiumEncryptor)); } + } - return new SodiumEncryptor(method, password); + public static IEncryptor GetEncryptor(string method, string password) + { + if (string.IsNullOrEmpty(method)) + { + method = "table"; + } + method = method.ToLowerInvariant(); + Type t = _registeredEncryptors[method]; + ConstructorInfo c = t.GetConstructor(_constructorTypes); + IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password }); + return result; } } } diff --git a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs index c9548acb..0e1e668f 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs @@ -22,15 +22,22 @@ namespace Shadowsocks.Encrypt InitKey(method, password); } - protected override Dictionary getCiphers() - { - return new Dictionary { + private static Dictionary _ciphers = new Dictionary { {"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, {"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, {"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, {"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, {"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, - }; + }; + + public static List SupportedCiphers() + { + return new List(_ciphers.Keys); + } + + protected override Dictionary getCiphers() + { + return _ciphers; } protected override void initCipher(byte[] iv, bool isCipher) diff --git a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs index 277fb80f..8b7ac5b2 100755 --- a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs @@ -27,12 +27,19 @@ namespace Shadowsocks.Encrypt _decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; } - protected override Dictionary getCiphers() - { - return new Dictionary { + private static Dictionary _ciphers = new Dictionary { {"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}}, {"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}}, - }; ; + }; + + protected override Dictionary getCiphers() + { + return _ciphers; + } + + public static List SupportedCiphers() + { + return new List(_ciphers.Keys); } protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) diff --git a/shadowsocks-csharp/Encrypt/TableEncryptor.cs b/shadowsocks-csharp/Encrypt/TableEncryptor.cs index a600a3a0..1382d7ca 100644 --- a/shadowsocks-csharp/Encrypt/TableEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/TableEncryptor.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Shadowsocks.Encrypt { @@ -25,6 +26,11 @@ namespace Shadowsocks.Encrypt } } + public static List SupportedCiphers() + { + return new List(new string[]{"table"}); + } + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { byte[] result = new byte[length]; From b30bb7ef5ea873960534acc2c9bb8aee2904b051 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 11:19:17 +0800 Subject: [PATCH 05/39] fix aes --- shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs | 5 +- shadowsocks-csharp/Properties/AssemblyInfo.cs | 2 +- test/UnitTest.cs | 77 +++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs index 0e1e668f..7e71d054 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs @@ -91,20 +91,23 @@ namespace Shadowsocks.Encrypt } byte[] iv; int ivOffset; + IntPtr ctx; if (isCipher) { iv = _encryptIV; ivOffset = _encryptIVOffset; + ctx = _encryptCtx; } else { iv = _decryptIV; ivOffset = _decryptIVOffset; + ctx = _decryptCtx; } switch (_cipher) { case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_encryptCtx, isCipher ? PolarSSL.AES_ENCRYPT : PolarSSL.AES_DECRYPT, length, ref ivOffset, iv, buf, outbuf); + PolarSSL.aes_crypt_cfb128(ctx, isCipher ? PolarSSL.AES_ENCRYPT : PolarSSL.AES_DECRYPT, length, ref ivOffset, iv, buf, outbuf); if (isCipher) { _encryptIVOffset = ivOffset; diff --git a/shadowsocks-csharp/Properties/AssemblyInfo.cs b/shadowsocks-csharp/Properties/AssemblyInfo.cs index 47f94a5e..2b18902f 100755 --- a/shadowsocks-csharp/Properties/AssemblyInfo.cs +++ b/shadowsocks-csharp/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.11")] +[assembly: AssemblyVersion("2.1")] // [assembly: AssemblyFileVersion("2.0.0")] diff --git a/test/UnitTest.cs b/test/UnitTest.cs index 69c23b41..b6856e8e 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -23,14 +23,14 @@ namespace test } [TestMethod] - public void TestEncryption() + public void TestPolarSSLEncryption() { // run it once before the multi-threading test to initialize global tables - RunSingleEncryptionThread(); + RunSinglePolarSSLEncryptionThread(); List threads = new List(); for (int i = 0; i < 10; i++) { - Thread t = new Thread(new ThreadStart(RunSingleEncryptionThread)); + Thread t = new Thread(new ThreadStart(RunSinglePolarSSLEncryptionThread)); threads.Add(t); t.Start(); } @@ -44,7 +44,7 @@ namespace test private static bool encryptionFailed = false; private static object locker = new object(); - private void RunSingleEncryptionThread() + private void RunSinglePolarSSLEncryptionThread() { try { @@ -93,5 +93,74 @@ namespace test throw; } } + + [TestMethod] + public void TestSodiumEncryption() + { + // run it once before the multi-threading test to initialize global tables + RunSingleSodiumEncryptionThread(); + List threads = new List(); + for (int i = 0; i < 10; i++) + { + Thread t = new Thread(new ThreadStart(RunSingleSodiumEncryptionThread)); + threads.Add(t); + t.Start(); + } + foreach (Thread t in threads) + { + t.Join(); + } + Assert.IsFalse(encryptionFailed); + } + + private void RunSingleSodiumEncryptionThread() + { + try + { + for (int i = 0; i < 100; i++) + { + var random = new Random(); + IEncryptor encryptor; + IEncryptor decryptor; + encryptor = new SodiumEncryptor("salsa20", "barfoo!"); + decryptor = new SodiumEncryptor("salsa20", "barfoo!"); + byte[] plain = new byte[16384]; + byte[] cipher = new byte[plain.Length + 16]; + byte[] plain2 = new byte[plain.Length + 16]; + int outLen = 0; + int outLen2 = 0; + random.NextBytes(plain); + //lock (locker) + //{ + encryptor.Encrypt(plain, plain.Length, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(plain.Length, outLen2); + for (int j = 0; j < plain.Length; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + encryptor.Encrypt(plain, 1000, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(1000, outLen2); + for (int j = 0; j < outLen2; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + encryptor.Encrypt(plain, 12333, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(12333, outLen2); + for (int j = 0; j < outLen2; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + //} + } + } + catch + { + encryptionFailed = true; + throw; + } + } } } From 34b9e2e08a23dc005a21446f87ca201ef4bbddf1 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 12:28:30 +0800 Subject: [PATCH 06/39] fix rc4 --- shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs index 7e71d054..83f64f09 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs @@ -118,7 +118,7 @@ namespace Shadowsocks.Encrypt } break; case CIPHER_RC4: - PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); + PolarSSL.arc4_crypt(ctx, length, buf, outbuf); break; } } From 05d8d5f6dcf898051c4b64e16b4a673e1b2159e0 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 12:49:59 +0800 Subject: [PATCH 07/39] refine tests --- test/UnitTest.cs | 155 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 84 insertions(+), 71 deletions(-) diff --git a/test/UnitTest.cs b/test/UnitTest.cs index b6856e8e..94fa9053 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -22,6 +22,41 @@ namespace test Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); } + private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) + { + byte[] plain = new byte[16384]; + byte[] cipher = new byte[plain.Length + 16]; + byte[] plain2 = new byte[plain.Length + 16]; + int outLen = 0; + int outLen2 = 0; + var random = new Random(); + random.NextBytes(plain); + encryptor.Encrypt(plain, plain.Length, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(plain.Length, outLen2); + for (int j = 0; j < plain.Length; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + encryptor.Encrypt(plain, 1000, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(1000, outLen2); + for (int j = 0; j < outLen2; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + encryptor.Encrypt(plain, 12333, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(12333, outLen2); + for (int j = 0; j < outLen2; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + } + + private static bool encryptionFailed = false; + private static object locker = new object(); + [TestMethod] public void TestPolarSSLEncryption() { @@ -41,51 +76,58 @@ namespace test Assert.IsFalse(encryptionFailed); } - private static bool encryptionFailed = false; - private static object locker = new object(); - private void RunSinglePolarSSLEncryptionThread() { try { - for (int i = 0; i < 100; i++) - { - var random = new Random(); - IEncryptor encryptor; - IEncryptor decryptor; - encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); - decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); - byte[] plain = new byte[16384]; - byte[] cipher = new byte[plain.Length + 16]; - byte[] plain2 = new byte[plain.Length + 16]; - int outLen = 0; - int outLen2 = 0; - random.NextBytes(plain); - //lock (locker) - //{ - encryptor.Encrypt(plain, plain.Length, cipher, out outLen); - decryptor.Decrypt(cipher, outLen, plain2, out outLen2); - Assert.AreEqual(plain.Length, outLen2); - for (int j = 0; j < plain.Length; j++) - { - Assert.AreEqual(plain[j], plain2[j]); - } - encryptor.Encrypt(plain, 1000, cipher, out outLen); - decryptor.Decrypt(cipher, outLen, plain2, out outLen2); - Assert.AreEqual(1000, outLen2); - for (int j = 0; j < outLen2; j++) - { - Assert.AreEqual(plain[j], plain2[j]); - } - encryptor.Encrypt(plain, 12333, cipher, out outLen); - decryptor.Decrypt(cipher, outLen, plain2, out outLen2); - Assert.AreEqual(12333, outLen2); - for (int j = 0; j < outLen2; j++) - { - Assert.AreEqual(plain[j], plain2[j]); - } - //} - } + for (int i = 0; i < 100; i++) + { + IEncryptor encryptor; + IEncryptor decryptor; + encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); + decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); + RunEncryptionRound(encryptor, decryptor); + } + } + catch + { + encryptionFailed = true; + throw; + } + } + + [TestMethod] + public void TestRC4Encryption() + { + // run it once before the multi-threading test to initialize global tables + RunSingleRC4EncryptionThread(); + List threads = new List(); + for (int i = 0; i < 10; i++) + { + Thread t = new Thread(new ThreadStart(RunSingleRC4EncryptionThread)); + threads.Add(t); + t.Start(); + } + foreach (Thread t in threads) + { + t.Join(); + } + Assert.IsFalse(encryptionFailed); + } + + private void RunSingleRC4EncryptionThread() + { + try + { + for (int i = 0; i < 100; i++) + { + var random = new Random(); + IEncryptor encryptor; + IEncryptor decryptor; + encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!"); + decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!"); + RunEncryptionRound(encryptor, decryptor); + } } catch { @@ -124,36 +166,7 @@ namespace test IEncryptor decryptor; encryptor = new SodiumEncryptor("salsa20", "barfoo!"); decryptor = new SodiumEncryptor("salsa20", "barfoo!"); - byte[] plain = new byte[16384]; - byte[] cipher = new byte[plain.Length + 16]; - byte[] plain2 = new byte[plain.Length + 16]; - int outLen = 0; - int outLen2 = 0; - random.NextBytes(plain); - //lock (locker) - //{ - encryptor.Encrypt(plain, plain.Length, cipher, out outLen); - decryptor.Decrypt(cipher, outLen, plain2, out outLen2); - Assert.AreEqual(plain.Length, outLen2); - for (int j = 0; j < plain.Length; j++) - { - Assert.AreEqual(plain[j], plain2[j]); - } - encryptor.Encrypt(plain, 1000, cipher, out outLen); - decryptor.Decrypt(cipher, outLen, plain2, out outLen2); - Assert.AreEqual(1000, outLen2); - for (int j = 0; j < outLen2; j++) - { - Assert.AreEqual(plain[j], plain2[j]); - } - encryptor.Encrypt(plain, 12333, cipher, out outLen); - decryptor.Decrypt(cipher, outLen, plain2, out outLen2); - Assert.AreEqual(12333, outLen2); - for (int j = 0; j < outLen2; j++) - { - Assert.AreEqual(plain[j], plain2[j]); - } - //} + RunEncryptionRound(encryptor, decryptor); } } catch From 639b6b20ee8e483a33b3dbdd97f22031ec762258 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 13:36:22 +0800 Subject: [PATCH 08/39] refine logging --- shadowsocks-csharp/Controller/Logging.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs index ada32ce5..22b5b9b1 100755 --- a/shadowsocks-csharp/Controller/Logging.cs +++ b/shadowsocks-csharp/Controller/Logging.cs @@ -47,6 +47,10 @@ namespace Shadowsocks.Controller { // received rst } + else if (se.SocketErrorCode == SocketError.NotConnected) + { + // close when not connected + } else { Console.WriteLine(e); From 104a401b6394d74bbd1fab8f9908ed98b6ef7d7c Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 14:25:09 +0800 Subject: [PATCH 09/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6981ebcb..254bfa30 100644 --- a/README.md +++ b/README.md @@ -39,4 +39,4 @@ GPLv3 [Appveyor]: https://ci.appveyor.com/project/clowwindy/shadowsocks-csharp [Build Status]: https://ci.appveyor.com/api/projects/status/gknc8l1lxy423ehv/branch/master -[latest release]: https://sourceforge.net/projects/shadowsocksgui/files/dist/ +[latest release]: https://github.com/clowwindy/shadowsocks-csharp/releases From 3fff8220e68233766e46694acc1228e7bf050720 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 14:25:46 +0800 Subject: [PATCH 10/39] make it simpler --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 254bfa30..16c0207b 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ Shadowsocks for Windows Download [latest release]. -For Windows 7 and older, please download Shadowsocks-win-x.x.x.zip. +For Windows 7 and older, download Shadowsocks-win-x.x.x.zip. -For Windows 8 and newer, please download Shadowsocks-win-dotnet4.0-x.x.x.zip. +For Windows 8 and newer, download Shadowsocks-win-dotnet4.0-x.x.x.zip. ### Usage From c65efc17fc83b74000e5ac861a9232349926b6c5 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 13 Dec 2014 17:56:45 +0800 Subject: [PATCH 11/39] update CHANGES --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index b84ed21e..668c3e25 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2.1 2014-12-12 +- Add salsa20 and chacha20 support + 2.0.11 2014-11-23 - Fix a crash - Only switch the system proxy off if we have switched it on From 5ed49ac6b64c8d5e1c663cae710ac0e75990d7eb Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 14 Dec 2014 17:43:04 +0800 Subject: [PATCH 12/39] add global mode --- .../Controller/ShadowsocksController.cs | 14 ++- shadowsocks-csharp/Controller/SystemProxy.cs | 17 +++- shadowsocks-csharp/Model/Configuration.cs | 1 + shadowsocks-csharp/View/MenuViewController.cs | 104 +++++++++++++++------ 4 files changed, 101 insertions(+), 35 deletions(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index f5bdb44c..464cc131 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -31,6 +31,7 @@ namespace Shadowsocks.Controller public event EventHandler ConfigChanged; public event EventHandler EnableStatusChanged; + public event EventHandler EnableGlobalChanged; public event EventHandler ShareOverLANStatusChanged; // when user clicked Edit PAC, and PAC file has already created @@ -93,6 +94,17 @@ namespace Shadowsocks.Controller } } + public void ToggleGlobal(bool global) + { + _config.global = global; + UpdateSystemProxy(); + SaveConfig(_config); + if (EnableGlobalChanged != null) + { + EnableGlobalChanged(this, new EventArgs()); + } + } + public void ToggleShareOverLAN(bool enabled) { _config.shareOverLan = enabled; @@ -175,7 +187,7 @@ namespace Shadowsocks.Controller { if (_config.enabled) { - SystemProxy.Enable(); + SystemProxy.Enable(_config.global); _systemProxyIsDirty = true; } else diff --git a/shadowsocks-csharp/Controller/SystemProxy.cs b/shadowsocks-csharp/Controller/SystemProxy.cs index b2e585da..c16aa235 100755 --- a/shadowsocks-csharp/Controller/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/SystemProxy.cs @@ -24,16 +24,25 @@ namespace Shadowsocks.Controller _refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); } - public static void Enable() + public static void Enable(bool global) { try { RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true); - registry.SetValue("ProxyEnable", 0); - registry.SetValue("ProxyServer", ""); - registry.SetValue("AutoConfigURL", "http://127.0.0.1:8093/pac?t=" + GetTimestamp(DateTime.Now)); + if (global) + { + registry.SetValue("ProxyEnable", 1); + registry.SetValue("ProxyServer", "127.0.0.1:8123"); + registry.SetValue("AutoConfigURL", ""); + } + else + { + registry.SetValue("ProxyEnable", 0); + registry.SetValue("ProxyServer", ""); + registry.SetValue("AutoConfigURL", "http://127.0.0.1:8093/pac?t=" + GetTimestamp(DateTime.Now)); + } SystemProxy.NotifyIE(); //Must Notify IE first, or the connections do not chanage CopyProxySettingFromLan(); diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index db02b840..66dbcb4c 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -11,6 +11,7 @@ namespace Shadowsocks.Model { public List configs; public int index; + public bool global; public bool enabled; public bool shareOverLan; public bool isDefault; diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index c4eb8193..9965f8dc 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -37,6 +37,9 @@ namespace Shadowsocks.View private MenuItem menuItem3; private MenuItem quitItem; private MenuItem menuItem1; + private MenuItem modeItem; + private MenuItem globalModeItem; + private MenuItem PACModeItem; private ConfigForm configForm; public MenuViewController(ShadowsocksController controller) @@ -49,6 +52,7 @@ namespace Shadowsocks.View controller.ConfigChanged += controller_ConfigChanged; controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; + controller.EnableGlobalChanged += controller_EnableGlobalChanged; this.updateChecker = new UpdateChecker(); updateChecker.NewVersionFound += updateChecker_NewVersionFound; @@ -98,6 +102,9 @@ namespace Shadowsocks.View { this.contextMenu1 = new System.Windows.Forms.ContextMenu(); this.enableItem = new System.Windows.Forms.MenuItem(); + this.modeItem = new System.Windows.Forms.MenuItem(); + this.PACModeItem = new System.Windows.Forms.MenuItem(); + this.globalModeItem = new System.Windows.Forms.MenuItem(); this.AutoStartupItem = new System.Windows.Forms.MenuItem(); this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); this.ServersItem = new System.Windows.Forms.MenuItem(); @@ -117,6 +124,7 @@ namespace Shadowsocks.View // this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.enableItem, + this.modeItem, this.ServersItem, this.menuItem1, this.AutoStartupItem, @@ -134,22 +142,30 @@ namespace Shadowsocks.View this.enableItem.Index = 0; this.enableItem.Text = "&Enable"; this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); - // - // AutoStartupItem - // - this.AutoStartupItem.Index = 3; - this.AutoStartupItem.Text = "Start on Boot"; - this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); - // - // ShareOverLANItem - // - this.ShareOverLANItem.Index = 4; - this.ShareOverLANItem.Text = "Share over LAN"; - this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); + // + // modeMenu + // + this.modeItem.Index = 1; + this.modeItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.PACModeItem, + this.globalModeItem}); + this.modeItem.Text = "Mode"; + // + // PACModeItem + // + this.PACModeItem.Index = 0; + this.PACModeItem.Text = "PAC"; + this.PACModeItem.Click += new System.EventHandler(this.PACModeItem_Click); + // + // globalModeItem + // + this.globalModeItem.Index = 1; + this.globalModeItem.Text = "Global"; + this.globalModeItem.Click += new System.EventHandler(this.GlobalModeItem_Click); // // ServersItem // - this.ServersItem.Index = 1; + this.ServersItem.Index = 2; this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.SeperatorItem, this.ConfigItem}); @@ -166,50 +182,62 @@ namespace Shadowsocks.View this.ConfigItem.Text = "Edit Servers..."; this.ConfigItem.Click += new System.EventHandler(this.Config_Click); // - // menuItem4 + // menuItem1 // - this.menuItem4.Index = 6; - this.menuItem4.Text = "-"; + this.menuItem1.Index = 3; + this.menuItem1.Text = "-"; + // + // AutoStartupItem + // + this.AutoStartupItem.Index = 4; + this.AutoStartupItem.Text = "Start on Boot"; + this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); + // + // ShareOverLANItem + // + this.ShareOverLANItem.Index = 5; + this.ShareOverLANItem.Text = "Share over LAN"; + this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); // // editPACFileItem // - this.editPACFileItem.Index = 5; + this.editPACFileItem.Index = 6; this.editPACFileItem.Text = "Edit &PAC File..."; this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); // + // menuItem4 + // + this.menuItem4.Index = 7; + this.menuItem4.Text = "-"; + // // QRCodeItem // - this.QRCodeItem.Index = 7; + this.QRCodeItem.Index = 8; this.QRCodeItem.Text = "Show &QRCode..."; this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); // // ShowLogItem // - this.ShowLogItem.Index = 8; + this.ShowLogItem.Index = 9; this.ShowLogItem.Text = "Show Logs..."; this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); // // aboutItem // - this.aboutItem.Index = 9; + this.aboutItem.Index = 10; this.aboutItem.Text = "About..."; this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); // // menuItem3 // - this.menuItem3.Index = 10; + this.menuItem3.Index = 11; this.menuItem3.Text = "-"; // // quitItem // - this.quitItem.Index = 11; + this.quitItem.Index = 12; this.quitItem.Text = "&Quit"; this.quitItem.Click += new System.EventHandler(this.Quit_Click); - // - // menuItem1 - // - this.menuItem1.Index = 2; - this.menuItem1.Text = "-"; } private void controller_ConfigChanged(object sender, EventArgs e) @@ -227,6 +255,12 @@ namespace Shadowsocks.View ShareOverLANItem.Checked = controller.GetConfiguration().shareOverLan; } + void controller_EnableGlobalChanged(object sender, EventArgs e) + { + globalModeItem.Checked = controller.GetConfiguration().global; + PACModeItem.Checked = !globalModeItem.Checked; + } + void controller_PACFileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) { string argument = @"/select, " + e.Path; @@ -255,6 +289,8 @@ namespace Shadowsocks.View Configuration config = controller.GetConfiguration(); UpdateServersMenu(); enableItem.Checked = config.enabled; + globalModeItem.Checked = config.global; + PACModeItem.Checked = !config.global; ShareOverLANItem.Checked = config.shareOverLan; AutoStartupItem.Checked = AutoStartup.Check(); } @@ -338,11 +374,19 @@ namespace Shadowsocks.View ShowConfigForm(); } - private void EnableItem_Click(object sender, EventArgs e) { - enableItem.Checked = !enableItem.Checked; - controller.ToggleEnable(enableItem.Checked); + controller.ToggleEnable(!enableItem.Checked); + } + + private void GlobalModeItem_Click(object sender, EventArgs e) + { + controller.ToggleGlobal(true); + } + + private void PACModeItem_Click(object sender, EventArgs e) + { + controller.ToggleGlobal(false); } private void ShareOverLANItem_Click(object sender, EventArgs e) From c1c29da664b2a2623dca601d90e03991c8cc9a9d Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 14 Dec 2014 17:43:33 +0800 Subject: [PATCH 13/39] bump --- shadowsocks-csharp/Properties/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Properties/AssemblyInfo.cs b/shadowsocks-csharp/Properties/AssemblyInfo.cs index 2b18902f..03f9be7e 100755 --- a/shadowsocks-csharp/Properties/AssemblyInfo.cs +++ b/shadowsocks-csharp/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1")] +[assembly: AssemblyVersion("2.1.1")] // [assembly: AssemblyFileVersion("2.0.0")] From ebcb5e08f157b4ac75a548abc375466cbc612080 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 14 Dec 2014 18:00:29 +0800 Subject: [PATCH 14/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16c0207b..f7b7f99f 100644 --- a/README.md +++ b/README.md @@ -39,4 +39,4 @@ GPLv3 [Appveyor]: https://ci.appveyor.com/project/clowwindy/shadowsocks-csharp [Build Status]: https://ci.appveyor.com/api/projects/status/gknc8l1lxy423ehv/branch/master -[latest release]: https://github.com/clowwindy/shadowsocks-csharp/releases +[latest release]: https://sourceforge.net/projects/shadowsocksgui/files/dist/ From 2b6a86d04a27c636b29d3a471a9a81c6e2760ba9 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 14 Dec 2014 18:14:50 +0800 Subject: [PATCH 15/39] fix a typo --- shadowsocks-csharp/View/MenuViewController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 9965f8dc..a91e48f7 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -14,7 +14,7 @@ namespace Shadowsocks.View { // yes this is just a menu view controller // when config form is closed, it moves away from RAM - // and it should just does anything related to the config form + // and it should just do anything related to the config form private ShadowsocksController controller; private UpdateChecker updateChecker; From fab822c8bbaa9e5d5f6008244586e6163c7f95d6 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 15 Dec 2014 10:36:50 +0800 Subject: [PATCH 16/39] fix #66 --- shadowsocks-csharp/Controller/Local.cs | 19 ++++++++++++++----- shadowsocks-csharp/Controller/PACServer.cs | 20 +++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/shadowsocks-csharp/Controller/Local.cs b/shadowsocks-csharp/Controller/Local.cs index 15649b40..1a749b1f 100755 --- a/shadowsocks-csharp/Controller/Local.cs +++ b/shadowsocks-csharp/Controller/Local.cs @@ -66,16 +66,12 @@ namespace Shadowsocks.Controller public void AcceptCallback(IAsyncResult ar) { + Socket listener = (Socket)ar.AsyncState; try { - Socket listener = (Socket)ar.AsyncState; Socket conn = listener.EndAccept(ar); conn.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - listener.BeginAccept( - new AsyncCallback(AcceptCallback), - listener); - Handler handler = new Handler(); handler.connection = conn; handler.encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); @@ -87,6 +83,19 @@ namespace Shadowsocks.Controller { //Console.WriteLine(e.Message); } + finally + { + try + { + listener.BeginAccept( + new AsyncCallback(AcceptCallback), + listener); + } + catch + { + //Console.WriteLine(e.Message); + } + } } } diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index a71fe3de..b64d3ce0 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -78,20 +78,17 @@ namespace Shadowsocks.Controller public void AcceptCallback(IAsyncResult ar) { + Socket listener = (Socket)ar.AsyncState; try { - Socket listener = (Socket)ar.AsyncState; Socket conn = listener.EndAccept(ar); - listener.BeginAccept( - new AsyncCallback(AcceptCallback), - listener); byte[] buf = new byte[2048]; object[] state = new object[] { conn, buf }; - + conn.BeginReceive(buf, 0, 1024, 0, new AsyncCallback(ReceiveCallback), state); } @@ -102,6 +99,19 @@ namespace Shadowsocks.Controller { Console.WriteLine(e); } + finally + { + try + { + listener.BeginAccept( + new AsyncCallback(AcceptCallback), + listener); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + } + } } private string GetPACContent() From 3a0cf596e81548fc00ef34f195851faa07eea714 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 15 Dec 2014 11:49:31 +0800 Subject: [PATCH 17/39] Update CHANGES --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 668c3e25..0949a788 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2.1.1 2014-12-14 +- Add global proxy option + 2.1 2014-12-12 - Add salsa20 and chacha20 support From 41329ff7129b7c3051dded1defea1909a656319d Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 15 Dec 2014 16:18:19 +0800 Subject: [PATCH 18/39] Update README.md --- README.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f7b7f99f..3304cffc 100644 --- a/README.md +++ b/README.md @@ -3,36 +3,34 @@ Shadowsocks for Windows [![Build Status]][Appveyor] -### Features +#### Features -1. Native Windows UI -2. Fast system proxy switching -3. Compatible with IE -4. Builtin PAC server with user editable PAC -5. QRCode generation -6. Only a single exe file of 200KB size +1. System proxy configuration +2. Fast profile switching +3. PAC mode and global mode +4. Compatible with IE +5. Only a single exe file of 200KB size -### Download +#### Download Download [latest release]. -For Windows 7 and older, download Shadowsocks-win-x.x.x.zip. +For <= Windows 7, download Shadowsocks-win-x.x.x.zip. -For Windows 8 and newer, download Shadowsocks-win-dotnet4.0-x.x.x.zip. +For >= Windows 8, download Shadowsocks-win-dotnet4.0-x.x.x.zip. -### Usage +#### Usage 1. Find Shadowsocks icon in notification tray 2. You can add multiple servers in servers menu -3. After servers are added, click Enable menu item to enable system proxy -4. After you saved PAC file with any editor, Shadowsocks will notify browsers +3. Select Enable menu to enable system proxy +4. Leave Enable menu unchecked, Shadowsocks will still provide an HTTP proxy at 127.0.0.1:8123 +5. After you saved PAC file with any editor, Shadowsocks will notify browsers about the change automatically -5. Please disable other proxy addons in your browser, or set them to use +6. Please disable other proxy addons in your browser, or set them to use system proxy -6. You may need to install VC 2008 Runtime and .Net framework if Shadowsocks -failed to start -### License +#### License GPLv3 From ecdb36ff3b75271c8717d062935882846e1c6b7d Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 15 Dec 2014 20:54:15 +0800 Subject: [PATCH 19/39] bump --- shadowsocks-csharp/Properties/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Properties/AssemblyInfo.cs b/shadowsocks-csharp/Properties/AssemblyInfo.cs index 03f9be7e..28eb113d 100755 --- a/shadowsocks-csharp/Properties/AssemblyInfo.cs +++ b/shadowsocks-csharp/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.1")] +[assembly: AssemblyVersion("2.1.2")] // [assembly: AssemblyFileVersion("2.0.0")] From d94d3074ec3d1f40cfb800bd53c4f23522a24211 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 15 Dec 2014 20:56:23 +0800 Subject: [PATCH 20/39] update CHANGES --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 0949a788..5a31eddb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2.1.2 2014-12-14 +- Fix sometimes Shadowsocks doesn't respond to requests + 2.1.1 2014-12-14 - Add global proxy option From e53873276f02e69d3c752fe94c915dc207bf9011 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Wed, 17 Dec 2014 17:20:08 +0800 Subject: [PATCH 21/39] translate Microsoft language into human language --- shadowsocks-csharp/Controller/PACServer.cs | 11 ++- .../Controller/ShadowsocksController.cs | 100 ++++++++++++++------- shadowsocks-csharp/Program.cs | 4 +- shadowsocks-csharp/View/MenuViewController.cs | 6 ++ 4 files changed, 86 insertions(+), 35 deletions(-) diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index b64d3ce0..0b2934b4 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -58,8 +58,11 @@ namespace Shadowsocks.Controller public void Stop() { - _listener.Close(); - _listener = null; + if (_listener != null) + { + _listener.Close(); + _listener = null; + } } public string TouchPACFile() @@ -107,6 +110,10 @@ namespace Shadowsocks.Controller new AsyncCallback(AcceptCallback), listener); } + catch (ObjectDisposedException) + { + // do nothing + } catch (Exception e) { Logging.LogUsefulException(e); diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 464cc131..e2a761ff 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Text; using System.Threading; +using System.Net.Sockets; namespace Shadowsocks.Controller { @@ -37,33 +38,34 @@ namespace Shadowsocks.Controller // when user clicked Edit PAC, and PAC file has already created public event EventHandler PACFileReadyToOpen; + public event ErrorEventHandler Errored; + public ShadowsocksController() { _config = Configuration.Load(); - polipoRunner = new PolipoRunner(); - polipoRunner.Start(_config); - local = new Local(_config); - try - { - local.Start(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - try - { - pacServer = new PACServer(); - pacServer.PACFileChanged += pacServer_PACFileChanged; - pacServer.Start(_config); - } - catch (Exception e) + } + + public void Start() + { + Reload(); + } + + protected void ReportError(Exception e) + { + if (Errored != null) { - Console.WriteLine(e); + // translate Microsoft language into human language + // i.e. 以一种访问权限不允许的方式做了一个访问套接字的尝试 => Port is already used + if (e is SocketException) + { + SocketException se = (SocketException)e; + if (se.SocketErrorCode == SocketError.AccessDenied) + { + e = new Exception("Port is already used", e); + } + } + Errored(this, new ErrorEventArgs(e)); } - - UpdateSystemProxy(); - StartReleasingMemory(); } public Server GetCurrentServer() @@ -128,8 +130,14 @@ namespace Shadowsocks.Controller return; } stopped = true; - local.Stop(); - polipoRunner.Stop(); + if (local != null) + { + local.Stop(); + } + if (polipoRunner != null) + { + polipoRunner.Stop(); + } if (_config.enabled) { SystemProxy.Disable(); @@ -153,36 +161,64 @@ namespace Shadowsocks.Controller return "ss://" + base64; } - - protected void SaveConfig(Configuration newConfig) + protected void Reload() { - Configuration.Save(newConfig); // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); + if (polipoRunner == null) + { + polipoRunner = new PolipoRunner(); + } + if (pacServer == null) + { + pacServer = new PACServer(); + pacServer.PACFileChanged += pacServer_PACFileChanged; + } + pacServer.Stop(); - local.Stop(); + + if (local != null) + { + local.Stop(); + } // don't put polipoRunner.Start() before pacServer.Stop() // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 // though UseShellExecute is set to true now // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open polipoRunner.Stop(); - polipoRunner.Start(_config); + try + { + polipoRunner.Start(_config); - local = new Local(_config); - local.Start(); - pacServer.Start(_config); + local = new Local(_config); + local.Start(); + pacServer.Start(_config); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + ReportError(e); + } if (ConfigChanged != null) { ConfigChanged(this, new EventArgs()); } + UpdateSystemProxy(); Util.Util.ReleaseMemory(); } + protected void SaveConfig(Configuration newConfig) + { + Configuration.Save(newConfig); + Reload(); + } + + private void UpdateSystemProxy() { if (_config.enabled) diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index 6b15ea9c..716e0df7 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -41,7 +41,9 @@ namespace Shadowsocks ShadowsocksController controller = new ShadowsocksController(); MenuViewController viewController = new MenuViewController(controller); - Util.Util.ReleaseMemory(); + + controller.Start(); + Application.Run(); } } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index a91e48f7..0d46ba5b 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -53,6 +53,7 @@ namespace Shadowsocks.View controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; controller.EnableGlobalChanged += controller_EnableGlobalChanged; + controller.Errored += controller_Errored; this.updateChecker = new UpdateChecker(); updateChecker.NewVersionFound += updateChecker_NewVersionFound; @@ -68,6 +69,11 @@ namespace Shadowsocks.View } } + void controller_Errored(object sender, System.IO.ErrorEventArgs e) + { + MessageBox.Show(e.GetException().ToString(), "Error: " + e.GetException().Message); + } + private void LoadTrayIcon() { int dpi; From 7122f82f0ba86446e174bd78613c639341eb4a17 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 13:07:07 +0800 Subject: [PATCH 22/39] merge polarssl and libsodium into a single dll --- shadowsocks-csharp/Data/libsodium.dll.gz | Bin 9989 -> 0 bytes shadowsocks-csharp/Data/libsscrypto.dll.gz | Bin 0 -> 10868 bytes shadowsocks-csharp/Data/polarssl.dll.gz | Bin 7964 -> 0 bytes shadowsocks-csharp/Encrypt/PolarSSL.cs | 13 ++++++++----- shadowsocks-csharp/Encrypt/Sodium.cs | 13 ++++++++----- shadowsocks-csharp/Properties/Resources.Designer.cs | 14 ++------------ shadowsocks-csharp/Properties/Resources.resx | 7 ++----- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 8 files changed, 21 insertions(+), 27 deletions(-) delete mode 100755 shadowsocks-csharp/Data/libsodium.dll.gz create mode 100755 shadowsocks-csharp/Data/libsscrypto.dll.gz delete mode 100755 shadowsocks-csharp/Data/polarssl.dll.gz diff --git a/shadowsocks-csharp/Data/libsodium.dll.gz b/shadowsocks-csharp/Data/libsodium.dll.gz deleted file mode 100755 index b4330a35d316e2c530978a0ab3b0080d4c523c70..0000000000000000000000000000000000000000 GIT binary patch literal 0 KcmV+b0RR6000031 literal 9989 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 PY0duxW!TyW*HZuh@=27x diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz new file mode 100755 index 0000000000000000000000000000000000000000..dfba9cdce863c625f744ed48be1d1e621f3250d8 GIT binary patch literal 10868 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 K7VC{DR{#LLZZ`}7 literal 0 KcmV+b0RR6000031 diff --git a/shadowsocks-csharp/Data/polarssl.dll.gz b/shadowsocks-csharp/Data/polarssl.dll.gz deleted file mode 100755 index 04a8f0a7f2e3e36f95858557b2d6d3ee731f83ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 KcmV+b0RR6000031 literal 7964 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 STC`QZPWj&kA-p>%LjV8 /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] libsodium_dll { + internal static byte[] libsscrypto_dll { get { - object obj = ResourceManager.GetObject("libsodium_dll", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] polarssl_dll { - get { - object obj = ResourceManager.GetObject("polarssl_dll", resourceCulture); + object obj = ResourceManager.GetObject("libsscrypto_dll", resourceCulture); return ((byte[])(obj)); } } diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index 4b6f8f3e..b28e1d17 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -118,11 +118,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\data\libsodium.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ..\Data\polarssl.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Data\polipo_config.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312 diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 06f5bc3a..9aca827b 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -129,6 +129,7 @@ Designer + From cdac52c19c70ad351a6918c4d85b339c31f64f4c Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 13:17:48 +0800 Subject: [PATCH 23/39] fix LoadLibrary --- shadowsocks-csharp/Encrypt/PolarSSL.cs | 2 +- shadowsocks-csharp/Encrypt/Sodium.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Encrypt/PolarSSL.cs b/shadowsocks-csharp/Encrypt/PolarSSL.cs index a76882b6..79941d57 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSL.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSL.cs @@ -23,7 +23,6 @@ namespace Shadowsocks.Encrypt try { FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); - LoadLibrary(dllPath); } catch (IOException) { @@ -32,6 +31,7 @@ namespace Shadowsocks.Encrypt { Console.WriteLine(e.ToString()); } + LoadLibrary(dllPath); } [DllImport("Kernel32.dll")] diff --git a/shadowsocks-csharp/Encrypt/Sodium.cs b/shadowsocks-csharp/Encrypt/Sodium.cs index 1fd6cc55..faced736 100755 --- a/shadowsocks-csharp/Encrypt/Sodium.cs +++ b/shadowsocks-csharp/Encrypt/Sodium.cs @@ -28,6 +28,7 @@ namespace Shadowsocks.Encrypt { Console.WriteLine(e.ToString()); } + LoadLibrary(dllPath); } [DllImport("Kernel32.dll")] From 58f51fcfe9483e09d8c74c73a223ea3541d080f9 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 13:53:43 +0800 Subject: [PATCH 24/39] gzip more --- shadowsocks-csharp/Data/libsscrypto.dll.gz | Bin 10868 -> 10603 bytes shadowsocks-csharp/Data/polipo.exe.gz | Bin 67842 -> 65617 bytes shadowsocks-csharp/Data/proxy.pac.txt.gz | Bin 16071 -> 14990 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz index dfba9cdce863c625f744ed48be1d1e621f3250d8..66a1185ec57e06bf2bddd81b0c93b3f72bd525a9 100755 GIT binary patch literal 10603 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 F008M3pJD(2 literal 10868 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 K7VC{DR{#LLZZ`}7 diff --git a/shadowsocks-csharp/Data/polipo.exe.gz b/shadowsocks-csharp/Data/polipo.exe.gz index 72e47a618b2d33885f35f0f2cf681d351ffc5225..836135111d80aadcead87cfcee734138933697af 100755 GIT binary patch literal 65617 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%0A}cW)^5( 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

EJMf@L!m-8u=^8=LA zY`KD8$)AG~X>Yj8v-^4t8reqaS7AcI0ZVrFk!-2*Hz=ESz)1Qg@S*MGPiac{OUH_F zEcKTYNg{sLBg16>HXfrbOUSG}60kA>q>}%CJM(GrRe|3?67(;t+O0nD820Q@G@?AupaLU~ zN+aO_v!L-*xLWy`C)%>8O!JHaReG^zWpl2-sc{6YCQ@eQo%FxZlg)`$co}Mt!fA(B zy{;y*EMp=ydhPG)yG8Rn35^ZL8f{O}wJ|(y<=5EA^_7q;$&Dj1o649Zv(*J<_xN&; zaVJk_ck4`t$%E)n{uQP}TS2yg2-zqNl)1fkd~V^ z`Wm6j3>G>Om{NpDV(3Rk0A~ry$gbu+%dN&y$E!>ipLIliOC#0j&QQmuAS5n|uGb`e zFIlS$lo&y!P6QU?)kKDuY7+Y;j5J)P`R#124ueaeWtUj+a5l(uvrK*qXK$Z9rLofv=+#yYv11jRwR~fj_FKf zhTB7EEMgo78k-Pk=bBl{sd{|qk?rc0!H;b2h2-nRlZHv2q(1Pd3-*%h9}gPa6o{4R z_#fZ}B?Wv+qmvLG6;RyNeRtN$6=2v^rc?p~?b%$~LzV&#W6LVwo(hL^5!^Qb$D?m} z$d=KU;%QVR@5_$}@@5{x11=W7`8xj78I)X1Nf4aleO^!cHYd&Dq@zf3bO%b|BDu@t z%e_c_Bwc8Rk2Mj5eR+-{_#i^!(fkhQB$lWQTgpEa$b3S`9GcG8 zZmk}Wpt@GgVS(o1oca)G49^+WkDT9|&O<;#{4^XQg&>wq7jIqdIcyXy+&X>+e1%G@ ze?Hez>r*18>rGt!}1pN!=Ns$LHF>cdu_*NU8iGf zonamO%PZ(ueW?g!!-u(2l&d=~ui^7okxL9dVIu&cwwnEaN~t65!>e?~%f(tdggfI^ z&~VVpSFGw1ERwxn;)4TJGX>LRxYlvMke1~+kHQ&jHJS;98pG}!Zix}+e<4jCK8xm4 zN4$XBTZNiGvI25J-ZSrc_q#}L9dnsW&SM19lr_mxHb{zhv(e%V!!&Mj@(h>q-kf&` z@=7UkN4J#r4nPNXk(}A)J~fYeGo^w|#NMDaJ@{`nsUpnZs|vfS^Y^A5R-@qDH& zu(KQw%MC5=51sFR6oZRrCDHCYo%9}v)-CFEYIW!cqhUFrH)?p$Okl-~shkkjiJh z!@S0xo*xS>1913mH22qc*Ca}F4(5H*lZLh&y);l^WKO=l#x_vfXnd|6i3+p{SEMAn z|A?7fo#6iS^Z{W5hYl6iE6lF+6NjPLR=>r}UNzxmyCa~y-;o?9WGm6H#H z7Bhr%rP|!gI9vT1eAHHDLQK1U8RgvGVjT$KI=Ihh}~c%k2==e6wi=Zh^qQ0Tc!fX z3pH#fmVWMZVDy2BFq%#nLD+^KA!kK+ZqFegF9Suyx%riClVLb)jK<|-yU1xl&L7hW zU>1~Vagrq+Hur2WRfeHy{XrJM%vEL=EBpMX`gw;;?{fCq=2Fk54(i!_u!7K+XiB-c zKYdNH|Cf3W)=8-u1$cfh17Uy?Jy`tcb~>UE1E9Fy6HQ&Xw2!n5=$o#@HtlXeuq=-B z(VC&O8(CfYasiEVp=kM_bjA(LCH8`$)SDDUFl~mQhs>L`lzc$ zI@p~7nHyx7f^Zm%DGwgqGx>sj3%TmeDeSCaz`}6A8wl`C0-U>uoe~2xpLNeyON5`= zlC#2Lux;K!at7@@Y%4iTWFyzlo?C_MU~=5HdEq$a5l#-^gyN`ou+$ZmI``O0_9#WA=(}Yr2KC(+5dm^SUfeR% zibc3)G^)V*&Lb;Vj;wsJevrBHq8JG71w4C))(0_l*IZ}nz8|4a-Dz<&b;H>l%l?5m zm=cRys&jOM z$KLE=?prCax+jT~VyyNztX#VIyCvi_lTOk7Y@w$&B;{hXc<9WJ7T7Hb$F7>NTYRgK zDwPGh8>DcJKe9=}n!GiKH zU%{iT1!TDVXHq|_8*ZT<66@D@frWAXDwqXgT>i{G!h2bB$F94)i*nTKJIYIdW;HFH zjd0KeH0x&Rrqf2agy}SXR-HRUXmgN@7hWHbS+C}M$cNvWh2&-1Auk)sUpi1goGjo$ zS-?mFXZ+>+(jhH)rRW>jB1kx z3=0DPP+n>>MZMVwv|neKV6?*<47mzuDkj%~Ski6|@gWuhG@K9daUqU6KN6}FzUreD z#CHEiz)gxaUs6Y5i;MF1Mb)GSB40_NEbV)GEsSbWv^3MIl)s_vyoJu5Z;%fmrQLfb z%KeaXc+Vw^ZD(2BQQOWr!=oJschNXX--C1bku&wJ?mX|lBq%2PkdYtXJWmJ4Jg4(| zzG0xJ854x!)^nV+e}icg$kZqF!JqSc(v(mu{|MM{|I0&2UpiS1)&>5pBIgI-<%D}~ z?zkrBp#lt~O_%%SKvKb*#YQF!6Ew0F?x2P56r=U>X<@z>sah>{Ne)&%aK-b|+9G&r zAmbOT*EiQ~v<#|cl@i|sLUydL9X55#$!+x)Qr%O%y=UBMSk^xp=e}u%v{lWM=b|}$ z@~lXbT!6?w?%|kz9FB^xGA_^4yr!Y`%v^%)Mqi)_kXrDZBS)n^SPz2K~<$tOQWf!DOB&7 ze~OkW>;IRQ*1D%judmlOHg8blf*%6VEBdI-sQP zOm1=u+fH&Jdmw@**~195FQlzyZdAHEkwabmC{F@LJb`X%#UuRUkF9wV@l~` zPQeI|MvkrYD;P(tV5$7=&C!+BrRuuJz;gUt!0=MPtMpx$N%-yXm4B>1+F9X0upNhax8W6)NKe)~p{ z^WLgWnaLs|OM)S{&`(7e*8jeK!}@RNX~{QmbfefRxP-xx*+(bjB&F~<+w0_{J-Pc0 zyBiX#FlmYXw){C|G5cy_w`)08Vy>8v)7z0!zNM{j8#PR9sW%5Raa$KX*(;m9L!k6~ zYF5KUderXDA7OP*1M9%y?YC9HZ$V8O)YSl9@w(MilZ@Xs`W!@>N_!&%zZuYI@`su)?^N=xQ{9xJ(2RJB9rL29Vn=$GrbqiFY&NF z54eo;6~3>(7*4a~aS6J{*J)@3B7?8|{hY$h)zDDhrj)(8L#cYRDKNs^*3)SQe`T9e zb!>-HaI7gPCAo`1dlWnq1?LoQkwvD46?wB-vc-HD{gh02?n!T* zT(ZSdzQr;-)mUav;bs&1*ZmFp5lxKw`tIg!pw6zJ;|~;jU^{V43l<}|lMlq~q7**z zk{9jsYex|M=Lq`eDdpP&#lBd0My?)5RUS@nPd{hgw{8z*VxqVOQD8fvdYgQNUJ~9R zOQ=IWm;km5OEa)Q6=-UEx`~FVx?rTE1;%2Zc630b_Bt~E!2S}o1N8LJSU;$iXIWe z=9I+pAq!*qb;2@t0(m4Td>U}jiql%j+&fuIpn{Z z84rkiMi~Xe-BA<_^+am#PM`^s89XjmC|aHdTuos`oCw`lqS_PTeY=XNHe@_?!1_Q0 z8H=hK{5Ed)l_#jA1adoj{;smHV%;?12<27~JL$m!q7o~|ZH zRoyZ)Ro_~IoQfMa)4^02>UsxNVoP=3QC%T{+&p%8CY z;~-m202%5_TpOgR0g$Ecrm7%bjigl4q(fwyI-{yVSbF9=PGpEkNKM8+cJ;sGiu6Ir zZ#kvVeeyqNV$!`m6r}rI7m*I9$DVywc*T6Byvap3A-|r>+Y%X=3*h$%_(=f_J57t& z=HCs?pHTEWm-`KB&kz3{<8Ovu-e(uNyyrvZMF0^fRhVLs^I6KdNzeKDzY8~*bSzf? zMtWm35U;};Wex&(DoOOX=CLR%7JFwb6;4#&Ws7ojlZnMW)%Ns3d|z*TC5&U!F7>~n zJtb(VSx#OjmL-S`Q7X2BWAmP(wWVCkW0-q)~ejrG3DllIc z2wega5~dP?FBlLQO+~pSO=tEQX?px`lJJ7C`DwUzAv)uO!E9%~nMeXZrdHa)!^8`L z()&C_RoPd}o--C)UBT6*M>}tByKd1rO3-SNpw*WMg(=A_J>as{*ICFYE?D6SFv~uS z?5=|wIB$O-nvKrG*8EosnO$k_bp)BAdL}2ota>=h^BlFkTxE}#T-~`Y$o@A{Ana;( z-=Na#n%&&%+&>u3dkNy%NLCI`F10&P*yiHnQkXd_Yt_aCXwVtdsZNTM;X%$f`C zOcB2fqH!S1+jyX4lf&S6W=pqPPhRW~vV~!JO>Z{Gib3_l3fDCTjmJfBi}`8-y^;05 zz_+6VmD)D9`hOT91?n<=`Ac7^n*#TzFg3Nkfj69@ETP_26BD{U#DCf!^xqXhV>*B2 zc4&7k!SC(Sw))8kAzlD^NZWU~N<0*~g-S&*C>9QS?VE3xoFhbFFSml`-?;(c{s4*> zL>Nh)?ypP_(E*xng`LuUuep~Ez^vi0fM5)1u4*Lq9VaU8m0H4r4W8@bPJ4!Fl5ledct8LX0HWq z*4M5^eNZJ+_M;LF-nG{kHbdXFki2eJtV6d4ZL4g0Y49oy1^HCsZPO^atG2q??PAUK3h7t%XU z9_TzyWzTC>NkP(<(N_h&qdH*p75r`J2gNp-1D3;muI^T|yO+{}H)n&p)xf4>XjO)) zH;PUqhxB$Sc9q;3YijVhCz{l<)HIg;q%E&ZDDZTGv2B3!?PMjvKTVhPNOd($aow7VE#*lt7YdZ_O^?c7N&I?kP_u@o^I6$F;4gWP}&@JK2 zz_*H)>_x}w{l(t~c=TUd;~A8yE>2|)#J7UVSJ|lcAOF z(Q=T+oB4b{StbPAn`r@JT>Xy2*dZZi?jEkd-Us+8o{fGW$@4)R`fW3 z`VS!{Y<%L)xzPnOy;qQ0jDMy0w+IbSKY0)5OD;BO z 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

SIa=uLUczjYA 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∋gb2E|a1cWM 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 x?)6p1JMVNdG_mcX8!RWh{k)kuw#wWahsb%ss diff --git a/shadowsocks-csharp/Data/proxy.pac.txt.gz b/shadowsocks-csharp/Data/proxy.pac.txt.gz index d5fce8c9d437161671d406480a593bdd8525ee01..3e8d18ad8cb824d39aa3c693e808a16be93df18a 100755 GIT binary patch literal 14990 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 From 41850e2931d3bc42e00fecc083a90fc9eb1745ec Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 13:59:59 +0800 Subject: [PATCH 25/39] update project --- shadowsocks-csharp/shadowsocks-csharp.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 9aca827b..bb2e76de 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -128,9 +128,7 @@ Designer - - SettingsSingleFileGenerator From 254f0ef62273a90faa28148fa3ca3a3bac4a39f2 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 14:28:36 +0800 Subject: [PATCH 26/39] save RAM a little more in PAC server --- shadowsocks-csharp/Controller/PACServer.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index 0b2934b4..f02476ae 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -78,6 +78,8 @@ namespace Shadowsocks.Controller } } + // we don't even use it + static byte[] requestBuf = new byte[2048]; public void AcceptCallback(IAsyncResult ar) { @@ -86,13 +88,12 @@ namespace Shadowsocks.Controller { Socket conn = listener.EndAccept(ar); - byte[] buf = new byte[2048]; object[] state = new object[] { conn, - buf + requestBuf }; - conn.BeginReceive(buf, 0, 1024, 0, + conn.BeginReceive(requestBuf, 0, requestBuf.Length, 0, new AsyncCallback(ReceiveCallback), state); } catch (ObjectDisposedException) @@ -130,18 +131,17 @@ namespace Shadowsocks.Controller else { byte[] pacGZ = Resources.proxy_pac_txt; - byte[] buffer = new byte[1024 * 1024]; // builtin pac gzip size: maximum 1M + byte[] buffer = new byte[1024]; // builtin pac gzip size: maximum 100K + MemoryStream sb = new MemoryStream(); int n; - using (GZipStream input = new GZipStream(new MemoryStream(pacGZ), CompressionMode.Decompress, false)) { - n = input.Read(buffer, 0, buffer.Length); - if (n == 0) + while((n = input.Read(buffer, 0, buffer.Length)) > 0) { - throw new IOException("can not decompress pac"); + sb.Write(buffer, 0, n); } - return System.Text.Encoding.UTF8.GetString(buffer, 0, n); + return System.Text.Encoding.UTF8.GetString(sb.ToArray()); } } } @@ -175,6 +175,7 @@ Connection: Close ", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac; byte[] response = System.Text.Encoding.UTF8.GetBytes(text); conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), conn); + Util.Util.ReleaseMemory(); } else { From 52ca609e3ee18d8fbc464f5faf8924eb7dbdf88e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 16:27:41 +0800 Subject: [PATCH 27/39] i18n --- shadowsocks-csharp/Controller/I18N.cs | 42 +++++++ .../Controller/ShadowsocksController.cs | 2 +- shadowsocks-csharp/Data/cn.txt | 36 ++++++ .../Properties/Resources.Designer.cs | 33 ++++++ shadowsocks-csharp/Properties/Resources.resx | 3 + shadowsocks-csharp/View/ConfigForm.Designer.cs | 132 ++++++++++----------- shadowsocks-csharp/View/ConfigForm.cs | 23 +++- shadowsocks-csharp/View/MenuViewController.cs | 83 +++++++------ shadowsocks-csharp/View/QRCodeForm.cs | 2 + shadowsocks-csharp/shadowsocks-csharp.csproj | 2 + 10 files changed, 254 insertions(+), 104 deletions(-) create mode 100755 shadowsocks-csharp/Controller/I18N.cs create mode 100644 shadowsocks-csharp/Data/cn.txt diff --git a/shadowsocks-csharp/Controller/I18N.cs b/shadowsocks-csharp/Controller/I18N.cs new file mode 100755 index 00000000..3ac09a41 --- /dev/null +++ b/shadowsocks-csharp/Controller/I18N.cs @@ -0,0 +1,42 @@ +using Shadowsocks.Properties; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace Shadowsocks.Controller +{ + public class I18N + { + protected static Dictionary Strings; + static I18N() + { + Strings = new Dictionary(); + + if (System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag.ToLowerInvariant().StartsWith("zh")) + { + string[] lines = Regex.Split(Resources.cn, "\r\n|\r|\n"); + foreach (string line in lines) + { + string[] kv = Regex.Split(line, "="); + if (kv.Length == 2) + { + Strings[kv[0]] = kv[1]; + } + } + } + } + + public static string GetString(string key) + { + if (Strings.ContainsKey(key)) + { + return Strings[key]; + } + else + { + return key; + } + } + } +} diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index e2a761ff..5388e39a 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -61,7 +61,7 @@ namespace Shadowsocks.Controller SocketException se = (SocketException)e; if (se.SocketErrorCode == SocketError.AccessDenied) { - e = new Exception("Port is already used", e); + e = new Exception(I18N.GetString("Port is already used"), e); } } Errored(this, new ErrorEventArgs(e)); diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt new file mode 100644 index 00000000..17736537 --- /dev/null +++ b/shadowsocks-csharp/Data/cn.txt @@ -0,0 +1,36 @@ +Shadowsocks=Shadowsocks +Enable=启用代理 +Mode=代理模式 +PAC=PAC 模式 +Global=全局模式 +Servers=服务器选择 +Edit Servers...=编辑服务器... +Start on Boot=自动启动 +Share over LAN=在局域网共享代理 +Edit PAC File...=编辑 PAC 文件... +Show QRCode...=显示二维码... +Show Logs...=显示日志... +About...=关于... +Quit=退出 +Edit Servers=编辑服务器 +&Add=添加(&A) +&Delete=删除(&D) +Server=服务器 +Server IP=服务器 IP +Server Port=服务器端口 +Password=密码 +Encryption=加密 +Proxy Port=代理端口 +Remarks=备注 +OK=确定 +Cancel=取消 +New server=新服务器 +QRCode=二维码 +Shadowsocks Error: {0}=Shadowsocks 错误: {0} +Port is already used=端口已被占用 +Illegal port number format=非法端口格式 +Please add at least one server=请添加至少一个服务器 +Shadowsocks {0} Update Found=Shadowsocks {0} 更新 +Click here to download=点击这里下载 +Shadowsocks is here=Shadowsocks 在这里 +You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks \ No newline at end of file diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 906e4d12..b8f50ab3 100755 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -61,6 +61,39 @@ namespace Shadowsocks.Properties { } ///

+ /// Looks up a localized string similar to Enable=启用 + ///Mode=模式 + ///PAC=PAC + ///Global=全局 + ///Servers=服务器 + ///Edit Servers...=编辑服务器... + ///Start on Boot=自动启动 + ///Share over LAN=在局域网共享代理 + ///Edit PAC File...=修改 PAC 文件... + ///Show QRCode...=显示二维码... + ///Show Logs...=显示日志... + ///About...=关于... + ///Quit=退出 + ///Edit Servers=编辑服务器 + ///Add=添加 + ///Delete=删除 + ///Server=服务器 + ///Server IP=服务器 IP + ///Server Port=服务器端口 + ///Password=密码 + ///Encryption=加密 + ///Proxy Port=代理端口 + ///Remarks=备注 + /// + ///. + /// + internal static string cn { + get { + return ResourceManager.GetString("cn", resourceCulture); + } + } + + /// /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] libsscrypto_dll { diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index b28e1d17..d8fb470d 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\data\cn.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + ..\data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 03b4a134..e95ca022 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -30,16 +30,16 @@ { this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.RemarksTextBox = new System.Windows.Forms.TextBox(); - this.label6 = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); + this.RemarksLabel = new System.Windows.Forms.Label(); + this.IPLabel = new System.Windows.Forms.Label(); + this.ServerPortLabel = new System.Windows.Forms.Label(); this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); - this.label4 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); + this.ProxyPortLabel = new System.Windows.Forms.Label(); + this.PasswordLabel = new System.Windows.Forms.Label(); this.IPTextBox = new System.Windows.Forms.TextBox(); this.ServerPortTextBox = new System.Windows.Forms.TextBox(); this.PasswordTextBox = new System.Windows.Forms.TextBox(); - this.label5 = new System.Windows.Forms.Label(); + this.EncryptionLabel = new System.Windows.Forms.Label(); this.EncryptionSelect = new System.Windows.Forms.ComboBox(); this.panel2 = new System.Windows.Forms.Panel(); this.OKButton = new System.Windows.Forms.Button(); @@ -64,16 +64,16 @@ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel1.Controls.Add(this.RemarksTextBox, 1, 5); - this.tableLayoutPanel1.Controls.Add(this.label6, 0, 5); - this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 5); + this.tableLayoutPanel1.Controls.Add(this.IPLabel, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.ServerPortLabel, 0, 1); this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 1, 4); - this.tableLayoutPanel1.Controls.Add(this.label4, 0, 4); - this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 0, 4); + this.tableLayoutPanel1.Controls.Add(this.PasswordLabel, 0, 2); this.tableLayoutPanel1.Controls.Add(this.IPTextBox, 1, 0); this.tableLayoutPanel1.Controls.Add(this.ServerPortTextBox, 1, 1); this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2); - this.tableLayoutPanel1.Controls.Add(this.label5, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.EncryptionLabel, 0, 3); this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5); @@ -98,35 +98,35 @@ this.RemarksTextBox.TabIndex = 10; this.RemarksTextBox.WordWrap = false; // - // label6 + // RemarksLabel // - this.label6.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(19, 142); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(49, 13); - this.label6.TabIndex = 9; - this.label6.Text = "Remarks"; + this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.RemarksLabel.AutoSize = true; + this.RemarksLabel.Location = new System.Drawing.Point(19, 142); + this.RemarksLabel.Name = "RemarksLabel"; + this.RemarksLabel.Size = new System.Drawing.Size(49, 13); + this.RemarksLabel.TabIndex = 9; + this.RemarksLabel.Text = "Remarks"; // - // label1 + // IPLabel // - this.label1.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(17, 11); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(51, 13); - this.label1.TabIndex = 0; - this.label1.Text = "Server IP"; + this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.IPLabel.AutoSize = true; + this.IPLabel.Location = new System.Drawing.Point(17, 11); + this.IPLabel.Name = "IPLabel"; + this.IPLabel.Size = new System.Drawing.Size(51, 13); + this.IPLabel.TabIndex = 0; + this.IPLabel.Text = "Server IP"; // - // label2 + // ServerPortLabel // - this.label2.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(8, 37); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(60, 13); - this.label2.TabIndex = 1; - this.label2.Text = "Server Port"; + this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.ServerPortLabel.AutoSize = true; + this.ServerPortLabel.Location = new System.Drawing.Point(8, 37); + this.ServerPortLabel.Name = "ServerPortLabel"; + this.ServerPortLabel.Size = new System.Drawing.Size(60, 13); + this.ServerPortLabel.TabIndex = 1; + this.ServerPortLabel.Text = "Server Port"; // // ProxyPortTextBox // @@ -137,25 +137,25 @@ this.ProxyPortTextBox.TabIndex = 4; this.ProxyPortTextBox.WordWrap = false; // - // label4 + // ProxyPortLabel // - this.label4.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(13, 116); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(55, 13); - this.label4.TabIndex = 3; - this.label4.Text = "Proxy Port"; + this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.ProxyPortLabel.AutoSize = true; + this.ProxyPortLabel.Location = new System.Drawing.Point(13, 116); + this.ProxyPortLabel.Name = "ProxyPortLabel"; + this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); + this.ProxyPortLabel.TabIndex = 3; + this.ProxyPortLabel.Text = "Proxy Port"; // - // label3 + // PasswordLabel // - this.label3.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(15, 63); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(53, 13); - this.label3.TabIndex = 2; - this.label3.Text = "Password"; + this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.PasswordLabel.AutoSize = true; + this.PasswordLabel.Location = new System.Drawing.Point(15, 63); + this.PasswordLabel.Name = "PasswordLabel"; + this.PasswordLabel.Size = new System.Drawing.Size(53, 13); + this.PasswordLabel.TabIndex = 2; + this.PasswordLabel.Text = "Password"; // // IPTextBox // @@ -185,15 +185,15 @@ this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.WordWrap = false; // - // label5 + // EncryptionLabel // - this.label5.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(11, 90); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(57, 13); - this.label5.TabIndex = 8; - this.label5.Text = "Encryption"; + this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.EncryptionLabel.AutoSize = true; + this.EncryptionLabel.Location = new System.Drawing.Point(11, 90); + this.EncryptionLabel.Name = "EncryptionLabel"; + this.EncryptionLabel.Size = new System.Drawing.Size(57, 13); + this.EncryptionLabel.TabIndex = 8; + this.EncryptionLabel.Text = "Encryption"; // // EncryptionSelect // @@ -347,15 +347,15 @@ #endregion private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label IPLabel; + private System.Windows.Forms.Label ServerPortLabel; + private System.Windows.Forms.Label PasswordLabel; + private System.Windows.Forms.Label ProxyPortLabel; private System.Windows.Forms.TextBox IPTextBox; private System.Windows.Forms.TextBox ServerPortTextBox; private System.Windows.Forms.TextBox PasswordTextBox; private System.Windows.Forms.TextBox ProxyPortTextBox; - private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label EncryptionLabel; private System.Windows.Forms.ComboBox EncryptionSelect; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Button OKButton; @@ -367,7 +367,7 @@ private System.Windows.Forms.GroupBox ServerGroupBox; private System.Windows.Forms.ListBox ServersListBox; private System.Windows.Forms.TextBox RemarksTextBox; - private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label RemarksLabel; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 1601e0ef..2ab4e03a 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -23,6 +23,7 @@ namespace Shadowsocks.View public ConfigForm(ShadowsocksController controller) { InitializeComponent(); + UpdateTexts(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); this.controller = controller; @@ -31,6 +32,22 @@ namespace Shadowsocks.View LoadCurrentConfiguration(); } + private void UpdateTexts() + { + AddButton.Text = I18N.GetString("&Add"); + DeleteButton.Text = I18N.GetString("&Delete"); + IPLabel.Text = I18N.GetString("Server IP"); + ServerPortLabel.Text = I18N.GetString("Server Port"); + PasswordLabel.Text = I18N.GetString("Password"); + EncryptionLabel.Text = I18N.GetString("Encryption"); + ProxyPortLabel.Text = I18N.GetString("Proxy Port"); + RemarksLabel.Text = I18N.GetString("Remarks"); + ServerGroupBox.Text = I18N.GetString("Server"); + OKButton.Text = I18N.GetString("OK"); + MyCancelButton.Text = I18N.GetString("Cancel"); + this.Text = I18N.GetString("Edit Servers"); + } + private void controller_ConfigChanged(object sender, EventArgs e) { LoadCurrentConfiguration(); @@ -67,7 +84,7 @@ namespace Shadowsocks.View } catch (FormatException) { - MessageBox.Show("illegal port number format"); + MessageBox.Show(I18N.GetString("Illegal port number format")); } catch (Exception ex) { @@ -102,7 +119,7 @@ namespace Shadowsocks.View ServersListBox.Items.Clear(); foreach (Server server in _modifiedConfiguration.configs) { - ServersListBox.Items.Add(string.IsNullOrEmpty(server.server) ? "New server" : string.IsNullOrEmpty(server.remarks)? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); + ServersListBox.Items.Add(string.IsNullOrEmpty(server.server) ? I18N.GetString("New server") : string.IsNullOrEmpty(server.remarks)? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); } } @@ -176,7 +193,7 @@ namespace Shadowsocks.View } if (_modifiedConfiguration.configs.Count == 0) { - MessageBox.Show("Please add at least one server"); + MessageBox.Show(I18N.GetString("Please add at least one server")); return; } controller.SaveServers(_modifiedConfiguration.configs); diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 0d46ba5b..50bd991c 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -19,7 +19,7 @@ namespace Shadowsocks.View private ShadowsocksController controller; private UpdateChecker updateChecker; - private NotifyIcon notifyIcon1; + private NotifyIcon _notifyIcon; private ContextMenu contextMenu1; private bool _isFirstRun; @@ -44,10 +44,10 @@ namespace Shadowsocks.View public MenuViewController(ShadowsocksController controller) { + this.controller = controller; + LoadMenu(); - LoadTrayIcon(); - this.controller = controller; controller.EnableStatusChanged += controller_EnableStatusChanged; controller.ConfigChanged += controller_ConfigChanged; controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; @@ -55,6 +55,13 @@ namespace Shadowsocks.View controller.EnableGlobalChanged += controller_EnableGlobalChanged; controller.Errored += controller_Errored; + _notifyIcon = new NotifyIcon(); + LoadTrayIcon(); + _notifyIcon.Visible = true; + _notifyIcon.Text = I18N.GetString("Shadowsocks"); + _notifyIcon.ContextMenu = contextMenu1; + _notifyIcon.DoubleClick += notifyIcon1_DoubleClick; + this.updateChecker = new UpdateChecker(); updateChecker.NewVersionFound += updateChecker_NewVersionFound; @@ -71,7 +78,7 @@ namespace Shadowsocks.View void controller_Errored(object sender, System.IO.ErrorEventArgs e) { - MessageBox.Show(e.GetException().ToString(), "Error: " + e.GetException().Message); + MessageBox.Show(e.GetException().ToString(), String.Format(I18N.GetString("Shadowsocks Error: {0}"), e.GetException().Message)); } private void LoadTrayIcon() @@ -95,13 +102,20 @@ namespace Shadowsocks.View { icon = Resources.ss24; } - notifyIcon1 = new NotifyIcon(); - notifyIcon1.Text = "Shadowsocks"; - notifyIcon1.Icon = Icon.FromHandle(icon.GetHicon()); - notifyIcon1.Visible = true; - - notifyIcon1.ContextMenu = contextMenu1; - notifyIcon1.DoubleClick +=notifyIcon1_DoubleClick; + if (!controller.GetConfiguration().enabled) + { + Bitmap iconCopy = new Bitmap(icon); + for (int x = 0; x < iconCopy.Width; x++) + { + for (int y = 0; y < iconCopy.Height; y++) + { + Color color = icon.GetPixel(x, y); + iconCopy.SetPixel(x, y , Color.FromArgb((byte)(color.A / 1.25), color.R, color.G, color.B)); + } + } + icon = iconCopy; + } + _notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); } private void LoadMenu() @@ -146,7 +160,7 @@ namespace Shadowsocks.View // enableItem // this.enableItem.Index = 0; - this.enableItem.Text = "&Enable"; + this.enableItem.Text = I18N.GetString("Enable"); this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); // // modeMenu @@ -155,18 +169,18 @@ namespace Shadowsocks.View this.modeItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.PACModeItem, this.globalModeItem}); - this.modeItem.Text = "Mode"; + this.modeItem.Text = I18N.GetString("Mode"); // // PACModeItem // this.PACModeItem.Index = 0; - this.PACModeItem.Text = "PAC"; + this.PACModeItem.Text = I18N.GetString("PAC"); this.PACModeItem.Click += new System.EventHandler(this.PACModeItem_Click); // // globalModeItem // this.globalModeItem.Index = 1; - this.globalModeItem.Text = "Global"; + this.globalModeItem.Text = I18N.GetString("Global"); this.globalModeItem.Click += new System.EventHandler(this.GlobalModeItem_Click); // // ServersItem @@ -175,7 +189,7 @@ namespace Shadowsocks.View this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.SeperatorItem, this.ConfigItem}); - this.ServersItem.Text = "&Servers"; + this.ServersItem.Text = I18N.GetString("Servers"); // // SeperatorItem // @@ -185,7 +199,7 @@ namespace Shadowsocks.View // ConfigItem // this.ConfigItem.Index = 1; - this.ConfigItem.Text = "Edit Servers..."; + this.ConfigItem.Text = I18N.GetString("Edit Servers..."); this.ConfigItem.Click += new System.EventHandler(this.Config_Click); // // menuItem1 @@ -196,19 +210,19 @@ namespace Shadowsocks.View // AutoStartupItem // this.AutoStartupItem.Index = 4; - this.AutoStartupItem.Text = "Start on Boot"; + this.AutoStartupItem.Text = I18N.GetString("Start on Boot"); this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); // // ShareOverLANItem // this.ShareOverLANItem.Index = 5; - this.ShareOverLANItem.Text = "Share over LAN"; + this.ShareOverLANItem.Text = I18N.GetString("Share over LAN"); this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); // // editPACFileItem // this.editPACFileItem.Index = 6; - this.editPACFileItem.Text = "Edit &PAC File..."; + this.editPACFileItem.Text = I18N.GetString("Edit PAC File..."); this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); // // menuItem4 @@ -219,19 +233,19 @@ namespace Shadowsocks.View // QRCodeItem // this.QRCodeItem.Index = 8; - this.QRCodeItem.Text = "Show &QRCode..."; + this.QRCodeItem.Text = I18N.GetString("Show QRCode..."); this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); // // ShowLogItem // this.ShowLogItem.Index = 9; - this.ShowLogItem.Text = "Show Logs..."; + this.ShowLogItem.Text = I18N.GetString("Show Logs..."); this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); // // aboutItem // this.aboutItem.Index = 10; - this.aboutItem.Text = "About..."; + this.aboutItem.Text = I18N.GetString("About..."); this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); // // menuItem3 @@ -242,7 +256,7 @@ namespace Shadowsocks.View // quitItem // this.quitItem.Index = 12; - this.quitItem.Text = "&Quit"; + this.quitItem.Text = I18N.GetString("Quit"); this.quitItem.Click += new System.EventHandler(this.Quit_Click); } @@ -254,6 +268,7 @@ namespace Shadowsocks.View private void controller_EnableStatusChanged(object sender, EventArgs e) { enableItem.Checked = controller.GetConfiguration().enabled; + LoadTrayIcon(); } void controller_ShareOverLANStatusChanged(object sender, EventArgs e) @@ -276,11 +291,11 @@ namespace Shadowsocks.View void updateChecker_NewVersionFound(object sender, EventArgs e) { - notifyIcon1.BalloonTipTitle = "Shadowsocks " + updateChecker.LatestVersionNumber + " Update Found"; - notifyIcon1.BalloonTipText = "Click here to download"; - notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; - notifyIcon1.BalloonTipClicked += notifyIcon1_BalloonTipClicked; - notifyIcon1.ShowBalloonTip(5000); + _notifyIcon.BalloonTipTitle = String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber); + _notifyIcon.BalloonTipText = I18N.GetString("Click here to download"); + _notifyIcon.BalloonTipIcon = ToolTipIcon.Info; + _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; + _notifyIcon.ShowBalloonTip(5000); _isFirstRun = false; } @@ -354,7 +369,7 @@ namespace Shadowsocks.View private void Quit_Click(object sender, EventArgs e) { controller.Stop(); - notifyIcon1.Visible = false; + _notifyIcon.Visible = false; Application.Exit(); } @@ -362,10 +377,10 @@ namespace Shadowsocks.View { if (_isFirstRun) { - notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; - notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; - notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; - notifyIcon1.ShowBalloonTip(0); + _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); _isFirstRun = false; } } diff --git a/shadowsocks-csharp/View/QRCodeForm.cs b/shadowsocks-csharp/View/QRCodeForm.cs index 01441614..3cde5f63 100755 --- a/shadowsocks-csharp/View/QRCodeForm.cs +++ b/shadowsocks-csharp/View/QRCodeForm.cs @@ -1,4 +1,5 @@ using QRCode4CS; +using Shadowsocks.Controller; using Shadowsocks.Properties; using System; using System.Collections.Generic; @@ -21,6 +22,7 @@ namespace Shadowsocks.View this.code = code; InitializeComponent(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); + this.Text = I18N.GetString("QRCode"); } private void GenQR(string ssconfig) diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index bb2e76de..1444ca66 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -73,6 +73,7 @@ + @@ -146,6 +147,7 @@ + From eaaacd398dc8f5edf186a3a545be8a5f180ac6a4 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 17:26:40 +0800 Subject: [PATCH 28/39] minor fixes --- shadowsocks-csharp/Controller/UpdateChecker.cs | 4 +++- shadowsocks-csharp/Data/cn.txt | 4 +++- shadowsocks-csharp/Model/Server.cs | 8 ++++++++ shadowsocks-csharp/Properties/AssemblyInfo.cs | 5 +++-- shadowsocks-csharp/View/ConfigForm.Designer.cs | 6 +++--- shadowsocks-csharp/View/ConfigForm.cs | 2 +- shadowsocks-csharp/View/MenuViewController.cs | 14 ++++++++------ 7 files changed, 29 insertions(+), 14 deletions(-) diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index 046ae941..43a1af07 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -17,6 +17,8 @@ namespace Shadowsocks.Controller public string LatestVersionURL; public event EventHandler NewVersionFound; + public const string Version = "2.1.3"; + public void CheckUpdate() { // TODO test failures @@ -100,7 +102,7 @@ namespace Shadowsocks.Controller { return false; } - string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + string currentVersion = Version; return CompareVersion(version, currentVersion) > 0; } diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 17736537..0e2cc5e5 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -33,4 +33,6 @@ Please add at least one server=请添加至少一个服务器 Shadowsocks {0} Update Found=Shadowsocks {0} 更新 Click here to download=点击这里下载 Shadowsocks is here=Shadowsocks 在这里 -You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks \ No newline at end of file +You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks +Enabled=已启用代理 +Disabled=已禁用代理 diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index 99e74f88..ddc3602d 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -16,5 +16,13 @@ namespace Shadowsocks.Model public string password; public string method; public string remarks; + + public string FriendlyName + { + get + { + return string.IsNullOrEmpty(remarks) ? server + ":" + server_port : server + ":" + server_port + " (" + remarks + ")"; + } + } } } diff --git a/shadowsocks-csharp/Properties/AssemblyInfo.cs b/shadowsocks-csharp/Properties/AssemblyInfo.cs index 28eb113d..edc36101 100755 --- a/shadowsocks-csharp/Properties/AssemblyInfo.cs +++ b/shadowsocks-csharp/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using Shadowsocks.Controller; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -32,5 +33,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.2")] +[assembly: AssemblyVersion(UpdateChecker.Version)] // [assembly: AssemblyFileVersion("2.0.0")] diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index e95ca022..86d95143 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -295,9 +295,9 @@ // ServerGroupBox // this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); - this.ServerGroupBox.Location = new System.Drawing.Point(223, 12); + this.ServerGroupBox.Location = new System.Drawing.Point(220, 12); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(255, 205); + this.ServerGroupBox.Size = new System.Drawing.Size(258, 199); this.ServerGroupBox.TabIndex = 6; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -307,7 +307,7 @@ this.ServersListBox.FormattingEnabled = true; this.ServersListBox.Location = new System.Drawing.Point(12, 12); this.ServersListBox.Name = "ServersListBox"; - this.ServersListBox.Size = new System.Drawing.Size(192, 173); + this.ServersListBox.Size = new System.Drawing.Size(192, 199); this.ServersListBox.TabIndex = 5; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 2ab4e03a..77281160 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -119,7 +119,7 @@ namespace Shadowsocks.View ServersListBox.Items.Clear(); foreach (Server server in _modifiedConfiguration.configs) { - ServersListBox.Items.Add(string.IsNullOrEmpty(server.server) ? I18N.GetString("New server") : string.IsNullOrEmpty(server.remarks)? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); + ServersListBox.Items.Add(string.IsNullOrEmpty(server.server) ? I18N.GetString("New server") : server.FriendlyName); } } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 50bd991c..7ffe071c 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -56,9 +56,8 @@ namespace Shadowsocks.View controller.Errored += controller_Errored; _notifyIcon = new NotifyIcon(); - LoadTrayIcon(); + UpdateTrayIcon(); _notifyIcon.Visible = true; - _notifyIcon.Text = I18N.GetString("Shadowsocks"); _notifyIcon.ContextMenu = contextMenu1; _notifyIcon.DoubleClick += notifyIcon1_DoubleClick; @@ -81,7 +80,7 @@ namespace Shadowsocks.View MessageBox.Show(e.GetException().ToString(), String.Format(I18N.GetString("Shadowsocks Error: {0}"), e.GetException().Message)); } - private void LoadTrayIcon() + private void UpdateTrayIcon() { int dpi; Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); @@ -102,7 +101,8 @@ namespace Shadowsocks.View { icon = Resources.ss24; } - if (!controller.GetConfiguration().enabled) + bool enabled = controller.GetConfiguration().enabled; + if (!enabled) { Bitmap iconCopy = new Bitmap(icon); for (int x = 0; x < iconCopy.Width; x++) @@ -116,6 +116,8 @@ namespace Shadowsocks.View icon = iconCopy; } _notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); + + _notifyIcon.Text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("Enabled") : I18N.GetString("Disabled")) + "\n" + controller.GetCurrentServer().FriendlyName; } private void LoadMenu() @@ -263,12 +265,12 @@ namespace Shadowsocks.View private void controller_ConfigChanged(object sender, EventArgs e) { LoadCurrentConfiguration(); + UpdateTrayIcon(); } private void controller_EnableStatusChanged(object sender, EventArgs e) { enableItem.Checked = controller.GetConfiguration().enabled; - LoadTrayIcon(); } void controller_ShareOverLANStatusChanged(object sender, EventArgs e) @@ -326,7 +328,7 @@ namespace Shadowsocks.View for (int i = 0; i < configuration.configs.Count; i++) { Server server = configuration.configs[i]; - MenuItem item = new MenuItem(string.IsNullOrEmpty(server.remarks) ? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); + MenuItem item = new MenuItem(server.FriendlyName); item.Tag = i; item.Click += AServerItem_Click; items.Add(item); From e9432471504e3bcb468aac2a35c9118803c2d818 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 18:19:43 +0800 Subject: [PATCH 29/39] update texts --- shadowsocks-csharp/Data/cn.txt | 5 ++++- shadowsocks-csharp/Model/Configuration.cs | 11 ++++++----- shadowsocks-csharp/Model/Server.cs | 5 +++++ shadowsocks-csharp/View/ConfigForm.cs | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 0e2cc5e5..ba18053c 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -24,12 +24,15 @@ Proxy Port=代理端口 Remarks=备注 OK=确定 Cancel=取消 -New server=新服务器 +New server=未配置的服务器 QRCode=二维码 Shadowsocks Error: {0}=Shadowsocks 错误: {0} Port is already used=端口已被占用 Illegal port number format=非法端口格式 Please add at least one server=请添加至少一个服务器 +Server IP can not be blank=服务器 IP 不能为空 +Password can not be blank=密码不能为空 +Port out of range=端口超出范围 Shadowsocks {0} Update Found=Shadowsocks {0} 更新 Click here to download=点击这里下载 Shadowsocks is here=Shadowsocks 在这里 diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 66dbcb4c..c2ee6ab5 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -1,4 +1,5 @@ -using System; +using Shadowsocks.Controller; +using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -109,7 +110,7 @@ namespace Shadowsocks.Model { if (!condition) { - throw new Exception("assertion failure"); + throw new Exception(I18N.GetString("assertion failure")); } } @@ -117,7 +118,7 @@ namespace Shadowsocks.Model { if (port <= 0 || port > 65535) { - throw new ArgumentException("port out of range"); + throw new ArgumentException(I18N.GetString("Port out of range")); } } @@ -125,7 +126,7 @@ namespace Shadowsocks.Model { if (string.IsNullOrEmpty(password)) { - throw new ArgumentException("password can not be blank"); + throw new ArgumentException(I18N.GetString("Password can not be blank")); } } @@ -133,7 +134,7 @@ namespace Shadowsocks.Model { if (string.IsNullOrEmpty(server)) { - throw new ArgumentException("server IP can not be blank"); + throw new ArgumentException(I18N.GetString("Server IP can not be blank")); } } diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index ddc3602d..a8d03dda 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -4,6 +4,7 @@ using System.Text; using System.IO; using System.Diagnostics; using SimpleJson; +using Shadowsocks.Controller; namespace Shadowsocks.Model { @@ -21,6 +22,10 @@ namespace Shadowsocks.Model { get { + if (string.IsNullOrEmpty(server)) + { + return I18N.GetString("New server"); + } return string.IsNullOrEmpty(remarks) ? server + ":" + server_port : server + ":" + server_port + " (" + remarks + ")"; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 77281160..e58702cf 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -119,7 +119,7 @@ namespace Shadowsocks.View ServersListBox.Items.Clear(); foreach (Server server in _modifiedConfiguration.configs) { - ServersListBox.Items.Add(string.IsNullOrEmpty(server.server) ? I18N.GetString("New server") : server.FriendlyName); + ServersListBox.Items.Add(server.FriendlyName); } } From c40e908d0562307c0c47b153ed04865b58059ef6 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 18:22:02 +0800 Subject: [PATCH 30/39] remove CheckRemark --- shadowsocks-csharp/Model/Configuration.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index c2ee6ab5..63b4c750 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -37,7 +37,6 @@ namespace Shadowsocks.Model CheckPort(server.server_port); CheckPassword(server.password); CheckServer(server.server); - CheckRemark(server.remarks); } public static Configuration Load() @@ -138,11 +137,6 @@ namespace Shadowsocks.Model } } - private static void CheckRemark(string remark) - { - //remark is optional - } - private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy { // convert string to int From a2cc753d5ae9bf11bd302aa6a92f20aeb7743fef Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 18:29:53 +0800 Subject: [PATCH 31/39] update translation --- .../Controller/ShadowsocksController.cs | 20 ++++++++++---------- shadowsocks-csharp/Data/cn.txt | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 5388e39a..080390be 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -54,16 +54,6 @@ namespace Shadowsocks.Controller { if (Errored != null) { - // translate Microsoft language into human language - // i.e. 以一种访问权限不允许的方式做了一个访问套接字的尝试 => Port is already used - if (e is SocketException) - { - SocketException se = (SocketException)e; - if (se.SocketErrorCode == SocketError.AccessDenied) - { - e = new Exception(I18N.GetString("Port is already used"), e); - } - } Errored(this, new ErrorEventArgs(e)); } } @@ -198,6 +188,16 @@ namespace Shadowsocks.Controller } catch (Exception e) { + // translate Microsoft language into human language + // i.e. An attempt was made to access a socket in a way forbidden by its access permissions => Port already in use + if (e is SocketException) + { + SocketException se = (SocketException)e; + if (se.SocketErrorCode == SocketError.AccessDenied) + { + e = new Exception(I18N.GetString("Port already in use"), e); + } + } Logging.LogUsefulException(e); ReportError(e); } diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index ba18053c..3feaeb98 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -27,7 +27,7 @@ Cancel=取消 New server=未配置的服务器 QRCode=二维码 Shadowsocks Error: {0}=Shadowsocks 错误: {0} -Port is already used=端口已被占用 +Port already in use=端口已被占用 Illegal port number format=非法端口格式 Please add at least one server=请添加至少一个服务器 Server IP can not be blank=服务器 IP 不能为空 From ba95aab7f5bd340d67aa19f58883e2b48751540b Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 19:01:19 +0800 Subject: [PATCH 32/39] update font --- shadowsocks-csharp/View/ConfigForm.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index e58702cf..489b7d2d 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -22,6 +22,7 @@ namespace Shadowsocks.View public ConfigForm(ShadowsocksController controller) { + this.Font = System.Drawing.SystemFonts.DialogFont; InitializeComponent(); UpdateTexts(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); From 06b92a3c0a86e115888690dfff326c3312189bde Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 19:59:05 +0800 Subject: [PATCH 33/39] auto layout --- .../Properties/Resources.Designer.cs | 26 +-- shadowsocks-csharp/View/ConfigForm.Designer.cs | 176 +++++++++++++-------- shadowsocks-csharp/View/ConfigForm.cs | 5 + 3 files changed, 135 insertions(+), 72 deletions(-) diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index b8f50ab3..25ea71a9 100755 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -61,22 +61,23 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized string similar to Enable=启用 - ///Mode=模式 - ///PAC=PAC - ///Global=全局 - ///Servers=服务器 + /// Looks up a localized string similar to Shadowsocks=Shadowsocks + ///Enable=启用代理 + ///Mode=代理模式 + ///PAC=PAC 模式 + ///Global=全局模式 + ///Servers=服务器选择 ///Edit Servers...=编辑服务器... ///Start on Boot=自动启动 ///Share over LAN=在局域网共享代理 - ///Edit PAC File...=修改 PAC 文件... + ///Edit PAC File...=编辑 PAC 文件... ///Show QRCode...=显示二维码... ///Show Logs...=显示日志... ///About...=关于... ///Quit=退出 ///Edit Servers=编辑服务器 - ///Add=添加 - ///Delete=删除 + ///&Add=添加(&A) + ///&Delete=删除(&D) ///Server=服务器 ///Server IP=服务器 IP ///Server Port=服务器端口 @@ -84,8 +85,13 @@ namespace Shadowsocks.Properties { ///Encryption=加密 ///Proxy Port=代理端口 ///Remarks=备注 - /// - ///. + ///OK=确定 + ///Cancel=取消 + ///New server=未配置的服务器 + ///QRCode=二维码 + ///Shadowsocks Error: {0}=Shadowsocks 错误: {0} + ///Port already in use=端口已被占用 + ///Il [rest of string was truncated]";. /// internal static string cn { get { diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 86d95143..6035ae4a 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -44,16 +44,18 @@ this.panel2 = new System.Windows.Forms.Panel(); this.OKButton = new System.Windows.Forms.Button(); this.MyCancelButton = new System.Windows.Forms.Button(); - this.panel1 = new System.Windows.Forms.Panel(); - this.panel3 = new System.Windows.Forms.Panel(); this.DeleteButton = new System.Windows.Forms.Button(); this.AddButton = new System.Windows.Forms.Button(); this.ServerGroupBox = new System.Windows.Forms.GroupBox(); this.ServersListBox = new System.Windows.Forms.ListBox(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel1.SuspendLayout(); - this.panel1.SuspendLayout(); - this.panel3.SuspendLayout(); this.ServerGroupBox.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + this.tableLayoutPanel4.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel1 @@ -76,9 +78,9 @@ this.tableLayoutPanel1.Controls.Add(this.EncryptionLabel, 0, 3); this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); - this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5); + this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); this.tableLayoutPanel1.RowCount = 6; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -86,13 +88,13 @@ 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(242, 167); + this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 163); this.tableLayoutPanel1.TabIndex = 0; // // 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(74, 139); + this.RemarksTextBox.Location = new System.Drawing.Point(72, 137); this.RemarksTextBox.Name = "RemarksTextBox"; this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); this.RemarksTextBox.TabIndex = 10; @@ -102,7 +104,7 @@ // this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.RemarksLabel.AutoSize = true; - this.RemarksLabel.Location = new System.Drawing.Point(19, 142); + this.RemarksLabel.Location = new System.Drawing.Point(17, 140); this.RemarksLabel.Name = "RemarksLabel"; this.RemarksLabel.Size = new System.Drawing.Size(49, 13); this.RemarksLabel.TabIndex = 9; @@ -112,7 +114,7 @@ // this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.IPLabel.AutoSize = true; - this.IPLabel.Location = new System.Drawing.Point(17, 11); + this.IPLabel.Location = new System.Drawing.Point(15, 9); this.IPLabel.Name = "IPLabel"; this.IPLabel.Size = new System.Drawing.Size(51, 13); this.IPLabel.TabIndex = 0; @@ -122,7 +124,7 @@ // this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ServerPortLabel.AutoSize = true; - this.ServerPortLabel.Location = new System.Drawing.Point(8, 37); + this.ServerPortLabel.Location = new System.Drawing.Point(6, 35); this.ServerPortLabel.Name = "ServerPortLabel"; this.ServerPortLabel.Size = new System.Drawing.Size(60, 13); this.ServerPortLabel.TabIndex = 1; @@ -131,7 +133,7 @@ // ProxyPortTextBox // this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyPortTextBox.Location = new System.Drawing.Point(74, 113); + this.ProxyPortTextBox.Location = new System.Drawing.Point(72, 111); this.ProxyPortTextBox.Name = "ProxyPortTextBox"; this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); this.ProxyPortTextBox.TabIndex = 4; @@ -141,7 +143,7 @@ // this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(13, 116); + this.ProxyPortLabel.Location = new System.Drawing.Point(11, 114); this.ProxyPortLabel.Name = "ProxyPortLabel"; this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); this.ProxyPortLabel.TabIndex = 3; @@ -151,7 +153,7 @@ // this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PasswordLabel.AutoSize = true; - this.PasswordLabel.Location = new System.Drawing.Point(15, 63); + this.PasswordLabel.Location = new System.Drawing.Point(13, 61); this.PasswordLabel.Name = "PasswordLabel"; this.PasswordLabel.Size = new System.Drawing.Size(53, 13); this.PasswordLabel.TabIndex = 2; @@ -160,7 +162,7 @@ // 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(74, 8); + this.IPTextBox.Location = new System.Drawing.Point(72, 6); this.IPTextBox.Name = "IPTextBox"; this.IPTextBox.Size = new System.Drawing.Size(160, 20); this.IPTextBox.TabIndex = 0; @@ -169,7 +171,7 @@ // 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(74, 34); + this.ServerPortTextBox.Location = new System.Drawing.Point(72, 32); this.ServerPortTextBox.Name = "ServerPortTextBox"; this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); this.ServerPortTextBox.TabIndex = 1; @@ -178,7 +180,7 @@ // 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(74, 60); + this.PasswordTextBox.Location = new System.Drawing.Point(72, 58); this.PasswordTextBox.Name = "PasswordTextBox"; this.PasswordTextBox.PasswordChar = '*'; this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); @@ -189,7 +191,7 @@ // this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.EncryptionLabel.AutoSize = true; - this.EncryptionLabel.Location = new System.Drawing.Point(11, 90); + this.EncryptionLabel.Location = new System.Drawing.Point(9, 88); this.EncryptionLabel.Name = "EncryptionLabel"; this.EncryptionLabel.Size = new System.Drawing.Size(57, 13); this.EncryptionLabel.TabIndex = 8; @@ -212,7 +214,7 @@ "aes-192-cfb", "aes-128-cfb", "rc4"}); - this.EncryptionSelect.Location = new System.Drawing.Point(74, 86); + this.EncryptionSelect.Location = new System.Drawing.Point(72, 84); this.EncryptionSelect.Name = "EncryptionSelect"; this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); this.EncryptionSelect.TabIndex = 3; @@ -222,7 +224,7 @@ 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(164, 175); + this.panel2.Location = new System.Drawing.Point(207, 187); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(0, 0); this.panel2.TabIndex = 1; @@ -230,7 +232,9 @@ // OKButton // this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.OKButton.Location = new System.Drawing.Point(4, 4); + 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.Name = "OKButton"; this.OKButton.Size = new System.Drawing.Size(75, 23); this.OKButton.TabIndex = 8; @@ -241,7 +245,9 @@ // MyCancelButton // this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.MyCancelButton.Location = new System.Drawing.Point(87, 4); + 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, 0, 0); this.MyCancelButton.Name = "MyCancelButton"; this.MyCancelButton.Size = new System.Drawing.Size(75, 23); this.MyCancelButton.TabIndex = 9; @@ -249,34 +255,13 @@ this.MyCancelButton.UseVisualStyleBackColor = true; this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); // - // panel1 - // - this.panel1.AutoSize = true; - this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel1.Controls.Add(this.MyCancelButton); - this.panel1.Controls.Add(this.OKButton); - this.panel1.Location = new System.Drawing.Point(313, 247); - this.panel1.Margin = new System.Windows.Forms.Padding(0); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(165, 30); - this.panel1.TabIndex = 1; - // - // panel3 - // - this.panel3.AutoSize = true; - this.panel3.Controls.Add(this.DeleteButton); - this.panel3.Controls.Add(this.AddButton); - this.panel3.Location = new System.Drawing.Point(12, 220); - this.panel3.Margin = new System.Windows.Forms.Padding(0); - this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(192, 31); - this.panel3.TabIndex = 5; - // // DeleteButton // - this.DeleteButton.Location = new System.Drawing.Point(100, 4); + 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.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(89, 23); + this.DeleteButton.Size = new System.Drawing.Size(80, 23); this.DeleteButton.TabIndex = 7; this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; @@ -284,9 +269,11 @@ // // AddButton // - this.AddButton.Location = new System.Drawing.Point(4, 4); + 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.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(89, 23); + this.AddButton.Size = new System.Drawing.Size(80, 23); this.AddButton.TabIndex = 6; this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; @@ -294,10 +281,13 @@ // // ServerGroupBox // + 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(220, 12); + this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); + this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(258, 199); + this.ServerGroupBox.Size = new System.Drawing.Size(249, 200); this.ServerGroupBox.TabIndex = 6; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -305,29 +295,88 @@ // ServersListBox // this.ServersListBox.FormattingEnabled = true; - this.ServersListBox.Location = new System.Drawing.Point(12, 12); + this.ServersListBox.IntegralHeight = false; + 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(192, 199); + this.ServersListBox.Size = new System.Drawing.Size(166, 148); this.ServersListBox.TabIndex = 5; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.AutoSize = true; + this.tableLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel2.ColumnCount = 2; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel3, 1, 2); + 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.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(427, 264); + this.tableLayoutPanel2.TabIndex = 7; + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.AutoSize = true; + this.tableLayoutPanel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel3.ColumnCount = 2; + 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.Controls.Add(this.MyCancelButton, 1, 0); + this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; + this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 235); + this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 1; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel3.Size = new System.Drawing.Size(159, 26); + this.tableLayoutPanel3.TabIndex = 8; + // + // tableLayoutPanel4 + // + this.tableLayoutPanel4.AutoSize = true; + this.tableLayoutPanel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel4.ColumnCount = 2; + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + 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, 200); + this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel4.Name = "tableLayoutPanel4"; + this.tableLayoutPanel4.RowCount = 1; + this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 32); + this.tableLayoutPanel4.TabIndex = 8; + // // ConfigForm // this.AcceptButton = this.OKButton; this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); 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(489, 287); - this.Controls.Add(this.ServersListBox); - this.Controls.Add(this.ServerGroupBox); - this.Controls.Add(this.panel1); - this.Controls.Add(this.panel3); + this.ClientSize = new System.Drawing.Size(574, 367); + this.Controls.Add(this.tableLayoutPanel2); this.Controls.Add(this.panel2); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ConfigForm"; + this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Edit Servers"; this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); @@ -335,10 +384,12 @@ this.Shown += new System.EventHandler(this.ConfigForm_Shown); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); - this.panel1.ResumeLayout(false); - this.panel3.ResumeLayout(false); this.ServerGroupBox.ResumeLayout(false); this.ServerGroupBox.PerformLayout(); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + this.tableLayoutPanel3.ResumeLayout(false); + this.tableLayoutPanel4.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -360,14 +411,15 @@ private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Button OKButton; private System.Windows.Forms.Button MyCancelButton; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.Panel panel3; private System.Windows.Forms.Button DeleteButton; private System.Windows.Forms.Button AddButton; private System.Windows.Forms.GroupBox ServerGroupBox; private System.Windows.Forms.ListBox ServersListBox; private System.Windows.Forms.TextBox RemarksTextBox; private System.Windows.Forms.Label RemarksLabel; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 489b7d2d..3fb8b04a 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -24,6 +24,11 @@ namespace Shadowsocks.View { this.Font = System.Drawing.SystemFonts.DialogFont; InitializeComponent(); + + // a dirty hack + this.ServersListBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.PerformLayout(); + UpdateTexts(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); From bcdbcae3058938a8b7d34a2051e0a5e42ced19b3 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 20:10:11 +0800 Subject: [PATCH 34/39] don't serialize FriendlyName --- shadowsocks-csharp/Model/Server.cs | 11 ++++------- shadowsocks-csharp/View/ConfigForm.cs | 2 +- shadowsocks-csharp/View/MenuViewController.cs | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index a8d03dda..6fcc80c1 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -18,16 +18,13 @@ namespace Shadowsocks.Model public string method; public string remarks; - public string FriendlyName + public string FriendlyName() { - get + if (string.IsNullOrEmpty(server)) { - if (string.IsNullOrEmpty(server)) - { - return I18N.GetString("New server"); - } - return string.IsNullOrEmpty(remarks) ? server + ":" + server_port : server + ":" + server_port + " (" + remarks + ")"; + return I18N.GetString("New server"); } + return string.IsNullOrEmpty(remarks) ? server + ":" + server_port : server + ":" + server_port + " (" + remarks + ")"; } } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 3fb8b04a..6693d552 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -125,7 +125,7 @@ namespace Shadowsocks.View ServersListBox.Items.Clear(); foreach (Server server in _modifiedConfiguration.configs) { - ServersListBox.Items.Add(server.FriendlyName); + ServersListBox.Items.Add(server.FriendlyName()); } } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 7ffe071c..250c220c 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -117,7 +117,7 @@ namespace Shadowsocks.View } _notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); - _notifyIcon.Text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("Enabled") : I18N.GetString("Disabled")) + "\n" + controller.GetCurrentServer().FriendlyName; + _notifyIcon.Text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("Enabled") : I18N.GetString("Disabled")) + "\n" + controller.GetCurrentServer().FriendlyName(); } private void LoadMenu() @@ -328,7 +328,7 @@ namespace Shadowsocks.View for (int i = 0; i < configuration.configs.Count; i++) { Server server = configuration.configs[i]; - MenuItem item = new MenuItem(server.FriendlyName); + MenuItem item = new MenuItem(server.FriendlyName()); item.Tag = i; item.Click += AServerItem_Click; items.Add(item); From f339acf3803257cc82efdf4b995e4b84ad3ab076 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 20:28:07 +0800 Subject: [PATCH 35/39] fix qrcode on high dpi --- shadowsocks-csharp/View/QRCodeForm.Designer.cs | 33 ++++++++------------------ 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/shadowsocks-csharp/View/QRCodeForm.Designer.cs b/shadowsocks-csharp/View/QRCodeForm.Designer.cs index 5bebca56..89a07907 100755 --- a/shadowsocks-csharp/View/QRCodeForm.Designer.cs +++ b/shadowsocks-csharp/View/QRCodeForm.Designer.cs @@ -29,49 +29,37 @@ private void InitializeComponent() { this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.panel1 = new System.Windows.Forms.Panel(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.panel1.SuspendLayout(); this.SuspendLayout(); // // pictureBox1 // - this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.pictureBox1.Location = new System.Drawing.Point(10, 10); + this.pictureBox1.Location = new System.Drawing.Point(9, 9); this.pictureBox1.Margin = new System.Windows.Forms.Padding(0); this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(204, 202); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pictureBox1.Size = new System.Drawing.Size(210, 210); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.pictureBox1.TabIndex = 1; this.pictureBox1.TabStop = false; // - // panel1 - // - this.panel1.Controls.Add(this.pictureBox1); - this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.panel1.Location = new System.Drawing.Point(0, 0); - this.panel1.Margin = new System.Windows.Forms.Padding(0); - this.panel1.Name = "panel1"; - this.panel1.Padding = new System.Windows.Forms.Padding(10); - this.panel1.Size = new System.Drawing.Size(224, 222); - this.panel1.TabIndex = 2; - // // QRCodeForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.AutoSize = true; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(224, 222); - this.Controls.Add(this.panel1); + this.ClientSize = new System.Drawing.Size(338, 274); + this.Controls.Add(this.pictureBox1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "QRCodeForm"; + this.Padding = new System.Windows.Forms.Padding(9); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "QRCode"; this.Load += new System.EventHandler(this.QRCodeForm_Load); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.panel1.ResumeLayout(false); this.ResumeLayout(false); } @@ -79,6 +67,5 @@ #endregion private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.Panel panel1; } } \ No newline at end of file From b2c01254bcead1a9bf6edc6b141b5c40014de9f6 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 20:35:46 +0800 Subject: [PATCH 36/39] fix font on Windows 8 --- shadowsocks-csharp/View/ConfigForm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 6693d552..ecc9bf1f 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -22,7 +22,7 @@ namespace Shadowsocks.View public ConfigForm(ShadowsocksController controller) { - this.Font = System.Drawing.SystemFonts.DialogFont; + this.Font = System.Drawing.SystemFonts.MessageBoxFont; InitializeComponent(); // a dirty hack From 8c59f4eea0c3099226b3bc985770c1052bb3ff29 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sat, 20 Dec 2014 20:59:08 +0800 Subject: [PATCH 37/39] update CHANGES --- CHANGES | 7 +++++++ shadowsocks-csharp/shadowsocks-csharp.csproj | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 5a31eddb..c234343b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +2.1.3 2014-12-20 +- Add Chinese Language +- Fix some UI issues on Windows 8 +- Fix some UI issues on high DPI screens +- Log bind error more friendly +- Stability issues + 2.1.2 2014-12-14 - Fix sometimes Shadowsocks doesn't respond to requests diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 1444ca66..0516153d 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -10,7 +10,7 @@ Properties Shadowsocks Shadowsocks - v2.0 + v4.0 512 @@ -21,8 +21,7 @@ 3.5 - - + Client publish\ true Disk From 5d194b42bc0891d7840df94c47adb7c8a3b1ba43 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 21 Dec 2014 15:52:30 +0800 Subject: [PATCH 38/39] fix #89 --- shadowsocks-csharp/Model/Server.cs | 9 ++++++++- shadowsocks-csharp/View/ConfigForm.Designer.cs | 5 +++++ shadowsocks-csharp/View/MenuViewController.cs | 3 ++- shadowsocks-csharp/shadowsocks-csharp.csproj | 5 +++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index 6fcc80c1..382efcbe 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -24,7 +24,14 @@ namespace Shadowsocks.Model { return I18N.GetString("New server"); } - return string.IsNullOrEmpty(remarks) ? server + ":" + server_port : server + ":" + server_port + " (" + remarks + ")"; + if (string.IsNullOrEmpty(remarks)) + { + return server + ":" + server_port; + } + else + { + return remarks + " (" + server + ":" + server_port + ")"; + } } } } diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 6035ae4a..57e1441b 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -95,6 +95,7 @@ // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.RemarksTextBox.Location = new System.Drawing.Point(72, 137); + this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); this.RemarksTextBox.TabIndex = 10; @@ -134,6 +135,7 @@ // this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.ProxyPortTextBox.Location = new System.Drawing.Point(72, 111); + this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); this.ProxyPortTextBox.TabIndex = 4; @@ -163,6 +165,7 @@ // this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.IPTextBox.Location = new System.Drawing.Point(72, 6); + this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; this.IPTextBox.Size = new System.Drawing.Size(160, 20); this.IPTextBox.TabIndex = 0; @@ -172,6 +175,7 @@ // this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.ServerPortTextBox.Location = new System.Drawing.Point(72, 32); + this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); this.ServerPortTextBox.TabIndex = 1; @@ -181,6 +185,7 @@ // this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.PasswordTextBox.Location = new System.Drawing.Point(72, 58); + this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; this.PasswordTextBox.PasswordChar = '*'; this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 250c220c..2bcf4cd4 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -117,7 +117,8 @@ namespace Shadowsocks.View } _notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); - _notifyIcon.Text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("Enabled") : I18N.GetString("Disabled")) + "\n" + controller.GetCurrentServer().FriendlyName(); + string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("Enabled") : I18N.GetString("Disabled")) + "\n" + controller.GetCurrentServer().FriendlyName(); + _notifyIcon.Text = text.Substring(0, Math.Min(63, text.Length)); } private void LoadMenu() diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 0516153d..1444ca66 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -10,7 +10,7 @@ Properties Shadowsocks Shadowsocks - v4.0 + v2.0 512 @@ -21,7 +21,8 @@ 3.5 - Client + + publish\ true Disk From e4e56f8f26ff20c83b311963c56af9dfe8c005ba Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 21 Dec 2014 15:55:47 +0800 Subject: [PATCH 39/39] update changes --- CHANGES | 3 +++ shadowsocks-csharp/Controller/UpdateChecker.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c234343b..444638d9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2.1.4 2014-12-20 +- Fix crash when remarks are too long + 2.1.3 2014-12-20 - Add Chinese Language - Fix some UI issues on Windows 8 diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index 43a1af07..ebf6e3b1 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -17,7 +17,7 @@ namespace Shadowsocks.Controller public string LatestVersionURL; public event EventHandler NewVersionFound; - public const string Version = "2.1.3"; + public const string Version = "2.1.4"; public void CheckUpdate() {