From e3b1ae0621f6ae636735fa3bfc0a1a05bc58bc90 Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Mon, 5 Jul 2021 20:29:45 +0800 Subject: [PATCH] Feature: Xray ServerName(sni) Support Refactor Generate Xray config file --- Netch/Servers/V2ray/Models/V2rayConfig.cs | 187 +------ Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs | 512 ++++++++---------- Netch/Servers/V2ray/V2rayUtils.cs | 19 +- Netch/Servers/VLESS/VLESS.cs | 3 +- Netch/Servers/VLESS/VLESSForm/VLESSForm.cs | 3 +- Netch/Servers/VMess/Form/VMessForm.cs | 7 +- Netch/Servers/VMess/VMess.cs | 8 +- Netch/Servers/VMess/VMessUtil.cs | 6 +- Netch/Utils/StringExtension.cs | 10 + 9 files changed, 268 insertions(+), 487 deletions(-) diff --git a/Netch/Servers/V2ray/Models/V2rayConfig.cs b/Netch/Servers/V2ray/Models/V2rayConfig.cs index dd7827cd..a6091a68 100644 --- a/Netch/Servers/V2ray/Models/V2rayConfig.cs +++ b/Netch/Servers/V2ray/Models/V2rayConfig.cs @@ -1,57 +1,21 @@ #nullable disable -using System.Collections.Generic; +// ReSharper disable InconsistentNaming -namespace Netch.Servers.Models +namespace Netch.Servers.V2ray.Models { - public class V2rayConfig + public struct V2rayConfig { - public List inbounds { get; } = new(); + public object[] inbounds { get; set; } - public List outbounds { get; } = new(); - - public Routing routing { get; } = new(); + public Outbound[] outbounds { get; set; } } - public class Inbounds - { - public string tag { get; set; } - - public ushort port { get; set; } - - public string listen { get; set; } - - public string protocol { get; set; } - - public Sniffing sniffing { get; set; } - - public Inboundsettings settings { get; set; } - - public StreamSettings streamSettings { get; set; } - } - - public class Inboundsettings - { - public string auth { get; set; } - - public bool udp { get; set; } - - public string ip { get; set; } - - public string address { get; set; } - - public List clients { get; set; } - - public string decryption { get; set; } - } - - public class UsersItem + public class User { public string id { get; set; } public int alterId { get; set; } - public string email { get; set; } - public string security { get; set; } public string encryption { get; set; } @@ -59,33 +23,22 @@ namespace Netch.Servers.Models public string flow { get; set; } } - public class Sniffing + public class Outbound { - public bool enabled { get; set; } - - public List destOverride { get; set; } - } - - public class Outbounds - { - public string tag { get; set; } - public string protocol { get; set; } - public Outboundsettings settings { get; set; } + public OutboundConfiguration settings { get; set; } public StreamSettings streamSettings { get; set; } public Mux mux { get; set; } } - public class Outboundsettings + public class OutboundConfiguration { - public List vnext { get; set; } + public VnextItem[] vnext { get; set; } - public List servers { get; set; } - - public Response response { get; set; } + public object[] servers { get; set; } } public class VnextItem @@ -94,35 +47,7 @@ namespace Netch.Servers.Models public ushort port { get; set; } - public List users { get; set; } - } - - public class ServersItem - { - public string email { get; set; } - - public string address { get; set; } - - public string method { get; set; } - - public bool ota { get; set; } - - public string password { get; set; } - - public ushort port { get; set; } - - public int level { get; set; } - - public List users { get; set; } - } - - public class SocksUsersItem - { - public string user { get; set; } - - public string pass { get; set; } - - public int level { get; set; } + public User[] users { get; set; } } public class Mux @@ -132,38 +57,6 @@ namespace Netch.Servers.Models public int concurrency { get; set; } } - public class Response - { - public string type { get; set; } - } - - public class Dns - { - public List servers { get; set; } - } - - public class RulesItem - { - public string type { get; set; } - - public string port { get; set; } - - public List inboundTag { get; set; } - - public string outboundTag { get; set; } - - public List ip { get; set; } - - public List domain { get; set; } - } - - public class Routing - { - public string domainStrategy { get; set; } - - public List rules { get; } = new(); - } - public class StreamSettings { public string network { get; set; } @@ -187,6 +80,8 @@ namespace Netch.Servers.Models public GrpcSettings grpcSettings { get; set; } } + #region Transport + public class TlsSettings { public bool allowInsecure { get; set; } @@ -196,40 +91,14 @@ namespace Netch.Servers.Models public class TcpSettings { - public Header header { get; set; } + public object header { get; set; } } - public class Header + public class WsSettings { - public string type { get; set; } + public string path { get; set; } - public TCPRequest request { get; set; } - - public object response { get; set; } - } - - public class TCPRequest - { - public TCPRequestHeaders headers { get; set; } - - public string method { get; set; } = "GET"; - - public string path { get; set; } = "/"; - - public string version { get; set; } = "1.1"; - } - - public class TCPRequestHeaders - { - //public string User_Agent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36"; - - public string Accept_Encoding { get; set; } = "gzip, deflate"; - - public string Connection { get; set; } = "keep-alive"; - - public string Host { get; set; } - - public string Pragma { get; set; } = "no-cache"; + public object headers { get; set; } } public class KcpSettings @@ -248,28 +117,16 @@ namespace Netch.Servers.Models public int writeBufferSize { get; set; } - public Header header { get; set; } + public object header { get; set; } public string seed { get; set; } } - public class WsSettings - { - public string path { get; set; } - - public Headers headers { get; set; } - } - - public class Headers - { - public string Host { get; set; } - } - public class HttpSettings { public string path { get; set; } - public List host { get; set; } + public string[] host { get; set; } } public class QuicSettings @@ -278,7 +135,7 @@ namespace Netch.Servers.Models public string key { get; set; } - public Header header { get; set; } + public object header { get; set; } } public class GrpcSettings @@ -287,4 +144,6 @@ namespace Netch.Servers.Models public bool multiMode { get; set; } } + + #endregion } \ No newline at end of file diff --git a/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs b/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs index 2493507e..e2d32587 100644 --- a/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs +++ b/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; -using System.Linq; +using System.Diagnostics; using System.Text.Json; using Netch.Models; -using Netch.Servers.Models; -using V2rayConfig = Netch.Servers.Models.V2rayConfig; +using Netch.Servers.V2ray.Models; +using Netch.Utils; +using V2rayConfig = Netch.Servers.V2ray.Models.V2rayConfig; namespace Netch.Servers.Utils { @@ -11,342 +11,252 @@ namespace Netch.Servers.Utils { public static string GenerateClientConfig(Server server) { - var v2rayConfig = new V2rayConfig(); - - inbound(server, ref v2rayConfig); - - routing(server, ref v2rayConfig); + var v2rayConfig = new V2rayConfig + { + inbounds = new object[] + { + new + { + port = Global.Settings.Socks5LocalPort, + protocol = "socks", + listen = Global.Settings.LocalAddress, + settings = new + { + udp = true + } + } + } + }; outbound(server, ref v2rayConfig); return JsonSerializer.Serialize(v2rayConfig, Global.NewDefaultJsonSerializerOptions); } - private static void inbound(Server server, ref V2rayConfig v2rayConfig) - { - try - { - var inbound = new Inbounds - { - port = Global.Settings.Socks5LocalPort, - protocol = "socks", - listen = Global.Settings.LocalAddress, - settings = new Inboundsettings - { - udp = true - } - }; - - v2rayConfig.inbounds.Add(inbound); - } - catch - { - // ignored - } - } - - private static void routing(Server server, ref V2rayConfig v2rayConfig) - { - try - { - var directRuleObject = new RulesItem - { - type = "field", - ip = new List(), - domain = new List(), - outboundTag = "direct" - }; - - var blockRuleObject = new RulesItem - { - type = "field", - ip = new List(), - domain = new List(), - outboundTag = "block" - }; - - static bool CheckRuleItem(ref RulesItem rulesItem) - { - bool ipResult, domainResult; - if (!(ipResult = rulesItem.ip?.Any() ?? false)) - rulesItem.ip = null; - - if (!(domainResult = rulesItem.domain?.Any() ?? false)) - rulesItem.domain = null; - - return ipResult || domainResult; - } - - if (CheckRuleItem(ref directRuleObject)) - v2rayConfig.routing.rules.Add(directRuleObject); - - if (CheckRuleItem(ref blockRuleObject)) - v2rayConfig.routing.rules.Add(blockRuleObject); - } - catch - { - // ignored - } - } - private static void outbound(Server server, ref V2rayConfig v2rayConfig) { - try + var outbound = new Outbound { - var outbound = new Outbounds + settings = new OutboundConfiguration(), + mux = new Mux(), + streamSettings = new StreamSettings { - settings = new Outboundsettings(), - mux = new Mux(), - streamSettings = new StreamSettings - { - network = "tcp" - } - }; + network = "tcp" + } + }; - switch (server) + v2rayConfig.outbounds = new[] { outbound }; + + switch (server) + { + case Socks5 socks5: { - case Socks5 socks5: + outbound.protocol = "socks"; + outbound.settings.servers = new object[] { - outbound.settings.servers = new List + new { - new() - { - users = socks5.Auth() - ? new List + users = socks5.Auth() + ? new [] + { + new { - new() - { - user = socks5.Username, - pass = socks5.Password, - level = 1 - } + user = socks5.Username, + pass = socks5.Password, + level = 1 } - : null, - address = server.AutoResolveHostname(), - port = server.Port - } - }; + } + : null, + address = server.AutoResolveHostname(), + port = server.Port + } + }; + outbound.mux.enabled = false; + outbound.mux.concurrency = -1; + break; + } + case VLESS vless: + { + outbound.protocol = "vless"; + outbound.settings.vnext = new[] + { + new VnextItem + { + address = server.AutoResolveHostname(), + port = server.Port, + users = new[] + { + new User + { + id = vless.UserID, + alterId = 0, + flow = vless.Flow.ValueOrDefault(), + encryption = vless.EncryptMethod + } + } + } + }; + + var streamSettings = outbound.streamSettings; + boundStreamSettings(vless, ref streamSettings); + + if (vless.TLSSecureType == "xtls") + { outbound.mux.enabled = false; outbound.mux.concurrency = -1; - outbound.protocol = "socks"; - break; } - case VLESS vless: + else { - var vnextItem = new VnextItem - { - users = new List(), - address = server.AutoResolveHostname(), - port = server.Port - }; - - outbound.settings.vnext = new List { vnextItem }; - - var usersItem = new UsersItem - { - id = vless.UserID, - alterId = 0, - flow = string.Empty, - encryption = vless.EncryptMethod - }; - - vnextItem.users.Add(usersItem); - - var streamSettings = outbound.streamSettings; - boundStreamSettings(vless, ref streamSettings); - - if (vless.TLSSecureType == "xtls") - { - usersItem.flow = string.IsNullOrEmpty(vless.Flow) ? "xtls-rprx-origin" : vless.Flow; - - outbound.mux.enabled = false; - outbound.mux.concurrency = -1; - } - else - { - outbound.mux.enabled = vless.UseMux ?? Global.Settings.V2RayConfig.UseMux; - outbound.mux.concurrency = vless.UseMux ?? Global.Settings.V2RayConfig.UseMux ? 8 : -1; - } - - outbound.protocol = "vless"; - outbound.settings.servers = null; - break; + outbound.mux.enabled = vless.UseMux ?? Global.Settings.V2RayConfig.UseMux; + outbound.mux.concurrency = vless.UseMux ?? Global.Settings.V2RayConfig.UseMux ? 8 : -1; } - case VMess.VMess vmess: - { - var vnextItem = new VnextItem - { - users = new List(), - address = server.AutoResolveHostname(), - port = server.Port - }; - outbound.settings.vnext = new List { vnextItem }; - - var usersItem = new UsersItem - { - id = vmess.UserID, - alterId = vmess.AlterID, - security = vmess.EncryptMethod - }; - - vnextItem.users.Add(usersItem); - - var streamSettings = outbound.streamSettings; - boundStreamSettings(vmess, ref streamSettings); - - outbound.mux.enabled = vmess.UseMux ?? Global.Settings.V2RayConfig.UseMux; - outbound.mux.concurrency = vmess.UseMux ?? Global.Settings.V2RayConfig.UseMux ? 8 : -1; - outbound.protocol = "vmess"; - break; - } + break; } - - v2rayConfig.outbounds.AddRange(new[] + case VMess vmess: { - outbound, - new() + outbound.protocol = "vmess"; + outbound.settings.vnext = new[] { - tag = "direct", protocol = "freedom" - }, - new() - { - tag = "block", protocol = "blackhole" - } - }); - } - catch - { - // ignored + new VnextItem + { + address = server.AutoResolveHostname(), + port = server.Port, + users = new[] + { + new User + { + id = vmess.UserID, + alterId = vmess.AlterID, + security = vmess.EncryptMethod + } + } + } + }; + + var streamSettings = outbound.streamSettings; + boundStreamSettings(vmess, ref streamSettings); + + outbound.mux.enabled = vmess.UseMux ?? Global.Settings.V2RayConfig.UseMux; + outbound.mux.concurrency = vmess.UseMux ?? Global.Settings.V2RayConfig.UseMux ? 8 : -1; + break; + } } } - private static void boundStreamSettings(VMess.VMess server, ref StreamSettings streamSettings) + private static void boundStreamSettings(VMess server, ref StreamSettings streamSettings) { - try + streamSettings.network = server.TransferProtocol; + streamSettings.security = server.TLSSecureType; + + if (server.TLSSecureType != "none") { - streamSettings.network = server.TransferProtocol; - - if ((streamSettings.security = server.TLSSecureType) != "none") + var tlsSettings = new TlsSettings { - var tlsSettings = new TlsSettings - { - allowInsecure = Global.Settings.V2RayConfig.AllowInsecure - }; + allowInsecure = Global.Settings.V2RayConfig.AllowInsecure, + serverName = server.ServerName.ValueOrDefault() ?? server.Hostname + }; - if (!string.IsNullOrWhiteSpace(server.Host)) - tlsSettings.serverName = server.Host; - else if (Global.Settings.ResolveServerHostname) - tlsSettings.serverName = server.Hostname; - - switch (server.TLSSecureType) - { - case "tls": - streamSettings.tlsSettings = tlsSettings; - break; - case "xtls": - streamSettings.xtlsSettings = tlsSettings; - break; - } - } - - switch (server.TransferProtocol) + switch (server.TLSSecureType) { - case "kcp": - var kcpSettings = new KcpSettings - { - mtu = Global.Settings.V2RayConfig.KcpConfig.mtu, - tti = Global.Settings.V2RayConfig.KcpConfig.tti, - uplinkCapacity = Global.Settings.V2RayConfig.KcpConfig.uplinkCapacity, - downlinkCapacity = Global.Settings.V2RayConfig.KcpConfig.downlinkCapacity, - congestion = Global.Settings.V2RayConfig.KcpConfig.congestion, - readBufferSize = Global.Settings.V2RayConfig.KcpConfig.readBufferSize, - writeBufferSize = Global.Settings.V2RayConfig.KcpConfig.writeBufferSize, - header = new Header - { - type = server.FakeType - }, - seed = !string.IsNullOrWhiteSpace(server.Path) ? server.Path : null - }; - - streamSettings.kcpSettings = kcpSettings; + case "tls": + streamSettings.tlsSettings = tlsSettings; break; - case "ws": - var wsSettings = new WsSettings - { - headers = !string.IsNullOrWhiteSpace(server.Host) ? new Headers { Host = server.Host } : null, - path = !string.IsNullOrWhiteSpace(server.Path) ? server.Path : null - }; - - streamSettings.wsSettings = wsSettings; - break; - case "h2": - var httpSettings = new HttpSettings - { - host = new List - { - string.IsNullOrWhiteSpace(server.Host) ? server.Hostname : server.Host! - }, - path = server.Path - }; - - streamSettings.httpSettings = httpSettings; - break; - case "quic": - var quicSettings = new QuicSettings - { - security = server.QUICSecure, - key = server.QUICSecret, - header = new Header - { - type = server.FakeType - } - }; - - if (server.TLSSecureType != "none") - // tls or xtls - streamSettings.tlsSettings.serverName = server.Hostname; - - streamSettings.quicSettings = quicSettings; - break; - case "grpc": - var grpcSettings = new GrpcSettings - { - serviceName = server.Path, - multiMode = server.FakeType == "multi" - }; - - streamSettings.grpcSettings = grpcSettings; - break; - default: - if (server.FakeType == "http") - { - var tcpSettings = new TcpSettings - { - header = new Header - { - type = server.FakeType, - request = new TCPRequest - { - path = string.IsNullOrWhiteSpace(server.Path) ? "/" : server.Path, - headers = new TCPRequestHeaders - { - Host = string.IsNullOrWhiteSpace(server.Host) ? server.Hostname : server.Host - } - } - } - }; - - streamSettings.tcpSettings = tcpSettings; - } - + case "xtls": + streamSettings.xtlsSettings = tlsSettings; break; } } - catch + + switch (server.TransferProtocol) { - // ignored + case "tcp": + if (server.FakeType == "http") + { + streamSettings.tcpSettings = new TcpSettings + { + header = new + { + request = new + { + path = server.Path.SplitOrDefault(), + headers = new + { + Host = server.Host.SplitOrDefault() + } + } + } + }; + } + else + { + throw new MessageException($"invalid tcp type {server.FakeType}"); + } + + break; + case "ws": + + streamSettings.wsSettings = new WsSettings + { + path = server.Path.ValueOrDefault(), + headers = new { Host = server.Host.ValueOrDefault() }, + }; + + break; + case "kcp": + + streamSettings.kcpSettings = new KcpSettings + { + mtu = Global.Settings.V2RayConfig.KcpConfig.mtu, + tti = Global.Settings.V2RayConfig.KcpConfig.tti, + uplinkCapacity = Global.Settings.V2RayConfig.KcpConfig.uplinkCapacity, + downlinkCapacity = Global.Settings.V2RayConfig.KcpConfig.downlinkCapacity, + congestion = Global.Settings.V2RayConfig.KcpConfig.congestion, + readBufferSize = Global.Settings.V2RayConfig.KcpConfig.readBufferSize, + writeBufferSize = Global.Settings.V2RayConfig.KcpConfig.writeBufferSize, + header = new + { + type = server.FakeType + }, + seed = server.Path.ValueOrDefault() + }; + + break; + case "h2": + + streamSettings.httpSettings = new HttpSettings + { + host = server.Host.SplitOrDefault(), + path = server.Path.ValueOrDefault() + }; + + break; + case "quic": + + streamSettings.quicSettings = new QuicSettings + { + security = server.QUICSecure, + key = server.QUICSecret, + header = new + { + type = server.FakeType + } + }; + + break; + case "grpc": + + streamSettings.grpcSettings = new GrpcSettings + { + serviceName = server.Path, + multiMode = server.FakeType == "multi" + }; + + break; + default: + Trace.Assert(false); + break; } } } diff --git a/Netch/Servers/V2ray/V2rayUtils.cs b/Netch/Servers/V2ray/V2rayUtils.cs index 4f8b6636..e98691cb 100644 --- a/Netch/Servers/V2ray/V2rayUtils.cs +++ b/Netch/Servers/V2ray/V2rayUtils.cs @@ -1,10 +1,10 @@ -using Netch.Models; -using Netch.Utils; 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 { @@ -13,7 +13,7 @@ namespace Netch.Servers public static IEnumerable ParseVUri(string text) { var scheme = ShareLink.GetUriScheme(text).ToLower(); - var server = scheme switch { "vmess" => new VMess.VMess(), "vless" => new VLESS(), _ => throw new ArgumentOutOfRangeException() }; + var server = scheme switch { "vmess" => new VMess(), "vless" => new VLESS(), _ => throw new ArgumentOutOfRangeException() }; if (text.Contains("#")) { server.Remark = Uri.UnescapeDataString(text.Split('#')[1]); @@ -56,7 +56,7 @@ namespace Netch.Servers server.TLSSecureType = parameter.Get("security") ?? "none"; if (server.TLSSecureType != "none") { - server.Host = parameter.Get("sni") ?? ""; + server.ServerName = parameter.Get("sni") ?? ""; if (server.TLSSecureType == "xtls") ((VLESS)server).Flow = parameter.Get("flow") ?? ""; } @@ -77,7 +77,7 @@ namespace Netch.Servers public static string GetVShareLink(Server s, string scheme = "vmess") { // https://github.com/XTLS/Xray-core/issues/91 - var server = (VMess.VMess)s; + var server = (VMess)s; var parameter = new Dictionary(); // protocol-specific fields parameter.Add("type", server.TransferProtocol); @@ -97,13 +97,13 @@ namespace Netch.Servers break; case "ws": - parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path!)); + parameter.Add("path", Uri.EscapeDataString(server.Path.ValueOrDefault() ?? "/")); if (!server.Host.IsNullOrWhiteSpace()) parameter.Add("host", Uri.EscapeDataString(server.Host!)); break; case "h2": - parameter.Add("path", Uri.EscapeDataString(server.Path.IsNullOrWhiteSpace() ? "/" : server.Path!)); + parameter.Add("path", Uri.EscapeDataString(server.Path.ValueOrDefault() ?? "/")); if (!server.Host.IsNullOrWhiteSpace()) parameter.Add("host", Uri.EscapeDataString(server.Host!)); @@ -113,7 +113,6 @@ namespace Netch.Servers { parameter.Add("quicSecurity", server.QUICSecure); parameter.Add("key", server.QUICSecret!); - // TODO Import and Create null value Check } if (server.FakeType != "none") @@ -124,7 +123,7 @@ namespace Netch.Servers if (!string.IsNullOrEmpty(server.Path)) parameter.Add("serviceName", server.Path); - if (server.FakeType == "gun" || server.FakeType == "multi") + if (server.FakeType is "gun" or "multi") parameter.Add("mode", server.FakeType); break; @@ -146,7 +145,7 @@ namespace Netch.Servers } return - $"{scheme}://{server.UserID}@{server.Hostname}:{server.Port}?{string.Join("&", parameter.Select(p => $"{p.Key}={p.Value}"))}{(server.Remark.IsNullOrWhiteSpace() ? "" : $"#{Uri.EscapeDataString(server.Remark)}")}"; + $"{scheme}://{server.UserID}@{server.Hostname}:{server.Port}?{string.Join("&", parameter.Select(p => $"{p.Key}={p.Value}"))}{(!server.Remark.IsNullOrWhiteSpace() ? $"#{Uri.EscapeDataString(server.Remark)}" : "")}"; } } } \ No newline at end of file diff --git a/Netch/Servers/VLESS/VLESS.cs b/Netch/Servers/VLESS/VLESS.cs index 5464e826..c2d526ca 100644 --- a/Netch/Servers/VLESS/VLESS.cs +++ b/Netch/Servers/VLESS/VLESS.cs @@ -1,9 +1,8 @@ -using Netch.Servers.VMess; using System.Collections.Generic; namespace Netch.Servers { - public class VLESS : VMess.VMess + public class VLESS : VMess { public override string Type { get; } = "VLESS"; diff --git a/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs b/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs index f2f05d38..5768f013 100644 --- a/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs +++ b/Netch/Servers/VLESS/VLESSForm/VLESSForm.cs @@ -1,5 +1,5 @@ -using Netch.Forms; using System.Collections.Generic; +using Netch.Forms; namespace Netch.Servers.VLESSForm { @@ -9,6 +9,7 @@ namespace Netch.Servers.VLESSForm { server ??= new VLESS(); Server = server; + CreateTextBox("Sni", "ServerName(Sni)", s => true, s => server.ServerName = s, server.ServerName); CreateTextBox("UUID", "UUID", s => true, s => server.UserID = s, server.UserID); CreateTextBox("EncryptMethod", "Encrypt Method", diff --git a/Netch/Servers/VMess/Form/VMessForm.cs b/Netch/Servers/VMess/Form/VMessForm.cs index 9e133d97..45a5277d 100644 --- a/Netch/Servers/VMess/Form/VMessForm.cs +++ b/Netch/Servers/VMess/Form/VMessForm.cs @@ -1,7 +1,7 @@ -using Netch.Forms; -using System.Collections.Generic; +using System.Collections.Generic; +using Netch.Forms; -namespace Netch.Servers.VMess.Form +namespace Netch.Servers.Form { public class VMessForm : ServerForm { @@ -9,6 +9,7 @@ namespace Netch.Servers.VMess.Form { server ??= new VMess(); Server = server; + CreateTextBox("Sni", "ServerName(Sni)", s => true, s => server.ServerName = s, server.ServerName); CreateTextBox("UserId", "User ID", s => true, s => server.UserID = s, server.UserID); CreateTextBox("AlterId", "Alter ID", s => int.TryParse(s, out _), s => server.AlterID = int.Parse(s), server.AlterID.ToString(), 76); CreateComboBox("EncryptMethod", "Encrypt Method", VMessGlobal.EncryptMethods, s => server.EncryptMethod = s, server.EncryptMethod); diff --git a/Netch/Servers/VMess/VMess.cs b/Netch/Servers/VMess/VMess.cs index b68b77c4..acea7548 100644 --- a/Netch/Servers/VMess/VMess.cs +++ b/Netch/Servers/VMess/VMess.cs @@ -1,13 +1,14 @@ using System.Collections.Generic; using Netch.Models; -namespace Netch.Servers.VMess +namespace Netch.Servers { public class VMess : Server { private string _tlsSecureType = VMessGlobal.TLSSecure[0]; public override string Type { get; } = "VMess"; + public override string MaskedData() { var maskedData = $"{EncryptMethod} + {TransferProtocol} + {FakeType}"; @@ -25,6 +26,7 @@ namespace Netch.Servers.VMess case "kcp": break; } + return maskedData; } @@ -91,7 +93,9 @@ namespace Netch.Servers.VMess /// /// Mux 多路复用 /// - public bool? UseMux { get; set; } = false; + public bool? UseMux { get; set; } + + public string? ServerName { get; set; } = string.Empty; } public class VMessGlobal diff --git a/Netch/Servers/VMess/VMessUtil.cs b/Netch/Servers/VMess/VMessUtil.cs index 2985f18c..4ddf0f2f 100644 --- a/Netch/Servers/VMess/VMessUtil.cs +++ b/Netch/Servers/VMess/VMessUtil.cs @@ -5,12 +5,11 @@ using System.Text.Json; using System.Text.Json.Serialization; using Netch.Interfaces; using Netch.Models; -using Netch.Servers; +using Netch.Servers.Form; using Netch.Servers.Models; -using Netch.Servers.VMess.Form; using Netch.Utils; -namespace Netch.Servers.VMess +namespace Netch.Servers { public class VMessUtil : IServerUtil { @@ -92,7 +91,6 @@ namespace Netch.Servers.VMess data.Remark = vmess.ps; data.Hostname = vmess.add; data.Port = vmess.port; - data.UserID = vmess.id; data.AlterID = vmess.aid; data.TransferProtocol = vmess.net; data.FakeType = vmess.type; diff --git a/Netch/Utils/StringExtension.cs b/Netch/Utils/StringExtension.cs index 1f99db9d..0362c673 100644 --- a/Netch/Utils/StringExtension.cs +++ b/Netch/Utils/StringExtension.cs @@ -72,5 +72,15 @@ namespace Netch.Utils { return value.Split(separator, StringSplitOptions.RemoveEmptyEntries); } + + public static string? ValueOrDefault(this string? value) + { + return string.IsNullOrWhiteSpace(value) ? null : value; + } + + public static string[]? SplitOrDefault(this string? value) + { + return !string.IsNullOrWhiteSpace(value) ? value.Split(',') : default; + } } } \ No newline at end of file