diff --git a/shadowsocks-csharp/Controller/GfwListUpdater.cs b/shadowsocks-csharp/Controller/GfwListUpdater.cs index 4cf77293..070c2b4e 100644 --- a/shadowsocks-csharp/Controller/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/GfwListUpdater.cs @@ -1,88 +1,100 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Net; -using System.IO; -using Shadowsocks.Properties; -using SimpleJson; -using Shadowsocks.Util; -using Shadowsocks.Model; - -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; - - public class ResultEventArgs : EventArgs - { - public bool Success; - - public ResultEventArgs(bool success) - { - this.Success = success; - } - } - - private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) - { - try - { - List lines = ParseResult(e.Result); - - string abpContent = Utils.UnGzip(Resources.abp_js); - abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines)); - if (File.Exists(PAC_FILE)) - { - string original = File.ReadAllText(PAC_FILE, Encoding.UTF8); - if (original == abpContent) - { - UpdateCompleted(this, new ResultEventArgs(false)); - return; - } - } - File.WriteAllText(PAC_FILE, abpContent, Encoding.UTF8); - if (UpdateCompleted != null) - { - UpdateCompleted(this, new ResultEventArgs(true)); - } - } - catch (Exception ex) - { - if (Error != null) - { - Error(this, new ErrorEventArgs(ex)); - } - } - } - - public void UpdatePACFromGFWList(Configuration config) - { - WebClient http = new WebClient(); - http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); - http.DownloadStringCompleted += http_DownloadStringCompleted; - http.DownloadStringAsync(new Uri(GFWLIST_URL)); - } - - public List 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 valid_lines = new List(lines.Length); - foreach (string line in lines) - { - if (line.StartsWith("!") || line.StartsWith("[")) - continue; - valid_lines.Add(line); - } - return valid_lines; - } - } +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.IO; +using Shadowsocks.Properties; +using SimpleJson; +using Shadowsocks.Util; +using Shadowsocks.Model; + +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; + + private static string USER_RULE_FILE = PACServer.USER_RULE_FILE; + + public event EventHandler UpdateCompleted; + + public event ErrorEventHandler Error; + + public class ResultEventArgs : EventArgs + { + public bool Success; + + public ResultEventArgs(bool success) + { + this.Success = success; + } + } + + private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) + { + try + { + List lines = ParseResult(e.Result); + if (File.Exists(USER_RULE_FILE)) + { + string local = File.ReadAllText(USER_RULE_FILE, Encoding.UTF8); + string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + foreach(string rule in rules) + { + if (rule.StartsWith("!") || rule.StartsWith("[")) + continue; + lines.Add(rule); + } + } + string abpContent = Utils.UnGzip(Resources.abp_js); + abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines)); + if (File.Exists(PAC_FILE)) + { + string original = File.ReadAllText(PAC_FILE, Encoding.UTF8); + if (original == abpContent) + { + UpdateCompleted(this, new ResultEventArgs(false)); + return; + } + } + File.WriteAllText(PAC_FILE, abpContent, Encoding.UTF8); + if (UpdateCompleted != null) + { + UpdateCompleted(this, new ResultEventArgs(true)); + } + } + catch (Exception ex) + { + if (Error != null) + { + Error(this, new ErrorEventArgs(ex)); + } + } + } + + public void UpdatePACFromGFWList(Configuration config) + { + WebClient http = new WebClient(); + http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); + http.DownloadStringCompleted += http_DownloadStringCompleted; + http.DownloadStringAsync(new Uri(GFWLIST_URL)); + } + + public List 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 valid_lines = new List(lines.Length); + foreach (string line in lines) + { + if (line.StartsWith("!") || line.StartsWith("[")) + continue; + valid_lines.Add(line); + } + return valid_lines; + } + } } \ No newline at end of file diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index 9d5e345e..934a7855 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -16,6 +16,8 @@ namespace Shadowsocks.Controller { public static string PAC_FILE = "pac.txt"; + public static string USER_RULE_FILE = "user-rule.txt"; + FileSystemWatcher watcher; private Configuration _config;