You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

GfwListUpdater.cs 4.1 kB

10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using System.Text;
  6. using Newtonsoft.Json;
  7. using Shadowsocks.Model;
  8. using Shadowsocks.Properties;
  9. using Shadowsocks.Util;
  10. namespace Shadowsocks.Controller
  11. {
  12. public class GFWListUpdater
  13. {
  14. private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";
  15. public event EventHandler<ResultEventArgs> UpdateCompleted;
  16. public event ErrorEventHandler Error;
  17. public class ResultEventArgs : EventArgs
  18. {
  19. public bool Success;
  20. public ResultEventArgs(bool success)
  21. {
  22. this.Success = success;
  23. }
  24. }
  25. private static readonly IEnumerable<char> IgnoredLineBegins = new[] { '!', '[' };
  26. private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
  27. {
  28. try
  29. {
  30. File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8);
  31. List<string> lines = ParseResult(e.Result);
  32. if (File.Exists(PACServer.USER_RULE_FILE))
  33. {
  34. string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8);
  35. using (var sr = new StringReader(local))
  36. {
  37. foreach (var rule in sr.NonWhiteSpaceLines())
  38. {
  39. if (rule.BeginWithAny(IgnoredLineBegins))
  40. continue;
  41. lines.Add(rule);
  42. }
  43. }
  44. }
  45. string abpContent;
  46. if (File.Exists(PACServer.USER_ABP_FILE))
  47. {
  48. abpContent = File.ReadAllText(PACServer.USER_ABP_FILE, Encoding.UTF8);
  49. }
  50. else
  51. {
  52. abpContent = Utils.UnGzip(Resources.abp_js);
  53. }
  54. abpContent = abpContent.Replace("__RULES__", JsonConvert.SerializeObject(lines, Formatting.Indented));
  55. if (File.Exists(PACServer.PAC_FILE))
  56. {
  57. string original = File.ReadAllText(PACServer.PAC_FILE, Encoding.UTF8);
  58. if (original == abpContent)
  59. {
  60. UpdateCompleted(this, new ResultEventArgs(false));
  61. return;
  62. }
  63. }
  64. File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8);
  65. if (UpdateCompleted != null)
  66. {
  67. UpdateCompleted(this, new ResultEventArgs(true));
  68. }
  69. }
  70. catch (Exception ex)
  71. {
  72. if (Error != null)
  73. {
  74. Error(this, new ErrorEventArgs(ex));
  75. }
  76. }
  77. }
  78. public void UpdatePACFromGFWList(Configuration config)
  79. {
  80. WebClient http = new WebClient();
  81. http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
  82. http.DownloadStringCompleted += http_DownloadStringCompleted;
  83. http.DownloadStringAsync(new Uri(GFWLIST_URL));
  84. }
  85. public static List<string> ParseResult(string response)
  86. {
  87. byte[] bytes = Convert.FromBase64String(response);
  88. string content = Encoding.ASCII.GetString(bytes);
  89. List<string> valid_lines = new List<string>();
  90. using (var sr = new StringReader(content))
  91. {
  92. foreach (var line in sr.NonWhiteSpaceLines())
  93. {
  94. if (line.BeginWithAny(IgnoredLineBegins))
  95. continue;
  96. valid_lines.Add(line);
  97. }
  98. }
  99. return valid_lines;
  100. }
  101. }
  102. }