Files
MWClash/lib/clash/interface.dart
chen08209 676f2d058a Add windows server mode start process verify
Add linux deb dependencies

Add backup recovery strategy select

Support custom text scaling

Optimize the display of different text scale

Optimize windows setup experience

Optimize startTun performance

Optimize android tv experience

Optimize default option

Optimize computed text size

Optimize hyperOS freeform window

Add developer mode

Update core

Optimize more details
2025-05-01 00:02:29 +08:00

432 lines
9.3 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:fl_clash/clash/message.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
mixin ClashInterface {
Future<bool> init(InitParams params);
Future<bool> preload();
Future<bool> shutdown();
Future<bool> get isInit;
Future<bool> forceGc();
FutureOr<String> validateConfig(String data);
Future<String> asyncTestDelay(String url, String proxyName);
FutureOr<String> updateConfig(UpdateConfigParams updateConfigParams);
FutureOr<String> getProxies();
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams);
Future<bool> startListener();
Future<bool> stopListener();
FutureOr<String> getExternalProviders();
FutureOr<String>? getExternalProvider(String externalProviderName);
Future<String> updateGeoData(UpdateGeoDataParams params);
Future<String> sideLoadExternalProvider({
required String providerName,
required String data,
});
Future<String> updateExternalProvider(String providerName);
FutureOr<String> getTraffic();
FutureOr<String> getTotalTraffic();
FutureOr<String> getCountryCode(String ip);
FutureOr<String> getMemory();
resetTraffic();
startLog();
stopLog();
Future<bool> crash();
FutureOr<String> getConnections();
FutureOr<bool> closeConnection(String id);
FutureOr<bool> closeConnections();
FutureOr<String> getProfile(String id);
Future<bool> setState(CoreState state);
}
mixin AndroidClashInterface {
Future<bool> setFdMap(int fd);
Future<bool> setProcessMap(ProcessMapItem item);
// Future<bool> stopTun();
Future<bool> updateDns(String value);
Future<AndroidVpnOptions?> getAndroidVpnOptions();
Future<String> getCurrentProfileName();
Future<DateTime?> getRunTime();
}
abstract class ClashHandlerInterface with ClashInterface {
Map<String, Completer> callbackCompleterMap = {};
Future<bool> nextHandleResult(ActionResult result, Completer? completer) =>
Future.value(false);
handleResult(ActionResult result) async {
final completer = callbackCompleterMap[result.id];
try {
switch (result.method) {
case ActionMethod.initClash:
case ActionMethod.shutdown:
case ActionMethod.getIsInit:
case ActionMethod.startListener:
case ActionMethod.resetTraffic:
case ActionMethod.closeConnections:
case ActionMethod.closeConnection:
case ActionMethod.stopListener:
case ActionMethod.setState:
case ActionMethod.crash:
completer?.complete(result.data as bool);
return;
case ActionMethod.changeProxy:
case ActionMethod.getProxies:
case ActionMethod.getTraffic:
case ActionMethod.getTotalTraffic:
case ActionMethod.asyncTestDelay:
case ActionMethod.getConnections:
case ActionMethod.getExternalProviders:
case ActionMethod.getExternalProvider:
case ActionMethod.validateConfig:
case ActionMethod.updateConfig:
case ActionMethod.updateGeoData:
case ActionMethod.updateExternalProvider:
case ActionMethod.sideLoadExternalProvider:
case ActionMethod.getCountryCode:
case ActionMethod.getMemory:
completer?.complete(result.data as String);
return;
case ActionMethod.message:
clashMessage.controller.add(result.data as String);
completer?.complete(true);
return;
default:
final isHandled = await nextHandleResult(result, completer);
if (isHandled) {
return;
}
completer?.complete(result.data);
}
} catch (_) {
commonPrint.log(result.id);
}
}
sendMessage(String message);
reStart();
FutureOr<bool> destroy();
Future<T> invoke<T>({
required ActionMethod method,
dynamic data,
Duration? timeout,
FutureOr<T> Function()? onTimeout,
}) async {
final id = "${method.name}#${utils.id}";
callbackCompleterMap[id] = Completer<T>();
dynamic defaultValue;
if (T == String) {
defaultValue = "";
}
if (T == bool) {
defaultValue = false;
}
sendMessage(
json.encode(
Action(
id: id,
method: method,
data: data,
defaultValue: defaultValue,
),
),
);
return (callbackCompleterMap[id] as Completer<T>).safeFuture(
timeout: timeout,
onLast: () {
callbackCompleterMap.remove(id);
},
onTimeout: onTimeout ??
() {
return defaultValue;
},
functionName: id,
);
}
@override
Future<bool> init(InitParams params) {
return invoke<bool>(
method: ActionMethod.initClash,
data: json.encode(params),
);
}
@override
Future<bool> setState(CoreState state) {
return invoke<bool>(
method: ActionMethod.setState,
data: json.encode(state),
);
}
@override
shutdown() async {
return await invoke<bool>(
method: ActionMethod.shutdown,
);
}
@override
Future<bool> get isInit {
return invoke<bool>(
method: ActionMethod.getIsInit,
);
}
@override
Future<bool> forceGc() {
return invoke<bool>(
method: ActionMethod.forceGc,
);
}
@override
FutureOr<String> validateConfig(String data) {
return invoke<String>(
method: ActionMethod.validateConfig,
data: data,
);
}
@override
Future<String> updateConfig(UpdateConfigParams updateConfigParams) async {
return await invoke<String>(
method: ActionMethod.updateConfig,
data: json.encode(updateConfigParams),
timeout: Duration(minutes: 2),
);
}
@override
Future<bool> crash() {
return invoke<bool>(
method: ActionMethod.crash,
);
}
@override
Future<String> getProxies() {
return invoke<String>(
method: ActionMethod.getProxies,
timeout: Duration(seconds: 5),
);
}
@override
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams) {
return invoke<String>(
method: ActionMethod.changeProxy,
data: json.encode(changeProxyParams),
);
}
@override
FutureOr<String> getExternalProviders() {
return invoke<String>(
method: ActionMethod.getExternalProviders,
);
}
@override
FutureOr<String> getExternalProvider(String externalProviderName) {
return invoke<String>(
method: ActionMethod.getExternalProvider,
data: externalProviderName,
);
}
@override
Future<String> updateGeoData(UpdateGeoDataParams params) {
return invoke<String>(
method: ActionMethod.updateGeoData,
data: json.encode(params),
timeout: Duration(minutes: 1));
}
@override
Future<String> sideLoadExternalProvider({
required String providerName,
required String data,
}) {
return invoke<String>(
method: ActionMethod.sideLoadExternalProvider,
data: json.encode({
"providerName": providerName,
"data": data,
}),
);
}
@override
Future<String> updateExternalProvider(String providerName) {
return invoke<String>(
method: ActionMethod.updateExternalProvider,
data: providerName,
timeout: Duration(minutes: 1),
);
}
@override
FutureOr<String> getConnections() {
return invoke<String>(
method: ActionMethod.getConnections,
);
}
@override
Future<bool> closeConnections() {
return invoke<bool>(
method: ActionMethod.closeConnections,
);
}
@override
Future<bool> closeConnection(String id) {
return invoke<bool>(
method: ActionMethod.closeConnection,
data: id,
);
}
@override
Future<String> getProfile(String id) {
return invoke<String>(
method: ActionMethod.getProfile,
data: id,
);
}
@override
FutureOr<String> getTotalTraffic() {
return invoke<String>(
method: ActionMethod.getTotalTraffic,
);
}
@override
FutureOr<String> getTraffic() {
return invoke<String>(
method: ActionMethod.getTraffic,
);
}
@override
resetTraffic() {
invoke(method: ActionMethod.resetTraffic);
}
@override
startLog() {
invoke(method: ActionMethod.startLog);
}
@override
stopLog() {
invoke<bool>(
method: ActionMethod.stopLog,
);
}
@override
Future<bool> startListener() {
return invoke<bool>(
method: ActionMethod.startListener,
);
}
@override
stopListener() {
return invoke<bool>(
method: ActionMethod.stopListener,
);
}
@override
Future<String> asyncTestDelay(String url, String proxyName) {
final delayParams = {
"proxy-name": proxyName,
"timeout": httpTimeoutDuration.inMilliseconds,
"test-url": url,
};
return invoke<String>(
method: ActionMethod.asyncTestDelay,
data: json.encode(delayParams),
timeout: Duration(
milliseconds: 6000,
),
onTimeout: () {
return json.encode(
Delay(
name: proxyName,
value: -1,
url: url,
),
);
},
);
}
@override
FutureOr<String> getCountryCode(String ip) {
return invoke<String>(
method: ActionMethod.getCountryCode,
data: ip,
);
}
@override
FutureOr<String> getMemory() {
return invoke<String>(
method: ActionMethod.getMemory,
);
}
}