refactor custom json

This commit is contained in:
arm64v8a
2023-04-17 17:49:07 +09:00
parent 4620d8aca2
commit 1c8ae4ef4f
12 changed files with 126 additions and 79 deletions

View File

@@ -12,6 +12,27 @@
namespace NekoRay { 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 // Common
QSharedPointer<BuildConfigResult> BuildConfig(const QSharedPointer<ProxyEntity> &ent, bool forTest, bool forExport) { QSharedPointer<BuildConfigResult> BuildConfig(const QSharedPointer<ProxyEntity> &ent, bool forTest, bool forExport) {
@@ -33,6 +54,9 @@ namespace NekoRay {
} }
} }
// apply custom config
MergeJson(QString2QJsonObject(ent->bean->custom_config), result->coreConfig);
// hook.js // hook.js
if (result->error.isEmpty() && !forTest) { if (result->error.isEmpty() && !forTest) {
auto source = qjs::ReadHookJS(); auto source = qjs::ReadHookJS();
@@ -86,27 +110,6 @@ namespace NekoRay {
return chainTagOut; 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 \ #define DOMAIN_USER_RULE \
for (const auto &line: SplitLinesSkipSharp(dataStore->routing->proxy_domain)) { \ for (const auto &line: SplitLinesSkipSharp(dataStore->routing->proxy_domain)) { \
if (dataStore->dns_routing) status->domainListDNSRemote += line; \ if (dataStore->dns_routing) status->domainListDNSRemote += line; \
@@ -603,10 +606,7 @@ namespace NekoRay {
} }
// apply custom outbound settings // apply custom outbound settings
auto custom_item = ent->bean->_get("custom"); MergeJson(QString2QJsonObject(ent->bean->custom_outbound), outbound);
if (custom_item != nullptr) {
ApplyCustomOutboundJsonSettings(QString2QJsonObject(*((QString *) custom_item->ptr)), outbound);
}
// Bypass Lookup for the first profile // Bypass Lookup for the first profile
auto serverAddress = ent->bean->serverAddress; auto serverAddress = ent->bean->serverAddress;

View File

@@ -11,6 +11,8 @@ namespace NekoRay::fmt {
_add(new configItem("name", &name, itemType::string)); _add(new configItem("name", &name, itemType::string));
_add(new configItem("addr", &serverAddress, itemType::string)); _add(new configItem("addr", &serverAddress, itemType::string));
_add(new configItem("port", &serverPort, itemType::integer)); _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) { QString AbstractBean::ToNekorayShareLink(const QString &type) {

View File

@@ -24,10 +24,14 @@ namespace NekoRay::fmt {
class AbstractBean : public JsonStore { class AbstractBean : public JsonStore {
public: public:
int version; int version;
QString name = ""; QString name = "";
QString serverAddress = "127.0.0.1"; QString serverAddress = "127.0.0.1";
int serverPort = 1080; int serverPort = 1080;
QString custom_config = "";
QString custom_outbound = "";
explicit AbstractBean(int version); explicit AbstractBean(int version);
// //

View File

@@ -11,14 +11,12 @@ namespace NekoRay::fmt {
QString plugin = ""; QString plugin = "";
QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings()); QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings());
QString custom = "";
ShadowSocksBean() : AbstractBean(0) { ShadowSocksBean() : AbstractBean(0) {
_add(new configItem("method", &method, itemType::string)); _add(new configItem("method", &method, itemType::string));
_add(new configItem("pass", &password, itemType::string)); _add(new configItem("pass", &password, itemType::string));
_add(new configItem("plugin", &plugin, itemType::string)); _add(new configItem("plugin", &plugin, itemType::string));
_add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore)); _add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore));
_add(new configItem("custom", &custom, itemType::string));
}; };
QString DisplayType() override { return "Shadowsocks"; }; QString DisplayType() override { return "Shadowsocks"; };

View File

@@ -15,7 +15,6 @@ namespace NekoRay::fmt {
QString password = ""; QString password = "";
QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings()); QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings());
QString custom = "";
explicit SocksHttpBean(int _socks_http_type) : AbstractBean(0) { explicit SocksHttpBean(int _socks_http_type) : AbstractBean(0) {
this->socks_http_type = _socks_http_type; this->socks_http_type = _socks_http_type;
@@ -23,7 +22,6 @@ namespace NekoRay::fmt {
_add(new configItem("username", &username, itemType::string)); _add(new configItem("username", &username, itemType::string));
_add(new configItem("password", &password, itemType::string)); _add(new configItem("password", &password, itemType::string));
_add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore)); _add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore));
_add(new configItem("custom", &custom, itemType::string));
}; };
QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; }; QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; };

View File

@@ -14,14 +14,12 @@ namespace NekoRay::fmt {
QString flow = ""; QString flow = "";
QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings()); QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings());
QString custom = "";
explicit TrojanVLESSBean(int _proxy_type) : AbstractBean(0) { explicit TrojanVLESSBean(int _proxy_type) : AbstractBean(0) {
proxy_type = _proxy_type; proxy_type = _proxy_type;
_add(new configItem("pass", &password, itemType::string)); _add(new configItem("pass", &password, itemType::string));
_add(new configItem("flow", &flow, itemType::string)); _add(new configItem("flow", &flow, itemType::string));
_add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore)); _add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore));
_add(new configItem("custom", &custom, itemType::string));
}; };
QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; }; QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; };

View File

@@ -11,14 +11,12 @@ namespace NekoRay::fmt {
QString security = "auto"; QString security = "auto";
QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings()); QSharedPointer<V2rayStreamSettings> stream = QSharedPointer<V2rayStreamSettings>(new V2rayStreamSettings());
QString custom = "";
VMessBean() : AbstractBean(0) { VMessBean() : AbstractBean(0) {
_add(new configItem("id", &uuid, itemType::string)); _add(new configItem("id", &uuid, itemType::string));
_add(new configItem("aid", &aid, itemType::integer)); _add(new configItem("aid", &aid, itemType::integer));
_add(new configItem("sec", &security, itemType::string)); _add(new configItem("sec", &security, itemType::string));
_add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore)); _add(new configItem("stream", dynamic_cast<JsonStore *>(stream.get()), itemType::jsonStore));
_add(new configItem("custom", &custom, itemType::string));
}; };
QString DisplayType() override { return "VMess"; }; QString DisplayType() override { return "VMess"; };

View File

@@ -329,10 +329,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod
<source>Name</source> <source>Name</source>
<translation>اسم</translation> <translation>اسم</translation>
</message> </message>
<message>
<source>Custom Json Settings</source>
<translation>تنظیمات JSON سفارشی</translation>
</message>
<message> <message>
<source>Settings</source> <source>Settings</source>
<translation>تنظیمات</translation> <translation>تنظیمات</translation>
@@ -421,6 +417,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod
<source>Custom (%1 config)</source> <source>Custom (%1 config)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Custom Outbound Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Custom Config Settings</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>DialogFirstSetup</name> <name>DialogFirstSetup</name>

View File

@@ -369,10 +369,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod
<source>Certificate</source> <source>Certificate</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>Custom Json Settings</source>
<translation> JSON </translation>
</message>
<message> <message>
<source>Not set</source> <source>Not set</source>
<translation></translation> <translation></translation>
@@ -413,6 +409,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod
<source>Custom (%1 config)</source> <source>Custom (%1 config)</source>
<translation> (%1 )</translation> <translation> (%1 )</translation>
</message> </message>
<message>
<source>Custom Outbound Settings</source>
<translation> JSON </translation>
</message>
<message>
<source>Custom Config Settings</source>
<translation> JSON </translation>
</message>
</context> </context>
<context> <context>
<name>DialogFirstSetup</name> <name>DialogFirstSetup</name>

View File

@@ -229,13 +229,22 @@ void DialogEditProfile::typeSelected(const QString &newType) {
} }
// left: custom // left: custom
auto custom_item = ent->bean->_get("custom"); CACHE.custom_config = ent->bean->custom_config;
if (custom_item != nullptr) { CACHE.custom_outbound = ent->bean->custom_outbound;
ui->custom_box->setVisible(true); bool show_custom_config = true;
CACHE.custom = *((QString *) custom_item->ptr); bool show_custom_outbound = true;
} else { if (type == "chain") {
ui->custom_box->setVisible(false); 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 // 左边 bean
auto old = ui->bean->layout()->itemAt(0)->widget(); auto old = ui->bean->layout()->itemAt(0)->widget();
@@ -342,10 +351,8 @@ void DialogEditProfile::accept() {
} }
// cached custom // cached custom
auto custom_item = ent->bean->_get("custom"); ent->bean->custom_outbound = CACHE.custom_outbound;
if (custom_item != nullptr) { ent->bean->custom_config = CACHE.custom_config;
*((QString *) custom_item->ptr) = CACHE.custom;
}
// finish // finish
QStringList msg = {"accept"}; QStringList msg = {"accept"};
@@ -372,10 +379,15 @@ void DialogEditProfile::editor_cache_updated_impl() {
} else { } else {
ui->certificate_edit->setText(tr("Already set")); ui->certificate_edit->setText(tr("Already set"));
} }
if (CACHE.custom.isEmpty()) { if (CACHE.custom_outbound.isEmpty()) {
ui->custom_edit->setText(tr("Not set")); ui->custom_outbound_edit->setText(tr("Not set"));
} else { } 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 // CACHE macro
@@ -388,8 +400,13 @@ void DialogEditProfile::editor_cache_updated_impl() {
} }
} }
void DialogEditProfile::on_custom_edit_clicked() { void DialogEditProfile::on_custom_outbound_edit_clicked() {
C_EDIT_JSON_ALLOW_EMPTY(custom) 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(); editor_cache_updated_impl();
} }

View File

@@ -23,7 +23,9 @@ public slots:
private 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(); void on_certificate_edit_clicked();
@@ -40,7 +42,8 @@ private:
QString network_title_base; QString network_title_base;
struct { struct {
QString custom; QString custom_outbound;
QString custom_config;
QString certificate; QString certificate;
} CACHE; } CACHE;

View File

@@ -116,26 +116,46 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="custom_box"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizePolicy"> <item>
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <widget class="QGroupBox" name="custom_box">
<horstretch>0</horstretch> <property name="sizePolicy">
<verstretch>0</verstretch> <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
</sizepolicy> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="title"> </sizepolicy>
<string>Custom Json Settings</string> </property>
</property> <property name="title">
<layout class="QVBoxLayout" name="verticalLayout_5"> <string>Custom Outbound Settings</string>
<item> </property>
<widget class="QPushButton" name="custom_edit"> <layout class="QVBoxLayout" name="verticalLayout_5">
<property name="text"> <item>
<string notr="true">Edit</string> <widget class="QPushButton" name="custom_outbound_edit">
</property> <property name="text">
</widget> <string notr="true">Edit</string>
</item> </property>
</layout> </widget>
</widget> </item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="custom_global_box">
<property name="title">
<string>Custom Config Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="custom_config_edit">
<property name="text">
<string notr="true">Edit</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
@@ -566,7 +586,8 @@ security (QUIC)</string>
<tabstop>name</tabstop> <tabstop>name</tabstop>
<tabstop>address</tabstop> <tabstop>address</tabstop>
<tabstop>port</tabstop> <tabstop>port</tabstop>
<tabstop>custom_edit</tabstop> <tabstop>custom_outbound_edit</tabstop>
<tabstop>custom_config_edit</tabstop>
<tabstop>network</tabstop> <tabstop>network</tabstop>
<tabstop>security</tabstop> <tabstop>security</tabstop>
<tabstop>packet_encoding</tabstop> <tabstop>packet_encoding</tabstop>