mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 12:34:37 +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,
|
uint WinCommander::runProcessElevated(const QString &path,
|
||||||
const QStringList ¶meters,
|
const QStringList ¶meters,
|
||||||
const QString &workingDir,
|
const QString &workingDir,
|
||||||
bool hide, bool aWait) {
|
int nShow, bool aWait) {
|
||||||
uint result = 0;
|
uint result = 0;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@@ -79,7 +79,7 @@ uint WinCommander::runProcessElevated(const QString &path,
|
|||||||
shex.lpParameters = pszParameters;
|
shex.lpParameters = pszParameters;
|
||||||
shex.lpDirectory = pszDirectory;
|
shex.lpDirectory = pszDirectory;
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
|
// 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);
|
ShellExecuteEx(&shex);
|
||||||
if (shex.hProcess)
|
if (shex.hProcess)
|
||||||
|
|||||||
6
3rdparty/WinCommander.hpp
vendored
6
3rdparty/WinCommander.hpp
vendored
@@ -28,10 +28,14 @@
|
|||||||
|
|
||||||
class WinCommander {
|
class WinCommander {
|
||||||
public:
|
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,
|
static uint runProcessElevated(const QString &path,
|
||||||
const QStringList ¶meters = QStringList(),
|
const QStringList ¶meters = QStringList(),
|
||||||
const QString &workingDir = QString(),
|
const QString &workingDir = QString(),
|
||||||
bool hide = false, bool aWait = true);
|
int nShow = SW_SHOWMINIMIZED, bool aWait = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINCOMMANDER_H
|
#endif // WINCOMMANDER_H
|
||||||
@@ -40,6 +40,11 @@ QJsonObject JsonEditor::OpenEditor() {
|
|||||||
auto string = jsonEditor->toPlainText();
|
auto string = jsonEditor->toPlainText();
|
||||||
|
|
||||||
while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) {
|
while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) {
|
||||||
|
if (string.isEmpty()) {
|
||||||
|
resultCode = QDialog::Accepted;
|
||||||
|
final = {};
|
||||||
|
break;
|
||||||
|
}
|
||||||
QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"),
|
QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"),
|
||||||
tr("You must correct these errors before continuing."));
|
tr("You must correct these errors before continuing."));
|
||||||
resultCode = this->exec();
|
resultCode = this->exec();
|
||||||
|
|||||||
@@ -13,6 +13,24 @@
|
|||||||
|
|
||||||
namespace NekoRay {
|
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) {
|
void MergeJson(const QJsonObject &custom, QJsonObject &outbound) {
|
||||||
// 合并
|
// 合并
|
||||||
if (custom.isEmpty()) return;
|
if (custom.isEmpty()) return;
|
||||||
@@ -215,8 +233,8 @@ namespace NekoRay {
|
|||||||
{"tag", "block"},
|
{"tag", "block"},
|
||||||
};
|
};
|
||||||
|
|
||||||
// DNS Routing
|
// DNS out
|
||||||
if (dataStore->dns_routing && !status->forTest) {
|
if (!status->forTest) {
|
||||||
QJsonObject dnsOut;
|
QJsonObject dnsOut;
|
||||||
dnsOut["protocol"] = "dns";
|
dnsOut["protocol"] = "dns";
|
||||||
dnsOut["tag"] = "dns-out";
|
dnsOut["tag"] = "dns-out";
|
||||||
@@ -300,7 +318,7 @@ namespace NekoRay {
|
|||||||
// Routing
|
// Routing
|
||||||
QJsonObject routing;
|
QJsonObject routing;
|
||||||
routing["domainStrategy"] = dataStore->domain_strategy;
|
routing["domainStrategy"] = dataStore->domain_strategy;
|
||||||
routing["domainMatcher"] = dataStore->domain_matcher == DomainMatcher::MPH ? "mph" : "linear";
|
routing["domainMatcher"] = "mph";
|
||||||
if (status->forTest) routing["domainStrategy"] = "AsIs";
|
if (status->forTest) routing["domainStrategy"] = "AsIs";
|
||||||
|
|
||||||
// final add user rule (block)
|
// final add user rule (block)
|
||||||
@@ -457,7 +475,12 @@ namespace NekoRay {
|
|||||||
// chain rules: this
|
// chain rules: this
|
||||||
auto ext_mapping_port = 0;
|
auto ext_mapping_port = 0;
|
||||||
auto ext_socks_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
|
// determine port
|
||||||
if (thisExternalStat > 0) {
|
if (thisExternalStat > 0) {
|
||||||
if (ent->type == "custom") {
|
if (ent->type == "custom") {
|
||||||
@@ -658,9 +681,28 @@ namespace NekoRay {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// apply domain_strategy
|
inboundObj["domain_strategy"] = dataStore->domain_strategy;
|
||||||
inboundObj["domain_strategy"] = dataStore->outbound_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;
|
status->inbounds += inboundObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,7 +847,12 @@ namespace NekoRay {
|
|||||||
// Routing
|
// Routing
|
||||||
|
|
||||||
// dns hijack
|
// 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
|
// sing-box routing rule object
|
||||||
auto add_rule_route = [&](const QStringList &list, bool isIP, const QString &out) {
|
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->domainListRemote, false, tagProxy);
|
||||||
add_rule_route(status->domainListDirect, false, "bypass");
|
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
|
// geopath
|
||||||
auto geoip = FindCoreAsset("geoip.db");
|
auto geoip = FindCoreAsset("geoip.db");
|
||||||
auto geosite = FindCoreAsset("geosite.db");
|
auto geosite = FindCoreAsset("geosite.db");
|
||||||
@@ -836,7 +926,7 @@ namespace NekoRay {
|
|||||||
QJSONARRAY_ADD(routingRules, status->routingRules)
|
QJSONARRAY_ADD(routingRules, status->routingRules)
|
||||||
auto routeObj = QJsonObject{
|
auto routeObj = QJsonObject{
|
||||||
{"rules", routingRules},
|
{"rules", routingRules},
|
||||||
{"auto_detect_interface", NekoRay::dataStore->core_box_auto_detect_interface},
|
{"auto_detect_interface", dataStore->spmode_vpn},
|
||||||
{
|
{
|
||||||
"geoip",
|
"geoip",
|
||||||
QJsonObject{
|
QJsonObject{
|
||||||
@@ -873,9 +963,10 @@ namespace NekoRay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString WriteVPNSingBoxConfig() {
|
QString WriteVPNSingBoxConfig() {
|
||||||
|
// tun user rule
|
||||||
auto match_out = NekoRay::dataStore->vpn_rule_white ? "nekoray-socks" : "direct";
|
auto match_out = NekoRay::dataStore->vpn_rule_white ? "nekoray-socks" : "direct";
|
||||||
auto no_match_out = NekoRay::dataStore->vpn_rule_white ? "direct" : "nekoray-socks";
|
auto no_match_out = NekoRay::dataStore->vpn_rule_white ? "direct" : "nekoray-socks";
|
||||||
// user rule
|
|
||||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
||||||
if (!process_name_rule.isEmpty()) {
|
if (!process_name_rule.isEmpty()) {
|
||||||
auto arr = SplitLinesSkipSharp(process_name_rule);
|
auto arr = SplitLinesSkipSharp(process_name_rule);
|
||||||
@@ -883,6 +974,7 @@ namespace NekoRay {
|
|||||||
{"process_name", QList2QJsonArray(arr)}};
|
{"process_name", QList2QJsonArray(arr)}};
|
||||||
process_name_rule = "," + QJsonObject2QString(rule, false);
|
process_name_rule = "," + QJsonObject2QString(rule, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString cidr_rule = dataStore->vpn_rule_cidr.trimmed();
|
QString cidr_rule = dataStore->vpn_rule_cidr.trimmed();
|
||||||
if (!cidr_rule.isEmpty()) {
|
if (!cidr_rule.isEmpty()) {
|
||||||
auto arr = SplitLinesSkipSharp(cidr_rule);
|
auto arr = SplitLinesSkipSharp(cidr_rule);
|
||||||
@@ -890,11 +982,9 @@ namespace NekoRay {
|
|||||||
{"ip_cidr", QList2QJsonArray(arr)}};
|
{"ip_cidr", QList2QJsonArray(arr)}};
|
||||||
cidr_rule = "," + QJsonObject2QString(rule, false);
|
cidr_rule = "," + QJsonObject2QString(rule, false);
|
||||||
}
|
}
|
||||||
// tun name
|
|
||||||
auto tun_name = "nekoray-tun";
|
// TODO bypass ext core process path?
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
tun_name = "utun9";
|
|
||||||
#endif
|
|
||||||
// auth
|
// auth
|
||||||
QString socks_user_pass;
|
QString socks_user_pass;
|
||||||
if (dataStore->inbound_auth->NeedAuth()) {
|
if (dataStore->inbound_auth->NeedAuth()) {
|
||||||
@@ -910,7 +1000,7 @@ namespace NekoRay {
|
|||||||
.replace("%STACK%", Preset::SingBox::VpnImplementation.value(dataStore->vpn_implementation))
|
.replace("%STACK%", Preset::SingBox::VpnImplementation.value(dataStore->vpn_implementation))
|
||||||
.replace("%PROCESS_NAME_RULE%", process_name_rule)
|
.replace("%PROCESS_NAME_RULE%", process_name_rule)
|
||||||
.replace("%CIDR_RULE%", cidr_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("%STRICT_ROUTE%", dataStore->vpn_strict_route ? "true" : "false")
|
||||||
.replace("%SOCKS_USER_PASS%", socks_user_pass)
|
.replace("%SOCKS_USER_PASS%", socks_user_pass)
|
||||||
.replace("%FINAL_OUT%", no_match_out)
|
.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 {}; };
|
virtual CoreObjOutboundBuildResult BuildCoreObjV2Ray() { return {}; };
|
||||||
|
|
||||||
|
|||||||
@@ -20,38 +20,50 @@
|
|||||||
auto TempFile = QFileInfo(f).absoluteFilePath();
|
auto TempFile = QFileInfo(f).absoluteFilePath();
|
||||||
|
|
||||||
namespace NekoRay::fmt {
|
namespace NekoRay::fmt {
|
||||||
|
// -1: Cannot use this config
|
||||||
// 0: Internal
|
// 0: Internal
|
||||||
// 1: Mapping External
|
// 1: Mapping External
|
||||||
// 2: Direct External
|
// 2: Direct External
|
||||||
|
|
||||||
int NaiveBean::NeedExternal(bool isFirstProfile, bool isVPN) {
|
int NaiveBean::NeedExternal(bool isFirstProfile) {
|
||||||
if (isFirstProfile && !isVPN) {
|
if (isFirstProfile) {
|
||||||
|
if (dataStore->spmode_vpn) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return 1;
|
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 (IS_NEKO_BOX) {
|
||||||
if (protocol == hysteria_protocol_udp && hopPort.trimmed().isEmpty()) {
|
if (protocol == hysteria_protocol_udp && hopPort.trimmed().isEmpty()) {
|
||||||
// sing-box support
|
// sing-box support
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// hysteria core support
|
// hysteria core support
|
||||||
if (isFirstProfile && !isVPN) {
|
return hysteriaCore();
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isFirstProfile && !isVPN) {
|
return hysteriaCore();
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CustomBean::NeedExternal(bool isFirstProfile, bool isVPN) {
|
int CustomBean::NeedExternal(bool isFirstProfile) {
|
||||||
if (core == "internal" || core == "internal-full") return 0;
|
if (core == "internal" || core == "internal-full") return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -99,8 +111,8 @@ namespace NekoRay::fmt {
|
|||||||
|
|
||||||
// determine server format
|
// determine server format
|
||||||
auto is_direct = external_stat == 2;
|
auto is_direct = external_stat == 2;
|
||||||
auto sni2 = sni;
|
auto sniGen = sni;
|
||||||
if (sni.isEmpty() && is_direct) sni2 = serverAddress;
|
if (sni.isEmpty() && !IsIpAddress(serverAddress)) sniGen = serverAddress;
|
||||||
|
|
||||||
auto server = serverAddress;
|
auto server = serverAddress;
|
||||||
if (!hopPort.trimmed().isEmpty()) {
|
if (!hopPort.trimmed().isEmpty()) {
|
||||||
@@ -130,7 +142,7 @@ namespace NekoRay::fmt {
|
|||||||
if (protocol == hysteria_protocol_facktcp) config["protocol"] = "faketcp";
|
if (protocol == hysteria_protocol_facktcp) config["protocol"] = "faketcp";
|
||||||
if (protocol == hysteria_protocol_wechat_video) config["protocol"] = "wechat-video";
|
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 (!alpn.isEmpty()) config["alpn"] = alpn;
|
||||||
|
|
||||||
if (!caText.trimmed().isEmpty()) {
|
if (!caText.trimmed().isEmpty()) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace NekoRay::fmt {
|
|||||||
return core;
|
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 {
|
QString DisplayAddress() override {
|
||||||
if (core == "internal") {
|
if (core == "internal") {
|
||||||
@@ -47,7 +47,7 @@ namespace NekoRay::fmt {
|
|||||||
return AbstractBean::DisplayAddress();
|
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;
|
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ namespace NekoRay::fmt {
|
|||||||
return ::DisplayAddress(serverAddress, serverPort);
|
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"; };
|
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;
|
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace NekoRay::fmt {
|
|||||||
|
|
||||||
QString DisplayType() override { return "Naive"; };
|
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;
|
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("sing-box-extra:", boxbox.Version(), "NekoBox:", neko_common.Version_neko)
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
// local DNS transport
|
|
||||||
_ = os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",netdns=go")
|
|
||||||
|
|
||||||
// nekobox_core
|
// nekobox_core
|
||||||
if len(os.Args) > 1 && os.Args[1] == "nekobox" {
|
if len(os.Args) > 1 && os.Args[1] == "nekobox" {
|
||||||
neko_common.RunMode = neko_common.RunMode_NekoBox_Core
|
neko_common.RunMode = neko_common.RunMode_NekoBox_Core
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
sudo apt install fuse -y
|
sudo apt-get install fuse -y
|
||||||
|
|
||||||
cp -r linux64 nekoray.AppDir
|
cp -r linux64 nekoray.AppDir
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ chmod +x nekoray.AppDir/AppRun
|
|||||||
|
|
||||||
# build
|
# 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
|
chmod +x appimagetool-x86_64.AppImage
|
||||||
./appimagetool-x86_64.AppImage nekoray.AppDir
|
./appimagetool-x86_64.AppImage nekoray.AppDir
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,6 @@ namespace NekoRay {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace SystemProxyMode {
|
|
||||||
enum SystemProxyMode {
|
|
||||||
DISABLE,
|
|
||||||
SYSTEM_PROXY,
|
|
||||||
VPN,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CoreType {
|
namespace CoreType {
|
||||||
enum CoreType {
|
enum CoreType {
|
||||||
V2RAY,
|
V2RAY,
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ namespace NekoRay {
|
|||||||
_add(new configItem("remote_dns_strategy", &remote_dns_strategy, itemType::string));
|
_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", &direct_dns, itemType::string));
|
||||||
_add(new configItem("direct_dns_strategy", &direct_dns_strategy, 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("domain_strategy", &domain_strategy, itemType::string));
|
||||||
_add(new configItem("outbound_domain_strategy", &outbound_domain_strategy, itemType::string));
|
_add(new configItem("outbound_domain_strategy", &outbound_domain_strategy, itemType::string));
|
||||||
_add(new configItem("sniffing_mode", &sniffing_mode, itemType::integer));
|
_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_id", &remember_id, itemType::integer));
|
||||||
_add(new configItem("remember_enable", &remember_enable, itemType::boolean));
|
_add(new configItem("remember_enable", &remember_enable, itemType::boolean));
|
||||||
_add(new configItem("language", &language, itemType::integer));
|
_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("skip_cert", &skip_cert, itemType::boolean));
|
||||||
_add(new configItem("hk_mw", &hotkey_mainwindow, itemType::string));
|
_add(new configItem("hk_mw", &hotkey_mainwindow, itemType::string));
|
||||||
_add(new configItem("hk_group", &hotkey_group, 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("max_log_line", &max_log_line, itemType::integer));
|
||||||
_add(new configItem("splitter_state", &splitter_state, itemType::string));
|
_add(new configItem("splitter_state", &splitter_state, itemType::string));
|
||||||
_add(new configItem("utlsFingerprint", &utlsFingerprint, 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", &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_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_box_underlying_dns", &core_box_underlying_dns, itemType::string));
|
||||||
_add(new configItem("core_ray_direct_dns", &core_ray_direct_dns, itemType::boolean));
|
_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("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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,5 +14,6 @@ namespace NekoRay {
|
|||||||
} // namespace NekoRay
|
} // namespace NekoRay
|
||||||
|
|
||||||
#define IS_NEKO_BOX (NekoRay::coreType == NekoRay::CoreType::SING_BOX)
|
#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_NAME QString(IS_NEKO_BOX ? "routes_box" : "routes")
|
||||||
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ namespace NekoRay {
|
|||||||
int started_id = -1919;
|
int started_id = -1919;
|
||||||
bool core_running = false;
|
bool core_running = false;
|
||||||
bool core_prepare_exit = 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;
|
bool need_keep_vpn_off = false;
|
||||||
QStringList ignoreConnTag = {};
|
QStringList ignoreConnTag = {};
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ namespace NekoRay {
|
|||||||
QString utlsFingerprint = "";
|
QString utlsFingerprint = "";
|
||||||
|
|
||||||
// Remember
|
// Remember
|
||||||
int remember_spmode = NekoRay::SystemProxyMode::DISABLE;
|
QStringList remember_spmode = {};
|
||||||
int remember_id = -1919;
|
int remember_id = -1919;
|
||||||
bool remember_enable = false;
|
bool remember_enable = false;
|
||||||
|
|
||||||
@@ -127,18 +128,17 @@ namespace NekoRay {
|
|||||||
QString domain_strategy = "AsIs";
|
QString domain_strategy = "AsIs";
|
||||||
QString outbound_domain_strategy = "AsIs";
|
QString outbound_domain_strategy = "AsIs";
|
||||||
int sniffing_mode = SniffingMode::FOR_ROUTING;
|
int sniffing_mode = SniffingMode::FOR_ROUTING;
|
||||||
int domain_matcher = DomainMatcher::MPH;
|
|
||||||
QString custom_route_global = "{\"rules\": []}";
|
QString custom_route_global = "{\"rules\": []}";
|
||||||
QString active_routing = "Default";
|
QString active_routing = "Default";
|
||||||
|
|
||||||
// VPN
|
// VPN
|
||||||
|
bool vpn_internal_tun = true;
|
||||||
int vpn_implementation = 0;
|
int vpn_implementation = 0;
|
||||||
int vpn_mtu = 9000;
|
int vpn_mtu = 9000;
|
||||||
bool vpn_ipv6 = false;
|
bool vpn_ipv6 = false;
|
||||||
bool vpn_hide_console = false;
|
bool vpn_hide_console = false;
|
||||||
bool vpn_strict_route = false;
|
bool vpn_strict_route = false;
|
||||||
bool vpn_rule_white = false;
|
bool vpn_rule_white = false;
|
||||||
bool vpn_already_admin = false; // not saved on Windows
|
|
||||||
QString vpn_rule_process = "";
|
QString vpn_rule_process = "";
|
||||||
QString vpn_rule_cidr = "";
|
QString vpn_rule_cidr = "";
|
||||||
|
|
||||||
@@ -149,7 +149,6 @@ namespace NekoRay {
|
|||||||
QString hotkey_system_proxy_menu = "";
|
QString hotkey_system_proxy_menu = "";
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
bool core_box_auto_detect_interface = true;
|
|
||||||
int core_box_clash_api = -9090;
|
int core_box_clash_api = -9090;
|
||||||
QString core_box_clash_api_secret = "";
|
QString core_box_clash_api_secret = "";
|
||||||
QString core_box_underlying_dns = "";
|
QString core_box_underlying_dns = "";
|
||||||
|
|||||||
@@ -91,19 +91,11 @@
|
|||||||
<source>Use proxy when updating subscription</source>
|
<source>Use proxy when updating subscription</source>
|
||||||
<translation>استفاده از پروکسی زمانی که اشتراک را بروزرسانی می کنید</translation>
|
<translation>استفاده از پروکسی زمانی که اشتراک را بروزرسانی می کنید</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Language</source>
|
|
||||||
<translation type="vanished">زبان</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Security</source>
|
<source>Security</source>
|
||||||
<translatorcomment>امنیت security</translatorcomment>
|
<translatorcomment>امنیت security</translatorcomment>
|
||||||
<translation>امنیت</translation>
|
<translation>امنیت</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Insecure hint</source>
|
|
||||||
<translation type="vanished">اشاره ناامن</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Statistics refresh rate</source>
|
<source>Statistics refresh rate</source>
|
||||||
<translation>نرخ تازه سازی آمار ترافیک</translation>
|
<translation>نرخ تازه سازی آمار ترافیک</translation>
|
||||||
@@ -357,10 +349,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod
|
|||||||
<source>Network Settings (%1)</source>
|
<source>Network Settings (%1)</source>
|
||||||
<translation>تنظیمات شبکه (1%)</translation>
|
<translation>تنظیمات شبکه (1%)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Security Settings</source>
|
|
||||||
<translation type="vanished">تنظیمات امنیت</translation>
|
|
||||||
</message>
|
|
||||||
<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>
|
<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>
|
<translation type="unfinished"></translation>
|
||||||
@@ -503,14 +491,6 @@ These settings can be changed later.</source>
|
|||||||
<source>Disable</source>
|
<source>Disable</source>
|
||||||
<translation>غیرفعال کردن</translation>
|
<translation>غیرفعال کردن</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Remote DNS</source>
|
<source>Remote DNS</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@@ -523,14 +503,6 @@ These settings can be changed later.</source>
|
|||||||
<source>Enable DNS Routing</source>
|
<source>Enable DNS Routing</source>
|
||||||
<translation>فعال کردن مسیریابی DNS</translation>
|
<translation>فعال کردن مسیریابی DNS</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>V2Ray Domain Strategy</source>
|
|
||||||
<translation>استراتژی دامنه</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Matcher</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Block</source>
|
<source>Block</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@@ -607,16 +579,28 @@ These settings can be changed later.</source>
|
|||||||
<source>Default Outbound</source>
|
<source>Default Outbound</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Query Strategy</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Remote</source>
|
<source>Remote</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<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>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@@ -682,11 +666,12 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</source>
|
|||||||
<translation type="unfinished">لغو کردن</translation>
|
<translation type="unfinished">لغو کردن</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Don't ask for privilege elevation</source>
|
<source>Internal Tun</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<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>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@@ -1336,14 +1321,6 @@ Split by line.</source>
|
|||||||
<source>Clear</source>
|
<source>Clear</source>
|
||||||
<translation>پاک کردن</translation>
|
<translation>پاک کردن</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>End</source>
|
|
||||||
<translation type="vanished">پایان</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Active</source>
|
|
||||||
<translation type="vanished">فعال</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Start: %1
|
<source>Start: %1
|
||||||
End: %2</source>
|
End: %2</source>
|
||||||
@@ -1373,10 +1350,6 @@ End: %2</source>
|
|||||||
<source>Starting profile %1</source>
|
<source>Starting profile %1</source>
|
||||||
<translation>اغاز پروفایل %1</translation>
|
<translation>اغاز پروفایل %1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Profile is insecure: %1</source>
|
|
||||||
<translation type="vanished">پروفایل ناامن می باشد: %1</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Stopping profile %1</source>
|
<source>Stopping profile %1</source>
|
||||||
<translation>متوقف کردن پروفایل %1</translation>
|
<translation>متوقف کردن پروفایل %1</translation>
|
||||||
@@ -1405,13 +1378,13 @@ End: %2</source>
|
|||||||
<source>Restart nekoray to take effect.</source>
|
<source>Restart nekoray to take effect.</source>
|
||||||
<translation type="unfinished">برای اعمال تغییرات nekoray را مجددا راه اندازی کنید.</translation>
|
<translation type="unfinished">برای اعمال تغییرات nekoray را مجددا راه اندازی کنید.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Please run NekoBox as admin</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ProxyItem</name>
|
<name>ProxyItem</name>
|
||||||
<message>
|
|
||||||
<source>Remove</source>
|
|
||||||
<translation type="vanished">حذف کردن</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Confirmation</source>
|
<source>Confirmation</source>
|
||||||
<translation>تائیدیه</translation>
|
<translation>تائیدیه</translation>
|
||||||
|
|||||||
@@ -95,10 +95,6 @@
|
|||||||
<source>Security</source>
|
<source>Security</source>
|
||||||
<translation>安全</translation>
|
<translation>安全</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Insecure hint</source>
|
|
||||||
<translation type="vanished">提示不安全的配置</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Statistics refresh rate</source>
|
<source>Statistics refresh rate</source>
|
||||||
<translation>流量统计刷新率</translation>
|
<translation>流量统计刷新率</translation>
|
||||||
@@ -494,11 +490,11 @@ These settings can be changed later.</source>
|
|||||||
<translation>流量探测</translation>
|
<translation>流量探测</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The sniffing result is used for routing</source>
|
<source>Sniff result for routing</source>
|
||||||
<translation>探测结果用于路由判断</translation>
|
<translation>探测结果用于路由判断</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The sniffing result is used for destination</source>
|
<source>Sniff result for destination</source>
|
||||||
<translation>探测结果用于目标地址</translation>
|
<translation>探测结果用于目标地址</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@@ -513,14 +509,6 @@ These settings can be changed later.</source>
|
|||||||
<source>Enable DNS Routing</source>
|
<source>Enable DNS Routing</source>
|
||||||
<translation>启用 DNS 路由</translation>
|
<translation>启用 DNS 路由</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>V2Ray Domain Strategy</source>
|
|
||||||
<translation>域名策略</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Matcher</source>
|
|
||||||
<translation>域名匹配器</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Block</source>
|
<source>Block</source>
|
||||||
<translation>阻止</translation>
|
<translation>阻止</translation>
|
||||||
@@ -597,17 +585,21 @@ These settings can be changed later.</source>
|
|||||||
<source>Default Outbound</source>
|
<source>Default Outbound</source>
|
||||||
<translation>默认出站</translation>
|
<translation>默认出站</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Query Strategy</source>
|
|
||||||
<translation>DNS 查询策略</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Remote</source>
|
<source>Remote</source>
|
||||||
<translation>远程</translation>
|
<translation>远程</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Inbound & Outbound Domain Strategy</source>
|
<source>DNS Query Strategy</source>
|
||||||
<translation>出入站域名策略</translation>
|
<translation>DNS 查询策略</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Domain Strategy</source>
|
||||||
|
<translation>域名策略</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Server Address Strategy</source>
|
||||||
|
<translation>服务器地址策略</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -675,12 +667,14 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
|
|||||||
<translation>取消</translation>
|
<translation>取消</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Don't ask for privilege elevation</source>
|
<source>Internal Tun</source>
|
||||||
<translation>不请求特权提升</translation>
|
<translation>内部 Tun</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Already Admin</source>
|
<source>Add a tun inbound to the profile startup, instead of using two processes.
|
||||||
<translation>已是管理员</translation>
|
This needs to be run NekoBox with administrator privileges.</source>
|
||||||
|
<translation>在配置文件启动时添加一个tun inbound,而不是使用两个进程。
|
||||||
|
这需要以管理员权限运行NekoBox。</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -1189,10 +1183,6 @@ End: %2</source>
|
|||||||
<source>Move %1 item(s)</source>
|
<source>Move %1 item(s)</source>
|
||||||
<translation>移动 %1 个项目</translation>
|
<translation>移动 %1 个项目</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Profile is insecure: %1</source>
|
|
||||||
<translation type="vanished">配置不安全: %1</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Remove Unavailable</source>
|
<source>Remove Unavailable</source>
|
||||||
<translation>删除不可用的配置</translation>
|
<translation>删除不可用的配置</translation>
|
||||||
@@ -1395,6 +1385,10 @@ Split by line.</source>
|
|||||||
<source>Restart nekoray to take effect.</source>
|
<source>Restart nekoray to take effect.</source>
|
||||||
<translation>重启 nekoray 生效。</translation>
|
<translation>重启 nekoray 生效。</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Please run NekoBox as admin</source>
|
||||||
|
<translation>请以管理员权限运行 NekoBox</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ProxyItem</name>
|
<name>ProxyItem</name>
|
||||||
@@ -1498,26 +1492,6 @@ Release note:
|
|||||||
<source>Chain Proxy</source>
|
<source>Chain Proxy</source>
|
||||||
<translation>链式代理</translation>
|
<translation>链式代理</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Requesting subscription: %1</source>
|
<source>Requesting subscription: %1</source>
|
||||||
<translation>正在请求订阅: %1</translation>
|
<translation>正在请求订阅: %1</translation>
|
||||||
@@ -1534,10 +1508,6 @@ As of January 1, 2022, compatibility with MD5 authentication information will be
|
|||||||
<source>Change of %1:</source>
|
<source>Change of %1:</source>
|
||||||
<translation>%1 变化:</translation>
|
<translation>%1 变化:</translation>
|
||||||
</message>
|
</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>
|
<message>
|
||||||
<source>Select</source>
|
<source>Select</source>
|
||||||
<translation>选择</translation>
|
<translation>选择</translation>
|
||||||
|
|||||||
@@ -392,7 +392,6 @@ void DialogBasicSettings::on_core_settings_clicked() {
|
|||||||
w->setLayout(layout);
|
w->setLayout(layout);
|
||||||
//
|
//
|
||||||
auto line = -1;
|
auto line = -1;
|
||||||
QCheckBox *core_box_auto_detect_interface;
|
|
||||||
QCheckBox *core_box_enable_clash_api;
|
QCheckBox *core_box_enable_clash_api;
|
||||||
MyLineEdit *core_box_clash_api;
|
MyLineEdit *core_box_clash_api;
|
||||||
MyLineEdit *core_box_clash_api_secret;
|
MyLineEdit *core_box_clash_api_secret;
|
||||||
@@ -412,12 +411,6 @@ void DialogBasicSettings::on_core_settings_clicked() {
|
|||||||
layout->addWidget(core_box_underlying_dns, line, 1);
|
layout->addWidget(core_box_underlying_dns, line, 1);
|
||||||
//
|
//
|
||||||
if (IS_NEKO_BOX) {
|
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");
|
auto core_box_enable_clash_api_l = new QLabel("Enable Clash API");
|
||||||
core_box_enable_clash_api = new QCheckBox;
|
core_box_enable_clash_api = new QCheckBox;
|
||||||
core_box_enable_clash_api->setChecked(NekoRay::dataStore->core_box_clash_api > 0);
|
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, [=] {
|
connect(box, &QDialogButtonBox::accepted, w, [=] {
|
||||||
NekoRay::dataStore->core_box_underlying_dns = core_box_underlying_dns->text();
|
NekoRay::dataStore->core_box_underlying_dns = core_box_underlying_dns->text();
|
||||||
if (IS_NEKO_BOX) {
|
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 = 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();
|
NekoRay::dataStore->core_box_clash_api_secret = core_box_clash_api_secret->text();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -31,16 +31,15 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(ne
|
|||||||
title_base = windowTitle();
|
title_base = windowTitle();
|
||||||
|
|
||||||
if (IS_NEKO_BOX) {
|
if (IS_NEKO_BOX) {
|
||||||
ui->domain_v2ray->setVisible(false);
|
|
||||||
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
ui->outbound_domain_strategy->addItems(Preset::SingBox::DomainStrategy);
|
||||||
|
ui->domainStrategyCombo->addItems(Preset::SingBox::DomainStrategy);
|
||||||
} else {
|
} else {
|
||||||
ui->domain_v2ray->setVisible(true);
|
|
||||||
ui->outbound_domain_strategy->addItems({"AsIs", "UseIPv4", "UseIPv6", "PreferIPv4", "PreferIPv6"});
|
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->sniffing_mode->setCurrentIndex(NekoRay::dataStore->sniffing_mode);
|
||||||
ui->outbound_domain_strategy->setCurrentText(NekoRay::dataStore->outbound_domain_strategy);
|
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->domainStrategyCombo->setCurrentText(NekoRay::dataStore->domain_strategy);
|
||||||
ui->dns_routing->setChecked(NekoRay::dataStore->dns_routing);
|
ui->dns_routing->setChecked(NekoRay::dataStore->dns_routing);
|
||||||
ui->dns_remote->setText(NekoRay::dataStore->remote_dns);
|
ui->dns_remote->setText(NekoRay::dataStore->remote_dns);
|
||||||
@@ -88,7 +87,6 @@ DialogManageRoutes::~DialogManageRoutes() {
|
|||||||
|
|
||||||
void DialogManageRoutes::accept() {
|
void DialogManageRoutes::accept() {
|
||||||
NekoRay::dataStore->sniffing_mode = ui->sniffing_mode->currentIndex();
|
NekoRay::dataStore->sniffing_mode = ui->sniffing_mode->currentIndex();
|
||||||
NekoRay::dataStore->domain_matcher = ui->domainMatcherCombo->currentIndex();
|
|
||||||
NekoRay::dataStore->domain_strategy = ui->domainStrategyCombo->currentText();
|
NekoRay::dataStore->domain_strategy = ui->domainStrategyCombo->currentText();
|
||||||
NekoRay::dataStore->outbound_domain_strategy = ui->outbound_domain_strategy->currentText();
|
NekoRay::dataStore->outbound_domain_strategy = ui->outbound_domain_strategy->currentText();
|
||||||
NekoRay::dataStore->dns_routing = ui->dns_routing->isChecked();
|
NekoRay::dataStore->dns_routing = ui->dns_routing->isChecked();
|
||||||
|
|||||||
@@ -21,12 +21,6 @@
|
|||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Sniffing Mode</string>
|
<string>Sniffing Mode</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -41,33 +35,38 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>The sniffing result is used for routing</string>
|
<string>Sniff result for routing</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>The sniffing result is used for destination</string>
|
<string>Sniff result for destination</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_4">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="orientation">
|
<property name="toolTip">
|
||||||
<enum>Qt::Vertical</enum>
|
<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>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<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">
|
<property name="text">
|
||||||
<string>Inbound & Outbound Domain Strategy</string>
|
<string>Server Address Strategy</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -111,12 +110,6 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="dns_routing">
|
<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">
|
<property name="text">
|
||||||
<string>Enable DNS Routing</string>
|
<string>Enable DNS Routing</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -124,81 +117,19 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="queryStrategy">
|
<widget class="QPushButton" name="queryStrategy">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Query Strategy</string>
|
<string>DNS Query Strategy</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -461,13 +392,8 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>sniffing_mode</tabstop>
|
<tabstop>sniffing_mode</tabstop>
|
||||||
<tabstop>outbound_domain_strategy</tabstop>
|
|
||||||
<tabstop>dns_remote</tabstop>
|
<tabstop>dns_remote</tabstop>
|
||||||
<tabstop>dns_direct</tabstop>
|
<tabstop>dns_direct</tabstop>
|
||||||
<tabstop>dns_routing</tabstop>
|
|
||||||
<tabstop>queryStrategy</tabstop>
|
|
||||||
<tabstop>domainStrategyCombo</tabstop>
|
|
||||||
<tabstop>domainMatcherCombo</tabstop>
|
|
||||||
<tabstop>preset</tabstop>
|
<tabstop>preset</tabstop>
|
||||||
<tabstop>custom_route_edit</tabstop>
|
<tabstop>custom_route_edit</tabstop>
|
||||||
<tabstop>def_outbound</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_mtu->setCurrentText(Int2String(NekoRay::dataStore->vpn_mtu));
|
||||||
ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6);
|
ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6);
|
||||||
ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_console);
|
ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_console);
|
||||||
ui->vpn_already_admin->setChecked(NekoRay::dataStore->vpn_already_admin);
|
#ifndef Q_OS_WIN
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
ui->vpn_already_admin->setVisible(false);
|
|
||||||
#else
|
|
||||||
ui->hide_console->setVisible(false);
|
ui->hide_console->setVisible(false);
|
||||||
#endif
|
#endif
|
||||||
ui->strict_route->setChecked(NekoRay::dataStore->vpn_strict_route);
|
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_cidr)
|
||||||
D_LOAD_STRING(vpn_rule_process)
|
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_hide_console = ui->hide_console->isChecked();
|
||||||
NekoRay::dataStore->vpn_strict_route = ui->strict_route->isChecked();
|
NekoRay::dataStore->vpn_strict_route = ui->strict_route->isChecked();
|
||||||
NekoRay::dataStore->vpn_rule_white = ui->whitelist_mode->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_cidr)
|
||||||
D_SAVE_STRING_QTEXTEDIT(vpn_rule_process)
|
D_SAVE_STRING_QTEXTEDIT(vpn_rule_process)
|
||||||
|
|||||||
@@ -86,13 +86,6 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="horizontalGroupBox_2">
|
<widget class="QGroupBox" name="horizontalGroupBox_2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="hide_console">
|
|
||||||
<property name="text">
|
|
||||||
<string>Hide Console</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="vpn_ipv6">
|
<widget class="QCheckBox" name="vpn_ipv6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -100,13 +93,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="fake_dns">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">FakeDNS</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="strict_route">
|
<widget class="QCheckBox" name="strict_route">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -115,12 +101,34 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<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">
|
<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>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Already Admin</string>
|
<string>Internal Tun</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -198,6 +206,19 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</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/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
|
|||||||
@@ -94,12 +94,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
software_name = "NekoBox";
|
software_name = "NekoBox";
|
||||||
software_core_name = "sing-box";
|
software_core_name = "sing-box";
|
||||||
// replace default values
|
// replace default values
|
||||||
if (NekoRay::dataStore->log_level == "warning") {
|
if (NekoRay::dataStore->log_level == "warning") NekoRay::dataStore->log_level = "info";
|
||||||
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 (!Preset::SingBox::DomainStrategy.contains(NekoRay::dataStore->outbound_domain_strategy)) {
|
|
||||||
NekoRay::dataStore->outbound_domain_strategy = "";
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
if (QDir("dashboard").isEmpty()) {
|
if (QDir("dashboard").isEmpty()) {
|
||||||
QDir().mkdir("dashboard");
|
QDir().mkdir("dashboard");
|
||||||
@@ -334,20 +331,19 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
MW_dialog_message("", "UpdateDataStore");
|
MW_dialog_message("", "UpdateDataStore");
|
||||||
});
|
});
|
||||||
//
|
//
|
||||||
connect(ui->checkBox_VPN, &QCheckBox::clicked, this, [=](bool checked) {
|
connect(ui->checkBox_VPN, &QCheckBox::clicked, this, [=](bool checked) { neko_set_spmode_vpn(checked); });
|
||||||
neko_set_spmode(checked ? NekoRay::SystemProxyMode::VPN : NekoRay::SystemProxyMode::DISABLE);
|
connect(ui->checkBox_SystemProxy, &QCheckBox::clicked, this, [=](bool checked) { neko_set_spmode_system_proxy(checked); });
|
||||||
});
|
|
||||||
connect(ui->checkBox_SystemProxy, &QCheckBox::clicked, this, [=](bool checked) {
|
|
||||||
neko_set_spmode(checked ? NekoRay::SystemProxyMode::SYSTEM_PROXY : NekoRay::SystemProxyMode::DISABLE);
|
|
||||||
});
|
|
||||||
connect(ui->menu_spmode, &QMenu::aboutToShow, this, [=]() {
|
connect(ui->menu_spmode, &QMenu::aboutToShow, this, [=]() {
|
||||||
ui->menu_spmode_disabled->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::DISABLE);
|
ui->menu_spmode_disabled->setChecked(!(NekoRay::dataStore->spmode_system_proxy || NekoRay::dataStore->spmode_vpn));
|
||||||
ui->menu_spmode_system_proxy->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY);
|
ui->menu_spmode_system_proxy->setChecked(NekoRay::dataStore->spmode_system_proxy);
|
||||||
ui->menu_spmode_vpn->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN);
|
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_qr, &QAction::triggered, this, [=]() { display_qr_link(false); });
|
||||||
connect(ui->menu_tcp_ping, &QAction::triggered, this, [=]() { speedtest_current_group(0); });
|
connect(ui->menu_tcp_ping, &QAction::triggered, this, [=]() { speedtest_current_group(0); });
|
||||||
connect(ui->menu_url_test, &QAction::triggered, this, [=]() { speedtest_current_group(1); });
|
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
|
// Start last
|
||||||
if (NekoRay::dataStore->remember_enable) {
|
if (NekoRay::dataStore->remember_enable) {
|
||||||
if (NekoRay::dataStore->remember_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
if (NekoRay::dataStore->remember_spmode.contains("system_proxy")) {
|
||||||
neko_set_spmode(NekoRay::dataStore->remember_spmode, false);
|
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) {
|
if (NekoRay::dataStore->remember_id >= 0) {
|
||||||
runOnUiThread([=] { neko_start(NekoRay::dataStore->remember_id); });
|
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();
|
auto changed = NekoRay::dataStore->Save();
|
||||||
if (info.contains("RouteChanged")) changed = true;
|
if (info.contains("RouteChanged")) changed = true;
|
||||||
refresh_proxy_list();
|
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."));
|
MessageBoxWarning(tr("VPN settings changed"), tr("Restart VPN to take effect."));
|
||||||
} else if (changed && NekoRay::dataStore->started_id >= 0 &&
|
} else if (changed && NekoRay::dataStore->started_id >= 0 &&
|
||||||
QMessageBox::question(GetMessageBoxParent(), tr("Confirmation"), tr("Settings changed, restart proxy?")) == QMessageBox::StandardButton::Yes) {
|
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() {
|
void MainWindow::on_menu_exit_triggered() {
|
||||||
neko_set_spmode(NekoRay::SystemProxyMode::DISABLE, false);
|
neko_set_spmode_system_proxy(false, false);
|
||||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) return;
|
neko_set_spmode_vpn(false, false);
|
||||||
|
if (NekoRay::dataStore->spmode_vpn) return;
|
||||||
RegisterHotkey(true);
|
RegisterHotkey(true);
|
||||||
//
|
//
|
||||||
on_commitDataRequest();
|
on_commitDataRequest();
|
||||||
@@ -638,13 +638,21 @@ void MainWindow::on_menu_exit_triggered() {
|
|||||||
if (exit_reason == 1) {
|
if (exit_reason == 1) {
|
||||||
QDir::setCurrent(QApplication::applicationDirPath());
|
QDir::setCurrent(QApplication::applicationDirPath());
|
||||||
QProcess::startDetached("./updater", QStringList{});
|
QProcess::startDetached("./updater", QStringList{});
|
||||||
} else if (exit_reason == 2) {
|
} else if (exit_reason == 2 || exit_reason == 3) {
|
||||||
QDir::setCurrent(QApplication::applicationDirPath());
|
QDir::setCurrent(QApplication::applicationDirPath());
|
||||||
auto arguments = NekoRay::dataStore->argv;
|
auto arguments = NekoRay::dataStore->argv;
|
||||||
if (arguments.length() > 0) arguments.removeFirst();
|
if (arguments.length() > 0) arguments.removeFirst();
|
||||||
auto isLauncher = qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1";
|
auto isLauncher = qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1";
|
||||||
if (isLauncher) arguments.prepend("--");
|
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();
|
tray->hide();
|
||||||
QCoreApplication::quit();
|
QCoreApplication::quit();
|
||||||
@@ -654,23 +662,11 @@ void MainWindow::on_menu_exit_triggered() {
|
|||||||
refresh_status(); \
|
refresh_status(); \
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void MainWindow::neko_set_spmode(int mode, bool save) {
|
void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||||
if (mode != NekoRay::dataStore->running_spmode) {
|
if (enable != NekoRay::dataStore->spmode_system_proxy) {
|
||||||
// DISABLE
|
if (enable) {
|
||||||
|
|
||||||
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) {
|
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
#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,
|
auto btn = QMessageBox::warning(this, software_name,
|
||||||
tr("Http inbound is not enabled, can't set system proxy."),
|
tr("Http inbound is not enabled, can't set system proxy."),
|
||||||
"OK", tr("Settings"), "", 0, 0);
|
"OK", tr("Settings"), "", 0, 0);
|
||||||
@@ -682,29 +678,72 @@ void MainWindow::neko_set_spmode(int mode, bool save) {
|
|||||||
#endif
|
#endif
|
||||||
auto socks_port = NekoRay::dataStore->inbound_socks_port;
|
auto socks_port = NekoRay::dataStore->inbound_socks_port;
|
||||||
auto http_port = NekoRay::dataStore->inbound_http_port;
|
auto http_port = NekoRay::dataStore->inbound_http_port;
|
||||||
if (IS_NEKO_BOX) {
|
if (IS_NEKO_BOX) http_port = socks_port;
|
||||||
http_port = socks_port;
|
|
||||||
}
|
|
||||||
SetSystemProxy(http_port, socks_port);
|
SetSystemProxy(http_port, socks_port);
|
||||||
} else if (mode == NekoRay::SystemProxyMode::VPN) {
|
} else {
|
||||||
if (NekoRay::dataStore->need_keep_vpn_off) {
|
ClearSystemProxy();
|
||||||
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 (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."));
|
||||||
|
neko_set_spmode_FAILED
|
||||||
|
}
|
||||||
|
if (!StartVPNProcess()) {
|
||||||
|
neko_set_spmode_FAILED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!StartVPNProcess()) {
|
} else {
|
||||||
neko_set_spmode_FAILED
|
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
||||||
|
// current core is sing-box
|
||||||
|
} else {
|
||||||
|
if (!StopVPNProcess()) {
|
||||||
|
neko_set_spmode_FAILED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (save) {
|
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->Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
NekoRay::dataStore->running_spmode = mode;
|
NekoRay::dataStore->spmode_vpn = enable;
|
||||||
refresh_status();
|
refresh_status();
|
||||||
|
|
||||||
|
if (NekoRay::dataStore->started_id >= 0) neko_start(NekoRay::dataStore->started_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refresh_status(const QString &traffic_update) {
|
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);
|
if (IS_NEKO_BOX) inbound_txt = QString("Mixed: %1").arg(display_socks);
|
||||||
ui->label_inbound->setText(inbound_txt);
|
ui->label_inbound->setText(inbound_txt);
|
||||||
//
|
//
|
||||||
ui->checkBox_VPN->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN);
|
ui->checkBox_VPN->setChecked(NekoRay::dataStore->spmode_vpn);
|
||||||
ui->checkBox_SystemProxy->setChecked(NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY);
|
ui->checkBox_SystemProxy->setChecked(NekoRay::dataStore->spmode_system_proxy);
|
||||||
if (select_mode) ui->label_running->setText("[" + tr("Select") + "]");
|
if (select_mode) ui->label_running->setText("[" + tr("Select") + "]");
|
||||||
|
|
||||||
auto make_title = [=](bool isTray) {
|
auto make_title = [=](bool isTray) {
|
||||||
@@ -747,11 +786,8 @@ void MainWindow::refresh_status(const QString &traffic_update) {
|
|||||||
#endif
|
#endif
|
||||||
if (select_mode) tt << "[" + tr("Select") + "]";
|
if (select_mode) tt << "[" + tr("Select") + "]";
|
||||||
if (!title_error.isEmpty()) tt << "[" + title_error + "]";
|
if (!title_error.isEmpty()) tt << "[" + title_error + "]";
|
||||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
if (NekoRay::dataStore->spmode_vpn) tt << "[VPN]";
|
||||||
tt << "[" + tr("System Proxy") + "]";
|
if (NekoRay::dataStore->spmode_system_proxy) tt << "[" + tr("System Proxy") + "]";
|
||||||
} else if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) {
|
|
||||||
tt << "[" + tr("VPN Mode") + "]";
|
|
||||||
}
|
|
||||||
tt << software_name;
|
tt << software_name;
|
||||||
if (!isTray) tt << "(" + QString(NKR_VERSION) + ")";
|
if (!isTray) tt << "(" + QString(NKR_VERSION) + ")";
|
||||||
if (!NekoRay::dataStore->active_routing.isEmpty() && NekoRay::dataStore->active_routing != "Default") {
|
if (!NekoRay::dataStore->active_routing.isEmpty() && NekoRay::dataStore->active_routing != "Default") {
|
||||||
@@ -762,12 +798,15 @@ void MainWindow::refresh_status(const QString &traffic_update) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto icon_status_new = Icon::NONE;
|
auto icon_status_new = Icon::NONE;
|
||||||
if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::SYSTEM_PROXY) {
|
|
||||||
icon_status_new = Icon::SYSTEM_PROXY;
|
if (!running.isNull()) {
|
||||||
} else if (NekoRay::dataStore->running_spmode == NekoRay::SystemProxyMode::VPN) {
|
if (NekoRay::dataStore->spmode_vpn) {
|
||||||
icon_status_new = Icon::VPN;
|
icon_status_new = Icon::VPN;
|
||||||
} else if (!running.isNull()) {
|
} else if (NekoRay::dataStore->spmode_system_proxy) {
|
||||||
icon_status_new = Icon::RUNNING;
|
icon_status_new = Icon::SYSTEM_PROXY;
|
||||||
|
} else {
|
||||||
|
icon_status_new = Icon::RUNNING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh title & window icon
|
// refresh title & window icon
|
||||||
@@ -1677,11 +1716,10 @@ bool MainWindow::StartVPNProcess() {
|
|||||||
runOnNewThread([=] {
|
runOnNewThread([=] {
|
||||||
vpn_pid = 1; // TODO get pid?
|
vpn_pid = 1; // TODO get pid?
|
||||||
WinCommander::runProcessElevated(QApplication::applicationDirPath() + "/nekobox_core.exe",
|
WinCommander::runProcessElevated(QApplication::applicationDirPath() + "/nekobox_core.exe",
|
||||||
{"--disable-color", "run", "-c", configPath},
|
{"--disable-color", "run", "-c", configPath}, "",
|
||||||
"",
|
NekoRay::dataStore->vpn_hide_console ? WinCommander::SW_HIDE : WinCommander::SW_SHOWMINIMIZED); // blocking
|
||||||
NekoRay::dataStore->vpn_hide_console); // blocking
|
|
||||||
vpn_pid = 0;
|
vpn_pid = 0;
|
||||||
runOnUiThread([=] { neko_set_spmode(NekoRay::SystemProxyMode::DISABLE); });
|
runOnUiThread([=] { neko_set_spmode_vpn(false); });
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
QFile::remove(protectPath);
|
QFile::remove(protectPath);
|
||||||
@@ -1695,7 +1733,7 @@ bool MainWindow::StartVPNProcess() {
|
|||||||
if (state == QProcess::NotRunning) {
|
if (state == QProcess::NotRunning) {
|
||||||
vpn_pid = 0;
|
vpn_pid = 0;
|
||||||
vpn_process->deleteLater();
|
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")
|
vpn_process->start("osascript", {"-e", QString("do shell script \"%1\" with administrator privileges")
|
||||||
.arg("bash " + scriptPath)});
|
.arg("bash " + scriptPath)});
|
||||||
#else
|
#else
|
||||||
if (NekoRay::dataStore->vpn_already_admin) {
|
vpn_process->start("pkexec", {"bash", scriptPath});
|
||||||
vpn_process->start("bash", {scriptPath});
|
|
||||||
} else {
|
|
||||||
vpn_process->start("pkexec", {"bash", scriptPath});
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
vpn_process->waitForStarted();
|
vpn_process->waitForStarted();
|
||||||
vpn_pid = vpn_process->processId(); // actually it's pkexec or bash PID
|
vpn_pid = vpn_process->processId(); // actually it's pkexec or bash PID
|
||||||
@@ -1731,14 +1765,10 @@ bool MainWindow::StopVPNProcess(bool unconditional) {
|
|||||||
p.start("osascript", {"-e", QString("do shell script \"%1\" with administrator privileges")
|
p.start("osascript", {"-e", QString("do shell script \"%1\" with administrator privileges")
|
||||||
.arg("pkill -2 -U 0 nekobox_core")});
|
.arg("pkill -2 -U 0 nekobox_core")});
|
||||||
#else
|
#else
|
||||||
if (NekoRay::dataStore->vpn_already_admin) {
|
if (unconditional) {
|
||||||
p.start("bash", {"kill", "-2", Int2String(vpn_pid)});
|
p.start("pkexec", {"killall", "-2", "nekobox_core"});
|
||||||
} else {
|
} else {
|
||||||
if (unconditional) {
|
p.start("pkexec", {"pkill", "-2", "-P", Int2String(vpn_pid)});
|
||||||
p.start("pkexec", {"killall", "-2", "nekobox_core"});
|
|
||||||
} else {
|
|
||||||
p.start("pkexec", {"pkill", "-2", "-P", Int2String(vpn_pid)});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
p.waitForFinished();
|
p.waitForFinished();
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ public:
|
|||||||
|
|
||||||
void neko_stop(bool crash = false);
|
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);
|
void show_log_impl(const QString &log);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user