Files
MWClash/lib/clash/core.dart

226 lines
6.1 KiB
Dart
Raw Normal View History

2024-05-04 21:51:40 +08:00
import 'dart:async';
2024-04-30 23:38:49 +08:00
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:fl_clash/clash/clash.dart';
import 'package:fl_clash/clash/interface.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
2024-04-30 23:38:49 +08:00
class ClashCore {
static ClashCore? _instance;
late ClashInterface clashInterface;
2024-05-04 21:51:40 +08:00
ClashCore._internal() {
if (Platform.isAndroid) {
clashInterface = clashLib!;
} else {
clashInterface = clashService!;
}
2024-04-30 23:38:49 +08:00
}
factory ClashCore() {
_instance ??= ClashCore._internal();
return _instance!;
}
Future<void> _initGeo() async {
final homePath = await appPath.getHomeDirPath();
final homeDir = Directory(homePath);
final isExists = await homeDir.exists();
if (!isExists) {
await homeDir.create(recursive: true);
}
const geoFileNameList = [
mmdbFileName,
geoIpFileName,
geoSiteFileName,
asnFileName,
];
try {
for (final geoFileName in geoFileNameList) {
final geoFile = File(
join(homePath, geoFileName),
);
final isExists = await geoFile.exists();
if (isExists) {
continue;
}
final data = await rootBundle.load('assets/data/$geoFileName');
List<int> bytes = data.buffer.asUint8List();
await geoFile.writeAsBytes(bytes, flush: true);
}
} catch (e) {
exit(0);
}
2024-04-30 23:38:49 +08:00
}
Future<bool> init({
required ClashConfig clashConfig,
required Config config,
}) async {
await _initGeo();
final homeDirPath = await appPath.getHomeDirPath();
return await clashInterface.init(homeDirPath);
2024-04-30 23:38:49 +08:00
}
shutdown() async {
await clashInterface.shutdown();
2024-04-30 23:38:49 +08:00
}
FutureOr<bool> get isInit => clashInterface.isInit;
FutureOr<String> validateConfig(String data) {
return clashInterface.validateConfig(data);
2024-04-30 23:38:49 +08:00
}
Future<String> updateConfig(UpdateConfigParams updateConfigParams) async {
return await clashInterface.updateConfig(updateConfigParams);
2024-07-13 16:36:08 +08:00
}
Future<List<Group>> getProxiesGroups() async {
final proxiesRawString = await clashInterface.getProxies();
2024-05-03 14:31:10 +08:00
return Isolate.run<List<Group>>(() {
2024-06-28 07:45:50 +08:00
if (proxiesRawString.isEmpty) return [];
final proxies = (json.decode(proxiesRawString) ?? {}) as Map;
2024-06-28 07:45:50 +08:00
if (proxies.isEmpty) return [];
2024-05-04 00:14:07 +08:00
final groupNames = [
UsedProxy.GLOBAL.name,
...(proxies[UsedProxy.GLOBAL.name]["all"] as List).where((e) {
final proxy = proxies[e] ?? {};
return GroupTypeExtension.valueList.contains(proxy['type']);
2024-05-04 00:14:07 +08:00
})
];
final groupsRaw = groupNames.map((groupName) {
2024-05-03 14:31:10 +08:00
final group = proxies[groupName];
group["all"] = ((group["all"] ?? []) as List)
2024-04-30 23:38:49 +08:00
.map(
(name) => proxies[name],
2024-06-28 07:45:50 +08:00
)
.where((proxy) => proxy != null)
2024-04-30 23:38:49 +08:00
.toList();
2024-05-03 14:31:10 +08:00
return group;
}).toList();
return groupsRaw
.map(
(e) => Group.fromJson(e),
)
.toList();
2024-05-03 14:31:10 +08:00
});
2024-04-30 23:38:49 +08:00
}
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams) async {
return await clashInterface.changeProxy(changeProxyParams);
}
Future<List<Connection>> getConnections() async {
final res = await clashInterface.getConnections();
final connectionsData = json.decode(res) as Map;
final connectionsRaw = connectionsData['connections'] as List? ?? [];
return connectionsRaw.map((e) => Connection.fromJson(e)).toList();
}
closeConnection(String id) {
clashInterface.closeConnection(id);
}
closeConnections() {
clashInterface.closeConnections();
}
Future<List<ExternalProvider>> getExternalProviders() async {
final externalProvidersRawString =
await clashInterface.getExternalProviders();
return Isolate.run<List<ExternalProvider>>(
() {
final externalProviders =
(json.decode(externalProvidersRawString) as List<dynamic>)
.map(
(item) => ExternalProvider.fromJson(item),
)
.toList();
return externalProviders;
},
);
}
Future<ExternalProvider?> getExternalProvider(
String externalProviderName) async {
final externalProvidersRawString =
await clashInterface.getExternalProvider(externalProviderName);
if (externalProvidersRawString == null) {
return null;
}
if (externalProvidersRawString.isEmpty) {
return null;
}
return ExternalProvider.fromJson(json.decode(externalProvidersRawString));
}
2024-08-05 19:25:35 +08:00
Future<String> updateGeoData({
required String geoType,
required String geoName,
}) {
return clashInterface.updateGeoData(geoType: geoType, geoName: geoName);
2024-08-05 19:25:35 +08:00
}
Future<String> sideLoadExternalProvider({
required String providerName,
required String data,
}) {
return clashInterface.sideLoadExternalProvider(
providerName: providerName, data: data);
2024-08-05 19:25:35 +08:00
}
Future<String> updateExternalProvider({
required String providerName,
}) async {
return clashInterface.updateExternalProvider(providerName);
}
startListener() async {
await clashInterface.startListener();
2024-04-30 23:38:49 +08:00
}
stopListener() async {
await clashInterface.stopListener();
}
Future<Delay> getDelay(String proxyName) async {
final data = await clashInterface.asyncTestDelay(proxyName);
return Delay.fromJson(json.decode(data));
}
Future<Traffic> getTraffic(bool value) async {
final trafficString = await clashInterface.getTraffic(value);
return Traffic.fromMap(json.decode(trafficString));
}
Future<Traffic> getTotalTraffic(bool value) async {
final totalTrafficString = await clashInterface.getTotalTraffic(value);
return Traffic.fromMap(json.decode(totalTrafficString));
2024-04-30 23:38:49 +08:00
}
resetTraffic() {
clashInterface.resetTraffic();
2024-04-30 23:38:49 +08:00
}
startLog() {
clashInterface.startLog();
2024-04-30 23:38:49 +08:00
}
stopLog() {
clashInterface.stopLog();
2024-04-30 23:38:49 +08:00
}
requestGc() {
clashInterface.forceGc();
}
2024-04-30 23:38:49 +08:00
}
final clashCore = ClashCore();