Conflicts: shadowsocks-csharp/Data/cn.txtpull/76/head
@@ -30,6 +30,10 @@ about the change automatically | |||||
6. Please disable other proxy addons in your browser, or set them to use | 6. Please disable other proxy addons in your browser, or set them to use | ||||
system proxy | system proxy | ||||
### Develop | |||||
Visual Studio Express 2012 is recommended. | |||||
#### License | #### License | ||||
GPLv3 | GPLv3 | ||||
@@ -1035,13 +1035,13 @@ namespace SimpleJson | |||||
protected static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) | protected static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) | ||||
{ | { | ||||
builder.Append("["); | |||||
builder.Append("[\r\n "); | |||||
bool first = true; | bool first = true; | ||||
foreach (object value in anArray) | foreach (object value in anArray) | ||||
{ | { | ||||
if (!first) | if (!first) | ||||
builder.Append(","); | |||||
builder.Append(",\r\n "); | |||||
if (!SerializeValue(jsonSerializerStrategy, value, builder)) | if (!SerializeValue(jsonSerializerStrategy, value, builder)) | ||||
return false; | return false; | ||||
@@ -1049,7 +1049,7 @@ namespace SimpleJson | |||||
first = false; | first = false; | ||||
} | } | ||||
builder.Append("]"); | |||||
builder.Append("\r\n]"); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -0,0 +1,68 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Net; | |||||
using System.IO; | |||||
using Shadowsocks.Properties; | |||||
using SimpleJson; | |||||
using Shadowsocks.Util; | |||||
namespace Shadowsocks.Controller | |||||
{ | |||||
public class GFWListUpdater | |||||
{ | |||||
private const string GFWLIST_URL = "https://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt"; | |||||
private static string PAC_FILE = PACServer.PAC_FILE; | |||||
public event EventHandler UpdateCompleted; | |||||
public event ErrorEventHandler Error; | |||||
private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) | |||||
{ | |||||
try | |||||
{ | |||||
List<string> lines = ParseResult(e.Result); | |||||
string abpContent = Utils.UnGzip(Resources.abp_js); | |||||
abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines)); | |||||
File.WriteAllText(PAC_FILE, abpContent, Encoding.UTF8); | |||||
if (UpdateCompleted != null) | |||||
{ | |||||
UpdateCompleted(this, new EventArgs()); | |||||
} | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
if (Error != null) | |||||
{ | |||||
Error(this, new ErrorEventArgs(ex)); | |||||
} | |||||
} | |||||
} | |||||
public void UpdatePACFromGFWList() | |||||
{ | |||||
WebClient http = new WebClient(); | |||||
http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), 8123); | |||||
http.DownloadStringCompleted += http_DownloadStringCompleted; | |||||
http.DownloadStringAsync(new Uri(GFWLIST_URL)); | |||||
} | |||||
public List<string> ParseResult(string response) | |||||
{ | |||||
byte[] bytes = Convert.FromBase64String(response); | |||||
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) | |||||
{ | |||||
if (line.StartsWith("!") || line.StartsWith("[")) | |||||
continue; | |||||
valid_lines.Add(line); | |||||
} | |||||
return valid_lines; | |||||
} | |||||
} | |||||
} |
@@ -17,8 +17,7 @@ namespace Shadowsocks.Controller | |||||
string temppath = Path.GetTempPath(); | string temppath = Path.GetTempPath(); | ||||
LogFile = Path.Combine(temppath, "shadowsocks.log"); | LogFile = Path.Combine(temppath, "shadowsocks.log"); | ||||
FileStream fs = new FileStream(LogFile, FileMode.Append); | FileStream fs = new FileStream(LogFile, FileMode.Append); | ||||
TextWriter tmp = Console.Out; | |||||
StreamWriter sw = new StreamWriter(fs); | |||||
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); | |||||
sw.AutoFlush = true; | sw.AutoFlush = true; | ||||
Console.SetOut(sw); | Console.SetOut(sw); | ||||
Console.SetError(sw); | Console.SetError(sw); | ||||
@@ -61,5 +60,30 @@ namespace Shadowsocks.Controller | |||||
Console.WriteLine(e); | Console.WriteLine(e); | ||||
} | } | ||||
} | } | ||||
} | |||||
// Simply extended System.IO.StreamWriter for adding timestamp workaround | |||||
public class StreamWriterWithTimestamp : StreamWriter | |||||
{ | |||||
public StreamWriterWithTimestamp(Stream stream) : base(stream) | |||||
{ | |||||
} | |||||
private string GetTimestamp() | |||||
{ | |||||
return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] "; | |||||
} | |||||
public override void WriteLine(string value) | |||||
{ | |||||
base.WriteLine(GetTimestamp() + value); | |||||
} | |||||
public override void Write(string value) | |||||
{ | |||||
base.Write(GetTimestamp() + value); | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,5 +1,6 @@ | |||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Properties; | using Shadowsocks.Properties; | ||||
using Shadowsocks.Util; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Diagnostics; | using System.Diagnostics; | ||||
@@ -14,7 +15,7 @@ namespace Shadowsocks.Controller | |||||
class PACServer | class PACServer | ||||
{ | { | ||||
private static int PORT = 8093; | private static int PORT = 8093; | ||||
private static string PAC_FILE = "pac.txt"; | |||||
public static string PAC_FILE = "pac.txt"; | |||||
private static Configuration config; | private static Configuration config; | ||||
Socket _listener; | Socket _listener; | ||||
@@ -130,19 +131,7 @@ namespace Shadowsocks.Controller | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
byte[] pacGZ = Resources.proxy_pac_txt; | |||||
byte[] buffer = new byte[1024]; // builtin pac gzip size: maximum 100K | |||||
MemoryStream sb = new MemoryStream(); | |||||
int n; | |||||
using (GZipStream input = new GZipStream(new MemoryStream(pacGZ), | |||||
CompressionMode.Decompress, false)) | |||||
{ | |||||
while((n = input.Read(buffer, 0, buffer.Length)) > 0) | |||||
{ | |||||
sb.Write(buffer, 0, n); | |||||
} | |||||
return System.Text.Encoding.UTF8.GetString(sb.ToArray()); | |||||
} | |||||
return Utils.UnGzip(Resources.proxy_pac_txt); | |||||
} | } | ||||
} | } | ||||
@@ -175,7 +164,7 @@ Connection: Close | |||||
", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac; | ", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac; | ||||
byte[] response = System.Text.Encoding.UTF8.GetBytes(text); | byte[] response = System.Text.Encoding.UTF8.GetBytes(text); | ||||
conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), conn); | conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), conn); | ||||
Util.Util.ReleaseMemory(); | |||||
Util.Utils.ReleaseMemory(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -21,6 +21,7 @@ namespace Shadowsocks.Controller | |||||
private PACServer pacServer; | private PACServer pacServer; | ||||
private Configuration _config; | private Configuration _config; | ||||
private PolipoRunner polipoRunner; | private PolipoRunner polipoRunner; | ||||
private GFWListUpdater gfwListUpdater; | |||||
private bool stopped = false; | private bool stopped = false; | ||||
private bool _systemProxyIsDirty = false; | private bool _systemProxyIsDirty = false; | ||||
@@ -38,6 +39,10 @@ namespace Shadowsocks.Controller | |||||
// when user clicked Edit PAC, and PAC file has already created | // when user clicked Edit PAC, and PAC file has already created | ||||
public event EventHandler<PathEventArgs> PACFileReadyToOpen; | public event EventHandler<PathEventArgs> PACFileReadyToOpen; | ||||
public event EventHandler UpdatePACFromGFWListCompleted; | |||||
public event ErrorEventHandler UpdatePACFromGFWListError; | |||||
public event ErrorEventHandler Errored; | public event ErrorEventHandler Errored; | ||||
public ShadowsocksController() | public ShadowsocksController() | ||||
@@ -151,6 +156,14 @@ namespace Shadowsocks.Controller | |||||
return "ss://" + base64; | return "ss://" + base64; | ||||
} | } | ||||
public void UpdatePACFromGFWList() | |||||
{ | |||||
if (gfwListUpdater != null) | |||||
{ | |||||
gfwListUpdater.UpdatePACFromGFWList(); | |||||
} | |||||
} | |||||
protected void Reload() | protected void Reload() | ||||
{ | { | ||||
// some logic in configuration updated the config when saving, we need to read it again | // some logic in configuration updated the config when saving, we need to read it again | ||||
@@ -165,6 +178,12 @@ namespace Shadowsocks.Controller | |||||
pacServer = new PACServer(); | pacServer = new PACServer(); | ||||
pacServer.PACFileChanged += pacServer_PACFileChanged; | pacServer.PACFileChanged += pacServer_PACFileChanged; | ||||
} | } | ||||
if (gfwListUpdater == null) | |||||
{ | |||||
gfwListUpdater = new GFWListUpdater(); | |||||
gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; | |||||
gfwListUpdater.Error += pacServer_PACUpdateError; | |||||
} | |||||
pacServer.Stop(); | pacServer.Stop(); | ||||
@@ -208,7 +227,7 @@ namespace Shadowsocks.Controller | |||||
} | } | ||||
UpdateSystemProxy(); | UpdateSystemProxy(); | ||||
Util.Util.ReleaseMemory(); | |||||
Util.Utils.ReleaseMemory(); | |||||
} | } | ||||
@@ -242,6 +261,18 @@ namespace Shadowsocks.Controller | |||||
UpdateSystemProxy(); | UpdateSystemProxy(); | ||||
} | } | ||||
private void pacServer_PACUpdateCompleted(object sender, EventArgs e) | |||||
{ | |||||
if (UpdatePACFromGFWListCompleted != null) | |||||
UpdatePACFromGFWListCompleted(this, e); | |||||
} | |||||
private void pacServer_PACUpdateError(object sender, ErrorEventArgs e) | |||||
{ | |||||
if (UpdatePACFromGFWListError != null) | |||||
UpdatePACFromGFWListError(this, e); | |||||
} | |||||
private void StartReleasingMemory() | private void StartReleasingMemory() | ||||
{ | { | ||||
_ramThread = new Thread(new ThreadStart(ReleaseMemory)); | _ramThread = new Thread(new ThreadStart(ReleaseMemory)); | ||||
@@ -253,7 +284,7 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
while (true) | while (true) | ||||
{ | { | ||||
Util.Util.ReleaseMemory(); | |||||
Util.Utils.ReleaseMemory(); | |||||
Thread.Sleep(30 * 1000); | Thread.Sleep(30 * 1000); | ||||
} | } | ||||
} | } | ||||
@@ -23,6 +23,7 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
// TODO test failures | // TODO test failures | ||||
WebClient http = new WebClient(); | WebClient http = new WebClient(); | ||||
http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), 8123); | |||||
http.DownloadStringCompleted += http_DownloadStringCompleted; | http.DownloadStringCompleted += http_DownloadStringCompleted; | ||||
http.DownloadStringAsync(new Uri(UpdateURL)); | http.DownloadStringAsync(new Uri(UpdateURL)); | ||||
} | } | ||||
@@ -145,7 +146,7 @@ namespace Shadowsocks.Controller | |||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
Console.Write(ex.ToString()); | |||||
Console.WriteLine(ex.ToString()); | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
@@ -4,8 +4,8 @@ Mode=代理模式 | |||||
PAC=PAC 模式 | PAC=PAC 模式 | ||||
Global=全局模式 | Global=全局模式 | ||||
Servers=服务器选择 | Servers=服务器选择 | ||||
Edit Servers...=编辑Shadowsocks服务器... | |||||
Start on Boot=开机启动 | |||||
Edit Servers...=编辑Shadowsocks服务器... | |||||
Start on Boot=开机启动 | |||||
Share over LAN=在局域网共享代理 | Share over LAN=在局域网共享代理 | ||||
Edit PAC File...=编辑 PAC 文件... | Edit PAC File...=编辑 PAC 文件... | ||||
Show QRCode...=显示二维码... | Show QRCode...=显示二维码... | ||||
@@ -39,6 +39,9 @@ Shadowsocks is here=Shadowsocks 在这里 | |||||
You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks | You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks | ||||
Enabled=已启用代理 | Enabled=已启用代理 | ||||
Disabled=已禁用代理 | Disabled=已禁用代理 | ||||
Update PAC from GFWList=从 GFWList 更新 PAC | |||||
Failed to update PAC file =更新 PAC 文件失败 | |||||
PAC updated=更新 PAC 成功 | |||||
&Parse=解析(&P) | &Parse=解析(&P) | ||||
Shadowsocks URI=Shadowsocks URI | Shadowsocks URI=Shadowsocks URI | ||||
Shadowsocks URI Parse=Shadowsocks URI解析 | Shadowsocks URI Parse=Shadowsocks URI解析 | ||||
@@ -18,7 +18,7 @@ namespace Shadowsocks | |||||
[STAThread] | [STAThread] | ||||
static void Main() | static void Main() | ||||
{ | { | ||||
Util.Util.ReleaseMemory(); | |||||
Util.Utils.ReleaseMemory(); | |||||
using (Mutex mutex = new Mutex(false, "Global\\" + "71981632-A427-497F-AB91-241CD227EC1F")) | using (Mutex mutex = new Mutex(false, "Global\\" + "71981632-A427-497F-AB91-241CD227EC1F")) | ||||
{ | { | ||||
Application.EnableVisualStyles(); | Application.EnableVisualStyles(); | ||||
@@ -61,6 +61,16 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized resource of type System.Byte[]. | |||||
/// </summary> | |||||
internal static byte[] abp_js { | |||||
get { | |||||
object obj = ResourceManager.GetObject("abp_js", resourceCulture); | |||||
return ((byte[])(obj)); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Looks up a localized string similar to Shadowsocks=Shadowsocks | /// Looks up a localized string similar to Shadowsocks=Shadowsocks | ||||
///Enable=启用代理 | ///Enable=启用代理 | ||||
///Mode=代理模式 | ///Mode=代理模式 | ||||
@@ -68,7 +78,7 @@ namespace Shadowsocks.Properties { | |||||
///Global=全局模式 | ///Global=全局模式 | ||||
///Servers=服务器选择 | ///Servers=服务器选择 | ||||
///Edit Servers...=编辑服务器... | ///Edit Servers...=编辑服务器... | ||||
///Start on Boot=自动启动 | |||||
///Start on Boot=开机启动 | |||||
///Share over LAN=在局域网共享代理 | ///Share over LAN=在局域网共享代理 | ||||
///Edit PAC File...=编辑 PAC 文件... | ///Edit PAC File...=编辑 PAC 文件... | ||||
///Show QRCode...=显示二维码... | ///Show QRCode...=显示二维码... | ||||
@@ -118,6 +118,9 @@ | |||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | ||||
</resheader> | </resheader> | ||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | ||||
<data name="abp_js" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||||
<value>..\Data\abp.js.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</data> | |||||
<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> | ||||
@@ -1,12 +1,14 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Diagnostics; | using System.Diagnostics; | ||||
using System.IO; | |||||
using System.IO.Compression; | |||||
using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
using System.Text; | using System.Text; | ||||
namespace Shadowsocks.Util | namespace Shadowsocks.Util | ||||
{ | { | ||||
public class Util | |||||
public class Utils | |||||
{ | { | ||||
public static void ReleaseMemory() | public static void ReleaseMemory() | ||||
{ | { | ||||
@@ -22,6 +24,24 @@ namespace Shadowsocks.Util | |||||
(UIntPtr)0xFFFFFFFF, (UIntPtr)0xFFFFFFFF); | (UIntPtr)0xFFFFFFFF, (UIntPtr)0xFFFFFFFF); | ||||
} | } | ||||
public static string UnGzip(byte[] buf) | |||||
{ | |||||
byte[] buffer = new byte[1024]; | |||||
int n; | |||||
using (MemoryStream sb = new MemoryStream()) | |||||
{ | |||||
using (GZipStream input = new GZipStream(new MemoryStream(buf), | |||||
CompressionMode.Decompress, false)) | |||||
{ | |||||
while ((n = input.Read(buffer, 0, buffer.Length)) > 0) | |||||
{ | |||||
sb.Write(buffer, 0, n); | |||||
} | |||||
} | |||||
return System.Text.Encoding.UTF8.GetString(sb.ToArray()); | |||||
} | |||||
} | |||||
[DllImport("kernel32.dll")] | [DllImport("kernel32.dll")] | ||||
[return: MarshalAs(UnmanagedType.Bool)] | [return: MarshalAs(UnmanagedType.Bool)] | ||||
private static extern bool SetProcessWorkingSetSize(IntPtr process, | private static extern bool SetProcessWorkingSetSize(IntPtr process, | ||||
@@ -45,6 +45,8 @@ namespace Shadowsocks.View | |||||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | ||||
controller.EnableGlobalChanged += controller_EnableGlobalChanged; | controller.EnableGlobalChanged += controller_EnableGlobalChanged; | ||||
controller.Errored += controller_Errored; | controller.Errored += controller_Errored; | ||||
controller.UpdatePACFromGFWListCompleted += controller_UpdatePACFromGFWListCompleted; | |||||
controller.UpdatePACFromGFWListError += controller_UpdatePACFromGFWListError; | |||||
_notifyIcon = new NotifyIcon(); | _notifyIcon = new NotifyIcon(); | ||||
UpdateTrayIcon(); | UpdateTrayIcon(); | ||||
@@ -138,6 +140,7 @@ namespace Shadowsocks.View | |||||
this.AutoStartupItem = CreateMenuItem("Start on Boot", new EventHandler(this.AutoStartupItem_Click)), | this.AutoStartupItem = CreateMenuItem("Start on Boot", new EventHandler(this.AutoStartupItem_Click)), | ||||
this.ShareOverLANItem = CreateMenuItem("Share over LAN", new EventHandler(this.ShareOverLANItem_Click)), | this.ShareOverLANItem = CreateMenuItem("Share over LAN", new EventHandler(this.ShareOverLANItem_Click)), | ||||
CreateMenuItem("Edit PAC File...", new EventHandler(this.EditPACFileItem_Click)), | CreateMenuItem("Edit PAC File...", new EventHandler(this.EditPACFileItem_Click)), | ||||
CreateMenuItem("Update PAC from GFWList", new EventHandler(this.UpdatePACFromGFWListItem_Click)), | |||||
new MenuItem("-"), | new MenuItem("-"), | ||||
CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)), | CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)), | ||||
CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), | CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), | ||||
@@ -176,19 +179,36 @@ namespace Shadowsocks.View | |||||
System.Diagnostics.Process.Start("explorer.exe", argument); | System.Diagnostics.Process.Start("explorer.exe", argument); | ||||
} | } | ||||
void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) | |||||
{ | |||||
_notifyIcon.BalloonTipTitle = title; | |||||
_notifyIcon.BalloonTipText = content; | |||||
_notifyIcon.BalloonTipIcon = icon; | |||||
_notifyIcon.ShowBalloonTip(timeout); | |||||
} | |||||
void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e) | |||||
{ | |||||
ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); | |||||
Logging.LogUsefulException(e.GetException()); | |||||
} | |||||
void controller_UpdatePACFromGFWListCompleted(object sender, EventArgs e) | |||||
{ | |||||
ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("PAC updated"), ToolTipIcon.Info, 1000); | |||||
} | |||||
void updateChecker_NewVersionFound(object sender, EventArgs e) | void updateChecker_NewVersionFound(object sender, EventArgs e) | ||||
{ | { | ||||
_notifyIcon.BalloonTipTitle = String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber); | |||||
_notifyIcon.BalloonTipText = I18N.GetString("Click here to download"); | |||||
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; | |||||
ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to download"), ToolTipIcon.Info, 5000); | |||||
_notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | ||||
_notifyIcon.ShowBalloonTip(5000); | |||||
_isFirstRun = false; | _isFirstRun = false; | ||||
} | } | ||||
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | ||||
{ | { | ||||
System.Diagnostics.Process.Start(updateChecker.LatestVersionURL); | System.Diagnostics.Process.Start(updateChecker.LatestVersionURL); | ||||
_notifyIcon.BalloonTipClicked -= notifyIcon1_BalloonTipClicked; | |||||
} | } | ||||
@@ -245,7 +265,7 @@ namespace Shadowsocks.View | |||||
void configForm_FormClosed(object sender, FormClosedEventArgs e) | void configForm_FormClosed(object sender, FormClosedEventArgs e) | ||||
{ | { | ||||
configForm = null; | configForm = null; | ||||
Util.Util.ReleaseMemory(); | |||||
Util.Utils.ReleaseMemory(); | |||||
ShowFirstTimeBalloon(); | ShowFirstTimeBalloon(); | ||||
} | } | ||||
@@ -312,6 +332,11 @@ namespace Shadowsocks.View | |||||
controller.TouchPACFile(); | controller.TouchPACFile(); | ||||
} | } | ||||
private void UpdatePACFromGFWListItem_Click(object sender, EventArgs e) | |||||
{ | |||||
controller.UpdatePACFromGFWList(); | |||||
} | |||||
private void AServerItem_Click(object sender, EventArgs e) | private void AServerItem_Click(object sender, EventArgs e) | ||||
{ | { | ||||
MenuItem item = (MenuItem)sender; | MenuItem item = (MenuItem)sender; | ||||
@@ -86,6 +86,7 @@ | |||||
<Compile Include="3rd\zxing\Version.cs" /> | <Compile Include="3rd\zxing\Version.cs" /> | ||||
<Compile Include="Controller\AutoStartup.cs" /> | <Compile Include="Controller\AutoStartup.cs" /> | ||||
<Compile Include="Controller\FileManager.cs" /> | <Compile Include="Controller\FileManager.cs" /> | ||||
<Compile Include="Controller\GFWListUpdater.cs" /> | |||||
<Compile Include="Controller\I18N.cs" /> | <Compile Include="Controller\I18N.cs" /> | ||||
<Compile Include="Controller\Logging.cs" /> | <Compile Include="Controller\Logging.cs" /> | ||||
<Compile Include="Controller\UpdateChecker.cs" /> | <Compile Include="Controller\UpdateChecker.cs" /> | ||||
@@ -101,6 +102,11 @@ | |||||
<Compile Include="Controller\PACServer.cs" /> | <Compile Include="Controller\PACServer.cs" /> | ||||
<Compile Include="Model\Server.cs" /> | <Compile Include="Model\Server.cs" /> | ||||
<Compile Include="Model\Configuration.cs" /> | <Compile Include="Model\Configuration.cs" /> | ||||
<Compile Include="Properties\Resources.Designer.cs"> | |||||
<AutoGen>True</AutoGen> | |||||
<DesignTime>True</DesignTime> | |||||
<DependentUpon>Resources.resx</DependentUpon> | |||||
</Compile> | |||||
<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> | ||||
@@ -133,14 +139,9 @@ | |||||
</EmbeddedResource> | </EmbeddedResource> | ||||
<EmbeddedResource Include="Properties\Resources.resx"> | <EmbeddedResource Include="Properties\Resources.resx"> | ||||
<Generator>ResXFileCodeGenerator</Generator> | <Generator>ResXFileCodeGenerator</Generator> | ||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||||
<SubType>Designer</SubType> | <SubType>Designer</SubType> | ||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||||
</EmbeddedResource> | </EmbeddedResource> | ||||
<Compile Include="Properties\Resources.Designer.cs"> | |||||
<AutoGen>True</AutoGen> | |||||
<DependentUpon>Resources.resx</DependentUpon> | |||||
<DesignTime>True</DesignTime> | |||||
</Compile> | |||||
<EmbeddedResource Include="View\QRCodeForm.resx"> | <EmbeddedResource Include="View\QRCodeForm.resx"> | ||||
<DependentUpon>QRCodeForm.cs</DependentUpon> | <DependentUpon>QRCodeForm.cs</DependentUpon> | ||||
</EmbeddedResource> | </EmbeddedResource> | ||||
@@ -151,6 +152,7 @@ | |||||
<None Include="app.manifest"> | <None Include="app.manifest"> | ||||
<SubType>Designer</SubType> | <SubType>Designer</SubType> | ||||
</None> | </None> | ||||
<None Include="Data\abp.js.gz" /> | |||||
<None Include="Data\libsscrypto.dll.gz" /> | <None Include="Data\libsscrypto.dll.gz" /> | ||||
<None Include="Data\polipo.exe.gz" /> | <None Include="Data\polipo.exe.gz" /> | ||||
<None Include="Data\proxy.pac.txt.gz" /> | <None Include="Data\proxy.pac.txt.gz" /> | ||||