Fix tray action issues Fix get profile redirect client ua issues Fix proxy card delay view issues Add Russian, Japanese adaptation Fix some issues
187 lines
4.8 KiB
Dart
187 lines
4.8 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:dio/io.dart';
|
|
import 'package:fl_clash/common/common.dart';
|
|
import 'package:fl_clash/models/models.dart';
|
|
import 'package:fl_clash/state.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
class Request {
|
|
late final Dio _dio;
|
|
late final Dio _clashDio;
|
|
String? userAgent;
|
|
|
|
Request() {
|
|
_dio = Dio(
|
|
BaseOptions(
|
|
headers: {
|
|
"User-Agent": browserUa,
|
|
},
|
|
),
|
|
);
|
|
_clashDio = Dio();
|
|
_clashDio.httpClientAdapter = IOHttpClientAdapter(createHttpClient: () {
|
|
final client = HttpClient();
|
|
client.findProxy = (Uri uri) {
|
|
client.userAgent = globalState.ua;
|
|
return FlClashHttpOverrides.handleFindProxy(uri);
|
|
};
|
|
return client;
|
|
});
|
|
}
|
|
|
|
Future<Response> getFileResponseForUrl(String url) async {
|
|
final response = await _clashDio.get(
|
|
url,
|
|
options: Options(
|
|
responseType: ResponseType.bytes,
|
|
),
|
|
);
|
|
return response;
|
|
}
|
|
|
|
Future<MemoryImage?> getImage(String url) async {
|
|
if (url.isEmpty) return null;
|
|
final response = await _dio.get<Uint8List>(
|
|
url,
|
|
options: Options(
|
|
responseType: ResponseType.bytes,
|
|
),
|
|
);
|
|
final data = response.data;
|
|
if (data == null) return null;
|
|
return MemoryImage(data);
|
|
}
|
|
|
|
Future<Map<String, dynamic>?> checkForUpdate() async {
|
|
final response = await _dio.get(
|
|
"https://api.github.com/repos/$repository/releases/latest",
|
|
options: Options(
|
|
responseType: ResponseType.json,
|
|
),
|
|
);
|
|
if (response.statusCode != 200) return null;
|
|
final data = response.data as Map<String, dynamic>;
|
|
final remoteVersion = data['tag_name'];
|
|
final version = globalState.packageInfo.version;
|
|
final hasUpdate =
|
|
other.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0;
|
|
if (!hasUpdate) return null;
|
|
return data;
|
|
}
|
|
|
|
final Map<String, IpInfo Function(Map<String, dynamic>)> _ipInfoSources = {
|
|
"https://ipwho.is/": IpInfo.fromIpwhoIsJson,
|
|
"https://api.ip.sb/geoip/": IpInfo.fromIpSbJson,
|
|
"https://ipapi.co/json/": IpInfo.fromIpApiCoJson,
|
|
"https://ipinfo.io/json/": IpInfo.fromIpInfoIoJson,
|
|
};
|
|
|
|
Future<IpInfo?> checkIp({CancelToken? cancelToken}) async {
|
|
for (final source in _ipInfoSources.entries) {
|
|
try {
|
|
final response = await _dio.get<Map<String, dynamic>>(
|
|
source.key,
|
|
cancelToken: cancelToken,
|
|
options: Options(
|
|
responseType: ResponseType.json,
|
|
),
|
|
);
|
|
if (response.statusCode != 200 || response.data == null) {
|
|
continue;
|
|
}
|
|
if (response.data == null) {
|
|
continue;
|
|
}
|
|
return source.value(response.data!);
|
|
} catch (e) {
|
|
commonPrint.log("checkIp error ===> $e");
|
|
if (e is DioException && e.type == DioExceptionType.cancel) {
|
|
throw "cancelled";
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<bool> pingHelper() async {
|
|
try {
|
|
final response = await _dio
|
|
.get(
|
|
"http://$localhost:$helperPort/ping",
|
|
options: Options(
|
|
responseType: ResponseType.plain,
|
|
),
|
|
)
|
|
.timeout(
|
|
const Duration(
|
|
milliseconds: 2000,
|
|
),
|
|
);
|
|
if (response.statusCode != HttpStatus.ok) {
|
|
return false;
|
|
}
|
|
return (response.data as String) == helperTag;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> startCoreByHelper(String arg) async {
|
|
try {
|
|
final response = await _dio
|
|
.post(
|
|
"http://$localhost:$helperPort/start",
|
|
data: json.encode({
|
|
"path": appPath.corePath,
|
|
"arg": arg,
|
|
}),
|
|
options: Options(
|
|
responseType: ResponseType.plain,
|
|
),
|
|
)
|
|
.timeout(
|
|
const Duration(
|
|
milliseconds: 2000,
|
|
),
|
|
);
|
|
if (response.statusCode != HttpStatus.ok) {
|
|
return false;
|
|
}
|
|
final data = response.data as String;
|
|
return data.isEmpty;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> stopCoreByHelper() async {
|
|
try {
|
|
final response = await _dio
|
|
.post(
|
|
"http://$localhost:$helperPort/stop",
|
|
options: Options(
|
|
responseType: ResponseType.plain,
|
|
),
|
|
)
|
|
.timeout(
|
|
const Duration(
|
|
milliseconds: 2000,
|
|
),
|
|
);
|
|
if (response.statusCode != HttpStatus.ok) {
|
|
return false;
|
|
}
|
|
final data = response.data as String;
|
|
return data.isEmpty;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
final request = Request();
|