diff --git a/db/ConfigBuilder.cpp b/db/ConfigBuilder.cpp index 4aa193c..026c8fb 100644 --- a/db/ConfigBuilder.cpp +++ b/db/ConfigBuilder.cpp @@ -72,8 +72,6 @@ namespace NekoRay { return chainTagOut; } - // V2Ray - void ApplyCustomOutboundJsonSettings(const QJsonObject &custom, QJsonObject &outbound) { // 合并 if (custom.isEmpty()) return; @@ -95,6 +93,38 @@ namespace NekoRay { } } +#define DOMAIN_USER_RULE \ + for (const auto &line: SplitLines(dataStore->routing->proxy_domain)) { \ + if (line.startsWith("#")) continue; \ + if (dataStore->dns_routing) status->domainListDNSRemote += line; \ + status->domainListRemote += line; \ + } \ + for (const auto &line: SplitLines(dataStore->routing->direct_domain)) { \ + if (line.startsWith("#")) continue; \ + if (dataStore->dns_routing) status->domainListDNSDirect += line; \ + status->domainListDirect += line; \ + } \ + for (const auto &line: SplitLines(dataStore->routing->block_domain)) { \ + if (line.startsWith("#")) continue; \ + status->domainListBlock += line; \ + } + +#define IP_USER_RULE \ + for (const auto &line: SplitLines(dataStore->routing->block_ip)) { \ + if (line.startsWith("#")) continue; \ + status->ipListBlock += line; \ + } \ + for (const auto &line: SplitLines(dataStore->routing->proxy_ip)) { \ + if (line.startsWith("#")) continue; \ + status->ipListRemote += line; \ + } \ + for (const auto &line: SplitLines(dataStore->routing->direct_ip)) { \ + if (line.startsWith("#")) continue; \ + status->ipListDirect += line; \ + } + + // V2Ray + QSharedPointer BuildConfigV2Ray(const QSharedPointer &ent, bool forTest, bool forExport) { auto result = QSharedPointer(new BuildConfigResult); auto status = QSharedPointer(new BuildConfigStatus); @@ -215,20 +245,10 @@ namespace NekoRay { result->coreConfig.insert("inbounds", status->inbounds); result->coreConfig.insert("outbounds", status->outbounds); - // dns domain user rule - for (const auto &line: SplitLines(dataStore->routing->proxy_domain)) { - if (line.startsWith("#")) continue; - if (dataStore->dns_routing) status->domainListDNSRemote += line; - status->domainListRemote += line; - } - for (const auto &line: SplitLines(dataStore->routing->direct_domain)) { - if (line.startsWith("#")) continue; - if (dataStore->dns_routing) status->domainListDNSDirect += line; - status->domainListDirect += line; - } - for (const auto &line: SplitLines(dataStore->routing->block_domain)) { - if (line.startsWith("#")) continue; - status->domainListBlock += line; + // user rule + if (!forTest) { + DOMAIN_USER_RULE + IP_USER_RULE } // final add DNS @@ -281,17 +301,10 @@ namespace NekoRay { routing["domainStrategy"] = dataStore->domain_strategy; routing["domainMatcher"] = dataStore->domain_matcher == DomainMatcher::MPH ? "mph" : "linear"; - // ip user rule + // final add block route QJsonObject routingRule_tmp; routingRule_tmp["type"] = "field"; - - // block routingRule_tmp["outboundTag"] = "block"; - for (const auto &line: SplitLines(dataStore->routing->block_ip)) { - if (line.startsWith("#")) continue; - status->ipListBlock += line; - } - // final add block route if (!status->ipListBlock.isEmpty()) { auto tmp = routingRule_tmp; tmp["ip"] = status->ipListBlock; @@ -303,13 +316,8 @@ namespace NekoRay { status->routingRules += tmp; } - // proxy - routingRule_tmp["outboundTag"] = tagProxy; - for (const auto &line: SplitLines(dataStore->routing->proxy_ip)) { - if (line.startsWith("#")) continue; - status->ipListRemote += line; - } // final add proxy route + routingRule_tmp["outboundTag"] = "proxy"; if (!status->ipListRemote.isEmpty()) { auto tmp = routingRule_tmp; tmp["ip"] = status->ipListRemote; @@ -321,13 +329,8 @@ namespace NekoRay { status->routingRules += tmp; } - // bypass - routingRule_tmp["outboundTag"] = "bypass"; - for (const auto &line: SplitLines(dataStore->routing->direct_ip)) { - if (line.startsWith("#")) continue; - status->ipListDirect += line; - } // final add bypass route + routingRule_tmp["outboundTag"] = "bypass"; if (!status->ipListDirect.isEmpty()) { auto tmp = routingRule_tmp; tmp["ip"] = status->ipListDirect; @@ -655,10 +658,12 @@ namespace NekoRay { {"type", "block"}, {"tag", "block"}, }; - status->outbounds += QJsonObject{ - {"type", "dns"}, - {"tag", "dns-out"}, - }; + if (!forTest) { + status->outbounds += QJsonObject{ + {"type", "dns"}, + {"tag", "dns-out"}, + }; + } // custom inbound QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray()) @@ -666,23 +671,13 @@ namespace NekoRay { result->coreConfig.insert("inbounds", status->inbounds); result->coreConfig.insert("outbounds", status->outbounds); - // dns domain user rule - for (const auto &line: SplitLines(dataStore->routing->proxy_domain)) { - if (line.startsWith("#")) continue; - status->domainListDNSRemote += line; - status->domainListRemote += line; - } - for (const auto &line: SplitLines(dataStore->routing->direct_domain)) { - if (line.startsWith("#")) continue; - status->domainListDNSDirect += line; - status->domainListDirect += line; - } - for (const auto &line: SplitLines(dataStore->routing->block_domain)) { - if (line.startsWith("#")) continue; - status->domainListBlock += line; + // user rule + if (!forTest) { + DOMAIN_USER_RULE + IP_USER_RULE } - // + // sing-box common rule object auto make_rule = [&](const QJsonArray &arr, bool isIP = false) { QJsonObject rule; QJsonArray ips; @@ -763,7 +758,7 @@ namespace NekoRay { {"detour", "direct"}, }; - // DNS rules + // sing-box dns rule object auto add_rule_dns = [&](const QJsonArray &arr, const QString &server) { auto rule = make_rule(arr, false); if (rule.isEmpty()) return; @@ -784,9 +779,9 @@ namespace NekoRay { auto routingRules = QString2QJsonObject(dataStore->routing->custom)["rules"].toArray(); // dns hijack - routingRules += QJsonObject{{"protocol", "dns"}, - {"outbound", "dns-out"}}; + if (!forTest) routingRules += QJsonObject{{"protocol", "dns"}, {"outbound", "dns-out"}}; + // sing-box routing rule object auto add_rule_route = [&](const QJsonArray &arr, bool isIP, const QString &out) { auto rule = make_rule(arr, isIP); if (rule.isEmpty()) return; @@ -794,24 +789,10 @@ namespace NekoRay { routingRules += rule; }; - // ip user rule - for (const auto &line: SplitLines(dataStore->routing->block_ip)) { - if (line.startsWith("#")) continue; - status->ipListBlock += line; - } - for (const auto &line: SplitLines(dataStore->routing->proxy_ip)) { - if (line.startsWith("#")) continue; - status->ipListRemote += line; - } - for (const auto &line: SplitLines(dataStore->routing->direct_ip)) { - if (line.startsWith("#")) continue; - status->ipListDirect += line; - } + // final add routing rule add_rule_route(status->ipListBlock, true, "block"); add_rule_route(status->ipListRemote, true, tagProxy); add_rule_route(status->ipListDirect, true, "bypass"); - - // domain user rule add_rule_route(status->domainListBlock, false, "block"); add_rule_route(status->domainListRemote, false, tagProxy); add_rule_route(status->domainListDirect, false, "bypass"); diff --git a/go/cmd/updater/main.go b/go/cmd/updater/main.go index c104cb9..ecfd80b 100644 --- a/go/cmd/updater/main.go +++ b/go/cmd/updater/main.go @@ -40,7 +40,11 @@ func main() { // 1. update files Updater() // 2. start - Launcher() + if os.Getenv("NKR_FROM_LAUNCHER") == "1" { + Launcher() + } else { + exec.Command("./nekoray").Start() + } } return } else if strings.HasPrefix(strings.ToLower(exe), "launcher") { diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 9f83aa5..dd7cfcb 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -558,7 +558,7 @@ void MainWindow::on_menu_exit_triggered() { QProcess::startDetached("./updater", QStringList{}); } else if (exit_reason == 2) { QDir::setCurrent(QApplication::applicationDirPath()); - QProcess::startDetached("./nekoray", QStringList{}); + QProcess::startDetached(qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1" ? "./launcher" : "./nekoray", QStringList{}); } tray->hide(); QCoreApplication::quit(); @@ -1013,13 +1013,19 @@ void MainWindow::on_menu_export_config_triggered() { QMessageBox msg(QMessageBox::Information, tr("Config copied"), config_core); msg.addButton("Copy core config", QMessageBox::YesRole); + msg.addButton("Copy test config", QMessageBox::YesRole); msg.addButton(QMessageBox::Ok); + msg.setEscapeButton(QMessageBox::Ok); msg.setDefaultButton(QMessageBox::Ok); auto ret = msg.exec(); if (ret == 0) { result = NekoRay::BuildConfig(ent, false, false); config_core = QJsonObject2QString(result->coreConfig, true); QApplication::clipboard()->setText(config_core); + } else if (ret == 1) { + result = NekoRay::BuildConfig(ent, true, false); + config_core = QJsonObject2QString(result->coreConfig, true); + QApplication::clipboard()->setText(config_core); } }