feat: add ducksoft link for VMess

This commit is contained in:
HystericalDragon
2023-08-14 09:00:53 +08:00
parent b7de4b0675
commit 1c6fe29ea6
6 changed files with 128 additions and 19 deletions

View File

@@ -1,4 +1,3 @@
#include "QUICBean.hpp"
#include "db/ProxyEntity.hpp"
#include "fmt/includes.h"
@@ -99,22 +98,69 @@ namespace NekoGui_fmt {
}
QString VMessBean::ToShareLink() {
QJsonObject N{
{"v", "2"},
{"ps", name},
{"add", serverAddress},
{"port", Int2String(serverPort)},
{"id", uuid},
{"aid", Int2String(aid)},
{"net", stream->network},
{"host", stream->host},
{"path", stream->path},
{"type", stream->header_type},
{"scy", security},
{"tls", stream->security == "tls" ? "tls" : ""},
{"sni", stream->sni},
};
return "vmess://" + QJsonObject2QString(N, true).toUtf8().toBase64();
if (NekoGui::dataStore->old_share_link_format) {
// v2rayN format
QJsonObject N{
{"v", "2"},
{"ps", name},
{"add", serverAddress},
{"port", Int2String(serverPort)},
{"id", uuid},
{"aid", Int2String(aid)},
{"net", stream->network},
{"host", stream->host},
{"path", stream->path},
{"type", stream->header_type},
{"scy", security},
{"tls", stream->security == "tls" ? "tls" : ""},
{"sni", stream->sni},
};
return "vmess://" + QJsonObject2QString(N, true).toUtf8().toBase64();
} else {
// ducksoft format
QUrl url;
QUrlQuery query;
url.setScheme("vmess");
url.setUserName(uuid);
url.setHost(serverAddress);
url.setPort(serverPort);
if (!name.isEmpty()) url.setFragment(name);
query.addQueryItem("encryption", security);
// security
auto security = stream->security;
if (security == "tls" && !stream->reality_pbk.trimmed().isEmpty()) security = "reality";
query.addQueryItem("security", security);
if (!stream->sni.isEmpty()) query.addQueryItem("sni", stream->sni);
if (stream->allow_insecure) query.addQueryItem("allowInsecure", "1");
if (!stream->utlsFingerprint.isEmpty()) query.addQueryItem("fp", stream->utlsFingerprint);
if (security == "reality") {
query.addQueryItem("pbk", stream->reality_pbk);
if (!stream->reality_sid.isEmpty()) query.addQueryItem("sid", stream->reality_sid);
if (!stream->reality_spx.isEmpty()) query.addQueryItem("spx", stream->reality_spx);
}
// type
query.addQueryItem("type", stream->network);
if (stream->network == "ws" || stream->network == "http") {
if (!stream->path.isEmpty()) query.addQueryItem("path", stream->path);
if (!stream->host.isEmpty()) query.addQueryItem("host", stream->host);
} else if (stream->network == "grpc") {
if (!stream->path.isEmpty()) query.addQueryItem("serviceName", stream->path);
} else if (stream->network == "tcp") {
if (stream->header_type == "http") {
query.addQueryItem("headerType", "http");
query.addQueryItem("host", stream->host);
}
}
url.setQuery(query);
return url.toString(QUrl::FullyEncoded);
}
}
QString NaiveBean::ToShareLink() {

View File

@@ -1,4 +1,3 @@
#include "QUICBean.hpp"
#include "db/ProxyEntity.hpp"
#include "fmt/includes.h"
@@ -153,9 +152,52 @@ namespace NekoGui_fmt {
stream->security = objN["tls"].toString();
// TODO quic & kcp
return true;
} else {
// https://github.com/XTLS/Xray-core/discussions/716
auto url = QUrl(link);
if (!url.isValid()) return false;
auto query = GetQuery(url);
name = url.fragment(QUrl::FullyDecoded);
serverAddress = url.host();
serverPort = url.port();
uuid = url.userName();
if (serverPort == -1) serverPort = 443;
aid = 0; // “此分享标准仅针对 VMess AEAD 和 VLESS。”
security = GetQueryValue(query, "encryption", "auto");
// security
stream->network = GetQueryValue(query, "type", "tcp");
stream->security = GetQueryValue(query, "security", "tls").replace("reality", "tls");
auto sni1 = GetQueryValue(query, "sni");
auto sni2 = GetQueryValue(query, "peer");
if (!sni1.isEmpty()) stream->sni = sni1;
if (!sni2.isEmpty()) stream->sni = sni2;
if (!query.queryItemValue("allowInsecure").isEmpty()) stream->allow_insecure = true;
stream->reality_pbk = GetQueryValue(query, "pbk", "");
stream->reality_sid = GetQueryValue(query, "sid", "");
stream->reality_spx = GetQueryValue(query, "spx", "");
stream->utlsFingerprint = GetQueryValue(query, "fp", "");
// type
if (stream->network == "ws") {
stream->path = GetQueryValue(query, "path", "");
stream->host = GetQueryValue(query, "host", "");
} else if (stream->network == "http") {
stream->path = GetQueryValue(query, "path", "");
stream->host = GetQueryValue(query, "host", "").replace("|", ",");
} else if (stream->network == "grpc") {
stream->path = GetQueryValue(query, "serviceName", "");
} else if (stream->network == "tcp") {
if (GetQueryValue(query, "headerType") == "http") {
stream->header_type = "http";
stream->host = GetQueryValue(query, "host", "");
}
}
return !(uuid.isEmpty() || serverAddress.isEmpty());
}
// Std Format
return false;
}

View File

@@ -97,6 +97,7 @@ namespace NekoGui {
QString test_download_url = "http://cachefly.cachefly.net/10mb.test";
int test_download_timeout = 30;
int test_concurrent = 5;
bool old_share_link_format = true;
int traffic_loop_interval = 1000;
bool connection_statistics = false;
int current_group = 0; // group id

View File

@@ -163,6 +163,14 @@
<source>Advanced system proxy settings. Please select a format.</source>
<translation></translation>
</message>
<message>
<source>Old Share Link Format</source>
<translation></translation>
</message>
<message>
<source>Share VMess Link with v2rayN Format</source>
<translation> v2rayN VMess </translation>
</message>
<message>
<source>Clear servers before updating subscription</source>
<translation></translation>

View File

@@ -81,6 +81,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
D_LOAD_INT(test_download_timeout)
D_LOAD_STRING(test_latency_url)
D_LOAD_STRING(test_download_url)
D_LOAD_BOOL(old_share_link_format)
connect(ui->custom_inbound_edit, &QPushButton::clicked, this, [=] {
C_EDIT_JSON_ALLOW_EMPTY(custom_inbound)
@@ -272,6 +273,7 @@ void DialogBasicSettings::accept() {
D_SAVE_INT(test_download_timeout)
D_SAVE_STRING(test_latency_url)
D_SAVE_STRING(test_download_url)
D_SAVE_BOOL(old_share_link_format)
// Style

View File

@@ -213,6 +213,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="old_share_link_format">
<property name="toolTip">
<string>Share VMess Link with v2rayN Format</string>
</property>
<property name="text">
<string>Old Share Link Format</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sys_proxy_format">
<property name="text">