mirror of
https://github.com/netchx/netch.git
synced 2026-03-28 18:59:46 +08:00
141 lines
6.1 KiB
C#
141 lines
6.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text.RegularExpressions;
|
||
using System.Web;
|
||
using Netch.Models;
|
||
using Netch.Utils;
|
||
|
||
namespace Netch.Servers.V2ray
|
||
{
|
||
internal static class V2rayUtils
|
||
{
|
||
public static IEnumerable<Server> ParseVUri(string text)
|
||
{
|
||
var scheme = ShareLink.GetUriScheme(text);
|
||
try
|
||
{
|
||
var server = new VMess.VMess();
|
||
if (text.Contains("#"))
|
||
{
|
||
server.Remark = Uri.UnescapeDataString(text.Split('#')[1]);
|
||
text = text.Split('#')[0];
|
||
}
|
||
|
||
if (text.Contains("?"))
|
||
{
|
||
var parameter = HttpUtility.ParseQueryString(text.Split('?')[1]);
|
||
text = text.Substring(0, text.IndexOf("?", StringComparison.Ordinal));
|
||
server.TransferProtocol = parameter.Get("type") ?? "tcp";
|
||
server.EncryptMethod = parameter.Get("encryption") ?? scheme switch {"vless" => "none", _ => "auto"};
|
||
switch (server.TransferProtocol)
|
||
{
|
||
case "tcp":
|
||
break;
|
||
case "kcp":
|
||
server.FakeType = parameter.Get("headerType") ?? "none";
|
||
server.Path = Uri.UnescapeDataString(parameter.Get("seed") ?? "");
|
||
break;
|
||
case "ws":
|
||
server.Path = Uri.UnescapeDataString(parameter.Get("path") ?? "/");
|
||
server.Host = parameter.Get("host") ?? "";
|
||
break;
|
||
case "h2":
|
||
server.Path = Uri.UnescapeDataString(parameter.Get("path") ?? "/");
|
||
server.Host = Uri.UnescapeDataString(parameter.Get("host") ?? "");
|
||
break;
|
||
case "quic":
|
||
server.QUICSecure = parameter.Get("quicSecurity") ?? "none";
|
||
server.QUICSecret = parameter.Get("key") ?? "";
|
||
server.FakeType = parameter.Get("headerType") ?? "none";
|
||
break;
|
||
}
|
||
server.TLSSecureType = parameter.Get("security") ?? "none";
|
||
if (server.TLSSecureType != "none")
|
||
{
|
||
server.Host = parameter.Get("sni") ?? "";
|
||
if (server.TLSSecureType == "xtls")
|
||
((VLESS.VLESS) server).Flow = parameter.Get("flow") ?? "";
|
||
}
|
||
}
|
||
var finder = new Regex(@$"^{scheme}://(?<guid>.+?)@(?<server>.+):(?<port>\d+)");
|
||
var match = finder.Match(text.Split('?')[0]);
|
||
if (!match.Success)
|
||
throw new FormatException();
|
||
|
||
server.UserID = match.Groups["guid"].Value;
|
||
server.Hostname = match.Groups["server"].Value;
|
||
server.Port = ushort.Parse(match.Groups["port"].Value);
|
||
|
||
return new[]
|
||
{
|
||
server
|
||
};
|
||
}
|
||
catch (FormatException e)
|
||
{
|
||
Logging.Error(e.ToString());
|
||
return null;
|
||
}
|
||
}
|
||
public static string GetVShareLink(Server s, string scheme = "vmess")
|
||
{
|
||
var server = (VMess.VMess) s;
|
||
var parameter = new Dictionary<string, string>();
|
||
// protocol-specific fields
|
||
parameter.Add("type", server.TransferProtocol);
|
||
if (server.EncryptMethod == "none")
|
||
// VLESS outbounds[].settings.encryption,当前可选值只有 none
|
||
parameter.Add("encryption", server.EncryptMethod);
|
||
// transport-specific fields
|
||
switch (server.TransferProtocol)
|
||
{
|
||
case "tcp":
|
||
break;
|
||
case "kcp":
|
||
if (server.FakeType != "none")
|
||
parameter.Add("headerType", server.FakeType);
|
||
if (!server.Path.IsNullOrWhiteSpace())
|
||
parameter.Add("seed", Uri.EscapeDataString(server.Path));
|
||
break;
|
||
case "ws":
|
||
parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path));
|
||
if (!server.Host.IsNullOrWhiteSpace())
|
||
parameter.Add("host", server.Host);
|
||
break;
|
||
case "h2":
|
||
parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path));
|
||
if (!server.Host.IsNullOrWhiteSpace())
|
||
parameter.Add("host", Uri.EscapeDataString(server.Host));
|
||
break;
|
||
case "quic":
|
||
if (server.QUICSecure != "none")
|
||
{
|
||
parameter.Add("quicSecurity", server.QUICSecure);
|
||
parameter.Add("key", server.QUICSecret);
|
||
}
|
||
|
||
if (server.FakeType != "none")
|
||
parameter.Add("headerType", server.FakeType);
|
||
break;
|
||
}
|
||
|
||
if (server.TLSSecureType != "none")
|
||
{
|
||
parameter.Add("security", server.TLSSecureType);
|
||
|
||
if (!server.Host.IsNullOrWhiteSpace())
|
||
parameter.Add("sni", server.Host);
|
||
|
||
if (server.TLSSecureType == "xtls")
|
||
{
|
||
var flow = ((VLESS.VLESS) server).Flow.Replace("-udp443", "");
|
||
if (!flow.IsNullOrWhiteSpace())
|
||
parameter.Add("flow", flow);
|
||
}
|
||
}
|
||
|
||
return $"{scheme}://{server.UserID}@{server.Hostname}:{server.Port}?{string.Join("&", parameter.Select(p => $"{p.Key}={p.Value}"))}{(server.Remark.IsNullOrWhiteSpace() ? "" : $"#{Uri.EscapeDataString(server.Remark)}")}";
|
||
}
|
||
}
|
||
} |