Skip to content

Commit

Permalink
Fix fallback issues
Browse files Browse the repository at this point in the history
Optimize change proxy
  • Loading branch information
chen08209 committed Dec 2, 2024
1 parent 25a3f03 commit 4e31954
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 85 deletions.
2 changes: 1 addition & 1 deletion core/Clash.Meta
70 changes: 37 additions & 33 deletions core/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"github.com/metacubex/mihomo/adapter"
"github.com/metacubex/mihomo/adapter/outboundgroup"
"github.com/metacubex/mihomo/adapter/provider"
"github.com/metacubex/mihomo/common/observable"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/updater"
Expand Down Expand Up @@ -108,36 +107,43 @@ func handleGetProxies() string {
return string(data)
}

func handleChangeProxy(data string) bool {
func handleChangeProxy(data string, fn func(string string)) {
runLock.Lock()
defer runLock.Unlock()
var params = &ChangeProxyParams{}
err := json.Unmarshal([]byte(data), params)
if err != nil {
log.Infoln("Unmarshal ChangeProxyParams %v", err)
}
groupName := *params.GroupName
proxyName := *params.ProxyName
proxies := tunnel.ProxiesWithProviders()
group, ok := proxies[groupName]
if !ok {
return false
}
adapterProxy := group.(*adapter.Proxy)
selector, ok := adapterProxy.ProxyAdapter.(outboundgroup.SelectAble)
if !ok {
return false
}
if proxyName == "" {
selector.ForceSet(proxyName)
} else {
err = selector.Set(proxyName)
}
if err == nil {
log.Infoln("[SelectAble] %s selected %s", groupName, proxyName)
return false
}
return true
go func() {
defer runLock.Unlock()
var params = &ChangeProxyParams{}
err := json.Unmarshal([]byte(data), params)
if err != nil {
fn(err.Error())
return
}
groupName := *params.GroupName
proxyName := *params.ProxyName
proxies := tunnel.ProxiesWithProviders()
group, ok := proxies[groupName]
if !ok {
fn("Not found group")
return
}
adapterProxy := group.(*adapter.Proxy)
selector, ok := adapterProxy.ProxyAdapter.(outboundgroup.SelectAble)
if !ok {
fn("Group is not selectable")
return
}
if proxyName == "" {
selector.ForceSet(proxyName)
} else {
err = selector.Set(proxyName)
}
if err != nil {
fn(err.Error())
return
}

fn("")
return
}()
}

func handleGetTraffic(onlyProxy bool) string {
Expand Down Expand Up @@ -339,8 +345,6 @@ func handleUpdateGeoData(geoType string, geoName string, fn func(value string))

func handleUpdateExternalProvider(providerName string, fn func(value string)) {
go func() {
runLock.Lock()
defer runLock.Unlock()
externalProvider, exist := externalProviders[providerName]
if !exist {
fn("external provider is not exist")
Expand Down Expand Up @@ -401,7 +405,7 @@ func handleStopLog() {
}

func init() {
provider.HealthcheckHook = func(name string, delay uint16) {
adapter.UrlTestHook = func(name string, delay uint16) {
delayData := &Delay{
Name: name,
}
Expand Down
7 changes: 5 additions & 2 deletions core/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,12 @@ func getProxies() *C.char {
}

//export changeProxy
func changeProxy(s *C.char) bool {
func changeProxy(s *C.char, port C.longlong) {
i := int64(port)
paramsString := C.GoString(s)
return handleChangeProxy(paramsString)
handleChangeProxy(paramsString, func(value string) {
bridge.SendToPort(i, value)
})
}

//export getTraffic
Expand Down
4 changes: 3 additions & 1 deletion core/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ func handleAction(action *Action) {
return
case changeProxyMethod:
data := action.Data.(string)
action.callback(handleChangeProxy(data))
handleChangeProxy(data, func(value string) {
action.callback(value)
})
return
case getTrafficMethod:
data := action.Data.(bool)
Expand Down
2 changes: 1 addition & 1 deletion lib/clash/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class ClashCore {
});
}

FutureOr<bool> changeProxy(ChangeProxyParams changeProxyParams) async {
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams) async {
return await clashInterface.changeProxy(changeProxyParams);
}

Expand Down
13 changes: 8 additions & 5 deletions lib/clash/generated/clash_ffi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2501,19 +2501,22 @@ class ClashFFI {
late final _getProxies =
_getProxiesPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();

int changeProxy(
void changeProxy(
ffi.Pointer<ffi.Char> s,
int port,
) {
return _changeProxy(
s,
port,
);
}

late final _changeProxyPtr =
_lookup<ffi.NativeFunction<GoUint8 Function(ffi.Pointer<ffi.Char>)>>(
'changeProxy');
late final _changeProxyPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<ffi.Char>, ffi.LongLong)>>('changeProxy');
late final _changeProxy =
_changeProxyPtr.asFunction<int Function(ffi.Pointer<ffi.Char>)>();
_changeProxyPtr.asFunction<void Function(ffi.Pointer<ffi.Char>, int)>();

ffi.Pointer<ffi.Char> getTraffic(
int port,
Expand Down
2 changes: 1 addition & 1 deletion lib/clash/interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mixin ClashInterface {

FutureOr<String> getProxies();

FutureOr<bool> changeProxy(ChangeProxyParams changeProxyParams);
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams);

Future<bool> startListener();

Expand Down
17 changes: 14 additions & 3 deletions lib/clash/lib.dart
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,23 @@ class ClashLib with ClashInterface {
}

@override
changeProxy(ChangeProxyParams changeProxyParams) {
Future<String> changeProxy(ChangeProxyParams changeProxyParams) {
final completer = Completer<String>();
final receiver = ReceivePort();
receiver.listen((message) {
if (!completer.isCompleted) {
completer.complete(message);
receiver.close();
}
});
final params = json.encode(changeProxyParams);
final paramsChar = params.toNativeUtf8().cast<Char>();
final res = clashFFI.changeProxy(paramsChar);
clashFFI.changeProxy(
paramsChar,
receiver.sendPort.nativePort,
);
malloc.free(paramsChar);
return res == 1;
return completer.future;
}

@override
Expand Down
20 changes: 11 additions & 9 deletions lib/clash/service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ class ClashService with ClashInterface {
case ActionMethod.resetTraffic:
case ActionMethod.closeConnections:
case ActionMethod.closeConnection:
case ActionMethod.changeProxy:
case ActionMethod.stopListener:
completer?.complete(action.data as bool);
return;
case ActionMethod.changeProxy:
case ActionMethod.getProxies:
case ActionMethod.getTraffic:
case ActionMethod.getTotalTraffic:
Expand Down Expand Up @@ -255,8 +255,8 @@ class ClashService with ClashInterface {
}

@override
FutureOr<bool> changeProxy(ChangeProxyParams changeProxyParams) {
return _invoke<bool>(
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams) {
return _invoke<String>(
method: ActionMethod.changeProxy,
data: json.encode(changeProxyParams),
);
Expand Down Expand Up @@ -284,10 +284,12 @@ class ClashService with ClashInterface {
}) {
return _invoke<String>(
method: ActionMethod.updateGeoData,
data: {
"geoType": geoType,
"geoName": geoName,
},
data: json.encode(
{
"geoType": geoType,
"geoName": geoName,
},
),
);
}

Expand All @@ -298,10 +300,10 @@ class ClashService with ClashInterface {
}) {
return _invoke<String>(
method: ActionMethod.sideLoadExternalProvider,
data: {
data: json.encode({
"providerName": providerName,
"data": data,
},
}),
);
}

Expand Down
8 changes: 4 additions & 4 deletions lib/common/lock.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ class SingleInstanceLock {
}

Future<bool> acquire() async {
final lockFilePath = await appPath.getLockFilePath();
final lockFile = File(lockFilePath);
await lockFile.create();
try {
final lockFilePath = await appPath.getLockFilePath();
final lockFile = File(lockFilePath);
await lockFile.create();
_accessFile = await lockFile.open(mode: FileMode.write);
_accessFile?.lock();
await _accessFile?.lock();
return true;
} catch (_) {
return false;
Expand Down
42 changes: 25 additions & 17 deletions lib/common/windows.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,17 @@ class Windows {
}

Future<WindowsHelperServiceStatus> checkService() async {
// final qcResult = await Process.run('sc', ['qc', appHelperService]);
// final qcOutput = qcResult.stdout.toString();
// if (qcResult.exitCode != 0 || !qcOutput.contains(appPath.helperPath)) {
// return WindowsHelperServiceStatus.none;
// }
final result = await Process.run('sc', ['query', appHelperService]);
if (result.exitCode != 0) {
if(result.exitCode != 0){
return WindowsHelperServiceStatus.none;
}
final isRunning = await request.pingHelper();
if (isRunning) {
final output = result.stdout.toString();
if (output.contains("RUNNING") && await request.pingHelper()) {
return WindowsHelperServiceStatus.running;
}
return WindowsHelperServiceStatus.presence;
Expand All @@ -98,30 +103,33 @@ class Windows {

await _killProcess(helperPort);

final startCommand = [
"start",
appHelperService,
].join(" ");

if (status == WindowsHelperServiceStatus.presence) {
return runas("sc", startCommand);
}

final createCommand = [
'create',
final command = [
"/c",
if (status == WindowsHelperServiceStatus.presence) ...[
"sc",
"delete",
appHelperService,
"/force",
"&&",
],
"sc",
"create",
appHelperService,
'binPath= "${appPath.helperPath}"',
'start= auto',
"&&",
"sc",
"start",
appHelperService,
].join(" ");

final createdRes = runas("sc", createCommand);
final startRes = runas("sc", startCommand);
final res = runas("cmd.exe", command);

await Future.delayed(
Duration(milliseconds: 300),
);

return createdRes && startRes;
return res;
}

Future<bool> registerTask(String appName) async {
Expand Down
8 changes: 8 additions & 0 deletions lib/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class AppController {
late Function addCheckIpNumDebounce;
late Function applyProfileDebounce;
late Function savePreferencesDebounce;
late Function changeProxyDebounce;

AppController(this.context) {
appState = context.read<AppState>();
Expand All @@ -43,6 +44,13 @@ class AppController {
applyProfileDebounce = debounce<Function()>(() async {
await applyProfile(isPrue: true);
});
changeProxyDebounce = debounce((String groupName, String proxyName) async {
await changeProxy(
groupName: groupName,
proxyName: proxyName,
);
await updateGroups();
});
addCheckIpNumDebounce = debounce(() {
appState.checkIpNum++;
});
Expand Down
9 changes: 4 additions & 5 deletions lib/fragments/proxies/card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,10 @@ class ProxyCard extends StatelessWidget {
groupName,
nextProxyName,
);
appController.changeProxy(
groupName: groupName,
proxyName: nextProxyName,
);
await appController.updateGroupDebounce();
await appController.changeProxyDebounce([
groupName,
nextProxyName,
]);
return;
}
globalState.showSnackBar(
Expand Down
6 changes: 3 additions & 3 deletions lib/widgets/card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ class CommonCard extends StatelessWidget {
?.resolve(states);
case CommonCardType.filled:
if (isSelected) {
return colorScheme.secondaryContainer;
return colorScheme.surfaceContainer.toLight();
}
if (states.isEmpty) {
return colorScheme.surfaceContainerLow;
return colorScheme.surfaceContainerHigh.darken(0.005);
}
return colorScheme.surfaceContainer;
return colorScheme.surfaceContainer.toLight();
}
}

Expand Down

0 comments on commit 4e31954

Please sign in to comment.