core.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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. final res = await client.get(Uri.http(url,'info'),headers: headers);
  75. if(res.statusCode == 200) {
  76. var jsonResponse =
  77. jsonDecode(res.body) as Map<String, dynamic>;
  78. return jsonResponse;
  79. }
  80. } on http.ClientException catch (e) {
  81. // 处理客户端异常,例如没有网络连接
  82. print('Client fetchHello Exception: ${e.message}');
  83. return null;
  84. } on Exception catch (e) {
  85. // 处理其他类型的异常
  86. print('Exception: $e');
  87. return null;
  88. }
  89. }
  90. Future<void> updateVersion() async {
  91. try {
  92. final res = await client.get(Uri.http(url,'version'),headers: headers);
  93. if(res.statusCode == 200) {
  94. var jsonResponse =
  95. jsonDecode(res.body) as Map<String, dynamic>;
  96. version.value = ClashCoreVersion.fromJson(jsonResponse);
  97. }
  98. } on http.ClientException catch (e) {
  99. // 处理客户端异常,例如没有网络连接
  100. print('Client updateVersion Exception: ${e.message}');
  101. return null;
  102. } on Exception catch (e) {
  103. // 处理其他类型的异常
  104. print('Exception: $e');
  105. return null;
  106. }
  107. }
  108. Future<void> updateConfig() async {
  109. try {
  110. var ut = Uri.parse('http://$url/configs');
  111. final res = await client.get(ut,headers: headers);
  112. print("updateConfig ---- ${res.statusCode}");
  113. if(res.statusCode == 200) {
  114. var jsonResponse =
  115. jsonDecode(res.body) as Map<String, dynamic>;
  116. config.value = ClashCoreConfig.fromJson(jsonResponse);
  117. }
  118. } on http.ClientException catch (e) {
  119. // 处理客户端异常,例如没有网络连接
  120. print('Client updateConfig Exception: ${e.message}');
  121. } on Exception catch (e) {
  122. // 处理其他类型的异常
  123. print('Exception updateConfig: $e');
  124. }
  125. }
  126. Future<void> fetchConfigUpdate(Map<String, dynamic> config) async {
  127. try {
  128. var ut = Uri.parse('http://$url/configs');
  129. final res = await client.patch(ut,headers: headers);
  130. print("fetchConfigUpdate ---- ${res.statusCode}");
  131. // var jsonResponse =
  132. // jsonDecode(res.body) as Map<String, dynamic>;
  133. // print(jsonResponse);
  134. await updateConfig();
  135. } on http.ClientException catch (e) {
  136. // 处理客户端异常,例如没有网络连接
  137. print('Client fetchConfigUpdate Exception: ${e.message}');
  138. } on Exception catch (e) {
  139. // 处理其他类型的异常
  140. print('Exception fetchConfigUpdate: $e');
  141. }
  142. }
  143. Future<void> changeConfig(String configPath) async{
  144. for (var i = 0 ; i< 5; i++) {
  145. try {
  146. final body = json.encode({
  147. "path": configPath
  148. });
  149. var ut = Uri.parse('http://$url/configs');
  150. final res = await client.put(ut,body:body,headers: headers);
  151. print("changeConfig ---- ${res.statusCode}");
  152. if(res.statusCode == 204)
  153. {
  154. await updateConfig();
  155. break;
  156. }
  157. } on http.ClientException catch (e) {
  158. // 处理客户端异常,例如没有网络连接
  159. print('Client changeConfig Exception: ${e.message}');
  160. continue;
  161. } on Exception catch (e) {
  162. // 处理其他类型的异常
  163. print('Exception changeConfig : $e');
  164. continue;
  165. }
  166. }
  167. }
  168. // type updateConfigRequest struct {
  169. // Path string `json:"path"`
  170. // Payload string `json:"payload"`
  171. // }
  172. // https://github.com/Dreamacro/clash/blob/c231fd14666d6ea05d6a75eaba6db69f9eee5ae9/hub/route/configs.go#L95
  173. // Future<void> fetchReloadConfig(Map<String, String> config) async {
  174. // print("fetchReloadConfig $config");
  175. // await dio.put('/configs', data: config);
  176. // }
  177. Future<void> fetchCloseConnections(String id) async {
  178. //await dio.delete('/connections/${Uri.encodeComponent(id)}');
  179. try {
  180. var ut = Uri.parse('http://$url/connections/${Uri.encodeComponent(id)}');
  181. final res = await client.delete(ut,headers: headers);
  182. print("fetchCloseConnections ---- ${res.statusCode}");
  183. if(res.statusCode == 204){
  184. var jsonResponse =
  185. jsonDecode(res.body) as Map<String, dynamic>;
  186. print(jsonResponse);
  187. await updateConfig();
  188. }
  189. } on http.ClientException catch (e) {
  190. // 处理客户端异常,例如没有网络连接
  191. print('Client fetchCloseConnections Exception: ${e.message}');
  192. } on Exception catch (e) {
  193. // 处理其他类型的异常
  194. print('Exception: $e');
  195. }
  196. }
  197. IOWebSocketChannel fetchConnectionsWs() {
  198. return IOWebSocketChannel.connect(
  199. Uri.parse('ws://${address.value}/connections'),
  200. headers: headers,
  201. );
  202. }
  203. Future updateRuleProvider() async {
  204. // final res = await dio.get('/providers/rules');
  205. // ruleProvider.value = RuleProvider.fromJson(res.data);
  206. // ruleProvider.refresh();
  207. try {
  208. var ut = Uri.parse('http://$url/rpoviders/rules');
  209. final res = await client.get(ut,headers: headers);
  210. if(res.statusCode == 200){
  211. var jsonResponse =
  212. jsonDecode(res.body) as Map<String, dynamic>;
  213. ruleProvider.value = RuleProvider.fromJson(jsonResponse);
  214. ruleProvider.refresh();
  215. }
  216. } on http.ClientException catch (e) {
  217. // 处理客户端异常,例如没有网络连接
  218. print('Client updateRuleProvider Exception: ${e.message}');
  219. } on Exception catch (e) {
  220. // 处理其他类型的异常
  221. print('Exception: $e');
  222. }
  223. }
  224. Future updateRule() async {
  225. // final res = await dio.get('/rules');
  226. // rule.value = Rule.fromJson(res.data);
  227. // rule.refresh();
  228. try {
  229. var ut = Uri.parse('http://$url/rules');
  230. final res = await client.get(ut,headers: headers);
  231. if(res.statusCode == 200){
  232. var jsonResponse =
  233. jsonDecode(res.body) as Map<String, dynamic>;
  234. rule.value = Rule.fromJson(jsonResponse);
  235. rule.refresh();
  236. }
  237. } on http.ClientException catch (e) {
  238. // 处理客户端异常,例如没有网络连接
  239. print('Client updateRule Exception: ${e.message}');
  240. } on Exception catch (e) {
  241. // 处理其他类型的异常
  242. print('Exception: $e');
  243. }
  244. }
  245. // Future<void> fetchRuleProviderUpdate(String name) async {
  246. // await dio.put('/providers/rules/${Uri.encodeComponent(name)}');
  247. // }
  248. // Future<Proxie> fetchProxie() async {
  249. // final res = await dio.get('/proxies');
  250. // return Proxie.fromJson(res.data);
  251. // }
  252. // Future<ProxieProvider> fetchProxieProvider() async {
  253. // final res = await dio.get('/providers/proxies');
  254. // return ProxieProvider.fromJson(res.data);
  255. // }
  256. // Future<void> fetchProxieProviderHealthCheck(String provider) async {
  257. // await dio.get('/providers/proxies/${Uri.encodeComponent(provider)}/healthcheck');
  258. // }
  259. Future<void> fetchSetProxieGroup(String group, String value) async {
  260. // await dio.put('/proxies/${Uri.encodeComponent(group)}', data: {'name': value});
  261. try {
  262. final body = json.encode({
  263. 'name': value
  264. });
  265. var ut = Uri.parse('http://$url/proxies/$group');
  266. final ret = await client.put(ut,body:body,headers: headers);
  267. print("fetchSetProxieGroup ${ret.statusCode}");
  268. } on http.ClientException catch (e) {
  269. // 处理客户端异常,例如没有网络连接
  270. print('Client fetchSetProxieGroup Exception: ${e.message}');
  271. } on Exception catch (e) {
  272. // 处理其他类型的异常
  273. print('fetchSetProxieGroup Exception: $e');
  274. }
  275. }
  276. //
  277. // Future<void> fetchProxieProviderUpdate(String name) async {
  278. // await dio.put('/providers/proxies/${Uri.encodeComponent(name)}');
  279. // }
  280. // Future<int> fetchProxieDelay(String name) async {
  281. // final query = {'timeout': 5000, 'url': 'http://www.gstatic.com/generate_204'};
  282. // final res = await dio.get('/proxies/${Uri.encodeComponent(name)}/delay', queryParameters: query);
  283. // return res.data['delay'] ?? 0;
  284. // }
  285. //
  286. Future<Connect?> fetchConnection() async {
  287. // final res = await dio.get('/connections');
  288. // if(res.data !=null){
  289. // // LogHelper().d("没有连接");
  290. // //return Connect();
  291. // }
  292. try {
  293. var ut = Uri.parse('http://$url/connections');
  294. final res = await client.get(ut,headers: headers);
  295. if(res.statusCode == 200){
  296. var jsonResponse =
  297. jsonDecode(res.body) as Map<String, dynamic>;
  298. return Connect.fromJson(jsonResponse);
  299. }
  300. } on http.ClientException catch (e) {
  301. // 处理客户端异常,例如没有网络连接
  302. print('Client fetchConnection Exception: ${e.message}');
  303. return null;
  304. } on Exception catch (e) {
  305. // 处理其他类型的异常
  306. print('fetchConnection Exception: $e');
  307. return null;
  308. }
  309. }
  310. }