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.

OnlineConfigResolver.cs 2.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Threading.Tasks;
  7. using Newtonsoft.Json.Linq;
  8. using Shadowsocks.Model;
  9. namespace Shadowsocks.Controller.Service
  10. {
  11. public class OnlineConfigResolver
  12. {
  13. public static async Task<List<Server>> GetOnline(string url)
  14. {
  15. var httpClient = Program.MainController.GetHttpClient();
  16. string server_json = await httpClient.GetStringAsync(url);
  17. var servers = server_json.GetServers();
  18. foreach (var server in servers)
  19. {
  20. server.group = url;
  21. }
  22. return servers.ToList();
  23. }
  24. }
  25. internal static class OnlineConfigResolverEx
  26. {
  27. private static readonly string[] BASIC_FORMAT = new[] { "server", "server_port", "password", "method" };
  28. private static readonly IEnumerable<Server> EMPTY_SERVERS = Array.Empty<Server>();
  29. internal static IEnumerable<Server> GetServers(this string json) =>
  30. JToken.Parse(json).SearchJToken().AsEnumerable();
  31. private static IEnumerable<Server> SearchJArray(JArray array) =>
  32. array == null ? EMPTY_SERVERS : array.SelectMany(SearchJToken).ToList();
  33. private static IEnumerable<Server> SearchJObject(JObject obj)
  34. {
  35. if (obj == null)
  36. return EMPTY_SERVERS;
  37. if (BASIC_FORMAT.All(field => obj.ContainsKey(field)))
  38. return new[] { obj.ToObject<Server>() };
  39. var servers = new List<Server>();
  40. foreach (var kv in obj)
  41. {
  42. var token = kv.Value;
  43. servers.AddRange(SearchJToken(token));
  44. }
  45. return servers;
  46. }
  47. private static IEnumerable<Server> SearchJToken(this JToken token)
  48. {
  49. switch (token.Type)
  50. {
  51. default:
  52. return Array.Empty<Server>();
  53. case JTokenType.Object:
  54. return SearchJObject(token as JObject);
  55. case JTokenType.Array:
  56. return SearchJArray(token as JArray);
  57. }
  58. }
  59. }
  60. }