1
0
Fork 0
mirror of https://github.com/proxysu/ProxySU.git synced 2025-04-10 12:40:55 +00:00

Merge pull request #1 from proxysu/master

Update 2021-3-18 3:41
This commit is contained in:
Stklv 2021-03-18 03:41:39 +08:00 committed by GitHub
commit b14b8b30ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1762 additions and 467 deletions

4
.editorconfig Normal file
View file

@ -0,0 +1,4 @@
[*.cs]
# Default severity for all analyzer diagnostics
dotnet_analyzer_diagnostic.severity = none

View file

@ -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

View file

@ -71,8 +71,8 @@
<Reference Include="QRCoder">
<HintPath>..\qrcoder\net40\QRCoder.dll</HintPath>
</Reference>
<Reference Include="Renci.SshNet">
<HintPath>..\ssh.net\net40\Renci.SshNet.dll</HintPath>
<Reference Include="Renci.SshNet, Version=2020.0.1.0, Culture=neutral, PublicKeyToken=1cee9f8bde3db106, processorArchitecture=MSIL">
<HintPath>..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
@ -181,6 +181,10 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="..\.editorconfig">
<Link>.editorconfig</Link>
</None>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SSH.NET" version="2016.1.0" targetFramework="net40" />
<package id="SSH.NET" version="2020.0.1" targetFramework="net40" />
</packages>

View file

@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="ControlzEx" publicKeyToken="69f1c32f803d307e" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -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);
}
}
}

View file

@ -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,

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.ViewModels.Developers
namespace ProxySU_Core.Models.Developers
{
public interface IParameters
{

View file

@ -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
/// </summary>
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($"域名解析失败,安装停止!");
}
}
/// <summary>
@ -341,26 +354,32 @@ namespace ProxySU_Core.ViewModels.Developers
/// </summary>
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("未识别的系统");

View file

@ -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<XraySettings>
{
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<string> writeOutput) : base(sshClient, parameters, writeOutput)
{
}
/// <summary>
/// 安装Xray
/// </summary>
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);
}
}
/// <summary>
/// 更新xray内核
/// </summary>
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内核完成 ************");
}
/// <summary>
/// 更新xray配置
/// </summary>
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配置成功更新配置不包含域名如果域名更换请重新安装。 ************");
}
/// <summary>
/// 重装Caddy
/// </summary>
public void ReinstallCaddy()
{
EnsureRootAuth();
EnsureSystemEnv();
InstallCaddy();
UploadCaddyFile();
WriteOutput("************ 重装Caddy完成 ************");
}
/// <summary>
/// 安装证书
/// </summary>
public void InstallCert()
{
EnsureRootAuth();
EnsureSystemEnv();
this.InstallCertToXray();
RunCmd("systemctl restart xray");
WriteOutput("************ 安装证书完成 ************");
}
/// <summary>
/// 上传证书
/// </summary>
/// <param name="keyStrem"></param>
/// <param name="crtStream"></param>
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("************ 上传证书完成 ************");
}
/// <summary>
/// 上传静态网站
/// </summary>
/// <param name="stream"></param>
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;
}
}
}

View file

@ -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; }
}
}

View file

@ -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> { XrayType.VLESS_TCP_XTLS };
UUID = guid;
Types = new List<XrayType>();
VLESS_WS_Path = "/vlessws";
VLESS_TCP_Path = "/vlesstcp";
VMESS_WS_Path = "/vmessws";
VMESS_TCP_Path = "/vmesstcp";
TrojanPassword = Guid.NewGuid().ToString();
TrojanPassword = guid;
}
/// <summary>
@ -42,6 +46,16 @@ namespace ProxySU_Core.Models
/// </summary>
public string VLESS_TCP_Path { get; set; }
/// <summary>
/// vless http2 path
/// </summary>
public string VLESS_H2_Path { get; set; }
/// <summary>
/// vless mKcp seed
/// </summary>
public string VLESS_mKCP_Seed { get; set; }
/// <summary>
/// vmess ws路径
/// </summary>
@ -52,11 +66,26 @@ namespace ProxySU_Core.Models
/// </summary>
public string VMESS_TCP_Path { get; set; }
/// <summary>
/// vmess http2 path
/// </summary>
public string VMESS_HTTP2_Path { get; set; }
/// <summary>
/// vmess mKcp seed
/// </summary>
public string VMESS_mKCP_Seed { get; set; }
/// <summary>
/// trojan密码
/// </summary>
public string TrojanPassword { get; set; }
/// <summary>
/// trojan ws path
/// </summary>
public string Trojan_WS_Path { get; set; }
/// <summary>
/// 域名
/// </summary>
@ -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,
}
}

View file

@ -16,6 +16,22 @@
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>C:\Users\huife\Desktop\publish_new\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -36,105 +52,24 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>D529B8E43BC86188988D830C545B400612900BB3</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>ProxySU_Core_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<ItemGroup>
<Reference Include="ControlzEx, Version=4.0.0.0, Culture=neutral, PublicKeyToken=69f1c32f803d307e, processorArchitecture=MSIL">
<HintPath>..\packages\ControlzEx.4.3.0\lib\net45\ControlzEx.dll</HintPath>
<Reference Include="ControlzEx, Version=5.0.0.0, Culture=neutral, PublicKeyToken=69f1c32f803d307e, processorArchitecture=MSIL">
<HintPath>..\packages\ControlzEx.5.0.0\lib\net452\ControlzEx.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro, Version=2.0.0.0, Culture=neutral, PublicKeyToken=51482d6f650b2b3f, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.2.0.0\lib\net46\MahApps.Metro.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.BootstrapIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.BootstrapIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.BoxIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.BoxIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Codicons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Codicons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Core.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Entypo, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Entypo.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.EvaIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.EvaIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.FeatherIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FeatherIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.FileIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FileIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Fontaudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Fontaudio.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.FontAwesome, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FontAwesome.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.ForkAwesome, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.ForkAwesome.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Ionicons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Ionicons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.JamIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.JamIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Material, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Material.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.MaterialDesign, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.MaterialDesign.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.MaterialLight, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.MaterialLight.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Microns, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Microns.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Modern, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Modern.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Octicons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Octicons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.PicolIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.PicolIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.PixelartIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.PixelartIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.RadixIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RadixIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.RemixIcon, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RemixIcon.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.RPGAwesome, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RPGAwesome.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.SimpleIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.SimpleIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Typicons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Typicons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Unicons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Unicons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.VaadinIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.VaadinIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.WeatherIcons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.WeatherIcons.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro.IconPacks.Zondicons, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0c0d510f9915137a, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Zondicons.dll</HintPath>
<HintPath>..\packages\MahApps.Metro.2.4.4\lib\net46\MahApps.Metro.dll</HintPath>
</Reference>
<Reference Include="MaterialDesignColors, Version=2.0.0.2422, Culture=neutral, PublicKeyToken=df2a72020bd7962a, processorArchitecture=MSIL">
<HintPath>..\packages\MaterialDesignColors.2.0.0\lib\net452\MaterialDesignColors.dll</HintPath>
@ -146,7 +81,7 @@
<HintPath>..\packages\MaterialDesignThemes.4.0.0\lib\net452\MaterialDesignThemes.Wpf.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.19\lib\net45\Microsoft.Xaml.Behaviors.dll</HintPath>
<HintPath>..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
@ -182,17 +117,19 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Common\Base64.cs" />
<Compile Include="Converters\LoginSecretTypeConverter.cs" />
<Compile Include="Models\Host.cs" />
<Compile Include="Models\ShareLink.cs" />
<Compile Include="Models\XraySettings.cs" />
<Compile Include="Tools\DateTimeUtils.cs" />
<Compile Include="Tools\Extensions.cs" />
<Compile Include="ViewModels\BaseCommand.cs" />
<Compile Include="ViewModels\BaseViewModel.cs" />
<Compile Include="ViewModels\Developers\ConfigBuilder.cs" />
<Compile Include="ViewModels\Developers\IParameters.cs" />
<Compile Include="ViewModels\Developers\Project.cs" />
<Compile Include="ViewModels\Developers\XrayProject.cs" />
<Compile Include="Models\Developers\ConfigBuilder.cs" />
<Compile Include="Models\Developers\IParameters.cs" />
<Compile Include="Models\Developers\Project.cs" />
<Compile Include="Models\Developers\XrayProject.cs" />
<Compile Include="ViewModels\HostViewModel.cs" />
<Compile Include="Models\LocalProxy.cs" />
<Compile Include="Models\LocalProxyType.cs" />
@ -201,6 +138,9 @@
<Compile Include="ViewModels\RecordViewModel.cs" />
<Compile Include="ViewModels\Terminal.cs" />
<Compile Include="ViewModels\XraySettingsViewModel.cs" />
<Compile Include="Views\ClientInfoWindow.xaml.cs">
<DependentUpon>ClientInfoWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
@ -210,6 +150,9 @@
<Compile Include="Views\TerminalWindow.xaml.cs">
<DependentUpon>TerminalWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\TextBoxWindow.xaml.cs">
<DependentUpon>TextBoxWindow.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Converters\ProxyTypeConverter.cs" />
@ -230,9 +173,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Data\Record.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@ -301,12 +241,27 @@
<None Include="Templates\xray\server\05_inbounds\Trojan_TCP_TLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\Trojan_WS_TLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VLESS_HTTP2_TLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VLESS_mKCP.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VLESS_TCP_XTLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VLESS_WS_TLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_HTTP2_TLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_mKCP.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_TCP_TLS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@ -342,6 +297,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\ClientInfoWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@ -354,6 +313,25 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\TextBoxWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="Data\" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 和 x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\MaterialDesignThemes.4.0.0\build\MaterialDesignThemes.targets" Condition="Exists('..\packages\MaterialDesignThemes.4.0.0\build\MaterialDesignThemes.targets')" />

View file

@ -1,5 +1,6 @@
{
"log": {
"loglevel": "warning"
}
"log": {
"access": "none",
"loglevel": "none"
}
}

View file

@ -1,3 +1,3 @@
{
"api": null
"api": {}
}

View file

@ -5,9 +5,7 @@
"settings": {
"clients": [
{
"password": "",
"level": 0,
"email": "love@example.com"
"password": ""
}
],
"fallbacks": [

View file

@ -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"
}
}
}

View file

@ -0,0 +1,19 @@
{
"port": 1234,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"decryption": "none",
"clients": [
{
"id": ""
}
]
},
"streamSettings": {
"network": "h2",
"httpSettings": {
"path": ""
}
}
}

View file

@ -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",

View file

@ -5,9 +5,7 @@
"settings": {
"clients": [
{
"id": "",
"level": 0,
"email": "love@example.com"
"id": ""
}
],
"decryption": "none"

View file

@ -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
}
}
}

View file

@ -0,0 +1,18 @@
{
"port": 1234,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": ""
}
]
},
"streamSettings": {
"network": "h2",
"httpSettings": {
"path": ""
}
}
}

View file

@ -5,9 +5,7 @@
"settings": {
"clients": [
{
"id": "",
"level": 0,
"email": "love@example.com"
"id": ""
}
]
},

View file

@ -5,9 +5,7 @@
"settings": {
"clients": [
{
"id": "",
"level": 0,
"email": "love@example.com"
"id": ""
}
]
},

View file

@ -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
}
}
}

View file

@ -1,3 +1,3 @@
{
"stats": null
"stats": {}
}

View file

@ -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<XraySettings>
{
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<string> 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;
}
}
}

View file

@ -15,6 +15,7 @@ namespace ProxySU_Core.ViewModels
private readonly ICommand _selectKeyCommand;
public HostViewModel(Host host)
{
_selectKeyCommand = new BaseCommand(obj => OpenFileDialog(obj));

View file

@ -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

View file

@ -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; }
}
}

View file

@ -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);
}
}
}

View file

@ -0,0 +1,339 @@
<metro:MetroWindow x:Class="ProxySU_Core.Views.ClientInfoWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
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"
mc:Ignorable="d"
Title="查看配置" Height="450" Width="800">
<Grid>
<TabControl
Background="#fff"
Style="{StaticResource MaterialDesignNavigatilRailTabControl}"
Padding="10">
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_VLESS_XTLS}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VLESS-TCP-XTLS">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="地址(address)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="端口(port)" Width="120" />
<TextBox Text="443" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="用户ID(id)" Width="120" />
<TextBox Text="{Binding Settings.UUID}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="流控(flow)" Width="120" />
<TextBox Text="xtls-rprx-direct" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="加密(encryption)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输协议(network)" Width="120" />
<TextBox Text="tcp" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装类型(type)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装域名(host)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="路径(path)" Width="120" />
<TextBox Text="" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="xtls" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.VLESS_TCP_XTLS_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_VLESS_TCP}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VLESS-TCP-TLS">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="地址(address)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="端口(port)" Width="120" />
<TextBox Text="443" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="用户ID(id)" Width="120" />
<TextBox Text="{Binding Settings.UUID}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="流控(flow)" Width="120" />
<TextBox Text="" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="加密(encryption)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输协议(network)" Width="120" />
<TextBox Text="tcp" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装类型(type)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装域名(host)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="路径(path)" Width="120" />
<TextBox Text="{Binding Settings.VLESS_TCP_Path}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="tls" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.VLESS_TCP_TLS_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_VLESS_WS}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VLESS-WebSocket-TLS">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="地址(address)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="端口(port)" Width="120" />
<TextBox Text="443" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="用户ID(id)" Width="120" />
<TextBox Text="{Binding Settings.UUID}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="流控(flow)" Width="120" />
<TextBox Text="" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="加密(encryption)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输协议(network)" Width="120" />
<TextBox Text="ws" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装类型(type)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装域名(host)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="路径(path)" Width="120" />
<TextBox Text="{Binding Settings.VLESS_WS_Path}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="tls" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.VLESS_WS_TLS_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_VMESS_TCP}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VMESS-TCP-TLS">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="地址(address)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="端口(port)" Width="120" />
<TextBox Text="443" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="用户ID(id)" Width="120" />
<TextBox Text="{Binding Settings.UUID}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="加密(security)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输协议(network)" Width="120" />
<TextBox Text="tcp" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装类型(type)" Width="120" />
<TextBox Text="http" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装域名(host)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="路径(path)" Width="120" />
<TextBox Text="{Binding Settings.VMESS_TCP_Path}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="tls" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.VMESS_TCP_TLS_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_VMESS_WS}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VLESS-WebSocket-TLS">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="地址(address)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="端口(port)" Width="120" />
<TextBox Text="443" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="用户ID(id)" Width="120" />
<TextBox Text="{Binding Settings.UUID}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="加密(security)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输协议(network)" Width="120" />
<TextBox Text="ws" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装类型(type)" Width="120" />
<TextBox Text="none" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装域名(host)" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="路径(path)" Width="120" />
<TextBox Text="{Binding Settings.VMESS_WS_Path}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="tls" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.VMESS_WS_TLS_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_Trojan_TCP}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VLESS-TCP-Trojan">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="服务器地址" Width="120" />
<TextBox Text="{Binding Settings.Domain}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="服务器端口" Width="120" />
<TextBox Text="443" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="密码" Width="120" />
<TextBox Text="{Binding Settings.TrojanPassword}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.Trojan_TCP_TLS_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</metro:MetroWindow>

View file

@ -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
{
/// <summary>
/// ClientInfoWindow.xaml 的交互逻辑
/// </summary>
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;
}
}
}

View file

@ -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 @@
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands>
<Button Click="LaunchGitHubSite" ToolTip="Open up the GitHub site">
<iconPacks:PackIconModern
Width="22"
Height="22"
Kind="SocialGithubOctocat" />
github
</Button>
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
@ -58,9 +54,21 @@
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
<Button
Content="{DynamicResource AddHost}"
Click="AddHost"
Width="100"/>
Content="{DynamicResource AddHost}"
Click="AddHost"
Width="100"/>
<Button
Margin="10,0,0,0"
Content="导出配置"
Click="ExportXraySettings"
Width="100" />
<Button
Margin="10,0,0,0"
Content="导出订阅"
Click="ExportXraySub"
Width="100" />
</StackPanel>
<DataGrid ItemsSource="{Binding Records}"
@ -75,6 +83,10 @@
BorderThickness="1"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="选择"
Binding="{Binding Path=IsChecked, UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="False"
Width="80"/>
<DataGridTextColumn Header="{DynamicResource HostTag}"
Binding="{Binding Path=Host.Tag}"
Width="150"/>
@ -96,7 +108,8 @@
<StackPanel Orientation="Horizontal">
<Button Content="{DynamicResource Connect}" FontSize="12" Height="24" Click="Connect" />
<Button Content="{DynamicResource Edit}" FontSize="12" Height="24" Margin="10,0,0,0" Click="EditHost" />
<Button Content="{DynamicResource Delete}" FontSize="12" Height="24" Margin="10,0,0,0" Click="DeleteHost" />
<Button Content="查看配置" FontSize="12" Height="24" Margin="10,0,0,0" Click="ShowClientInfo" />
<Button Content="{DynamicResource Delete}" FontSize="12" Height="24" Margin="10,0,0,0" Click="DeleteHost" BorderBrush="IndianRed" Background="IndianRed" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
@ -111,9 +124,9 @@
<TabItem
Width="160"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="V2ray">
Header="其他功能">
<StackPanel>
<TextBox />
<TextBlock Text="还不知道要点啥...看大家建议?" />
</StackPanel>
</TabItem>
</TabControl>

View file

@ -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<List<Record>>(recordsJson);
records.ForEach(item =>
if (!string.IsNullOrEmpty(recordsJson))
{
Records.Add(new RecordViewModel(item));
});
var records = JsonConvert.DeserializeObject<List<Record>>(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)
{

View file

@ -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">
<Window.Resources>
<converters:LoginSecretTypeConverter x:Key="LoginSecretTypeConverter" />

View file

@ -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">
<StackPanel>
<RichTextBox IsReadOnly="True"
<TextBox IsReadOnly="True"
Block.LineHeight="18"
Background="#000"
Foreground="LawnGreen"
FontSize="14"
FontFamily="Consolas"
x:Name="OutputTextBox"
Height="320">
<FlowDocument>
<Paragraph>
<Run Text="{Binding Path=OutputText, Mode=OneWay}" />
</Paragraph>
</FlowDocument>
</RichTextBox>
Height="260"
Text="{Binding Path=OutputText}"
/>
<StackPanel Margin="0,10,0,0">
<Button Content="安装Xray"
Click="Install"
Height="32"
Width="100"/>
<StackPanel Margin="10"
Orientation="Vertical"
HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal">
<TextBlock Text="内核/配置"
VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Button Content="安装Xray"
Click="Install"
Height="26"
IsEnabled="{Binding HasConnected}"
Width="120"/>
<Button Content="更新Xray内核"
Margin="10,0,0,0"
Click="UpdateXrayCore"
Height="26"
IsEnabled="{Binding HasConnected}"
Width="120"/>
<Button Content="更新Xray配置"
Margin="10,0,0,0"
Click="UpdateXraySettings"
Height="26"
IsEnabled="{Binding HasConnected}"
Width="120"/>
</StackPanel>
<StackPanel Orientation="Horizontal"
Margin="0,10,0,0">
<TextBlock Text="证书/网站"
VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Button Content="生成证书"
Margin="0,0,0,0"
Height="26"
Width="120"
IsEnabled="{Binding HasConnected}"
Click="InstallCert"/>
<Button Content="上传自有证书"
Margin="10,0,0,0"
Height="26"
Width="120"
IsEnabled="{Binding HasConnected}"
Click="UploadCert"/>
<Button Content="上传伪装网站"
Margin="10,0,0,0"
Height="26"
Width="120"
IsEnabled="{Binding HasConnected}"
Click="UploadWeb"/>
<Button Content="重装Caddy"
Margin="10,0,0,0"
Click="ReinstallCaddy"
Height="26"
IsEnabled="{Binding HasConnected}"
Width="120"/>
</StackPanel>
</StackPanel>
<StackPanel Margin="10,0,0,0">
<Label Content="静态网页模版(感谢网友推荐),将网站压缩包上传到服务区即可。" />
<TextBlock>
<Hyperlink NavigateUri="https://www.themezy.com" Click="OpenLink">Themezy</Hyperlink>
</TextBlock>
<TextBlock>
<Hyperlink NavigateUri="https://onepagelove.com/templates/free-templates" Click="OpenLink">One Page Love</Hyperlink>
</TextBlock>
<TextBlock>
<Hyperlink NavigateUri="https://html5up.net/" Click="OpenLink">HTML5 UP</Hyperlink>
</TextBlock>
<TextBlock>
<Hyperlink NavigateUri="https://templatemo.com/" Click="OpenLink">template mo</Hyperlink>
</TextBlock>
</StackPanel>
</StackPanel>
</metro:MetroWindow>

View file

@ -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));
}
}
}

View file

@ -0,0 +1,17 @@
<metro:MetroWindow x:Class="ProxySU_Core.Views.TextBoxWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProxySU_Core.Views"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
Title="TextBoxWindow" Height="450" Width="800">
<Grid>
<TextBox Margin="20"
Text="{Binding Path=Message}"
TextWrapping="Wrap"
FontSize="14"
Style="{StaticResource MahApps.Styles.TextBox}" />
</Grid>
</metro:MetroWindow>

View file

@ -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
{
/// <summary>
/// TextBoxWindow.xaml 的交互逻辑
/// </summary>
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;
}
}
}

View file

@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ControlzEx" version="4.3.0" targetFramework="net461" />
<package id="MahApps.Metro" version="2.0.0" targetFramework="net461" />
<package id="MahApps.Metro.IconPacks" version="4.8.0" targetFramework="net461" />
<package id="ControlzEx" version="5.0.0" targetFramework="net461" />
<package id="MahApps.Metro" version="2.4.4" targetFramework="net461" />
<package id="MaterialDesignColors" version="2.0.0" targetFramework="net461" />
<package id="MaterialDesignThemes" version="4.0.0" targetFramework="net461" />
<package id="MaterialDesignThemes.MahApps" version="0.1.6" targetFramework="net461" />
<package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.19" targetFramework="net461" />
<package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.31" targetFramework="net461" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" />
<package id="SSH.NET" version="2020.0.1" targetFramework="net461" />
</packages>