# Conflicts: # shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs # shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs # shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.cstags/3.0
@@ -30,16 +30,16 @@ namespace ZXing.Common | |||||
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || WINDOWS_PHONE80 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE) | #if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || WINDOWS_PHONE80 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE) | ||||
private const String PLATFORM_DEFAULT_ENCODING = "UTF-8"; | private const String PLATFORM_DEFAULT_ENCODING = "UTF-8"; | ||||
#else | #else | ||||
private static String PLATFORM_DEFAULT_ENCODING = Encoding.Default.WebName; | |||||
private static string PLATFORM_DEFAULT_ENCODING = Encoding.Default.WebName; | |||||
#endif | #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 = | 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); | |||||
/// <summary> | /// <summary> | ||||
/// Guesses the encoding. | /// Guesses the encoding. | ||||
@@ -145,7 +145,7 @@ namespace ZXing.Common.ReedSolomon | |||||
internal GenericGFPoly addOrSubtract(GenericGFPoly other) | internal GenericGFPoly addOrSubtract(GenericGFPoly other) | ||||
{ | { | ||||
if (!field.Equals(other.field)) | |||||
if (field != other.field) | |||||
{ | { | ||||
throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); | throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); | ||||
} | } | ||||
@@ -181,7 +181,7 @@ namespace ZXing.Common.ReedSolomon | |||||
internal GenericGFPoly multiply(GenericGFPoly other) | internal GenericGFPoly multiply(GenericGFPoly other) | ||||
{ | { | ||||
if (!field.Equals(other.field)) | |||||
if (field != other.field) | |||||
{ | { | ||||
throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); | throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); | ||||
} | } | ||||
@@ -246,7 +246,7 @@ namespace ZXing.Common.ReedSolomon | |||||
internal GenericGFPoly[] divide(GenericGFPoly other) | internal GenericGFPoly[] divide(GenericGFPoly other) | ||||
{ | { | ||||
if (!field.Equals(other.field)) | |||||
if (field != other.field) | |||||
{ | { | ||||
throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); | throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); | ||||
} | } | ||||
@@ -86,7 +86,7 @@ namespace ZXing.QrCode.Internal | |||||
{ | { | ||||
encoding = DEFAULT_BYTE_MODE_ENCODING; | encoding = DEFAULT_BYTE_MODE_ENCODING; | ||||
} | } | ||||
bool generateECI = !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding); | |||||
bool generateECI = !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding, StringComparison.OrdinalIgnoreCase); | |||||
#else | #else | ||||
// Silverlight supports only UTF-8 and UTF-16 out-of-the-box | // Silverlight supports only UTF-8 and UTF-16 out-of-the-box | ||||
const string encoding = "UTF-8"; | const string encoding = "UTF-8"; | ||||
@@ -514,7 +514,8 @@ namespace ZXing.QrCode.Internal | |||||
BitArray bits, | BitArray bits, | ||||
String encoding) | String encoding) | ||||
{ | { | ||||
if (mode.Equals(Mode.BYTE)) | |||||
// TODO: check the purpose of this .Equals(obj) | |||||
if (mode == Mode.BYTE) | |||||
append8BitBytes(content, bits, encoding); | append8BitBytes(content, bits, encoding); | ||||
else | else | ||||
throw new WriterException("Invalid mode: " + mode); | throw new WriterException("Invalid mode: " + mode); | ||||
@@ -10,37 +10,35 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
try | 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; | return true; | ||||
} | } | ||||
catch (Exception _Exception) | |||||
catch (Exception ex) | |||||
{ | { | ||||
Console.WriteLine("Exception caught in process: {0}", | Console.WriteLine("Exception caught in process: {0}", | ||||
_Exception.ToString()); | |||||
ex.ToString()); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
public static void UncompressFile(string fileName, byte[] content) | public static void UncompressFile(string fileName, byte[] content) | ||||
{ | { | ||||
FileStream destinationFile = File.Create(fileName); | |||||
// Because the uncompressed size of the file is unknown, | // Because the uncompressed size of the file is unknown, | ||||
// we are using an arbitrary buffer size. | // we are using an arbitrary buffer size. | ||||
byte[] buffer = new byte[4096]; | byte[] buffer = new byte[4096]; | ||||
int n; | 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)) | CompressionMode.Decompress, false)) | ||||
{ | { | ||||
while ((n = input.Read(buffer, 0, buffer.Length)) > 0) | while ((n = input.Read(buffer, 0, buffer.Length)) > 0) | ||||
{ | { | ||||
destinationFile.Write(buffer, 0, n); | |||||
fs.Write(buffer, 0, n); | |||||
} | } | ||||
} | } | ||||
destinationFile.Close(); | |||||
} | } | ||||
} | } | ||||
@@ -1,11 +1,12 @@ | |||||
using Shadowsocks.Properties; | |||||
using System; | |||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | |||||
using System.Text.RegularExpressions; | |||||
using System.Globalization; | |||||
using System.IO; | |||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
{ | { | ||||
using Shadowsocks.Properties; | |||||
public class I18N | public class I18N | ||||
{ | { | ||||
protected static Dictionary<string, string> Strings; | protected static Dictionary<string, string> Strings; | ||||
@@ -13,19 +14,19 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
Strings = new Dictionary<string, string>(); | Strings = new Dictionary<string, string>(); | ||||
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) | |||||
foreach (var line in sr.NonWhiteSpaceLines()) | |||||
{ | { | ||||
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); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -316,4 +316,4 @@ namespace Shadowsocks.Controller | |||||
_speedMonior.Dispose(); | _speedMonior.Dispose(); | ||||
} | } | ||||
} | } | ||||
} | |||||
} |
@@ -30,6 +30,7 @@ namespace Shadowsocks.Controller | |||||
} | } | ||||
} | } | ||||
private static readonly IEnumerable<char> IgnoredLineBegins = new[] { '!', '[' }; | |||||
private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) | ||||
{ | { | ||||
try | try | ||||
@@ -39,12 +40,14 @@ namespace Shadowsocks.Controller | |||||
if (File.Exists(PACServer.USER_RULE_FILE)) | if (File.Exists(PACServer.USER_RULE_FILE)) | ||||
{ | { | ||||
string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); | 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.StartsWith("!") || rule.StartsWith("[")) | |||||
continue; | |||||
lines.Add(rule); | |||||
foreach (var rule in sr.NonWhiteSpaceLines()) | |||||
{ | |||||
if (rule.BeginWithAny(IgnoredLineBegins)) | |||||
continue; | |||||
lines.Add(rule); | |||||
} | |||||
} | } | ||||
} | } | ||||
string abpContent; | string abpContent; | ||||
@@ -93,13 +96,15 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
byte[] bytes = Convert.FromBase64String(response); | byte[] bytes = Convert.FromBase64String(response); | ||||
string content = Encoding.ASCII.GetString(bytes); | string content = Encoding.ASCII.GetString(bytes); | ||||
string[] lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); | |||||
List<string> valid_lines = new List<string>(lines.Length); | |||||
foreach (string line in lines) | |||||
List<string> valid_lines = new List<string>(); | |||||
using (var sr = new StringReader(content)) | |||||
{ | { | ||||
if (line.StartsWith("!") || line.StartsWith("[")) | |||||
continue; | |||||
valid_lines.Add(line); | |||||
foreach (var line in sr.NonWhiteSpaceLines()) | |||||
{ | |||||
if (line.BeginWithAny(IgnoredLineBegins)) | |||||
continue; | |||||
valid_lines.Add(line); | |||||
} | |||||
} | } | ||||
return valid_lines; | return valid_lines; | ||||
} | } | ||||
@@ -438,6 +438,7 @@ namespace Shadowsocks.Controller | |||||
UpdatePACFromGFWListError(this, e); | UpdatePACFromGFWListError(this, e); | ||||
} | } | ||||
private static readonly IEnumerable<char> IgnoredLineBegins = new[] { '!', '[' }; | |||||
private void pacServer_UserRuleFileChanged(object sender, EventArgs e) | private void pacServer_UserRuleFileChanged(object sender, EventArgs e) | ||||
{ | { | ||||
// TODO: this is a dirty hack. (from code GListUpdater.http_DownloadStringCompleted()) | // TODO: this is a dirty hack. (from code GListUpdater.http_DownloadStringCompleted()) | ||||
@@ -450,12 +451,14 @@ namespace Shadowsocks.Controller | |||||
if (File.Exists(PACServer.USER_RULE_FILE)) | if (File.Exists(PACServer.USER_RULE_FILE)) | ||||
{ | { | ||||
string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); | 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.StartsWith("!") || rule.StartsWith("[")) | |||||
continue; | |||||
lines.Add(rule); | |||||
foreach (var rule in sr.NonWhiteSpaceLines()) | |||||
{ | |||||
if (rule.BeginWithAny(IgnoredLineBegins)) | |||||
continue; | |||||
lines.Add(rule); | |||||
} | |||||
} | } | ||||
} | } | ||||
string abpContent; | string abpContent; | ||||
@@ -20,7 +20,7 @@ namespace Shadowsocks.Controller.Strategy | |||||
private Statistics _filteredStatistics; | private Statistics _filteredStatistics; | ||||
private AvailabilityStatistics Service => _controller.availabilityStatistics; | private AvailabilityStatistics Service => _controller.availabilityStatistics; | ||||
private int ChoiceKeptMilliseconds | private int ChoiceKeptMilliseconds | ||||
=> (int) TimeSpan.FromMinutes(_controller.StatisticsConfiguration.ChoiceKeptMinutes).TotalMilliseconds; | |||||
=> (int)TimeSpan.FromMinutes(_controller.StatisticsConfiguration.ChoiceKeptMinutes).TotalMilliseconds; | |||||
public StatisticsStrategy(ShadowsocksController controller) | public StatisticsStrategy(ShadowsocksController controller) | ||||
{ | { | ||||
@@ -93,7 +93,7 @@ namespace Shadowsocks.Controller.Strategy | |||||
} | } | ||||
).Aggregate((result1, result2) => result1.score > result2.score ? result1 : result2); | ).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; | _currentServer = bestResult.server; | ||||
} | } | ||||
catch (Exception e) | catch (Exception e) | ||||
@@ -1,5 +1,5 @@ | |||||
using System; | |||||
using System.Windows.Forms; | |||||
using System; | |||||
using System.Windows.Forms; | |||||
using Microsoft.Win32; | using Microsoft.Win32; | ||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
@@ -14,7 +14,7 @@ namespace Shadowsocks.Controller | |||||
try | try | ||||
{ | { | ||||
string path = Application.ExecutablePath; | 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) | if (enabled) | ||||
{ | { | ||||
runKey.SetValue(Key, path); | runKey.SetValue(Key, path); | ||||
@@ -47,16 +47,16 @@ namespace Shadowsocks.Controller | |||||
try | try | ||||
{ | { | ||||
string path = Application.ExecutablePath; | 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(); | string[] runList = runKey.GetValueNames(); | ||||
foreach (string item in runList) | foreach (string item in runList) | ||||
{ | { | ||||
if (item.Equals(Key)) | |||||
if (item.Equals(Key, StringComparison.OrdinalIgnoreCase)) | |||||
return true; | return true; | ||||
else if (item.Equals("Shadowsocks")) // Compatibility with older versions | |||||
else if (item.Equals("Shadowsocks", StringComparison.OrdinalIgnoreCase)) // Compatibility with older versions | |||||
{ | { | ||||
string value = Convert.ToString(runKey.GetValue(item)); | string value = Convert.ToString(runKey.GetValue(item)); | ||||
if (path.Equals(value, StringComparison.InvariantCultureIgnoreCase)) | |||||
if (path.Equals(value, StringComparison.OrdinalIgnoreCase)) | |||||
{ | { | ||||
runKey.DeleteValue(item); | runKey.DeleteValue(item); | ||||
runKey.SetValue(Key, path); | runKey.SetValue(Key, path); | ||||
@@ -76,10 +76,10 @@ namespace Shadowsocks.Controller | |||||
if (runKey != null) | if (runKey != null) | ||||
{ | { | ||||
try { runKey.Close(); } | try { runKey.Close(); } | ||||
catch(Exception e) | |||||
catch (Exception e) | |||||
{ Logging.LogUsefulException(e); } | { Logging.LogUsefulException(e); } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | |||||
} |
@@ -9,7 +9,7 @@ using Shadowsocks.Model; | |||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
{ | { | ||||
public class SystemProxy | |||||
public static class SystemProxy | |||||
{ | { | ||||
[DllImport("wininet.dll")] | [DllImport("wininet.dll")] | ||||
@@ -26,19 +26,29 @@ namespace Shadowsocks.Controller | |||||
_refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); | _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) | public static void Update(Configuration config, bool forceDisable) | ||||
{ | { | ||||
bool global = config.global; | bool global = config.global; | ||||
bool enabled = config.enabled; | bool enabled = config.enabled; | ||||
if (forceDisable) | if (forceDisable) | ||||
{ | { | ||||
enabled = false; | enabled = false; | ||||
} | } | ||||
try | 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 (enabled) | ||||
{ | { | ||||
if (global) | if (global) | ||||
@@ -50,10 +60,10 @@ namespace Shadowsocks.Controller | |||||
else | else | ||||
{ | { | ||||
string pacUrl; | string pacUrl; | ||||
if (config.useOnlinePac && !string.IsNullOrEmpty(config.pacUrl)) | |||||
if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty()) | |||||
pacUrl = config.pacUrl; | pacUrl = config.pacUrl; | ||||
else | 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); | registry.SetValue("ProxyEnable", 0); | ||||
var readProxyServer = registry.GetValue("ProxyServer"); | var readProxyServer = registry.GetValue("ProxyServer"); | ||||
registry.SetValue("ProxyServer", ""); | registry.SetValue("ProxyServer", ""); | ||||
@@ -66,9 +76,11 @@ namespace Shadowsocks.Controller | |||||
registry.SetValue("ProxyServer", ""); | registry.SetValue("ProxyServer", ""); | ||||
registry.SetValue("AutoConfigURL", ""); | 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 | //Must Notify IE first, or the connections do not chanage | ||||
CopyProxySettingFromLan(); | CopyProxySettingFromLan(); | ||||
} | } | ||||
@@ -82,55 +94,66 @@ namespace Shadowsocks.Controller | |||||
private static void CopyProxySettingFromLan() | 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"); | var defaultValue = registry.GetValue("DefaultConnectionSettings"); | ||||
try | try | ||||
{ | { | ||||
var connections = registry.GetValueNames(); | var connections = registry.GetValueNames(); | ||||
foreach (String each in connections) | |||||
foreach (var each in connections) | |||||
{ | { | ||||
if (!(each.Equals("DefaultConnectionSettings") | |||||
|| each.Equals("LAN Connection") | |||||
|| each.Equals("SavedLegacySettings"))) | |||||
switch (each.ToUpperInvariant()) | |||||
{ | { | ||||
//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; | |||||
} | } | ||||
} | } | ||||
SystemProxy.NotifyIE(); | |||||
} catch (IOException e) { | |||||
NotifyIE(); | |||||
} | |||||
catch (IOException e) | |||||
{ | |||||
Logging.LogUsefulException(e); | Logging.LogUsefulException(e); | ||||
} | } | ||||
} | } | ||||
private static String GetTimestamp(DateTime value) | |||||
{ | |||||
return value.ToString("yyyyMMddHHmmssffff"); | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Checks or unchecks the IE Options Connection setting of "Automatically detect Proxy" | /// Checks or unchecks the IE Options Connection setting of "Automatically detect Proxy" | ||||
/// </summary> | /// </summary> | ||||
/// <param name="set">Provide 'true' if you want to check the 'Automatically detect Proxy' check box. To uncheck, pass 'false'</param> | /// <param name="set">Provide 'true' if you want to check the 'Automatically detect Proxy' check box. To uncheck, pass 'false'</param> | ||||
private static void IEAutoDetectProxy(bool set) | 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"); | |||||
const int versionOffset = 4; | |||||
const int optionsOffset = 8; | |||||
if (set) | if (set) | ||||
{ | { | ||||
defConnection[8] = Convert.ToByte(defConnection[8] & 8); | |||||
savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & 8); | |||||
defConnection[optionsOffset] = (byte)(defConnection[optionsOffset] | 8); | |||||
savedLegacySetting[optionsOffset] = (byte)(savedLegacySetting[optionsOffset] | 8); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
defConnection[8] = Convert.ToByte(defConnection[8] & ~8); | |||||
savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & ~8); | |||||
defConnection[optionsOffset] = (byte)(defConnection[optionsOffset] & ~8); | |||||
savedLegacySetting[optionsOffset] = (byte)(savedLegacySetting[optionsOffset] & ~8); | |||||
} | } | ||||
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("DefaultConnectionSettings", defConnection); | ||||
registry.SetValue("SavedLegacySettings", savedLegacySetting); | registry.SetValue("SavedLegacySettings", savedLegacySetting); | ||||
} | } | ||||
@@ -25,7 +25,7 @@ namespace Shadowsocks.Encryption | |||||
public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth, bool isudp) | public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth, bool isudp) | ||||
{ | { | ||||
if (string.IsNullOrEmpty(method)) | |||||
if (method.IsNullOrEmpty()) | |||||
{ | { | ||||
method = "aes-256-cfb"; | method = "aes-256-cfb"; | ||||
} | } | ||||
@@ -1,5 +1,6 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Concurrent; | |||||
using System.Security.Cryptography; | using System.Security.Cryptography; | ||||
using System.Text; | using System.Text; | ||||
using System.Net; | using System.Net; | ||||
@@ -24,7 +25,7 @@ namespace Shadowsocks.Encryption | |||||
protected Dictionary<string, int[]> ciphers; | protected Dictionary<string, int[]> ciphers; | ||||
private static readonly Dictionary<string, byte[]> CachedKeys = new Dictionary<string, byte[]>(); | |||||
private static readonly ConcurrentDictionary<string, byte[]> CachedKeys = new ConcurrentDictionary<string, byte[]>(); | |||||
protected byte[] _encryptIV; | protected byte[] _encryptIV; | ||||
protected byte[] _decryptIV; | protected byte[] _decryptIV; | ||||
protected bool _decryptIVReceived; | protected bool _decryptIVReceived; | ||||
@@ -62,22 +63,14 @@ namespace Shadowsocks.Encryption | |||||
} | } | ||||
keyLen = ciphers[_method][0]; | keyLen = ciphers[_method][0]; | ||||
ivLen = ciphers[_method][1]; | ivLen = ciphers[_method][1]; | ||||
if (!CachedKeys.ContainsKey(k)) | |||||
_key = CachedKeys.GetOrAdd(k, (nk) => | |||||
{ | { | ||||
lock (CachedKeys) | |||||
{ | |||||
if (!CachedKeys.ContainsKey(k)) | |||||
{ | |||||
byte[] passbuf = Encoding.UTF8.GetBytes(password); | |||||
_key = new byte[32]; | |||||
byte[] iv = new byte[16]; | |||||
bytesToKey(passbuf, _key); | |||||
CachedKeys[k] = _key; | |||||
} | |||||
} | |||||
} | |||||
if (_key == null) | |||||
_key = CachedKeys[k]; | |||||
byte[] passbuf = Encoding.UTF8.GetBytes(password); | |||||
byte[] key = new byte[32]; | |||||
byte[] iv = new byte[16]; | |||||
bytesToKey(passbuf, key); | |||||
return key; | |||||
}); | |||||
} | } | ||||
protected void bytesToKey(byte[] password, byte[] key) | protected void bytesToKey(byte[] password, byte[] key) | ||||
@@ -1,5 +1,5 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<Weavers> | <Weavers> | ||||
<Costura/> | |||||
<Caseless StringComparison="Ordinal"/> | |||||
<Costura/> | |||||
</Weavers> | </Weavers> |
@@ -124,13 +124,13 @@ namespace Shadowsocks.Model | |||||
private static void CheckPassword(string password) | private static void CheckPassword(string password) | ||||
{ | { | ||||
if (string.IsNullOrEmpty(password)) | |||||
if (password.IsNullOrEmpty()) | |||||
throw new ArgumentException(I18N.GetString("Password can not be blank")); | throw new ArgumentException(I18N.GetString("Password can not be blank")); | ||||
} | } | ||||
private static void CheckServer(string server) | private static void CheckServer(string server) | ||||
{ | { | ||||
if (string.IsNullOrEmpty(server)) | |||||
if (server.IsNullOrEmpty()) | |||||
throw new ArgumentException(I18N.GetString("Server IP can not be blank")); | throw new ArgumentException(I18N.GetString("Server IP can not be blank")); | ||||
} | } | ||||
} | } | ||||
@@ -29,11 +29,11 @@ namespace Shadowsocks.Model | |||||
public string FriendlyName() | public string FriendlyName() | ||||
{ | { | ||||
if (string.IsNullOrEmpty(server)) | |||||
if (server.IsNullOrEmpty()) | |||||
{ | { | ||||
return I18N.GetString("New server"); | return I18N.GetString("New server"); | ||||
} | } | ||||
if (string.IsNullOrEmpty(remarks)) | |||||
if (remarks.IsNullOrEmpty()) | |||||
{ | { | ||||
return server + ":" + server_port; | return server + ":" + server_port; | ||||
} | } | ||||
@@ -0,0 +1,237 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Globalization; | |||||
using System.IO; | |||||
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); | |||||
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) | |||||
{ | |||||
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<char> 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<char> 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 ToLines | |||||
public static IEnumerable<string> ToLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
yield return line; | |||||
} | |||||
public static IEnumerable<string> NonEmptyLines(this TextReader reader) | |||||
{ | |||||
string line; | |||||
while ((line = reader.ReadLine()) != null) | |||||
{ | |||||
if (line == "") continue; | |||||
yield return line; | |||||
} | |||||
} | |||||
public static IEnumerable<string> 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[] | |||||
{ | |||||
"\"\"", | |||||
"''", | |||||
"“”", | |||||
"‘’", | |||||
"『』", | |||||
"「」", | |||||
"〖〗", | |||||
"【】", | |||||
}.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 | |||||
} |
@@ -630,11 +630,11 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
if (!onlinePACItem.Checked) | if (!onlinePACItem.Checked) | ||||
{ | { | ||||
if (String.IsNullOrEmpty(controller.GetConfigurationCopy().pacUrl)) | |||||
if (controller.GetConfigurationCopy().pacUrl.IsNullOrEmpty()) | |||||
{ | { | ||||
UpdateOnlinePACURLItem_Click(sender, e); | UpdateOnlinePACURLItem_Click(sender, e); | ||||
} | } | ||||
if (!String.IsNullOrEmpty(controller.GetConfigurationCopy().pacUrl)) | |||||
if (!controller.GetConfigurationCopy().pacUrl.IsNullOrEmpty()) | |||||
{ | { | ||||
localPACItem.Checked = false; | localPACItem.Checked = false; | ||||
onlinePACItem.Checked = true; | onlinePACItem.Checked = true; | ||||
@@ -651,7 +651,7 @@ namespace Shadowsocks.View | |||||
I18N.GetString("Please input PAC Url"), | I18N.GetString("Please input PAC Url"), | ||||
I18N.GetString("Edit Online PAC URL"), | I18N.GetString("Edit Online PAC URL"), | ||||
origPacUrl, -1, -1); | origPacUrl, -1, -1); | ||||
if (!string.IsNullOrEmpty(pacUrl) && pacUrl != origPacUrl) | |||||
if (!pacUrl.IsNullOrEmpty() && pacUrl != origPacUrl) | |||||
{ | { | ||||
controller.SavePACUrl(pacUrl); | controller.SavePACUrl(pacUrl); | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<packages> | <packages> | ||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net4-client" developmentDependency="true" /> | |||||
<package id="Caseless.Fody" version="1.4.1" targetFramework="net40-client" developmentDependency="true" /> | |||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net40-client" developmentDependency="true" /> | |||||
<package id="Fody" version="1.29.4" targetFramework="net40-client" developmentDependency="true" /> | <package id="Fody" version="1.29.4" targetFramework="net40-client" developmentDependency="true" /> | ||||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net40-client" /> | <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net40-client" /> | ||||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net40-client" /> | <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net40-client" /> | ||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net40-client" /> | <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net40-client" /> | ||||
<package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net4-client" /> | <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net4-client" /> | ||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net40-client" /> | <package id="Newtonsoft.Json" version="8.0.2" targetFramework="net40-client" /> | ||||
<package id="StringEx.CS" version="0.2" targetFramework="net40-client" /> | |||||
<package id="System.Net.Http" version="2.0.20710.0" targetFramework="net40-client" /> | <package id="System.Net.Http" version="2.0.20710.0" targetFramework="net40-client" /> | ||||
</packages> | </packages> |
@@ -205,6 +205,7 @@ | |||||
<Compile Include="Controller\Strategy\BalancingStrategy.cs" /> | <Compile Include="Controller\Strategy\BalancingStrategy.cs" /> | ||||
<Compile Include="Controller\Strategy\StrategyManager.cs" /> | <Compile Include="Controller\Strategy\StrategyManager.cs" /> | ||||
<Compile Include="Controller\Strategy\IStrategy.cs" /> | <Compile Include="Controller\Strategy\IStrategy.cs" /> | ||||
<Compile Include="StringEx.cs" /> | |||||
<Compile Include="Util\Util.cs" /> | <Compile Include="Util\Util.cs" /> | ||||
<Compile Include="View\ConfigForm.cs"> | <Compile Include="View\ConfigForm.cs"> | ||||
<SubType>Form</SubType> | <SubType>Form</SubType> | ||||
@@ -334,6 +335,43 @@ | |||||
</Target> | </Target> | ||||
<Import Project="3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" /> | <Import Project="3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" /> | ||||
<Import Project="3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" /> | <Import Project="3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" /> | ||||
<UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory"> | |||||
<ParameterGroup> | |||||
<Config Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem" /> | |||||
<Files Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" /> | |||||
</ParameterGroup> | |||||
<Task Evaluate="true"> | |||||
<Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml" /> | |||||
<Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml.Linq" /> | |||||
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" /> | |||||
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" /> | |||||
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" /> | |||||
<Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"> | |||||
<![CDATA[ | |||||
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault(); | |||||
if (config == null) return true; | |||||
var excludedAssemblies = new List<string>(); | |||||
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); | |||||
]]> | |||||
</Code></Task> | |||||
</UsingTask> | |||||
<Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget"> | |||||
<CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" /> | |||||
</Target> | |||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | ||||
Other similar extension points exist, see Microsoft.Common.targets. | Other similar extension points exist, see Microsoft.Common.targets. | ||||
<Target Name="BeforeBuild"> | <Target Name="BeforeBuild"> | ||||
@@ -1,30 +1,32 @@ | |||||
| |||||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio Express 2012 for Windows Desktop | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" | |||||
EndProject | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{45913187-0685-4903-B250-DCEF0479CD86}" | |||||
ProjectSection(ProjectDependencies) = postProject | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} = {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} | |||||
EndProjectSection | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|x86 = Debug|x86 | |||||
Release|x86 = Release|x86 | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
EndGlobal | |||||
| |||||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio 14 | |||||
VisualStudioVersion = 14.0.24720.0 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" | |||||
EndProject | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{45913187-0685-4903-B250-DCEF0479CD86}" | |||||
ProjectSection(ProjectDependencies) = postProject | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} = {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} | |||||
EndProjectSection | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|x86 = Debug|x86 | |||||
Release|x86 = Release|x86 | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
EndGlobal |