diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index 70720fb9..dc8d692c 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -36,6 +36,7 @@ namespace Shadowsocks.Controller { try { + File.WriteAllText(Utils.GetTempPath() + "\\gfwlist.txt", e.Result, Encoding.UTF8); List lines = ParseResult(e.Result); if (File.Exists(USER_RULE_FILE)) { @@ -82,7 +83,7 @@ namespace Shadowsocks.Controller http.DownloadStringAsync(new Uri(GFWLIST_URL)); } - public List ParseResult(string response) + public static List ParseResult(string response) { byte[] bytes = Convert.FromBase64String(response); string content = Encoding.ASCII.GetString(bytes); diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs index f8fc80e8..52ea241d 100644 --- a/shadowsocks-csharp/Controller/Service/PACServer.cs +++ b/shadowsocks-csharp/Controller/Service/PACServer.cs @@ -18,14 +18,17 @@ namespace Shadowsocks.Controller public static string USER_RULE_FILE = "user-rule.txt"; - FileSystemWatcher watcher; + FileSystemWatcher PACFileWatcher; + FileSystemWatcher UserRuleFileWatcher; private Configuration _config; public event EventHandler PACFileChanged; + public event EventHandler UserRuleFileChanged; public PACServer() { this.WatchPacFile(); + this.WatchUserRuleFile(); } public void UpdateConfiguration(Configuration config) @@ -167,28 +170,54 @@ Connection: Close private void WatchPacFile() { - if (watcher != null) - { - watcher.Dispose(); - } - watcher = new FileSystemWatcher(Directory.GetCurrentDirectory()); - watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; - watcher.Filter = PAC_FILE; - watcher.Changed += Watcher_Changed; - watcher.Created += Watcher_Changed; - watcher.Deleted += Watcher_Changed; - watcher.Renamed += Watcher_Changed; - watcher.EnableRaisingEvents = true; + if (PACFileWatcher != null) + { + PACFileWatcher.Dispose(); + } + PACFileWatcher = new FileSystemWatcher(Directory.GetCurrentDirectory()); + PACFileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; + PACFileWatcher.Filter = PAC_FILE; + PACFileWatcher.Changed += PACFileWatcher_Changed; + PACFileWatcher.Created += PACFileWatcher_Changed; + PACFileWatcher.Deleted += PACFileWatcher_Changed; + PACFileWatcher.Renamed += PACFileWatcher_Changed; + PACFileWatcher.EnableRaisingEvents = true; + } + + private void WatchUserRuleFile() + { + if (UserRuleFileWatcher != null) + { + UserRuleFileWatcher.Dispose(); + } + UserRuleFileWatcher = new FileSystemWatcher(Directory.GetCurrentDirectory()); + UserRuleFileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; + UserRuleFileWatcher.Filter = USER_RULE_FILE; + UserRuleFileWatcher.Changed += UserRuleFileWatcher_Changed; + UserRuleFileWatcher.Created += UserRuleFileWatcher_Changed; + UserRuleFileWatcher.Deleted += UserRuleFileWatcher_Changed; + UserRuleFileWatcher.Renamed += UserRuleFileWatcher_Changed; + UserRuleFileWatcher.EnableRaisingEvents = true; } - private void Watcher_Changed(object sender, FileSystemEventArgs e) + private void PACFileWatcher_Changed(object sender, FileSystemEventArgs e) { if (PACFileChanged != null) { + Console.WriteLine("Detected: PAC file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower()); PACFileChanged(this, new EventArgs()); } } + private void UserRuleFileWatcher_Changed(object sender, FileSystemEventArgs e) + { + if (UserRuleFileChanged != null) + { + Console.WriteLine("Detected: User Rule file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower()); + UserRuleFileChanged(this, new EventArgs()); + } + } + private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint, bool useSocks) { //try diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 2e2f5528..87496199 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -7,6 +7,8 @@ using System.Threading; using System.Net.Sockets; using Shadowsocks.Controller.Strategy; using System.Net; +using Shadowsocks.Util; +using Shadowsocks.Properties; namespace Shadowsocks.Controller { @@ -293,6 +295,7 @@ namespace Shadowsocks.Controller { _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; + _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged; } _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) @@ -404,6 +407,46 @@ namespace Shadowsocks.Controller UpdatePACFromGFWListError(this, e); } + private void pacServer_UserRuleFileChanged(object sender, EventArgs e) + { + // TODO: this is a dirty hack. (from code GListUpdater.http_DownloadStringCompleted()) + + //UpdatePACFromGFWList(); // TODO: code like this temporary + //try + //{ + List lines = GFWListUpdater.ParseResult(File.ReadAllText(Utils.GetTempPath() + "\\gfwlist.txt")); + if (File.Exists(PACServer.USER_RULE_FILE)) + { + string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8); + string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string rule in rules) + { + 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(PACServer.PAC_FILE)) + { + string original = File.ReadAllText(PACServer.PAC_FILE, Encoding.UTF8); + if (original == abpContent) + { + return; + } + } + File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8); + //} + //catch (Exception ex) + //{ + // if (Error != null) + // { + // Error(this, new ErrorEventArgs(ex)); + // } + //} + } + private void StartReleasingMemory() { _ramThread = new Thread(new ThreadStart(ReleaseMemory));