core.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. import 'dart:convert';
  2. import 'package:dio/dio.dart';
  3. import 'package:get/get.dart';
  4. import 'package:naiyouwl/app/bean/clash_core.dart';
  5. import 'package:naiyouwl/app/bean/connect.dart';
  6. import 'package:naiyouwl/app/bean/proxie.dart';
  7. import 'package:naiyouwl/app/bean/rule.dart';
  8. import 'package:naiyouwl/app/common/LogHelper.dart';
  9. import 'package:naiyouwl/app/controller/controllers.dart';
  10. import 'package:naiyouwl/app/controller/service.dart';
  11. import 'package:naiyouwl/app/utils/system_proxy.dart';
  12. import 'package:web_socket_channel/io.dart';
  13. import 'package:http/http.dart' as http;
  14. class CoreController extends GetxController {
  15. // late final dio = Dio(BaseOptions(
  16. // baseUrl: 'http://127.0.0.1:9799',
  17. // ));
  18. var ip = "127.0.0.1";
  19. var url = "";
  20. var client = http.Client();
  21. var headers = Map<String,String>();
  22. late final LogHelper _logger = LogHelper();
  23. var version = ClashCoreVersion(premium: true, version: '').obs;
  24. var address = ''.obs;
  25. var secret = ''.obs;
  26. var config = ClashCoreConfig(
  27. port: 0,
  28. socksPort: 0,
  29. redirPort: 0,
  30. tproxyPort: 0,
  31. mixedPort: 0,
  32. allowLan: false,
  33. bindAddress: '',
  34. mode: 'rule',
  35. logLevel: '',
  36. ipv6: false,
  37. ).obs;
  38. var ruleProvider = RuleProvider(providers: {}).obs;
  39. var rule = Rule(rules: []).obs;
  40. CoreController(){
  41. // dio.interceptors.add(LogInterceptor(
  42. // request: true,
  43. // requestBody: true,
  44. // responseBody: true,
  45. // error: true,
  46. // logPrint: _logger.d, // 使用 Logger 插件打印日志
  47. // ));
  48. //dio.interceptors.add(FriendlyErrorInterceptor());
  49. }
  50. SystemProxyConfig get proxyConfig {
  51. final mixedPort = config.value.mixedPort == 0 ? null : config.value.mixedPort;
  52. final httpPort = mixedPort ?? config.value.port;
  53. final httpsPort = mixedPort ?? config.value.port;
  54. final socksPort = mixedPort ?? config.value.socksPort;
  55. return SystemProxyConfig(
  56. http: httpPort == 0 ? null : '127.0.0.1:$httpPort',
  57. https: httpsPort == 0 ? null : '127.0.0.1:$httpsPort',
  58. socks: socksPort == 0 ? null : '127.0.0.1:$socksPort',
  59. );
  60. }
  61. setApi(String apiAddress, String apiSecret) {
  62. address.value = apiAddress;
  63. secret.value = apiSecret;
  64. // dio.close(force: true);
  65. url = "${address.value}";
  66. headers["Authorization"] = 'Bearer ${secret.value}';
  67. //client.head(Uri.http(url,'info'))
  68. // dio.options.baseUrl = 'http://${address.value}';
  69. // print("dio baseUrl api ${dio.options.baseUrl}");
  70. // dio.options.headers['Authorization'] = 'Bearer ${secret.value}';
  71. }
  72. Future<dynamic> fetchHello() async {
  73. try {
  74. var ut = Uri.parse('http://$url/info');
  75. final res = await client.get(ut,headers: headers);
  76. if(res.statusCode == 200) {
  77. var jsonResponse =
  78. jsonDecode(res.body) as Map<String, dynamic>;
  79. return jsonResponse;
  80. }
  81. } on http.ClientException catch (e) {
  82. // 处理客户端异常,例如没有网络连接
  83. print('Client fetchHello Exception: ${e.message}');
  84. return null;
  85. } on Exception catch (e) {
  86. // 处理其他类型的异常
  87. print('Exception: $e');
  88. return null;
  89. }
  90. }
  91. Future<ClashCoreVersion?> updateVersion() async {
  92. try {
  93. var ut = Uri.parse('http://$url/version');
  94. final res = await client.get(ut,headers: headers);
  95. if(res.statusCode == 200) {
  96. var jsonResponse =
  97. jsonDecode(res.body) as Map<String, dynamic>;
  98. version.value = ClashCoreVersion.fromJson(jsonResponse);
  99. return version.value;
  100. }
  101. } on http.ClientException catch (e) {
  102. // 处理客户端异常,例如没有网络连接
  103. print('Client updateVersion Exception: ${e.message}');
  104. return null;
  105. } on Exception catch (e) {
  106. // 处理其他类型的异常
  107. print('Exception: $e');
  108. return null;
  109. }
  110. return null;
  111. }
  112. Future<void> updateConfig() async {
  113. try {
  114. var ut = Uri.parse('http://$url/configs');
  115. final res = await client.get(ut,headers: headers);
  116. print("updateConfig ---- ${res.statusCode}");
  117. if(res.statusCode == 200) {
  118. var jsonResponse =
  119. jsonDecode(res.body) as Map<String, dynamic>;
  120. config.value = ClashCoreConfig.fromJson(jsonResponse);
  121. }
  122. } on http.ClientException catch (e) {
  123. // 处理客户端异常,例如没有网络连接
  124. print('Client updateConfig Exception: ${e.message}');
  125. } on Exception catch (e) {
  126. // 处理其他类型的异常
  127. print('Exception updateConfig: $e');
  128. }
  129. }
  130. Future<void> fetchConfigUpdate(Map<String, dynamic> config) async {
  131. try {
  132. var ut = Uri.parse('http://$url/configs');
  133. final res = await client.patch(ut,headers: headers);
  134. print("fetchConfigUpdate ---- ${res.statusCode}");
  135. // var jsonResponse =
  136. // jsonDecode(res.body) as Map<String, dynamic>;
  137. // print(jsonResponse);
  138. await updateConfig();
  139. } on http.ClientException catch (e) {
  140. // 处理客户端异常,例如没有网络连接
  141. print('Client fetchConfigUpdate Exception: ${e.message}');
  142. } on Exception catch (e) {
  143. // 处理其他类型的异常
  144. print('Exception fetchConfigUpdate: $e');
  145. }
  146. }
  147. Future<void> changeConfig(String configPath) async{
  148. for (var i = 0 ; i< 5; i++) {
  149. try {
  150. final body = json.encode({
  151. "path": configPath
  152. });
  153. var ut = Uri.parse('http://$url/configs');
  154. final res = await client.put(ut,body:body,headers: headers);
  155. print("changeConfig ---- ${res.statusCode}");
  156. if(res.statusCode == 204)
  157. {
  158. await updateConfig();
  159. break;
  160. }
  161. } on http.ClientException catch (e) {
  162. // 处理客户端异常,例如没有网络连接
  163. print('Client changeConfig Exception: ${e.message}');
  164. continue;
  165. } on Exception catch (e) {
  166. // 处理其他类型的异常
  167. print('Exception changeConfig : $e');
  168. continue;
  169. }
  170. }
  171. }
  172. // type updateConfigRequest struct {
  173. // Path string `json:"path"`
  174. // Payload string `json:"payload"`
  175. // }
  176. // https://github.com/Dreamacro/clash/blob/c231fd14666d6ea05d6a75eaba6db69f9eee5ae9/hub/route/configs.go#L95
  177. // Future<void> fetchReloadConfig(Map<String, String> config) async {
  178. // print("fetchReloadConfig $config");
  179. // await dio.put('/configs', data: config);
  180. // }
  181. Future<void> fetchCloseConnections(String id) async {
  182. //await dio.delete('/connections/${Uri.encodeComponent(id)}');
  183. try {
  184. var ut = Uri.parse('http://$url/connections/${Uri.encodeComponent(id)}');
  185. final res = await client.delete(ut,headers: headers);
  186. print("fetchCloseConnections ---- ${res.statusCode}");
  187. if(res.statusCode == 204){
  188. var jsonResponse =
  189. jsonDecode(res.body) as Map<String, dynamic>;
  190. print(jsonResponse);
  191. await updateConfig();
  192. }
  193. } on http.ClientException catch (e) {
  194. // 处理客户端异常,例如没有网络连接
  195. print('Client fetchCloseConnections Exception: ${e.message}');
  196. } on Exception catch (e) {
  197. // 处理其他类型的异常
  198. print('Exception: $e');
  199. }
  200. }
  201. IOWebSocketChannel fetchConnectionsWs() {
  202. return IOWebSocketChannel.connect(
  203. Uri.parse('ws://${address.value}/connections'),
  204. headers: headers,
  205. );
  206. }
  207. Future updateRuleProvider() async {
  208. // final res = await dio.get('/providers/rules');
  209. // ruleProvider.value = RuleProvider.fromJson(res.data);
  210. // ruleProvider.refresh();
  211. try {
  212. var ut = Uri.parse('http://$url/rpoviders/rules');
  213. final res = await client.get(ut,headers: headers);
  214. if(res.statusCode == 200){
  215. var jsonResponse =
  216. jsonDecode(res.body) as Map<String, dynamic>;
  217. ruleProvider.value = RuleProvider.fromJson(jsonResponse);
  218. ruleProvider.refresh();
  219. }
  220. } on http.ClientException catch (e) {
  221. // 处理客户端异常,例如没有网络连接
  222. print('Client updateRuleProvider Exception: ${e.message}');
  223. } on Exception catch (e) {
  224. // 处理其他类型的异常
  225. print('Exception: $e');
  226. }
  227. }
  228. Future updateRule() async {
  229. // final res = await dio.get('/rules');
  230. // rule.value = Rule.fromJson(res.data);
  231. // rule.refresh();
  232. try {
  233. var ut = Uri.parse('http://$url/rules');
  234. final res = await client.get(ut,headers: headers);
  235. if(res.statusCode == 200){
  236. var jsonResponse =
  237. jsonDecode(res.body) as Map<String, dynamic>;
  238. rule.value = Rule.fromJson(jsonResponse);
  239. rule.refresh();
  240. }
  241. } on http.ClientException catch (e) {
  242. // 处理客户端异常,例如没有网络连接
  243. print('Client updateRule Exception: ${e.message}');
  244. } on Exception catch (e) {
  245. // 处理其他类型的异常
  246. print('Exception: $e');
  247. }
  248. }
  249. // Future<void> fetchRuleProviderUpdate(String name) async {
  250. // await dio.put('/providers/rules/${Uri.encodeComponent(name)}');
  251. // }
  252. // Future<Proxie> fetchProxie() async {
  253. // final res = await dio.get('/proxies');
  254. // return Proxie.fromJson(res.data);
  255. // }
  256. // Future<ProxieProvider> fetchProxieProvider() async {
  257. // final res = await dio.get('/providers/proxies');
  258. // return ProxieProvider.fromJson(res.data);
  259. // }
  260. // Future<void> fetchProxieProviderHealthCheck(String provider) async {
  261. // await dio.get('/providers/proxies/${Uri.encodeComponent(provider)}/healthcheck');
  262. // }
  263. Future<void> fetchSetProxieGroup(String group, String value) async {
  264. // await dio.put('/proxies/${Uri.encodeComponent(group)}', data: {'name': value});
  265. try {
  266. final body = json.encode({
  267. 'name': value
  268. });
  269. var ut = Uri.parse('http://$url/proxies/$group');
  270. final ret = await client.put(ut,body:body,headers: headers);
  271. print("fetchSetProxieGroup ${ret.statusCode}");
  272. } on http.ClientException catch (e) {
  273. // 处理客户端异常,例如没有网络连接
  274. print('Client fetchSetProxieGroup Exception: ${e.message}');
  275. } on Exception catch (e) {
  276. // 处理其他类型的异常
  277. print('fetchSetProxieGroup Exception: $e');
  278. }
  279. }
  280. //
  281. // Future<void> fetchProxieProviderUpdate(String name) async {
  282. // await dio.put('/providers/proxies/${Uri.encodeComponent(name)}');
  283. // }
  284. // Future<int> fetchProxieDelay(String name) async {
  285. // final query = {'timeout': 5000, 'url': 'http://www.gstatic.com/generate_204'};
  286. // final res = await dio.get('/proxies/${Uri.encodeComponent(name)}/delay', queryParameters: query);
  287. // return res.data['delay'] ?? 0;
  288. // }
  289. //
  290. Future<Connect?> fetchConnection() async {
  291. // final res = await dio.get('/connections');
  292. // if(res.data !=null){
  293. // // LogHelper().d("没有连接");
  294. // //return Connect();
  295. // }
  296. try {
  297. var ut = Uri.parse('http://$url/connections');
  298. final res = await client.get(ut,headers: headers);
  299. if(res.statusCode == 200){
  300. var jsonResponse =
  301. jsonDecode(res.body) as Map<String, dynamic>;
  302. return Connect.fromJson(jsonResponse);
  303. }
  304. } on http.ClientException catch (e) {
  305. // 处理客户端异常,例如没有网络连接
  306. print('Client fetchConnection Exception: ${e.message}');
  307. return null;
  308. } on Exception catch (e) {
  309. // 处理其他类型的异常
  310. print('fetchConnection Exception: $e');
  311. return null;
  312. }
  313. }
  314. }