diff --git a/src/Qv2rayBase.h b/src/Qv2rayBase.h index ca9499b7..292acc9e 100644 --- a/src/Qv2rayBase.h +++ b/src/Qv2rayBase.h @@ -18,6 +18,14 @@ #define QV2RAY_VCORE_ACCESS_LOG_FILENAME "access.log" #define QV2RAY_VCORE_ERROR_LOG_FILENAME "error.log" +// These is for early-2.0 version, final 2.0 will move these content into global config. +#define QV2RAY_CONFIG_TYPE_FILE "File" +#define QV2RAY_CONFIG_TYPE_MANUAL "Manual" +#define QV2RAY_CONFIG_TYPE_CONNECTIONSTRING "ConnectionString" +#define QV2RAY_CONFIG_TYPE_SUBSCRIPTION "Subscription" +#define QV2RAY_CONFIG_TYPE_JSON_KEY "_qv2ray.configSource" + + // GUI TOOLS #define RED(obj) \ diff --git a/src/QvCoreConfigOperations_Convertion.cpp b/src/QvCoreConfigOperations_Convertion.cpp index 35429d67..fa314ea8 100644 --- a/src/QvCoreConfigOperations_Convertion.cpp +++ b/src/QvCoreConfigOperations_Convertion.cpp @@ -66,6 +66,7 @@ namespace Qv2ray outbounds.append(outbound); root.insert("outbounds", outbounds); root.insert("QV2RAY_ALIAS", QString::fromStdString(vmessConf.ps)); + root.insert(QV2RAY_CONFIG_TYPE_JSON_KEY, QV2RAY_CONFIG_TYPE_CONNECTIONSTRING); RROOT } @@ -77,30 +78,11 @@ namespace Qv2ray JSON_ROOT_TRY_REMOVE("inbounds") } - // JSON_ROOT_TRY_REMOVE("log") JSON_ROOT_TRY_REMOVE("api") JSON_ROOT_TRY_REMOVE("stats") - JSON_ROOT_TRY_REMOVE("policy") JSON_ROOT_TRY_REMOVE("dns") - JSON_ROOT_TRY_REMOVE("routing") - QJsonArray outbounds; - - // - // Currently, we only support VMess (And ShadowSocks now). So remove all other types of outbounds. - for (int i = root["outbounds"].toArray().count(); i >= 0 ; i--) { - auto isVMess = root["outbounds"].toArray()[i].toObject()["protocol"].toString() == "vmess"; - auto isSS = root["outbounds"].toArray()[i].toObject()["protocol"].toString() == "shadowsocks"; - - if (isVMess || isSS) { - auto conn = root["outbounds"].toArray()[i].toObject(); - conn.insert("tag", OUTBOUND_TAG_PROXY); - outbounds.append(conn); - } - } - - JSON_ROOT_TRY_REMOVE("outbounds") - root.insert("outbounds", outbounds); + root.insert(QV2RAY_CONFIG_TYPE_JSON_KEY, QV2RAY_CONFIG_TYPE_FILE); return root; } diff --git a/src/QvCoreConfigOperations_Generation.cpp b/src/QvCoreConfigOperations_Generation.cpp index e1961585..676d526a 100644 --- a/src/QvCoreConfigOperations_Generation.cpp +++ b/src/QvCoreConfigOperations_Generation.cpp @@ -166,9 +166,16 @@ namespace Qv2ray auto dnsObject = GenerateDNS(gConf.withLocalDNS, dnsList); root.insert("dns", dnsObject); + // - auto routeObject = GenerateRoutes(gConf.proxyDefault, gConf.proxyCN); - root.insert("routing", routeObject); + // This is for imported config files as there are routing entries already. + // We don't add extra routings. + // We don't use QV2RAY_CONFIG_TYPE_FILE checking scheme because not all connections have this part. + if (!root.contains("routing")) { + auto routeObject = GenerateRoutes(gConf.proxyDefault, gConf.proxyCN); + root.insert("routing", routeObject); + } + // // root.insert("stats", QJsonObject()); @@ -178,20 +185,16 @@ namespace Qv2ray root.insert("inbounds", QJsonArray()); } - // - // This is configured as a global option... - auto conf = GetGlobalConfig(); - // HTTP InBound - if (conf.inBoundSettings.http_port != 0) { + if (gConf.inBoundSettings.http_port != 0) { QJsonObject httpInBoundObject; - httpInBoundObject.insert("listen", QString::fromStdString(conf.inBoundSettings.listenip)); - httpInBoundObject.insert("port", conf.inBoundSettings.http_port); + httpInBoundObject.insert("listen", QString::fromStdString(gConf.inBoundSettings.listenip)); + httpInBoundObject.insert("port", gConf.inBoundSettings.http_port); httpInBoundObject.insert("protocol", "http"); httpInBoundObject.insert("tag", "http_IN"); - if (conf.inBoundSettings.http_useAuth) { - auto httpInSettings = GenerateHTTPIN(QList() << conf.inBoundSettings.httpAccount); + if (gConf.inBoundSettings.http_useAuth) { + auto httpInSettings = GenerateHTTPIN(QList() << gConf.inBoundSettings.httpAccount); httpInBoundObject.insert("settings", httpInSettings); } @@ -199,24 +202,32 @@ namespace Qv2ray } // SOCKS InBound - if (conf.inBoundSettings.socks_port != 0) { + if (gConf.inBoundSettings.socks_port != 0) { QJsonObject socksInBoundObject; - socksInBoundObject.insert("listen", QString::fromStdString(conf.inBoundSettings.listenip)); - socksInBoundObject.insert("port", conf.inBoundSettings.socks_port); + socksInBoundObject.insert("listen", QString::fromStdString(gConf.inBoundSettings.listenip)); + socksInBoundObject.insert("port", gConf.inBoundSettings.socks_port); socksInBoundObject.insert("protocol", "socks"); socksInBoundObject.insert("tag", "socks_IN"); - auto socksInSettings = GenerateSocksIN(conf.inBoundSettings.socks_useAuth ? "password" : "noauth", QList() << conf.inBoundSettings.socksAccount); + auto socksInSettings = GenerateSocksIN(gConf.inBoundSettings.socks_useAuth ? "password" : "noauth", QList() << gConf.inBoundSettings.socksAccount); socksInBoundObject.insert("settings", socksInSettings); root["inbounds"].toArray().append(socksInBoundObject); } - QJsonArray outbounds = root["outbounds"].toArray(); - // For DIRECT - outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_DIRECT)); - QJsonObject first = outbounds.first().toObject(); - first.insert("mux", GetRootObject(gConf.mux)); - outbounds[0] = first; - root["outbounds"] = outbounds; + // TODO: MultiOutbound Settings + if (root.contains(QV2RAY_CONFIG_TYPE_JSON_KEY) && root[QV2RAY_CONFIG_TYPE_JSON_KEY] == QV2RAY_CONFIG_TYPE_FILE) { + LOG(MODULE_CONFIG, "Found an imported config file, skipping adding 'freedom' outbound.") + // Do nothing because it's an imported connection. + } else { + QJsonArray outbounds = root["outbounds"].toArray(); + // It's not imported so we add new stuff. + // For DIRECT + outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_DIRECT)); + QJsonObject first = outbounds.first().toObject(); + first.insert("mux", GetRootObject(gConf.mux)); + outbounds[0] = first; + root["outbounds"] = outbounds; + } + return root; } } diff --git a/src/w_ConnectionEditWindow.cpp b/src/w_ConnectionEditWindow.cpp index 90a12ba8..50420272 100644 --- a/src/w_ConnectionEditWindow.cpp +++ b/src/w_ConnectionEditWindow.cpp @@ -25,6 +25,7 @@ ConnectionEditWindow::ConnectionEditWindow(QWidget *parent) vmess = VMessServerObject(); vmess.users.push_back(VMessServerObject::UserObject()); stream = StreamSettingsObject(); + OutboundType = "vmess"; ReLoad_GUI_JSON_ModelContent(); GEN_JSON } @@ -142,8 +143,8 @@ void ConnectionEditWindow::ReLoad_GUI_JSON_ModelContent() void ConnectionEditWindow::on_buttonBox_accepted() { - bool new_config = _alias == ""; - auto alias = new_config ? (ui->ipLineEdit->text() + "_" + ui->portLineEdit->text()) : _alias; + bool is_new_config = _alias == ""; + auto alias = is_new_config ? (ui->ipLineEdit->text() + "_" + ui->portLineEdit->text()) : _alias; // auto outbound = GenerateConnectionJson(); QJsonArray outbounds; @@ -155,16 +156,17 @@ void ConnectionEditWindow::on_buttonBox_accepted() } originalRoot.insert("outbounds", outbounds); + originalRoot.insert(QV2RAY_CONFIG_TYPE_JSON_KEY, QV2RAY_CONFIG_TYPE_MANUAL); SaveConnectionConfig(originalRoot, &alias); auto globalConf = GetGlobalConfig(); - if (new_config) { + if (is_new_config) { // New config... globalConf.configs.push_back(alias.toStdString()); } SetGlobalConfig(globalConf); - emit s_reload_config(!new_config); + emit s_reload_config(!is_new_config); } void ConnectionEditWindow::on_ipLineEdit_textEdited(const QString &arg1) diff --git a/src/w_ImportConfig.cpp b/src/w_ImportConfig.cpp index c529b59e..d51e2866 100644 --- a/src/w_ImportConfig.cpp +++ b/src/w_ImportConfig.cpp @@ -59,6 +59,7 @@ void ImportConfigWindow::on_buttonBox_accepted() int result = VerifyVMessProtocolString(vmess); if (result == 0) { + // This result code passes the validation check. //QvMessageBox(this, tr("#VMessCheck"), tr("#AbleToImportConfig")); } else if (result == -1) { QvMessageBox(this, tr("#VMessCheck"), tr("#NotValidVMessProtocolString")); diff --git a/test.conf.json b/test.conf.json deleted file mode 100644 index c790fd9b..00000000 --- a/test.conf.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "dns": { - "servers": [ - "8.8.8.8", - "8.8.4.4", - "localhost" - ] - }, - "inbounds": [ - { - "listen": "0.0.0.0", - "port": 60080, - "protocol": "dokodemo-door", - "settings": { - "followRedirect": true, - "network": "tcp,udp" - }, - "streamSettings": { - "sockopt": { - "tproxy": "tproxy" - } - } - }, - { - "listen": "127.0.0.1", - "port": 1081, - "protocol": "socks", - "settings": { - "auth": "noauth", - "ip": "127.0.0.1", - "udp": true - }, - "tag": "socks-in" - }, - { - "listen": "127.0.0.1", - "port": 6666, - "protocol": "http", - "settings": { - "auth": "noauth", - "ip": "127.0.0.1", - "udp": true - }, - "tag": "http-in" - } - ], - "log": { - "error": "", - "loglevel": "" - }, - "outbounds": [ - { - "mux": { - "enabled": true - }, - "protocol": "vmess", - "settings": { - "vnext": [ - { - "address": "addreess1.com", - "port": 443, - "users": [ - { - "alterId": 233, - "id": "askdsakldlskdmsadml", - "security": "auto" - } - ] - } - ] - }, - "streamSettings": { - "headers": null, - "network": "ws", - "security": "tls", - "tlsSettings": { - "allowInsecure": true, - "serverName": null - }, - "wsSettings": { - "path": "/admin" - } - }, - "tag": "route1" - }, - { - "protocol": "freedom", - "settings": {}, - "tag": "direct" - }, - { - "mux": { - "enabled": true - }, - "protocol": "vmess", - "settings": { - "vnext": [ - { - "address": "addreess2.com", - "port": 443, - "users": [ - { - "alterId": 233, - "id": "asdsadasdsadadsa", - "security": "auto" - } - ] - } - ] - }, - "streamSettings": { - "headers": null, - "network": "ws", - "security": "tls", - "tlsSettings": { - "allowInsecure": true, - "serverName": null - }, - "wsSettings": { - "path": "/admin" - } - }, - "tag": "route2" - }, - { - "mux": { - "enabled": true - }, - "protocol": "vmess", - "settings": { - "vnext": [ - { - "address": "addreess3.com", - "port": 33333, - "users": [ - { - "alterId": 2, - "id": "asddadadadasd", - "security": "chacha20-poly1305" - } - ] - } - ] - }, - "tag": "route3" - }, - { - "protocol": "socks", - "settings": { - "servers": [ - { - "address": "127.0.0.1", - "port": 1082 - } - ] - }, - "tag": "sock" - } - ], - "routing": { - "domainStrategy": "IPOnDemand", - "rules": [ - { - "domain": [ - "youtube.com", - "googlevideo.com", - "googleusercontent.com", - "gstatic.com", - "download.ok.is" - ], - "network": "tcp,udp", - "outboundTag": "route1", - "type": "field" - }, - { - "ip": [ - "172.65.128.0/24" - ], - "network": "tcp,udp", - "outboundTag": "route2", - "type": "field" - } - ] - } -}