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 05b8fd7..9ae9d06 100644
--- a/ProxySU/ProxySU.csproj
+++ b/ProxySU/ProxySU.csproj
@@ -71,8 +71,8 @@
..\qrcoder\net40\QRCoder.dll
-
- ..\ssh.net\net40\Renci.SshNet.dll
+
+ ..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll
@@ -181,6 +181,10 @@
ResXFileCodeGenerator
Resources.Designer.cs
+
+ .editorconfig
+
+
SettingsSingleFileGenerator
Settings.Designer.cs
diff --git a/ProxySU/packages.config b/ProxySU/packages.config
index 6161026..cd7f780 100644
--- a/ProxySU/packages.config
+++ b/ProxySU/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/ProxySU_Core/App.config b/ProxySU_Core/App.config
index 731f6de..9626b5e 100644
--- a/ProxySU_Core/App.config
+++ b/ProxySU_Core/App.config
@@ -1,6 +1,14 @@
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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/ViewModels/Developers/ConfigBuilder.cs b/ProxySU_Core/Models/Developers/ConfigBuilder.cs
similarity index 75%
rename from ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs
rename to ProxySU_Core/Models/Developers/ConfigBuilder.cs
index 8946378..78bb2d8 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,16 @@ 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 static dynamic LoadXrayConfig()
@@ -48,7 +55,7 @@ namespace ProxySU_Core.ViewModels.Developers
return new
{
log = logObj["log"],
- api = apiObj["api"],
+ //api = apiObj["api"], api不能为空
dns = dnsObj["dns"],
routing = routingObj["routing"],
policy = policyObj["policy"],
@@ -60,17 +67,26 @@ namespace ProxySU_Core.ViewModels.Developers
};
}
- public static string BuildCaddyConfig(XraySettings parameters)
+ public static string BuildCaddyConfig(XraySettings parameters, bool useCustomWeb = false)
{
var caddyStr = File.ReadAllText(Path.Combine(CaddyFileDir, "base.caddyfile"));
- caddyStr.Replace("##domain##", parameters.Domain);
- if (!string.IsNullOrEmpty(parameters.MaskDomain))
+ caddyStr = caddyStr.Replace("##domain##", parameters.Domain);
+ if (!useCustomWeb && !string.IsNullOrEmpty(parameters.MaskDomain))
{
- caddyStr.Replace("##server_proxy##", $"reverse_proxy http://{parameters.MaskDomain} {{ header_up Host {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.Replace("##server_proxy##", "");
+ caddyStr = caddyStr.Replace("##reverse_proxy##", "");
}
return caddyStr;
@@ -83,20 +99,13 @@ namespace ProxySU_Core.ViewModels.Developers
baseBound.port = parameters.Port;
baseBound.settings.fallbacks.Add(JToken.FromObject(new
{
- dest = 80,
- xver = 1,
+ dest = 80
}));
xrayConfig.inbounds.Add(baseBound);
-
- if (parameters.Types.Contains(XrayType.VLESS_TCP_XTLS))
- {
- baseBound.settings.clients[0].id = parameters.UUID;
- }
+ 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"));
wsInbound.port = VLESS_WS_Port;
wsInbound.settings.clients[0].id = parameters.UUID;
@@ -104,12 +113,30 @@ namespace ProxySU_Core.ViewModels.Developers
baseBound.settings.fallbacks.Add(JToken.FromObject(new
{
dest = VLESS_WS_Port,
- path = parameters.VLESS_WS_Path,
- xver = 1,
+ path = parameters.VLESS_WS_Path
}));
xrayConfig.inbounds.Add(JToken.FromObject(wsInbound));
}
+ if (parameters.Types.Contains(XrayType.VLESS_H2_TLS))
+ {
+ var h2Inbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_HTTP2_TLS.json"));
+ h2Inbound.port = VLESS_H2_Port;
+ h2Inbound.settings.clients[0].id = parameters.UUID;
+ h2Inbound.streamSettings.httpSettings.path = parameters.VLESS_H2_Path;
+ baseBound.settings.fallbacks.Add(JToken.FromObject(new
+ {
+ dest = VLESS_H2_Port,
+ path = parameters.VLESS_H2_Path
+ }));
+ xrayConfig.inbounds.Add(JToken.FromObject(h2Inbound));
+ }
+
+ if (parameters.Types.Contains(XrayType.VLESS_mKCP_Speed))
+ {
+ var kcpInbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_mKCP"));
+ }
+
if (parameters.Types.Contains(XrayType.VMESS_TCP_TLS))
{
var mtcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_TCP_TLS.json"));
@@ -140,6 +167,10 @@ namespace ProxySU_Core.ViewModels.Developers
xrayConfig.inbounds.Add(JToken.FromObject(mwsBound));
}
+ if (parameters.Types.Contains(XrayType.VMESS_H2_TLS)) { }
+
+ if (parameters.Types.Contains(XrayType.VMESS_mKCP_Speed)) { }
+
if (parameters.Types.Contains(XrayType.Trojan_TCP_TLS))
{
var trojanTcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "Trojan_TCP_TLS.json"));
@@ -153,6 +184,8 @@ namespace ProxySU_Core.ViewModels.Developers
xrayConfig.inbounds.Add(JToken.FromObject(trojanTcpBound));
}
+ if (parameters.Types.Contains(XrayType.Trojan_WS_TLS)) { }
+
return JsonConvert.SerializeObject(
xrayConfig,
Formatting.Indented,
diff --git a/ProxySU_Core/ViewModels/Developers/IParameters.cs b/ProxySU_Core/Models/Developers/IParameters.cs
similarity index 80%
rename from ProxySU_Core/ViewModels/Developers/IParameters.cs
rename to ProxySU_Core/Models/Developers/IParameters.cs
index c54bcbf..11554c0 100644
--- a/ProxySU_Core/ViewModels/Developers/IParameters.cs
+++ b/ProxySU_Core/Models/Developers/IParameters.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
-namespace ProxySU_Core.ViewModels.Developers
+namespace ProxySU_Core.Models.Developers
{
public interface IParameters
{
diff --git a/ProxySU_Core/ViewModels/Developers/Project.cs b/ProxySU_Core/Models/Developers/Project.cs
similarity index 86%
rename from ProxySU_Core/ViewModels/Developers/Project.cs
rename to ProxySU_Core/Models/Developers/Project.cs
index 5c24a10..c0bc53a 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
{
@@ -156,8 +157,14 @@ namespace ProxySU_Core.ViewModels.Developers
///
protected void ConfigureSoftware()
{
+ string cmd = RunCmd("command -v sudo");
+ if (string.IsNullOrEmpty(cmd))
+ {
+ RunCmd(GetInstallCmd("sudo"));
+ }
+
// 安装curl,wget,unzip
- string cmd = RunCmd("command -v curl");
+ cmd = RunCmd("command -v curl");
if (string.IsNullOrEmpty(cmd))
{
RunCmd(GetInstallCmd("curl"));
@@ -306,9 +313,7 @@ namespace ProxySU_Core.ViewModels.Developers
var cmd = $"dig @resolver1.opendns.com AAAA {Parameters.Domain} +short -6 {cmdFilter}";
var result = RunCmd(cmd).TrimEnd('\r', '\n');
- if (result != IPv6)
- {
- }
+ if (result == IPv6) return;
}
else
@@ -317,11 +322,19 @@ namespace ProxySU_Core.ViewModels.Developers
var cmd = $"dig @resolver1.opendns.com A {Parameters.Domain} +short -4 {cmdFilter}";
var result = RunCmd(cmd).TrimEnd('\r', '\n');
- if (result != IPv4)
- {
- throw new Exception("域名未能解析到服务器IP,请检查域名配置");
- }
+ if (result == IPv4) return;
+
}
+
+
+ var btnResult = MessageBox.Show(
+ $"{Parameters.Domain}未能正常解析到服务器的IP,如果您使用了CDN请忽略,是否继续安装?", "提示", MessageBoxButton.YesNo);
+
+ if (btnResult == MessageBoxResult.No)
+ {
+ throw new Exception($"域名解析失败,安装停止!");
+ }
+
}
///
@@ -341,26 +354,32 @@ namespace ProxySU_Core.ViewModels.Developers
///
protected void InstallCaddy()
{
- 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("sudo apt update");
- RunCmd("sudo apt install caddy");
- }
- else if (CmdType == CmdType.Dnf)
- {
- RunCmd("dnf install 'dnf-command(copr)'");
- RunCmd("dnf copr enable @caddy/caddy");
- RunCmd("dnf install caddy");
- }
- else if (CmdType == CmdType.Yum)
- {
- RunCmd("yum install yum-plugin-copr");
- RunCmd("yum copr enable @caddy/caddy");
- RunCmd("yum install caddy");
- }
+ 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");
+
+ //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");
+ //}
}
@@ -399,7 +418,7 @@ namespace ProxySU_Core.ViewModels.Developers
{
if (force)
{
- var btnResult = MessageBox.Show("80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?", "提示", MessageBoxButton.YesNo);
+ var btnResult = MessageBox.Show($"{port}端口被占用,将强制停止占用{port}端口的程序?", "提示", MessageBoxButton.YesNo);
if (btnResult == MessageBoxResult.No)
{
throw new Exception($"{port}端口被占用,安装停止!");
@@ -435,7 +454,7 @@ namespace ProxySU_Core.ViewModels.Developers
}
}
- private void SetNat64()
+ protected void SetNat64()
{
var dns64List = FilterFastestIP();
if (dns64List.Count == 0)
@@ -456,7 +475,7 @@ namespace ProxySU_Core.ViewModels.Developers
}
}
- private void RemoveNat64()
+ protected void RemoveNat64()
{
RunCmd("rm /etc/resolv.conf");
RunCmd("mv /etc/resolv.conf.proxysu /etc/resolv.conf");
@@ -518,7 +537,7 @@ namespace ProxySU_Core.ViewModels.Developers
{
if (CmdType == CmdType.Apt)
{
- return "apt-get update ";
+ return "apt-get update";
}
else if (CmdType == CmdType.Dnf)
{
@@ -541,15 +560,15 @@ namespace ProxySU_Core.ViewModels.Developers
{
if (CmdType == CmdType.Apt)
{
- return "apt-get install " + soft;
+ return "echo y | apt-get install " + soft;
}
else if (CmdType == CmdType.Dnf)
{
- return "dnf -y install " + soft;
+ return "echo y | dnf -y install " + soft;
}
else if (CmdType == CmdType.Yum)
{
- return "yum -y install " + soft;
+ return "echo y | yum -y install " + soft;
}
throw new Exception("未识别的系统");
diff --git a/ProxySU_Core/Models/Developers/XrayProject.cs b/ProxySU_Core/Models/Developers/XrayProject.cs
new file mode 100644
index 0000000..4c65360
--- /dev/null
+++ b/ProxySU_Core/Models/Developers/XrayProject.cs
@@ -0,0 +1,403 @@
+using Renci.SshNet;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Windows;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using ProxySU_Core.Models;
+
+namespace ProxySU_Core.Models.Developers
+{
+ public class XrayProject : Project
+ {
+
+ private const string ServerLogDir = @"Templates\xray\server\00_log";
+ private const string ServerApiDir = @"Templates\xray\server\01_api";
+ private const string ServerDnsDir = @"Templates\xray\server\02_dns";
+ private const string ServerRoutingDir = @"Templates\xray\server\03_routing";
+ private const string ServerPolicyDir = @"Templates\xray\server\04_policy";
+ private const string ServerInboundsDir = @"Templates\xray\server\05_inbounds";
+ private const string ServerOutboundsDir = @"Templates\xray\server\06_outbounds";
+ private const string ServerTransportDir = @"Templates\xray\server\07_transport";
+ private const string ServerStatsDir = @"Templates\xray\server\08_stats";
+ private const string ServerReverseDir = @"Templates\xray\server\09_reverse";
+ private const string CaddyFileDir = @"Templates\xray\caddy";
+
+ public XrayProject(SshClient sshClient, XraySettings parameters, Action writeOutput) : base(sshClient, parameters, writeOutput)
+ {
+ }
+
+
+ ///
+ /// 安装Xray
+ ///
+ public override void Install()
+ {
+ try
+ {
+ EnsureRootAuth();
+
+ if (FileExists("/usr/local/bin/xray"))
+ {
+ var btnResult = MessageBox.Show("已经安装Xray,是否需要重装?", "提示", MessageBoxButton.YesNo);
+ if (btnResult == MessageBoxResult.No)
+ {
+ MessageBox.Show("安装终止", "提示");
+ return;
+ }
+ }
+
+ WriteOutput("检测安装系统环境...");
+ EnsureSystemEnv();
+ WriteOutput("检测安装系统环境完成");
+
+ WriteOutput("配置服务器端口...");
+ ConfigurePort();
+ WriteOutput("端口配置完成");
+
+ WriteOutput("安装必要的系统工具...");
+ ConfigureSoftware();
+ WriteOutput("系统工具安装完成");
+
+ WriteOutput("检测IP6...");
+ ConfigureIPv6();
+ WriteOutput("检测IP6完成");
+
+ WriteOutput("配置防火墙...");
+ ConfigureFirewall();
+ WriteOutput("防火墙配置完成");
+
+ WriteOutput("同步系统和本地世间...");
+ SyncTimeDiff();
+ WriteOutput("时间同步完成");
+
+ WriteOutput("检测域名是否绑定本机IP...");
+ ValidateDomain();
+ WriteOutput("域名检测完成");
+
+ WriteOutput("安装Xray-Core...");
+ InstallXrayWithCert();
+ WriteOutput("Xray-Core安装完成");
+
+ WriteOutput("安装Caddy...");
+ InstallCaddy();
+ WriteOutput("Caddy安装完成");
+
+ WriteOutput("启动BBR");
+ EnableBBR();
+ WriteOutput("BBR启动成功");
+
+ UploadCaddyFile();
+ WriteOutput("************");
+ WriteOutput("安装完成,尽情享用吧......");
+ WriteOutput("************");
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("安装终止," + ex.Message);
+ }
+ }
+
+ ///
+ /// 更新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();
+ 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);
+ var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson));
+ RunCmd("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.back");
+ UploadFile(stream, "/etc/caddy/Caddyfile");
+ RunCmd("systemctl restart caddy");
+ }
+
+ private void EnableBBR()
+ {
+ var osVersion = RunCmd("uname -r");
+ var canInstallBBR = CheckKernelVersionBBR(osVersion.Split('-')[0]);
+
+ var bbrInfo = RunCmd("sysctl net.ipv4.tcp_congestion_control | grep bbr");
+ var installed = bbrInfo.Contains("bbr");
+ if (canInstallBBR && !installed)
+ {
+ RunCmd(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'");
+ RunCmd(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'");
+ RunCmd(@"sysctl -p");
+
+ if (OnlyIpv6)
+ {
+ RemoveNat64();
+ }
+ }
+
+ if (!canInstallBBR)
+ {
+ WriteOutput("****** 系统不满足启用BBR条件,启动失败。 ******");
+ }
+
+ }
+
+ private bool CheckKernelVersionBBR(string kernelVer)
+ {
+ string[] linuxKernelCompared = kernelVer.Split('.');
+ if (int.Parse(linuxKernelCompared[0]) > 4)
+ {
+ return true;
+ }
+ else if (int.Parse(linuxKernelCompared[0]) < 4)
+ {
+ return false;
+ }
+ else if (int.Parse(linuxKernelCompared[0]) == 4)
+ {
+ if (int.Parse(linuxKernelCompared[1]) >= 9)
+ {
+ return true;
+ }
+ else if (int.Parse(linuxKernelCompared[1]) < 9)
+ {
+ return false;
+ }
+
+ }
+ return false;
+
+ }
+
+ 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"))
+ {
+ throw new Exception("Xray-Core安装失败,请联系开发者");
+ }
+
+ RunCmd($"sed -i 's/User=nobody/User=root/g' /etc/systemd/system/xray.service");
+ RunCmd($"sed -i 's/CapabilityBoundingSet=/#CapabilityBoundingSet=/g' /etc/systemd/system/xray.service");
+ RunCmd($"sed -i 's/AmbientCapabilities=/#AmbientCapabilities=/g' /etc/systemd/system/xray.service");
+ RunCmd($"systemctl daemon-reload");
+
+ if (FileExists("/usr/local/etc/xray/config.json"))
+ {
+ RunCmd(@"mv /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.1");
+ }
+
+ WriteOutput("安装TLS证书");
+ InstallCertToXray();
+ WriteOutput("TLS证书安装完成");
+
+
+ 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");
+ }
+
+ private void InstallCertToXray()
+ {
+ // 安装依赖
+ RunCmd(GetInstallCmd("socat"));
+
+ // 解决搬瓦工CentOS缺少问题
+ RunCmd(GetInstallCmd("automake autoconf libtool"));
+
+ // 安装Acme
+ var result = RunCmd($"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m {GetRandomEmail()}");
+ if (result.Contains("Install success"))
+ {
+ WriteOutput("安装 acme.sh 成功");
+ }
+ else
+ {
+ throw new Exception("安装 acme.sh 失败,请联系开发者!");
+ }
+
+ RunCmd("cd ~/.acme.sh/");
+ RunCmd("alias acme.sh=~/.acme.sh/acme.sh");
+
+ // 申请证书
+ if (OnlyIpv6)
+ {
+ var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain} --listen-v6";
+ result = RunCmd(cmd);
+ }
+ else
+ {
+ var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain}";
+ result = RunCmd(cmd);
+ }
+
+ if (result.Contains("Cert success"))
+ {
+ WriteOutput("申请证书成功");
+ }
+ else
+ {
+ throw new Exception("申请证书失败,请联系开发者!");
+ }
+
+ // 安装证书到xray
+ RunCmd("mkdir -p /usr/local/etc/xray/ssl");
+ RunCmd($"/root/.acme.sh/acme.sh --installcert -d {Parameters.Domain} --certpath /usr/local/etc/xray/ssl/xray_ssl.crt --keypath /usr/local/etc/xray/ssl/xray_ssl.key --capath /usr/local/etc/xray/ssl/xray_ssl.crt");
+ result = RunCmd(@"if [ ! -f ""/usr/local/etc/xray/ssl/xray_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1");
+ if (result.Contains("1"))
+ {
+ WriteOutput("安装证书成功");
+ }
+ else
+ {
+ throw new Exception("安装证书失败,请联系开发者!");
+ }
+
+ RunCmd(@"chmod 755 /usr/local/etc/xray/ssl");
+ }
+
+ private string GetRandomEmail()
+ {
+ Random r = new Random();
+ var num = r.Next(200000000, 900000000);
+ return $"{num}@qq.com";
+ }
+
+ private int GetRandomPort()
+ {
+ var random = new Random();
+ return random.Next(10001, 60000);
+ }
+
+ private dynamic LoadJsonObj(string path)
+ {
+ if (File.Exists(path))
+ {
+ var jsonStr = File.ReadAllText(path, Encoding.UTF8);
+ return JsonConvert.DeserializeObject(jsonStr);
+ }
+ return null;
+ }
+
+ }
+}
diff --git a/ProxySU_Core/Models/ShareLink.cs b/ProxySU_Core/Models/ShareLink.cs
new file mode 100644
index 0000000..dec2823
--- /dev/null
+++ b/ProxySU_Core/Models/ShareLink.cs
@@ -0,0 +1,170 @@
+using Newtonsoft.Json;
+using ProxySU_Core.Common;
+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_TLS:
+ case XrayType.VLESS_TCP_XTLS:
+ case XrayType.VLESS_WS_TLS:
+ case XrayType.Trojan_TCP_TLS:
+ return BuildVlessShareLink(xrayType, settings);
+ case XrayType.VMESS_TCP_TLS:
+ case XrayType.VMESS_WS_TLS:
+ return BuildVmessShareLink(xrayType, settings);
+ default:
+ return string.Empty;
+ }
+ }
+
+
+ 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_TLS:
+ vmess.ps = "vmess-tcp-tls";
+ vmess.net = "tcp";
+ vmess.type = "http";
+ vmess.path = settings.VMESS_TCP_Path;
+ break;
+ case XrayType.VMESS_WS_TLS:
+ vmess.ps = "vmess-ws-tls";
+ vmess.net = "ws";
+ vmess.type = "none";
+ vmess.path = settings.VMESS_WS_Path;
+ 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_TLS:
+ _protocol = "vless";
+ _type = "tcp";
+ _path = settings.VLESS_TCP_Path;
+ _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_TLS:
+ _protocol = "vless";
+ _type = "ws";
+ _path = settings.VLESS_WS_Path;
+ _encryption = "none";
+ _descriptiveText = "vless-ws-tls";
+ break;
+ case XrayType.VMESS_TCP_TLS:
+ _protocol = "vmess";
+ _type = "tcp";
+ _path = settings.VMESS_TCP_Path;
+ _encryption = "auto";
+ _descriptiveText = "vmess-tcp-tls";
+ break;
+ case XrayType.VMESS_WS_TLS:
+ _protocol = "vmess";
+ _type = "ws";
+ _path = settings.VMESS_WS_Path;
+ _encryption = "auto";
+ _descriptiveText = "vmess-ws-tls";
+ break;
+ case XrayType.Trojan_TCP_TLS:
+ _protocol = "trojan";
+ _descriptiveText = "trojan-tcp";
+ break;
+ default:
+ throw new Exception("暂未实现的协议");
+ }
+
+
+ string parametersURL = string.Empty;
+ if (xrayType != XrayType.Trojan_TCP_TLS)
+ {
+ // 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 9e08eb2..56dbda9 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
{
@@ -12,14 +15,15 @@ namespace ProxySU_Core.Models
public XraySettings()
{
+ var guid = Guid.NewGuid().ToString();
Port = 443;
- UUID = Guid.NewGuid().ToString();
- Types = new List { XrayType.VLESS_TCP_XTLS };
+ UUID = guid;
+ Types = new List();
VLESS_WS_Path = "/vlessws";
VLESS_TCP_Path = "/vlesstcp";
VMESS_WS_Path = "/vmessws";
VMESS_TCP_Path = "/vmesstcp";
- TrojanPassword = Guid.NewGuid().ToString();
+ TrojanPassword = guid;
}
///
@@ -42,6 +46,16 @@ namespace ProxySU_Core.Models
///
public string VLESS_TCP_Path { get; set; }
+ ///
+ /// vless http2 path
+ ///
+ public string VLESS_H2_Path { get; set; }
+
+ ///
+ /// vless mKcp seed
+ ///
+ public string VLESS_mKCP_Seed { get; set; }
+
///
/// vmess ws路径
///
@@ -52,11 +66,26 @@ namespace ProxySU_Core.Models
///
public string VMESS_TCP_Path { get; set; }
+ ///
+ /// vmess http2 path
+ ///
+ public string VMESS_HTTP2_Path { get; set; }
+
+ ///
+ /// vmess mKcp seed
+ ///
+ public string VMESS_mKCP_Seed { get; set; }
+
///
/// trojan密码
///
public string TrojanPassword { get; set; }
+ ///
+ /// trojan ws path
+ ///
+ public string Trojan_WS_Path { get; set; }
+
///
/// 域名
///
@@ -83,27 +112,48 @@ namespace ProxySU_Core.Models
return VLESS_TCP_Path;
case XrayType.VLESS_WS_TLS:
return VLESS_WS_Path;
+ case XrayType.VLESS_H2_TLS:
+ return VLESS_H2_Path;
+
case XrayType.VMESS_TCP_TLS:
return VMESS_TCP_Path;
case XrayType.VMESS_WS_TLS:
return VMESS_WS_Path;
+ case XrayType.Trojan_WS_TLS:
+ return Trojan_WS_Path;
+
+ // no path
+ case XrayType.VLESS_mKCP_Speed:
case XrayType.Trojan_TCP_TLS:
+ case XrayType.VMESS_mKCP_Speed:
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_TLS = 101,
+ VLESS_WS_TLS = 102,
+ VLESS_H2_TLS = 103,
+ VLESS_mKCP_Speed = 104,
- Trojan_TCP_TLS
+ // vmess 201开头
+ VMESS_TCP_TLS = 201,
+ VMESS_WS_TLS = 202,
+ VMESS_H2_TLS = 203,
+ VMESS_mKCP_Speed = 204,
+
+ // trojan 301开头
+ Trojan_TCP_TLS = 301,
+ Trojan_WS_TLS = 302,
}
}
diff --git a/ProxySU_Core/ProxySU_Core.csproj b/ProxySU_Core/ProxySU_Core.csproj
index 1daf4c3..8de2020 100644
--- a/ProxySU_Core/ProxySU_Core.csproj
+++ b/ProxySU_Core/ProxySU_Core.csproj
@@ -16,6 +16,22 @@
true
+ false
+ C:\Users\huife\Desktop\publish_new\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 1
+ 1.0.0.%2a
+ false
+ true
+ true
AnyCPU
@@ -36,105 +52,24 @@
prompt
4
+
+ D529B8E43BC86188988D830C545B400612900BB3
+
+
+ ProxySU_Core_TemporaryKey.pfx
+
+
+ true
+
+
+ false
+
-
- ..\packages\ControlzEx.4.3.0\lib\net45\ControlzEx.dll
+
+ ..\packages\ControlzEx.5.0.0\lib\net452\ControlzEx.dll
- ..\packages\MahApps.Metro.2.0.0\lib\net46\MahApps.Metro.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.BootstrapIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.BoxIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Codicons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Core.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Entypo.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.EvaIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FeatherIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FileIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Fontaudio.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FontAwesome.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.ForkAwesome.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Ionicons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.JamIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Material.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.MaterialDesign.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.MaterialLight.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Microns.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Modern.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Octicons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.PicolIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.PixelartIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RadixIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RemixIcon.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RPGAwesome.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.SimpleIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Typicons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Unicons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.VaadinIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.WeatherIcons.dll
-
-
- ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Zondicons.dll
+ ..\packages\MahApps.Metro.2.4.4\lib\net46\MahApps.Metro.dll
..\packages\MaterialDesignColors.2.0.0\lib\net452\MaterialDesignColors.dll
@@ -146,7 +81,7 @@
..\packages\MaterialDesignThemes.4.0.0\lib\net452\MaterialDesignThemes.Wpf.dll
- ..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.19\lib\net45\Microsoft.Xaml.Behaviors.dll
+ ..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll
..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
@@ -182,17 +117,19 @@
App.xaml
Code
+
+
-
-
-
-
+
+
+
+
@@ -201,6 +138,9 @@
+
+ ClientInfoWindow.xaml
+
MainWindow.xaml
@@ -210,6 +150,9 @@
TerminalWindow.xaml
+
+ TextBoxWindow.xaml
+
@@ -230,9 +173,6 @@
ResXFileCodeGenerator
Resources.Designer.cs
-
- PreserveNewest
-
SettingsSingleFileGenerator
@@ -301,12 +241,27 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -342,6 +297,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -354,6 +313,25 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4.6.1 %28x86 和 x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
diff --git a/ProxySU_Core/Templates/xray/server/00_log/00_log.json b/ProxySU_Core/Templates/xray/server/00_log/00_log.json
index 6a4cf00..40c2cd5 100644
--- a/ProxySU_Core/Templates/xray/server/00_log/00_log.json
+++ b/ProxySU_Core/Templates/xray/server/00_log/00_log.json
@@ -1,5 +1,6 @@
{
- "log": {
- "loglevel": "warning"
- }
+ "log": {
+ "access": "none",
+ "loglevel": "none"
+ }
}
\ No newline at end of file
diff --git a/ProxySU_Core/Templates/xray/server/01_api/01_api.json b/ProxySU_Core/Templates/xray/server/01_api/01_api.json
index aa1982b..34c6b17 100644
--- a/ProxySU_Core/Templates/xray/server/01_api/01_api.json
+++ b/ProxySU_Core/Templates/xray/server/01_api/01_api.json
@@ -1,3 +1,3 @@
{
- "api": null
+ "api": {}
}
\ 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_TLS.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_TLS.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_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS_TLS.json
new file mode 100644
index 0000000..51d725c
--- /dev/null
+++ b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS_TLS.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_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2_TLS.json
new file mode 100644
index 0000000..a99e848
--- /dev/null
+++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2_TLS.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_TCP_XTLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json
index 07a491a..d8cddd9 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,9 +15,7 @@
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
- "alpn": [
- "http/1.1"
- ],
+ "alpn": [ "h2", "http/1.1" ],
"certificates": [
{
"certificateFile": "/usr/local/etc/xray/ssl/xray_ssl.crt",
diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.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_TLS.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/VLESS_mKCP.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_mKCP.json
new file mode 100644
index 0000000..77b6aba
--- /dev/null
+++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_mKCP.json
@@ -0,0 +1,24 @@
+{
+ "port": 3456,
+ "listen": "127.0.0.1",
+ "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/VMESS_HTTP2_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2_TLS.json
new file mode 100644
index 0000000..9957e76
--- /dev/null
+++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2_TLS.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_TCP_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.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_TLS.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_TLS.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_TLS.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_mKCP.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_mKCP.json
new file mode 100644
index 0000000..63bcf27
--- /dev/null
+++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_mKCP.json
@@ -0,0 +1,24 @@
+{
+ "port": 3456,
+ "listen": "127.0.0.1",
+ "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/08_stats/08_stats.json b/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json
index 02c9ed0..b406e15 100644
--- a/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json
+++ b/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json
@@ -1,3 +1,3 @@
{
- "stats": null
+ "stats": {}
}
\ No newline at end of file
diff --git a/ProxySU_Core/ViewModels/Developers/XrayProject.cs b/ProxySU_Core/ViewModels/Developers/XrayProject.cs
deleted file mode 100644
index b605860..0000000
--- a/ProxySU_Core/ViewModels/Developers/XrayProject.cs
+++ /dev/null
@@ -1,195 +0,0 @@
-using Renci.SshNet;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Windows;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using ProxySU_Core.Models;
-
-namespace ProxySU_Core.ViewModels.Developers
-{
- public class XrayProject : Project
- {
-
- private const string ServerLogDir = @"Templates\xray\server\00_log";
- private const string ServerApiDir = @"Templates\xray\server\01_api";
- private const string ServerDnsDir = @"Templates\xray\server\02_dns";
- private const string ServerRoutingDir = @"Templates\xray\server\03_routing";
- private const string ServerPolicyDir = @"Templates\xray\server\04_policy";
- private const string ServerInboundsDir = @"Templates\xray\server\05_inbounds";
- private const string ServerOutboundsDir = @"Templates\xray\server\06_outbounds";
- private const string ServerTransportDir = @"Templates\xray\server\07_transport";
- private const string ServerStatsDir = @"Templates\xray\server\08_stats";
- private const string ServerReverseDir = @"Templates\xray\server\09_reverse";
- private const string CaddyFileDir = @"Templates\xray\caddy";
-
- public XrayProject(SshClient sshClient, XraySettings parameters, Action writeOutput) : base(sshClient, parameters, writeOutput)
- {
- }
-
- public override void Install()
- {
- try
- {
- EnsureRootAuth();
-
- if (FileExists("/usr/local/bin/xray"))
- {
- var btnResult = MessageBox.Show("已经安装Xray,是否需要重装?", "提示", MessageBoxButton.YesNo);
- if (btnResult == MessageBoxResult.No)
- {
- MessageBox.Show("安装终止", "提示");
- return;
- }
- }
-
- EnsureSystemEnv();
-
- ConfigurePort();
-
- ConfigureSoftware();
-
- ConfigureIPv6();
-
- ConfigureFirewall();
-
- SyncTimeDiff();
-
- ValidateDomain();
-
- InstallXrayWithCert();
-
- InstallCaddy();
-
- UploadCaddyFile();
- }
- catch (Exception ex)
- {
- MessageBox.Show("安装终止," + ex.Message);
- }
- }
-
- private void UploadCaddyFile()
- {
- var configJson = ConfigBuilder.BuildCaddyConfig(Parameters);
- var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson));
- RunCmd("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.back");
- UploadFile(stream, "/etc/caddy/Caddyfile");
- RunCmd("systemctl reload caddy");
- }
-
- 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安装成功");
- }
-
- RunCmd($"sed -i 's/User=nobody/User=root/g' /etc/systemd/system/xray.service");
- RunCmd($"sed -i 's/CapabilityBoundingSet=/#CapabilityBoundingSet=/g' /etc/systemd/system/xray.service");
- RunCmd($"sed -i 's/AmbientCapabilities=/#AmbientCapabilities=/g' /etc/systemd/system/xray.service");
- RunCmd($"systemctl daemon-reload");
-
- if (FileExists("/usr/local/etc/xray/config.json"))
- {
- RunCmd(@"mv /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.1");
- }
-
- InstallCertToXray();
-
-
- 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");
- }
-
- private void InstallCertToXray()
- {
- // 安装依赖
- RunCmd(GetInstallCmd("socat"));
-
- // 解决搬瓦工CentOS缺少问题
- RunCmd(GetInstallCmd("automake autoconf libtool"));
-
- // 安装Acme
- var result = RunCmd($"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m {GetRandomEmail()}");
- if (result.Contains("Install success"))
- {
- WriteOutput("安装 acme.sh 成功");
- }
- else
- {
- throw new Exception("安装 acme.sh 失败,请联系开发者!");
- }
-
- RunCmd("cd ~/.acme.sh/");
- RunCmd("alias acme.sh=~/.acme.sh/acme.sh");
-
- // 申请证书
- if (OnlyIpv6)
- {
- var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain} --listen-v6";
- result = RunCmd(cmd);
- }
- else
- {
- var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain}";
- result = RunCmd(cmd);
- }
-
- if (result.Contains("Cert success"))
- {
- WriteOutput("申请证书成功");
- }
- else
- {
- throw new Exception("申请证书失败,请联系开发者!");
- }
-
- // 安装证书到xray
- RunCmd("mkdir -p /usr/local/etc/xray/ssl");
- RunCmd($"/root/.acme.sh/acme.sh --installcert -d {Parameters.Domain} --certpath /usr/local/etc/xray/ssl/xray_ssl.crt --keypath /usr/local/etc/xray/ssl/xray_ssl.key --capath /usr/local/etc/xray/ssl/xray_ssl.crt --reloadcmd \"systemctl restart xray\"");
- result = RunCmd(@"if [ ! -f ""/usr/local/etc/xray/ssl/xray_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1");
- if (result.Contains("1"))
- {
- WriteOutput("安装证书成功");
- }
- else
- {
- throw new Exception("安装证书失败,请联系开发者!");
- }
-
-
- RunCmd(@"chmod 644 /usr/local/etc/xray/ssl/xray_ssl.key");
- }
-
- private string GetRandomEmail()
- {
- Random r = new Random();
- var num = r.Next(200000000, 900000000);
- return $"{num}@qq.com";
- }
-
- private int GetRandomPort()
- {
- var random = new Random();
- return random.Next(10001, 60000);
- }
-
- private dynamic LoadJsonObj(string path)
- {
- if (File.Exists(path))
- {
- var jsonStr = File.ReadAllText(path, Encoding.UTF8);
- return JsonConvert.DeserializeObject(jsonStr);
- }
- return null;
- }
-
- }
-}
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/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/Terminal.cs b/ProxySU_Core/ViewModels/Terminal.cs
index 4c5028b..1f2a92a 100644
--- a/ProxySU_Core/ViewModels/Terminal.cs
+++ b/ProxySU_Core/ViewModels/Terminal.cs
@@ -8,37 +8,31 @@ namespace ProxySU_Core.ViewModels
{
public class Terminal : BaseViewModel
{
- private string outputText;
+ private bool hasConnected;
public Terminal(Host host)
{
Host = host;
+ HasConnected = false;
+ }
+
+ public bool HasConnected
+ {
+ get
+ {
+ return hasConnected;
+ }
+ set
+ {
+ hasConnected = value;
+ Notify("HasConnected");
+ }
}
public Host Host { get; set; }
public string CommandText { get; set; }
- public string OutputText
- {
- get => outputText;
- }
-
- public void ClearOutput()
- {
- outputText = "";
- Notify("OutputText");
- }
-
- public void AddOutput(string text)
- {
- outputText += text;
-
- if (!text.EndsWith("\n"))
- {
- outputText += "\n";
- }
- Notify("OutputText");
- }
+ public string OutputText { get; set; }
}
}
diff --git a/ProxySU_Core/ViewModels/XraySettingsViewModel.cs b/ProxySU_Core/ViewModels/XraySettingsViewModel.cs
index 3bf4ef3..54d1435 100644
--- a/ProxySU_Core/ViewModels/XraySettingsViewModel.cs
+++ b/ProxySU_Core/ViewModels/XraySettingsViewModel.cs
@@ -1,10 +1,12 @@
-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.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Web;
using System.Windows;
namespace ProxySU_Core.ViewModels
@@ -76,7 +78,9 @@ namespace ProxySU_Core.ViewModels
{
if (value == true)
{
- settings.Types.Add(XrayType.VLESS_TCP_TLS);
+ if (!settings.Types.Contains(XrayType.VLESS_TCP_TLS))
+ settings.Types.Add(XrayType.VLESS_TCP_TLS);
+
}
else
{
@@ -97,7 +101,8 @@ namespace ProxySU_Core.ViewModels
{
if (value == true)
{
- settings.Types.Add(XrayType.VLESS_TCP_XTLS);
+ if (!settings.Types.Contains(XrayType.VLESS_TCP_XTLS))
+ settings.Types.Add(XrayType.VLESS_TCP_XTLS);
}
else
{
@@ -117,7 +122,8 @@ namespace ProxySU_Core.ViewModels
{
if (value == true)
{
- settings.Types.Add(XrayType.VLESS_WS_TLS);
+ if (!settings.Types.Contains(XrayType.VLESS_WS_TLS))
+ settings.Types.Add(XrayType.VLESS_WS_TLS);
}
else
{
@@ -138,7 +144,8 @@ namespace ProxySU_Core.ViewModels
{
if (value == true)
{
- settings.Types.Add(XrayType.VMESS_TCP_TLS);
+ if (!settings.Types.Contains(XrayType.VMESS_TCP_TLS))
+ settings.Types.Add(XrayType.VMESS_TCP_TLS);
}
else
{
@@ -159,7 +166,8 @@ namespace ProxySU_Core.ViewModels
{
if (value == true)
{
- settings.Types.Add(XrayType.VMESS_WS_TLS);
+ if (!settings.Types.Contains(XrayType.VMESS_WS_TLS))
+ settings.Types.Add(XrayType.VMESS_WS_TLS);
}
else
{
@@ -180,7 +188,8 @@ namespace ProxySU_Core.ViewModels
{
if (value == true)
{
- settings.Types.Add(XrayType.Trojan_TCP_TLS);
+ if (!settings.Types.Contains(XrayType.Trojan_TCP_TLS))
+ settings.Types.Add(XrayType.Trojan_TCP_TLS);
}
else
{
@@ -227,5 +236,31 @@ namespace ProxySU_Core.ViewModels
}
}
+ public string VLESS_TCP_XTLS_ShareLink
+ {
+ get => ShareLink.Build(XrayType.VLESS_TCP_XTLS, settings);
+ }
+ public string VLESS_TCP_TLS_ShareLink
+ {
+ get => ShareLink.Build(XrayType.VLESS_TCP_TLS, settings);
+ }
+ public string VLESS_WS_TLS_ShareLink
+ {
+ get => ShareLink.Build(XrayType.VLESS_WS_TLS, settings);
+ }
+ public string VMESS_TCP_TLS_ShareLink
+ {
+ get => ShareLink.Build(XrayType.VMESS_TCP_TLS, settings);
+ }
+ public string VMESS_WS_TLS_ShareLink
+ {
+ get => ShareLink.Build(XrayType.VMESS_WS_TLS, settings);
+ }
+ public string Trojan_TCP_TLS_ShareLink
+ {
+ get => ShareLink.Build(XrayType.Trojan_TCP_TLS, settings);
+ }
+
}
+
}
diff --git a/ProxySU_Core/Views/ClientInfoWindow.xaml b/ProxySU_Core/Views/ClientInfoWindow.xaml
new file mode 100644
index 0000000..3380bc7
--- /dev/null
+++ b/ProxySU_Core/Views/ClientInfoWindow.xaml
@@ -0,0 +1,339 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ProxySU_Core/Views/ClientInfoWindow.xaml.cs b/ProxySU_Core/Views/ClientInfoWindow.xaml.cs
new file mode 100644
index 0000000..a0cf9b7
--- /dev/null
+++ b/ProxySU_Core/Views/ClientInfoWindow.xaml.cs
@@ -0,0 +1,36 @@
+using ProxySU_Core.Models;
+using ProxySU_Core.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace ProxySU_Core.Views
+{
+ ///
+ /// ClientInfoWindow.xaml 的交互逻辑
+ ///
+ public partial class ClientInfoWindow
+ {
+ public XraySettingsViewModel Settings { get; set; }
+
+ public ClientInfoWindow(Record record)
+ {
+ InitializeComponent();
+ ResizeMode = ResizeMode.NoResize;
+ WindowStartupLocation = WindowStartupLocation.CenterScreen;
+
+ Settings = new XraySettingsViewModel(record.Settings);
+ DataContext = this;
+ }
+ }
+}
diff --git a/ProxySU_Core/Views/MainWindow.xaml b/ProxySU_Core/Views/MainWindow.xaml
index 22e7029..2649b91 100644
--- a/ProxySU_Core/Views/MainWindow.xaml
+++ b/ProxySU_Core/Views/MainWindow.xaml
@@ -7,7 +7,6 @@
mc:Ignorable="d"
BorderThickness="1"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
- xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
TextElement.FontSize="14"
Title="ProxySU Core" Height="800" Width="1200">
@@ -15,10 +14,7 @@
@@ -58,9 +54,21 @@
+ Content="{DynamicResource AddHost}"
+ Click="AddHost"
+ Width="100"/>
+
+
+
+
+
@@ -96,7 +108,8 @@
-
+
+
@@ -111,9 +124,9 @@
+ Header="其他功能">
-
+
diff --git a/ProxySU_Core/Views/MainWindow.xaml.cs b/ProxySU_Core/Views/MainWindow.xaml.cs
index ddd59fd..5e6fcc4 100644
--- a/ProxySU_Core/Views/MainWindow.xaml.cs
+++ b/ProxySU_Core/Views/MainWindow.xaml.cs
@@ -1,8 +1,9 @@
using MahApps.Metro.Controls.Dialogs;
using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using ProxySU_Core.Common;
using ProxySU_Core.Models;
using ProxySU_Core.ViewModels;
-using ProxySU_Core.ViewModels.Developers;
using ProxySU_Core.Views;
using Renci.SshNet;
using System;
@@ -45,17 +46,35 @@ namespace ProxySU_Core
if (File.Exists(RecordPath))
{
var recordsJson = File.ReadAllText(RecordPath, Encoding.UTF8);
- var records = JsonConvert.DeserializeObject>(recordsJson);
- records.ForEach(item =>
+ if (!string.IsNullOrEmpty(recordsJson))
{
- Records.Add(new RecordViewModel(item));
- });
+ var records = JsonConvert.DeserializeObject>(recordsJson);
+ records.ForEach(item =>
+ {
+ Records.Add(new RecordViewModel(item));
+ });
+ }
}
DataContext = this;
}
+ private void SaveRecord()
+ {
+ var recordList = Records.Select(x => x.record);
+ var json = JsonConvert.SerializeObject(recordList,
+ Formatting.Indented,
+ new JsonSerializerSettings
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver()
+ });
+ if (!Directory.Exists("Data"))
+ {
+ Directory.CreateDirectory("Data");
+ }
+ File.WriteAllText("Data\\Record.json", json, Encoding.UTF8);
+ }
private void LaunchGitHubSite(object sender, RoutedEventArgs e)
{
@@ -98,6 +117,36 @@ namespace ProxySU_Core
Application.Current.Resources.MergedDictionaries[0] = resource;
}
+ private void ExportXraySettings(object sender, RoutedEventArgs e)
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (var record in Records.Where(x => x.IsChecked))
+ {
+ record.Settings.Types.ForEach(type =>
+ {
+ var link = ShareLink.Build(type, record.Settings);
+ sb.AppendLine(link);
+ });
+ }
+ var tbx = new TextBoxWindow("分享链接", sb.ToString());
+ tbx.ShowDialog();
+ }
+
+ private void ExportXraySub(object sender, RoutedEventArgs e)
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (var record in Records.Where(x => x.IsChecked))
+ {
+ record.Settings.Types.ForEach(type =>
+ {
+ var link = ShareLink.Build(type, record.Settings);
+ sb.AppendLine(link);
+ });
+ }
+ var result = Base64.Encode(sb.ToString());
+ var tbx = new TextBoxWindow("订阅内容", result);
+ tbx.ShowDialog();
+ }
private void AddHost(object sender, RoutedEventArgs e)
{
@@ -107,6 +156,7 @@ namespace ProxySU_Core
if (result == true)
{
Records.Add(new RecordViewModel(newRecord));
+ SaveRecord();
}
}
@@ -119,10 +169,20 @@ namespace ProxySU_Core
if (result == true)
{
project.Notify();
+ SaveRecord();
}
}
}
+ private void ShowClientInfo(object sender, RoutedEventArgs e)
+ {
+ if (DataGrid.SelectedItem is RecordViewModel project)
+ {
+ var dialog = new ClientInfoWindow(project.record);
+ dialog.ShowDialog();
+ }
+ }
+
private void DeleteHost(object sender, RoutedEventArgs e)
{
diff --git a/ProxySU_Core/Views/RecordEditorWindow.xaml b/ProxySU_Core/Views/RecordEditorWindow.xaml
index b3d048a..785af14 100644
--- a/ProxySU_Core/Views/RecordEditorWindow.xaml
+++ b/ProxySU_Core/Views/RecordEditorWindow.xaml
@@ -8,7 +8,7 @@
xmlns:local="clr-namespace:ProxySU_Core.Views"
xmlns:converters="clr-namespace:ProxySU_Core.Converters"
mc:Ignorable="d"
- Title="RecordEditorWindow" Height="800" Width="710">
+ Title="编辑主机信息" Height="800" Width="710">
diff --git a/ProxySU_Core/Views/TerminalWindow.xaml b/ProxySU_Core/Views/TerminalWindow.xaml
index 30cb0e4..d31972f 100644
--- a/ProxySU_Core/Views/TerminalWindow.xaml
+++ b/ProxySU_Core/Views/TerminalWindow.xaml
@@ -6,29 +6,98 @@
xmlns:local="clr-namespace:ProxySU_Core"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
- Title="TerminalWindow" Height="500" Width="800">
+ Title="主机控制台" Height="500" Width="800">
-
-
-
-
-
-
-
+ Height="260"
+ Text="{Binding Path=OutputText}"
+ />
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Themezy
+
+
+ One Page Love
+
+
+ HTML5 UP
+
+
+ template mo
+
diff --git a/ProxySU_Core/Views/TerminalWindow.xaml.cs b/ProxySU_Core/Views/TerminalWindow.xaml.cs
index d1e4d01..1fd8139 100644
--- a/ProxySU_Core/Views/TerminalWindow.xaml.cs
+++ b/ProxySU_Core/Views/TerminalWindow.xaml.cs
@@ -1,11 +1,14 @@
using MahApps.Metro.Controls.Dialogs;
+using Microsoft.Win32;
using ProxySU_Core.Models;
+using ProxySU_Core.Models.Developers;
using ProxySU_Core.ViewModels;
-using ProxySU_Core.ViewModels.Developers;
using ProxySU_Core.Views;
using Renci.SshNet;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
@@ -29,6 +32,8 @@ namespace ProxySU_Core
private readonly Terminal _vm;
private SshClient _sshClient;
+ XrayProject project;
+
public TerminalWindow(Record record)
{
InitializeComponent();
@@ -39,7 +44,7 @@ namespace ProxySU_Core
_vm = new Terminal(record.Host);
DataContext = _vm;
- _vm.AddOutput("Connect ...");
+ WriteOutput("Connect ...");
Task.Factory.StartNew(() =>
{
try
@@ -56,6 +61,7 @@ namespace ProxySU_Core
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
+ _vm.HasConnected = false;
if (_sshClient != null)
_sshClient.Disconnect();
@@ -102,31 +108,110 @@ namespace ProxySU_Core
var conneInfo = CreateConnectionInfo(host);
_sshClient = new SshClient(conneInfo);
_sshClient.Connect();
- _vm.AddOutput("Connected");
+ WriteOutput("Connected");
+
+ _vm.HasConnected = true;
+ project = new XrayProject(_sshClient, Record.Settings, WriteOutput);
}
- private void WriteShell(string outShell)
+ private void WriteOutput(string outShell)
{
- _vm.AddOutput(outShell);
+ if (!outShell.EndsWith("\n"))
+ {
+ outShell += "\n";
+ }
Dispatcher.Invoke(() =>
{
+ OutputTextBox.AppendText(outShell);
OutputTextBox.ScrollToEnd();
});
}
private void Install(object sender, RoutedEventArgs e)
{
- XrayProject project = new XrayProject(
- _sshClient,
- Record.Settings,
- WriteShell);
-
Task.Factory.StartNew(() =>
{
project.Install();
});
}
+ private void UpdateXrayCore(object sender, RoutedEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ project.UpdateXrayCore();
+ });
+ }
+
+ private void UpdateXraySettings(object sender, RoutedEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ project.UpdateXraySettings();
+ });
+ }
+
+ private void InstallCert(object sender, RoutedEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ project.InstallCert();
+ });
+ }
+
+ private void UploadCert(object sender, RoutedEventArgs e)
+ {
+ var fileDialog = new OpenFileDialog();
+ fileDialog.Filter = "压缩文件|*.zip";
+ fileDialog.FileOk += DoUploadCert;
+ fileDialog.ShowDialog();
+ }
+
+ private void UploadWeb(object sender, RoutedEventArgs e)
+ {
+ var fileDialog = new OpenFileDialog();
+ fileDialog.Filter = "压缩文件|*.zip";
+ fileDialog.FileOk += DoUploadWeb;
+ fileDialog.ShowDialog();
+ }
+
+ private void ReinstallCaddy(object sender, RoutedEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ project.ReinstallCaddy();
+ });
+ }
+
+ private void DoUploadWeb(object sender, CancelEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ var file = sender as OpenFileDialog;
+ using (var stream = file.OpenFile())
+ {
+ project.UploadWeb(stream);
+ }
+ });
+ }
+
+ private void DoUploadCert(object sender, CancelEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ var file = sender as OpenFileDialog;
+ using (var stream = file.OpenFile())
+ {
+ project.UploadCert(stream);
+ }
+ });
+ }
+
+ private void OpenLink(object sender, RoutedEventArgs e)
+ {
+ Hyperlink link = sender as Hyperlink;
+ Process.Start(new ProcessStartInfo(link.NavigateUri.AbsoluteUri));
+ }
}
}
diff --git a/ProxySU_Core/Views/TextBoxWindow.xaml b/ProxySU_Core/Views/TextBoxWindow.xaml
new file mode 100644
index 0000000..1e10a5a
--- /dev/null
+++ b/ProxySU_Core/Views/TextBoxWindow.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/ProxySU_Core/Views/TextBoxWindow.xaml.cs b/ProxySU_Core/Views/TextBoxWindow.xaml.cs
new file mode 100644
index 0000000..af105e2
--- /dev/null
+++ b/ProxySU_Core/Views/TextBoxWindow.xaml.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace ProxySU_Core.Views
+{
+ ///
+ /// TextBoxWindow.xaml 的交互逻辑
+ ///
+ public partial class TextBoxWindow
+ {
+ public string Message { get; set; }
+
+ public TextBoxWindow(string title, string message)
+ {
+ InitializeComponent();
+ this.Title = title;
+ this.Message = message;
+
+ this.DataContext = this;
+ }
+ }
+}
diff --git a/ProxySU_Core/packages.config b/ProxySU_Core/packages.config
index 1c6357a..43548b5 100644
--- a/ProxySU_Core/packages.config
+++ b/ProxySU_Core/packages.config
@@ -1,12 +1,11 @@
-
-
-
+
+
-
+
\ No newline at end of file