Skip to content

Commit

Permalink
feat: add ducksoft link for VMess
Browse files Browse the repository at this point in the history
  • Loading branch information
HystericalDragon authored and HystericalDragon committed Aug 15, 2023
1 parent b7de4b0 commit 1c6fe29
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 19 deletions.
80 changes: 63 additions & 17 deletions fmt/Bean2Link.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include "QUICBean.hpp"
#include "db/ProxyEntity.hpp"
#include "fmt/includes.h"

Expand Down Expand Up @@ -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() {
Expand Down
46 changes: 44 additions & 2 deletions fmt/Link2Bean.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include "QUICBean.hpp"
#include "db/ProxyEntity.hpp"
#include "fmt/includes.h"

Expand Down Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions main/NekoGui_DataStore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions translations/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 2 additions & 0 deletions ui/dialog_basic_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down
10 changes: 10 additions & 0 deletions ui/dialog_basic_settings.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down

0 comments on commit 1c6fe29

Please sign in to comment.