diff --git a/ProxySuper.Core/Models/Projects/IProjectSettings.cs b/ProxySuper.Core/Models/Projects/IProjectSettings.cs index 1570c4e..aa5eb9d 100644 --- a/ProxySuper.Core/Models/Projects/IProjectSettings.cs +++ b/ProxySuper.Core/Models/Projects/IProjectSettings.cs @@ -22,7 +22,7 @@ namespace ProxySuper.Core.Models.Projects /// /// 类型 /// - ProjectType Type { get; set; } + //ProjectType Type { get; set; } /// /// 邮箱 diff --git a/ProxySuper.Core/Models/Projects/ProjectType.cs b/ProxySuper.Core/Models/Projects/ProjectType.cs index 7216689..027a80a 100644 --- a/ProxySuper.Core/Models/Projects/ProjectType.cs +++ b/ProxySuper.Core/Models/Projects/ProjectType.cs @@ -6,5 +6,6 @@ TrojanGo = 1, NaiveProxy = 2, Brook = 3, + V2ray = 4, } } diff --git a/ProxySuper.Core/Models/Projects/XrayType.cs b/ProxySuper.Core/Models/Projects/RayType.cs similarity index 94% rename from ProxySuper.Core/Models/Projects/XrayType.cs rename to ProxySuper.Core/Models/Projects/RayType.cs index 337e220..5f73e69 100644 --- a/ProxySuper.Core/Models/Projects/XrayType.cs +++ b/ProxySuper.Core/Models/Projects/RayType.cs @@ -1,6 +1,6 @@ namespace ProxySuper.Core.Models.Projects { - public enum XrayType + public enum RayType { // 入口 VLESS_TCP_XTLS = 100, @@ -25,4 +25,6 @@ // SS ShadowsocksAEAD = 401 } + + } diff --git a/ProxySuper.Core/Models/Projects/V2raySettings.cs b/ProxySuper.Core/Models/Projects/V2raySettings.cs new file mode 100644 index 0000000..fa0bf1c --- /dev/null +++ b/ProxySuper.Core/Models/Projects/V2raySettings.cs @@ -0,0 +1,160 @@ +using Newtonsoft.Json; +using ProxySuper.Core.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; + +namespace ProxySuper.Core.Models.Projects +{ + public partial class V2raySettings : IProjectSettings + { + public V2raySettings() + { + WithTLS = true; + + var guid = Guid.NewGuid().ToString(); + Port = 443; + VLESS_KCP_Port = 2001; + VLESS_gRPC_Port = 2002; + VMESS_KCP_Port = 3001; + ShadowSocksPort = 4001; + + UUID = guid; + Types = new List(); + + VLESS_WS_Path = "/" + Utils.RandomString(6); + VLESS_KCP_Type = "none"; + VLESS_KCP_Seed = guid; + VLESS_gRPC_ServiceName = "/" + Utils.RandomString(7); + + VMESS_WS_Path = "/" + Utils.RandomString(8); + VMESS_TCP_Path = "/" + Utils.RandomString(9); + VMESS_KCP_Seed = guid; + VMESS_KCP_Type = "none"; + + TrojanPassword = guid; + + ShadowSocksPassword = guid; + ShadowSocksMethod = "aes-128-gcm"; + } + + [JsonIgnore] + public bool IsIPAddress + { + get + { + return IPAddress.TryParse(Domain, out _); + } + } + + [JsonIgnore] + public List FreePorts + { + get + { + var list = new List(); + list.Add(80); + list.Add(Port); + + if (Types.Contains(RayType.VLESS_KCP)) + { + list.Add(VLESS_KCP_Port); + } + + if (Types.Contains(RayType.VMESS_KCP)) + { + list.Add(VMESS_KCP_Port); + } + + if (Types.Contains(RayType.ShadowsocksAEAD)) + { + list.Add(ShadowSocksPort); + } + + if (Types.Contains(RayType.VLESS_gRPC)) + { + list.Add(VLESS_gRPC_Port); + } + + return list.Distinct().ToList(); + } + } + + //public ProjectType Type { get; set; } = ProjectType.Xray; + + /// + /// 是否安装证书, + /// 上传自有证书时选False,则不会自动安装证书。 + /// + public bool WithTLS { get; set; } + + /// + /// 端口 + /// + public int Port { get; set; } + + /// + /// 域名 + /// + public string Domain { get; set; } + + /// + /// UUID + /// + public string UUID { get; set; } + + /// + /// 多用户 + /// + public List MulitUUID { get; set; } = new List(); + + /// + /// 伪装域名 + /// + public string MaskDomain { get; set; } + + [JsonIgnore] + public string Email + { + get + { + if (!string.IsNullOrEmpty(Domain)) + { + var arr = Domain.Split('.'); + if (arr.Length == 3) + { + return $"{arr[0]}@{arr[1]}.{arr[2]}"; + } + } + + return $"{UUID.Substring(2, 6)}@gmail.com"; + } + } + + /// + /// 安装类型 + /// + public List Types { get; set; } = new List(); + + /// + /// 根据xray类型获取路径 + /// + /// + /// + public string GetPath(RayType type) + { + switch (type) + { + case RayType.VLESS_WS: + return VLESS_WS_Path; + case RayType.VMESS_TCP: + return VMESS_TCP_Path; + case RayType.VMESS_WS: + return VMESS_WS_Path; + default: + return string.Empty; + } + } + } +} diff --git a/ProxySuper.Core/Models/Projects/XraySettings_SS.cs b/ProxySuper.Core/Models/Projects/V2raySettings_SS.cs similarity index 83% rename from ProxySuper.Core/Models/Projects/XraySettings_SS.cs rename to ProxySuper.Core/Models/Projects/V2raySettings_SS.cs index 71936dd..945cadf 100644 --- a/ProxySuper.Core/Models/Projects/XraySettings_SS.cs +++ b/ProxySuper.Core/Models/Projects/V2raySettings_SS.cs @@ -2,7 +2,7 @@ namespace ProxySuper.Core.Models.Projects { - public partial class XraySettings + public partial class V2raySettings { /// /// ss password @@ -23,7 +23,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.ShadowsocksAEAD, this); + return ShareLink.Build(RayType.ShadowsocksAEAD, this); } } } diff --git a/ProxySuper.Core/Models/Projects/XraySettings_Trojan.cs b/ProxySuper.Core/Models/Projects/V2raySettings_Trojan.cs similarity index 70% rename from ProxySuper.Core/Models/Projects/XraySettings_Trojan.cs rename to ProxySuper.Core/Models/Projects/V2raySettings_Trojan.cs index 6d110a7..df02d34 100644 --- a/ProxySuper.Core/Models/Projects/XraySettings_Trojan.cs +++ b/ProxySuper.Core/Models/Projects/V2raySettings_Trojan.cs @@ -2,7 +2,7 @@ namespace ProxySuper.Core.Models.Projects { - public partial class XraySettings + public partial class V2raySettings { public string TrojanPassword { get; set; } @@ -10,7 +10,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.Trojan_TCP, this); + return ShareLink.Build(RayType.Trojan_TCP, this); } } } diff --git a/ProxySuper.Core/Models/Projects/XraySettings_VLESS.cs b/ProxySuper.Core/Models/Projects/V2raySettings_VLESS.cs similarity index 73% rename from ProxySuper.Core/Models/Projects/XraySettings_VLESS.cs rename to ProxySuper.Core/Models/Projects/V2raySettings_VLESS.cs index e2b959e..8bb677b 100644 --- a/ProxySuper.Core/Models/Projects/XraySettings_VLESS.cs +++ b/ProxySuper.Core/Models/Projects/V2raySettings_VLESS.cs @@ -2,19 +2,8 @@ namespace ProxySuper.Core.Models.Projects { - public partial class XraySettings + public partial class V2raySettings { - /// - /// vless xtls shareLink - /// - public string VLESS_TCP_XTLS_ShareLink - { - get - { - return ShareLink.Build(XrayType.VLESS_TCP_XTLS, this); - } - } - /// /// vless tcp shareLink /// @@ -22,7 +11,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VLESS_TCP, this); + return ShareLink.Build(RayType.VLESS_TCP, this); } } @@ -38,7 +27,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VLESS_WS, this); + return ShareLink.Build(RayType.VLESS_WS, this); } } @@ -64,7 +53,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VLESS_KCP, this); + return ShareLink.Build(RayType.VLESS_KCP, this); } } @@ -85,7 +74,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VLESS_gRPC, this); + return ShareLink.Build(RayType.VLESS_gRPC, this); } } } diff --git a/ProxySuper.Core/Models/Projects/XraySettings_VMESS.cs b/ProxySuper.Core/Models/Projects/V2raySettings_VMESS.cs similarity index 84% rename from ProxySuper.Core/Models/Projects/XraySettings_VMESS.cs rename to ProxySuper.Core/Models/Projects/V2raySettings_VMESS.cs index 61fce95..d0e2e21 100644 --- a/ProxySuper.Core/Models/Projects/XraySettings_VMESS.cs +++ b/ProxySuper.Core/Models/Projects/V2raySettings_VMESS.cs @@ -2,7 +2,7 @@ namespace ProxySuper.Core.Models.Projects { - public partial class XraySettings + public partial class V2raySettings { /// /// vmess websocket path @@ -16,7 +16,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VMESS_WS, this); + return ShareLink.Build(RayType.VMESS_WS, this); } } @@ -32,7 +32,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VMESS_TCP, this); + return ShareLink.Build(RayType.VMESS_TCP, this); } } @@ -58,7 +58,7 @@ namespace ProxySuper.Core.Models.Projects { get { - return ShareLink.Build(XrayType.VMESS_KCP, this); + return ShareLink.Build(RayType.VMESS_KCP, this); } } } diff --git a/ProxySuper.Core/Models/Projects/XraySettings.cs b/ProxySuper.Core/Models/Projects/XraySettings.cs index dc0ff65..e1ed4cc 100644 --- a/ProxySuper.Core/Models/Projects/XraySettings.cs +++ b/ProxySuper.Core/Models/Projects/XraySettings.cs @@ -1,159 +1,22 @@ -using Newtonsoft.Json; -using ProxySuper.Core.Services; +using ProxySuper.Core.Services; using System; using System.Collections.Generic; using System.Linq; -using System.Net; +using System.Text; +using System.Threading.Tasks; namespace ProxySuper.Core.Models.Projects { - public partial class XraySettings : IProjectSettings + public class XraySettings : V2raySettings { - public XraySettings() - { - WithTLS = true; - - var guid = Guid.NewGuid().ToString(); - Port = 443; - VLESS_KCP_Port = 2001; - VLESS_gRPC_Port = 2002; - VMESS_KCP_Port = 3001; - ShadowSocksPort = 4001; - - UUID = guid; - Types = new List(); - - VLESS_WS_Path = "/" + Utils.RandomString(6); - VLESS_KCP_Type = "none"; - VLESS_KCP_Seed = guid; - VLESS_gRPC_ServiceName = "/" + Utils.RandomString(7); - - VMESS_WS_Path = "/" + Utils.RandomString(8); - VMESS_TCP_Path = "/" + Utils.RandomString(9); - VMESS_KCP_Seed = guid; - VMESS_KCP_Type = "none"; - - TrojanPassword = guid; - - ShadowSocksPassword = guid; - ShadowSocksMethod = "aes-128-gcm"; - } - - [JsonIgnore] - public bool IsIPAddress + /// + /// vless xtls shareLink + /// + public string VLESS_TCP_XTLS_ShareLink { get { - return IPAddress.TryParse(Domain, out _); - } - } - - [JsonIgnore] - public List FreePorts - { - get - { - var list = new List(); - list.Add(80); - list.Add(Port); - - if (Types.Contains(XrayType.VLESS_KCP)) - { - list.Add(VLESS_KCP_Port); - } - - if (Types.Contains(XrayType.VMESS_KCP)) - { - list.Add(VMESS_KCP_Port); - } - - if (Types.Contains(XrayType.ShadowsocksAEAD)) - { - list.Add(ShadowSocksPort); - } - - if (Types.Contains(XrayType.VLESS_gRPC)) - { - list.Add(VLESS_gRPC_Port); - } - - return list.Distinct().ToList(); - } - } - - public ProjectType Type { get; set; } = ProjectType.Xray; - - /// - /// 是否安装证书, - /// 上传自有证书时选False,则不会自动安装证书。 - /// - public bool WithTLS { get; set; } - - /// - /// 端口 - /// - public int Port { get; set; } - - /// - /// 域名 - /// - public string Domain { get; set; } - - /// - /// UUID - /// - public string UUID { get; set; } - - /// - /// 多用户 - /// - public List MulitUUID { get; set; } = new List(); - - /// - /// 伪装域名 - /// - public string MaskDomain { get; set; } - - [JsonIgnore] - public string Email - { - get - { - if (!string.IsNullOrEmpty(Domain)) - { - var arr = Domain.Split('.'); - if (arr.Length == 3) - { - return $"{arr[0]}@{arr[1]}.{arr[2]}"; - } - } - - return $"{UUID.Substring(2, 6)}@gmail.com"; - } - } - - /// - /// 安装类型 - /// - public List Types { get; set; } = new List(); - - /// - /// 根据xray类型获取路径 - /// - /// - /// - public string GetPath(XrayType type) - { - switch (type) - { - case XrayType.VLESS_WS: - return VLESS_WS_Path; - case XrayType.VMESS_TCP: - return VMESS_TCP_Path; - case XrayType.VMESS_WS: - return VMESS_WS_Path; - default: - return string.Empty; + return ShareLink.Build(RayType.VLESS_TCP_XTLS, this); } } } diff --git a/ProxySuper.Core/Models/Record.cs b/ProxySuper.Core/Models/Record.cs index b032781..4faf1c9 100644 --- a/ProxySuper.Core/Models/Record.cs +++ b/ProxySuper.Core/Models/Record.cs @@ -32,6 +32,9 @@ namespace ProxySuper.Core.Models } } + [JsonProperty("v2raySettings")] + public V2raySettings V2raySettings { get; set; } + [JsonProperty("settings")] public XraySettings XraySettings { get; set; } @@ -52,6 +55,8 @@ namespace ProxySuper.Core.Models { if (XraySettings != null) return ProjectType.Xray; + if (V2raySettings != null) return ProjectType.V2ray; + if (TrojanGoSettings != null) return ProjectType.TrojanGo; if (NaiveProxySettings != null) return ProjectType.NaiveProxy; @@ -76,6 +81,17 @@ namespace ProxySuper.Core.Models public string GetShareLink() { + if (Type == ProjectType.V2ray) + { + StringBuilder strBuilder = new StringBuilder(); + XraySettings.Types.ForEach(type => + { + var link = ShareLink.Build(type, V2raySettings); + strBuilder.AppendLine(link); + }); + return strBuilder.ToString(); + } + if (Type == ProjectType.Xray) { StringBuilder strBuilder = new StringBuilder(); diff --git a/ProxySuper.Core/ProxySuper.Core.csproj b/ProxySuper.Core/ProxySuper.Core.csproj index 8e0b987..21e8ee9 100644 --- a/ProxySuper.Core/ProxySuper.Core.csproj +++ b/ProxySuper.Core/ProxySuper.Core.csproj @@ -78,12 +78,13 @@ - - - + + + + + - - + @@ -93,6 +94,8 @@ + + @@ -107,6 +110,9 @@ + + + diff --git a/ProxySuper.Core/Services/ShareLink.cs b/ProxySuper.Core/Services/ShareLink.cs index 00992e1..b892100 100644 --- a/ProxySuper.Core/Services/ShareLink.cs +++ b/ProxySuper.Core/Services/ShareLink.cs @@ -69,30 +69,30 @@ namespace ProxySuper.Core.Services return strBuilder.ToString(); } - public static string Build(XrayType xrayType, XraySettings settings) + public static string Build(RayType xrayType, V2raySettings settings) { switch (xrayType) { - case XrayType.VLESS_TCP: - case XrayType.VLESS_TCP_XTLS: - case XrayType.VLESS_WS: - case XrayType.VLESS_KCP: - case XrayType.VLESS_gRPC: - case XrayType.Trojan_TCP: + case RayType.VLESS_TCP: + case RayType.VLESS_TCP_XTLS: + case RayType.VLESS_WS: + case RayType.VLESS_KCP: + case RayType.VLESS_gRPC: + case RayType.Trojan_TCP: return BuildVlessShareLink(xrayType, settings); - case XrayType.VMESS_TCP: - case XrayType.VMESS_WS: - case XrayType.VMESS_KCP: + case RayType.VMESS_TCP: + case RayType.VMESS_WS: + case RayType.VMESS_KCP: return BuildVmessShareLink(xrayType, settings); - case XrayType.ShadowsocksAEAD: + case RayType.ShadowsocksAEAD: return BuildShadowSocksShareLink(settings); default: return string.Empty; } } - private static string BuildShadowSocksShareLink(XraySettings settings) + private static string BuildShadowSocksShareLink(V2raySettings settings) { var _method = settings.ShadowSocksMethod; var _password = settings.ShadowSocksPassword; @@ -103,7 +103,7 @@ namespace ProxySuper.Core.Services return "ss://" + base64URL + "#ShadowSocks"; } - private static string BuildVmessShareLink(XrayType xrayType, XraySettings settings) + private static string BuildVmessShareLink(RayType xrayType, V2raySettings settings) { var vmess = new Vmess { @@ -122,19 +122,19 @@ namespace ProxySuper.Core.Services switch (xrayType) { - case XrayType.VMESS_TCP: + case RayType.VMESS_TCP: vmess.ps = "vmess-tcp-tls"; vmess.net = "tcp"; vmess.type = "http"; vmess.path = settings.VMESS_TCP_Path; break; - case XrayType.VMESS_WS: + case RayType.VMESS_WS: vmess.ps = "vmess-ws-tls"; vmess.net = "ws"; vmess.type = "none"; vmess.path = settings.VMESS_WS_Path; break; - case XrayType.VMESS_KCP: + case RayType.VMESS_KCP: vmess.ps = "vmess-mKCP"; vmess.port = settings.VMESS_KCP_Port.ToString(); vmess.net = "kcp"; @@ -150,7 +150,7 @@ namespace ProxySuper.Core.Services return $"vmess://" + base64Url; } - private static string BuildVlessShareLink(XrayType xrayType, XraySettings settings) + private static string BuildVlessShareLink(RayType xrayType, V2raySettings settings) { var _protocol = string.Empty; var _uuid = settings.UUID; @@ -167,24 +167,24 @@ namespace ProxySuper.Core.Services switch (xrayType) { - case XrayType.VLESS_TCP: + case RayType.VLESS_TCP: _protocol = "vless"; _type = "tcp"; _descriptiveText = "vless-tcp-tls"; break; - case XrayType.VLESS_TCP_XTLS: + case RayType.VLESS_TCP_XTLS: _protocol = "vless"; _type = "tcp"; _security = "xtls"; _descriptiveText = "vless-tcp-xtls"; break; - case XrayType.VLESS_WS: + case RayType.VLESS_WS: _protocol = "vless"; _type = "ws"; _path = settings.VLESS_WS_Path; _descriptiveText = "vless-ws-tls"; break; - case XrayType.VLESS_KCP: + case RayType.VLESS_KCP: _protocol = "vless"; _type = "kcp"; _headerType = settings.VLESS_KCP_Type; @@ -193,13 +193,13 @@ namespace ProxySuper.Core.Services _security = "none"; _descriptiveText = "vless-mKCP"; break; - case XrayType.VLESS_gRPC: + case RayType.VLESS_gRPC: _protocol = "vless"; _type = "grpc"; _port = settings.VLESS_gRPC_Port; _descriptiveText = "vless-gRPC"; break; - case XrayType.Trojan_TCP: + case RayType.Trojan_TCP: _protocol = "trojan"; _uuid = settings.TrojanPassword; _descriptiveText = "trojan-tcp"; @@ -210,25 +210,25 @@ namespace ProxySuper.Core.Services string parametersURL = string.Empty; - if (xrayType != XrayType.Trojan_TCP) + if (xrayType != RayType.Trojan_TCP) { // 4.3 传输层相关段 parametersURL = $"?type={_type}&encryption={_encryption}&security={_security}&path={HttpUtility.UrlEncode(_path)}&headerType={_headerType}"; // kcp - if (xrayType == XrayType.VLESS_KCP) + if (xrayType == RayType.VLESS_KCP) { parametersURL += $"&seed={_seed}"; } // 4.4 TLS 相关段 - if (xrayType == XrayType.VLESS_TCP_XTLS) + if (xrayType == RayType.VLESS_TCP_XTLS) { parametersURL += "&flow=xtls-rprx-direct"; } - if (xrayType == XrayType.VLESS_gRPC) + if (xrayType == RayType.VLESS_gRPC) { parametersURL += $"&serviceName={settings.VLESS_gRPC_ServiceName}&mode=gun"; } diff --git a/ProxySuper.Core/Services/V2rayConfigBuilder.cs b/ProxySuper.Core/Services/V2rayConfigBuilder.cs new file mode 100644 index 0000000..9adb136 --- /dev/null +++ b/ProxySuper.Core/Services/V2rayConfigBuilder.cs @@ -0,0 +1,252 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using ProxySuper.Core.Models.Projects; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProxySuper.Core.Services +{ + public class V2rayConfigBuilder + { + private const string ServerLogDir = @"Templates\v2ray\server\00_log"; + private const string ServerApiDir = @"Templates\v2ray\server\01_api"; + private const string ServerDnsDir = @"Templates\v2ray\server\02_dns"; + private const string ServerRoutingDir = @"Templates\v2ray\server\03_routing"; + private const string ServerPolicyDir = @"Templates\v2ray\server\04_policy"; + private const string ServerInboundsDir = @"Templates\v2ray\server\05_inbounds"; + private const string ServerOutboundsDir = @"Templates\v2ray\server\06_outbounds"; + private const string ServerTransportDir = @"Templates\v2ray\server\07_transport"; + private const string ServerStatsDir = @"Templates\v2ray\server\08_stats"; + private const string ServerReverseDir = @"Templates\v2ray\server\09_reverse"; + private const string CaddyFileDir = @"Templates\v2ray\caddy"; + + public static int VLESS_TCP_Port = 1110; + public static int VLESS_WS_Port = 1111; + public static int VLESS_H2_Port = 1112; + + public static int VMESS_TCP_Port = 1210; + public static int VMESS_WS_Port = 1211; + public static int VMESS_H2_Port = 1212; + + public static int Trojan_TCP_Port = 1310; + public static int Trojan_WS_Port = 1311; + + public static int FullbackPort = 8080; + + + + public static dynamic LoadV2rayConfig() + { + dynamic logObj = LoadJsonObj(Path.Combine(ServerLogDir, "00_log.json")); + dynamic apiObj = LoadJsonObj(Path.Combine(ServerApiDir, "01_api.json")); + dynamic dnsObj = LoadJsonObj(Path.Combine(ServerDnsDir, "02_dns.json")); + dynamic routingObj = LoadJsonObj(Path.Combine(ServerRoutingDir, "03_routing.json")); + dynamic policyObj = LoadJsonObj(Path.Combine(ServerPolicyDir, "04_policy.json")); + dynamic inboundsObj = LoadJsonObj(Path.Combine(ServerInboundsDir, "05_inbounds.json")); + dynamic outboundsObj = LoadJsonObj(Path.Combine(ServerOutboundsDir, "06_outbounds.json")); + dynamic transportObj = LoadJsonObj(Path.Combine(ServerTransportDir, "07_transport.json")); + dynamic statsObj = LoadJsonObj(Path.Combine(ServerStatsDir, "08_stats.json")); + dynamic reverseObj = LoadJsonObj(Path.Combine(ServerReverseDir, "09_reverse.json")); + + return new + { + log = logObj["log"], + //api = apiObj["api"], api不能为空 + dns = dnsObj["dns"], + routing = routingObj["routing"], + policy = policyObj["policy"], + inbounds = inboundsObj["inbounds"], + outbounds = outboundsObj["outbounds"], + transport = transportObj["transport"], + stats = statsObj["stats"], + reverse = reverseObj["reverse"] + }; + } + + public static string BuildCaddyConfig(V2raySettings parameters, bool useCustomWeb = false) + { + var caddyStr = File.ReadAllText(Path.Combine(CaddyFileDir, "base.caddyfile")); + caddyStr = caddyStr.Replace("##domain##", parameters.IsIPAddress ? "" : parameters.Domain); + caddyStr = caddyStr.Replace("##port##", FullbackPort.ToString()); + + if (!useCustomWeb && !string.IsNullOrEmpty(parameters.MaskDomain)) + { + var prefix = "http://"; + if (parameters.MaskDomain.StartsWith("https://")) + { + prefix = "https://"; + } + var domain = parameters.MaskDomain + .TrimStart("http://".ToCharArray()) + .TrimStart("https://".ToCharArray()); + + caddyStr = caddyStr.Replace("##reverse_proxy##", $"reverse_proxy {prefix}{domain} {{ \n header_up Host {domain} \n }}"); + } + else + { + caddyStr = caddyStr.Replace("##reverse_proxy##", ""); + } + + return caddyStr; + } + + private static void SetClients(dynamic bound, List uuidList) + { + bound.settings.clients.Clear(); + uuidList.ForEach(id => + { + object obj; + + obj = new { id = id }; + + bound.settings.clients.Add(JToken.FromObject(obj)); + }); + } + + + public static string BuildV2rayConfig(V2raySettings parameters) + { + var uuidList = parameters.MulitUUID; + uuidList.Insert(0, parameters.UUID); + + var xrayConfig = LoadV2rayConfig(); + + var baseBound = GetBound("VLESS_TCP_TLS.json"); + baseBound.port = parameters.Port; + baseBound.settings.fallbacks.Add(JToken.FromObject(new + { + dest = FullbackPort + })); + xrayConfig.inbounds.Add(baseBound); + SetClients(baseBound, uuidList); + + #region Fullbacks + + if (parameters.Types.Contains(RayType.VLESS_WS)) + { + var wsInbound = GetBound("VLESS_WS.json"); + wsInbound.port = VLESS_WS_Port; + SetClients(wsInbound, uuidList); + wsInbound.streamSettings.wsSettings.path = parameters.VLESS_WS_Path; + baseBound.settings.fallbacks.Add(JToken.FromObject(new + { + dest = VLESS_WS_Port, + path = parameters.VLESS_WS_Path, + xver = 1, + })); + xrayConfig.inbounds.Add(JToken.FromObject(wsInbound)); + } + + if (parameters.Types.Contains(RayType.VMESS_TCP)) + { + var mtcpBound = GetBound("VMESS_TCP.json"); + mtcpBound.port = VMESS_TCP_Port; + SetClients(mtcpBound, uuidList); + mtcpBound.streamSettings.tcpSettings.header.request.path = parameters.VMESS_TCP_Path; + baseBound.settings.fallbacks.Add(JToken.FromObject(new + { + dest = VMESS_TCP_Port, + path = parameters.VMESS_TCP_Path, + xver = 1, + })); + xrayConfig.inbounds.Add(JToken.FromObject(mtcpBound)); + } + + if (parameters.Types.Contains(RayType.VMESS_WS)) + { + var mwsBound = GetBound("VMESS_WS.json"); + mwsBound.port = VMESS_WS_Port; + SetClients(mwsBound, uuidList); + mwsBound.streamSettings.wsSettings.path = parameters.VMESS_WS_Path; + baseBound.settings.fallbacks.Add(JToken.FromObject(new + { + dest = VMESS_WS_Port, + path = parameters.VMESS_WS_Path, + xver = 1, + })); + xrayConfig.inbounds.Add(JToken.FromObject(mwsBound)); + } + + if (parameters.Types.Contains(RayType.Trojan_TCP)) + { + var trojanTcpBound = GetBound("Trojan_TCP.json"); + trojanTcpBound.port = Trojan_TCP_Port; + trojanTcpBound.settings.clients[0].password = parameters.TrojanPassword; + trojanTcpBound.settings.fallbacks[0].dest = FullbackPort; + baseBound.settings.fallbacks[0] = JToken.FromObject(new + { + dest = Trojan_TCP_Port, + xver = 1, + }); + xrayConfig.inbounds.Add(JToken.FromObject(trojanTcpBound)); + } + #endregion + + if (parameters.Types.Contains(RayType.VLESS_gRPC)) + { + var gRPCInBound = GetBound("VLESS_gRPC.json"); + gRPCInBound.port = parameters.VLESS_gRPC_Port; + SetClients(gRPCInBound, uuidList); + gRPCInBound.streamSettings.grpcSettings.serviceName = parameters.VLESS_gRPC_ServiceName; + gRPCInBound.streamSettings.tlsSettings.serverName = parameters.Domain; + xrayConfig.inbounds.Add(JToken.FromObject(gRPCInBound)); + } + + if (parameters.Types.Contains(RayType.VLESS_KCP)) + { + var kcpBound = GetBound("VLESS_KCP.json"); + kcpBound.port = parameters.VLESS_KCP_Port; + SetClients(kcpBound, uuidList); + kcpBound.streamSettings.kcpSettings.header.type = parameters.VLESS_KCP_Type; + kcpBound.streamSettings.kcpSettings.seed = parameters.VLESS_KCP_Seed; + xrayConfig.inbounds.Add(JToken.FromObject(kcpBound)); + } + + if (parameters.Types.Contains(RayType.VMESS_KCP)) + { + var kcpBound = GetBound("VMESS_KCP.json"); + kcpBound.port = parameters.VMESS_KCP_Port; + SetClients(kcpBound, uuidList); + kcpBound.streamSettings.kcpSettings.header.type = parameters.VMESS_KCP_Type; + kcpBound.streamSettings.kcpSettings.seed = parameters.VMESS_KCP_Seed; + xrayConfig.inbounds.Add(JToken.FromObject(kcpBound)); + } + + if (parameters.Types.Contains(RayType.ShadowsocksAEAD)) + { + var ssBound = GetBound("Shadowsocks-AEAD.json"); + ssBound.port = parameters.ShadowSocksPort; + ssBound.settings.clients[0].password = parameters.ShadowSocksPassword; + ssBound.settings.clients[0].method = parameters.ShadowSocksMethod; + xrayConfig.inbounds.Add(JToken.FromObject(ssBound)); + } + + return JsonConvert.SerializeObject( + xrayConfig, + Formatting.Indented, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }); + } + + private static dynamic GetBound(string name) + { + return LoadJsonObj(Path.Combine(ServerInboundsDir, name)); + } + + private static dynamic LoadJsonObj(string path) + { + if (File.Exists(path)) + { + var jsonStr = File.ReadAllText(path, Encoding.UTF8); + return JToken.FromObject(JsonConvert.DeserializeObject(jsonStr)); + } + return null; + } + } +} diff --git a/ProxySuper.Core/Services/V2rayService.cs b/ProxySuper.Core/Services/V2rayService.cs new file mode 100644 index 0000000..5f5135f --- /dev/null +++ b/ProxySuper.Core/Services/V2rayService.cs @@ -0,0 +1,433 @@ +using Microsoft.Win32; +using ProxySuper.Core.Models.Hosts; +using ProxySuper.Core.Models.Projects; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace ProxySuper.Core.Services +{ + public class V2rayService : ServiceBase + { + public V2rayService(Host host, V2raySettings settings) : base(host, settings) + { + } + + public void Install() + { + Task.Factory.StartNew(() => + { + try + { + int index = 1; + EnsureRootUser(); + + if (FileExists("/usr/local/bin/v2ray")) + { + var btnResult = MessageBox.Show("已经安装v2ray,是否需要重装?", "提示", MessageBoxButton.YesNo); + if (btnResult == MessageBoxResult.No) + { + MessageBox.Show("安装终止", "提示"); + return; + } + } + + Progress.Step = $"{index++}. 检测系统环境"; + EnsureSystemEnv(); + Progress.Percentage = 5; + + Progress.Step = $"{index++}. 安装必要的系统工具"; + InstallSystemTools(); + Progress.Percentage = 15; + + Progress.Step = $"{index++}. 配置防火墙"; + ConfigFirewalld(); + Progress.Percentage = 20; + + Progress.Step = $"{index++}. 检测网络环境"; + EnsureNetwork(); + if (Settings.IsIPAddress) + { + Progress.Desc = ("检查域名是否解析正确"); + ValidateDomain(); + } + Progress.Percentage = 25; + + Progress.Step = $"{index}. 同步系统和本地时间"; + SyncTimeDiff(); + Progress.Percentage = 30; + + Progress.Step = $"{index++}. 安装Caddy服务器"; + InstallCaddy(); + Progress.Percentage = 50; + + Progress.Step = $"{index++}. 安装V2ray-Core"; + InstallV2ray(); + Progress.Percentage = 80; + + Progress.Step = $"{index++}. 上传Web服务器配置"; + UploadCaddyFile(); + Progress.Percentage = 90; + + Progress.Step = $"{index++}. 启动BBR"; + EnableBBR(); + + Progress.Desc = "重启V2ray服务"; + RunCmd("systemctl restart caddy"); + RunCmd("systemctl restart V2ray"); + + Progress.Percentage = 100; + Progress.Step = "安装成功"; + Progress.Desc = string.Empty; + + if (!Settings.WithTLS) + { + Progress.Step = "安装成功,请上传您的 TLS 证书。"; + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + public void UpdateSettings() + { + Task.Factory.StartNew(() => + { + try + { + Progress.Step = "更新V2ray配置"; + Progress.Percentage = 0; + EnsureRootUser(); + var index = 0; + + Progress.Desc = $"{index++}. 检测系统环境"; + EnsureSystemEnv(); + Progress.Percentage = 20; + + Progress.Desc = $"{index++}. 配置防火墙"; + RunCmd("systemctl stop v2ray"); + RunCmd("systemctl stop caddy"); + ConfigFirewalld(); + Progress.Percentage = 40; + + Progress.Desc = $"{index++}. 上传V2ray配置文件"; + var configJson = V2rayConfigBuilder.BuildV2rayConfig(Settings); + WriteToFile(configJson, "/usr/local/etc/v2ray/config.json"); + Progress.Percentage = 70; + + Progress.Desc = $"{index++}. 上传Caddy配置文件"; + UploadCaddyFile(); + Progress.Percentage = 90; + + Progress.Desc = $"{index++}. 重启v2ray服务"; + RunCmd("systemctl restart caddy"); + RunCmd("systemctl restart v2ray"); + Progress.Percentage = 100; + + Progress.Desc = ("更新配置成功"); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + public void UpdateV2rayCore() + { + Task.Factory.StartNew(() => + { + try + { + Progress.Step = "更新V2ray-Core"; + Progress.Percentage = 0; + + EnsureRootUser(); + Progress.Percentage = 20; + + Progress.Desc = "下载最新版本V2ray-Core"; + EnsureSystemEnv(); + Progress.Percentage = 40; + + RunCmd("bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)"); + RunCmd("systemctl restart v2ray"); + Progress.Percentage = 100; + + Progress.Desc = "更新V2ray-Core成功"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + public void Uninstall() + { + Task.Factory.StartNew(() => + { + try + { + EnsureRootUser(); + + var index = 1; + Progress.Percentage = 0; + + Progress.Step = $"{index++}. 检测系统环境"; + Progress.Desc = "检测系统环境"; + EnsureSystemEnv(); + Progress.Percentage = 20; + + Progress.Step = $"{index++}. 卸载Caddy服务"; + UninstallCaddy(); + Progress.Percentage = 40; + + Progress.Step = $"{index++}. 卸载V2ray服务"; + UninstallV2ray(); + Progress.Percentage = 60; + + Progress.Step = $"{index++}. 卸载Acme证书申请服务"; + UninstallAcme(); + Progress.Percentage = 80; + + Progress.Step = $"{index++}. 重置防火墙端口"; + ResetFirewalld(); + Progress.Percentage = 100; + + Progress.Step = "卸载完成"; + Progress.Desc = "卸载完成"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + public void UploadCert() + { + var fileDialog = new OpenFileDialog(); + fileDialog.Filter = "压缩文件|*.zip"; + fileDialog.FileOk += DoUploadCert; + fileDialog.ShowDialog(); + } + + public void UploadWeb() + { + var fileDialog = new OpenFileDialog(); + fileDialog.Filter = "压缩文件|*.zip"; + fileDialog.FileOk += DoUploadWeb; + fileDialog.ShowDialog(); + } + + public void ApplyForCert() + { + Task.Factory.StartNew(() => + { + try + { + Progress.Percentage = 0; + Progress.Step = "续签证书"; + + InstallCert( + dirPath: "/usr/local/etc/v2ray/ssl", + certName: "v2ray_ssl.crt", + keyName: "v2ray_ssl.key"); + + Progress.Percentage = 90; + Progress.Desc = "重启服务"; + RunCmd("systemctl restart v2ray"); + + Progress.Percentage = 100; + Progress.Desc = "续签证书成功"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + + #region 似有方法 + + private void DoUploadCert(object sender, CancelEventArgs e) + { + Task.Factory.StartNew(() => + { + try + { + EnsureRootUser(); + + Progress.Percentage = 0; + Progress.Step = "上传自有证书"; + Progress.Desc = "检测系统环境"; + + EnsureSystemEnv(); + Progress.Percentage = 20; + + Progress.Desc = "正在上传文件"; + var file = sender as OpenFileDialog; + using (var stream = file.OpenFile()) + { + var oldFileName = $"ssl_{DateTime.Now.Ticks}"; + RunCmd($"mv /usr/local/etc/v2ray/ssl /usr/local/etc/v2ray/{oldFileName}"); + + RunCmd("mkdir /usr/local/etc/v2ray/ssl"); + UploadFile(stream, "/usr/local/etc/v2ray/ssl/ssl.zip"); + RunCmd("unzip /usr/local/etc/v2ray/ssl/ssl.zip -d /usr/local/etc/v2ray/ssl"); + } + + var crtFiles = RunCmd("find /usr/local/etc/v2ray/ssl/*.crt").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + var keyFiles = RunCmd("find /usr/local/etc/v2ray/ssl/*.key").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if (crtFiles.Length > 0 && keyFiles.Length > 0) + { + RunCmd($"mv {crtFiles[0]} /usr/local/etc/v2ray/ssl/v2ray_ssl.crt"); + RunCmd($"mv {keyFiles[0]} /usr/local/etc/v2ray/ssl/v2ray_ssl.key"); + } + else + { + Progress.Step = "上传失败"; + Progress.Desc = "上传证书失败,缺少 .crt 和 .key 文件"; + return; + } + + Progress.Desc = "重启V2ray服务"; + RunCmd("systemctl restart v2ray"); + + Progress.Percentage = 100; + Progress.Desc = "上传证书完成"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + private void DoUploadWeb(object sender, CancelEventArgs e) + { + Task.Factory.StartNew(() => + { + try + { + EnsureRootUser(); + + Progress.Step = "上传静态网站"; + Progress.Desc = "上传静态网站"; + Progress.Percentage = 0; + + Progress.Desc = "检测系统环境"; + EnsureSystemEnv(); + Progress.Percentage = 20; + + Progress.Desc = "创建网站目录"; + if (!FileExists("/usr/share/caddy")) + { + RunCmd("mkdir /usr/share/caddy"); + } + RunCmd("rm -rf /usr/share/caddy/*"); + Progress.Percentage = 40; + + Progress.Desc = "正在上传文件"; + var file = sender as OpenFileDialog; + using (var stream = file.OpenFile()) + { + UploadFile(stream, "/usr/share/caddy/caddy.zip"); + RunCmd("unzip /usr/share/caddy/caddy.zip -d /usr/share/caddy"); + } + RunCmd("chmod -R 777 /usr/share/caddy"); + Progress.Percentage = 80; + + Progress.Desc = "上传Web配置文件"; + UploadCaddyFile(useCustomWeb: true); + Progress.Percentage = 100; + + Progress.Desc = "上传静态网站成功"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + private void InstallV2ray() + { + Progress.Desc = ("开始安装V2ray-Core"); + RunCmd("bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)"); + + if (!FileExists("/usr/local/bin/v2ray")) + { + Progress.Desc = ("V2ray-Core安装失败,请联系开发者"); + throw new Exception("V2ray-Core安装失败,请联系开发者"); + } + + Progress.Desc = ("设置V2ray-Core权限"); + RunCmd($"sed -i 's/User=nobody/User=root/g' /etc/systemd/system/v2ray.service"); + RunCmd($"sed -i 's/CapabilityBoundingSet=/#CapabilityBoundingSet=/g' /etc/systemd/system/v2ray.service"); + RunCmd($"sed -i 's/AmbientCapabilities=/#AmbientCapabilities=/g' /etc/systemd/system/v2ray.service"); + RunCmd($"systemctl daemon-reload"); + + if (FileExists("/usr/local/etc/v2ray/config.json")) + { + RunCmd(@"mv /usr/local/etc/v2ray/config.json /usr/local/etc/v2ray/config.json.1"); + } + Progress.Percentage = 60; + + if (Settings.WithTLS && !Settings.IsIPAddress) + { + Progress.Desc = ("安装TLS证书"); + InstallCert( + dirPath: "/usr/local/etc/v2ray/ssl", + certName: "v2ray_ssl.crt", + keyName: "v2ray_ssl.key"); + Progress.Percentage = 75; + } + + Progress.Desc = ("生成v2ray服务器配置文件"); + var configJson = V2rayConfigBuilder.BuildV2rayConfig(Settings); + WriteToFile(configJson, "/usr/local/etc/v2ray/config.json"); + } + + private void UploadCaddyFile(bool useCustomWeb = false) + { + var configJson = V2rayConfigBuilder.BuildCaddyConfig(Settings, useCustomWeb); + + if (FileExists("/etc/caddy/Caddyfile")) + { + RunCmd("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.back"); + } + WriteToFile(configJson, "/etc/caddy/Caddyfile"); + } + + + private void UninstallV2ray() + { + Progress.Desc = "关闭V2ray服务"; + RunCmd("systemctl stop v2ray"); + RunCmd("systemctl disable v2ray"); + + Progress.Desc = "卸载V2ray"; + RunCmd("bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh) --remove"); + } + + private void UninstallAcme() + { + Progress.Desc = "卸载 acme.sh"; + RunCmd("acme.sh --uninstall"); + + Progress.Desc = "删除 acme.sh 相关文件"; + RunCmd("rm -rf ~/.acme.sh"); + } + + #endregion + } +} diff --git a/ProxySuper.Core/Services/XrayConfigBuilder.cs b/ProxySuper.Core/Services/XrayConfigBuilder.cs index 12226bc..04ee9a3 100644 --- a/ProxySuper.Core/Services/XrayConfigBuilder.cs +++ b/ProxySuper.Core/Services/XrayConfigBuilder.cs @@ -129,7 +129,7 @@ namespace ProxySuper.Core.Services #region Fullbacks - if (parameters.Types.Contains(XrayType.VLESS_WS)) + if (parameters.Types.Contains(RayType.VLESS_WS)) { var wsInbound = GetBound("VLESS_WS.json"); wsInbound.port = VLESS_WS_Port; @@ -144,7 +144,7 @@ namespace ProxySuper.Core.Services xrayConfig.inbounds.Add(JToken.FromObject(wsInbound)); } - if (parameters.Types.Contains(XrayType.VMESS_TCP)) + if (parameters.Types.Contains(RayType.VMESS_TCP)) { var mtcpBound = GetBound("VMESS_TCP.json"); mtcpBound.port = VMESS_TCP_Port; @@ -159,7 +159,7 @@ namespace ProxySuper.Core.Services xrayConfig.inbounds.Add(JToken.FromObject(mtcpBound)); } - if (parameters.Types.Contains(XrayType.VMESS_WS)) + if (parameters.Types.Contains(RayType.VMESS_WS)) { var mwsBound = GetBound("VMESS_WS.json"); mwsBound.port = VMESS_WS_Port; @@ -174,7 +174,7 @@ namespace ProxySuper.Core.Services xrayConfig.inbounds.Add(JToken.FromObject(mwsBound)); } - if (parameters.Types.Contains(XrayType.Trojan_TCP)) + if (parameters.Types.Contains(RayType.Trojan_TCP)) { var trojanTcpBound = GetBound("Trojan_TCP.json"); trojanTcpBound.port = Trojan_TCP_Port; @@ -189,7 +189,7 @@ namespace ProxySuper.Core.Services } #endregion - if (parameters.Types.Contains(XrayType.VLESS_gRPC)) + if (parameters.Types.Contains(RayType.VLESS_gRPC)) { var gRPCInBound = GetBound("VLESS_gRPC.json"); gRPCInBound.port = parameters.VLESS_gRPC_Port; @@ -199,7 +199,7 @@ namespace ProxySuper.Core.Services xrayConfig.inbounds.Add(JToken.FromObject(gRPCInBound)); } - if (parameters.Types.Contains(XrayType.VLESS_KCP)) + if (parameters.Types.Contains(RayType.VLESS_KCP)) { var kcpBound = GetBound("VLESS_KCP.json"); kcpBound.port = parameters.VLESS_KCP_Port; @@ -209,7 +209,7 @@ namespace ProxySuper.Core.Services xrayConfig.inbounds.Add(JToken.FromObject(kcpBound)); } - if (parameters.Types.Contains(XrayType.VMESS_KCP)) + if (parameters.Types.Contains(RayType.VMESS_KCP)) { var kcpBound = GetBound("VMESS_KCP.json"); kcpBound.port = parameters.VMESS_KCP_Port; @@ -219,7 +219,7 @@ namespace ProxySuper.Core.Services xrayConfig.inbounds.Add(JToken.FromObject(kcpBound)); } - if (parameters.Types.Contains(XrayType.ShadowsocksAEAD)) + if (parameters.Types.Contains(RayType.ShadowsocksAEAD)) { var ssBound = GetBound("Shadowsocks-AEAD.json"); ssBound.port = parameters.ShadowSocksPort; diff --git a/ProxySuper.Core/ViewModels/HomeViewModel.cs b/ProxySuper.Core/ViewModels/HomeViewModel.cs index c6c0839..8b401db 100644 --- a/ProxySuper.Core/ViewModels/HomeViewModel.cs +++ b/ProxySuper.Core/ViewModels/HomeViewModel.cs @@ -58,6 +58,8 @@ namespace ProxySuper.Core.ViewModels public MvxObservableCollection Records { get; set; } + public IMvxCommand AddV2rayCommand => new MvxAsyncCommand(AddV2rayRecord); + public IMvxCommand AddXrayCommand => new MvxAsyncCommand(AddXrayRecord); public IMvxCommand AddTrojanGoCommand => new MvxAsyncCommand(AddTrojanGoRecord); @@ -74,6 +76,20 @@ namespace ProxySuper.Core.ViewModels public IMvxCommand InstallCommand => new MvxAsyncCommand(GoToInstall); + public async Task AddV2rayRecord() + { + Record record = new Record(); + record.Id = Utils.GetTickID(); + record.Host = new Host(); + record.V2raySettings = new V2raySettings(); + + var result = await _navigationService.Navigate(record); + if (result == null) return; + + Records.Add(result); + SaveToJson(); + } + public async Task AddXrayRecord() { Record record = new Record(); @@ -140,6 +156,14 @@ namespace ProxySuper.Core.ViewModels if (record == null) return; Record result = null; + if (record.Type == ProjectType.V2ray) + { + result = await _navigationService.Navigate(record); + if (result == null) return; + + record.Host = result.Host; + record.V2raySettings = result.V2raySettings; + } if (record.Type == ProjectType.Xray) { result = await _navigationService.Navigate(record); @@ -196,6 +220,10 @@ namespace ProxySuper.Core.ViewModels var record = Records.FirstOrDefault(x => x.Id == id); if (record == null) return; + if (record.Type == ProjectType.V2ray) + { + await _navigationService.Navigate(record.V2raySettings); + } if (record.Type == ProjectType.Xray) { await _navigationService.Navigate(record.XraySettings); @@ -219,6 +247,10 @@ namespace ProxySuper.Core.ViewModels var record = Records.FirstOrDefault(x => x.Id == id); if (record == null) return; + if (record.Type == ProjectType.V2ray) + { + await _navigationService.Navigate(record); + } if (record.Type == ProjectType.Xray) { await _navigationService.Navigate(record); diff --git a/ProxySuper.Core/ViewModels/V2rayConfigViewModel.cs b/ProxySuper.Core/ViewModels/V2rayConfigViewModel.cs new file mode 100644 index 0000000..f381366 --- /dev/null +++ b/ProxySuper.Core/ViewModels/V2rayConfigViewModel.cs @@ -0,0 +1,93 @@ +using MvvmCross.ViewModels; +using ProxySuper.Core.Models.Projects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProxySuper.Core.ViewModels +{ + public class V2rayConfigViewModel : MvxViewModel + { + public V2raySettings Settings { get; set; } + + public override void Prepare(V2raySettings parameter) + { + Settings = parameter; + } + + + public bool Checked_VLESS_TCP + { + get + { + return Settings.Types.Contains(RayType.VLESS_TCP); + } + } + + public bool Checked_VLESS_WS + { + get + { + return Settings.Types.Contains(RayType.VLESS_WS); + } + } + + public bool Checked_VLESS_KCP + { + get + { + return Settings.Types.Contains(RayType.VLESS_KCP); + } + } + + public bool Checked_VLESS_gRPC + { + get + { + return Settings.Types.Contains(RayType.VLESS_gRPC); + } + } + + public bool Checked_VMESS_TCP + { + get + { + return Settings.Types.Contains(RayType.VMESS_TCP); + } + } + + public bool Checked_VMESS_WS + { + get + { + return Settings.Types.Contains(RayType.VMESS_WS); + } + } + + public bool Checked_VMESS_KCP + { + get + { + return Settings.Types.Contains(RayType.VMESS_KCP); + } + } + + public bool Checked_Trojan_TCP + { + get + { + return Settings.Types.Contains(RayType.Trojan_TCP); + } + } + + public bool CheckedShadowSocks + { + get + { + return Settings.Types.Contains(RayType.ShadowsocksAEAD); + } + } + } +} diff --git a/ProxySuper.Core/ViewModels/V2rayEditorViewModel.cs b/ProxySuper.Core/ViewModels/V2rayEditorViewModel.cs new file mode 100644 index 0000000..1460073 --- /dev/null +++ b/ProxySuper.Core/ViewModels/V2rayEditorViewModel.cs @@ -0,0 +1,442 @@ +using MvvmCross.Commands; +using MvvmCross.Navigation; +using MvvmCross.ViewModels; +using ProxySuper.Core.Models; +using ProxySuper.Core.Models.Hosts; +using ProxySuper.Core.Models.Projects; +using ProxySuper.Core.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace ProxySuper.Core.ViewModels +{ + public partial class V2rayEditorViewModel : MvxViewModel + { + public V2rayEditorViewModel(IMvxNavigationService navigationService) + { + NavigationService = navigationService; + } + + public string Id { get; set; } + + public Host Host { get; set; } + + public V2raySettings Settings { get; set; } + + public IMvxCommand SaveCommand => new MvxCommand(Save); + + public IMvxCommand SaveAndInstallCommand => new MvxCommand(SaveAndInstall); + + public IMvxNavigationService NavigationService { get; } + + public override void Prepare(Record parameter) + { + var record = Utils.DeepClone(parameter); + Id = record.Id; + Host = record.Host; + Settings = record.V2raySettings; + } + + public void Save() + { + NavigationService.Close(this, new Record() + { + Id = Id, + Host = Host, + V2raySettings = Settings, + }); + } + + public void SaveAndInstall() + { + var record = new Record() + { + Id = Id, + Host = Host, + V2raySettings = Settings, + }; + NavigationService.Close(this, record); + NavigationService.Navigate(record); + } + } + + + + + + public partial class V2rayEditorViewModel + { + public IMvxCommand RandomUuid => new MvxCommand(() => GetUuid()); + + public bool WithTLS + { + get => Settings.WithTLS; + set + { + Settings.WithTLS = value; + RaisePropertyChanged("Port"); + } + } + + public int Port + { + get => Settings.Port; + set + { + Settings.Port = value; + RaisePropertyChanged("Port"); + } + } + + public int VLESS_KCP_Port + { + get => Settings.VLESS_KCP_Port; + set + { + Settings.VLESS_KCP_Port = value; + RaisePropertyChanged("VLESS_KCP_Port"); + } + } + + public int VMESS_KCP_Port + { + get => Settings.VMESS_KCP_Port; + set + { + Settings.VMESS_KCP_Port = value; + RaisePropertyChanged("VMESS_KCP_Port"); + } + } + + public int ShadowSocksPort + { + get => Settings.ShadowSocksPort; + set + { + Settings.ShadowSocksPort = value; + RaisePropertyChanged("ShadowSocksPort"); + } + } + + + public string UUID + { + get => Settings.UUID; + set + { + Settings.UUID = value; + RaisePropertyChanged("UUID"); + } + } + + public string MultiUUID + { + get => string.Join(",", Settings.MulitUUID); + set + { + var input = value.Replace(',', ','); + var arr = input.Split(',').ToList(); + Settings.MulitUUID = arr; + RaisePropertyChanged("MultiUUID"); + } + } + + public string Domain + { + get => Settings.Domain; + set + { + Settings.Domain = value; + RaisePropertyChanged("Domain"); + } + } + + public string MaskDomain + { + get => Settings.MaskDomain; + set + { + Settings.MaskDomain = value; + RaisePropertyChanged("MaskDomain"); + } + } + + public string TrojanPassword + { + get => Settings.TrojanPassword; + set => Settings.TrojanPassword = value; + } + + public bool Checked_Trojan_TCP + { + get + { + return Settings.Types.Contains(RayType.Trojan_TCP); + } + set + { + if (value == true) + { + if (!Settings.Types.Contains(RayType.Trojan_TCP)) + Settings.Types.Add(RayType.Trojan_TCP); + } + else + { + Settings.Types.Remove(RayType.Trojan_TCP); + } + RaisePropertyChanged("Checked_Trojan_TCP"); + } + } + public string Trojan_TCP_ShareLink + { + get => ShareLink.Build(RayType.Trojan_TCP, Settings); + } + + private List _ssMethods = new List { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305" }; + public List ShadowSocksMethods => _ssMethods; + public bool CheckedShadowSocks + { + + get => Settings.Types.Contains(RayType.ShadowsocksAEAD); + set + { + CheckBoxChanged(value, RayType.ShadowsocksAEAD); + RaisePropertyChanged("CheckedShadowSocks"); + } + } + public string ShadowSocksPassword + { + get => Settings.ShadowSocksPassword; + set => Settings.ShadowSocksPassword = value; + } + public string ShadowSocksMethod + { + get => Settings.ShadowSocksMethod; + set + { + var namespaceStr = typeof(ComboBoxItem).FullName + ":"; + var trimValue = value.Replace(namespaceStr, ""); + trimValue = trimValue.Trim(); + Settings.ShadowSocksMethod = trimValue; + RaisePropertyChanged("ShadowSocksMethod"); + } + } + public string ShadowSocksShareLink + { + get => ShareLink.Build(RayType.ShadowsocksAEAD, Settings); + } + + + private void CheckBoxChanged(bool value, RayType type) + { + if (value == true) + { + if (!Settings.Types.Contains(type)) + { + Settings.Types.Add(type); + } + } + else + { + Settings.Types.RemoveAll(x => x == type); + } + } + + + + private void GetUuid() + { + UUID = Guid.NewGuid().ToString(); + RaisePropertyChanged("UUID"); + } + + } + + /// + /// VMESS + /// + public partial class V2rayEditorViewModel + { + // vmess tcp + public bool Checked_VMESS_TCP + { + get => Settings.Types.Contains(RayType.VMESS_TCP); + set + { + CheckBoxChanged(value, RayType.VMESS_TCP); + RaisePropertyChanged("Checked_VMESS_TCP"); + } + } + public string VMESS_TCP_Path + { + get => Settings.VMESS_TCP_Path; + set => Settings.VMESS_TCP_Path = value; + } + public string VMESS_TCP_ShareLink + { + get => ShareLink.Build(RayType.VMESS_TCP, Settings); + } + + // vmess ws + public bool Checked_VMESS_WS + { + get => Settings.Types.Contains(RayType.VMESS_WS); + set + { + CheckBoxChanged(value, RayType.VMESS_WS); + RaisePropertyChanged("Checked_VMESS_WS"); + } + } + public string VMESS_WS_Path + { + get => Settings.VMESS_WS_Path; + set => Settings.VMESS_WS_Path = value; + } + public string VMESS_WS_ShareLink + { + get => ShareLink.Build(RayType.VMESS_WS, Settings); + } + + // vmess kcp + public string VMESS_KCP_Seed + { + get => Settings.VMESS_KCP_Seed; + set => Settings.VMESS_KCP_Seed = value; + } + public string VMESS_KCP_Type + { + get => Settings.VMESS_KCP_Type; + set + { + var namespaceStr = typeof(ComboBoxItem).FullName + ":"; + var trimValue = value.Replace(namespaceStr, ""); + trimValue = trimValue.Trim(); + Settings.VMESS_KCP_Type = trimValue; + RaisePropertyChanged("VMESS_KCP_Type"); + } + } + public bool Checked_VMESS_KCP + { + get => Settings.Types.Contains(RayType.VMESS_KCP); + set + { + CheckBoxChanged(value, RayType.VMESS_KCP); + RaisePropertyChanged("Checked_VMESS_KCP"); + } + } + public string VMESS_KCP_ShareLink + { + get => ShareLink.Build(RayType.VMESS_KCP, Settings); + } + + + private List _kcpTypes = new List { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", }; + public List KcpTypes => _kcpTypes; + } + + /// + /// VLESS + /// + public partial class V2rayEditorViewModel + { + // vless tcp + public bool Checked_VLESS_TCP + { + get => Settings.Types.Contains(RayType.VLESS_TCP); + set + { + CheckBoxChanged(value, RayType.VLESS_TCP); + RaisePropertyChanged("Checked_VLESS_TCP"); + } + } + public string VLESS_TCP_ShareLink + { + get => ShareLink.Build(RayType.VLESS_TCP, Settings); + } + + + // vless ws + public string VLESS_WS_Path + { + get => Settings.VLESS_WS_Path; + set => Settings.VLESS_WS_Path = value; + } + public bool Checked_VLESS_WS + { + get + { + return Settings.Types.Contains(RayType.VLESS_WS); + } + set + { + CheckBoxChanged(value, RayType.VLESS_WS); + RaisePropertyChanged("Checked_VLESS_WS"); + } + } + public string VLESS_WS_ShareLink + { + get => ShareLink.Build(RayType.VLESS_WS, Settings); + } + + // vless kcp + public string VLESS_KCP_Seed + { + get => Settings.VLESS_KCP_Seed; + set => Settings.VLESS_KCP_Seed = value; + } + public string VLESS_KCP_Type + { + get => Settings.VLESS_KCP_Type; + set + { + var namespaceStr = typeof(ComboBoxItem).FullName + ":"; + var trimValue = value.Replace(namespaceStr, ""); + trimValue = trimValue.Trim(); + Settings.VLESS_KCP_Type = trimValue; + RaisePropertyChanged("VLESS_KCP_Type"); + } + } + public bool Checked_VLESS_KCP + { + get => Settings.Types.Contains(RayType.VLESS_KCP); + set + { + CheckBoxChanged(value, RayType.VLESS_KCP); + RaisePropertyChanged("Checked_VLESS_KCP"); + } + } + public string VLESS_KCP_ShareLink + { + get => ShareLink.Build(RayType.VLESS_KCP, Settings); + } + + // vless grpc + public string VLESS_gRPC_ServiceName + { + get => Settings.VLESS_gRPC_ServiceName; + set => Settings.VLESS_gRPC_ServiceName = value; + } + public int VLESS_gRPC_Port + { + get => Settings.VLESS_gRPC_Port; + set => Settings.VLESS_gRPC_Port = value; + } + public bool Checked_VLESS_gRPC + { + get => Settings.Types.Contains(RayType.VLESS_gRPC); + set + { + CheckBoxChanged(value, RayType.VLESS_gRPC); + RaisePropertyChanged("Checked_VLESS_gRPC"); + } + } + public string VLESS_gRPC_ShareLink + { + get => ShareLink.Build(RayType.VLESS_gRPC, Settings); + } + } +} diff --git a/ProxySuper.Core/ViewModels/V2rayInstallViewModel.cs b/ProxySuper.Core/ViewModels/V2rayInstallViewModel.cs new file mode 100644 index 0000000..5a27854 --- /dev/null +++ b/ProxySuper.Core/ViewModels/V2rayInstallViewModel.cs @@ -0,0 +1,88 @@ +using MvvmCross.Commands; +using MvvmCross.ViewModels; +using ProxySuper.Core.Models; +using ProxySuper.Core.Models.Hosts; +using ProxySuper.Core.Models.Projects; +using ProxySuper.Core.Services; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProxySuper.Core.ViewModels +{ + public class V2rayInstallViewModel : MvxViewModel + { + Host _host; + + V2raySettings _settings; + + V2rayService _service; + + public override void ViewDestroy(bool viewFinishing = true) + { + _service.Disconnect(); + this.SaveInstallLog(); + base.ViewDestroy(viewFinishing); + } + + public override void Prepare(Record parameter) + { + this._host = parameter.Host; + this._settings = parameter.V2raySettings; + } + + public override Task Initialize() + { + _service = new V2rayService(_host, _settings); + _service.Progress.StepUpdate = () => RaisePropertyChanged("Progress"); + _service.Progress.LogsUpdate = () => RaisePropertyChanged("Logs"); + _service.Connect(); + + return base.Initialize(); + } + + public ProjectProgress Progress + { + get => _service.Progress; + } + + public string Logs + { + get => _service.Progress.Logs; + } + + + + #region Command + + public IMvxCommand InstallCommand => new MvxCommand(_service.Install); + + public IMvxCommand UpdateSettingsCommand => new MvxCommand(_service.UpdateSettings); + + public IMvxCommand UpdateV2rayCoreCommand => new MvxCommand(_service.UpdateV2rayCore); + + public IMvxCommand UninstallCommand => new MvxCommand(_service.Uninstall); + + public IMvxCommand UploadCertCommand => new MvxCommand(_service.UploadCert); + + public IMvxCommand UploadWebCommand => new MvxCommand(_service.UploadWeb); + + public IMvxCommand ApplyForCertCommand => new MvxCommand(_service.ApplyForCert); + + #endregion + + private void SaveInstallLog() + { + if (!Directory.Exists("Logs")) + { + Directory.CreateDirectory("Logs"); + } + + var fileName = Path.Combine("Logs", DateTime.Now.ToString("yyyy-MM-dd hh-mm") + ".xary.txt"); + File.WriteAllText(fileName, Logs); + } + } +} diff --git a/ProxySuper.Core/ViewModels/XrayConfigViewModel.cs b/ProxySuper.Core/ViewModels/XrayConfigViewModel.cs index 5988329..57d19aa 100644 --- a/ProxySuper.Core/ViewModels/XrayConfigViewModel.cs +++ b/ProxySuper.Core/ViewModels/XrayConfigViewModel.cs @@ -17,7 +17,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VLESS_TCP_XTLS); + return Settings.Types.Contains(RayType.VLESS_TCP_XTLS); } } @@ -25,7 +25,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VLESS_TCP); + return Settings.Types.Contains(RayType.VLESS_TCP); } } @@ -33,7 +33,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VLESS_WS); + return Settings.Types.Contains(RayType.VLESS_WS); } } @@ -41,7 +41,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VLESS_KCP); + return Settings.Types.Contains(RayType.VLESS_KCP); } } @@ -49,7 +49,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VLESS_gRPC); + return Settings.Types.Contains(RayType.VLESS_gRPC); } } @@ -57,7 +57,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VMESS_TCP); + return Settings.Types.Contains(RayType.VMESS_TCP); } } @@ -65,7 +65,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VMESS_WS); + return Settings.Types.Contains(RayType.VMESS_WS); } } @@ -73,7 +73,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VMESS_KCP); + return Settings.Types.Contains(RayType.VMESS_KCP); } } @@ -81,7 +81,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.Trojan_TCP); + return Settings.Types.Contains(RayType.Trojan_TCP); } } @@ -89,7 +89,7 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.ShadowsocksAEAD); + return Settings.Types.Contains(RayType.ShadowsocksAEAD); } } } diff --git a/ProxySuper.Core/ViewModels/XrayEditorViewModel.cs b/ProxySuper.Core/ViewModels/XrayEditorViewModel.cs index b90580d..db613f7 100644 --- a/ProxySuper.Core/ViewModels/XrayEditorViewModel.cs +++ b/ProxySuper.Core/ViewModels/XrayEditorViewModel.cs @@ -170,25 +170,25 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.Trojan_TCP); + return Settings.Types.Contains(RayType.Trojan_TCP); } set { if (value == true) { - if (!Settings.Types.Contains(XrayType.Trojan_TCP)) - Settings.Types.Add(XrayType.Trojan_TCP); + if (!Settings.Types.Contains(RayType.Trojan_TCP)) + Settings.Types.Add(RayType.Trojan_TCP); } else { - Settings.Types.Remove(XrayType.Trojan_TCP); + Settings.Types.Remove(RayType.Trojan_TCP); } RaisePropertyChanged("Checked_Trojan_TCP"); } } public string Trojan_TCP_ShareLink { - get => ShareLink.Build(XrayType.Trojan_TCP, Settings); + get => ShareLink.Build(RayType.Trojan_TCP, Settings); } private List _ssMethods = new List { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305" }; @@ -196,10 +196,10 @@ namespace ProxySuper.Core.ViewModels public bool CheckedShadowSocks { - get => Settings.Types.Contains(XrayType.ShadowsocksAEAD); + get => Settings.Types.Contains(RayType.ShadowsocksAEAD); set { - CheckBoxChanged(value, XrayType.ShadowsocksAEAD); + CheckBoxChanged(value, RayType.ShadowsocksAEAD); RaisePropertyChanged("CheckedShadowSocks"); } } @@ -222,11 +222,11 @@ namespace ProxySuper.Core.ViewModels } public string ShadowSocksShareLink { - get => ShareLink.Build(XrayType.ShadowsocksAEAD, Settings); + get => ShareLink.Build(RayType.ShadowsocksAEAD, Settings); } - private void CheckBoxChanged(bool value, XrayType type) + private void CheckBoxChanged(bool value, RayType type) { if (value == true) { @@ -259,10 +259,10 @@ namespace ProxySuper.Core.ViewModels // vmess tcp public bool Checked_VMESS_TCP { - get => Settings.Types.Contains(XrayType.VMESS_TCP); + get => Settings.Types.Contains(RayType.VMESS_TCP); set { - CheckBoxChanged(value, XrayType.VMESS_TCP); + CheckBoxChanged(value, RayType.VMESS_TCP); RaisePropertyChanged("Checked_VMESS_TCP"); } } @@ -273,16 +273,16 @@ namespace ProxySuper.Core.ViewModels } public string VMESS_TCP_ShareLink { - get => ShareLink.Build(XrayType.VMESS_TCP, Settings); + get => ShareLink.Build(RayType.VMESS_TCP, Settings); } // vmess ws public bool Checked_VMESS_WS { - get => Settings.Types.Contains(XrayType.VMESS_WS); + get => Settings.Types.Contains(RayType.VMESS_WS); set { - CheckBoxChanged(value, XrayType.VMESS_WS); + CheckBoxChanged(value, RayType.VMESS_WS); RaisePropertyChanged("Checked_VMESS_WS"); } } @@ -293,7 +293,7 @@ namespace ProxySuper.Core.ViewModels } public string VMESS_WS_ShareLink { - get => ShareLink.Build(XrayType.VMESS_WS, Settings); + get => ShareLink.Build(RayType.VMESS_WS, Settings); } // vmess kcp @@ -316,16 +316,16 @@ namespace ProxySuper.Core.ViewModels } public bool Checked_VMESS_KCP { - get => Settings.Types.Contains(XrayType.VMESS_KCP); + get => Settings.Types.Contains(RayType.VMESS_KCP); set { - CheckBoxChanged(value, XrayType.VMESS_KCP); + CheckBoxChanged(value, RayType.VMESS_KCP); RaisePropertyChanged("Checked_VMESS_KCP"); } } public string VMESS_KCP_ShareLink { - get => ShareLink.Build(XrayType.VMESS_KCP, Settings); + get => ShareLink.Build(RayType.VMESS_KCP, Settings); } @@ -342,31 +342,31 @@ namespace ProxySuper.Core.ViewModels // vless xtls public bool Checked_VLESS_TCP_XTLS { - get => Settings.Types.Contains(XrayType.VLESS_TCP_XTLS); + get => Settings.Types.Contains(RayType.VLESS_TCP_XTLS); set { - CheckBoxChanged(value, XrayType.VLESS_TCP_XTLS); + CheckBoxChanged(value, RayType.VLESS_TCP_XTLS); RaisePropertyChanged("Checked_VLESS_TCP_XTLS"); } } public string VLESS_TCP_XTLS_ShareLink { - get => ShareLink.Build(XrayType.VLESS_TCP_XTLS, Settings); + get => ShareLink.Build(RayType.VLESS_TCP_XTLS, Settings); } // vless tcp public bool Checked_VLESS_TCP { - get => Settings.Types.Contains(XrayType.VLESS_TCP); + get => Settings.Types.Contains(RayType.VLESS_TCP); set { - CheckBoxChanged(value, XrayType.VLESS_TCP); + CheckBoxChanged(value, RayType.VLESS_TCP); RaisePropertyChanged("Checked_VLESS_TCP"); } } public string VLESS_TCP_ShareLink { - get => ShareLink.Build(XrayType.VLESS_TCP, Settings); + get => ShareLink.Build(RayType.VLESS_TCP, Settings); } @@ -380,17 +380,17 @@ namespace ProxySuper.Core.ViewModels { get { - return Settings.Types.Contains(XrayType.VLESS_WS); + return Settings.Types.Contains(RayType.VLESS_WS); } set { - CheckBoxChanged(value, XrayType.VLESS_WS); + CheckBoxChanged(value, RayType.VLESS_WS); RaisePropertyChanged("Checked_VLESS_WS"); } } public string VLESS_WS_ShareLink { - get => ShareLink.Build(XrayType.VLESS_WS, Settings); + get => ShareLink.Build(RayType.VLESS_WS, Settings); } // vless kcp @@ -413,16 +413,16 @@ namespace ProxySuper.Core.ViewModels } public bool Checked_VLESS_KCP { - get => Settings.Types.Contains(XrayType.VLESS_KCP); + get => Settings.Types.Contains(RayType.VLESS_KCP); set { - CheckBoxChanged(value, XrayType.VLESS_KCP); + CheckBoxChanged(value, RayType.VLESS_KCP); RaisePropertyChanged("Checked_VLESS_KCP"); } } public string VLESS_KCP_ShareLink { - get => ShareLink.Build(XrayType.VLESS_KCP, Settings); + get => ShareLink.Build(RayType.VLESS_KCP, Settings); } // vless grpc @@ -438,16 +438,16 @@ namespace ProxySuper.Core.ViewModels } public bool Checked_VLESS_gRPC { - get => Settings.Types.Contains(XrayType.VLESS_gRPC); + get => Settings.Types.Contains(RayType.VLESS_gRPC); set { - CheckBoxChanged(value, XrayType.VLESS_gRPC); + CheckBoxChanged(value, RayType.VLESS_gRPC); RaisePropertyChanged("Checked_VLESS_gRPC"); } } public string VLESS_gRPC_ShareLink { - get => ShareLink.Build(XrayType.VLESS_gRPC, Settings); + get => ShareLink.Build(RayType.VLESS_gRPC, Settings); } } diff --git a/ProxySuper.WPF/Controls/V2raySettingsControl.xaml b/ProxySuper.WPF/Controls/V2raySettingsControl.xaml new file mode 100644 index 0000000..5c63f27 --- /dev/null +++ b/ProxySuper.WPF/Controls/V2raySettingsControl.xaml @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +