Skip to content

Inner uri#9245

Merged
2dust merged 4 commits into
2dust:masterfrom
DHR60:inner_uri
May 6, 2026
Merged

Inner uri#9245
2dust merged 4 commits into
2dust:masterfrom
DHR60:inner_uri

Conversation

@DHR60
Copy link
Copy Markdown
Contributor

@DHR60 DHR60 commented May 5, 2026

v2rayN 内部分享链接

用于备份配置,同时可用于分享协议标准提案外字段

概览

v2rayn://
	${ConfigType}
	/
	${url-safe base64 encoded json string}

Json Payload

普通 http 节点:

{
  "IndexId": "AIy0Iw",
  "ConfigType": 10,
  "ConfigVersion": 4,
  "Remarks": "example",
  "Address": "127.0.0.1",
  "Port": 8080,
  "Password": "pass",
  "Username": "user"
}

策略组:

指向其他节点 IndexId:

{
  "IndexId": "oWjrYw",
  "ConfigType": 101,
  "CoreType": 2,
  "ConfigVersion": 4,
  "Remarks": "example_group",
  "ProtoExtraObj": {
    "ChildItems": "AIy0Iw",
    "MultipleLoad": 0
  }
}

按其他节点 Remark 筛选:

{
  "IndexId": "slDgGA",
  "ConfigType": 101,
  "CoreType": 2,
  "ConfigVersion": 4,
  "Remarks": "example_group",
  "ProtoExtraObj": {
    "SubChildItems": "self",
    "Filter": "example",
    "MultipleLoad": 0
  }
}

注:

示例

v2rayn://http/eyJJbmRleElkIjoiQUl5MEl3IiwiQ29uZmlnVHlwZSI6MTAsIkNvbmZpZ1ZlcnNpb24iOjQsIlJlbWFya3MiOiJleGFtcGxlIiwiQWRkcmVzcyI6IjEyNy4wLjAuMSIsIlBvcnQiOjgwODAsIlBhc3N3b3JkIjoicGFzcyIsIlVzZXJuYW1lIjoidXNlciJ9
v2rayn://policygroup/eyJJbmRleElkIjoib1dqcll3IiwiQ29uZmlnVHlwZSI6MTAxLCJDb3JlVHlwZSI6MiwiQ29uZmlnVmVyc2lvbiI6NCwiUmVtYXJrcyI6ImV4YW1wbGVfZ3JvdXAiLCJQcm90b0V4dHJhT2JqIjp7IkNoaWxkSXRlbXMiOiJBSXkwSXciLCJNdWx0aXBsZUxvYWQiOjB9fQ
v2rayn://policygroup/eyJJbmRleElkIjoic2xEZ0dBIiwiQ29uZmlnVHlwZSI6MTAxLCJDb3JlVHlwZSI6MiwiQ29uZmlnVmVyc2lvbiI6NCwiUmVtYXJrcyI6ImV4YW1wbGVfZ3JvdXAiLCJQcm90b0V4dHJhT2JqIjp7IlN1YkNoaWxkSXRlbXMiOiJzZWxmIiwiRmlsdGVyIjoiZXhhbXBsZSIsIk11bHRpcGxlTG9hZCI6MH19

@DHR60

This comment was marked as outdated.

@2dust
Copy link
Copy Markdown
Owner

2dust commented May 6, 2026

功能挺好,就是这个导出的名称看不懂;
不如直接叫 v2rayN 内部分享链接导出 v2rayN 分享链接至剪贴板 这样看到更明白

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 6, 2026

Done

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a v2rayN-specific “inner URI” (v2rayn://...) format for exporting/importing profiles (including extra/non-standard fields) and wires it into both the WPF and Avalonia UI as an export-to-clipboard action.

Changes:

  • Add UI menu + command binding to export selected profiles as v2rayN internal share links to the clipboard.
  • Implement InnerFmt to serialize profiles to v2rayn://{type}/{urlsafe-b64-json} and to resolve/import them back (including policy-group reference rewriting).
  • Extend batch import to recognize and import v2rayn:// links; add a unit test for policy-group round-tripping.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
v2rayN/v2rayN/Views/ProfilesView.xaml.cs Bind new Export2InnerUriCmd to the WPF menu item.
v2rayN/v2rayN/Views/ProfilesView.xaml Add WPF menu entry for exporting internal share links.
v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs Bind new Export2InnerUriCmd to the Avalonia menu item.
v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml Add Avalonia menu entry for exporting internal share links.
v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs Add Export2InnerUriCmd and export implementation using InnerFmt.ToUri.
v2rayN/ServiceLib/Resx/ResUI.resx Add menuExport2InnerUri resource key (default locale).
v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx Add Simplified Chinese translation for new menu label.
v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx Add Traditional Chinese resource entry for new menu label.
v2rayN/ServiceLib/Resx/ResUI.ru.resx Add Russian resource entry for new menu label (English fallback text).
v2rayN/ServiceLib/Resx/ResUI.hu.resx Add Hungarian resource entry for new menu label (English fallback text).
v2rayN/ServiceLib/Resx/ResUI.fr.resx Add French resource entry for new menu label (English fallback text).
v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx Add Persian resource entry for new menu label (English fallback text).
v2rayN/ServiceLib/Resx/ResUI.Designer.cs Expose menuExport2InnerUri via strongly-typed resource accessor.
v2rayN/ServiceLib/Handler/Fmt/InnerFmt.cs New formatter/parser for the internal share-link format with group reference handling.
v2rayN/ServiceLib/Handler/ConfigHandler.cs Add inner-URI batch import and invoke it from AddBatchServers.
v2rayN/ServiceLib/Global.cs Define Global.InnerUriProtocol = "v2rayn://" constant.
v2rayN/ServiceLib.Tests/Fmt/InnerFmtTests.cs Add unit test validating policy-group reference round-trip behavior.
Files not reviewed (1)
  • v2rayN/ServiceLib/Resx/ResUI.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1868 to +1878
var innerUriCount = await AddBatchServers4InnerUri(config, strData, subid, isSub);
if (innerUriCount > 0)
{
if (counter > 0)
{
counter += innerUriCount;
}
else
{
counter = innerUriCount;
}
Comment on lines +1793 to +1804
EConfigType.VMess => await AddVMessServer(config, profileItem),
EConfigType.Shadowsocks => await AddShadowsocksServer(config, profileItem),
EConfigType.HTTP => await AddHttpServer(config, profileItem),
EConfigType.SOCKS => await AddSocksServer(config, profileItem),
EConfigType.Trojan => await AddTrojanServer(config, profileItem),
EConfigType.VLESS => await AddVlessServer(config, profileItem),
EConfigType.Hysteria2 => await AddHysteria2Server(config, profileItem),
EConfigType.TUIC => await AddTuicServer(config, profileItem),
EConfigType.WireGuard => await AddWireguardServer(config, profileItem),
EConfigType.Anytls => await AddAnytlsServer(config, profileItem),
EConfigType.Naive => await AddNaiveServer(config, profileItem),
EConfigType.PolicyGroup or EConfigType.ProxyChain => await AddServerCommon(config, profileItem),
Comment on lines +20 to +26
var trimmedLine = line.Trim();
if (!line.StartsWith(Global.InnerUriProtocol, StringComparison.OrdinalIgnoreCase))
{
continue;
}
var profileItem = ResolveSingle(trimmedLine);
if (profileItem is null)
@2dust 2dust merged commit 75ea81d into 2dust:master May 6, 2026
5 checks passed
@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 6, 2026

CC @fscarmen

[ -s ${WORK_DIR}/cert/cert_200.pem ] && local CERT_200_JSON2=$(awk '{printf "%s\\n", $0}' ${WORK_DIR}/cert/cert_200.pem)

v2rayn://anytls/$(echo -n "{\"ConfigType\":11,\"CoreType\":24,\"ConfigVersion\":4,\"Remarks\":\"${NODE_NAME[21]} ${NODE_TAG[10]}\",\"Address\":\"${SERVER_IP_1}\",\"Port\":${PORT_NAIVE},\"Password\":\"${UUID[21]}\",\"StreamSecurity\":\"tls\",\"AllowInsecure\":\"false\",\"Sni\":\"${TLS_SERVER}\",\"Fingerprint\":\"firefox\",\"Cert\":\"${CERT_200_JSON2}\"}" | base64 -w0 | tr '+/' '-_' | tr -d '=')

v2rayn://naive/$(echo -n "{\"ConfigType\":12,\"CoreType\":24,\"ConfigVersion\":4,\"Remarks\":\"${NODE_NAME[22]} ${NODE_TAG[11]} http2\",\"Address\":\"${SERVER_IP_1}\",\"Port\":${PORT_NAIVE},\"Password\":\"${UUID[22]}\",\"Username\":\"${UUID[22]}\",\"StreamSecurity\":\"tls\",\"AllowInsecure\":\"false\",\"Sni\":\"${TLS_SERVER}\",\"Cert\":\"${CERT_200_JSON2}\"}" | base64 -w0 | tr '+/' '-_' | tr -d '=')

v2rayn://naive/$(echo -n "{\"ConfigType\":12,\"CoreType\":24,\"ConfigVersion\":4,\"Remarks\":\"${NODE_NAME[22]} ${NODE_TAG[11]} quic\",\"Address\":\"${SERVER_IP_1}\",\"Port\":${PORT_NAIVE},\"Password\":\"${UUID[22]}\",\"Username\":\"${UUID[22]}\",\"StreamSecurity\":\"tls\",\"AllowInsecure\":\"false\",\"Sni\":\"${TLS_SERVER}\",\"Cert\":\"${CERT_200_JSON2}\",\"ProtoExtraObj\":{\"CongestionControl\":\"bbr\",\"NaiveQuic\":true}}" | base64 -w0 | tr '+/' '-_' | tr -d '=')

@fscarmen
Copy link
Copy Markdown

fscarmen commented May 6, 2026

Nice,一直觉得v2rayN应该有自己一套分享规则。这次把证书指纹处理了,谢谢大佬啊!我今晚更新一下脚本先。

@fscarmen
Copy link
Copy Markdown

fscarmen commented May 6, 2026

CC @fscarmen

搞掂,fscarmen/sing-box@847fb00

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 7, 2026

CC @fscarmen

搞掂,fscarmen/sing-box@847fb00

对...对吗?

证书解析只认 \n\r\n 来着,逗号应该不认;
或者直接不加换行应该也认

public static string ExportCertToPem(X509Certificate2 cert)
{
var der = cert.Export(X509ContentType.Cert);
var b64 = Convert.ToBase64String(der);
return $"-----BEGIN CERTIFICATE-----\n{b64}\n-----END CERTIFICATE-----\n";
}
/// <summary>
/// Parse concatenated PEM certificates string into a list of individual certificates
/// Normalizes format: removes line breaks from base64 content for better compatibility
/// </summary>
/// <param name="pemChain">Concatenated PEM certificates string (supports both \r\n and \n line endings)</param>
/// <returns>List of individual PEM certificate strings with normalized format</returns>
public static List<string> ParsePemChain(string pemChain)
{
var certs = new List<string>();
if (string.IsNullOrWhiteSpace(pemChain))
{
return certs;
}
// Normalize line endings (CRLF -> LF) at the beginning
pemChain = pemChain.Replace("\r\n", "\n").Replace("\r", "\n");
const string beginMarker = "-----BEGIN CERTIFICATE-----";
const string endMarker = "-----END CERTIFICATE-----";

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 7, 2026

@fscarmen
Copy link
Copy Markdown

fscarmen commented May 7, 2026

CC @fscarmen

搞掂,fscarmen/sing-box@847fb00

对...对吗?

证书解析只认 \n\r\n 来着,逗号应该不认; 或者直接不加换行应该也认

public static string ExportCertToPem(X509Certificate2 cert)
{
var der = cert.Export(X509ContentType.Cert);
var b64 = Convert.ToBase64String(der);
return $"-----BEGIN CERTIFICATE-----\n{b64}\n-----END CERTIFICATE-----\n";
}
/// <summary>
/// Parse concatenated PEM certificates string into a list of individual certificates
/// Normalizes format: removes line breaks from base64 content for better compatibility
/// </summary>
/// <param name="pemChain">Concatenated PEM certificates string (supports both \r\n and \n line endings)</param>
/// <returns>List of individual PEM certificate strings with normalized format</returns>
public static List<string> ParsePemChain(string pemChain)
{
var certs = new List<string>();
if (string.IsNullOrWhiteSpace(pemChain))
{
return certs;
}
// Normalize line endings (CRLF -> LF) at the beginning
pemChain = pemChain.Replace("\r\n", "\n").Replace("\r", "\n");
const string beginMarker = "-----BEGIN CERTIFICATE-----";
const string endMarker = "-----END CERTIFICATE-----";

可以的。这个小意思,我看导出的,有 /r/n 的,我用一模一样的格式可以了,在 tuic / anyTLS / naive 上试过都可以了。至于 hysteria2 / trojan 用 xray 内核,分享链接可以短一点。

另外我从导出的v2rayN专属链接 base64 解码后

{"IndexId":"G9enRw","ConfigType":8,"CoreType":24,"ConfigVersion":4,"IsSub":false,"DisplayLog":true,"Remarks":"\uD83C\uDDFA\uD83C\uDDF8 dartnode tuic","Address":"126.58.142.198","Port":8883,"Password":"3ea4a724-31ff-4bba-993d-7dc07d1b67aa","Username":"3ea4a724-31ff-4bba-993d-7dc07d1b67aa","StreamSecurity":"tls","AllowInsecure":"false","Sni":"addons.mozilla.org","Alpn":"h3","Cert":"-----BEGIN CERTIFICATE-----\r\nMIIBcTCCARagAwIBAgIUNoU6kcynHFQXOyb48Q8AMhsueG0wCgYIKoZIzj0EAwIw\r\nFjEUMBIGA1UEAwwLbW96aWxsYS5vcmcwIBcNMjYwNDI2MDcxMTMwWhgPMjEyNjA0\r\nMDIwNzExMzBaMBYxFDASBgNVBAMMC21vemlsbGEub3JnMFkwEwYHKoZIzj0CAQYI\r\nKoZIzj0DAQcDQgAEcyJ4UIMgBAUwT6s486g2cM/nKthnHOQfxsNDDFh507DsJ68Z\r\n/x0tUIcp1ojAXBp+kRSDlbukec9YcBJJn2ZHkaNAMD4wHQYDVR0RBBYwFIISYWRk\r\nb25zLm1vemlsbGEub3JnMB0GA1UdDgQWBBTojkmCuCz+esQcVVLL/ZhgiyRBLjAK\r\nBggqhkjOPQQDAgNJADBGAiEA3szKvP+M2XOKZc6kXGltW3BdgkY9sSr5Zy3OuBbu\r\nARACIQCHCrpYLnYg2MDRndLq/hHGMd2p/4c7mVdTUR5MWBmWog==\r\n-----END CERTIFICATE-----","CertSha":"AD43F6CF705E4C3FAB96AFFA9D58481D29AA908DB977973E8BBDBDA521565A05","AlterId":0,"ProtoExtraObj":{"CongestionControl":"bbr","VmessSecurity":"auto","VlessEncryption":"none","WgMtu":1280},"TransportExtraObj":{"RawHeaderType":"none","XhttpMode":"auto","GrpcMode":"gun","KcpHeaderType":"none"}}

我没有要 IndexId ,IsSub, DisplayLog 和 CertSha 及之后的,再编码导入 v2rayN,是可以通的,这些是不是都不需要的。

"ConfigVersion":4 这个我现在保留,要不要的?
有了 ConfigType 8 已经代表 tuic了,为什么还要 v2rayn://tuic/ 这里的 tuic 呢?只是给用户容易辨别是什么协议?
上面的请帮确定一下呢:)

@2dust
Copy link
Copy Markdown
Owner

2dust commented May 7, 2026

有了 ConfigType 8 已经代表 tuic了,为什么还要 v2rayn://tuic/ 这里的 tuic 呢?只是给用户容易辨别是什么协议?

你问的对,是可以不要 tuic 的。
可能 @DHR60 是考虑方便处理或人类可读?
我们是否要考虑打通 v2rayN 和 v2rayNG 的 内部分享?

@fscarmen
Copy link
Copy Markdown

fscarmen commented May 7, 2026

我们是否要考虑打通 v2rayN 和 v2rayNG 的 内部分享?

必须要啦,有了 v2rayN 专属的规范,N 和 NG 共用就方便了。

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 8, 2026

我没有要 IndexId ,IsSub, DisplayLog 和 CertSha 及之后的,再编码导入 v2rayN,是可以通的,这些是不是都不需要的。

是的,必填字段只有 ConfigType,ConfigVersion,Remarks,否则导入失败
其他的按需填写

"ConfigVersion":4 这个我现在保留,要不要的?

需要

有了 ConfigType 8 已经代表 tuic了,为什么还要 v2rayn://tuic/ 这里的 tuic 呢?只是给用户容易辨别是什么协议? 上面的请帮确定一下呢:)

目前是这样,只是给用户容易辨别是什么协议
未来说不定会加校验,分享链接版本这种

@fscarmen
Copy link
Copy Markdown

fscarmen commented May 10, 2026

原来各协议通过base64编码后弄成订阅是可以的,现在 v2rayn:// 内部分享连接经过编码后不行了。

LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2bGVzczovL2JkZDQzZTE1LTczYjktNDIyMC1hNTRlLWNhZWI4ZDA5ZjRiYUBbMjYwMjoyOTQ6MDpkYzoxMjM0OjQzMjE6NzAwMzoxXTo4ODgxP2VuY3J5cHRpb249bm9uZSZmbG93PXh0bHMtcnByeC12aXNpb24mc2VjdXJpdHk9cmVhbGl0eSZzbmk9YWRkb25zLm1vemlsbGEub3JnJmZwPWZpcmVmb3gmcGJrPUpuSUptR3BuS3VDY1l6UVBYX19wMGNGdjJKTm5ETTRZVldtTU9lTG1KaEEmdHlwZT10Y3AmaGVhZGVyVHlwZT1ub25lI/Cfh7rwn4e4JTIwYm9iYSUyMHh0bHMtcmVhbGl0eQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmh5c3RlcmlhMjovL2JkZDQzZTE1LTczYjktNDIyMC1hNTRlLWNhZWI4ZDA5ZjRiYUBbMjYwMjoyOTQ6MDpkYzoxMjM0OjQzMjE6NzAwMzoxXTo4ODgyP3NuaT1hZGRvbnMubW96aWxsYS5vcmcmYWxwbj1oMyZpbnNlY3VyZT0xJmFsbG93SW5zZWN1cmU9MSZwaW5TSEEyNTY9N0EyQkZCRjE2MUI1NzIwMUI3NDBENzEwQ0UyMkMwOTUzMTJDRUMzQUUxOTJFQjJFRUNEQjEwQzI4RDFEQjIwNSZtcG9ydD01MDAwMC01MTAwMCPwn4e68J+HuCUyMGJvYmElMjBoeXN0ZXJpYTIKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2MnJheW46Ly90dWljL2V5SkRiMjVtYVdkVWVYQmxJam80TENKRGIzSmxWSGx3WlNJNk1qUXNJa052Ym1acFoxWmxjbk5wYjI0aU9qUXNJbEpsYldGeWEzTWlPaUx3bjRlNjhKLUh1Q0JpYjJKaElIUjFhV01pTENKQlpHUnlaWE56SWpvaVd6STJNREk2TWprME9qQTZaR002TVRJek5EbzBNekl4T2pjd01ETTZNVjBpTENKUWIzSjBJam80T0RnekxDSlFZWE56ZDI5eVpDSTZJbUprWkRRelpURTFMVGN6WWprdE5ESXlNQzFoTlRSbExXTmhaV0k0WkRBNVpqUmlZU0lzSWxWelpYSnVZVzFsSWpvaVltUmtORE5sTVRVdE56TmlPUzAwTWpJd0xXRTFOR1V0WTJGbFlqaGtNRGxtTkdKaElpd2lVM1J5WldGdFUyVmpkWEpwZEhraU9pSjBiSE1pTENKQmJHeHZkMGx1YzJWamRYSmxJam9pWm1Gc2MyVWlMQ0pUYm1raU9pSmhaR1J2Ym5NdWJXOTZhV3hzWVM1dmNtY2lMQ0pCYkhCdUlqb2lhRE1pTENKRFpYSjBJam9pTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0WEhKY2JrMUpTVUpWUkVOQ09UWkJSRUZuUlVOQmFGRnVSVkZaV2xNMFlUWlVjbEIxTVhObWQzQXlWVnB4Ynpob1dFUkJTMEpuWjNGb2EycFBVRkZSUkVGcVFWZGNjbHh1VFZKUmQwVm5XVVJXVVZGRVJFRjBkR0l6Y0hCaVIzaG9URzA1ZVZwNlFXZEdkekI1VG1wQk1FMXFZM2hPVkZVelRrUmFZVWRCT0hsTlZFa3lUVVJSZDF4eVhHNU5la1V4VGxSak1FNXNiM2RHYWtWVlRVSkpSMEV4VlVWQmQzZE1ZbGM1Tm1GWGVITlpVelYyWTIxamQxZFVRVlJDWjJOeGFHdHFUMUJSU1VKQ1oyZHhYSEpjYm1ocmFrOVFVVTFDUW5kT1EwRkJVMUpuT1hOMFVqTTBNa2QxWkROa01XUkVieXRIVm5SVGJXMWxlamxKTTFSelEwVlRLMVp2TjNaelFqVkRTa3BYVUhkY2NseHVXRzlTT0U1cVJsQnlNR0ZyUjNCSlJ6QXZNa2RwYlhkSlZtcExNa1ZhTUc5cVRHc3hiM2xGZDBoNlFXUkNaMDVXU0ZKRlJVWnFRVlZuYUVwb1drZFNkbHh5WEc1aWJrMTFZbGM1Tm1GWGVITlpVelYyWTIxamQwTm5XVWxMYjFwSmVtb3dSVUYzU1VSVFFVRjNVbEZKWjJFNWN6TlRNVlI1ZEZVd1NsZHRSVVJPTnk5VVhISmNibUUyYXpZM1pEaHNhSE1yWlZsNlVrRXpXRFZaVTBSWlEwbFJRMnBHWkhCbWJFTmtibk54V25sV1lqWklkbWRFVUVWUU9VRnlkRTlaVDJ3MFVIWTRPR0pjY2x4dVNuQjZhR2xSUFQxY2NseHVMUzB0TFMxRlRrUWdRMFZTVkVsR1NVTkJWRVV0TFMwdExWeHlYRzRpTENKUWNtOTBiMFY0ZEhKaFQySnFJanA3SWtOdmJtZGxjM1JwYjI1RGIyNTBjbTlzSWpvaVltSnlJbjE5Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzczovL01qQXlNaTFpYkdGclpUTXRZV1Z6TFRFeU9DMW5ZMjA2VlVGc1RXbFVVM3BLZVZreGNtWktjSEJIZVU5NmR6MDlRRnN5TmpBeU9qSTVORG93T21Sak9qRXlNelE2TkRNeU1UbzNNREF6T2pGZE9qZzRPRFU9I/Cfh7rwn4e4JTIwYm9iYSUyMHNoYWRvd3NvY2tzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdHJvamFuOi8vYmRkNDNlMTUtNzNiOS00MjIwLWE1NGUtY2FlYjhkMDlmNGJhQFsyNjAyOjI5NDowOmRjOjEyMzQ6NDMyMTo3MDAzOjFdOjg4ODY/c2VjdXJpdHk9dGxzJmluc2VjdXJlPTEmYWxsb3dJbnNlY3VyZT0xJnBjcz03QTJCRkJGMTYxQjU3MjAxQjc0MEQ3MTBDRTIyQzA5NTMxMkNFQzNBRTE5MkVCMkVFQ0RCMTBDMjhEMURCMjA1JnR5cGU9dGNwJmhlYWRlclR5cGU9bm9uZSPwn4e68J+HuCUyMGJvYmElMjB0cm9qYW4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2bWVzczovL2V5QWlkaUk2SUNJeUlpd2dJbkJ6SWpvZ0l2Q2ZoN3J3bjRlNElHSnZZbUVnZG0xbGMzTXRkM01pTENBaVlXUmtJam9nSW1ObUxqQTVNREl5Tnk1NGVYb2lMQ0FpY0c5eWRDSTZJQ0k0TUNJc0lDSnBaQ0k2SUNKaVpHUTBNMlV4TlMwM00ySTVMVFF5TWpBdFlUVTBaUzFqWVdWaU9HUXdPV1kwWW1FaUxDQWlZV2xrSWpvZ0lqQWlMQ0FpYzJONUlqb2dJbTV2Ym1VaUxDQWlibVYwSWpvZ0luZHpJaXdnSW5SNWNHVWlPaUFpWVhWMGJ5SXNJQ0pvYjNOMElqb2dJbVJ1WVMxallYSnlhV1Z5TFhSeWIzVjBMWE4wZVd4MWN5NTBjbmxqYkc5MVpHWnNZWEpsTG1OdmJTSXNJQ0p3WVhSb0lqb2dJaTlpWkdRME0yVXhOUzAzTTJJNUxUUXlNakF0WVRVMFpTMWpZV1ZpT0dRd09XWTBZbUV0ZG0xbGMzTWlMQ0FpZEd4eklqb2dJaUlzSUNKemJta2lPaUFpSWl3Z0ltRnNjRzRpT2lBaUlpQjkKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2bGVzczovL2JkZDQzZTE1LTczYjktNDIyMC1hNTRlLWNhZWI4ZDA5ZjRiYUBjZi4wOTAyMjcueHl6OjQ0Mz9lbmNyeXB0aW9uPW5vbmUmc2VjdXJpdHk9dGxzJnNuaT1kbmEtY2Fycmllci10cm91dC1zdHlsdXMudHJ5Y2xvdWRmbGFyZS5jb20mdHlwZT13cyZob3N0PWRuYS1jYXJyaWVyLXRyb3V0LXN0eWx1cy50cnljbG91ZGZsYXJlLmNvbSZwYXRoPSUyRmJkZDQzZTE1LTczYjktNDIyMC1hNTRlLWNhZWI4ZDA5ZjRiYS12bGVzcyUzRmVkJTNEMjU2MCPwn4e68J+HuCUyMGJvYmElMjB2bGVzcy13cy10bHMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2bGVzczovL2JkZDQzZTE1LTczYjktNDIyMC1hNTRlLWNhZWI4ZDA5ZjRiYUBbMjYwMjoyOTQ6MDpkYzoxMjM0OjQzMjE6NzAwMzoxXTo4ODg5P2VuY3J5cHRpb249bm9uZSZzZWN1cml0eT1yZWFsaXR5JnNuaT1hZGRvbnMubW96aWxsYS5vcmcmZnA9ZmlyZWZveCZwYms9Sm5JSm1HcG5LdUNjWXpRUFhfX3AwY0Z2MkpObkRNNFlWV21NT2VMbUpoQSZ0eXBlPWh0dHAj8J+HuvCfh7glMjBib2JhJTIwaDItcmVhbGl0eQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZsZXNzOi8vYmRkNDNlMTUtNzNiOS00MjIwLWE1NGUtY2FlYjhkMDlmNGJhQFsyNjAyOjI5NDowOmRjOjEyMzQ6NDMyMTo3MDAzOjFdOjg4OTA/ZW5jcnlwdGlvbj1ub25lJnNlY3VyaXR5PXJlYWxpdHkmc25pPWFkZG9ucy5tb3ppbGxhLm9yZyZmcD1maXJlZm94JnBiaz1KbklKbUdwbkt1Q2NZelFQWF9fcDBjRnYySk5uRE00WVZXbU1PZUxtSmhBJnR5cGU9Z3JwYyZzZXJ2aWNlTmFtZT1ncnBjJm1vZGU9Z3VuI/Cfh7rwn4e4JTIwYm9iYSUyMGdycGMtcmVhbGl0eQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnYycmF5bjovL2FueXRscy9leUpEYjI1bWFXZFVlWEJsSWpveE1Td2lRMjl5WlZSNWNHVWlPakkwTENKRGIyNW1hV2RXWlhKemFXOXVJam8wTENKU1pXMWhjbXR6SWpvaThKLUh1dkNmaDdnZ1ltOWlZU0JoYm5sMGJITWlMQ0pCWkdSeVpYTnpJam9pV3pJMk1ESTZNamswT2pBNlpHTTZNVEl6TkRvME16SXhPamN3TURNNk1WMGlMQ0pRYjNKMElqbzRPRGt4TENKUVlYTnpkMjl5WkNJNkltSmtaRFF6WlRFMUxUY3pZamt0TkRJeU1DMWhOVFJsTFdOaFpXSTRaREE1WmpSaVlTSXNJbE4wY21WaGJWTmxZM1Z5YVhSNUlqb2lkR3h6SWl3aVFXeHNiM2RKYm5ObFkzVnlaU0k2SW1aaGJITmxJaXdpVTI1cElqb2lZV1JrYjI1ekxtMXZlbWxzYkdFdWIzSm5JaXdpUm1sdVoyVnljSEpwYm5RaU9pSm1hWEpsWm05NElpd2lRMlZ5ZENJNklpMHRMUzB0UWtWSFNVNGdRMFZTVkVsR1NVTkJWRVV0TFMwdExWeHlYRzVOU1VsQ1ZVUkRRamsyUVVSQlowVkRRV2hSYmtWUldWcFROR0UyVkhKUWRURnpabmR3TWxWYWNXODRhRmhFUVV0Q1oyZHhhR3RxVDFCUlVVUkJha0ZYWEhKY2JrMVNVWGRGWjFsRVZsRlJSRVJCZEhSaU0zQndZa2Q0YUV4dE9YbGFla0ZuUm5jd2VVNXFRVEJOYW1ONFRsUlZNMDVFV21GSFFUaDVUVlJKTWsxRVVYZGNjbHh1VFhwRk1VNVVZekJPYkc5M1JtcEZWVTFDU1VkQk1WVkZRWGQzVEdKWE9UWmhWM2h6V1ZNMWRtTnRZM2RYVkVGVVFtZGpjV2hyYWs5UVVVbENRbWRuY1Z4eVhHNW9hMnBQVUZGTlFrSjNUa05CUVZOU1p6bHpkRkl6TkRKSGRXUXpaREZrUkc4clIxWjBVMjF0WlhvNVNUTlVjME5GVXl0V2J6ZDJjMEkxUTBwS1YxQjNYSEpjYmxodlVqaE9ha1pRY2pCaGEwZHdTVWN3THpKSGFXMTNTVlpxU3pKRldqQnZha3hyTVc5NVJYZElla0ZrUW1kT1ZraFNSVVZHYWtGVloyaEthRnBIVW5aY2NseHVZbTVOZFdKWE9UWmhWM2h6V1ZNMWRtTnRZM2REWjFsSlMyOWFTWHBxTUVWQmQwbEVVMEZCZDFKUlNXZGhPWE16VXpGVWVYUlZNRXBYYlVWRVRqY3ZWRnh5WEc1aE5tczJOMlE0YkdoeksyVlplbEpCTTFnMVdWTkVXVU5KVVVOcVJtUndabXhEWkc1emNWcDVWbUkyU0hablJGQkZVRGxCY25SUFdVOXNORkIyT0RoaVhISmNia3B3ZW1ocFVUMDlYSEpjYmkwdExTMHRSVTVFSUVORlVsUkpSa2xEUVZSRkxTMHRMUzFjY2x4dUluMAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnYycmF5bjovL25haXZlL2V5SkRiMjVtYVdkVWVYQmxJam94TWl3aVEyOXlaVlI1Y0dVaU9qSTBMQ0pEYjI1bWFXZFdaWEp6YVc5dUlqbzBMQ0pTWlcxaGNtdHpJam9pOEotSHV2Q2ZoN2dnWW05aVlTQnVZV2wyWlNCb2RIUndNaUlzSWtGa1pISmxjM01pT2lKYk1qWXdNam95T1RRNk1EcGtZem94TWpNME9qUXpNakU2TnpBd016b3hYU0lzSWxCdmNuUWlPamc0T1RJc0lsQmhjM04zYjNKa0lqb2lZbVJrTkRObE1UVXROek5pT1MwME1qSXdMV0UxTkdVdFkyRmxZamhrTURsbU5HSmhJaXdpVlhObGNtNWhiV1VpT2lKaVpHUTBNMlV4TlMwM00ySTVMVFF5TWpBdFlUVTBaUzFqWVdWaU9HUXdPV1kwWW1FaUxDSlRkSEpsWVcxVFpXTjFjbWwwZVNJNkluUnNjeUlzSWtGc2JHOTNTVzV6WldOMWNtVWlPaUptWVd4elpTSXNJbE51YVNJNkltRmtaRzl1Y3k1dGIzcHBiR3hoTG05eVp5SXNJa05sY25RaU9pSXRMUzB0TFVKRlIwbE9JRU5GVWxSSlJrbERRVlJGTFMwdExTMWNjbHh1VFVsSlFsUjZRMEk1WVVGRVFXZEZRMEZvVVV4bWMwUkVhREJYVEdSQlF6RkdWMFV3TjFZMmIzSmxTazl6VkVGTFFtZG5jV2hyYWs5UVVWRkVRV3BCVjF4eVhHNU5VbEYzUldkWlJGWlJVVVJFUVhSMFlqTndjR0pIZUdoTWJUbDVXbnBCWlVaM01IbE9ha0V3VFdwamVFNVVWVE5PUkZwaFJuY3dlVTVxUlhoTlZFMTRYSEpjYms1VVZUTk9SRnBoVFVKWmVFWkVRVk5DWjA1V1FrRk5UVU15TVhabGJXeHpZa2RGZFdJelNtNU5SbXQzUlhkWlNFdHZXa2w2YWpCRFFWRlpTVXR2V2tsY2NseHVlbW93UkVGUlkwUlJaMEZGYTFsUVlreFZaQ3RPYUhKdVpETmtXRkUyVUdoc1lsVndjRzV6TDFOT01EZEJhRVYyYkdGUE56ZEJaVkZwVTFacU9FWTJSVnh5WEc1bVJGbDRWRFk1UjNCQ2NWTkNkRkE1YUc5d2MwTkdXWGwwYUVka1MwbDVOVTVoVFdoTlFqaDNTRkZaUkZaU01GSkNRbGwzUmtsSlUxbFhVbXRpTWpWNlhISmNia3h0TVhabGJXeHpZa2RGZFdJelNtNU5RVzlIUTBOeFIxTk5ORGxDUVUxRFFUQnJRVTFGV1VOSlVVUlVVaXRqWm1Gck5HSlRVamR1ZFM5SEszaGFRMkZjY2x4dVpXeHVjRU5KWlZGb2JHTktkRGhXZW1SMlZrWjRaMGxvUVVzNGJEbHhaRWRRZWpSWFdrTmFNRnBoVVU1WlVrbGlkRGcyV1doM2ExUmpaV1JDUldoSk4xeHlYRzQxU0U1VFhISmNiaTB0TFMwdFJVNUVJRU5GVWxSSlJrbERRVlJGTFMwdExTMWNjbHh1SW4wCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdjJyYXluOi8vbmFpdmUvZXlKRGIyNW1hV2RVZVhCbElqb3hNaXdpUTI5eVpWUjVjR1VpT2pJMExDSkRiMjVtYVdkV1pYSnphVzl1SWpvMExDSlNaVzFoY210eklqb2k4Si1IdXZDZmg3Z2dZbTlpWVNCdVlXbDJaU0J4ZFdsaklpd2lRV1JrY21WemN5STZJbHN5TmpBeU9qSTVORG93T21Sak9qRXlNelE2TkRNeU1UbzNNREF6T2pGZElpd2lVRzl5ZENJNk9EZzVNaXdpVUdGemMzZHZjbVFpT2lKaVpHUTBNMlV4TlMwM00ySTVMVFF5TWpBdFlUVTBaUzFqWVdWaU9HUXdPV1kwWW1FaUxDSlZjMlZ5Ym1GdFpTSTZJbUprWkRRelpURTFMVGN6WWprdE5ESXlNQzFoTlRSbExXTmhaV0k0WkRBNVpqUmlZU0lzSWxOMGNtVmhiVk5sWTNWeWFYUjVJam9pZEd4eklpd2lRV3hzYjNkSmJuTmxZM1Z5WlNJNkltWmhiSE5sSWl3aVUyNXBJam9pWVdSa2IyNXpMbTF2ZW1sc2JHRXViM0puSWl3aVEyVnlkQ0k2SWkwdExTMHRRa1ZIU1U0Z1EwVlNWRWxHU1VOQlZFVXRMUzB0TFZ4eVhHNU5TVWxDVkhwRFFqbGhRVVJCWjBWRFFXaFJUR1p6UkVSb01GZE1aRUZETVVaWFJUQTNWalp2Y21WS1QzTlVRVXRDWjJkeGFHdHFUMUJSVVVSQmFrRlhYSEpjYmsxU1VYZEZaMWxFVmxGUlJFUkJkSFJpTTNCd1lrZDRhRXh0T1hsYWVrRmxSbmN3ZVU1cVFUQk5hbU40VGxSVk0wNUVXbUZHZHpCNVRtcEZlRTFVVFhoY2NseHVUbFJWTTA1RVdtRk5RbGw0UmtSQlUwSm5UbFpDUVUxTlF6SXhkbVZ0YkhOaVIwVjFZak5LYmsxR2EzZEZkMWxJUzI5YVNYcHFNRU5CVVZsSlMyOWFTVnh5WEc1NmFqQkVRVkZqUkZGblFVVnJXVkJpVEZWa0swNW9jbTVrTTJSWVVUWlFhR3hpVlhCd2JuTXZVMDR3TjBGb1JYWnNZVTgzTjBGbFVXbFRWbW80UmpaRlhISmNibVpFV1hoVU5qbEhjRUp4VTBKMFVEbG9iM0J6UTBaWmVYUm9SMlJMU1hrMVRtRk5hRTFDT0hkSVVWbEVWbEl3VWtKQ1dYZEdTVWxUV1ZkU2EySXlOWHBjY2x4dVRHMHhkbVZ0YkhOaVIwVjFZak5LYmsxQmIwZERRM0ZIVTAwME9VSkJUVU5CTUd0QlRVVlpRMGxSUkZSU0syTm1ZV3MwWWxOU04yNTFMMGNyZUZwRFlWeHlYRzVsYkc1d1EwbGxVV2hzWTBwME9GWjZaSFpXUm5oblNXaEJTemhzT1hGa1IxQjZORmRhUTFvd1dtRlJUbGxTU1dKME9EWlphSGRyVkdObFpFSkZhRWszWEhKY2JqVklUbE5jY2x4dUxTMHRMUzFGVGtRZ1EwVlNWRWxHU1VOQlZFVXRMUzB0TFZ4eVhHNGlMQ0pRY205MGIwVjRkSEpoVDJKcUlqcDdJa052Ym1kbGMzUnBiMjVEYjI1MGNtOXNJam9pWW1KeUlpd2lUbUZwZG1WUmRXbGpJanAwY25WbGZYMA==

结果有4个 v2rayn:// 的不行,分别是 anyTLS , tuic, naive 的两个

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 10, 2026

原来各协议通过base64编码后弄成订阅是可以的,现在 v2rayn:// 内部分享连接经过编码后不行了。

坏了,成笨蛋了,最近写的代码怎么老犯这种低级错误

@2dust
Copy link
Copy Markdown
Owner

2dust commented May 11, 2026

有个问题要讨论下,
可能直接用 ProfileItem 来作为分享的标准来后面会越来越受限,到后面可能会又要重构。
需要考虑新建一个类来作为标准会更好些,虽然这样inner的解析和构造就会复杂了

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 11, 2026

受限是 功能 兼容 还是与其他软件交互上的?

@2dust
Copy link
Copy Markdown
Owner

2dust commented May 11, 2026

  1. ProfileItem 主要是数据持久化设计的,分享或传输应该加一个 DTO 比较合适
  2. ProfileItem 现在产生的内部分享是两层结构,可以考虑一层结构
  3. 和其他软件比如 v2rayNG 的互通
  4. 目前没有想到的情况,应该也会更灵活

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 11, 2026

个人意见,Inner uri 首要的功能是备份,即导出导入后字段不丢失;再的都是次要

所以如果再加个 DTO 也是要做到和 ProfileItem 字段一一映射,感觉好处不大?

@DHR60
Copy link
Copy Markdown
Contributor Author

DHR60 commented May 11, 2026

感觉二层结构不赖吧,层次更强

一层结构感觉不如直接用 URL query 序列化过去

@2dust
Copy link
Copy Markdown
Owner

2dust commented May 11, 2026

为什么我会提出前面的讨论呢,
主要是看到 @fscarmen 在做外部分享给本应用,才会想到方便分享的需要考虑重新设计 DTO

如果我们有不同的意见,那保持现在的先不动。

@fscarmen
Copy link
Copy Markdown

https://github.com/2dust/v2rayN/releases/tag/7.22.0 已可以了,谢谢!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants