diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index d3123e51..b3f00f5b 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -1,127 +1,129 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Text; - -using Newtonsoft.Json; - -using Shadowsocks.Model; -using Shadowsocks.Properties; -using Shadowsocks.Util; - -namespace Shadowsocks.Controller -{ - public class GFWListUpdater - { - private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"; - - public event EventHandler UpdateCompleted; - - public event ErrorEventHandler Error; - - public class ResultEventArgs : EventArgs - { - public bool Success; - - public ResultEventArgs(bool success) - { - this.Success = success; - } - } - - private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; - private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) - { - try - { - File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8); - bool pacFileChanged = MergeAndWritePACFile(e.Result); - UpdateCompleted?.Invoke(this, new ResultEventArgs(pacFileChanged)); - } - catch (Exception ex) - { - Error?.Invoke(this, new ErrorEventArgs(ex)); - } - } - - public static bool MergeAndWritePACFile(string gfwListResult) - { - string abpContent = MergePACFile(gfwListResult); - if (File.Exists(PACDaemon.PAC_FILE)) - { - string original = FileManager.NonExclusiveReadAllText(PACDaemon.PAC_FILE, Encoding.UTF8); - if (original == abpContent) - { - return false; - } - } - File.WriteAllText(PACDaemon.PAC_FILE, abpContent, Encoding.UTF8); - return true; - } - - private static string MergePACFile(string gfwListResult) - { - string abpContent; - if (File.Exists(PACDaemon.USER_ABP_FILE)) - { - abpContent = FileManager.NonExclusiveReadAllText(PACDaemon.USER_ABP_FILE, Encoding.UTF8); - } - else - { - abpContent = Resources.abp_js; - } - - List userruleLines = new List(); - if (File.Exists(PACDaemon.USER_RULE_FILE)) - { - string userrulesString = FileManager.NonExclusiveReadAllText(PACDaemon.USER_RULE_FILE, Encoding.UTF8); - userruleLines = ParseToValidList(userrulesString); - } - - List gfwLines = new List(); - gfwLines = ParseBase64ToValidList(gfwListResult); - abpContent = -$@"var __USERRULES__ = {JsonConvert.SerializeObject(userruleLines, Formatting.Indented)}; -var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)}; -{abpContent}"; - return abpContent; - } - - public void UpdatePACFromGFWList(Configuration config) - { - Logging.Info($"Checking GFWList from {GFWLIST_URL}"); - WebClient http = new WebClient(); - if (config.enabled) - { - http.Proxy = new WebProxy( - config.isIPv6Enabled ? IPAddress.IPv6Loopback.ToString() : IPAddress.Loopback.ToString(), - config.localPort); - } - http.DownloadStringCompleted += http_DownloadStringCompleted; - http.DownloadStringAsync(new Uri(GFWLIST_URL)); - } - - public static List ParseBase64ToValidList(string response) - { - byte[] bytes = Convert.FromBase64String(response); - string content = Encoding.ASCII.GetString(bytes); - return ParseToValidList(content); - } - - private static List ParseToValidList(string content) - { - List valid_lines = new List(); - using (var sr = new StringReader(content)) - { - foreach (var line in sr.NonWhiteSpaceLines()) - { - if (line.BeginWithAny(IgnoredLineBegins)) - continue; - valid_lines.Add(line); - } - } - return valid_lines; - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; + +using Newtonsoft.Json; + +using Shadowsocks.Model; +using Shadowsocks.Properties; +using Shadowsocks.Util; + +namespace Shadowsocks.Controller +{ + public class GFWListUpdater + { + private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"; + + public event EventHandler UpdateCompleted; + + public event ErrorEventHandler Error; + + public class ResultEventArgs : EventArgs + { + public bool Success; + + public ResultEventArgs(bool success) + { + this.Success = success; + } + } + + private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' }; + private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) + { + try + { + File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8); + bool pacFileChanged = MergeAndWritePACFile(e.Result); + UpdateCompleted?.Invoke(this, new ResultEventArgs(pacFileChanged)); + } + catch (Exception ex) + { + Error?.Invoke(this, new ErrorEventArgs(ex)); + } + } + + public static bool MergeAndWritePACFile(string gfwListResult) + { + string abpContent = MergePACFile(gfwListResult); + if (File.Exists(PACDaemon.PAC_FILE)) + { + string original = FileManager.NonExclusiveReadAllText(PACDaemon.PAC_FILE, Encoding.UTF8); + if (original == abpContent) + { + return false; + } + } + File.WriteAllText(PACDaemon.PAC_FILE, abpContent, Encoding.UTF8); + return true; + } + + private static string MergePACFile(string gfwListResult) + { + string abpContent; + if (File.Exists(PACDaemon.USER_ABP_FILE)) + { + abpContent = FileManager.NonExclusiveReadAllText(PACDaemon.USER_ABP_FILE, Encoding.UTF8); + } + else + { + abpContent = Resources.abp_js; + } + + List userruleLines = new List(); + if (File.Exists(PACDaemon.USER_RULE_FILE)) + { + string userrulesString = FileManager.NonExclusiveReadAllText(PACDaemon.USER_RULE_FILE, Encoding.UTF8); + userruleLines = ParseToValidList(userrulesString); + } + + List gfwLines = new List(); + gfwLines = ParseBase64ToValidList(gfwListResult); + abpContent = +$@"var __USERRULES__ = {JsonConvert.SerializeObject(userruleLines, Formatting.Indented)}; +var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)}; +{abpContent}"; + return abpContent; + } + + public void UpdatePACFromGFWList(Configuration config) + { + Logging.Info($"Checking GFWList from {GFWLIST_URL}"); + WebClient http = new WebClient(); + if (config.enabled) + { + http.Proxy = new WebProxy( + config.isIPv6Enabled + ? $"[{IPAddress.IPv6Loopback.ToString()}]" + : IPAddress.Loopback.ToString(), + config.localPort); + } + http.DownloadStringCompleted += http_DownloadStringCompleted; + http.DownloadStringAsync(new Uri(GFWLIST_URL)); + } + + public static List ParseBase64ToValidList(string response) + { + byte[] bytes = Convert.FromBase64String(response); + string content = Encoding.ASCII.GetString(bytes); + return ParseToValidList(content); + } + + private static List ParseToValidList(string content) + { + List valid_lines = new List(); + using (var sr = new StringReader(content)) + { + foreach (var line in sr.NonWhiteSpaceLines()) + { + if (line.BeginWithAny(IgnoredLineBegins)) + continue; + valid_lines.Add(line); + } + } + return valid_lines; + } + } +}