diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..516f5da --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# Default severity for all analyzer diagnostics +dotnet_analyzer_diagnostic.severity = none diff --git a/ProxySU.sln b/ProxySU.sln index 6b8b4af..6f38af8 100644 --- a/ProxySU.sln +++ b/ProxySU.sln @@ -7,6 +7,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxySU", "ProxySU\ProxySU. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxySU_Core", "ProxySU_Core\ProxySU_Core.csproj", "{B066015C-D347-4493-92F1-6556D3863996}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18714411-764D-47E5-AFE6-A96200B7CE41}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/ProxySU/ProxySU.csproj b/ProxySU/ProxySU.csproj index be52772..9ae9d06 100644 --- a/ProxySU/ProxySU.csproj +++ b/ProxySU/ProxySU.csproj @@ -181,6 +181,9 @@ ResXFileCodeGenerator Resources.Designer.cs + + .editorconfig + SettingsSingleFileGenerator diff --git a/ProxySU_Core/Common/Base64.cs b/ProxySU_Core/Common/Base64.cs new file mode 100644 index 0000000..0a61841 --- /dev/null +++ b/ProxySU_Core/Common/Base64.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProxySU_Core.Common +{ + public class Base64 + { + public static string Encode(string plainText) + { + var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); + return System.Convert.ToBase64String(plainTextBytes); + } + + public static string Decode(string base64EncodedData) + { + var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); + return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); + } + } +} diff --git a/ProxySU_Core/Converters/VisibleConverter.cs b/ProxySU_Core/Converters/VisibleConverter.cs new file mode 100644 index 0000000..f52a08d --- /dev/null +++ b/ProxySU_Core/Converters/VisibleConverter.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace ProxySU_Core.Converters +{ + public class VisibleConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value.Equals(true) ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return false; + } + + if (value.Equals(Visibility.Visible)) + { + return true; + } + + return false; + } + } +} diff --git a/ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs b/ProxySU_Core/Models/Developers/ConfigBuilder.cs similarity index 77% rename from ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs rename to ProxySU_Core/Models/Developers/ConfigBuilder.cs index 5748161..fdd6425 100644 --- a/ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs +++ b/ProxySU_Core/Models/Developers/ConfigBuilder.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public class ConfigBuilder { @@ -27,9 +27,18 @@ namespace ProxySU_Core.ViewModels.Developers public const int VLESS_TCP_Port = 1110; public const int VLESS_WS_Port = 1111; + public const int VLESS_H2_Port = 1112; + public const int VLESS_mKCP_Port = 1113; + public const int VMESS_TCP_Port = 2110; public const int VMESS_WS_Port = 2111; + public const int VMESS_H2_Port = 2112; + public const int VMESS_mKCP_Port = 2113; + public const int Trojan_TCP_Port = 3110; + public const int Trojan_WS_Port = 3111; + + public const int ShadowSocksPort = 4110; public static dynamic LoadXrayConfig() @@ -88,25 +97,18 @@ namespace ProxySU_Core.ViewModels.Developers public static string BuildXrayConfig(XraySettings parameters) { var xrayConfig = LoadXrayConfig(); - var baseBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_TCP_XTLS.json")); + var baseBound = GetBound("VLESS_TCP_XTLS.json"); baseBound.port = parameters.Port; baseBound.settings.fallbacks.Add(JToken.FromObject(new { - dest = 80, - xver = 1, + dest = 80 })); xrayConfig.inbounds.Add(baseBound); + baseBound.settings.clients[0].id = parameters.UUID; - if (parameters.Types.Contains(XrayType.VLESS_TCP_XTLS)) + if (parameters.Types.Contains(XrayType.VLESS_WS)) { - baseBound.settings.clients[0].id = parameters.UUID; - } - - if (parameters.Types.Contains(XrayType.VLESS_WS_TLS)) - { - baseBound.settings.clients[0].id = parameters.UUID; - - var wsInbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_WS_TLS.json")); + var wsInbound = GetBound("VLESS_WS.json"); wsInbound.port = VLESS_WS_Port; wsInbound.settings.clients[0].id = parameters.UUID; wsInbound.streamSettings.wsSettings.path = parameters.VLESS_WS_Path; @@ -119,9 +121,9 @@ namespace ProxySU_Core.ViewModels.Developers xrayConfig.inbounds.Add(JToken.FromObject(wsInbound)); } - if (parameters.Types.Contains(XrayType.VMESS_TCP_TLS)) + if (parameters.Types.Contains(XrayType.VMESS_TCP)) { - var mtcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_TCP_TLS.json")); + var mtcpBound = GetBound("VMESS_TCP.json"); mtcpBound.port = VMESS_TCP_Port; mtcpBound.settings.clients[0].id = parameters.UUID; mtcpBound.streamSettings.tcpSettings.header.request.path = parameters.VMESS_TCP_Path; @@ -134,9 +136,9 @@ namespace ProxySU_Core.ViewModels.Developers xrayConfig.inbounds.Add(JToken.FromObject(mtcpBound)); } - if (parameters.Types.Contains(XrayType.VMESS_WS_TLS)) + if (parameters.Types.Contains(XrayType.VMESS_WS)) { - var mwsBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_WS_TLS.json")); + var mwsBound = GetBound("VMESS_WS.json"); mwsBound.port = VMESS_WS_Port; mwsBound.settings.clients[0].id = parameters.UUID; mwsBound.streamSettings.wsSettings.path = parameters.VMESS_WS_Path; @@ -149,9 +151,9 @@ namespace ProxySU_Core.ViewModels.Developers xrayConfig.inbounds.Add(JToken.FromObject(mwsBound)); } - if (parameters.Types.Contains(XrayType.Trojan_TCP_TLS)) + if (parameters.Types.Contains(XrayType.Trojan_TCP)) { - var trojanTcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "Trojan_TCP_TLS.json")); + var trojanTcpBound = GetBound("Trojan_TCP.json"); trojanTcpBound.port = Trojan_TCP_Port; trojanTcpBound.settings.clients[0].password = parameters.TrojanPassword; baseBound.settings.fallbacks[0] = JToken.FromObject(new @@ -162,6 +164,26 @@ namespace ProxySU_Core.ViewModels.Developers xrayConfig.inbounds.Add(JToken.FromObject(trojanTcpBound)); } + if (parameters.Types.Contains(XrayType.VMESS_KCP)) + { + var kcpBound = GetBound("VMESS_KCP.json"); + kcpBound.port = VMESS_mKCP_Port; + kcpBound.settings.clients[0].id = parameters.UUID; + 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(XrayType.ShadowsocksAEAD)) + { + var ssBound = GetBound("Shadowsocks-AEAD.json"); + ssBound.port = 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, @@ -171,6 +193,11 @@ namespace ProxySU_Core.ViewModels.Developers }); } + private static dynamic GetBound(string name) + { + return LoadJsonObj(Path.Combine(ServerInboundsDir, name)); + } + private static dynamic LoadJsonObj(string path) { if (File.Exists(path)) diff --git a/ProxySU_Core/ViewModels/Developers/IParameters.cs b/ProxySU_Core/Models/Developers/IParameters.cs similarity index 68% rename from ProxySU_Core/ViewModels/Developers/IParameters.cs rename to ProxySU_Core/Models/Developers/IParameters.cs index c54bcbf..e532214 100644 --- a/ProxySU_Core/ViewModels/Developers/IParameters.cs +++ b/ProxySU_Core/Models/Developers/IParameters.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Text; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public interface IParameters { int Port { get; set; } string Domain { get; set; } + + List Types { get; set; } } } diff --git a/ProxySU_Core/ViewModels/Developers/Project.cs b/ProxySU_Core/Models/Developers/Project.cs similarity index 85% rename from ProxySU_Core/ViewModels/Developers/Project.cs rename to ProxySU_Core/Models/Developers/Project.cs index 61aba94..7f23b83 100644 --- a/ProxySU_Core/ViewModels/Developers/Project.cs +++ b/ProxySU_Core/Models/Developers/Project.cs @@ -1,4 +1,5 @@ using ProxySU_Core.Tools; +using ProxySU_Core.ViewModels; using Renci.SshNet; using System; using System.Collections.Generic; @@ -9,7 +10,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public enum CmdType { @@ -221,10 +222,7 @@ namespace ProxySU_Core.ViewModels.Developers } } - /// - /// 配置防火墙 - /// - protected void ConfigureFirewall() + protected void ClosePort(params int[] portList) { string cmd; @@ -239,43 +237,88 @@ namespace ProxySU_Core.ViewModels.Developers RunCmd("systemctl restart firewalld"); } - if (Parameters.Port == 443) + foreach (var port in portList) { - RunCmd("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - RunCmd("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - RunCmd("firewall-cmd --zone=public --add-port=80/udp --permanent"); - RunCmd("firewall-cmd --zone=public --add-port=443/udp --permanent"); - RunCmd("yes | firewall-cmd --reload"); + RunCmd($"firewall-cmd --zone=public --remove-port={port}/tcp --permanent"); + RunCmd($"firewall-cmd --zone=public --remove-port={port}/udp --permanent"); } - else - { - RunCmd($"firewall-cmd --zone=public --add-port={Parameters.Port}/tcp --permanent"); - RunCmd($"firewall-cmd --zone=public --add-port={Parameters.Port}/udp --permanent"); - RunCmd("yes | firewall-cmd --reload"); - } - return; + RunCmd("yes | firewall-cmd --reload"); } + else + { + cmd = RunCmd("command -v ufw"); + if (!string.IsNullOrEmpty(cmd)) + { + foreach (var port in portList) + { + RunCmd($"ufw delete allow {port}/tcp"); + RunCmd($"ufw delete allow {port}/udp"); + } + RunCmd("yes | ufw reload"); + } + } + } - cmd = RunCmd("command -v ufw"); + protected void OpenPort(params int[] portList) + { + + string cmd; + + cmd = RunCmd("command -v firewall-cmd"); if (!string.IsNullOrEmpty(cmd)) { - if (Parameters.Port == 443) + //有很奇怪的vps主机,在firewalld未运行时,端口是关闭的,无法访问。所以要先启动firewalld + //用于保证acme.sh申请证书成功 + cmd = RunCmd("firewall-cmd --state"); + if (cmd.Trim() != "running") { - RunCmd("ufw allow 80/tcp"); - RunCmd("ufw allow 443/tcp"); - RunCmd("ufw allow 80/udp"); - RunCmd("ufw allow 443/udp"); - RunCmd("yes | ufw reload"); + RunCmd("systemctl restart firewalld"); } - else + + foreach (var port in portList) { - RunCmd($"ufw allow {Parameters.Port}/tcp"); - RunCmd($"ufw allow {Parameters.Port}/udp"); + RunCmd($"firewall-cmd --zone=public --add-port={port}/tcp --permanent"); + RunCmd($"firewall-cmd --zone=public --add-port={port}/udp --permanent"); + } + RunCmd("yes | firewall-cmd --reload"); + } + else + { + cmd = RunCmd("command -v ufw"); + if (!string.IsNullOrEmpty(cmd)) + { + foreach (var port in portList) + { + RunCmd($"ufw allow {port}/tcp"); + RunCmd($"ufw allow {port}/udp"); + } RunCmd("yes | ufw reload"); } } } + /// + /// 配置防火墙 + /// + protected void ConfigureFirewall() + { + var portList = new List(); + portList.Add(80); + portList.Add(Parameters.Port); + + if (Parameters.Types.Contains(XrayType.ShadowsocksAEAD)) + { + portList.Add(ConfigBuilder.ShadowSocksPort); + } + + if (Parameters.Types.Contains(XrayType.VMESS_KCP)) + { + portList.Add(ConfigBuilder.VMESS_mKCP_Port); + } + + OpenPort(portList.ToArray()); + } + /// /// 配置同步时间差 /// @@ -356,29 +399,16 @@ namespace ProxySU_Core.ViewModels.Developers RunCmd("rm -rf caddy_install.sh"); RunCmd("curl -o caddy_install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/Caddy-Naive/caddy-naive-install.sh"); RunCmd("yes | bash caddy_install.sh"); + RunCmd("rm -rf caddy_install.sh"); + } - //if (CmdType == CmdType.Apt) - //{ - // RunCmd("sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https"); - // RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -"); - // RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list"); - // RunCmd(GetUpdateCmd()); - // RunCmd("sudo apt install caddy"); - //} - //else if (CmdType == CmdType.Dnf) - //{ - // RunCmd("echo y | dnf install 'dnf-command(copr)'"); - // RunCmd("echo y | dnf copr enable @caddy/caddy"); - // RunCmd(GetUpdateCmd()); - // RunCmd("dnf install caddy"); - //} - //else if (CmdType == CmdType.Yum) - //{ - // RunCmd("echo y | echo y | yum install yum-plugin-copr"); - // RunCmd("echo y | echo y | yum copr enable @caddy/caddy"); - // RunCmd(GetUpdateCmd()); - // RunCmd("yum install caddy"); - //} + protected void UninstallCaddy() + { + RunCmd("rm -rf caddy_install.sh"); + RunCmd("curl -o caddy_install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/Caddy-Naive/caddy-naive-install.sh"); + RunCmd("yes | bash caddy_install.sh uninstall"); + RunCmd("rm -rf caddy_install.sh"); + RunCmd("rm -rf /usr/share/caddy"); } diff --git a/ProxySU_Core/ViewModels/Developers/XrayProject.cs b/ProxySU_Core/Models/Developers/XrayProject.cs similarity index 72% rename from ProxySU_Core/ViewModels/Developers/XrayProject.cs rename to ProxySU_Core/Models/Developers/XrayProject.cs index 588e506..98a550e 100644 --- a/ProxySU_Core/ViewModels/Developers/XrayProject.cs +++ b/ProxySU_Core/Models/Developers/XrayProject.cs @@ -8,7 +8,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using ProxySU_Core.Models; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public class XrayProject : Project { @@ -29,52 +29,10 @@ namespace ProxySU_Core.ViewModels.Developers { } - public void InstallCert() - { - EnsureRootAuth(); - EnsureSystemEnv(); - this.InstallCertToXray(); - RunCmd("systemctl restart xray"); - WriteOutput("************ 安装证书完成 ************"); - } - - public void UploadWeb(Stream stream) - { - EnsureRootAuth(); - EnsureSystemEnv(); - if (!FileExists("/usr/share/caddy")) - { - RunCmd("mkdir /usr/share/caddy"); - } - RunCmd("rm -rf /usr/share/caddy/*"); - 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"); - UploadCaddyFile(useCustomWeb: true); - WriteOutput("************ 上传网站模板完成 ************"); - } - - public void UpdateXraySettings() - { - EnsureRootAuth(); - EnsureSystemEnv(); - var configJson = ConfigBuilder.BuildXrayConfig(Parameters); - var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); - RunCmd("rm -rf /usr/local/etc/xray/config.json"); - UploadFile(stream, "/usr/local/etc/xray/config.json"); - RunCmd("systemctl restart xray"); - WriteOutput("************ 更新Xray配置成功,更新配置不包含域名,如果域名更换请重新安装。 ************"); - } - - public void ReinstallCaddy() - { - EnsureRootAuth(); - EnsureSystemEnv(); - InstallCaddy(); - UploadCaddyFile(); - WriteOutput("************ 重装Caddy完成 ************"); - } + /// + /// 安装Xray + /// public override void Install() { try @@ -111,7 +69,7 @@ namespace ProxySU_Core.ViewModels.Developers ConfigureFirewall(); WriteOutput("防火墙配置完成"); - WriteOutput("同步系统和本地世间..."); + WriteOutput("同步系统和本地时间..."); SyncTimeDiff(); WriteOutput("时间同步完成"); @@ -138,10 +96,152 @@ namespace ProxySU_Core.ViewModels.Developers } catch (Exception ex) { - MessageBox.Show("安装终止," + ex.Message); + var errorLog = "安装终止," + ex.Message; + WriteOutput(errorLog); + MessageBox.Show(errorLog); } } + public void Uninstall() + { + EnsureRootAuth(); + WriteOutput("卸载Caddy"); + UninstallCaddy(); + WriteOutput("卸载Xray"); + UninstallXray(); + WriteOutput("卸载证书"); + UninstallAcme(); + WriteOutput("关闭端口"); + ClosePort(ConfigBuilder.ShadowSocksPort, ConfigBuilder.VLESS_mKCP_Port, ConfigBuilder.VMESS_mKCP_Port); + + WriteOutput("************ 卸载完成 ************"); + } + + /// + /// 更新xray内核 + /// + public void UpdateXrayCore() + { + EnsureRootAuth(); + EnsureSystemEnv(); + RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install"); + RunCmd("systemctl restart xray"); + WriteOutput("************ 更新xray内核完成 ************"); + } + + /// + /// 更新xray配置 + /// + public void UpdateXraySettings() + { + EnsureRootAuth(); + EnsureSystemEnv(); + ConfigureFirewall(); + var configJson = ConfigBuilder.BuildXrayConfig(Parameters); + var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); + RunCmd("rm -rf /usr/local/etc/xray/config.json"); + UploadFile(stream, "/usr/local/etc/xray/config.json"); + RunCmd("systemctl restart xray"); + WriteOutput("************ 更新Xray配置成功,更新配置不包含域名,如果域名更换请重新安装。 ************"); + } + + /// + /// 重装Caddy + /// + public void ReinstallCaddy() + { + EnsureRootAuth(); + EnsureSystemEnv(); + InstallCaddy(); + UploadCaddyFile(); + WriteOutput("************ 重装Caddy完成 ************"); + } + + /// + /// 安装证书 + /// + public void InstallCert() + { + EnsureRootAuth(); + EnsureSystemEnv(); + this.InstallCertToXray(); + RunCmd("systemctl restart xray"); + WriteOutput("************ 安装证书完成 ************"); + } + + /// + /// 上传证书 + /// + /// + /// + public void UploadCert(Stream stream) + { + EnsureRootAuth(); + EnsureSystemEnv(); + + // 转移旧文件 + var oldFileName = $"ssl_{DateTime.Now.Ticks}"; + RunCmd($"mv /usr/local/etc/xray/ssl /usr/local/etc/xray/{oldFileName}"); + + // 上传新文件 + RunCmd("mkdir /usr/local/etc/xray/ssl"); + UploadFile(stream, "/usr/local/etc/xray/ssl/ssl.zip"); + RunCmd("unzip /usr/local/etc/xray/ssl/ssl.zip -d /usr/local/etc/xray/ssl"); + + // 改名 + var crtFiles = RunCmd("find /usr/local/etc/xray/ssl/*.crt").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if (crtFiles.Length > 0) + { + RunCmd($"mv {crtFiles[0]} /usr/local/etc/xray/ssl/xray_ssl.crt"); + } + else + { + WriteOutput("************ 上传证书失败,请联系开发者 ************"); + RunCmd("rm -rf /usr/local/etc/xray/ssl"); + RunCmd($"mv /usr/local/etc/xray/ssl{oldFileName} /usr/local/etc/xray/ssl"); + WriteOutput("操作已回滚"); + return; + } + + var keyFiles = RunCmd("find /usr/local/etc/xray/ssl/*.key").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if (keyFiles.Length > 0) + { + RunCmd($"mv {keyFiles[0]} /usr/local/etc/xray/ssl/xray_ssl.key"); + } + else + { + WriteOutput("************ 上传证书失败,请联系开发者 ************"); + RunCmd("rm -rf /usr/local/etc/xray/ssl"); + RunCmd($"mv /usr/local/etc/xray/ssl{oldFileName} /usr/local/etc/xray/ssl"); + WriteOutput("操作已回滚"); + return; + } + + RunCmd("systemctl restart xray"); + WriteOutput("************ 上传证书完成 ************"); + } + + /// + /// 上传静态网站 + /// + /// + public void UploadWeb(Stream stream) + { + EnsureRootAuth(); + EnsureSystemEnv(); + if (!FileExists("/usr/share/caddy")) + { + RunCmd("mkdir /usr/share/caddy"); + } + RunCmd("rm -rf /usr/share/caddy/*"); + 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"); + UploadCaddyFile(useCustomWeb: true); + WriteOutput("************ 上传网站模板完成 ************"); + } + + private void UploadCaddyFile(bool useCustomWeb = false) { var configJson = ConfigBuilder.BuildCaddyConfig(Parameters, useCustomWeb); @@ -204,12 +304,24 @@ namespace ProxySU_Core.ViewModels.Developers } + private void UninstallXray() + { + RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ remove"); + } + + private void UninstallAcme() + { + RunCmd("acme.sh --uninstall"); + RunCmd("rm -r ~/.acme.sh"); + } + private void InstallXrayWithCert() { RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install"); if (!FileExists("/usr/local/bin/xray")) { + WriteOutput("Xray-Core安装失败,请联系开发者"); throw new Exception("Xray-Core安装失败,请联系开发者"); } @@ -251,6 +363,7 @@ namespace ProxySU_Core.ViewModels.Developers } else { + WriteOutput("安装 acme.sh 失败,请联系开发者!"); throw new Exception("安装 acme.sh 失败,请联系开发者!"); } @@ -275,6 +388,7 @@ namespace ProxySU_Core.ViewModels.Developers } else { + WriteOutput("申请证书失败,请联系开发者!"); throw new Exception("申请证书失败,请联系开发者!"); } @@ -288,6 +402,7 @@ namespace ProxySU_Core.ViewModels.Developers } else { + WriteOutput("安装证书失败,请联系开发者!"); throw new Exception("安装证书失败,请联系开发者!"); } diff --git a/ProxySU_Core/Models/ShareLink.cs b/ProxySU_Core/Models/ShareLink.cs new file mode 100644 index 0000000..13a33be --- /dev/null +++ b/ProxySU_Core/Models/ShareLink.cs @@ -0,0 +1,192 @@ +using Newtonsoft.Json; +using ProxySU_Core.Common; +using ProxySU_Core.Models.Developers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace ProxySU_Core.Models +{ + public class ShareLink + { + public static string Build(XrayType xrayType, XraySettings settings) + { + + switch (xrayType) + { + case XrayType.VLESS_TCP: + case XrayType.VLESS_TCP_XTLS: + case XrayType.VLESS_WS: + case XrayType.Trojan_TCP: + return BuildVlessShareLink(xrayType, settings); + case XrayType.VMESS_TCP: + case XrayType.VMESS_WS: + case XrayType.VMESS_KCP: + return BuildVmessShareLink(xrayType, settings); + case XrayType.ShadowsocksAEAD: + return BuildShadowSocksShareLink(settings); + default: + return string.Empty; + } + } + + private static string BuildShadowSocksShareLink(XraySettings settings) + { + var _method = settings.ShadowsocksMethod; + var _password = settings.ShadowsocksPassword; + var _server = settings.Domain; + var _port = ConfigBuilder.ShadowSocksPort; + + var base64URL = Base64.Encode($"{_method}:{_password}@{_server}:{_port}"); + return "ss://" + base64URL; + } + + private static string BuildVmessShareLink(XrayType xrayType, XraySettings settings) + { + var vmess = new Vmess + { + v = "2", + add = settings.Domain, + port = settings.Port.ToString(), + id = settings.UUID, + aid = "0", + net = "", + type = "none", + host = settings.Domain, + path = "", + tls = "tls", + ps = "", + }; + + switch (xrayType) + { + case XrayType.VMESS_TCP: + vmess.ps = "vmess-tcp-tls"; + vmess.net = "tcp"; + vmess.type = "http"; + vmess.path = settings.VMESS_TCP_Path; + break; + case XrayType.VMESS_WS: + vmess.ps = "vmess-ws-tls"; + vmess.net = "ws"; + vmess.type = "none"; + vmess.path = settings.VMESS_WS_Path; + break; + case XrayType.VMESS_KCP: + vmess.ps = "vmess-mKCP"; + vmess.port = ConfigBuilder.VMESS_mKCP_Port.ToString(); + vmess.net = "kcp"; + vmess.type = settings.VMESS_KCP_Type; + vmess.path = settings.VMESS_KCP_Seed; + vmess.tls = ""; + break; + default: + return string.Empty; + } + + var base64Url = Base64.Encode(JsonConvert.SerializeObject(vmess)); + return $"vmess://" + base64Url; + } + + private static string BuildVlessShareLink(XrayType xrayType, XraySettings settings) + { + var _protocol = string.Empty; + var _uuid = settings.UUID; + var _domain = settings.Domain; + var _port = settings.Port; + var _type = string.Empty; + var _encryption = string.Empty; + var _security = "tls"; + var _path = "/"; + var _host = settings.Domain; + var _descriptiveText = string.Empty; + + switch (xrayType) + { + case XrayType.VLESS_TCP: + _protocol = "vless"; + _type = "tcp"; + _encryption = "none"; + _descriptiveText = "vless-tcp-tls"; + break; + case XrayType.VLESS_TCP_XTLS: + _protocol = "vless"; + _type = "tcp"; + _security = "xtls"; + _encryption = "none"; + _descriptiveText = "vless-tcp-xtls"; + break; + case XrayType.VLESS_WS: + _protocol = "vless"; + _type = "ws"; + _path = settings.VLESS_WS_Path; + _encryption = "none"; + _descriptiveText = "vless-ws-tls"; + break; + case XrayType.VMESS_TCP: + _protocol = "vmess"; + _type = "tcp"; + _path = settings.VMESS_TCP_Path; + _encryption = "auto"; + _descriptiveText = "vmess-tcp-tls"; + break; + case XrayType.VMESS_WS: + _protocol = "vmess"; + _type = "ws"; + _path = settings.VMESS_WS_Path; + _encryption = "auto"; + _descriptiveText = "vmess-ws-tls"; + break; + case XrayType.Trojan_TCP: + _protocol = "trojan"; + _uuid = settings.TrojanPassword; + _descriptiveText = "trojan-tcp"; + break; + default: + throw new Exception("暂未实现的协议"); + } + + + string parametersURL = string.Empty; + if (xrayType != XrayType.Trojan_TCP) + { + // 4.3 传输层相关段 + parametersURL = $"?type={_type}&encryption={_encryption}&security={_security}&host={_host}&path={HttpUtility.UrlEncode(_path)}"; + + + // if mKCP + // if QUIC + + // 4.4 TLS 相关段 + if (xrayType == XrayType.VLESS_TCP_XTLS) + { + parametersURL += "&flow=xtls-rprx-direct"; + } + } + + + return $"{_protocol}://{HttpUtility.UrlEncode(_uuid)}@{_domain}:{_port}{parametersURL}#{HttpUtility.UrlEncode(_descriptiveText)}"; + } + + } + + + + class Vmess + { + public string v { get; set; } + public string ps { get; set; } + public string add { get; set; } + public string port { get; set; } + public string id { get; set; } + public string aid { get; set; } + public string net { get; set; } + public string type { get; set; } + public string host { get; set; } + public string path { get; set; } + public string tls { get; set; } + } +} diff --git a/ProxySU_Core/Models/XraySettings.cs b/ProxySU_Core/Models/XraySettings.cs index 1c125e2..fcea1fb 100644 --- a/ProxySU_Core/Models/XraySettings.cs +++ b/ProxySU_Core/Models/XraySettings.cs @@ -1,9 +1,12 @@ -using ProxySU_Core.ViewModels.Developers; +using Newtonsoft.Json; +using ProxySU_Core.Common; +using ProxySU_Core.Models.Developers; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; namespace ProxySU_Core.Models { @@ -15,12 +18,22 @@ namespace ProxySU_Core.Models var guid = Guid.NewGuid().ToString(); Port = 443; UUID = guid; - Types = new List { XrayType.VLESS_TCP_XTLS }; + Types = new List(); + VLESS_WS_Path = "/vlessws"; - VLESS_TCP_Path = "/vlesstcp"; + VLESS_H2_Path = "/vlessh2"; + VMESS_WS_Path = "/vmessws"; VMESS_TCP_Path = "/vmesstcp"; + VMESS_H2_Path = "/vmessh2"; + VMESS_KCP_Seed = guid; + VMESS_KCP_Type = "none"; + TrojanPassword = guid; + Trojan_WS_Path = "/trojanws"; + + ShadowsocksPassword = guid; + ShadowsocksMethod = "aes-128-gcm"; } /// @@ -33,16 +46,19 @@ namespace ProxySU_Core.Models /// public string UUID { get; set; } + #region vless /// /// vless ws路径 /// public string VLESS_WS_Path { get; set; } /// - /// vless tcp路径 + /// vless http2 path /// - public string VLESS_TCP_Path { get; set; } + public string VLESS_H2_Path { get; set; } + #endregion + #region vmess /// /// vmess ws路径 /// @@ -53,11 +69,47 @@ namespace ProxySU_Core.Models /// public string VMESS_TCP_Path { get; set; } + /// + /// vmess http2 path + /// + public string VMESS_H2_Path { get; set; } + + /// + /// vmess kcp seed + /// + public string VMESS_KCP_Seed { get; set; } + + /// + /// vmess kcp type + /// + public string VMESS_KCP_Type { get; set; } + #endregion + + #region Trojan /// /// trojan密码 /// public string TrojanPassword { get; set; } + /// + /// trojan ws path + /// + public string Trojan_WS_Path { get; set; } + #endregion + + #region ShadowsocksAEAD + /// + /// ss password + /// + public string ShadowsocksPassword { get; set; } + + /// + /// ss method + /// + public string ShadowsocksMethod { get; set; } + #endregion + + /// /// 域名 /// @@ -78,33 +130,55 @@ namespace ProxySU_Core.Models { switch (type) { - case XrayType.VLESS_TCP_TLS: - return VLESS_TCP_Path; - case XrayType.VLESS_TCP_XTLS: - return VLESS_TCP_Path; - case XrayType.VLESS_WS_TLS: + case XrayType.VLESS_WS: return VLESS_WS_Path; - case XrayType.VMESS_TCP_TLS: + case XrayType.VLESS_H2: + return VLESS_H2_Path; + + case XrayType.VMESS_TCP: return VMESS_TCP_Path; - case XrayType.VMESS_WS_TLS: + case XrayType.VMESS_WS: return VMESS_WS_Path; - case XrayType.Trojan_TCP_TLS: + case XrayType.Trojan_WS: + return Trojan_WS_Path; + + // no path + case XrayType.VLESS_TCP_XTLS: + case XrayType.VLESS_TCP: + case XrayType.VLESS_KCP: + case XrayType.VMESS_KCP: + case XrayType.Trojan_TCP: return string.Empty; default: return string.Empty; } } + } + public enum XrayType { - VLESS_TCP_TLS, - VLESS_TCP_XTLS, - VLESS_WS_TLS, + // 入口 + VLESS_TCP_XTLS = 100, - VMESS_TCP_TLS, - VMESS_WS_TLS, + // vless 101开头 + VLESS_TCP = 101, + VLESS_WS = 102, + VLESS_H2 = 103, + VLESS_KCP = 104, - Trojan_TCP_TLS + // vmess 201开头 + VMESS_TCP = 201, + VMESS_WS = 202, + VMESS_H2 = 203, + VMESS_KCP = 204, + + // trojan 301开头 + Trojan_TCP = 301, + Trojan_WS = 302, + + // ss + ShadowsocksAEAD = 401 } } diff --git a/ProxySU_Core/Properties/AssemblyInfo.cs b/ProxySU_Core/Properties/AssemblyInfo.cs index 82eaa44..52079d5 100644 --- a/ProxySU_Core/Properties/AssemblyInfo.cs +++ b/ProxySU_Core/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ using System.Windows; //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("3.1.0.0")] +[assembly: AssemblyFileVersion("3.1.0.0")] diff --git a/ProxySU_Core/ProxySU.ico b/ProxySU_Core/ProxySU.ico new file mode 100644 index 0000000..9d7a128 Binary files /dev/null and b/ProxySU_Core/ProxySU.ico differ diff --git a/ProxySU_Core/ProxySU_Core.csproj b/ProxySU_Core/ProxySU_Core.csproj index 270e96a..b9a1d8e 100644 --- a/ProxySU_Core/ProxySU_Core.csproj +++ b/ProxySU_Core/ProxySU_Core.csproj @@ -62,7 +62,10 @@ true - true + false + + + ProxySU.ico @@ -117,22 +120,26 @@ App.xaml Code + + + - - - - + + + + + @@ -148,6 +155,9 @@ TerminalWindow.xaml + + TextBoxWindow.xaml + @@ -233,19 +243,37 @@ PreserveNewest - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + PreserveNewest PreserveNewest - + PreserveNewest - + PreserveNewest - + + PreserveNewest + + + PreserveNewest + + PreserveNewest @@ -293,6 +321,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + @@ -309,6 +341,12 @@ false + + + + + + diff --git a/ProxySU_Core/Resources/ProxySU.ico b/ProxySU_Core/Resources/ProxySU.ico new file mode 100644 index 0000000..9d7a128 Binary files /dev/null and b/ProxySU_Core/Resources/ProxySU.ico differ diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/Shadowsocks-AEAD.json b/ProxySU_Core/Templates/xray/server/05_inbounds/Shadowsocks-AEAD.json new file mode 100644 index 0000000..e7179e5 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/Shadowsocks-AEAD.json @@ -0,0 +1,13 @@ +{ + "port": 12345, + "protocol": "shadowsocks", + "settings": { + "clients": [ + { + "password": "", + "method": "aes-128-gcm" + } + ], + "network": "tcp,udp" + } +} \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP.json similarity index 80% rename from ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json rename to ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP.json index 0aca4d2..5f17571 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "password": "", - "level": 0, - "email": "love@example.com" + "password": "" } ], "fallbacks": [ diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS.json new file mode 100644 index 0000000..51d725c --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS.json @@ -0,0 +1,26 @@ +{ + "port": 1320, + "listen": "127.0.0.1", + "protocol": "trojan", + "settings": { + "clients": [ + { + "password": "" + } + ], + "fallbacks": [ + { + "dest": 80 + } + ] + }, + + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "acceptProxyProtocol": true, + "path": "/trojanws" + } + } +} diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2.json new file mode 100644 index 0000000..a99e848 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2.json @@ -0,0 +1,19 @@ +{ + "port": 1234, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "decryption": "none", + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "h2", + "httpSettings": { + "path": "" + } + } +} \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_KCP.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_KCP.json new file mode 100644 index 0000000..8421a45 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_KCP.json @@ -0,0 +1,23 @@ +{ + "port": 3456, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "none" + }, + "seed": null + } + } +} diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json index 07a491a..eab8363 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json @@ -5,9 +5,7 @@ "clients": [ { "id": "", - "flow": "xtls-rprx-direct", - "level": 0, - "email": "love@example.com" + "flow": "xtls-rprx-direct" } ], "decryption": "none", @@ -17,6 +15,8 @@ "network": "tcp", "security": "xtls", "xtlsSettings": { + "allowInsecure": false, + "minVersion": "1.2", "alpn": [ "http/1.1" ], diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS.json similarity index 80% rename from ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json rename to ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS.json index 1b7d25c..0abf2e8 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "id": "", - "level": 0, - "email": "love@example.com" + "id": "" } ], "decryption": "none" diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2.json new file mode 100644 index 0000000..9957e76 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2.json @@ -0,0 +1,18 @@ +{ + "port": 1234, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "h2", + "httpSettings": { + "path": "" + } + } +} \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_KCP.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_KCP.json new file mode 100644 index 0000000..0c3ea2b --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_KCP.json @@ -0,0 +1,23 @@ +{ + "port": 3456, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "none" + }, + "seed": null + } + } +} diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP.json similarity index 84% rename from ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json rename to ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP.json index 2c569a8..b14181e 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "id": "", - "level": 0, - "email": "love@example.com" + "id": "" } ] }, diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS.json similarity index 79% rename from ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json rename to ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS.json index bbf6dbb..2e863a4 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "id": "", - "level": 0, - "email": "love@example.com" + "id": "" } ] }, diff --git a/ProxySU_Core/ViewModels/HostViewModel.cs b/ProxySU_Core/ViewModels/HostViewModel.cs index 1d06af0..04ceb62 100644 --- a/ProxySU_Core/ViewModels/HostViewModel.cs +++ b/ProxySU_Core/ViewModels/HostViewModel.cs @@ -15,6 +15,7 @@ namespace ProxySU_Core.ViewModels private readonly ICommand _selectKeyCommand; + public HostViewModel(Host host) { _selectKeyCommand = new BaseCommand(obj => OpenFileDialog(obj)); diff --git a/ProxySU_Core/ViewModels/IdValueViewModel.cs b/ProxySU_Core/ViewModels/IdValueViewModel.cs new file mode 100644 index 0000000..d7b8fbf --- /dev/null +++ b/ProxySU_Core/ViewModels/IdValueViewModel.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProxySU_Core.ViewModels +{ + public class IdValueViewModel + { + public IdValueViewModel(int id, string value) + { + Id = id; + Value = value; + } + + public int Id { get; set; } + + public string Value { get; set; } + } +} diff --git a/ProxySU_Core/ViewModels/RecordViewModel.cs b/ProxySU_Core/ViewModels/RecordViewModel.cs index 70f0b81..e2270be 100644 --- a/ProxySU_Core/ViewModels/RecordViewModel.cs +++ b/ProxySU_Core/ViewModels/RecordViewModel.cs @@ -11,10 +11,22 @@ namespace ProxySU_Core.ViewModels public class RecordViewModel : BaseViewModel { public Record record; + private bool _isChecked; public RecordViewModel(Record record) { this.record = record; + this._isChecked = false; + } + + public bool IsChecked + { + get => _isChecked; + set + { + _isChecked = value; + Notify("IsChecked"); + } } public Host Host diff --git a/ProxySU_Core/ViewModels/XraySettingsViewModel.cs b/ProxySU_Core/ViewModels/XraySettingsViewModel.cs index 1df53d4..eacf8ec 100644 --- a/ProxySU_Core/ViewModels/XraySettingsViewModel.cs +++ b/ProxySU_Core/ViewModels/XraySettingsViewModel.cs @@ -1,27 +1,36 @@ -using ProxySU_Core.Models; -using ProxySU_Core.ViewModels.Developers; +using Newtonsoft.Json; +using ProxySU_Core.Common; +using ProxySU_Core.Models; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; using System.Windows; +using System.Windows.Controls; namespace ProxySU_Core.ViewModels { - public class XraySettingsViewModel : BaseViewModel + public partial class XraySettingsViewModel : BaseViewModel { public XraySettings settings; public XraySettingsViewModel(XraySettings parameters) { this.settings = parameters; + Notify("VMESS_KCP_Type"); } public string UUID { get => settings.UUID; - set => settings.UUID = value; + set + { + settings.UUID = value; + Notify("UUID"); + } } public string Domain @@ -36,203 +45,226 @@ namespace ProxySU_Core.ViewModels set => settings.MaskDomain = value; } - public string VLESS_TCP_Path - { - get => settings.VLESS_TCP_Path; - set => settings.VLESS_TCP_Path = value; - } - - public string VLESS_WS_Path - { - get => settings.VLESS_WS_Path; - set => settings.VLESS_WS_Path = value; - } - - public string VMESS_TCP_Path - { - get => settings.VMESS_TCP_Path; - set => settings.VMESS_TCP_Path = value; - } - - public string VMESS_WS_Path - { - get => settings.VMESS_WS_Path; - set => settings.VMESS_WS_Path = value; - } - public string TrojanPassword { get => settings.TrojanPassword; set => settings.TrojanPassword = value; } - - public bool Checked_VLESS_TCP - { - get - { - return settings.Types.Contains(XrayType.VLESS_TCP_TLS); - } - set - { - if (value == true) - { - if (!settings.Types.Contains(XrayType.VLESS_TCP_TLS)) - settings.Types.Add(XrayType.VLESS_TCP_TLS); - - } - else - { - settings.Types.Remove(XrayType.VLESS_TCP_TLS); - } - Notify("Checked_VLESS_TCP"); - Notify("VLESS_TCP_Path_Visibility"); - } - } - - public bool Checked_VLESS_XTLS - { - get - { - return settings.Types.Contains(XrayType.VLESS_TCP_XTLS); - } - set - { - if (value == true) - { - if (!settings.Types.Contains(XrayType.VLESS_TCP_XTLS)) - settings.Types.Add(XrayType.VLESS_TCP_XTLS); - } - else - { - settings.Types.Remove(XrayType.VLESS_TCP_XTLS); - } - Notify("Checked_VLESS_XTLS"); - } - } - - public bool Checked_VLESS_WS - { - get - { - return settings.Types.Contains(XrayType.VLESS_WS_TLS); - } - set - { - if (value == true) - { - if (!settings.Types.Contains(XrayType.VLESS_WS_TLS)) - settings.Types.Add(XrayType.VLESS_WS_TLS); - } - else - { - settings.Types.Remove(XrayType.VLESS_WS_TLS); - } - Notify("Checked_VLESS_WS"); - Notify("VLESS_WS_Path_Visibility"); - } - } - - public bool Checked_VMESS_TCP - { - get - { - return settings.Types.Contains(XrayType.VMESS_TCP_TLS); - } - set - { - if (value == true) - { - if (!settings.Types.Contains(XrayType.VMESS_TCP_TLS)) - settings.Types.Add(XrayType.VMESS_TCP_TLS); - } - else - { - settings.Types.Remove(XrayType.VMESS_TCP_TLS); - } - Notify("Checked_VMESS_TCP"); - Notify("VMESS_TCP_Path_Visibility"); - } - } - - public bool Checked_VMESS_WS - { - get - { - return settings.Types.Contains(XrayType.VMESS_WS_TLS); - } - set - { - if (value == true) - { - if (!settings.Types.Contains(XrayType.VMESS_WS_TLS)) - settings.Types.Add(XrayType.VMESS_WS_TLS); - } - else - { - settings.Types.Remove(XrayType.VMESS_WS_TLS); - } - Notify("Checked_VMESS_WS"); - Notify("VMESS_WS_Path_Visibility"); - } - } - public bool Checked_Trojan_TCP { get { - return settings.Types.Contains(XrayType.Trojan_TCP_TLS); + return settings.Types.Contains(XrayType.Trojan_TCP); } set { if (value == true) { - if (!settings.Types.Contains(XrayType.Trojan_TCP_TLS)) - settings.Types.Add(XrayType.Trojan_TCP_TLS); + if (!settings.Types.Contains(XrayType.Trojan_TCP)) + settings.Types.Add(XrayType.Trojan_TCP); } else { - settings.Types.Remove(XrayType.Trojan_TCP_TLS); + settings.Types.Remove(XrayType.Trojan_TCP); } Notify("Checked_Trojan_TCP"); - Notify("Trojan_TCP_Pwd_Visibility"); } } + public string Trojan_TCP_ShareLink + { + get => ShareLink.Build(XrayType.Trojan_TCP, settings); + } - public Visibility VLESS_TCP_Path_Visibility + private List _ssMethods = new List { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305" }; + public List ShadowSocksMethods => _ssMethods; + public bool CheckedShadowSocks { - get + + get => settings.Types.Contains(XrayType.ShadowsocksAEAD); + set { - return Checked_VLESS_TCP ? Visibility.Visible : Visibility.Hidden; + CheckBoxChanged(value, XrayType.ShadowsocksAEAD); + Notify("CheckedShadowSocks"); } } - public Visibility VLESS_WS_Path_Visibility + public string ShadowSocksPassword { - get + get => settings.ShadowsocksPassword; + set => settings.ShadowsocksPassword = value; + } + public string ShadowSocksMethod + { + get => settings.ShadowsocksMethod; + set { - return Checked_VLESS_WS ? Visibility.Visible : Visibility.Hidden; + var namespaceStr = typeof(ComboBoxItem).FullName + ":"; + var trimValue = value.Replace(namespaceStr, ""); + trimValue = trimValue.Trim(); + settings.ShadowsocksMethod = trimValue; + Notify("ShadowSocksMethod"); } } - public Visibility VMESS_TCP_Path_Visibility + public string ShadowSocksShareLink { - get - { - return Checked_VMESS_TCP ? Visibility.Visible : Visibility.Hidden; - } + get => ShareLink.Build(XrayType.ShadowsocksAEAD, settings); } - public Visibility VMESS_WS_Path_Visibility + + + private void CheckBoxChanged(bool value, XrayType type) { - get + if (value == true) { - return Checked_VMESS_WS ? Visibility.Visible : Visibility.Hidden; + if (!settings.Types.Contains(type)) + { + settings.Types.Add(type); + } } - } - public Visibility Trojan_TCP_Pwd_Visibility - { - get + else { - return Checked_Trojan_TCP ? Visibility.Visible : Visibility.Hidden; + settings.Types.RemoveAll(x => x == type); } } } + + public partial class XraySettingsViewModel + { + // vmess tcp + public bool Checked_VMESS_TCP + { + get => settings.Types.Contains(XrayType.VMESS_TCP); + set + { + CheckBoxChanged(value, XrayType.VMESS_TCP); + Notify("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(XrayType.VMESS_TCP, settings); + } + + // vmess ws + public bool Checked_VMESS_WS + { + get => settings.Types.Contains(XrayType.VMESS_WS); + set + { + CheckBoxChanged(value, XrayType.VMESS_WS); + Notify("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(XrayType.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; + Notify("VMESS_KCP_Type"); + } + } + public bool Checked_VMESS_KCP + { + get => settings.Types.Contains(XrayType.VMESS_KCP); + set + { + CheckBoxChanged(value, XrayType.VMESS_KCP); + Notify("Checked_VMESS_KCP"); + } + } + public string VMESS_KCP_ShareLink + { + get => ShareLink.Build(XrayType.VMESS_KCP, settings); + } + + + private List _kcpTypes = new List { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", }; + public List KcpTypes => _kcpTypes; + } + + + public partial class XraySettingsViewModel + { + + // vless xtls + public bool Checked_VLESS_TCP_XTLS + { + get => settings.Types.Contains(XrayType.VLESS_TCP_XTLS); + set + { + CheckBoxChanged(value, XrayType.VLESS_TCP_XTLS); + Notify("Checked_VLESS_XTLS"); + } + } + public string VLESS_TCP_XTLS_ShareLink + { + get => ShareLink.Build(XrayType.VLESS_TCP_XTLS, settings); + } + + + // vless tcp + public bool Checked_VLESS_TCP + { + get => settings.Types.Contains(XrayType.VLESS_TCP); + set + { + CheckBoxChanged(value, XrayType.VLESS_TCP); + Notify("Checked_VLESS_TCP"); + } + } + public string VLESS_TCP_ShareLink + { + get => ShareLink.Build(XrayType.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(XrayType.VLESS_WS); + } + set + { + CheckBoxChanged(value, XrayType.VLESS_WS); + Notify("Checked_VLESS_WS"); + } + } + public string VLESS_WS_ShareLink + { + get => ShareLink.Build(XrayType.VLESS_WS, settings); + } + + } + } diff --git a/ProxySU_Core/Views/ClientInfoWindow.xaml b/ProxySU_Core/Views/ClientInfoWindow.xaml index 46e393c..18ba595 100644 --- a/ProxySU_Core/Views/ClientInfoWindow.xaml +++ b/ProxySU_Core/Views/ClientInfoWindow.xaml @@ -5,8 +5,11 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls" xmlns:local="clr-namespace:ProxySU_Core.Views" + xmlns:dev="clr-namespace:ProxySU_Core.Models.Developers" mc:Ignorable="d" - Title="查看配置" Height="450" Width="800"> + Title="查看配置" Height="500" Width="800"> + + diff --git a/ProxySU_Core/Views/MainWindow.xaml b/ProxySU_Core/Views/MainWindow.xaml index 9fe598d..cfbdef0 100644 --- a/ProxySU_Core/Views/MainWindow.xaml +++ b/ProxySU_Core/Views/MainWindow.xaml @@ -26,6 +26,7 @@ @@ -54,9 +55,21 @@ diff --git a/ProxySU_Core/Views/RecordEditorWindow.xaml.cs b/ProxySU_Core/Views/RecordEditorWindow.xaml.cs index d62e097..4a0c19f 100644 --- a/ProxySU_Core/Views/RecordEditorWindow.xaml.cs +++ b/ProxySU_Core/Views/RecordEditorWindow.xaml.cs @@ -48,5 +48,11 @@ namespace ProxySU_Core.Views DialogResult = true; Close(); } + + public void RandomUuid(object sender, RoutedEventArgs e) + { + Settings.UUID = Guid.NewGuid().ToString(); + } + } } diff --git a/ProxySU_Core/Views/TerminalWindow.xaml b/ProxySU_Core/Views/TerminalWindow.xaml index 1e9d1f9..ff0576b 100644 --- a/ProxySU_Core/Views/TerminalWindow.xaml +++ b/ProxySU_Core/Views/TerminalWindow.xaml @@ -15,47 +15,80 @@ FontSize="14" FontFamily="Consolas" x:Name="OutputTextBox" - Height="320" + Height="260" Text="{Binding Path=OutputText}" /> + + + +