Compare commits

..
1 Commits
Author SHA1 Message Date
noisyfox 09abe5642e Add x64 target support 2016-11-19 06:22:42 +11:00
27 changed files with 482 additions and 503 deletions
-11
View File
@@ -1,14 +1,3 @@
3.3.6 2016-12-6
- Refine system proxy mode switching logic,
merge 'Switch to PAC' and 'Switch to Global' into
'Switch system proxy mode'.
- Don't store LogViewer window size in config file,
now you can sync config between devices with different
resolutions.
- Add tag support for SS url
- Add pre-release channel in update checker
- Bug fixes and improvements
3.3.5 2016-11-7 3.3.5 2016-11-7
- Improve system power mode handling - Improve system power mode handling
- Update mbed TLS to 2.4.0 - Update mbed TLS to 2.4.0
@@ -14,9 +14,9 @@ namespace Shadowsocks.Controller
{ {
class PACServer : Listener.Service class PACServer : Listener.Service
{ {
public const string PAC_FILE = "pac.txt"; public static readonly string PAC_FILE = "pac.txt";
public const string USER_RULE_FILE = "user-rule.txt"; public static readonly string USER_RULE_FILE = "user-rule.txt";
public const string USER_ABP_FILE = "abp.txt"; public static readonly string USER_ABP_FILE = "abp.txt";
FileSystemWatcher PACFileWatcher; FileSystemWatcher PACFileWatcher;
FileSystemWatcher UserRuleFileWatcher; FileSystemWatcher UserRuleFileWatcher;
@@ -6,7 +6,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
@@ -42,10 +41,17 @@ namespace Shadowsocks.Controller
} }
} }
public int RunningPort => _runningPort; public int RunningPort
{
get
{
return _runningPort;
}
}
public void Start(Configuration configuration) public void Start(Configuration configuration)
{ {
Server server = configuration.GetCurrentServer();
if (_process == null) if (_process == null)
{ {
Process[] existingPrivoxy = Process.GetProcessesByName("ss_privoxy"); Process[] existingPrivoxy = Process.GetProcessesByName("ss_privoxy");
@@ -84,7 +90,6 @@ namespace Shadowsocks.Controller
if (_process != null) if (_process != null)
{ {
KillProcess(_process); KillProcess(_process);
_process.Dispose();
_process = null; _process = null;
} }
RefreshTrayArea(); RefreshTrayArea();
@@ -155,12 +160,21 @@ namespace Shadowsocks.Controller
int defaultPort = 8123; int defaultPort = 8123;
try try
{ {
// TCP stack please do me a favor IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
TcpListener l = new TcpListener(IPAddress.Loopback, 0); IPEndPoint[] tcpEndPoints = properties.GetActiveTcpListeners();
l.Start();
var port = ((IPEndPoint)l.LocalEndpoint).Port; List<int> usedPorts = new List<int>();
l.Stop(); foreach (IPEndPoint endPoint in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners())
return port; {
usedPorts.Add(endPoint.Port);
}
for (int port = defaultPort; port <= 65535; port++)
{
if (!usedPorts.Contains(port))
{
return port;
}
}
} }
catch (Exception e) catch (Exception e)
{ {
@@ -168,6 +182,7 @@ namespace Shadowsocks.Controller
Logging.LogUsefulException(e); Logging.LogUsefulException(e);
return defaultPort; return defaultPort;
} }
throw new Exception("No free port found.");
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@@ -18,13 +18,12 @@ namespace Shadowsocks.Controller
private Configuration config; private Configuration config;
public bool NewVersionFound; public bool NewVersionFound;
public string LatestVersionNumber; public string LatestVersionNumber;
public string LatestVersionSuffix;
public string LatestVersionName; public string LatestVersionName;
public string LatestVersionURL; public string LatestVersionURL;
public string LatestVersionLocalName; public string LatestVersionLocalName;
public event EventHandler CheckUpdateCompleted; public event EventHandler CheckUpdateCompleted;
public const string Version = "3.3.6"; public const string Version = "3.3.5";
private class CheckUpdateTimer : System.Timers.Timer private class CheckUpdateTimer : System.Timers.Timer
{ {
@@ -84,21 +83,17 @@ namespace Shadowsocks.Controller
{ {
foreach (JObject release in result) foreach (JObject release in result)
{ {
var isPreRelease = (bool) release["prerelease"]; if ((bool)release["prerelease"])
if (isPreRelease && !config.checkPreRelease)
{ {
continue; continue;
} }
foreach (JObject asset in (JArray)release["assets"]) foreach (JObject asset in (JArray)release["assets"])
{ {
Asset ass = Asset.ParseAsset(asset); Asset ass = new Asset();
if (ass != null) ass.Parse(asset);
if (ass.IsNewVersion(Version))
{ {
ass.prerelease = isPreRelease; asserts.Add(ass);
if (ass.IsNewVersion(Version, config.checkPreRelease))
{
asserts.Add(ass);
}
} }
} }
} }
@@ -111,7 +106,6 @@ namespace Shadowsocks.Controller
LatestVersionURL = asset.browser_download_url; LatestVersionURL = asset.browser_download_url;
LatestVersionNumber = asset.version; LatestVersionNumber = asset.version;
LatestVersionName = asset.name; LatestVersionName = asset.name;
LatestVersionSuffix = asset.suffix == null ? "" : $"-{asset.suffix}";
startDownload(); startDownload();
} }
@@ -154,7 +148,7 @@ namespace Shadowsocks.Controller
Logging.LogUsefulException(e.Error); Logging.LogUsefulException(e.Error);
return; return;
} }
Logging.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); Logging.Debug($"New version {LatestVersionNumber} found: {LatestVersionLocalName}");
if (CheckUpdateCompleted != null) if (CheckUpdateCompleted != null)
{ {
CheckUpdateCompleted(this, new EventArgs()); CheckUpdateCompleted(this, new EventArgs());
@@ -185,38 +179,10 @@ namespace Shadowsocks.Controller
public string name; public string name;
public string version; public string version;
public string browser_download_url; public string browser_download_url;
public string suffix;
public static Asset ParseAsset(JObject assertJObject) public bool IsNewVersion(string currentVersion)
{ {
var name = (string) assertJObject["name"]; if (prerelease)
Match match = Regex.Match(name, @"^Shadowsocks-(?<version>\d+(?:\.\d+)*)(?:|-(?<suffix>.+))\.\w+$",
RegexOptions.IgnoreCase);
if (match.Success)
{
string version = match.Groups["version"].Value;
var asset = new Asset
{
browser_download_url = (string) assertJObject["browser_download_url"],
name = name,
version = version
};
if (match.Groups["suffix"].Success)
{
asset.suffix = match.Groups["suffix"].Value;
}
return asset;
}
return null;
}
public bool IsNewVersion(string currentVersion, bool checkPreRelease)
{
if (prerelease && !checkPreRelease)
{ {
return false; return false;
} }
@@ -224,8 +190,28 @@ namespace Shadowsocks.Controller
{ {
return false; return false;
} }
var cmp = CompareVersion(version, currentVersion); return CompareVersion(version, currentVersion) > 0;
return cmp > 0; }
public void Parse(JObject asset)
{
name = (string)asset["name"];
browser_download_url = (string)asset["browser_download_url"];
version = ParseVersionFromURL(browser_download_url);
prerelease = browser_download_url.IndexOf("prerelease", StringComparison.Ordinal) >= 0;
}
private static string ParseVersionFromURL(string url)
{
Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase);
if (match.Success)
{
if (match.Groups.Count == 2)
{
return match.Groups[1].Value;
}
}
return null;
} }
public static int CompareVersion(string l, string r) public static int CompareVersion(string l, string r)
@@ -5,7 +5,6 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Web;
using Newtonsoft.Json; using Newtonsoft.Json;
using Shadowsocks.Controller.Strategy; using Shadowsocks.Controller.Strategy;
@@ -187,6 +186,7 @@ namespace Shadowsocks.Controller
public void ToggleEnable(bool enabled) public void ToggleEnable(bool enabled)
{ {
_config.enabled = enabled; _config.enabled = enabled;
UpdateSystemProxy();
SaveConfig(_config); SaveConfig(_config);
if (EnableStatusChanged != null) if (EnableStatusChanged != null)
{ {
@@ -197,6 +197,7 @@ namespace Shadowsocks.Controller
public void ToggleGlobal(bool global) public void ToggleGlobal(bool global)
{ {
_config.global = global; _config.global = global;
UpdateSystemProxy();
SaveConfig(_config); SaveConfig(_config);
if (EnableGlobalChanged != null) if (EnableGlobalChanged != null)
{ {
@@ -300,15 +301,11 @@ namespace Shadowsocks.Controller
public static string GetQRCode(Server server) public static string GetQRCode(Server server)
{ {
string tag = string.Empty; string parts = server.method;
string auth = server.auth ? "-auth" : string.Empty; if (server.auth) parts += "-auth";
string parts = $"{server.method}{auth}:{server.password}@{server.server}:{server.server_port}"; parts += ":" + server.password + "@" + server.server + ":" + server.server_port;
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts));
if(!server.remarks.IsNullOrEmpty()) return "ss://" + base64;
{
tag = $"#{HttpUtility.UrlEncode(server.remarks, Encoding.UTF8)}";
}
return $"ss://{base64}{tag}";
} }
public void UpdatePACFromGFWList() public void UpdatePACFromGFWList()
@@ -330,6 +327,7 @@ namespace Shadowsocks.Controller
public void SavePACUrl(string pacUrl) public void SavePACUrl(string pacUrl)
{ {
_config.pacUrl = pacUrl; _config.pacUrl = pacUrl;
UpdateSystemProxy();
SaveConfig(_config); SaveConfig(_config);
if (ConfigChanged != null) if (ConfigChanged != null)
{ {
@@ -340,6 +338,7 @@ namespace Shadowsocks.Controller
public void UseOnlinePAC(bool useOnlinePac) public void UseOnlinePAC(bool useOnlinePac)
{ {
_config.useOnlinePac = useOnlinePac; _config.useOnlinePac = useOnlinePac;
UpdateSystemProxy();
SaveConfig(_config); SaveConfig(_config);
if (ConfigChanged != null) if (ConfigChanged != null)
{ {
@@ -357,16 +356,6 @@ namespace Shadowsocks.Controller
} }
} }
public void ToggleCheckingPreRelease(bool enabled)
{
_config.checkPreRelease = enabled;
Configuration.Save(_config);
if (ConfigChanged != null)
{
ConfigChanged(this, new EventArgs());
}
}
public void SaveLogViewerConfig(LogViewerConfig newConfig) public void SaveLogViewerConfig(LogViewerConfig newConfig)
{ {
_config.logViewer = newConfig; _config.logViewer = newConfig;
@@ -1,115 +0,0 @@
using System;
using System.Reflection;
namespace Shadowsocks.Controller.Hotkeys
{
public class HotkeyCallbacks
{
public static void InitInstance(ShadowsocksController controller)
{
if (Instance != null)
{
return;
}
Instance = new HotkeyCallbacks(controller);
}
/// <summary>
/// Create hotkey callback handler delegate based on callback name
/// </summary>
/// <param name="methodname"></param>
/// <returns></returns>
public static Delegate GetCallback(string methodname)
{
if (methodname.IsNullOrEmpty()) throw new ArgumentException(nameof(methodname));
MethodInfo dynMethod = typeof(HotkeyCallbacks).GetMethod(methodname,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
return dynMethod == null ? null : Delegate.CreateDelegate(typeof(HotKeys.HotKeyCallBackHandler), Instance, dynMethod);
}
#region Singleton
private static HotkeyCallbacks Instance { get; set; }
private readonly ShadowsocksController _controller;
private HotkeyCallbacks(ShadowsocksController controller)
{
_controller = controller;
}
#endregion
#region Callbacks
private void SwitchSystemProxyCallback()
{
bool enabled = _controller.GetConfigurationCopy().enabled;
_controller.ToggleEnable(!enabled);
}
private void SwitchProxyModeCallback()
{
var config = _controller.GetConfigurationCopy();
if (config.enabled == false) return;
var currStatus = config.global;
_controller.ToggleGlobal(!currStatus);
}
private void SwitchAllowLanCallback()
{
var status = _controller.GetConfigurationCopy().shareOverLan;
_controller.ToggleShareOverLAN(!status);
}
private void ShowLogsCallback()
{
Program.MenuController.ShowLogForm_HotKey();
}
private void ServerMoveUpCallback()
{
int currIndex;
int serverCount;
GetCurrServerInfo(out currIndex, out serverCount);
if (currIndex - 1 < 0)
{
// revert to last server
currIndex = serverCount - 1;
}
else
{
currIndex -= 1;
}
_controller.SelectServerIndex(currIndex);
}
private void ServerMoveDownCallback()
{
int currIndex;
int serverCount;
GetCurrServerInfo(out currIndex, out serverCount);
if (currIndex + 1 == serverCount)
{
// revert to first server
currIndex = 0;
}
else
{
currIndex += 1;
}
_controller.SelectServerIndex(currIndex);
}
private void GetCurrServerInfo(out int currIndex, out int serverCount)
{
var currConfig = _controller.GetCurrentConfiguration();
currIndex = currConfig.index;
serverCount = currConfig.configs.Count;
}
#endregion
}
}
-1
View File
@@ -27,7 +27,6 @@ Verbose Logging=详细记录日志
Updates...=更新... Updates...=更新...
Check for Updates...=检查更新 Check for Updates...=检查更新
Check for Updates at Startup=启动时检查更新 Check for Updates at Startup=启动时检查更新
Check Pre-release Version=检查测试版更新
Edit Hotkeys...=编辑快捷键... Edit Hotkeys...=编辑快捷键...
About...=关于... About...=关于...
Quit=退出 Quit=退出
Binary file not shown.
-1
View File
@@ -27,7 +27,6 @@ Verbose Logging=詳細記錄日誌
Updates...=更新... Updates...=更新...
Check for Updates...=檢查更新 Check for Updates...=檢查更新
Check for Updates at Startup=啟動時檢查更新 Check for Updates at Startup=啟動時檢查更新
Check Pre-release Version=檢查測試版更新
Edit Hotkeys...=編輯捷徑鍵... Edit Hotkeys...=編輯捷徑鍵...
About...=關於... About...=關於...
Quit=退出 Quit=退出
+4
View File
@@ -20,7 +20,11 @@ namespace Shadowsocks.Encryption
string dllPath = Utils.GetTempPath("libsscrypto.dll"); string dllPath = Utils.GetTempPath("libsscrypto.dll");
try try
{ {
#if _X64
FileManager.UncompressFile(dllPath, Resources.libsscrypto64_dll);
#else
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
#endif
} }
catch (IOException) catch (IOException)
{ {
+4
View File
@@ -17,7 +17,11 @@ namespace Shadowsocks.Encryption
string dllPath = Utils.GetTempPath("libsscrypto.dll"); string dllPath = Utils.GetTempPath("libsscrypto.dll");
try try
{ {
#if _X64
FileManager.UncompressFile(dllPath, Resources.libsscrypto64_dll);
#else
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
#endif
} }
catch (IOException) catch (IOException)
{ {
-6
View File
@@ -24,7 +24,6 @@ namespace Shadowsocks.Model
public bool useOnlinePac; public bool useOnlinePac;
public bool availabilityStatistics; public bool availabilityStatistics;
public bool autoCheckUpdate; public bool autoCheckUpdate;
public bool checkPreRelease;
public bool isVerboseLogging; public bool isVerboseLogging;
public LogViewerConfig logViewer; public LogViewerConfig logViewer;
public ProxyConfig proxy; public ProxyConfig proxy;
@@ -55,11 +54,6 @@ namespace Shadowsocks.Model
string configContent = File.ReadAllText(CONFIG_FILE); string configContent = File.ReadAllText(CONFIG_FILE);
Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent); Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent);
config.isDefault = false; config.isDefault = false;
if (config.configs == null)
config.configs = new List<Server>();
if (config.configs.Count == 0)
config.configs.Add(GetDefaultServer());
if (config.localPort == 0) if (config.localPort == 0)
config.localPort = 1080; config.localPort = 1080;
if (config.index == -1 && config.strategy == null) if (config.index == -1 && config.strategy == null)
+3 -6
View File
@@ -1,7 +1,7 @@
using System; using System;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using Shadowsocks.Controller; using Shadowsocks.Controller;
namespace Shadowsocks.Model namespace Shadowsocks.Model
@@ -10,8 +10,8 @@ namespace Shadowsocks.Model
public class Server public class Server
{ {
public static readonly Regex public static readonly Regex
UrlFinder = new Regex("^(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?$", UrlFinder = new Regex("^ss://((?:[A-Za-z0-9+/]+)|((?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?))$",
RegexOptions.IgnoreCase | RegexOptions.Compiled), RegexOptions.Compiled | RegexOptions.IgnoreCase),
DetailsParser = new Regex("^((?<method>.+?)(?<auth>-auth)??:(?<password>.*)@(?<hostname>.+?)" + DetailsParser = new Regex("^((?<method>.+?)(?<auth>-auth)??:(?<password>.*)@(?<hostname>.+?)" +
":(?<port>\\d+?))$", RegexOptions.Compiled | RegexOptions.IgnoreCase); ":(?<port>\\d+?))$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
@@ -79,9 +79,6 @@ namespace Shadowsocks.Model
var match = UrlFinder.Match(ssURL); var match = UrlFinder.Match(ssURL);
if (!match.Success) throw new FormatException(); if (!match.Success) throw new FormatException();
var base64 = match.Groups[1].Value; var base64 = match.Groups[1].Value;
var tag = match.Groups[3].Value;
if (!tag.IsNullOrEmpty())
remarks = HttpUtility.UrlDecode(tag, Encoding.UTF8);
match = DetailsParser.Match(Encoding.UTF8.GetString(Convert.FromBase64String( match = DetailsParser.Match(Encoding.UTF8.GetString(Convert.FromBase64String(
base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=')))); base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))));
method = match.Groups["method"].Value; method = match.Groups["method"].Value;
+15 -15
View File
@@ -6,7 +6,6 @@ using System.Windows.Forms;
using Microsoft.Win32; using Microsoft.Win32;
using Shadowsocks.Controller; using Shadowsocks.Controller;
using Shadowsocks.Controller.Hotkeys;
using Shadowsocks.Util; using Shadowsocks.Util;
using Shadowsocks.View; using Shadowsocks.View;
@@ -14,8 +13,9 @@ namespace Shadowsocks
{ {
static class Program static class Program
{ {
public static ShadowsocksController MainController { get; private set; } private static ShadowsocksController _controller;
public static MenuViewController MenuController { get; private set; } // XXX: Don't change this name
private static MenuViewController _viewController;
/// <summary> /// <summary>
/// 应用程序的主入口点。 /// 应用程序的主入口点。
@@ -79,10 +79,10 @@ namespace Shadowsocks
#else #else
Logging.OpenLogFile(); Logging.OpenLogFile();
#endif #endif
MainController = new ShadowsocksController(); _controller = new ShadowsocksController();
MenuController = new MenuViewController(MainController); _viewController = new MenuViewController(_controller);
HotKeys.Init(MainController); HotKeys.Init();
MainController.Start(); _controller.Start();
Application.Run(); Application.Run();
} }
} }
@@ -120,7 +120,7 @@ namespace Shadowsocks
{ {
case PowerModes.Resume: case PowerModes.Resume:
Logging.Info("os wake up"); Logging.Info("os wake up");
if (MainController != null) if (_controller != null)
{ {
System.Timers.Timer timer = new System.Timers.Timer(10 * 1000); System.Timers.Timer timer = new System.Timers.Timer(10 * 1000);
timer.Elapsed += Timer_Elapsed; timer.Elapsed += Timer_Elapsed;
@@ -130,9 +130,9 @@ namespace Shadowsocks
} }
break; break;
case PowerModes.Suspend: case PowerModes.Suspend:
if (MainController != null) if (_controller != null)
{ {
MainController.Stop(); _controller.Stop();
Logging.Info("controller stopped"); Logging.Info("controller stopped");
} }
Logging.Info("os suspend"); Logging.Info("os suspend");
@@ -144,9 +144,9 @@ namespace Shadowsocks
{ {
try try
{ {
if (MainController != null) if (_controller != null)
{ {
MainController.Start(); _controller.Start();
Logging.Info("controller started"); Logging.Info("controller started");
} }
} }
@@ -177,10 +177,10 @@ namespace Shadowsocks
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
Application.ThreadException -= Application_ThreadException; Application.ThreadException -= Application_ThreadException;
HotKeys.Destroy(); HotKeys.Destroy();
if (MainController != null) if (_controller != null)
{ {
MainController.Stop(); _controller.Stop();
MainController = null; _controller = null;
} }
} }
} }
+33 -23
View File
@@ -111,6 +111,16 @@ namespace Shadowsocks.Properties {
} }
} }
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] libsscrypto64_dll {
get {
object obj = ResourceManager.GetObject("libsscrypto64_dll", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary> /// <summary>
/// 查找 System.Byte[] 类型的本地化资源。 /// 查找 System.Byte[] 类型的本地化资源。
/// </summary> /// </summary>
@@ -227,29 +237,29 @@ namespace Shadowsocks.Properties {
} }
/// <summary> /// <summary>
/// 查找类似 # translation for Traditional Chinese /// 查找类似 # translation for Traditional Chinese
/// ///
///Shadowsocks=Shadowsocks ///Shadowsocks=Shadowsocks
/// ///
///# Menu items ///# Menu items
/// ///
///Enable System Proxy=啟用系統代理 ///Enable System Proxy=啟用系統代理
///Mode=系統代理模式 ///Mode=系統代理模式
///PAC=PAC 模式 ///PAC=PAC 模式
///Global=全局模式 ///Global=全局模式
///Servers=伺服器 ///Servers=伺服器
///Edit Servers...=編輯伺服器... ///Edit Servers...=編輯伺服器...
///Statistics Config...=統計配置... ///Statistics Config...=統計配置...
///Start on Boot=開機啟動 ///Start on Boot=開機啟動
///Forward Proxy...=正向代理設置... ///Forward Proxy...=正向代理設置...
///Allow Clients from LAN=允許來自區域網路的連接 ///Allow Clients from LAN=允許來自區域網路的連接
///Local PAC=使用本地 PAC ///Local PAC=使用本地 PAC
///Online PAC=使用在線 PAC ///Online PAC=使用在線 PAC
///Edit Local PAC File...=編輯本地 PAC 文件... ///Edit Local PAC File...=編輯本地 PAC 文件...
///Update Local PAC from GFWList=從 GFWList 更新本地 PAC ///Update Local PAC from GFWList=從 GFWList 更新本地 PAC
///Edit User Rule for GFWList...=編輯 GFWList 的用戶規則... ///Edit User Rule for GFWList...=編輯 GFWList 的用戶規則...
///Show QRCode...=顯示 QR 碼... ///Show QRCode...=顯示 QR 碼...
///Scan QRCode from Screen [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///S [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string zh_tw { internal static string zh_tw {
get { get {
+4 -1
View File
@@ -124,8 +124,11 @@
<data name="cn" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="cn" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\cn.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>..\data\cn.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>
<data name="libsscrypto64_dll" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Data\libsscrypto64.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="libsscrypto_dll" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="libsscrypto_dll" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>..\Data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="mgwz_dll" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="mgwz_dll" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\mgwz.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>..\data\mgwz.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
@@ -1,174 +1,179 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Windows.Input; using System.Windows.Forms;
using GlobalHotKey; using System.Windows.Input;
using GlobalHotKey;
namespace Shadowsocks.Controller.Hotkeys
{ namespace Shadowsocks.Util
public static class HotKeys {
{ public static class HotKeys
private static HotKeyManager _hotKeyManager; {
private static HotKeyManager _hotKeyManager;
public delegate void HotKeyCallBackHandler();
// map key and corresponding handler function public delegate void HotKeyCallBackHandler();
private static Dictionary<HotKey, HotKeyCallBackHandler> _keymap = new Dictionary<HotKey, HotKeyCallBackHandler>(); // map key and corresponding handler function
private static Dictionary<HotKey, HotKeyCallBackHandler> _keymap = new Dictionary<HotKey, HotKeyCallBackHandler>();
public static void Init(ShadowsocksController controller)
{ public static void Init()
_hotKeyManager = new HotKeyManager(); {
_hotKeyManager.KeyPressed += HotKeyManagerPressed; _hotKeyManager = new HotKeyManager();
_hotKeyManager.KeyPressed += HotKeyManagerPressed;
HotkeyCallbacks.InitInstance(controller); }
}
public static void Destroy()
public static void Destroy() {
{ _hotKeyManager.KeyPressed -= HotKeyManagerPressed;
_hotKeyManager.KeyPressed -= HotKeyManagerPressed; _hotKeyManager.Dispose();
_hotKeyManager.Dispose(); }
}
private static void HotKeyManagerPressed(object sender, KeyPressedEventArgs e)
private static void HotKeyManagerPressed(object sender, KeyPressedEventArgs e) {
{ var hotkey = e.HotKey;
var hotkey = e.HotKey; HotKeyCallBackHandler callback;
HotKeyCallBackHandler callback; if (_keymap.TryGetValue(hotkey, out callback))
if (_keymap.TryGetValue(hotkey, out callback)) callback();
callback(); }
}
public static bool IsHotkeyExists( HotKey hotKey )
public static bool IsHotkeyExists( HotKey hotKey ) {
{ if (hotKey == null) throw new ArgumentNullException(nameof(hotKey));
if (hotKey == null) throw new ArgumentNullException(nameof(hotKey)); return _keymap.Any( v => v.Key.Equals( hotKey ) );
return _keymap.Any( v => v.Key.Equals( hotKey ) ); }
}
public static bool IsCallbackExists( HotKeyCallBackHandler cb, out HotKey hotkey)
public static bool IsCallbackExists( HotKeyCallBackHandler cb, out HotKey hotkey) {
{ if (cb == null) throw new ArgumentNullException(nameof(cb));
if (cb == null) throw new ArgumentNullException(nameof(cb)); try
try {
{ var key = _keymap.First(x => x.Value == cb).Key;
var key = _keymap.First(x => x.Value == cb).Key; hotkey = key;
hotkey = key; return true;
return true; }
} catch (InvalidOperationException)
catch (InvalidOperationException) {
{ // not found
// not found hotkey = null;
hotkey = null; return false;
return false; }
} }
} public static string HotKey2Str( HotKey key )
public static string HotKey2Str( HotKey key ) {
{ if (key == null) throw new ArgumentNullException(nameof(key));
if (key == null) throw new ArgumentNullException(nameof(key)); return HotKey2Str( key.Key, key.Modifiers );
return HotKey2Str( key.Key, key.Modifiers ); }
}
public static string HotKey2Str( Key key, ModifierKeys modifier )
public static string HotKey2Str( Key key, ModifierKeys modifier ) {
{ if (!Enum.IsDefined(typeof(Key), key))
if (!Enum.IsDefined(typeof(Key), key)) throw new InvalidEnumArgumentException(nameof(key), (int) key, typeof(Key));
throw new InvalidEnumArgumentException(nameof(key), (int) key, typeof(Key)); try
try {
{ ModifierKeysConverter mkc = new ModifierKeysConverter();
ModifierKeysConverter mkc = new ModifierKeysConverter(); var keyStr = Enum.GetName(typeof(Key), key);
var keyStr = Enum.GetName(typeof(Key), key); var modifierStr = mkc.ConvertToInvariantString(modifier);
var modifierStr = mkc.ConvertToInvariantString(modifier);
return $"{modifierStr}+{keyStr}";
return $"{modifierStr}+{keyStr}"; }
} catch (NotSupportedException)
catch (NotSupportedException) {
{ // converter exception
// converter exception return null;
return null; }
} }
}
public static HotKey Str2HotKey(string s)
public static HotKey Str2HotKey(string s) {
{ try
try {
{ if (s.IsNullOrEmpty()) return null;
if (s.IsNullOrEmpty()) return null; int offset = s.LastIndexOf("+", StringComparison.OrdinalIgnoreCase);
int offset = s.LastIndexOf("+", StringComparison.OrdinalIgnoreCase); if (offset <= 0) return null;
if (offset <= 0) return null; string modifierStr = s.Substring(0, offset).Trim();
string modifierStr = s.Substring(0, offset).Trim(); string keyStr = s.Substring(offset + 1).Trim();
string keyStr = s.Substring(offset + 1).Trim();
KeyConverter kc = new KeyConverter();
KeyConverter kc = new KeyConverter(); ModifierKeysConverter mkc = new ModifierKeysConverter();
ModifierKeysConverter mkc = new ModifierKeysConverter(); Key key = (Key) kc.ConvertFrom(keyStr.ToUpper());
Key key = (Key) kc.ConvertFrom(keyStr.ToUpper()); ModifierKeys modifier = (ModifierKeys) mkc.ConvertFrom(modifierStr.ToUpper());
ModifierKeys modifier = (ModifierKeys) mkc.ConvertFrom(modifierStr.ToUpper());
return new HotKey(key, modifier);
return new HotKey(key, modifier); }
} catch (NotSupportedException)
catch (NotSupportedException) {
{ // converter exception
// converter exception return null;
return null; }
} catch (NullReferenceException)
catch (NullReferenceException) {
{ return null;
return null; }
} }
}
public static bool Regist( HotKey key, HotKeyCallBackHandler callBack )
public static bool Regist( HotKey key, HotKeyCallBackHandler callBack ) {
{ if (key == null)
if (key == null) throw new ArgumentNullException(nameof(key));
throw new ArgumentNullException(nameof(key)); if (callBack == null)
if (callBack == null) throw new ArgumentNullException(nameof(callBack));
throw new ArgumentNullException(nameof(callBack)); try
try {
{ _hotKeyManager.Register(key);
_hotKeyManager.Register(key); _keymap[key] = callBack;
_keymap[key] = callBack; return true;
return true; }
} catch (ArgumentException)
catch (ArgumentException) {
{ // already called this method with the specific hotkey
// already called this method with the specific hotkey // return success silently
// return success silently return true;
return true; }
} catch (Win32Exception)
catch (Win32Exception) {
{ // this hotkey already registered by other programs
// this hotkey already registered by other programs // notify user to change key
// notify user to change key return false;
return false; }
} }
}
public static bool Regist(Key key, ModifierKeys modifiers, HotKeyCallBackHandler callBack)
public static bool Regist(Key key, ModifierKeys modifiers, HotKeyCallBackHandler callBack) {
{ if (!Enum.IsDefined(typeof(Key), key))
if (!Enum.IsDefined(typeof(Key), key)) throw new InvalidEnumArgumentException(nameof(key), (int) key, typeof(Key));
throw new InvalidEnumArgumentException(nameof(key), (int) key, typeof(Key)); try
try {
{ var hotkey = _hotKeyManager.Register(key, modifiers);
var hotkey = _hotKeyManager.Register(key, modifiers); _keymap[hotkey] = callBack;
_keymap[hotkey] = callBack; return true;
return true; }
} catch (ArgumentException)
catch (ArgumentException) {
{ // already called this method with the specific hotkey
// already called this method with the specific hotkey // return success silently
// return success silently return true;
return true; }
} catch (Win32Exception)
catch (Win32Exception) {
{ // already registered by other programs
// already registered by other programs // notify user to change key
// notify user to change key return false;
return false; }
} }
}
public static void UnRegist(HotKey key)
public static void UnRegist(HotKey key) {
{ if (key == null)
if (key == null) throw new ArgumentNullException(nameof(key));
throw new ArgumentNullException(nameof(key)); _hotKeyManager.Unregister(key);
_hotKeyManager.Unregister(key); if(_keymap.ContainsKey(key))
if(_keymap.ContainsKey(key)) _keymap.Remove(key);
_keymap.Remove(key); }
}
} public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
var children = control.Controls.Count > 0 ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
}
}
} }
@@ -93,7 +93,7 @@ namespace Shadowsocks.Util.SystemProxy
foreach (INTERNET_PER_CONN_OPTION eachOption in _optionlist) foreach (INTERNET_PER_CONN_OPTION eachOption in _optionlist)
{ {
Marshal.StructureToPtr(eachOption, current, false); Marshal.StructureToPtr(eachOption, current, false);
current = (IntPtr)((int)current + Marshal.SizeOf(eachOption)); current = (IntPtr)(current.ToInt64() + Marshal.SizeOf(eachOption));
} }
// Initialize a INTERNET_PER_CONN_OPTION_LIST instance. // Initialize a INTERNET_PER_CONN_OPTION_LIST instance.
+1 -1
View File
@@ -23,7 +23,7 @@ namespace Shadowsocks.Util
} }
} }
public static class Utils public class Utils
{ {
private static bool? _portableMode; private static bool? _portableMode;
private static string TempPath = null; private static string TempPath = null;
-21
View File
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Shadowsocks.Util
{
public static class ViewUtils
{
public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
if (control.Controls.Count == 0)
{
return Enumerable.Empty<TControl>();
}
var children = control.Controls.OfType<TControl>().ToList();
return children.SelectMany(GetChildControls<TControl>).Concat(children);
}
}
}
+1 -1
View File
@@ -151,7 +151,7 @@ namespace Shadowsocks.View
_modifiedConfiguration = controller.GetConfigurationCopy(); _modifiedConfiguration = controller.GetConfigurationCopy();
LoadConfiguration(_modifiedConfiguration); LoadConfiguration(_modifiedConfiguration);
_lastSelectedIndex = _modifiedConfiguration.index; _lastSelectedIndex = _modifiedConfiguration.index;
if (_lastSelectedIndex < 0 || _lastSelectedIndex >= ServersListBox.Items.Count) if (_lastSelectedIndex < 0)
{ {
_lastSelectedIndex = 0; _lastSelectedIndex = 0;
} }
+122 -32
View File
@@ -7,7 +7,6 @@ using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Shadowsocks.Controller; using Shadowsocks.Controller;
using Shadowsocks.Controller.Hotkeys;
using Shadowsocks.Model; using Shadowsocks.Model;
using Shadowsocks.Properties; using Shadowsocks.Properties;
using Shadowsocks.Util; using Shadowsocks.Util;
@@ -16,18 +15,23 @@ namespace Shadowsocks.View
{ {
public partial class HotkeySettingsForm : Form public partial class HotkeySettingsForm : Form
{ {
private readonly ShadowsocksController _controller; private ShadowsocksController _controller;
// this is a copy of configuration that we are working on // this is a copy of configuration that we are working on
private HotkeyConfig _modifiedConfig; private HotkeyConfig _modifiedConfig;
private readonly IEnumerable<TextBox> _allTextBoxes; private StringBuilder _sb = new StringBuilder();
private IEnumerable<TextBox> _allTextBoxes;
private Label _lb = null;
private HotKeys.HotKeyCallBackHandler _callBack = null;
public HotkeySettingsForm(ShadowsocksController controller) public HotkeySettingsForm(ShadowsocksController controller)
{ {
InitializeComponent(); InitializeComponent();
UpdateTexts(); UpdateTexts();
Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
_controller = controller; _controller = controller;
_controller.ConfigChanged += controller_ConfigChanged; _controller.ConfigChanged += controller_ConfigChanged;
@@ -35,7 +39,7 @@ namespace Shadowsocks.View
LoadCurrentConfiguration(); LoadCurrentConfiguration();
// get all textboxes belong to this form // get all textboxes belong to this form
_allTextBoxes = tableLayoutPanel1.GetChildControls<TextBox>(); _allTextBoxes = HotKeys.GetChildControls<TextBox>(this.tableLayoutPanel1);
if (!_allTextBoxes.Any()) throw new Exception("Cannot get all textboxes"); if (!_allTextBoxes.Any()) throw new Exception("Cannot get all textboxes");
} }
@@ -72,7 +76,7 @@ namespace Shadowsocks.View
btnOK.Text = I18N.GetString("OK"); btnOK.Text = I18N.GetString("OK");
btnCancel.Text = I18N.GetString("Cancel"); btnCancel.Text = I18N.GetString("Cancel");
btnRegisterAll.Text = I18N.GetString("Reg All"); btnRegisterAll.Text = I18N.GetString("Reg All");
Text = I18N.GetString("Edit Hotkeys..."); this.Text = I18N.GetString("Edit Hotkeys...");
} }
/// <summary> /// <summary>
@@ -80,7 +84,7 @@ namespace Shadowsocks.View
/// </summary> /// </summary>
private void HotkeyDown(object sender, KeyEventArgs e) private void HotkeyDown(object sender, KeyEventArgs e)
{ {
StringBuilder sb = new StringBuilder(); _sb.Length = 0;
//Combination key only //Combination key only
if (e.Modifiers != 0) if (e.Modifiers != 0)
{ {
@@ -88,15 +92,15 @@ namespace Shadowsocks.View
// Windows key is reserved by operating system, we deny this key. // Windows key is reserved by operating system, we deny this key.
if (e.Control) if (e.Control)
{ {
sb.Append("Ctrl+"); _sb.Append("Ctrl+");
} }
if (e.Alt) if (e.Alt)
{ {
sb.Append("Alt+"); _sb.Append("Alt+");
} }
if (e.Shift) if (e.Shift)
{ {
sb.Append("Shift+"); _sb.Append("Shift+");
} }
Keys keyvalue = (Keys) e.KeyValue; Keys keyvalue = (Keys) e.KeyValue;
@@ -104,18 +108,18 @@ namespace Shadowsocks.View
(keyvalue >= Keys.A && keyvalue <= Keys.Z) || (keyvalue >= Keys.A && keyvalue <= Keys.Z) ||
(keyvalue >= Keys.F1 && keyvalue <= Keys.F12)) (keyvalue >= Keys.F1 && keyvalue <= Keys.F12))
{ {
sb.Append(e.KeyCode); _sb.Append(e.KeyCode);
} }
else if (keyvalue >= Keys.D0 && keyvalue <= Keys.D9) else if (keyvalue >= Keys.D0 && keyvalue <= Keys.D9)
{ {
sb.Append('D').Append((char) e.KeyValue); _sb.Append('D').Append((char) e.KeyValue);
} }
else if (keyvalue >= Keys.NumPad0 && keyvalue <= Keys.NumPad9) else if (keyvalue >= Keys.NumPad0 && keyvalue <= Keys.NumPad9)
{ {
sb.Append("NumPad").Append((char) (e.KeyValue - 48)); _sb.Append("NumPad").Append((char) (e.KeyValue - 48));
} }
} }
((TextBox) sender).Text = sb.ToString(); ((TextBox) sender).Text = _sb.ToString();
} }
/// <summary> /// <summary>
@@ -123,8 +127,8 @@ namespace Shadowsocks.View
/// </summary> /// </summary>
private void HotkeyUp(object sender, KeyEventArgs e) private void HotkeyUp(object sender, KeyEventArgs e)
{ {
var tb = (TextBox) sender; TextBox tb = sender as TextBox;
var content = tb.Text.TrimEnd(); string content = tb.Text.TrimEnd();
if (content.Length >= 1 && content[content.Length - 1] == '+') if (content.Length >= 1 && content[content.Length - 1] == '+')
{ {
tb.Text = ""; tb.Text = "";
@@ -133,7 +137,7 @@ namespace Shadowsocks.View
private void TextBox_TextChanged(object sender, EventArgs e) private void TextBox_TextChanged(object sender, EventArgs e)
{ {
var tb = (TextBox) sender; TextBox tb = sender as TextBox;
if (tb.Text == "") if (tb.Text == "")
{ {
@@ -144,17 +148,15 @@ namespace Shadowsocks.View
private void UnregHotkey(TextBox tb) private void UnregHotkey(TextBox tb)
{ {
HotKeys.HotKeyCallBackHandler callBack;
Label lb;
PrepareForHotkey(tb, out callBack, out lb); PrepareForHotkey(tb, out _callBack, out _lb);
UnregPrevHotkey(callBack); UnregPrevHotkey(_callBack);
} }
private void CancelButton_Click(object sender, EventArgs e) private void CancelButton_Click(object sender, EventArgs e)
{ {
Close(); this.Close();
} }
private void OKButton_Click(object sender, EventArgs e) private void OKButton_Click(object sender, EventArgs e)
@@ -175,7 +177,7 @@ namespace Shadowsocks.View
// All check passed, saving // All check passed, saving
SaveConfig(); SaveConfig();
Close(); this.Close();
} }
private void RegisterAllButton_Click(object sender, EventArgs e) private void RegisterAllButton_Click(object sender, EventArgs e)
@@ -200,12 +202,9 @@ namespace Shadowsocks.View
return false; return false;
} }
HotKeys.HotKeyCallBackHandler callBack; PrepareForHotkey(tb, out _callBack, out _lb);
Label lb;
PrepareForHotkey(tb, out callBack, out lb); UnregPrevHotkey(_callBack);
UnregPrevHotkey(callBack);
// try to register keys // try to register keys
// if already registered by other progs // if already registered by other progs
@@ -218,8 +217,8 @@ namespace Shadowsocks.View
// or change to another one // or change to another one
// Transparent without color: first run or empty config // Transparent without color: first run or empty config
bool regResult = HotKeys.Regist(hotkey, callBack); bool regResult = HotKeys.Regist(hotkey, _callBack);
lb.BackColor = regResult ? Color.Green : Color.Yellow; _lb.BackColor = regResult ? Color.Green : Color.Yellow;
return regResult; return regResult;
} }
@@ -244,7 +243,81 @@ namespace Shadowsocks.View
_controller.SaveHotkeyConfig(_modifiedConfig); _controller.SaveHotkeyConfig(_modifiedConfig);
} }
#region Callbacks
private void SwitchSystemProxyCallback()
{
bool enabled = _controller.GetConfigurationCopy().enabled;
_controller.ToggleEnable(!enabled);
}
private void SwitchProxyModeCallback()
{
var config = _controller.GetConfigurationCopy();
if (config.enabled == false) return;
var currStatus = config.global;
_controller.ToggleGlobal(!currStatus);
}
private void SwitchAllowLanCallback()
{
var status = _controller.GetConfigurationCopy().shareOverLan;
_controller.ToggleShareOverLAN(!status);
}
private void ShowLogsCallback()
{
// Get the current MenuViewController in this program via reflection
FieldInfo fi = Assembly.GetExecutingAssembly().GetType("Shadowsocks.Program")
.GetField("_viewController",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase);
// To retrieve the value of a static field, pass null here
var mvc = fi.GetValue(null) as MenuViewController;
mvc.ShowLogForm_HotKey();
}
private void ServerMoveUpCallback()
{
int currIndex;
int serverCount;
GetCurrServerInfo(out currIndex, out serverCount);
if (currIndex - 1 < 0)
{
// revert to last server
currIndex = serverCount - 1;
}
else
{
currIndex -= 1;
}
_controller.SelectServerIndex(currIndex);
}
private void ServerMoveDownCallback()
{
int currIndex;
int serverCount;
GetCurrServerInfo(out currIndex, out serverCount);
if (currIndex + 1 == serverCount)
{
// revert to first server
currIndex = 0;
}
else
{
currIndex += 1;
}
_controller.SelectServerIndex(currIndex);
}
private void GetCurrServerInfo(out int currIndex, out int serverCount)
{
var currConfig = _controller.GetCurrentConfiguration();
currIndex = currConfig.index;
serverCount = currConfig.configs.Count;
}
#endregion
#region Prepare hotkey #region Prepare hotkey
@@ -270,14 +343,14 @@ namespace Shadowsocks.View
var labelName = rawName + "Label"; var labelName = rawName + "Label";
var callbackName = rawName + "Callback"; var callbackName = rawName + "Callback";
var callback = HotkeyCallbacks.GetCallback(callbackName); var callback = GetDelegateViaMethodName(this.GetType(), callbackName);
if (callback == null) if (callback == null)
{ {
throw new Exception($"{callbackName} not found"); throw new Exception($"{callbackName} not found");
} }
cb = callback as HotKeys.HotKeyCallBackHandler; cb = callback as HotKeys.HotKeyCallBackHandler;
var label = GetFieldViaName(GetType(), labelName, this); object label = GetFieldViaName(this.GetType(), labelName, this);
if (label == null) if (label == null)
{ {
throw new Exception($"{labelName} not found"); throw new Exception($"{labelName} not found");
@@ -302,6 +375,23 @@ namespace Shadowsocks.View
return fi == null ? null : fi.GetValue(obj); return fi == null ? null : fi.GetValue(obj);
} }
/// <summary>
/// Create hotkey callback handler delegate based on callback name
/// </summary>
/// <param name="type"></param>
/// <param name="methodname"></param>
/// <returns></returns>
private Delegate GetDelegateViaMethodName(Type type, string methodname)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (methodname.IsNullOrEmpty()) throw new ArgumentException(nameof(methodname));
//HotkeySettingsForm form = new HotkeySettingsForm(_controller);
Type delegateType = Type.GetType("Shadowsocks.Util.HotKeys").GetNestedType("HotKeyCallBackHandler");
MethodInfo dynMethod = type.GetMethod(methodname,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
return dynMethod == null ? null : Delegate.CreateDelegate(delegateType, this, dynMethod);
}
#endregion #endregion
} }
} }
+1 -11
View File
@@ -48,7 +48,6 @@ namespace Shadowsocks.View
private MenuItem editGFWUserRuleItem; private MenuItem editGFWUserRuleItem;
private MenuItem editOnlinePACItem; private MenuItem editOnlinePACItem;
private MenuItem autoCheckUpdatesToggleItem; private MenuItem autoCheckUpdatesToggleItem;
private MenuItem checkPreReleaseToggleItem;
private MenuItem proxyItem; private MenuItem proxyItem;
private MenuItem hotKeyItem; private MenuItem hotKeyItem;
private MenuItem VerboseLoggingToggleItem; private MenuItem VerboseLoggingToggleItem;
@@ -284,7 +283,6 @@ namespace Shadowsocks.View
CreateMenuItem("Check for Updates...", new EventHandler(this.checkUpdatesItem_Click)), CreateMenuItem("Check for Updates...", new EventHandler(this.checkUpdatesItem_Click)),
new MenuItem("-"), new MenuItem("-"),
this.autoCheckUpdatesToggleItem = CreateMenuItem("Check for Updates at Startup", new EventHandler(this.autoCheckUpdatesToggleItem_Click)), this.autoCheckUpdatesToggleItem = CreateMenuItem("Check for Updates at Startup", new EventHandler(this.autoCheckUpdatesToggleItem_Click)),
this.checkPreReleaseToggleItem = CreateMenuItem("Check Pre-release Version", new EventHandler(this.checkPreReleaseToggleItem_Click)),
}), }),
CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)), CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)),
new MenuItem("-"), new MenuItem("-"),
@@ -354,7 +352,7 @@ namespace Shadowsocks.View
{ {
if (updateChecker.NewVersionFound) if (updateChecker.NewVersionFound)
{ {
ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000);
} }
else if (!_isStartupChecking) else if (!_isStartupChecking)
{ {
@@ -818,7 +816,6 @@ namespace Shadowsocks.View
{ {
Configuration configuration = controller.GetConfigurationCopy(); Configuration configuration = controller.GetConfigurationCopy();
autoCheckUpdatesToggleItem.Checked = configuration.autoCheckUpdate; autoCheckUpdatesToggleItem.Checked = configuration.autoCheckUpdate;
checkPreReleaseToggleItem.Checked = configuration.checkPreRelease;
} }
private void autoCheckUpdatesToggleItem_Click(object sender, EventArgs e) private void autoCheckUpdatesToggleItem_Click(object sender, EventArgs e)
@@ -828,13 +825,6 @@ namespace Shadowsocks.View
UpdateUpdateMenu(); UpdateUpdateMenu();
} }
private void checkPreReleaseToggleItem_Click(object sender, EventArgs e)
{
Configuration configuration = controller.GetConfigurationCopy();
controller.ToggleCheckingPreRelease(!configuration.checkPreRelease);
UpdateUpdateMenu();
}
private void checkUpdatesItem_Click(object sender, EventArgs e) private void checkUpdatesItem_Click(object sender, EventArgs e)
{ {
updateChecker.CheckUpdate(controller.GetConfigurationCopy()); updateChecker.CheckUpdate(controller.GetConfigurationCopy());
+23 -6
View File
@@ -23,6 +23,8 @@
<OldToolsVersion>3.5</OldToolsVersion> <OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile> <TargetFrameworkProfile>
</TargetFrameworkProfile> </TargetFrameworkProfile>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<PublishUrl>publish\</PublishUrl> <PublishUrl>publish\</PublishUrl>
<Install>true</Install> <Install>true</Install>
<InstallFrom>Disk</InstallFrom> <InstallFrom>Disk</InstallFrom>
@@ -37,8 +39,6 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion> <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust> <UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled> <BootstrapperEnabled>true</BootstrapperEnabled>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -65,6 +65,25 @@
<PropertyGroup> <PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;_X64</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;_X64</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>3rd\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath> <HintPath>3rd\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath>
@@ -81,7 +100,6 @@
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Management" /> <Reference Include="System.Management" />
<Reference Include="System.Net" /> <Reference Include="System.Net" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Forms.DataVisualization" /> <Reference Include="System.Windows.Forms.DataVisualization" />
<Reference Include="System.XML" /> <Reference Include="System.XML" />
@@ -140,7 +158,6 @@
<Compile Include="3rd\zxing\ResultPoint.cs" /> <Compile Include="3rd\zxing\ResultPoint.cs" />
<Compile Include="3rd\zxing\ResultPointCallback.cs" /> <Compile Include="3rd\zxing\ResultPointCallback.cs" />
<Compile Include="3rd\zxing\WriterException.cs" /> <Compile Include="3rd\zxing\WriterException.cs" />
<Compile Include="Controller\System\Hotkeys\HotkeyCallbacks.cs" />
<Compile Include="Model\HotKeyConfig.cs" /> <Compile Include="Model\HotKeyConfig.cs" />
<Compile Include="Model\ProxyConfig.cs" /> <Compile Include="Model\ProxyConfig.cs" />
<Compile Include="Properties\Settings.Designer.cs"> <Compile Include="Properties\Settings.Designer.cs">
@@ -188,7 +205,7 @@
<Compile Include="Proxy\Socks5Proxy.cs" /> <Compile Include="Proxy\Socks5Proxy.cs" />
<Compile Include="Settings.cs" /> <Compile Include="Settings.cs" />
<Compile Include="StringEx.cs" /> <Compile Include="StringEx.cs" />
<Compile Include="Controller\System\Hotkeys\Hotkeys.cs" /> <Compile Include="Util\Hotkeys.cs" />
<Compile Include="Util\ProcessManagement\Job.cs" /> <Compile Include="Util\ProcessManagement\Job.cs" />
<Compile Include="Util\ProcessManagement\ThreadUtil.cs" /> <Compile Include="Util\ProcessManagement\ThreadUtil.cs" />
<Compile Include="Encryption\RNG.cs" /> <Compile Include="Encryption\RNG.cs" />
@@ -203,7 +220,6 @@
<Compile Include="Util\SystemProxy\RAS.cs" /> <Compile Include="Util\SystemProxy\RAS.cs" />
<Compile Include="Util\SystemProxy\WinINet.cs" /> <Compile Include="Util\SystemProxy\WinINet.cs" />
<Compile Include="Util\Util.cs" /> <Compile Include="Util\Util.cs" />
<Compile Include="Util\ViewUtils.cs" />
<Compile Include="View\ConfigForm.cs"> <Compile Include="View\ConfigForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@@ -289,6 +305,7 @@
</None> </None>
<None Include="Data\abp.js.gz" /> <None Include="Data\abp.js.gz" />
<None Include="Data\libsscrypto.dll.gz" /> <None Include="Data\libsscrypto.dll.gz" />
<None Include="Data\libsscrypto64.dll.gz" />
<None Include="Data\mgwz.dll.gz" /> <None Include="Data\mgwz.dll.gz" />
<None Include="Data\privoxy.exe.gz" /> <None Include="Data\privoxy.exe.gz" />
<None Include="Data\proxy.pac.txt.gz" /> <None Include="Data\proxy.pac.txt.gz" />
+11 -1
View File
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.24720.0 VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}"
EndProject EndProject
@@ -12,17 +12,27 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj",
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x64.ActiveCfg = Debug|x64
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x64.Build.0 = Debug|x64
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x64.ActiveCfg = Release|x64
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x64.Build.0 = Release|x64
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x64.ActiveCfg = Debug|x64
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x64.Build.0 = Debug|x64
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x64.ActiveCfg = Release|x64
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x64.Build.0 = Release|x64
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
+1 -1
View File
@@ -2,11 +2,11 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shadowsocks.Controller; using Shadowsocks.Controller;
using Shadowsocks.Encryption; using Shadowsocks.Encryption;
using Shadowsocks.Util;
using GlobalHotKey; using GlobalHotKey;
using System.Windows.Input; using System.Windows.Input;
using System.Threading; using System.Threading;
using System.Collections.Generic; using System.Collections.Generic;
using Shadowsocks.Controller.Hotkeys;
namespace test namespace test
{ {
+14
View File
@@ -34,6 +34,20 @@
<PropertyGroup> <PropertyGroup>
<StartupObject /> <StartupObject />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\shadowsocks-csharp\3rd\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath> <HintPath>..\shadowsocks-csharp\3rd\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath>