From 0a71dc6f0047379739b862bc3814ae4876718c46 Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 12:19:03 +0800 Subject: [PATCH 01/24] - better FileStream handling - restore WPAD --- shadowsocks-csharp/Controller/FileManager.cs | 18 +++--- .../Controller/System/SystemProxy.cs | 67 +++++++++++++--------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/shadowsocks-csharp/Controller/FileManager.cs b/shadowsocks-csharp/Controller/FileManager.cs index f6edf147..60dc66e4 100755 --- a/shadowsocks-csharp/Controller/FileManager.cs +++ b/shadowsocks-csharp/Controller/FileManager.cs @@ -10,37 +10,35 @@ namespace Shadowsocks.Controller { try { - FileStream _FileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); - _FileStream.Write(content, 0, content.Length); - _FileStream.Close(); + using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) + fs.Write(content, 0, content.Length); return true; } - catch (Exception _Exception) + catch (Exception ex) { Console.WriteLine("Exception caught in process: {0}", - _Exception.ToString()); + ex.ToString()); } return false; } public static void UncompressFile(string fileName, byte[] content) { - FileStream destinationFile = File.Create(fileName); - // Because the uncompressed size of the file is unknown, // we are using an arbitrary buffer size. byte[] buffer = new byte[4096]; int n; - using (GZipStream input = new GZipStream(new MemoryStream(content), + using(var fs = File.Create(fileName)) + using (var input = new GZipStream( + new MemoryStream(content), CompressionMode.Decompress, false)) { while ((n = input.Read(buffer, 0, buffer.Length)) > 0) { - destinationFile.Write(buffer, 0, n); + fs.Write(buffer, 0, n); } } - destinationFile.Close(); } } diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index 74e4beb4..655bffd0 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -9,7 +9,7 @@ using Shadowsocks.Model; namespace Shadowsocks.Controller { - public class SystemProxy + public static class SystemProxy { [DllImport("wininet.dll")] @@ -26,19 +26,29 @@ namespace Shadowsocks.Controller _refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); } + private static readonly DateTime UnixEpoch + = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + public static long ToUnixEpochMilliseconds(this DateTime dt) + => (long)(dt - UnixEpoch).TotalMilliseconds; + private static string GetTimestamp(DateTime value) + { + return value.ToString("yyyyMMddHHmmssfff"); + } + public static void Update(Configuration config, bool forceDisable) { bool global = config.global; bool enabled = config.enabled; + if (forceDisable) { enabled = false; } + try { - RegistryKey registry = - Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", - true); + var registry = Registry.CurrentUser + .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true); if (enabled) { if (global) @@ -53,7 +63,7 @@ namespace Shadowsocks.Controller if (config.useOnlinePac && !string.IsNullOrEmpty(config.pacUrl)) pacUrl = config.pacUrl; else - pacUrl = "http://127.0.0.1:" + config.localPort.ToString() + "/pac?t=" + GetTimestamp(DateTime.Now); + pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}"; registry.SetValue("ProxyEnable", 0); var readProxyServer = registry.GetValue("ProxyServer"); registry.SetValue("ProxyServer", ""); @@ -66,9 +76,11 @@ namespace Shadowsocks.Controller registry.SetValue("ProxyServer", ""); registry.SetValue("AutoConfigURL", ""); } - //Set AutoDetectProxy Off - IEAutoDetectProxy(false); - SystemProxy.NotifyIE(); + + //Set AutoDetectProxy + IEAutoDetectProxy(!enabled); + + NotifyIE(); //Must Notify IE first, or the connections do not chanage CopyProxySettingFromLan(); } @@ -82,14 +94,13 @@ namespace Shadowsocks.Controller private static void CopyProxySettingFromLan() { - RegistryKey registry = - Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", - true); + var registry = Registry.CurrentUser + .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", true); var defaultValue = registry.GetValue("DefaultConnectionSettings"); try { var connections = registry.GetValueNames(); - foreach (String each in connections) + foreach (var each in connections) { if (!(each.Equals("DefaultConnectionSettings") || each.Equals("LAN Connection") @@ -99,38 +110,38 @@ namespace Shadowsocks.Controller registry.SetValue(each, defaultValue); } } - SystemProxy.NotifyIE(); - } catch (IOException e) { + NotifyIE(); + } + catch (IOException e) + { Logging.LogUsefulException(e); } } - private static String GetTimestamp(DateTime value) - { - return value.ToString("yyyyMMddHHmmssffff"); - } - /// /// Checks or unchecks the IE Options Connection setting of "Automatically detect Proxy" /// /// Provide 'true' if you want to check the 'Automatically detect Proxy' check box. To uncheck, pass 'false' private static void IEAutoDetectProxy(bool set) { - RegistryKey registry = - Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", - true); - byte[] defConnection = (byte[])registry.GetValue("DefaultConnectionSettings"); - byte[] savedLegacySetting = (byte[])registry.GetValue("SavedLegacySettings"); + var registry = Registry.CurrentUser + .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", true); + var defConnection = (byte[])registry.GetValue("DefaultConnectionSettings"); + var savedLegacySetting = (byte[])registry.GetValue("SavedLegacySettings"); + if (set) { - defConnection[8] = Convert.ToByte(defConnection[8] & 8); - savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & 8); + defConnection[8] = (byte)(defConnection[8] | 8); + savedLegacySetting[8] = (byte)(savedLegacySetting[8] | 8); } else { - defConnection[8] = Convert.ToByte(defConnection[8] & ~8); - savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & ~8); + defConnection[8] = (byte)(defConnection[8] & ~8); + savedLegacySetting[8] = (byte)(savedLegacySetting[8] & ~8); } + BitConverter.GetBytes(unchecked(BitConverter.ToUInt32(defConnection, 4) + 1)).CopyTo(defConnection, 4); + BitConverter.GetBytes(unchecked(BitConverter.ToUInt32(savedLegacySetting, 4) + 1)).CopyTo(savedLegacySetting, 4); + registry.SetValue("DefaultConnectionSettings", defConnection); registry.SetValue("SavedLegacySettings", savedLegacySetting); } From 88e4d2e3178a104ab5d21a98076a8a6574b1f16b Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 12:27:13 +0800 Subject: [PATCH 02/24] . --- shadowsocks-csharp/Controller/System/SystemProxy.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index 655bffd0..c7ed0d28 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -129,18 +129,26 @@ namespace Shadowsocks.Controller var defConnection = (byte[])registry.GetValue("DefaultConnectionSettings"); var savedLegacySetting = (byte[])registry.GetValue("SavedLegacySettings"); + const int versionOffset = 4; + const int optionsOffset = 8; + if (set) { - defConnection[8] = (byte)(defConnection[8] | 8); - savedLegacySetting[8] = (byte)(savedLegacySetting[8] | 8); + defConnection[optionsOffset] = (byte)(defConnection[optionsOffset] | 8); + savedLegacySetting[optionsOffset] = (byte)(savedLegacySetting[optionsOffset] | 8); } else { - defConnection[8] = (byte)(defConnection[8] & ~8); - savedLegacySetting[8] = (byte)(savedLegacySetting[8] & ~8); + defConnection[optionsOffset] = (byte)(defConnection[optionsOffset] & ~8); + savedLegacySetting[optionsOffset] = (byte)(savedLegacySetting[optionsOffset] & ~8); } - BitConverter.GetBytes(unchecked(BitConverter.ToUInt32(defConnection, 4) + 1)).CopyTo(defConnection, 4); - BitConverter.GetBytes(unchecked(BitConverter.ToUInt32(savedLegacySetting, 4) + 1)).CopyTo(savedLegacySetting, 4); + + BitConverter.GetBytes( + unchecked(BitConverter.ToUInt32(defConnection, versionOffset) + 1)) + .CopyTo(defConnection, versionOffset); + BitConverter.GetBytes( + unchecked(BitConverter.ToUInt32(savedLegacySetting, versionOffset) + 1)) + .CopyTo(savedLegacySetting, versionOffset); registry.SetValue("DefaultConnectionSettings", defConnection); registry.SetValue("SavedLegacySettings", savedLegacySetting); From 2c90e0fcb14a92cf91b13546f21729e8e3c00f64 Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 12:35:57 +0800 Subject: [PATCH 03/24] code style --- shadowsocks-csharp/Controller/System/SystemProxy.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index c7ed0d28..29560ff4 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -102,12 +102,16 @@ namespace Shadowsocks.Controller var connections = registry.GetValueNames(); foreach (var each in connections) { - if (!(each.Equals("DefaultConnectionSettings") - || each.Equals("LAN Connection") - || each.Equals("SavedLegacySettings"))) + switch (each) { - //set all the connections's proxy as the lan - registry.SetValue(each, defaultValue); + case "DefaultConnectionSettings": + case "LAN Connection": + case "SavedLegacySettings": + continue; + default: + //set all the connections's proxy as the lan + registry.SetValue(each, defaultValue); + continue; } } NotifyIE(); From 24609bf53b6122657afad6f8a231765b3f95f3aa Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 12:46:41 +0800 Subject: [PATCH 04/24] never use string.Equals(string) if you don't know what you are doing --- shadowsocks-csharp/Controller/System/AutoStartup.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shadowsocks-csharp/Controller/System/AutoStartup.cs b/shadowsocks-csharp/Controller/System/AutoStartup.cs index a2ad21c1..06180bdb 100644 --- a/shadowsocks-csharp/Controller/System/AutoStartup.cs +++ b/shadowsocks-csharp/Controller/System/AutoStartup.cs @@ -1,5 +1,5 @@ -using System; -using System.Windows.Forms; +using System; +using System.Windows.Forms; using Microsoft.Win32; namespace Shadowsocks.Controller @@ -14,7 +14,7 @@ namespace Shadowsocks.Controller try { string path = Application.ExecutablePath; - runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + runKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); if (enabled) { runKey.SetValue(Key, path); @@ -47,13 +47,13 @@ namespace Shadowsocks.Controller try { string path = Application.ExecutablePath; - runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + runKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); string[] runList = runKey.GetValueNames(); foreach (string item in runList) { - if (item.Equals(Key)) + if (item == Key) return true; - else if (item.Equals("Shadowsocks")) // Compatibility with older versions + else if (item == "Shadowsocks") // Compatibility with older versions { string value = Convert.ToString(runKey.GetValue(item)); if (path.Equals(value, StringComparison.InvariantCultureIgnoreCase)) @@ -82,4 +82,4 @@ namespace Shadowsocks.Controller } } } -} +} From b08e24c49fb26d353c1a8b31ad8674952d79a0da Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 12:51:27 +0800 Subject: [PATCH 05/24] equality operators are always prefered in C# since the default object.Equals(object) does nothing more than object.ReferenceEquals(object) --- shadowsocks-csharp/3rd/zxing/common/reedsolomon/GenericGFPoly.cs | 6 +++--- shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/3rd/zxing/common/reedsolomon/GenericGFPoly.cs b/shadowsocks-csharp/3rd/zxing/common/reedsolomon/GenericGFPoly.cs index 427fe11d..96df3e69 100755 --- a/shadowsocks-csharp/3rd/zxing/common/reedsolomon/GenericGFPoly.cs +++ b/shadowsocks-csharp/3rd/zxing/common/reedsolomon/GenericGFPoly.cs @@ -145,7 +145,7 @@ namespace ZXing.Common.ReedSolomon internal GenericGFPoly addOrSubtract(GenericGFPoly other) { - if (!field.Equals(other.field)) + if (field != other.field) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } @@ -181,7 +181,7 @@ namespace ZXing.Common.ReedSolomon internal GenericGFPoly multiply(GenericGFPoly other) { - if (!field.Equals(other.field)) + if (field != other.field) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } @@ -246,7 +246,7 @@ namespace ZXing.Common.ReedSolomon internal GenericGFPoly[] divide(GenericGFPoly other) { - if (!field.Equals(other.field)) + if (field != other.field) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } diff --git a/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs b/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs index 56c9a9a8..0af5537f 100755 --- a/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs +++ b/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs @@ -514,7 +514,8 @@ namespace ZXing.QrCode.Internal BitArray bits, String encoding) { - if (mode.Equals(Mode.BYTE)) + // TODO: check the purpose of this .Equals(obj) + if (mode == Mode.BYTE) append8BitBytes(content, bits, encoding); else throw new WriterException("Invalid mode: " + mode); From 6c28613c7e1e7e36506ebdf862d943a09aefdef0 Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 14:17:07 +0800 Subject: [PATCH 06/24] fix case-insensitive string comparison --- shadowsocks-csharp/3rd/zxing/common/StringUtils.cs | 16 ++++++++-------- shadowsocks-csharp/FodyWeavers.xml | 4 ++-- shadowsocks-csharp/packages.config | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/shadowsocks-csharp/3rd/zxing/common/StringUtils.cs b/shadowsocks-csharp/3rd/zxing/common/StringUtils.cs index 55b5ec91..f15fd8e6 100755 --- a/shadowsocks-csharp/3rd/zxing/common/StringUtils.cs +++ b/shadowsocks-csharp/3rd/zxing/common/StringUtils.cs @@ -30,16 +30,16 @@ namespace ZXing.Common #if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || WINDOWS_PHONE80 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE) private const String PLATFORM_DEFAULT_ENCODING = "UTF-8"; #else - private static String PLATFORM_DEFAULT_ENCODING = Encoding.Default.WebName; + private static string PLATFORM_DEFAULT_ENCODING = Encoding.Default.WebName; #endif - public static String SHIFT_JIS = "SJIS"; - public static String GB2312 = "GB2312"; - private const String EUC_JP = "EUC-JP"; - private const String UTF8 = "UTF-8"; - private const String ISO88591 = "ISO-8859-1"; + public static string SHIFT_JIS = "SJIS"; + public static string GB2312 = "GB2312"; + private const string EUC_JP = "EUC-JP"; + private const string UTF8 = "UTF-8"; + private const string ISO88591 = "ISO-8859-1"; private static readonly bool ASSUME_SHIFT_JIS = - String.Compare(SHIFT_JIS, PLATFORM_DEFAULT_ENCODING, StringComparison.OrdinalIgnoreCase) == 0 || - String.Compare(EUC_JP, PLATFORM_DEFAULT_ENCODING, StringComparison.OrdinalIgnoreCase) == 0; + string.Equals(SHIFT_JIS, PLATFORM_DEFAULT_ENCODING, StringComparison.OrdinalIgnoreCase) || + string.Equals(EUC_JP, PLATFORM_DEFAULT_ENCODING, StringComparison.OrdinalIgnoreCase); /// /// Guesses the encoding. diff --git a/shadowsocks-csharp/FodyWeavers.xml b/shadowsocks-csharp/FodyWeavers.xml index 2e6d4a7a..6e33a3fc 100644 --- a/shadowsocks-csharp/FodyWeavers.xml +++ b/shadowsocks-csharp/FodyWeavers.xml @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index 2230519e..c0fab934 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -1,5 +1,6 @@  + From 1287eb0fa78915986f44fff52f7131a2e0da86f9 Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 17:27:45 +0800 Subject: [PATCH 07/24] fix default string comparison --- shadowsocks-csharp/FodyWeavers.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/FodyWeavers.xml b/shadowsocks-csharp/FodyWeavers.xml index 6e33a3fc..17e88514 100644 --- a/shadowsocks-csharp/FodyWeavers.xml +++ b/shadowsocks-csharp/FodyWeavers.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file From 413803c56ff0ba93a4d2e610252f75bd2f51b9c4 Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 17:29:25 +0800 Subject: [PATCH 08/24] fix case-insensitive behavior --- .../3rd/zxing/qrcode/encoder/Encoder.cs | 2 +- shadowsocks-csharp/Controller/I18N.cs | 30 ++++++++++++---------- .../Controller/System/AutoStartup.cs | 8 +++--- .../Controller/System/SystemProxy.cs | 8 +++--- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs b/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs index 0af5537f..dbae7bf3 100755 --- a/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs +++ b/shadowsocks-csharp/3rd/zxing/qrcode/encoder/Encoder.cs @@ -86,7 +86,7 @@ namespace ZXing.QrCode.Internal { encoding = DEFAULT_BYTE_MODE_ENCODING; } - bool generateECI = !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding); + bool generateECI = !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding, StringComparison.OrdinalIgnoreCase); #else // Silverlight supports only UTF-8 and UTF-16 out-of-the-box const string encoding = "UTF-8"; diff --git a/shadowsocks-csharp/Controller/I18N.cs b/shadowsocks-csharp/Controller/I18N.cs index c99d0f14..af49e36c 100755 --- a/shadowsocks-csharp/Controller/I18N.cs +++ b/shadowsocks-csharp/Controller/I18N.cs @@ -1,11 +1,12 @@ -using Shadowsocks.Properties; -using System; +using System; using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; +using System.Globalization; +using System.IO; namespace Shadowsocks.Controller { + using Shadowsocks.Properties; + public class I18N { protected static Dictionary Strings; @@ -13,19 +14,20 @@ namespace Shadowsocks.Controller { Strings = new Dictionary(); - if (System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag.ToLowerInvariant().StartsWith("zh")) + if (CultureInfo.CurrentCulture.IetfLanguageTag.StartsWith("zh", StringComparison.OrdinalIgnoreCase)) { - string[] lines = Regex.Split(Resources.cn, "\r\n|\r|\n"); - foreach (string line in lines) + using (var sr = new StringReader(Resources.cn)) { - if (line.StartsWith("#")) - { - continue; - } - string[] kv = Regex.Split(line, "="); - if (kv.Length == 2) + string line; + while ((line = sr.ReadLine()) != null) { - Strings[kv[0]] = kv[1]; + if (line[0] == '#') + continue; + + var pos = line.IndexOf('='); + if (pos < 1) + continue; + Strings[line.Substring(0, pos)] = line.Substring(pos + 1); } } } diff --git a/shadowsocks-csharp/Controller/System/AutoStartup.cs b/shadowsocks-csharp/Controller/System/AutoStartup.cs index 06180bdb..353056eb 100644 --- a/shadowsocks-csharp/Controller/System/AutoStartup.cs +++ b/shadowsocks-csharp/Controller/System/AutoStartup.cs @@ -51,12 +51,12 @@ namespace Shadowsocks.Controller string[] runList = runKey.GetValueNames(); foreach (string item in runList) { - if (item == Key) + if (item.Equals(Key, StringComparison.OrdinalIgnoreCase)) return true; - else if (item == "Shadowsocks") // Compatibility with older versions + else if (item.Equals("Shadowsocks", StringComparison.OrdinalIgnoreCase)) // Compatibility with older versions { string value = Convert.ToString(runKey.GetValue(item)); - if (path.Equals(value, StringComparison.InvariantCultureIgnoreCase)) + if (path.Equals(value, StringComparison.OrdinalIgnoreCase)) { runKey.DeleteValue(item); runKey.SetValue(Key, path); @@ -76,7 +76,7 @@ namespace Shadowsocks.Controller if (runKey != null) { try { runKey.Close(); } - catch(Exception e) + catch (Exception e) { Logging.LogUsefulException(e); } } } diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index 29560ff4..c13c2f10 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -102,11 +102,11 @@ namespace Shadowsocks.Controller var connections = registry.GetValueNames(); foreach (var each in connections) { - switch (each) + switch (each.ToUpperInvariant()) { - case "DefaultConnectionSettings": - case "LAN Connection": - case "SavedLegacySettings": + case "DEFAULTCONNECTIONSETTINGS": + case "LAN CONNECTION": + case "SAVEDLEGACYSETTINGS": continue; default: //set all the connections's proxy as the lan From 859474b5775d3881249fb93d26920813ba208b6e Mon Sep 17 00:00:00 2001 From: Licshee Date: Thu, 4 Feb 2016 17:30:04 +0800 Subject: [PATCH 09/24] misc improve --- .../Controller/Service/GfwListUpdater.cs | 4 ++-- shadowsocks-csharp/Controller/ShadowsocksController.cs | 2 +- .../Controller/Strategy/StatisticsStrategy.cs | 18 +++++++++--------- .../View/StatisticsStrategyConfigurationForm.cs | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index 2497090d..42dc70ca 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -42,7 +42,7 @@ namespace Shadowsocks.Controller string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string rule in rules) { - if (rule.StartsWith("!") || rule.StartsWith("[")) + if (rule[0] == '!' || rule[0] == '[') continue; lines.Add(rule); } @@ -97,7 +97,7 @@ namespace Shadowsocks.Controller List valid_lines = new List(lines.Length); foreach (string line in lines) { - if (line.StartsWith("!") || line.StartsWith("[")) + if (line[0] == '!' || line[0] == '[') continue; valid_lines.Add(line); } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index f7d50bd3..0950c2d9 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -457,7 +457,7 @@ namespace Shadowsocks.Controller string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string rule in rules) { - if (rule.StartsWith("!") || rule.StartsWith("[")) + if (rule[0] == '!' || rule[0] == '[') continue; lines.Add(rule); } diff --git a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs index df34c994..70da0ac8 100644 --- a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs +++ b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs @@ -18,7 +18,7 @@ namespace Shadowsocks.Controller.Strategy private readonly Timer _timer; private Dictionary> _filteredStatistics; private int ChoiceKeptMilliseconds - => (int) TimeSpan.FromMinutes(_controller.StatisticsConfiguration.ChoiceKeptMinutes).TotalMilliseconds; + => (int)TimeSpan.FromMinutes(_controller.StatisticsConfiguration.ChoiceKeptMinutes).TotalMilliseconds; public StatisticsStrategy(ShadowsocksController controller) { @@ -49,11 +49,11 @@ namespace Shadowsocks.Controller.Strategy var config = _controller.StatisticsConfiguration; List dataList; if (_filteredStatistics == null || !_filteredStatistics.TryGetValue(serverName, out dataList)) return 0; - var successTimes = (float) dataList.Count(data => data.ICMPStatus.Equals(IPStatus.Success.ToString())); - var timedOutTimes = (float) dataList.Count(data => data.ICMPStatus.Equals(IPStatus.TimedOut.ToString())); + var successTimes = (float)dataList.Count(data => data.ICMPStatus == IPStatus.Success.ToString()); + var timedOutTimes = (float)dataList.Count(data => data.ICMPStatus == IPStatus.TimedOut.ToString()); var statisticsData = new AvailabilityStatistics.StatisticsData { - PackageLoss = timedOutTimes/(successTimes + timedOutTimes)*100, + PackageLoss = timedOutTimes / (successTimes + timedOutTimes) * 100, AverageResponse = Convert.ToInt32(dataList.Average(data => data.RoundtripTime)), MinResponse = dataList.Min(data => data.RoundtripTime), MaxResponse = dataList.Max(data => data.RoundtripTime) @@ -61,13 +61,13 @@ namespace Shadowsocks.Controller.Strategy float factor; float score = 0; if (!config.Calculations.TryGetValue("PackageLoss", out factor)) factor = 0; - score += statisticsData.PackageLoss*factor; + score += statisticsData.PackageLoss * factor; if (!config.Calculations.TryGetValue("AverageResponse", out factor)) factor = 0; - score += statisticsData.AverageResponse*factor; + score += statisticsData.AverageResponse * factor; if (!config.Calculations.TryGetValue("MinResponse", out factor)) factor = 0; - score += statisticsData.MinResponse*factor; + score += statisticsData.MinResponse * factor; if (!config.Calculations.TryGetValue("MaxResponse", out factor)) factor = 0; - score += statisticsData.MaxResponse*factor; + score += statisticsData.MaxResponse * factor; Logging.Debug($"{serverName} {JsonConvert.SerializeObject(statisticsData)}"); return score; } @@ -90,7 +90,7 @@ namespace Shadowsocks.Controller.Strategy } ).Aggregate((result1, result2) => result1.score > result2.score ? result1 : result2); - LogWhenEnabled($"Switch to server: {bestResult.server.FriendlyName()} by statistics: score {bestResult.score}"); + LogWhenEnabled($"Switch to server: {bestResult.server.FriendlyName()} by statistics: score {bestResult.score}"); _currentServer = bestResult.server; } catch (Exception e) diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs index aae33546..02b57cd4 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cs @@ -108,7 +108,7 @@ namespace Shadowsocks.View Timestamp = dataGroup.First().Timestamp, Ping = (int)dataGroup.Average(data => data.RoundtripTime), PackageLoss = (int) - (dataGroup.Count(data => data.ICMPStatus.Equals(IPStatus.TimedOut.ToString())) + (dataGroup.Count(data => data.ICMPStatus == IPStatus.TimedOut.ToString()) / (float)dataGroup.Count() * 100) }; foreach (var data in finalData) From 6a33e24ebc41441800eac7e9ec567b0a7fe4cee4 Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 11:13:17 +0800 Subject: [PATCH 10/24] forgot about empty lines, my bad --- shadowsocks-csharp/Controller/I18N.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/I18N.cs b/shadowsocks-csharp/Controller/I18N.cs index af49e36c..b298ae0c 100755 --- a/shadowsocks-csharp/Controller/I18N.cs +++ b/shadowsocks-csharp/Controller/I18N.cs @@ -21,7 +21,7 @@ namespace Shadowsocks.Controller string line; while ((line = sr.ReadLine()) != null) { - if (line[0] == '#') + if (line == "" || line[0] == '#') continue; var pos = line.IndexOf('='); From 0c7597cdf4383b510321e14506b1d00ea730de2a Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 11:36:40 +0800 Subject: [PATCH 11/24] moar --- .../Controller/Service/GfwListUpdater.cs | 28 +++++++++++++--------- .../Controller/ShadowsocksController.cs | 12 ++++++---- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index 42dc70ca..e89935b2 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -39,12 +39,15 @@ namespace Shadowsocks.Controller if (File.Exists(PACServer.USER_RULE_FILE)) { string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); - string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string rule in rules) + using (var sr = new StringReader(local)) { - if (rule[0] == '!' || rule[0] == '[') - continue; - lines.Add(rule); + string rule; + while ((rule = sr.ReadLine()) != null) + { + if (rule == "" || rule[0] == '!' || rule[0] == '[') + continue; + lines.Add(rule); + } } } string abpContent; @@ -93,13 +96,16 @@ namespace Shadowsocks.Controller { byte[] bytes = Convert.FromBase64String(response); string content = Encoding.ASCII.GetString(bytes); - string[] lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - List valid_lines = new List(lines.Length); - foreach (string line in lines) + List valid_lines = new List(); + using (var sr = new StringReader(content)) { - if (line[0] == '!' || line[0] == '[') - continue; - valid_lines.Add(line); + string line; + while ((line = sr.ReadLine()) != null) + { + if (line == "" || line[0] == '!' || line[0] == '[') + continue; + valid_lines.Add(line); + } } return valid_lines; } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 0950c2d9..51a46ec8 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -455,11 +455,15 @@ namespace Shadowsocks.Controller { string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string rule in rules) + using (var sr = new StringReader(local)) { - if (rule[0] == '!' || rule[0] == '[') - continue; - lines.Add(rule); + string rule; + while ((rule = sr.ReadLine()) != null) + { + if (rule == "" || rule[0] == '!' || rule[0] == '[') + continue; + lines.Add(rule); + } } } string abpContent; From 0e2c28c9b0bacb7600d8930bc891b4db3b1d1140 Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 11:52:07 +0800 Subject: [PATCH 12/24] . --- shadowsocks-csharp/Controller/ShadowsocksController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 51a46ec8..960b8f97 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -454,7 +454,6 @@ namespace Shadowsocks.Controller if (File.Exists(PACServer.USER_RULE_FILE)) { string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); - string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); using (var sr = new StringReader(local)) { string rule; From 687f397ae30b53f84d0ee5b427b44cbe15c14064 Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 12:47:45 +0800 Subject: [PATCH 13/24] using StringEx --- .../Controller/System/SystemProxy.cs | 2 +- shadowsocks-csharp/Encryption/EncryptorFactory.cs | 2 +- shadowsocks-csharp/Model/Configuration.cs | 4 +- shadowsocks-csharp/Model/Server.cs | 4 +- shadowsocks-csharp/StringEx.cs | 196 +++++++++++++++++++++ shadowsocks-csharp/View/MenuViewController.cs | 6 +- shadowsocks-csharp/packages.config | 1 + shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 8 files changed, 207 insertions(+), 9 deletions(-) create mode 100644 shadowsocks-csharp/StringEx.cs diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index c13c2f10..bf77f999 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -60,7 +60,7 @@ namespace Shadowsocks.Controller else { string pacUrl; - if (config.useOnlinePac && !string.IsNullOrEmpty(config.pacUrl)) + if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty()) pacUrl = config.pacUrl; else pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}"; diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index b9cda1a7..41bd5c64 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -25,7 +25,7 @@ namespace Shadowsocks.Encryption public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth, bool isudp) { - if (string.IsNullOrEmpty(method)) + if (method.IsNullOrEmpty()) { method = "aes-256-cfb"; } diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index d65c23a9..10a42124 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -124,13 +124,13 @@ namespace Shadowsocks.Model private static void CheckPassword(string password) { - if (string.IsNullOrEmpty(password)) + if (password.IsNullOrEmpty()) throw new ArgumentException(I18N.GetString("Password can not be blank")); } private static void CheckServer(string server) { - if (string.IsNullOrEmpty(server)) + if (server.IsNullOrEmpty()) 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 8306d9e3..69682302 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -29,11 +29,11 @@ namespace Shadowsocks.Model public string FriendlyName() { - if (string.IsNullOrEmpty(server)) + if (server.IsNullOrEmpty()) { return I18N.GetString("New server"); } - if (string.IsNullOrEmpty(remarks)) + if (remarks.IsNullOrEmpty()) { return server + ":" + server_port; } diff --git a/shadowsocks-csharp/StringEx.cs b/shadowsocks-csharp/StringEx.cs new file mode 100644 index 00000000..e116ed73 --- /dev/null +++ b/shadowsocks-csharp/StringEx.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +static partial class StringEx +{ +#pragma warning disable 1591 + + public static StringComparison GlobalDefaultComparison { get; set; } = StringComparison.Ordinal; + + [ThreadStatic] + private static StringComparison? _DefaultComparison; + public static StringComparison DefaultComparison + { + get { return _DefaultComparison ?? GlobalDefaultComparison; } + set { _DefaultComparison = value; } + } + + #region basic String methods + + public static bool IsNullOrEmpty(this string value) + => string.IsNullOrEmpty(value); + + public static bool IsNullOrWhiteSpace(this string value) + => string.IsNullOrWhiteSpace(value); + +#if !PCL + public static string IsInterned(this string value) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + + return string.IsInterned(value); + } + + public static string Intern(this string value) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + + return string.Intern(value); + } +#endif + + #endregion + + #region comparing + + #region Is + + public static bool Is(this string a, string b) + => string.Equals(a, b, DefaultComparison); + public static bool Is(this string a, string b, StringComparison comparisonType) + => string.Equals(a, b, comparisonType); + + #endregion + + #region BeginWith + + public static bool BeginWith(this string s, char c) + { + if (s.IsNullOrEmpty()) return false; + return s[0] == c; + } + public static bool BeginWithAny(this string s, IEnumerable chars) + { + if (s.IsNullOrEmpty()) return false; + return chars.Contains(s[0]); + } + public static bool BeginWithAny(this string s, params char[] chars) + => s.BeginWithAny(chars.AsEnumerable()); + + public static bool BeginWith(this string a, string b) + { + if (a == null || b == null) return false; + + return a.StartsWith(b, DefaultComparison); + } + public static bool BeginWith(this string a, string b, StringComparison comparisonType) + { + if (a == null || b == null) return false; + + return a.StartsWith(b, comparisonType); + } +#if !PCL + public static bool BeginWith(this string a, string b, bool ignoreCase, CultureInfo culture) + { + if (a == null || b == null) return false; + + return a.StartsWith(b, ignoreCase, culture); + } +#endif + + #endregion + + #region FinishWith + + public static bool FinishWith(this string s, char c) + { + if (s.IsNullOrEmpty()) return false; + return s.Last() == c; + } + public static bool FinishWithAny(this string s, IEnumerable chars) + { + if (s.IsNullOrEmpty()) return false; + return chars.Contains(s.Last()); + } + public static bool FinishWithAny(this string s, params char[] chars) + => s.FinishWithAny(chars.AsEnumerable()); + + public static bool FinishWith(this string a, string b) + { + if (a == null || b == null) return false; + + return a.EndsWith(b, DefaultComparison); + } + public static bool FinishWith(this string a, string b, StringComparison comparisonType) + { + if (a == null || b == null) return false; + + return a.EndsWith(b, comparisonType); + } +#if !PCL + public static bool FinishWith(this string a, string b, bool ignoreCase, CultureInfo culture) + { + if (a == null || b == null) return false; + + return a.EndsWith(b, ignoreCase, culture); + } +#endif + + #endregion + + #endregion + + #region others + + private static readonly char[][] Quotes = new[] + { + "\"\"", + "''", + "“”", + "‘’", + "『』", + "「」", + "〖〗", + "【】", + }.Select(s => s.ToCharArray()).ToArray(); + public static string Enquote(this string value) + { + if (value == null) + return "(null)"; + + foreach (var pair in Quotes) + { + if (value.IndexOfAny(pair) < 0) + return pair[0] + value + pair[1]; + } + + return '"' + value.Replace("\\", @"\\").Replace("\"", @"\""") + '"'; + } + + public static string Replace(this string value, string find, string rep, StringComparison comparsionType) + { + if (find.IsNullOrEmpty()) + throw new ArgumentException(null, nameof(find)); + if (rep == null) + rep = ""; + if (value.IsNullOrEmpty()) + return value; + + var sb = new StringBuilder(value.Length); + + var last = 0; + var len = find.Length; + var idx = value.IndexOf(find, DefaultComparison); + while (idx != -1) + { + sb.Append(value.Substring(last, idx - last)); + sb.Append(rep); + idx += len; + + last = idx; + idx = value.IndexOf(find, idx, comparsionType); + } + sb.Append(value.Substring(last)); + + return sb.ToString(); + } + public static string ReplaceEx(this string value, string find, string rep) + => value.Replace(find, rep, DefaultComparison); + + #endregion +} diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 32eb992d..fc942835 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -630,11 +630,11 @@ namespace Shadowsocks.View { if (!onlinePACItem.Checked) { - if (String.IsNullOrEmpty(controller.GetConfigurationCopy().pacUrl)) + if (controller.GetConfigurationCopy().pacUrl.IsNullOrEmpty()) { UpdateOnlinePACURLItem_Click(sender, e); } - if (!String.IsNullOrEmpty(controller.GetConfigurationCopy().pacUrl)) + if (!controller.GetConfigurationCopy().pacUrl.IsNullOrEmpty()) { localPACItem.Checked = false; onlinePACItem.Checked = true; @@ -651,7 +651,7 @@ namespace Shadowsocks.View I18N.GetString("Please input PAC Url"), I18N.GetString("Edit Online PAC URL"), origPacUrl, -1, -1); - if (!string.IsNullOrEmpty(pacUrl) && pacUrl != origPacUrl) + if (!pacUrl.IsNullOrEmpty() && pacUrl != origPacUrl) { controller.SavePACUrl(pacUrl); } diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index c0fab934..2dfd52b7 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -8,5 +8,6 @@ + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 69f7b546..aee35162 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -204,6 +204,7 @@ + Form From 4a45d60c40b6ea59e13630993c47c55575d59032 Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 12:56:25 +0800 Subject: [PATCH 14/24] more reliable & maintainable extension methods --- shadowsocks-csharp/Controller/I18N.cs | 2 +- shadowsocks-csharp/Controller/Service/GfwListUpdater.cs | 5 +++-- shadowsocks-csharp/Controller/ShadowsocksController.cs | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/Controller/I18N.cs b/shadowsocks-csharp/Controller/I18N.cs index b298ae0c..fcae64da 100755 --- a/shadowsocks-csharp/Controller/I18N.cs +++ b/shadowsocks-csharp/Controller/I18N.cs @@ -21,7 +21,7 @@ namespace Shadowsocks.Controller string line; while ((line = sr.ReadLine()) != null) { - if (line == "" || line[0] == '#') + if (line.BeginWith('#')) continue; var pos = line.IndexOf('='); diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index e89935b2..8098897c 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -30,6 +30,7 @@ namespace Shadowsocks.Controller } } + private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { try @@ -44,7 +45,7 @@ namespace Shadowsocks.Controller string rule; while ((rule = sr.ReadLine()) != null) { - if (rule == "" || rule[0] == '!' || rule[0] == '[') + if (rule.BeginWithAny(IgnoredLineBegins)) continue; lines.Add(rule); } @@ -102,7 +103,7 @@ namespace Shadowsocks.Controller string line; while ((line = sr.ReadLine()) != null) { - if (line == "" || line[0] == '!' || line[0] == '[') + if (line.BeginWithAny(IgnoredLineBegins)) continue; valid_lines.Add(line); } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 960b8f97..d8a76ced 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -442,6 +442,7 @@ namespace Shadowsocks.Controller UpdatePACFromGFWListError(this, e); } + private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; private void pacServer_UserRuleFileChanged(object sender, EventArgs e) { // TODO: this is a dirty hack. (from code GListUpdater.http_DownloadStringCompleted()) @@ -459,7 +460,7 @@ namespace Shadowsocks.Controller string rule; while ((rule = sr.ReadLine()) != null) { - if (rule == "" || rule[0] == '!' || rule[0] == '[') + if (rule.BeginWithAny(IgnoredLineBegins)) continue; lines.Add(rule); } From 281dfe028a5999d0bde8e61a5eeaf4bbea0feede Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 13:40:56 +0800 Subject: [PATCH 15/24] . --- shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs index f6e6831b..3a89ed8b 100644 --- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs +++ b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs @@ -247,7 +247,7 @@ namespace Shadowsocks.Controller { var currentHour = DateTime.Now.Hour; filteredData = filteredData.Where(data => - data.Timestamp != UnknownDateTime && data.Timestamp.Hour.Equals(currentHour) + data.Timestamp != UnknownDateTime && data.Timestamp.Hour == currentHour ); if (filteredData.LongCount() == 0) return; } From df83691e915aa85ded612543fc47988a0ffc6f66 Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 14:32:26 +0800 Subject: [PATCH 16/24] updated Caseless.Fody depencency --- shadowsocks-csharp/packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index c0fab934..4c530282 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -1,6 +1,6 @@  - + From a8ffc60d317889f8e733a64437e807558b06cb0e Mon Sep 17 00:00:00 2001 From: Licshee Date: Sat, 6 Feb 2016 15:03:52 +0800 Subject: [PATCH 17/24] updated StringEx to 0.2, in favor of s.NonWhiteSpaceLines() --- shadowsocks-csharp/Controller/I18N.cs | 5 ++- .../Controller/Service/GfwListUpdater.cs | 6 ++-- .../Controller/ShadowsocksController.cs | 3 +- shadowsocks-csharp/StringEx.cs | 41 ++++++++++++++++++++++ shadowsocks-csharp/packages.config | 2 +- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/shadowsocks-csharp/Controller/I18N.cs b/shadowsocks-csharp/Controller/I18N.cs index fcae64da..85f3ae60 100755 --- a/shadowsocks-csharp/Controller/I18N.cs +++ b/shadowsocks-csharp/Controller/I18N.cs @@ -18,10 +18,9 @@ namespace Shadowsocks.Controller { using (var sr = new StringReader(Resources.cn)) { - string line; - while ((line = sr.ReadLine()) != null) + foreach (var line in sr.NonWhiteSpaceLines()) { - if (line.BeginWith('#')) + if (line[0] == '#') continue; var pos = line.IndexOf('='); diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index 8098897c..3d04fafc 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -42,8 +42,7 @@ namespace Shadowsocks.Controller string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); using (var sr = new StringReader(local)) { - string rule; - while ((rule = sr.ReadLine()) != null) + foreach (var rule in sr.NonWhiteSpaceLines()) { if (rule.BeginWithAny(IgnoredLineBegins)) continue; @@ -100,8 +99,7 @@ namespace Shadowsocks.Controller List valid_lines = new List(); using (var sr = new StringReader(content)) { - string line; - while ((line = sr.ReadLine()) != null) + foreach (var line in sr.NonWhiteSpaceLines()) { if (line.BeginWithAny(IgnoredLineBegins)) continue; diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index d8a76ced..4b86a204 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -457,8 +457,7 @@ namespace Shadowsocks.Controller string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); using (var sr = new StringReader(local)) { - string rule; - while ((rule = sr.ReadLine()) != null) + foreach (var rule in sr.NonWhiteSpaceLines()) { if (rule.BeginWithAny(IgnoredLineBegins)) continue; diff --git a/shadowsocks-csharp/StringEx.cs b/shadowsocks-csharp/StringEx.cs index e116ed73..5f107a50 100644 --- a/shadowsocks-csharp/StringEx.cs +++ b/shadowsocks-csharp/StringEx.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text; @@ -26,6 +27,17 @@ static partial class StringEx public static bool IsNullOrWhiteSpace(this string value) => string.IsNullOrWhiteSpace(value); + public static bool IsWhiteSpace(this string value) + { + foreach(var c in value) + { + if (char.IsWhiteSpace(c)) continue; + + return false; + } + return true; + } + #if !PCL public static string IsInterned(this string value) { @@ -135,6 +147,35 @@ static partial class StringEx #endregion + #region ToLines + + public static IEnumerable ToLines(this TextReader reader) + { + string line; + while ((line = reader.ReadLine()) != null) + yield return line; + } + public static IEnumerable NonEmptyLines(this TextReader reader) + { + string line; + while ((line = reader.ReadLine()) != null) + { + if (line == "") continue; + yield return line; + } + } + public static IEnumerable NonWhiteSpaceLines(this TextReader reader) + { + string line; + while ((line = reader.ReadLine()) != null) + { + if (line.IsWhiteSpace()) continue; + yield return line; + } + } + + #endregion + #region others private static readonly char[][] Quotes = new[] diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index 2dfd52b7..93252521 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -8,6 +8,6 @@ - + \ No newline at end of file From 65998d0cf5b37ef0e18ca855dd50c60204ec9a43 Mon Sep 17 00:00:00 2001 From: Licshee Date: Mon, 8 Feb 2016 18:03:17 +0800 Subject: [PATCH 18/24] supposed to work around a problem between Caseless & Costura --- shadowsocks-csharp/FodyWeavers.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/FodyWeavers.xml b/shadowsocks-csharp/FodyWeavers.xml index 17e88514..5af4424f 100644 --- a/shadowsocks-csharp/FodyWeavers.xml +++ b/shadowsocks-csharp/FodyWeavers.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file From f2f0227a4deddad049bea4b248382bc48197d72c Mon Sep 17 00:00:00 2001 From: Licshee Date: Mon, 8 Feb 2016 18:19:54 +0800 Subject: [PATCH 19/24] PM> Install-CleanReferencesTarget --- shadowsocks-csharp/shadowsocks-csharp.csproj | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index aee35162..d401a59a 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -334,6 +334,43 @@ + + + + + + + + + + + + +(); +var attribute = config.Attribute("ExcludeAssemblies"); +if (attribute != null) + foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty)) + excludedAssemblies.Add(item); +var element = config.Element("ExcludeAssemblies"); +if (element != null) + foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty)) + excludedAssemblies.Add(item); + +var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase)); + +foreach (var item in filesToCleanup) + File.Delete(item); +]]> + + + + +