Files
MWClash/lib/main.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

154 lines
3.9 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';
import 'package:fl_clash/models/core.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/tile.dart';
import 'package:fl_clash/plugins/vpn.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'application.dart';
import 'clash/core.dart';
import 'clash/lib.dart';
import 'common/common.dart';
Future<void> main() async {
globalState.isService = false;
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (details) {
commonPrint.log(details.stack.toString());
};
final version = await system.version;
await clashCore.preload();
await globalState.initApp(version);
await android?.init();
await window?.init(version);
globalState.isPre = const String.fromEnvironment("APP_ENV") != 'stable';
globalState.coreSHA256 = const String.fromEnvironment("CORE_SHA256");
HttpOverrides.global = FlClashHttpOverrides();
runApp(ProviderScope(
child: const Application(),
));
}
@pragma('vm:entry-point')
Future<void> _service(List<String> flags) async {
globalState.isService = true;
WidgetsFlutterBinding.ensureInitialized();
final quickStart = flags.contains("quick");
final clashLibHandler = ClashLibHandler();
await globalState.init();
tile?.addListener(
_TileListenerWithService(
onStop: () async {
await app?.tip(appLocalizations.stopVpn);
clashLibHandler.stopListener();
await vpn?.stop();
exit(0);
},
),
);
vpn?.handleGetStartForegroundParams = () {
final traffic = clashLibHandler.getTraffic();
return json.encode({
"title": clashLibHandler.getCurrentProfileName(),
"content": "$traffic"
});
};
vpn?.addListener(
_VpnListenerWithService(
onDnsChanged: (String dns) {
clashLibHandler.updateDns(dns);
},
),
);
if (!quickStart) {
_handleMainIpc(clashLibHandler);
} else {
commonPrint.log("quick start");
await ClashCore.initGeo();
app?.tip(appLocalizations.startVpn);
final homeDirPath = await appPath.homeDirPath;
final version = await system.version;
clashLibHandler
.quickStart(
InitParams(
homeDir: homeDirPath,
version: version,
),
globalState.getUpdateConfigParams(),
globalState.getCoreState(),
)
.then(
(res) async {
if (res.isNotEmpty) {
await vpn?.stop();
exit(0);
}
await vpn?.start(
clashLibHandler.getAndroidVpnOptions(),
);
clashLibHandler.startListener();
},
);
}
}
_handleMainIpc(ClashLibHandler clashLibHandler) {
final sendPort = IsolateNameServer.lookupPortByName(mainIsolate);
if (sendPort == null) {
return;
}
final serviceReceiverPort = ReceivePort();
serviceReceiverPort.listen((message) async {
final res = await clashLibHandler.invokeAction(message);
sendPort.send(res);
});
sendPort.send(serviceReceiverPort.sendPort);
final messageReceiverPort = ReceivePort();
clashLibHandler.attachMessagePort(
messageReceiverPort.sendPort.nativePort,
);
messageReceiverPort.listen((message) {
sendPort.send(message);
});
}
@immutable
class _TileListenerWithService with TileListener {
final Function() _onStop;
const _TileListenerWithService({
required Function() onStop,
}) : _onStop = onStop;
@override
void onStop() {
_onStop();
}
}
@immutable
class _VpnListenerWithService with VpnListener {
final Function(String dns) _onDnsChanged;
const _VpnListenerWithService({
required Function(String dns) onDnsChanged,
}) : _onDnsChanged = onDnsChanged;
@override
void onDnsChanged(String dns) {
super.onDnsChanged(dns);
_onDnsChanged(dns);
}
}