From 1c8ae4ef4f16ab668f5880fd6b8bff6790e2882a Mon Sep 17 00:00:00 2001 From: arm64v8a <48624112+arm64v8a@users.noreply.github.com> Date: Mon, 17 Apr 2023 17:49:07 +0900 Subject: [PATCH] refactor custom json --- db/ConfigBuilder.cpp | 50 +++++++++++++------------- fmt/AbstractBean.cpp | 2 ++ fmt/AbstractBean.hpp | 4 +++ fmt/ShadowSocksBean.hpp | 2 -- fmt/SocksHttpBean.hpp | 2 -- fmt/TrojanVLESSBean.hpp | 2 -- fmt/VMessBean.hpp | 2 -- translations/fa_IR.ts | 12 ++++--- translations/zh_CN.ts | 12 ++++--- ui/edit/dialog_edit_profile.cpp | 47 ++++++++++++++++-------- ui/edit/dialog_edit_profile.h | 7 ++-- ui/edit/dialog_edit_profile.ui | 63 ++++++++++++++++++++++----------- 12 files changed, 126 insertions(+), 79 deletions(-) diff --git a/db/ConfigBuilder.cpp b/db/ConfigBuilder.cpp index a1072aa..4969f6d 100644 --- a/db/ConfigBuilder.cpp +++ b/db/ConfigBuilder.cpp @@ -12,6 +12,27 @@ namespace NekoRay { + void MergeJson(const QJsonObject &custom, QJsonObject &outbound) { + // 合并 + if (custom.isEmpty()) return; + for (const auto &key: custom.keys()) { + if (outbound.contains(key)) { + auto v = custom[key]; + auto v_orig = outbound[key]; + if (v.isObject() && v_orig.isObject()) { // isObject 则合并? + auto vo = v.toObject(); + QJsonObject vo_orig = v_orig.toObject(); + MergeJson(vo, vo_orig); + outbound[key] = vo_orig; + } else { + outbound[key] = v; + } + } else { + outbound[key] = custom[key]; + } + } + } + // Common QSharedPointer BuildConfig(const QSharedPointer &ent, bool forTest, bool forExport) { @@ -33,6 +54,9 @@ namespace NekoRay { } } + // apply custom config + MergeJson(QString2QJsonObject(ent->bean->custom_config), result->coreConfig); + // hook.js if (result->error.isEmpty() && !forTest) { auto source = qjs::ReadHookJS(); @@ -86,27 +110,6 @@ namespace NekoRay { return chainTagOut; } - void ApplyCustomOutboundJsonSettings(const QJsonObject &custom, QJsonObject &outbound) { - // 合并 - if (custom.isEmpty()) return; - for (const auto &key: custom.keys()) { - if (outbound.contains(key)) { - auto v = custom[key]; - auto v_orig = outbound[key]; - if (v.isObject() && v_orig.isObject()) { // isObject 则合并? - auto vo = v.toObject(); - QJsonObject vo_orig = v_orig.toObject(); - ApplyCustomOutboundJsonSettings(vo, vo_orig); - outbound[key] = vo_orig; - } else { - outbound[key] = v; - } - } else { - outbound[key] = custom[key]; - } - } - } - #define DOMAIN_USER_RULE \ for (const auto &line: SplitLinesSkipSharp(dataStore->routing->proxy_domain)) { \ if (dataStore->dns_routing) status->domainListDNSRemote += line; \ @@ -603,10 +606,7 @@ namespace NekoRay { } // apply custom outbound settings - auto custom_item = ent->bean->_get("custom"); - if (custom_item != nullptr) { - ApplyCustomOutboundJsonSettings(QString2QJsonObject(*((QString *) custom_item->ptr)), outbound); - } + MergeJson(QString2QJsonObject(ent->bean->custom_outbound), outbound); // Bypass Lookup for the first profile auto serverAddress = ent->bean->serverAddress; diff --git a/fmt/AbstractBean.cpp b/fmt/AbstractBean.cpp index 7bfc3ae..89bf033 100644 --- a/fmt/AbstractBean.cpp +++ b/fmt/AbstractBean.cpp @@ -11,6 +11,8 @@ namespace NekoRay::fmt { _add(new configItem("name", &name, itemType::string)); _add(new configItem("addr", &serverAddress, itemType::string)); _add(new configItem("port", &serverPort, itemType::integer)); + _add(new configItem("c_cfg", &custom_config, itemType::string)); + _add(new configItem("c_out", &custom_outbound, itemType::string)); } QString AbstractBean::ToNekorayShareLink(const QString &type) { diff --git a/fmt/AbstractBean.hpp b/fmt/AbstractBean.hpp index 27ff737..f118b57 100644 --- a/fmt/AbstractBean.hpp +++ b/fmt/AbstractBean.hpp @@ -24,10 +24,14 @@ namespace NekoRay::fmt { class AbstractBean : public JsonStore { public: int version; + QString name = ""; QString serverAddress = "127.0.0.1"; int serverPort = 1080; + QString custom_config = ""; + QString custom_outbound = ""; + explicit AbstractBean(int version); // diff --git a/fmt/ShadowSocksBean.hpp b/fmt/ShadowSocksBean.hpp index 64a388d..829a79f 100644 --- a/fmt/ShadowSocksBean.hpp +++ b/fmt/ShadowSocksBean.hpp @@ -11,14 +11,12 @@ namespace NekoRay::fmt { QString plugin = ""; QSharedPointer stream = QSharedPointer(new V2rayStreamSettings()); - QString custom = ""; ShadowSocksBean() : AbstractBean(0) { _add(new configItem("method", &method, itemType::string)); _add(new configItem("pass", &password, itemType::string)); _add(new configItem("plugin", &plugin, itemType::string)); _add(new configItem("stream", dynamic_cast(stream.get()), itemType::jsonStore)); - _add(new configItem("custom", &custom, itemType::string)); }; QString DisplayType() override { return "Shadowsocks"; }; diff --git a/fmt/SocksHttpBean.hpp b/fmt/SocksHttpBean.hpp index daea0ed..8180b40 100644 --- a/fmt/SocksHttpBean.hpp +++ b/fmt/SocksHttpBean.hpp @@ -15,7 +15,6 @@ namespace NekoRay::fmt { QString password = ""; QSharedPointer stream = QSharedPointer(new V2rayStreamSettings()); - QString custom = ""; explicit SocksHttpBean(int _socks_http_type) : AbstractBean(0) { this->socks_http_type = _socks_http_type; @@ -23,7 +22,6 @@ namespace NekoRay::fmt { _add(new configItem("username", &username, itemType::string)); _add(new configItem("password", &password, itemType::string)); _add(new configItem("stream", dynamic_cast(stream.get()), itemType::jsonStore)); - _add(new configItem("custom", &custom, itemType::string)); }; QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; }; diff --git a/fmt/TrojanVLESSBean.hpp b/fmt/TrojanVLESSBean.hpp index 7dc2fc7..204f696 100644 --- a/fmt/TrojanVLESSBean.hpp +++ b/fmt/TrojanVLESSBean.hpp @@ -14,14 +14,12 @@ namespace NekoRay::fmt { QString flow = ""; QSharedPointer stream = QSharedPointer(new V2rayStreamSettings()); - QString custom = ""; explicit TrojanVLESSBean(int _proxy_type) : AbstractBean(0) { proxy_type = _proxy_type; _add(new configItem("pass", &password, itemType::string)); _add(new configItem("flow", &flow, itemType::string)); _add(new configItem("stream", dynamic_cast(stream.get()), itemType::jsonStore)); - _add(new configItem("custom", &custom, itemType::string)); }; QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; }; diff --git a/fmt/VMessBean.hpp b/fmt/VMessBean.hpp index ad05d13..f6c5703 100644 --- a/fmt/VMessBean.hpp +++ b/fmt/VMessBean.hpp @@ -11,14 +11,12 @@ namespace NekoRay::fmt { QString security = "auto"; QSharedPointer stream = QSharedPointer(new V2rayStreamSettings()); - QString custom = ""; VMessBean() : AbstractBean(0) { _add(new configItem("id", &uuid, itemType::string)); _add(new configItem("aid", &aid, itemType::integer)); _add(new configItem("sec", &security, itemType::string)); _add(new configItem("stream", dynamic_cast(stream.get()), itemType::jsonStore)); - _add(new configItem("custom", &custom, itemType::string)); }; QString DisplayType() override { return "VMess"; }; diff --git a/translations/fa_IR.ts b/translations/fa_IR.ts index 59b2e0d..d25edc7 100644 --- a/translations/fa_IR.ts +++ b/translations/fa_IR.ts @@ -329,10 +329,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod Name اسم - - Custom Json Settings - تنظیمات JSON سفارشی - Settings تنظیمات @@ -421,6 +417,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod Custom (%1 config) + + Custom Outbound Settings + + + + Custom Config Settings + + DialogFirstSetup diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 914c376..796758a 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -369,10 +369,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod Certificate 证书 - - Custom Json Settings - 自定义 JSON 设置 - Not set 未设置 @@ -413,6 +409,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod Custom (%1 config) 自定义 (%1 完整配置) + + Custom Outbound Settings + 自定义出站 JSON 设置 + + + Custom Config Settings + 自定义配置 JSON 设置 + DialogFirstSetup diff --git a/ui/edit/dialog_edit_profile.cpp b/ui/edit/dialog_edit_profile.cpp index 6391cd5..7fef6a9 100644 --- a/ui/edit/dialog_edit_profile.cpp +++ b/ui/edit/dialog_edit_profile.cpp @@ -229,13 +229,22 @@ void DialogEditProfile::typeSelected(const QString &newType) { } // left: custom - auto custom_item = ent->bean->_get("custom"); - if (custom_item != nullptr) { - ui->custom_box->setVisible(true); - CACHE.custom = *((QString *) custom_item->ptr); - } else { - ui->custom_box->setVisible(false); + CACHE.custom_config = ent->bean->custom_config; + CACHE.custom_outbound = ent->bean->custom_outbound; + bool show_custom_config = true; + bool show_custom_outbound = true; + if (type == "chain") { + show_custom_outbound = false; + } else if (type == "custom") { + if (customType == "internal") { + show_custom_outbound = false; + } else if (customType == "internal-full") { + show_custom_outbound = false; + show_custom_config = false; + } } + ui->custom_box->setVisible(show_custom_outbound); + ui->custom_global_box->setVisible(show_custom_config); // 左边 bean auto old = ui->bean->layout()->itemAt(0)->widget(); @@ -342,10 +351,8 @@ void DialogEditProfile::accept() { } // cached custom - auto custom_item = ent->bean->_get("custom"); - if (custom_item != nullptr) { - *((QString *) custom_item->ptr) = CACHE.custom; - } + ent->bean->custom_outbound = CACHE.custom_outbound; + ent->bean->custom_config = CACHE.custom_config; // finish QStringList msg = {"accept"}; @@ -372,10 +379,15 @@ void DialogEditProfile::editor_cache_updated_impl() { } else { ui->certificate_edit->setText(tr("Already set")); } - if (CACHE.custom.isEmpty()) { - ui->custom_edit->setText(tr("Not set")); + if (CACHE.custom_outbound.isEmpty()) { + ui->custom_outbound_edit->setText(tr("Not set")); } else { - ui->custom_edit->setText(tr("Already set")); + ui->custom_outbound_edit->setText(tr("Already set")); + } + if (CACHE.custom_config.isEmpty()) { + ui->custom_config_edit->setText(tr("Not set")); + } else { + ui->custom_config_edit->setText(tr("Already set")); } // CACHE macro @@ -388,8 +400,13 @@ void DialogEditProfile::editor_cache_updated_impl() { } } -void DialogEditProfile::on_custom_edit_clicked() { - C_EDIT_JSON_ALLOW_EMPTY(custom) +void DialogEditProfile::on_custom_outbound_edit_clicked() { + C_EDIT_JSON_ALLOW_EMPTY(custom_outbound) + editor_cache_updated_impl(); +} + +void DialogEditProfile::on_custom_config_edit_clicked() { + C_EDIT_JSON_ALLOW_EMPTY(custom_config) editor_cache_updated_impl(); } diff --git a/ui/edit/dialog_edit_profile.h b/ui/edit/dialog_edit_profile.h index 42a5ac2..815c5e5 100644 --- a/ui/edit/dialog_edit_profile.h +++ b/ui/edit/dialog_edit_profile.h @@ -23,7 +23,9 @@ public slots: private slots: - void on_custom_edit_clicked(); + void on_custom_outbound_edit_clicked(); + + void on_custom_config_edit_clicked(); void on_certificate_edit_clicked(); @@ -40,7 +42,8 @@ private: QString network_title_base; struct { - QString custom; + QString custom_outbound; + QString custom_config; QString certificate; } CACHE; diff --git a/ui/edit/dialog_edit_profile.ui b/ui/edit/dialog_edit_profile.ui index 107b9bb..48d3086 100644 --- a/ui/edit/dialog_edit_profile.ui +++ b/ui/edit/dialog_edit_profile.ui @@ -116,26 +116,46 @@ - - - - 0 - 0 - - - - Custom Json Settings - - - - - - Edit - - - - - + + + + + + 0 + 0 + + + + Custom Outbound Settings + + + + + + Edit + + + + + + + + + + Custom Config Settings + + + + + + Edit + + + + + + + @@ -566,7 +586,8 @@ security (QUIC) name address port - custom_edit + custom_outbound_edit + custom_config_edit network security packet_encoding