Files
MWClash/plugins/proxy/lib/proxy.dart

265 lines
6.8 KiB
Dart
Raw Normal View History

2024-04-30 23:38:49 +08:00
import 'dart:io';
import "package:path/path.dart";
import 'proxy_platform_interface.dart';
2024-04-30 23:38:49 +08:00
enum ProxyTypes { http, https, socks }
class Proxy extends ProxyPlatform {
static String url = "127.0.0.1";
@override
Future<bool?> startProxy(
int port, [
List<String> bypassDomain = const [],
]) async {
return switch (Platform.operatingSystem) {
"macos" => await _startProxyWithMacos(port, bypassDomain),
"linux" => await _startProxyWithLinux(port, bypassDomain),
"windows" => await ProxyPlatform.instance.startProxy(port, bypassDomain),
String() => false,
};
2024-04-30 23:38:49 +08:00
}
@override
Future<bool?> stopProxy() async {
return switch (Platform.operatingSystem) {
"macos" => await _stopProxyWithMacos(),
"linux" => await _stopProxyWithLinux(),
"windows" => await ProxyPlatform.instance.stopProxy(),
String() => false,
};
2024-04-30 23:38:49 +08:00
}
Future<bool> _startProxyWithLinux(int port, List<String> bypassDomain) async {
2024-04-30 23:38:49 +08:00
try {
final homeDir = Platform.environment['HOME']!;
final configDir = join(homeDir, ".config");
final cmdList = List<List<String>>.empty(growable: true);
final desktop = Platform.environment['XDG_CURRENT_DESKTOP'];
final isKDE = desktop == "KDE";
if (isKDE) {
2024-04-30 23:38:49 +08:00
cmdList.add(
[
"kwriteconfig5",
"--file",
"$configDir/kioslaverc",
"--group",
"Proxy Settings",
"--key",
"ProxyType",
"1"
],
2024-04-30 23:38:49 +08:00
);
cmdList.add(
[
"kwriteconfig5",
"--file",
"$configDir/kioslaverc",
"--group",
"Proxy Settings",
"--key",
"NoProxyFor",
bypassDomain.join(",")
2024-04-30 23:38:49 +08:00
],
);
} else {
cmdList.add(
["gsettings", "set", "org.gnome.system.proxy", "mode", "manual"],
);
final ignoreHosts = "\"['${bypassDomain.join("', '")}']\"";
2024-04-30 23:38:49 +08:00
cmdList.add(
[
"gsettings",
"set",
"org.gnome.system.proxy",
"ignore-hosts",
ignoreHosts
2024-04-30 23:38:49 +08:00
],
);
}
for (final type in ProxyTypes.values) {
if (!isKDE) {
2024-04-30 23:38:49 +08:00
cmdList.add(
[
"gsettings",
"set",
"org.gnome.system.proxy.${type.name}",
"host",
url
],
);
cmdList.add(
[
"gsettings",
"set",
"org.gnome.system.proxy.${type.name}",
"port",
"$port"
2024-04-30 23:38:49 +08:00
],
);
cmdList.add(
[
"gsettings",
"set",
"org.gnome.system.proxy.${type.name}",
"port",
"$port"
],
);
cmdList.add(
[
"gsettings",
"set",
"org.gnome.system.proxy.${type.name}",
"port",
"$port"
],
);
}
if (isKDE) {
2024-04-30 23:38:49 +08:00
cmdList.add(
[
"kwriteconfig5",
"--file",
"$configDir/kioslaverc",
"--group",
"Proxy Settings",
"--key",
"${type.name}Proxy",
"${type.name}://$url:$port"
],
);
}
}
for (final cmd in cmdList) {
await Process.run(cmd[0], cmd.sublist(1), runInShell: true);
}
return true;
} catch (_) {
return false;
}
}
Future<bool> _stopProxyWithLinux() async {
try {
final homeDir = Platform.environment['HOME']!;
final configDir = join(homeDir, ".config/");
final cmdList = List<List<String>>.empty(growable: true);
final desktop = Platform.environment['XDG_CURRENT_DESKTOP'];
final isKDE = desktop == "KDE";
if (isKDE) {
cmdList.add(
[
"kwriteconfig5",
"--file",
"$configDir/kioslaverc",
"--group",
"Proxy Settings",
"--key",
"ProxyType",
"0"
],
);
} else {
cmdList.add(
["gsettings", "set", "org.gnome.system.proxy", "mode", "none"],
);
2024-04-30 23:38:49 +08:00
}
for (final cmd in cmdList) {
await Process.run(cmd[0], cmd.sublist(1));
}
return true;
} catch (_) {
return false;
}
}
Future<bool> _startProxyWithMacos(int port, List<String> bypassDomain) async {
2024-04-30 23:38:49 +08:00
try {
final devices = await _getNetworkDeviceListWithMacos();
for (final dev in devices) {
await Future.wait([
Process.run(
"/usr/sbin/networksetup",
["-setwebproxystate", dev, "on"],
),
Process.run(
"/usr/sbin/networksetup",
["-setwebproxy", dev, url, "$port"],
),
Process.run(
"/usr/sbin/networksetup",
["-setsecurewebproxystate", dev, "on"],
),
Process.run(
"/usr/sbin/networksetup",
["-setsecurewebproxy", dev, url, "$port"],
),
2024-04-30 23:38:49 +08:00
Process.run(
"/usr/sbin/networksetup",
["-setsocksfirewallproxystate", dev, "on"],
),
2024-04-30 23:38:49 +08:00
Process.run(
"/usr/sbin/networksetup",
["-setsocksfirewallproxy", dev, url, "$port"],
),
Process.run(
"/usr/sbin/networksetup",
[
"-setproxybypassdomains",
dev,
bypassDomain.join(","),
],
),
2024-04-30 23:38:49 +08:00
]);
}
return true;
} catch (e) {
return false;
}
}
Future<bool> _stopProxyWithMacos() async {
try {
final devices = await _getNetworkDeviceListWithMacos();
for (final dev in devices) {
await Future.wait([
Process.run(
"/usr/sbin/networksetup",
["-setautoproxystate", dev, "off"],
),
Process.run(
"/usr/sbin/networksetup",
["-setwebproxystate", dev, "off"],
),
Process.run(
"/usr/sbin/networksetup",
["-setsecurewebproxystate", dev, "off"],
),
Process.run(
"/usr/sbin/networksetup",
["-setsocksfirewallproxystate", dev, "off"],
),
2024-04-30 23:38:49 +08:00
Process.run(
"/usr/sbin/networksetup",
["-setproxybypassdomains", dev, ""],
),
2024-04-30 23:38:49 +08:00
]);
}
return true;
} catch (e) {
return false;
}
}
Future<List<String>> _getNetworkDeviceListWithMacos() async {
final res = await Process.run(
"/usr/sbin/networksetup", ["-listallnetworkservices"]);
final lines = res.stdout.toString().split("\n");
lines.removeWhere((element) => element.contains("*"));
return lines;
}
}