mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 20:44:38 +03:00
refactor vpn mode
This commit is contained in:
4
3rdparty/WinCommander.cpp
vendored
4
3rdparty/WinCommander.cpp
vendored
@@ -48,7 +48,7 @@ Returns the return value of the executed command
|
||||
uint WinCommander::runProcessElevated(const QString &path,
|
||||
const QStringList ¶meters,
|
||||
const QString &workingDir,
|
||||
bool hide, bool aWait) {
|
||||
int nShow, bool aWait) {
|
||||
uint result = 0;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -79,7 +79,7 @@ uint WinCommander::runProcessElevated(const QString &path,
|
||||
shex.lpParameters = pszParameters;
|
||||
shex.lpDirectory = pszDirectory;
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
|
||||
shex.nShow = hide ? SW_HIDE : SW_SHOWMINIMIZED;
|
||||
shex.nShow = nShow;
|
||||
|
||||
ShellExecuteEx(&shex);
|
||||
if (shex.hProcess)
|
||||
|
||||
6
3rdparty/WinCommander.hpp
vendored
6
3rdparty/WinCommander.hpp
vendored
@@ -28,10 +28,14 @@
|
||||
|
||||
class WinCommander {
|
||||
public:
|
||||
static const int SW_HIDE = 0;
|
||||
static const int SW_NORMAL = 1;
|
||||
static const int SW_SHOWMINIMIZED = 2;
|
||||
|
||||
static uint runProcessElevated(const QString &path,
|
||||
const QStringList ¶meters = QStringList(),
|
||||
const QString &workingDir = QString(),
|
||||
bool hide = false, bool aWait = true);
|
||||
int nShow = SW_SHOWMINIMIZED, bool aWait = true);
|
||||
};
|
||||
|
||||
#endif // WINCOMMANDER_H
|
||||
@@ -40,6 +40,11 @@ QJsonObject JsonEditor::OpenEditor() {
|
||||
auto string = jsonEditor->toPlainText();
|
||||
|
||||
while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) {
|
||||
if (string.isEmpty()) {
|
||||
resultCode = QDialog::Accepted;
|
||||
final = {};
|
||||
break;
|
||||
}
|
||||
QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"),
|
||||
tr("You must correct these errors before continuing."));
|
||||
resultCode = this->exec();
|
||||
|
||||
@@ -13,6 +13,24 @@
|
||||
|
||||
namespace NekoRay {
|
||||
|
||||
QStringList getAutoBypassExternalProcessPaths(const QSharedPointer<BuildConfigResult> &result) {
|
||||
QStringList paths;
|
||||
for (const auto &ext: result->exts) {
|
||||
auto path = ext.first.program;
|
||||
if (path.trimmed().isEmpty()) continue;
|
||||
paths << path.replace("\\", "/");
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
QString genTunName() {
|
||||
auto tun_name = "nekoray-tun";
|
||||
#ifdef Q_OS_MACOS
|
||||
tun_name = "utun9";
|
||||
#endif
|
||||
return tun_name;
|
||||
}
|
||||
|
||||
void MergeJson(const QJsonObject &custom, QJsonObject &outbound) {
|
||||
// 合并
|
||||
if (custom.isEmpty()) return;
|
||||
@@ -215,8 +233,8 @@ namespace NekoRay {
|
||||
{"tag", "block"},
|
||||
};
|
||||
|
||||
// DNS Routing
|
||||
if (dataStore->dns_routing && !status->forTest) {
|
||||
// DNS out
|
||||
if (!status->forTest) {
|
||||
QJsonObject dnsOut;
|
||||
dnsOut["protocol"] = "dns";
|
||||
dnsOut["tag"] = "dns-out";
|
||||
@@ -300,7 +318,7 @@ namespace NekoRay {
|
||||
// Routing
|
||||
QJsonObject routing;
|
||||
routing["domainStrategy"] = dataStore->domain_strategy;
|
||||
routing["domainMatcher"] = dataStore->domain_matcher == DomainMatcher::MPH ? "mph" : "linear";
|
||||
routing["domainMatcher"] = "mph";
|
||||
if (status->forTest) routing["domainStrategy"] = "AsIs";
|
||||
|
||||
// final add user rule (block)
|
||||
@@ -457,7 +475,12 @@ namespace NekoRay {
|
||||
// chain rules: this
|
||||
auto ext_mapping_port = 0;
|
||||
auto ext_socks_port = 0;
|
||||
auto thisExternalStat = ent->bean->NeedExternal(isFirstProfile, dataStore->running_spmode == SystemProxyMode::VPN);
|
||||
auto thisExternalStat = ent->bean->NeedExternal(isFirstProfile);
|
||||
if (thisExternalStat < 0) {
|
||||
status->result->error = "This configuration cannot be set automatically, please try another.";
|
||||
return {};
|
||||
}
|
||||
|
||||
// determine port
|
||||
if (thisExternalStat > 0) {
|
||||
if (ent->type == "custom") {
|
||||
@@ -658,9 +681,28 @@ namespace NekoRay {
|
||||
},
|
||||
};
|
||||
}
|
||||
// apply domain_strategy
|
||||
inboundObj["domain_strategy"] = dataStore->outbound_domain_strategy;
|
||||
//
|
||||
inboundObj["domain_strategy"] = dataStore->domain_strategy;
|
||||
status->inbounds += inboundObj;
|
||||
}
|
||||
|
||||
// tun-in
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "tun-in";
|
||||
inboundObj["type"] = "tun";
|
||||
inboundObj["interface_name"] = genTunName();
|
||||
inboundObj["auto_route"] = true;
|
||||
inboundObj["endpoint_independent_nat"] = true;
|
||||
inboundObj["mtu"] = dataStore->vpn_mtu;
|
||||
inboundObj["stack"] = Preset::SingBox::VpnImplementation.value(dataStore->vpn_implementation);
|
||||
inboundObj["strict_route"] = dataStore->vpn_strict_route;
|
||||
inboundObj["inet4_address"] = "172.19.0.1/28";
|
||||
if (dataStore->vpn_ipv6) inboundObj["inet4_address"] = "fdfe:dcba:9876::1/126";
|
||||
if (dataStore->sniffing_mode != SniffingMode::DISABLE) {
|
||||
inboundObj["sniff"] = true;
|
||||
inboundObj["sniff_override_destination"] = dataStore->sniffing_mode == SniffingMode::FOR_DESTINATION;
|
||||
}
|
||||
inboundObj["domain_strategy"] = dataStore->domain_strategy;
|
||||
status->inbounds += inboundObj;
|
||||
}
|
||||
|
||||
@@ -805,7 +847,12 @@ namespace NekoRay {
|
||||
// Routing
|
||||
|
||||
// dns hijack
|
||||
if (!status->forTest) status->routingRules += QJsonObject{{"protocol", "dns"}, {"outbound", "dns-out"}};
|
||||
if (!status->forTest) {
|
||||
status->routingRules += QJsonObject{
|
||||
{"protocol", "dns"},
|
||||
{"outbound", "dns-out"},
|
||||
};
|
||||
}
|
||||
|
||||
// sing-box routing rule object
|
||||
auto add_rule_route = [&](const QStringList &list, bool isIP, const QString &out) {
|
||||
@@ -823,6 +870,49 @@ namespace NekoRay {
|
||||
add_rule_route(status->domainListRemote, false, tagProxy);
|
||||
add_rule_route(status->domainListDirect, false, "bypass");
|
||||
|
||||
// built-in rules
|
||||
status->routingRules += QJsonObject{
|
||||
{"network", "udp"},
|
||||
{"port", QJsonArray{135, 137, 138, 5353}},
|
||||
{"outbound", "block"},
|
||||
};
|
||||
status->routingRules += QJsonObject{
|
||||
{"ip_cidr", QJsonArray{"224.0.0.0/3", "ff00::/8"}},
|
||||
{"outbound", "block"},
|
||||
};
|
||||
status->routingRules += QJsonObject{
|
||||
{"source_ip_cidr", QJsonArray{"224.0.0.0/3", "ff00::/8"}},
|
||||
{"outbound", "block"},
|
||||
};
|
||||
|
||||
// tun user rule
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn) {
|
||||
auto match_out = NekoRay::dataStore->vpn_rule_white ? "proxy" : "bypass";
|
||||
|
||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
||||
if (!process_name_rule.isEmpty()) {
|
||||
auto arr = SplitLinesSkipSharp(process_name_rule);
|
||||
QJsonObject rule{{"outbound", match_out},
|
||||
{"process_name", QList2QJsonArray(arr)}};
|
||||
status->routingRules += rule;
|
||||
}
|
||||
|
||||
QString cidr_rule = dataStore->vpn_rule_cidr.trimmed();
|
||||
if (!cidr_rule.isEmpty()) {
|
||||
auto arr = SplitLinesSkipSharp(cidr_rule);
|
||||
QJsonObject rule{{"outbound", match_out},
|
||||
{"ip_cidr", QList2QJsonArray(arr)}};
|
||||
status->routingRules += rule;
|
||||
}
|
||||
|
||||
auto autoBypassExternalProcessPaths = getAutoBypassExternalProcessPaths(status->result);
|
||||
if (!autoBypassExternalProcessPaths.isEmpty()) {
|
||||
QJsonObject rule{{"outbound", "bypass"},
|
||||
{"process_name", QList2QJsonArray(autoBypassExternalProcessPaths)}};
|
||||
status->routingRules += rule;
|
||||
}
|
||||
}
|
||||
|
||||
// geopath
|
||||
auto geoip = FindCoreAsset("geoip.db");
|
||||
auto geosite = FindCoreAsset("geosite.db");
|
||||
@@ -836,7 +926,7 @@ namespace NekoRay {
|
||||
QJSONARRAY_ADD(routingRules, status->routingRules)
|
||||
auto routeObj = QJsonObject{
|
||||
{"rules", routingRules},
|
||||
{"auto_detect_interface", NekoRay::dataStore->core_box_auto_detect_interface},
|
||||
{"auto_detect_interface", dataStore->spmode_vpn},
|
||||
{
|
||||
"geoip",
|
||||
QJsonObject{
|
||||
@@ -873,9 +963,10 @@ namespace NekoRay {
|
||||
}
|
||||
|
||||
QString WriteVPNSingBoxConfig() {
|
||||
// tun user rule
|
||||
auto match_out = NekoRay::dataStore->vpn_rule_white ? "nekoray-socks" : "direct";
|
||||
auto no_match_out = NekoRay::dataStore->vpn_rule_white ? "direct" : "nekoray-socks";
|
||||
// user rule
|
||||
|
||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
||||
if (!process_name_rule.isEmpty()) {
|
||||
auto arr = SplitLinesSkipSharp(process_name_rule);
|
||||
@@ -883,6 +974,7 @@ namespace NekoRay {
|
||||
{"process_name", QList2QJsonArray(arr)}};
|
||||
process_name_rule = "," + QJsonObject2QString(rule, false);
|
||||
}
|
||||
|
||||
QString cidr_rule = dataStore->vpn_rule_cidr.trimmed();
|
||||
if (!cidr_rule.isEmpty()) {
|
||||
auto arr = SplitLinesSkipSharp(cidr_rule);
|
||||
@@ -890,11 +982,9 @@ namespace NekoRay {
|
||||
{"ip_cidr", QList2QJsonArray(arr)}};
|
||||
cidr_rule = "," + QJsonObject2QString(rule, false);
|
||||
}
|
||||
// tun name
|
||||
auto tun_name = "nekoray-tun";
|
||||
#ifdef Q_OS_MACOS
|
||||
tun_name = "utun9";
|
||||
#endif
|
||||
|
||||
// TODO bypass ext core process path?
|
||||
|
||||
// auth
|
||||
QString socks_user_pass;
|
||||
if (dataStore->inbound_auth->NeedAuth()) {
|
||||
@@ -910,7 +1000,7 @@ namespace NekoRay {
|
||||
.replace("%STACK%", Preset::SingBox::VpnImplementation.value(dataStore->vpn_implementation))
|
||||
.replace("%PROCESS_NAME_RULE%", process_name_rule)
|
||||
.replace("%CIDR_RULE%", cidr_rule)
|
||||
.replace("%TUN_NAME%", tun_name)
|
||||
.replace("%TUN_NAME%", genTunName())
|
||||
.replace("%STRICT_ROUTE%", dataStore->vpn_strict_route ? "true" : "false")
|
||||
.replace("%SOCKS_USER_PASS%", socks_user_pass)
|
||||
.replace("%FINAL_OUT%", no_match_out)
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace NekoRay::fmt {
|
||||
|
||||
//
|
||||
|
||||
virtual int NeedExternal(bool isFirstProfile, bool isVPN) { return 0; };
|
||||
virtual int NeedExternal(bool isFirstProfile) { return 0; };
|
||||
|
||||
virtual CoreObjOutboundBuildResult BuildCoreObjV2Ray() { return {}; };
|
||||
|
||||
|
||||
@@ -20,38 +20,50 @@
|
||||
auto TempFile = QFileInfo(f).absoluteFilePath();
|
||||
|
||||
namespace NekoRay::fmt {
|
||||
// -1: Cannot use this config
|
||||
// 0: Internal
|
||||
// 1: Mapping External
|
||||
// 2: Direct External
|
||||
|
||||
int NaiveBean::NeedExternal(bool isFirstProfile, bool isVPN) {
|
||||
if (isFirstProfile && !isVPN) {
|
||||
int NaiveBean::NeedExternal(bool isFirstProfile) {
|
||||
if (isFirstProfile) {
|
||||
if (dataStore->spmode_vpn) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int HysteriaBean::NeedExternal(bool isFirstProfile, bool isVPN) {
|
||||
int HysteriaBean::NeedExternal(bool isFirstProfile) {
|
||||
auto hysteriaCore = [=] {
|
||||
if (isFirstProfile) {
|
||||
if (dataStore->spmode_vpn && protocol != hysteria_protocol_facktcp && hopPort.trimmed().isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
} else {
|
||||
if (protocol == hysteria_protocol_facktcp || !hopPort.trimmed().isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
if (IS_NEKO_BOX) {
|
||||
if (protocol == hysteria_protocol_udp && hopPort.trimmed().isEmpty()) {
|
||||
// sing-box support
|
||||
return 0;
|
||||
} else {
|
||||
// hysteria core support
|
||||
if (isFirstProfile && !isVPN) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
return hysteriaCore();
|
||||
}
|
||||
} else {
|
||||
if (isFirstProfile && !isVPN) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
return hysteriaCore();
|
||||
}
|
||||
}
|
||||
|
||||
int CustomBean::NeedExternal(bool isFirstProfile, bool isVPN) {
|
||||
int CustomBean::NeedExternal(bool isFirstProfile) {
|
||||
if (core == "internal" || core == "internal-full") return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -99,8 +111,8 @@ namespace NekoRay::fmt {
|
||||
|
||||
// determine server format
|
||||
auto is_direct = external_stat == 2;
|
||||
auto sni2 = sni;
|
||||
if (sni.isEmpty() && is_direct) sni2 = serverAddress;
|
||||
auto sniGen = sni;
|
||||
if (sni.isEmpty() && !IsIpAddress(serverAddress)) sniGen = serverAddress;
|
||||
|
||||
auto server = serverAddress;
|
||||
if (!hopPort.trimmed().isEmpty()) {
|
||||
@@ -130,7 +142,7 @@ namespace NekoRay::fmt {
|
||||
if (protocol == hysteria_protocol_facktcp) config["protocol"] = "faketcp";
|
||||
if (protocol == hysteria_protocol_wechat_video) config["protocol"] = "wechat-video";
|
||||
|
||||
if (!sni2.isEmpty()) config["server_name"] = sni2;
|
||||
if (!sniGen.isEmpty()) config["server_name"] = sniGen;
|
||||
if (!alpn.isEmpty()) config["alpn"] = alpn;
|
||||
|
||||
if (!caText.trimmed().isEmpty()) {
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace NekoRay::fmt {
|
||||
return core;
|
||||
};
|
||||
|
||||
QString DisplayCoreType() override { return NeedExternal(false, false) ? core : software_core_name; };
|
||||
QString DisplayCoreType() override { return NeedExternal(false) ? core : software_core_name; };
|
||||
|
||||
QString DisplayAddress() override {
|
||||
if (core == "internal") {
|
||||
@@ -47,7 +47,7 @@ namespace NekoRay::fmt {
|
||||
return AbstractBean::DisplayAddress();
|
||||
};
|
||||
|
||||
int NeedExternal(bool isFirstProfile, bool isVPN) override;
|
||||
int NeedExternal(bool isFirstProfile) override;
|
||||
|
||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ namespace NekoRay::fmt {
|
||||
return ::DisplayAddress(serverAddress, serverPort);
|
||||
}
|
||||
|
||||
QString DisplayCoreType() override { return NeedExternal(false, false) == 0 ? software_core_name : "Hysteria"; };
|
||||
QString DisplayCoreType() override { return NeedExternal(false) == 0 ? software_core_name : "Hysteria"; };
|
||||
|
||||
QString DisplayType() override { return "Hysteria"; };
|
||||
|
||||
int NeedExternal(bool isFirstProfile, bool isVPN) override;
|
||||
int NeedExternal(bool isFirstProfile) override;
|
||||
|
||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace NekoRay::fmt {
|
||||
|
||||
QString DisplayType() override { return "Naive"; };
|
||||
|
||||
int NeedExternal(bool isFirstProfile, bool isVPN) override;
|
||||
int NeedExternal(bool isFirstProfile) override;
|
||||
|
||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||
|
||||
|
||||
@@ -17,9 +17,6 @@ func main() {
|
||||
fmt.Println("sing-box-extra:", boxbox.Version(), "NekoBox:", neko_common.Version_neko)
|
||||
fmt.Println()
|
||||
|
||||
// local DNS transport
|
||||
_ = os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",netdns=go")
|
||||
|
||||
// nekobox_core
|
||||
if len(os.Args) > 1 && os.Args[1] == "nekobox" {
|
||||
neko_common.RunMode = neko_common.RunMode_NekoBox_Core
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo apt install fuse -y
|
||||
sudo apt-get install fuse -y
|
||||
|
||||
cp -r linux64 nekoray.AppDir
|
||||
|
||||
@@ -25,7 +25,7 @@ chmod +x nekoray.AppDir/AppRun
|
||||
|
||||
# build
|
||||
|
||||
curl -L -O https://github.com/AppImage/AppImageKit/releases/latest/download/appimagetool-x86_64.AppImage
|
||||
curl -fLSO https://github.com/AppImage/AppImageKit/releases/latest/download/appimagetool-x86_64.AppImage
|
||||
chmod +x appimagetool-x86_64.AppImage
|
||||
./appimagetool-x86_64.AppImage nekoray.AppDir
|
||||
|
||||
|
||||
@@ -16,14 +16,6 @@ namespace NekoRay {
|
||||
};
|
||||
}
|
||||
|
||||
namespace SystemProxyMode {
|
||||
enum SystemProxyMode {
|
||||
DISABLE,
|
||||
SYSTEM_PROXY,
|
||||
VPN,
|
||||
};
|
||||
}
|
||||
|
||||
namespace CoreType {
|
||||
enum CoreType {
|
||||
V2RAY,
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace NekoRay {
|
||||
_add(new configItem("remote_dns_strategy", &remote_dns_strategy, itemType::string));
|
||||
_add(new configItem("direct_dns", &direct_dns, itemType::string));
|
||||
_add(new configItem("direct_dns_strategy", &direct_dns_strategy, itemType::string));
|
||||
_add(new configItem("domain_matcher", &domain_matcher, itemType::integer));
|
||||
_add(new configItem("domain_strategy", &domain_strategy, itemType::string));
|
||||
_add(new configItem("outbound_domain_strategy", &outbound_domain_strategy, itemType::string));
|
||||
_add(new configItem("sniffing_mode", &sniffing_mode, itemType::integer));
|
||||
@@ -46,7 +45,7 @@ namespace NekoRay {
|
||||
_add(new configItem("remember_id", &remember_id, itemType::integer));
|
||||
_add(new configItem("remember_enable", &remember_enable, itemType::boolean));
|
||||
_add(new configItem("language", &language, itemType::integer));
|
||||
_add(new configItem("spmode", &remember_spmode, itemType::integer));
|
||||
_add(new configItem("spmode2", &remember_spmode, itemType::stringList));
|
||||
_add(new configItem("skip_cert", &skip_cert, itemType::boolean));
|
||||
_add(new configItem("hk_mw", &hotkey_mainwindow, itemType::string));
|
||||
_add(new configItem("hk_group", &hotkey_group, itemType::string));
|
||||
@@ -74,14 +73,13 @@ namespace NekoRay {
|
||||
_add(new configItem("max_log_line", &max_log_line, itemType::integer));
|
||||
_add(new configItem("splitter_state", &splitter_state, itemType::string));
|
||||
_add(new configItem("utlsFingerprint", &utlsFingerprint, itemType::string));
|
||||
_add(new configItem("core_box_auto_detect_interface", &core_box_auto_detect_interface, itemType::boolean));
|
||||
_add(new configItem("core_box_clash_api", &core_box_clash_api, itemType::integer));
|
||||
_add(new configItem("core_box_clash_api_secret", &core_box_clash_api_secret, itemType::string));
|
||||
_add(new configItem("core_box_underlying_dns", &core_box_underlying_dns, itemType::string));
|
||||
_add(new configItem("core_ray_direct_dns", &core_ray_direct_dns, itemType::boolean));
|
||||
#ifndef Q_OS_WIN
|
||||
_add(new configItem("vpn_internal_tun", &vpn_internal_tun, itemType::boolean));
|
||||
#ifdef Q_OS_WIN
|
||||
_add(new configItem("core_ray_windows_disable_auto_interface", &core_ray_windows_disable_auto_interface, itemType::boolean));
|
||||
_add(new configItem("vpn_already_admin", &vpn_already_admin, itemType::boolean));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -14,5 +14,6 @@ namespace NekoRay {
|
||||
} // namespace NekoRay
|
||||
|
||||
#define IS_NEKO_BOX (NekoRay::coreType == NekoRay::CoreType::SING_BOX)
|
||||
#define IS_NEKO_BOX_INTERNAL_TUN (IS_NEKO_BOX && NekoRay::dataStore->vpn_internal_tun)
|
||||
#define ROUTES_PREFIX_NAME QString(IS_NEKO_BOX ? "routes_box" : "routes")
|
||||
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
||||
|
||||
@@ -54,7 +54,8 @@ namespace NekoRay {
|
||||
int started_id = -1919;
|
||||
bool core_running = false;
|
||||
bool core_prepare_exit = false;
|
||||
int running_spmode = NekoRay::SystemProxyMode::DISABLE;
|
||||
bool spmode_vpn = false;
|
||||
bool spmode_system_proxy = false;
|
||||
bool need_keep_vpn_off = false;
|
||||
QStringList ignoreConnTag = {};
|
||||
|
||||
@@ -104,7 +105,7 @@ namespace NekoRay {
|
||||
QString utlsFingerprint = "";
|
||||
|
||||
// Remember
|
||||
int remember_spmode = NekoRay::SystemProxyMode::DISABLE;
|
||||
QStringList remember_spmode = {};
|
||||
int remember_id = -1919;
|
||||
bool remember_enable = false;
|
||||
|
||||
@@ -127,18 +128,17 @@ namespace NekoRay {
|
||||
QString domain_strategy = "AsIs";
|
||||
QString outbound_domain_strategy = "AsIs";
|
||||
int sniffing_mode = SniffingMode::FOR_ROUTING;
|
||||
int domain_matcher = DomainMatcher::MPH;
|
||||
QString custom_route_global = "{\"rules\": []}";
|
||||
QString active_routing = "Default";
|
||||
|
||||
// VPN
|
||||
bool vpn_internal_tun = true;
|
||||
int vpn_implementation = 0;
|
||||
int vpn_mtu = 9000;
|
||||
bool vpn_ipv6 = false;
|
||||
bool vpn_hide_console = false;
|
||||
bool vpn_strict_route = false;
|
||||
bool vpn_rule_white = false;
|
||||
bool vpn_already_admin = false; // not saved on Windows
|
||||
QString vpn_rule_process = "";
|
||||
QString vpn_rule_cidr = "";
|
||||
|
||||
@@ -149,7 +149,6 @@ namespace NekoRay {
|
||||
QString hotkey_system_proxy_menu = "";
|
||||
|
||||
// Core
|
||||
bool core_box_auto_detect_interface = true;
|
||||
int core_box_clash_api = -9090;
|
||||
QString core_box_clash_api_secret = "";
|
||||
QString core_box_underlying_dns = "";
|
||||
|
||||
@@ -91,19 +91,11 @@
|
||||
<source>Use proxy when updating subscription</source>
|
||||
<translation>استفاده از پروکسی زمانی که اشتراک را بروزرسانی می کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Language</source>
|
||||
<translation type="vanished">زبان</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Security</source>
|
||||
<translatorcomment>امنیت security</translatorcomment>
|
||||
<translation>امنیت</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insecure hint</source>
|
||||
<translation type="vanished">اشاره ناامن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Statistics refresh rate</source>
|
||||
<translation>نرخ تازه سازی آمار ترافیک</translation>
|
||||
@@ -357,10 +349,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod
|
||||
<source>Network Settings (%1)</source>
|
||||
<translation>تنظیمات شبکه (1%)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Security Settings</source>
|
||||
<translation type="vanished">تنظیمات امنیت</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>When enabled, V2Ray will not check the validity of the TLS certificate provided by the remote host (the security is equivalent to plaintext)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@@ -503,14 +491,6 @@ These settings can be changed later.</source>
|
||||
<source>Disable</source>
|
||||
<translation>غیرفعال کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The sniffing result is used for routing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The sniffing result is used for destination</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remote DNS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@@ -523,14 +503,6 @@ These settings can be changed later.</source>
|
||||
<source>Enable DNS Routing</source>
|
||||
<translation>فعال کردن مسیریابی DNS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>V2Ray Domain Strategy</source>
|
||||
<translation>استراتژی دامنه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Matcher</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Block</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@@ -607,16 +579,28 @@ These settings can be changed later.</source>
|
||||
<source>Default Outbound</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query Strategy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remote</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Inbound & Outbound Domain Strategy</source>
|
||||
<source>DNS Query Strategy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Domain Strategy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server Address Strategy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sniff result for routing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sniff result for destination</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
@@ -682,11 +666,12 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</source>
|
||||
<translation type="unfinished">لغو کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Don't ask for privilege elevation</source>
|
||||
<source>Internal Tun</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Already Admin</source>
|
||||
<source>Add a tun inbound to the profile startup, instead of using two processes.
|
||||
This needs to be run NekoBox with administrator privileges.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
@@ -1336,14 +1321,6 @@ Split by line.</source>
|
||||
<source>Clear</source>
|
||||
<translation>پاک کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>End</source>
|
||||
<translation type="vanished">پایان</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Active</source>
|
||||
<translation type="vanished">فعال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Start: %1
|
||||
End: %2</source>
|
||||
@@ -1373,10 +1350,6 @@ End: %2</source>
|
||||
<source>Starting profile %1</source>
|
||||
<translation>اغاز پروفایل %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Profile is insecure: %1</source>
|
||||
<translation type="vanished">پروفایل ناامن می باشد: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stopping profile %1</source>
|
||||
<translation>متوقف کردن پروفایل %1</translation>
|
||||
@@ -1405,13 +1378,13 @@ End: %2</source>
|
||||
<source>Restart nekoray to take effect.</source>
|
||||
<translation type="unfinished">برای اعمال تغییرات nekoray را مجددا راه اندازی کنید.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please run NekoBox as admin</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ProxyItem</name>
|
||||
<message>
|
||||
<source>Remove</source>
|
||||
<translation type="vanished">حذف کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirmation</source>
|
||||
<translation>تائیدیه</translation>
|
||||
|
||||
@@ -95,10 +95,6 @@
|
||||
<source>Security</source>
|
||||
<translation>安全</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insecure hint</source>
|
||||
<translation type="vanished">提示不安全的配置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Statistics refresh rate</source>
|
||||
<translation>流量统计刷新率</translation>
|
||||
@@ -494,11 +490,11 @@ These settings can be changed later.</source>
|
||||
<translation>流量探测</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The sniffing result is used for routing</source>
|
||||
<source>Sniff result for routing</source>
|
||||
<translation>探测结果用于路由判断</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The sniffing result is used for destination</source>
|
||||
<source>Sniff result for destination</source>
|
||||
<translation>探测结果用于目标地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
@@ -513,14 +509,6 @@ These settings can be changed later.</source>
|
||||
<source>Enable DNS Routing</source>
|
||||
<translation>启用 DNS 路由</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>V2Ray Domain Strategy</source>
|
||||
<translation>域名策略</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Matcher</source>
|
||||
<translation>域名匹配器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Block</source>
|
||||
<translation>阻止</translation>
|
||||
@@ -597,17 +585,21 @@ These settings can be changed later.</source>
|
||||
<source>Default Outbound</source>
|
||||
<translation>默认出站</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query Strategy</source>
|
||||
<translation>DNS 查询策略</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remote</source>
|
||||
<translation>远程</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Inbound & Outbound Domain Strategy</source>
|
||||
<translation>出入站域名策略</translation>
|
||||
<source>DNS Query Strategy</source>
|
||||
<translation>DNS 查询策略</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Domain Strategy</source>
|
||||
<translation>域名策略</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server Address Strategy</source>
|
||||
<translation>服务器地址策略</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -675,12 +667,14 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Don't ask for privilege elevation</source>
|
||||
<translation>不请求特权提升</translation>
|
||||
<source>Internal Tun</source>
|
||||
<translation>内部 Tun</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Already Admin</source>
|
||||
<translation>已是管理员</translation>
|
||||
<source>Add a tun inbound to the profile startup, instead of using two processes.
|
||||
This needs to be run NekoBox with administrator privileges.</source>
|
||||
<translation>在配置文件启动时添加一个tun inbound,而不是使用两个进程。
|
||||
这需要以管理员权限运行NekoBox。</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -1189,10 +1183,6 @@ End: %2</source>
|
||||
<source>Move %1 item(s)</source>
|
||||
<translation>移动 %1 个项目</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Profile is insecure: %1</source>
|
||||
<translation type="vanished">配置不安全: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Unavailable</source>
|
||||
<translation>删除不可用的配置</translation>
|
||||
@@ -1395,6 +1385,10 @@ Split by line.</source>
|
||||
<source>Restart nekoray to take effect.</source>
|
||||
<translation>重启 nekoray 生效。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please run NekoBox as admin</source>
|
||||
<translation>请以管理员权限运行 NekoBox</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ProxyItem</name>
|
||||
@@ -1498,26 +1492,6 @@ Release note:
|
||||
<source>Chain Proxy</source>
|
||||
<translation>链式代理</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The configuration (insecure) can be detected and identified, the transmission is fully visible to the censor and is not resistant to man-in-the-middle tampering with the content of the communication.</source>
|
||||
<translation type="vanished">该配置 (不安全) 能够被检测识别,传输的内容对审查者完全可见,并且无法抵抗中间人篡改通讯内容.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This configuration (Shadowsocks streaming cipher) can be accurately proactively detected and decrypted by censors without requiring a password, and cannot be mitigated by turning on IV replay filters on the server side.
|
||||
|
||||
Learn more: https://github.com/net4people/bbs/issues/24</source>
|
||||
<translation type="vanished">该配置 (Shadowsocks 流式密码) 可以被准确地主动探测、在不需要密码的情况下被审查者解密流量, 且服务端开启 IV 重放过滤器也无法缓解.
|
||||
|
||||
了解更多: https://github.com/net4people/bbs/issues/24</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This configuration (VMess MD5 authentication) has been deprecated by upstream because of its questionable resistance to tampering and concealment.
|
||||
|
||||
As of January 1, 2022, compatibility with MD5 authentication information will be disabled on the server side by default. Any client using MD5 authentication information will not be able to connect to a server with VMess MD5 authentication information disabled.</source>
|
||||
<translation type="vanished">该配置 (VMess MD5 认证) 抗篡改能力存疑, 隐蔽性存疑, 已被上游废弃.
|
||||
|
||||
自 2022 年 1 月 1 日起, 服务器端将默认禁用对于 MD5 认证信息 的兼容. 任何使用 MD5 认证信息的客户端将无法连接到禁用 VMess MD5 认证信息的服务器端.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Requesting subscription: %1</source>
|
||||
<translation>正在请求订阅: %1</translation>
|
||||
@@ -1534,10 +1508,6 @@ As of January 1, 2022, compatibility with MD5 authentication information will be
|
||||
<source>Change of %1:</source>
|
||||
<translation>%1 变化:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This profile is cleartext, don't use it if the server is not in your local network.</source>
|
||||
<translation type="vanished">该配置为明文传输,如果服务器不在本地局域网,请不要使用。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select</source>
|
||||
<translation>选择</translation>
|
||||
|
||||
@@ -392,7 +392,6 @@ void DialogBasicSettings::on_core_settings_clicked() {
|
||||
w->setLayout(layout);
|
||||
//
|
||||
auto line = -1;
|
||||
QCheckBox *core_box_auto_detect_interface;
|
||||
QCheckBox *core_box_enable_clash_api;
|
||||
MyLineEdit *core_box_clash_api;
|
||||
MyLineEdit *core_box_clash_api_secret;
|
||||
@@ -412,12 +411,6 @@ void DialogBasicSettings::on_core_settings_clicked() {
|
||||
layout->addWidget(core_box_underlying_dns, line, 1);
|
||||
//
|
||||
if (IS_NEKO_BOX) {
|
||||
auto core_box_auto_detect_interface_l = new QLabel("auto_detect_interface");
|
||||
core_box_auto_detect_interface = new QCheckBox;
|
||||
core_box_auto_detect_interface->setChecked(NekoRay::dataStore->core_box_auto_detect_interface);
|
||||
layout->addWidget(core_box_auto_detect_interface_l, ++line, 0);
|
||||
layout->addWidget(core_box_auto_detect_interface, line, 1);
|
||||
//
|
||||
auto core_box_enable_clash_api_l = new QLabel("Enable Clash API");
|
||||
core_box_enable_clash_api = new QCheckBox;
|
||||
core_box_enable_clash_api->setChecked(NekoRay::dataStore->core_box_clash_api > 0);
|
||||
@@ -460,7 +453,6 @@ void DialogBasicSettings::on_core_settings_clicked() {
|
||||
connect(box, &QDialogButtonBox::accepted, w, [=] {
|
||||
NekoRay::dataStore->core_box_underlying_dns = core_box_underlying_dns->text();
|
||||
if (IS_NEKO_BOX) {
|
||||
NekoRay::dataStore->core_box_auto_detect_interface = core_box_auto_detect_interface->isChecked();
|
||||
NekoRay::dataStore->core_box_clash_api = core_box_clash_api->text().toInt() * (core_box_enable_clash_api->isChecked() ? 1 : -1);
|
||||
NekoRay::dataStore->core_box_clash_api_secret = core_box_clash_api_secret->text();
|
||||
} else {
|
||||
|
||||
@@ -31,16 +31,15 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(ne
|
||||
title_base = windowTitle();
|
||||
|
||||
if (IS_NEKO_BOX) {
|
||||
ui->domain_v2ray->setVisible(false);
|
||||
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
||||
ui->domainStrategyCombo->addItems(Preset::SingBox::DomainStrategy);
|
||||
} else {
|
||||
ui->domain_v2ray->setVisible(true);
|
||||
ui->outbound_domain_strategy->addItems({"AsIs", "UseIPv4", "UseIPv6", "PreferIPv4", "PreferIPv6"});
|
||||
ui->domainStrategyCombo->addItems({"AsIs", "IPIfNonMatch", "IPOnDemand"});
|
||||
}
|
||||
//
|
||||
ui->sniffing_mode->setCurrentIndex(NekoRay::dataStore->sniffing_mode);
|
||||
ui->outbound_domain_strategy->setCurrentText(NekoRay::dataStore->outbound_domain_strategy);
|
||||
ui->domainMatcherCombo->setCurrentIndex(NekoRay::dataStore->domain_matcher);
|
||||
ui->domainStrategyCombo->setCurrentText(NekoRay::dataStore->domain_strategy);
|
||||
ui->dns_routing->setChecked(NekoRay::dataStore->dns_routing);
|
||||
ui->dns_remote->setText(NekoRay::dataStore->remote_dns);
|
||||
@@ -88,7 +87,6 @@ DialogManageRoutes::~DialogManageRoutes() {
|
||||
|
||||
void DialogManageRoutes::accept() {
|
||||
NekoRay::dataStore->sniffing_mode = ui->sniffing_mode->currentIndex();
|
||||
NekoRay::dataStore->domain_matcher = ui->domainMatcherCombo->currentIndex();
|
||||
NekoRay::dataStore->domain_strategy = ui->domainStrategyCombo->currentText();
|
||||
NekoRay::dataStore->outbound_domain_strategy = ui->outbound_domain_strategy->currentText();
|
||||
NekoRay::dataStore->dns_routing = ui->dns_routing->isChecked();
|
||||
|
||||
@@ -21,12 +21,6 @@
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sniffing Mode</string>
|
||||
</property>
|
||||
@@ -41,33 +35,38 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>The sniffing result is used for routing</string>
|
||||
<string>Sniff result for routing</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>The sniffing result is used for destination</string>
|
||||
<string>Sniff result for destination</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="toolTip">
|
||||
<string notr="true">For V2Ray, it sets routing.domainStrategy
|
||||
For sing-box, it sets inbound.domain_strategy</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Domain Strategy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="domainStrategyCombo">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Inbound & Outbound Domain Strategy</string>
|
||||
<string>Server Address Strategy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -111,12 +110,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="dns_routing">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable DNS Routing</string>
|
||||
</property>
|
||||
@@ -124,81 +117,19 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="queryStrategy">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Query Strategy</string>
|
||||
<string>DNS Query Strategy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="domain_v2ray" native="true">
|
||||
<layout class="QHBoxLayout" name="_2" stretch="0,1,0,1">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>V2Ray Domain Strategy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="domainStrategyCombo">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">AsIs</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">IPIfNonMatch</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">IPOnDemand</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Matcher</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="domainMatcherCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Original</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Minimal Perfect Hash Matcher</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -461,13 +392,8 @@
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>sniffing_mode</tabstop>
|
||||
<tabstop>outbound_domain_strategy</tabstop>
|
||||
<tabstop>dns_remote</tabstop>
|
||||
<tabstop>dns_direct</tabstop>
|
||||
<tabstop>dns_routing</tabstop>
|
||||
<tabstop>queryStrategy</tabstop>
|
||||
<tabstop>domainStrategyCombo</tabstop>
|
||||
<tabstop>domainMatcherCombo</tabstop>
|
||||
<tabstop>preset</tabstop>
|
||||
<tabstop>custom_route_edit</tabstop>
|
||||
<tabstop>def_outbound</tabstop>
|
||||
|
||||
@@ -18,13 +18,12 @@ DialogVPNSettings::DialogVPNSettings(QWidget *parent) : QDialog(parent), ui(new
|
||||
ui->vpn_mtu->setCurrentText(Int2String(NekoRay::dataStore->vpn_mtu));
|
||||
ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6);
|
||||
ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_console);
|
||||
ui->vpn_already_admin->setChecked(NekoRay::dataStore->vpn_already_admin);
|
||||
#ifdef Q_OS_WIN
|
||||
ui->vpn_already_admin->setVisible(false);
|
||||
#else
|
||||
#ifndef Q_OS_WIN
|
||||
ui->hide_console->setVisible(false);
|
||||
#endif
|
||||
ui->strict_route->setChecked(NekoRay::dataStore->vpn_strict_route);
|
||||
ui->single_core->setVisible(IS_NEKO_BOX);
|
||||
ui->single_core->setChecked(NekoRay::dataStore->vpn_internal_tun);
|
||||
//
|
||||
D_LOAD_STRING(vpn_rule_cidr)
|
||||
D_LOAD_STRING(vpn_rule_process)
|
||||
@@ -56,7 +55,7 @@ void DialogVPNSettings::accept() {
|
||||
NekoRay::dataStore->vpn_hide_console = ui->hide_console->isChecked();
|
||||
NekoRay::dataStore->vpn_strict_route = ui->strict_route->isChecked();
|
||||
NekoRay::dataStore->vpn_rule_white = ui->whitelist_mode->isChecked();
|
||||
NekoRay::dataStore->vpn_already_admin = ui->vpn_already_admin->isChecked();
|
||||
NekoRay::dataStore->vpn_internal_tun = ui->single_core->isChecked();
|
||||
//
|
||||
D_SAVE_STRING_QTEXTEDIT(vpn_rule_cidr)
|
||||
D_SAVE_STRING_QTEXTEDIT(vpn_rule_process)
|
||||
|
||||
@@ -86,13 +86,6 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="horizontalGroupBox_2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="hide_console">
|
||||
<property name="text">
|
||||
<string>Hide Console</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="vpn_ipv6">
|
||||
<property name="text">
|
||||
@@ -100,13 +93,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fake_dns">
|
||||
<property name="text">
|
||||
<string notr="true">FakeDNS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="strict_route">
|
||||
<property name="text">
|
||||
@@ -115,12 +101,34 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="vpn_already_admin">
|
||||
<widget class="QCheckBox" name="fake_dns">
|
||||
<property name="text">
|
||||
<string notr="true">FakeDNS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="hide_console">
|
||||
<property name="text">
|
||||
<string>Hide Console</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="single_core">
|
||||
<property name="toolTip">
|
||||
<string>Don't ask for privilege elevation</string>
|
||||
<string>Add a tun inbound to the profile startup, instead of using two processes.
|
||||
This needs to be run NekoBox with administrator privileges.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Already Admin</string>
|
||||
<string>Internal Tun</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -198,6 +206,19 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>vpn_implementation</tabstop>
|
||||
<tabstop>vpn_mtu</tabstop>
|
||||
<tabstop>vpn_ipv6</tabstop>
|
||||
<tabstop>strict_route</tabstop>
|
||||
<tabstop>fake_dns</tabstop>
|
||||
<tabstop>hide_console</tabstop>
|
||||
<tabstop>single_core</tabstop>
|
||||
<tabstop>vpn_rule_cidr</tabstop>
|
||||
<tabstop>vpn_rule_process</tabstop>
|
||||
<tabstop>whitelist_mode</tabstop>
|
||||
<tabstop>troubleshooting</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
||||
@@ -94,12 +94,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
software_name = "NekoBox";
|
||||
software_core_name = "sing-box";
|
||||
// replace default values
|
||||
if (NekoRay::dataStore->log_level == "warning") {
|
||||
NekoRay::dataStore->log_level = "info";
|
||||
}
|
||||
if (!Preset::SingBox::DomainStrategy.contains(NekoRay::dataStore->outbound_domain_strategy)) {
|
||||
NekoRay::dataStore->outbound_domain_strategy = "";
|
||||
}
|
||||
if (NekoRay::dataStore->log_level == "warning") NekoRay::dataStore->log_level = "info";
|
||||
if (!Preset::SingBox::DomainStrategy.contains(NekoRay::dataStore->domain_strategy)) NekoRay::dataStore->domain_strategy = "";
|
||||
if (!Preset::SingBox::DomainStrategy.contains(NekoRay::dataStore->outbound_domain_strategy)) NekoRay::dataStore->outbound_domain_strategy = "";
|
||||
//
|
||||
if (QDir("dashboard").isEmpty()) {
|
||||
QDir().mkdir("dashboard");
|
||||
@@ -334,20 +331,19 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
MW_dialog_message("", "UpdateDataStore");
|
||||
});
|
||||
//
|
||||
connect(ui->checkBox_VPN, &QCheckBox::clicked, this, [=](bool checked) {
|
||||
neko_set_spmode(checked ? NekoRay::SystemProxyMode::VPN : NekoRay::SystemProxyMode::DISABLE);
|
||||
});
|
||||
connect(ui->checkBox_SystemProxy, &QCheckBox::clicked, this, [=](bool checked) {
|
||||
neko_set_spmode(checked ? NekoRay::SystemProxyMode::SYSTEM_PROXY : NekoRay::SystemProxyMode::DISABLE);
|
||||
});
|
||||
connect(ui->checkBox_VPN, &QCheckBox::clicked, this, [=](bool checked) { neko_set_spmode_vpn(checked); });
|
||||
connect(ui->checkBox_SystemProxy, &QCheckBox::clicked, this, [=](bool checked) { neko_set_spmode_system_proxy(checked); });
|
||||
connect(ui->menu_spmode, &QMenu::aboutToShow, this, [=]() {
|
||||
ui->menu_spmode_disabled->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::DISABLE);
|
||||
ui->menu_spmode_system_proxy->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY);
|
||||
ui->menu_spmode_vpn->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN);
|
||||
ui->menu_spmode_disabled->setChecked(!(NekoRay::dataStore->spmode_system_proxy || NekoRay::dataStore->spmode_vpn));
|
||||
ui->menu_spmode_system_proxy->setChecked(NekoRay::dataStore->spmode_system_proxy);
|
||||
ui->menu_spmode_vpn->setChecked(NekoRay::dataStore->spmode_vpn);
|
||||
});
|
||||
connect(ui->menu_spmode_system_proxy, &QAction::triggered, this, [=](bool checked) { neko_set_spmode_system_proxy(checked); });
|
||||
connect(ui->menu_spmode_vpn, &QAction::triggered, this, [=](bool checked) { neko_set_spmode_vpn(checked); });
|
||||
connect(ui->menu_spmode_disabled, &QAction::triggered, this, [=]() {
|
||||
neko_set_spmode_system_proxy(false);
|
||||
neko_set_spmode_vpn(false);
|
||||
});
|
||||
connect(ui->menu_spmode_system_proxy, &QAction::triggered, this, [=]() { neko_set_spmode(NekoRay::SystemProxyMode::SYSTEM_PROXY); });
|
||||
connect(ui->menu_spmode_vpn, &QAction::triggered, this, [=]() { neko_set_spmode(NekoRay::SystemProxyMode::VPN); });
|
||||
connect(ui->menu_spmode_disabled, &QAction::triggered, this, [=]() { neko_set_spmode(NekoRay::SystemProxyMode::DISABLE); });
|
||||
connect(ui->menu_qr, &QAction::triggered, this, [=]() { display_qr_link(false); });
|
||||
connect(ui->menu_tcp_ping, &QAction::triggered, this, [=]() { speedtest_current_group(0); });
|
||||
connect(ui->menu_url_test, &QAction::triggered, this, [=]() { speedtest_current_group(1); });
|
||||
@@ -417,8 +413,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
|
||||
// Start last
|
||||
if (NekoRay::dataStore->remember_enable) {
|
||||
if (NekoRay::dataStore->remember_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
||||
neko_set_spmode(NekoRay::dataStore->remember_spmode, false);
|
||||
if (NekoRay::dataStore->remember_spmode.contains("system_proxy")) {
|
||||
neko_set_spmode_system_proxy(true, false);
|
||||
}
|
||||
if (NekoRay::dataStore->remember_spmode.contains("vpn")) {
|
||||
neko_set_spmode_vpn(true, false);
|
||||
}
|
||||
if (NekoRay::dataStore->remember_id >= 0) {
|
||||
runOnUiThread([=] { neko_start(NekoRay::dataStore->remember_id); });
|
||||
@@ -514,7 +513,7 @@ void MainWindow::dialog_message_impl(const QString &sender, const QString &info)
|
||||
auto changed = NekoRay::dataStore->Save();
|
||||
if (info.contains("RouteChanged")) changed = true;
|
||||
refresh_proxy_list();
|
||||
if (info.contains("VPNChanged") && NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) {
|
||||
if (info.contains("VPNChanged") && NekoRay::dataStore->spmode_vpn) {
|
||||
MessageBoxWarning(tr("VPN settings changed"), tr("Restart VPN to take effect."));
|
||||
} else if (changed && NekoRay::dataStore->started_id >= 0 &&
|
||||
QMessageBox::question(GetMessageBoxParent(), tr("Confirmation"), tr("Settings changed, restart proxy?")) == QMessageBox::StandardButton::Yes) {
|
||||
@@ -624,8 +623,9 @@ void MainWindow::on_commitDataRequest() {
|
||||
}
|
||||
|
||||
void MainWindow::on_menu_exit_triggered() {
|
||||
neko_set_spmode(NekoRay::SystemProxyMode::DISABLE, false);
|
||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) return;
|
||||
neko_set_spmode_system_proxy(false, false);
|
||||
neko_set_spmode_vpn(false, false);
|
||||
if (NekoRay::dataStore->spmode_vpn) return;
|
||||
RegisterHotkey(true);
|
||||
//
|
||||
on_commitDataRequest();
|
||||
@@ -638,13 +638,21 @@ void MainWindow::on_menu_exit_triggered() {
|
||||
if (exit_reason == 1) {
|
||||
QDir::setCurrent(QApplication::applicationDirPath());
|
||||
QProcess::startDetached("./updater", QStringList{});
|
||||
} else if (exit_reason == 2) {
|
||||
} else if (exit_reason == 2 || exit_reason == 3) {
|
||||
QDir::setCurrent(QApplication::applicationDirPath());
|
||||
auto arguments = NekoRay::dataStore->argv;
|
||||
if (arguments.length() > 0) arguments.removeFirst();
|
||||
auto isLauncher = qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1";
|
||||
if (isLauncher) arguments.prepend("--");
|
||||
QProcess::startDetached(isLauncher ? "./launcher" : QApplication::applicationFilePath(), arguments);
|
||||
auto program = isLauncher ? "./launcher" : QApplication::applicationFilePath();
|
||||
|
||||
if (exit_reason == 3) { // restart as admin
|
||||
#ifdef Q_OS_WIN
|
||||
WinCommander::runProcessElevated(program, arguments, "", WinCommander::SW_NORMAL, false);
|
||||
#endif
|
||||
} else {
|
||||
QProcess::startDetached(program, arguments);
|
||||
}
|
||||
}
|
||||
tray->hide();
|
||||
QCoreApplication::quit();
|
||||
@@ -654,23 +662,11 @@ void MainWindow::on_menu_exit_triggered() {
|
||||
refresh_status(); \
|
||||
return;
|
||||
|
||||
void MainWindow::neko_set_spmode(int mode, bool save) {
|
||||
if (mode != NekoRay::dataStore->running_spmode) {
|
||||
// DISABLE
|
||||
|
||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
||||
ClearSystemProxy();
|
||||
} else if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) {
|
||||
if (!StopVPNProcess()) {
|
||||
neko_set_spmode_FAILED
|
||||
}
|
||||
}
|
||||
|
||||
// ENABLE
|
||||
|
||||
if (mode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
||||
void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||
if (enable != NekoRay::dataStore->spmode_system_proxy) {
|
||||
if (enable) {
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
||||
if (mode == NekoRay::SystemProxyMode::SYSTEM_PROXY && !IS_NEKO_BOX && !IsValidPort(NekoRay::dataStore->inbound_http_port)) {
|
||||
if (!IS_NEKO_BOX && !IsValidPort(NekoRay::dataStore->inbound_http_port)) {
|
||||
auto btn = QMessageBox::warning(this, software_name,
|
||||
tr("Http inbound is not enabled, can't set system proxy."),
|
||||
"OK", tr("Settings"), "", 0, 0);
|
||||
@@ -682,29 +678,72 @@ void MainWindow::neko_set_spmode(int mode, bool save) {
|
||||
#endif
|
||||
auto socks_port = NekoRay::dataStore->inbound_socks_port;
|
||||
auto http_port = NekoRay::dataStore->inbound_http_port;
|
||||
if (IS_NEKO_BOX) {
|
||||
http_port = socks_port;
|
||||
}
|
||||
if (IS_NEKO_BOX) http_port = socks_port;
|
||||
SetSystemProxy(http_port, socks_port);
|
||||
} else if (mode == NekoRay::SystemProxyMode::VPN) {
|
||||
} else {
|
||||
ClearSystemProxy();
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
NekoRay::dataStore->remember_spmode.removeAll("system_proxy");
|
||||
if (enable) {
|
||||
NekoRay::dataStore->remember_spmode.append("system_proxy");
|
||||
}
|
||||
NekoRay::dataStore->Save();
|
||||
}
|
||||
|
||||
NekoRay::dataStore->spmode_system_proxy = enable;
|
||||
refresh_status();
|
||||
}
|
||||
|
||||
void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
||||
if (enable != NekoRay::dataStore->spmode_vpn) {
|
||||
if (enable) {
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
||||
#ifdef Q_OS_WIN
|
||||
if (!Windows_IsInAdmin()) {
|
||||
auto n = QMessageBox::warning(GetMessageBoxParent(), software_name, tr("Please run NekoBox as admin"), QMessageBox::Yes | QMessageBox::No);
|
||||
if (n == QMessageBox::Yes) {
|
||||
this->exit_reason = 3;
|
||||
on_menu_exit_triggered();
|
||||
}
|
||||
neko_set_spmode_FAILED
|
||||
}
|
||||
#endif
|
||||
// TODO check permission for Linux
|
||||
} else {
|
||||
if (NekoRay::dataStore->need_keep_vpn_off) {
|
||||
MessageBoxWarning(software_name,
|
||||
tr("Current server is incompatible with VPN. Please stop the server first, enable VPN mode, and then restart."));
|
||||
MessageBoxWarning(software_name, tr("Current server is incompatible with VPN. Please stop the server first, enable VPN mode, and then restart."));
|
||||
neko_set_spmode_FAILED
|
||||
}
|
||||
if (!StartVPNProcess()) {
|
||||
neko_set_spmode_FAILED
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
||||
// current core is sing-box
|
||||
} else {
|
||||
if (!StopVPNProcess()) {
|
||||
neko_set_spmode_FAILED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
NekoRay::dataStore->remember_spmode = mode;
|
||||
NekoRay::dataStore->remember_spmode.removeAll("vpn");
|
||||
if (enable) {
|
||||
NekoRay::dataStore->remember_spmode.append("vpn");
|
||||
}
|
||||
NekoRay::dataStore->Save();
|
||||
}
|
||||
|
||||
NekoRay::dataStore->running_spmode = mode;
|
||||
NekoRay::dataStore->spmode_vpn = enable;
|
||||
refresh_status();
|
||||
|
||||
if (NekoRay::dataStore->started_id >= 0) neko_start(NekoRay::dataStore->started_id);
|
||||
}
|
||||
|
||||
void MainWindow::refresh_status(const QString &traffic_update) {
|
||||
@@ -736,8 +775,8 @@ void MainWindow::refresh_status(const QString &traffic_update) {
|
||||
if (IS_NEKO_BOX) inbound_txt = QString("Mixed: %1").arg(display_socks);
|
||||
ui->label_inbound->setText(inbound_txt);
|
||||
//
|
||||
ui->checkBox_VPN->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN);
|
||||
ui->checkBox_SystemProxy->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY);
|
||||
ui->checkBox_VPN->setChecked(NekoRay::dataStore->spmode_vpn);
|
||||
ui->checkBox_SystemProxy->setChecked(NekoRay::dataStore->spmode_system_proxy);
|
||||
if (select_mode) ui->label_running->setText("[" + tr("Select") + "]");
|
||||
|
||||
auto make_title = [=](bool isTray) {
|
||||
@@ -747,11 +786,8 @@ void MainWindow::refresh_status(const QString &traffic_update) {
|
||||
#endif
|
||||
if (select_mode) tt << "[" + tr("Select") + "]";
|
||||
if (!title_error.isEmpty()) tt << "[" + title_error + "]";
|
||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
||||
tt << "[" + tr("System Proxy") + "]";
|
||||
} else if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) {
|
||||
tt << "[" + tr("VPN Mode") + "]";
|
||||
}
|
||||
if (NekoRay::dataStore->spmode_vpn) tt << "[VPN]";
|
||||
if (NekoRay::dataStore->spmode_system_proxy) tt << "[" + tr("System Proxy") + "]";
|
||||
tt << software_name;
|
||||
if (!isTray) tt << "(" + QString(NKR_VERSION) + ")";
|
||||
if (!NekoRay::dataStore->active_routing.isEmpty() && NekoRay::dataStore->active_routing != "Default") {
|
||||
@@ -762,13 +798,16 @@ void MainWindow::refresh_status(const QString &traffic_update) {
|
||||
};
|
||||
|
||||
auto icon_status_new = Icon::NONE;
|
||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
||||
icon_status_new = Icon::SYSTEM_PROXY;
|
||||
} else if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) {
|
||||
|
||||
if (!running.isNull()) {
|
||||
if (NekoRay::dataStore->spmode_vpn) {
|
||||
icon_status_new = Icon::VPN;
|
||||
} else if (!running.isNull()) {
|
||||
} else if (NekoRay::dataStore->spmode_system_proxy) {
|
||||
icon_status_new = Icon::SYSTEM_PROXY;
|
||||
} else {
|
||||
icon_status_new = Icon::RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
// refresh title & window icon
|
||||
setWindowTitle(make_title(false));
|
||||
@@ -1677,11 +1716,10 @@ bool MainWindow::StartVPNProcess() {
|
||||
runOnNewThread([=] {
|
||||
vpn_pid = 1; // TODO get pid?
|
||||
WinCommander::runProcessElevated(QApplication::applicationDirPath() + "/nekobox_core.exe",
|
||||
{"--disable-color", "run", "-c", configPath},
|
||||
"",
|
||||
NekoRay::dataStore->vpn_hide_console); // blocking
|
||||
{"--disable-color", "run", "-c", configPath}, "",
|
||||
NekoRay::dataStore->vpn_hide_console ? WinCommander::SW_HIDE : WinCommander::SW_SHOWMINIMIZED); // blocking
|
||||
vpn_pid = 0;
|
||||
runOnUiThread([=] { neko_set_spmode(NekoRay::SystemProxyMode::DISABLE); });
|
||||
runOnUiThread([=] { neko_set_spmode_vpn(false); });
|
||||
});
|
||||
#else
|
||||
QFile::remove(protectPath);
|
||||
@@ -1695,7 +1733,7 @@ bool MainWindow::StartVPNProcess() {
|
||||
if (state == QProcess::NotRunning) {
|
||||
vpn_pid = 0;
|
||||
vpn_process->deleteLater();
|
||||
GetMainWindow()->neko_set_spmode(NekoRay::SystemProxyMode::DISABLE);
|
||||
GetMainWindow()->neko_set_spmode_vpn(false);
|
||||
}
|
||||
});
|
||||
//
|
||||
@@ -1704,11 +1742,7 @@ bool MainWindow::StartVPNProcess() {
|
||||
vpn_process->start("osascript", {"-e", QString("do shell script \"%1\" with administrator privileges")
|
||||
.arg("bash " + scriptPath)});
|
||||
#else
|
||||
if (NekoRay::dataStore->vpn_already_admin) {
|
||||
vpn_process->start("bash", {scriptPath});
|
||||
} else {
|
||||
vpn_process->start("pkexec", {"bash", scriptPath});
|
||||
}
|
||||
#endif
|
||||
vpn_process->waitForStarted();
|
||||
vpn_pid = vpn_process->processId(); // actually it's pkexec or bash PID
|
||||
@@ -1731,15 +1765,11 @@ bool MainWindow::StopVPNProcess(bool unconditional) {
|
||||
p.start("osascript", {"-e", QString("do shell script \"%1\" with administrator privileges")
|
||||
.arg("pkill -2 -U 0 nekobox_core")});
|
||||
#else
|
||||
if (NekoRay::dataStore->vpn_already_admin) {
|
||||
p.start("bash", {"kill", "-2", Int2String(vpn_pid)});
|
||||
} else {
|
||||
if (unconditional) {
|
||||
p.start("pkexec", {"killall", "-2", "nekobox_core"});
|
||||
} else {
|
||||
p.start("pkexec", {"pkill", "-2", "-P", Int2String(vpn_pid)});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
p.waitForFinished();
|
||||
ok = p.exitCode() == 0;
|
||||
|
||||
@@ -51,7 +51,9 @@ public:
|
||||
|
||||
void neko_stop(bool crash = false);
|
||||
|
||||
void neko_set_spmode(int mode, bool save = true);
|
||||
void neko_set_spmode_system_proxy(bool enable, bool save = true);
|
||||
|
||||
void neko_set_spmode_vpn(bool enable, bool save = true);
|
||||
|
||||
void show_log_impl(const QString &log);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user