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

Merge pull request #2 from proxysu/master

p
This commit is contained in:
xnxy2012 2021-03-30 15:37:00 +08:00 committed by GitHub
commit 1a5546d2d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1548 additions and 447 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

@ -181,6 +181,9 @@
<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>

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

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace ProxySU_Core.Converters
{
public class VisibleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.Equals(true) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return false;
}
if (value.Equals(Visibility.Visible))
{
return true;
}
return false;
}
}
}

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,18 @@ namespace ProxySU_Core.ViewModels.Developers
public const int VLESS_TCP_Port = 1110;
public const int VLESS_WS_Port = 1111;
public const int VLESS_H2_Port = 1112;
public const int VLESS_mKCP_Port = 1113;
public const int VMESS_TCP_Port = 2110;
public const int VMESS_WS_Port = 2111;
public const int VMESS_H2_Port = 2112;
public const int VMESS_mKCP_Port = 2113;
public const int Trojan_TCP_Port = 3110;
public const int Trojan_WS_Port = 3111;
public const int ShadowSocksPort = 4110;
public static dynamic LoadXrayConfig()
@ -88,25 +97,18 @@ namespace ProxySU_Core.ViewModels.Developers
public static string BuildXrayConfig(XraySettings parameters)
{
var xrayConfig = LoadXrayConfig();
var baseBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_TCP_XTLS.json"));
var baseBound = GetBound("VLESS_TCP_XTLS.json");
baseBound.port = parameters.Port;
baseBound.settings.fallbacks.Add(JToken.FromObject(new
{
dest = 80,
xver = 1,
dest = 80
}));
xrayConfig.inbounds.Add(baseBound);
baseBound.settings.clients[0].id = parameters.UUID;
if (parameters.Types.Contains(XrayType.VLESS_TCP_XTLS))
if (parameters.Types.Contains(XrayType.VLESS_WS))
{
baseBound.settings.clients[0].id = parameters.UUID;
}
if (parameters.Types.Contains(XrayType.VLESS_WS_TLS))
{
baseBound.settings.clients[0].id = parameters.UUID;
var wsInbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_WS_TLS.json"));
var wsInbound = GetBound("VLESS_WS.json");
wsInbound.port = VLESS_WS_Port;
wsInbound.settings.clients[0].id = parameters.UUID;
wsInbound.streamSettings.wsSettings.path = parameters.VLESS_WS_Path;
@ -119,9 +121,9 @@ namespace ProxySU_Core.ViewModels.Developers
xrayConfig.inbounds.Add(JToken.FromObject(wsInbound));
}
if (parameters.Types.Contains(XrayType.VMESS_TCP_TLS))
if (parameters.Types.Contains(XrayType.VMESS_TCP))
{
var mtcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_TCP_TLS.json"));
var mtcpBound = GetBound("VMESS_TCP.json");
mtcpBound.port = VMESS_TCP_Port;
mtcpBound.settings.clients[0].id = parameters.UUID;
mtcpBound.streamSettings.tcpSettings.header.request.path = parameters.VMESS_TCP_Path;
@ -134,9 +136,9 @@ namespace ProxySU_Core.ViewModels.Developers
xrayConfig.inbounds.Add(JToken.FromObject(mtcpBound));
}
if (parameters.Types.Contains(XrayType.VMESS_WS_TLS))
if (parameters.Types.Contains(XrayType.VMESS_WS))
{
var mwsBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_WS_TLS.json"));
var mwsBound = GetBound("VMESS_WS.json");
mwsBound.port = VMESS_WS_Port;
mwsBound.settings.clients[0].id = parameters.UUID;
mwsBound.streamSettings.wsSettings.path = parameters.VMESS_WS_Path;
@ -149,9 +151,9 @@ namespace ProxySU_Core.ViewModels.Developers
xrayConfig.inbounds.Add(JToken.FromObject(mwsBound));
}
if (parameters.Types.Contains(XrayType.Trojan_TCP_TLS))
if (parameters.Types.Contains(XrayType.Trojan_TCP))
{
var trojanTcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "Trojan_TCP_TLS.json"));
var trojanTcpBound = GetBound("Trojan_TCP.json");
trojanTcpBound.port = Trojan_TCP_Port;
trojanTcpBound.settings.clients[0].password = parameters.TrojanPassword;
baseBound.settings.fallbacks[0] = JToken.FromObject(new
@ -162,6 +164,26 @@ namespace ProxySU_Core.ViewModels.Developers
xrayConfig.inbounds.Add(JToken.FromObject(trojanTcpBound));
}
if (parameters.Types.Contains(XrayType.VMESS_KCP))
{
var kcpBound = GetBound("VMESS_KCP.json");
kcpBound.port = VMESS_mKCP_Port;
kcpBound.settings.clients[0].id = parameters.UUID;
kcpBound.streamSettings.kcpSettings.header.type = parameters.VMESS_KCP_Type;
kcpBound.streamSettings.kcpSettings.seed = parameters.VMESS_KCP_Seed;
xrayConfig.inbounds.Add(JToken.FromObject(kcpBound));
}
if (parameters.Types.Contains(XrayType.ShadowsocksAEAD))
{
var ssBound = GetBound("Shadowsocks-AEAD.json");
ssBound.port = ShadowSocksPort;
ssBound.settings.clients[0].password = parameters.ShadowsocksPassword;
ssBound.settings.clients[0].method = parameters.ShadowsocksMethod;
xrayConfig.inbounds.Add(JToken.FromObject(ssBound));
}
return JsonConvert.SerializeObject(
xrayConfig,
Formatting.Indented,
@ -171,6 +193,11 @@ namespace ProxySU_Core.ViewModels.Developers
});
}
private static dynamic GetBound(string name)
{
return LoadJsonObj(Path.Combine(ServerInboundsDir, name));
}
private static dynamic LoadJsonObj(string path)
{
if (File.Exists(path))

View file

@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.ViewModels.Developers
namespace ProxySU_Core.Models.Developers
{
public interface IParameters
{
int Port { get; set; }
string Domain { get; set; }
List<XrayType> Types { get; set; }
}
}

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
{
@ -221,10 +222,7 @@ namespace ProxySU_Core.ViewModels.Developers
}
}
/// <summary>
/// 配置防火墙
/// </summary>
protected void ConfigureFirewall()
protected void ClosePort(params int[] portList)
{
string cmd;
@ -239,43 +237,88 @@ namespace ProxySU_Core.ViewModels.Developers
RunCmd("systemctl restart firewalld");
}
if (Parameters.Port == 443)
foreach (var port in portList)
{
RunCmd("firewall-cmd --zone=public --add-port=80/tcp --permanent");
RunCmd("firewall-cmd --zone=public --add-port=443/tcp --permanent");
RunCmd("firewall-cmd --zone=public --add-port=80/udp --permanent");
RunCmd("firewall-cmd --zone=public --add-port=443/udp --permanent");
RunCmd("yes | firewall-cmd --reload");
RunCmd($"firewall-cmd --zone=public --remove-port={port}/tcp --permanent");
RunCmd($"firewall-cmd --zone=public --remove-port={port}/udp --permanent");
}
else
{
RunCmd($"firewall-cmd --zone=public --add-port={Parameters.Port}/tcp --permanent");
RunCmd($"firewall-cmd --zone=public --add-port={Parameters.Port}/udp --permanent");
RunCmd("yes | firewall-cmd --reload");
}
return;
RunCmd("yes | firewall-cmd --reload");
}
else
{
cmd = RunCmd("command -v ufw");
if (!string.IsNullOrEmpty(cmd))
{
foreach (var port in portList)
{
RunCmd($"ufw delete allow {port}/tcp");
RunCmd($"ufw delete allow {port}/udp");
}
RunCmd("yes | ufw reload");
}
}
}
cmd = RunCmd("command -v ufw");
protected void OpenPort(params int[] portList)
{
string cmd;
cmd = RunCmd("command -v firewall-cmd");
if (!string.IsNullOrEmpty(cmd))
{
if (Parameters.Port == 443)
//有很奇怪的vps主机在firewalld未运行时端口是关闭的无法访问。所以要先启动firewalld
//用于保证acme.sh申请证书成功
cmd = RunCmd("firewall-cmd --state");
if (cmd.Trim() != "running")
{
RunCmd("ufw allow 80/tcp");
RunCmd("ufw allow 443/tcp");
RunCmd("ufw allow 80/udp");
RunCmd("ufw allow 443/udp");
RunCmd("yes | ufw reload");
RunCmd("systemctl restart firewalld");
}
else
foreach (var port in portList)
{
RunCmd($"ufw allow {Parameters.Port}/tcp");
RunCmd($"ufw allow {Parameters.Port}/udp");
RunCmd($"firewall-cmd --zone=public --add-port={port}/tcp --permanent");
RunCmd($"firewall-cmd --zone=public --add-port={port}/udp --permanent");
}
RunCmd("yes | firewall-cmd --reload");
}
else
{
cmd = RunCmd("command -v ufw");
if (!string.IsNullOrEmpty(cmd))
{
foreach (var port in portList)
{
RunCmd($"ufw allow {port}/tcp");
RunCmd($"ufw allow {port}/udp");
}
RunCmd("yes | ufw reload");
}
}
}
/// <summary>
/// 配置防火墙
/// </summary>
protected void ConfigureFirewall()
{
var portList = new List<int>();
portList.Add(80);
portList.Add(Parameters.Port);
if (Parameters.Types.Contains(XrayType.ShadowsocksAEAD))
{
portList.Add(ConfigBuilder.ShadowSocksPort);
}
if (Parameters.Types.Contains(XrayType.VMESS_KCP))
{
portList.Add(ConfigBuilder.VMESS_mKCP_Port);
}
OpenPort(portList.ToArray());
}
/// <summary>
/// 配置同步时间差
/// </summary>
@ -356,29 +399,16 @@ namespace ProxySU_Core.ViewModels.Developers
RunCmd("rm -rf caddy_install.sh");
RunCmd("curl -o caddy_install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/Caddy-Naive/caddy-naive-install.sh");
RunCmd("yes | bash caddy_install.sh");
RunCmd("rm -rf caddy_install.sh");
}
//if (CmdType == CmdType.Apt)
//{
// RunCmd("sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https");
// RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -");
// RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list");
// RunCmd(GetUpdateCmd());
// RunCmd("sudo apt install caddy");
//}
//else if (CmdType == CmdType.Dnf)
//{
// RunCmd("echo y | dnf install 'dnf-command(copr)'");
// RunCmd("echo y | dnf copr enable @caddy/caddy");
// RunCmd(GetUpdateCmd());
// RunCmd("dnf install caddy");
//}
//else if (CmdType == CmdType.Yum)
//{
// RunCmd("echo y | echo y | yum install yum-plugin-copr");
// RunCmd("echo y | echo y | yum copr enable @caddy/caddy");
// RunCmd(GetUpdateCmd());
// RunCmd("yum install caddy");
//}
protected void UninstallCaddy()
{
RunCmd("rm -rf caddy_install.sh");
RunCmd("curl -o caddy_install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/Caddy-Naive/caddy-naive-install.sh");
RunCmd("yes | bash caddy_install.sh uninstall");
RunCmd("rm -rf caddy_install.sh");
RunCmd("rm -rf /usr/share/caddy");
}

View file

@ -8,7 +8,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ProxySU_Core.Models;
namespace ProxySU_Core.ViewModels.Developers
namespace ProxySU_Core.Models.Developers
{
public class XrayProject : Project<XraySettings>
{
@ -29,52 +29,10 @@ namespace ProxySU_Core.ViewModels.Developers
{
}
public void InstallCert()
{
EnsureRootAuth();
EnsureSystemEnv();
this.InstallCertToXray();
RunCmd("systemctl restart xray");
WriteOutput("************ 安装证书完成 ************");
}
public void UploadWeb(Stream stream)
{
EnsureRootAuth();
EnsureSystemEnv();
if (!FileExists("/usr/share/caddy"))
{
RunCmd("mkdir /usr/share/caddy");
}
RunCmd("rm -rf /usr/share/caddy/*");
UploadFile(stream, "/usr/share/caddy/caddy.zip");
RunCmd("unzip /usr/share/caddy/caddy.zip -d /usr/share/caddy");
RunCmd("chmod -R 777 /usr/share/caddy");
UploadCaddyFile(useCustomWeb: true);
WriteOutput("************ 上传网站模板完成 ************");
}
public void UpdateXraySettings()
{
EnsureRootAuth();
EnsureSystemEnv();
var configJson = ConfigBuilder.BuildXrayConfig(Parameters);
var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson));
RunCmd("rm -rf /usr/local/etc/xray/config.json");
UploadFile(stream, "/usr/local/etc/xray/config.json");
RunCmd("systemctl restart xray");
WriteOutput("************ 更新Xray配置成功更新配置不包含域名如果域名更换请重新安装。 ************");
}
public void ReinstallCaddy()
{
EnsureRootAuth();
EnsureSystemEnv();
InstallCaddy();
UploadCaddyFile();
WriteOutput("************ 重装Caddy完成 ************");
}
/// <summary>
/// 安装Xray
/// </summary>
public override void Install()
{
try
@ -111,7 +69,7 @@ namespace ProxySU_Core.ViewModels.Developers
ConfigureFirewall();
WriteOutput("防火墙配置完成");
WriteOutput("同步系统和本地间...");
WriteOutput("同步系统和本地间...");
SyncTimeDiff();
WriteOutput("时间同步完成");
@ -138,10 +96,152 @@ namespace ProxySU_Core.ViewModels.Developers
}
catch (Exception ex)
{
MessageBox.Show("安装终止," + ex.Message);
var errorLog = "安装终止," + ex.Message;
WriteOutput(errorLog);
MessageBox.Show(errorLog);
}
}
public void Uninstall()
{
EnsureRootAuth();
WriteOutput("卸载Caddy");
UninstallCaddy();
WriteOutput("卸载Xray");
UninstallXray();
WriteOutput("卸载证书");
UninstallAcme();
WriteOutput("关闭端口");
ClosePort(ConfigBuilder.ShadowSocksPort, ConfigBuilder.VLESS_mKCP_Port, ConfigBuilder.VMESS_mKCP_Port);
WriteOutput("************ 卸载完成 ************");
}
/// <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();
ConfigureFirewall();
var configJson = ConfigBuilder.BuildXrayConfig(Parameters);
var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson));
RunCmd("rm -rf /usr/local/etc/xray/config.json");
UploadFile(stream, "/usr/local/etc/xray/config.json");
RunCmd("systemctl restart xray");
WriteOutput("************ 更新Xray配置成功更新配置不包含域名如果域名更换请重新安装。 ************");
}
/// <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);
@ -204,12 +304,24 @@ namespace ProxySU_Core.ViewModels.Developers
}
private void UninstallXray()
{
RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ remove");
}
private void UninstallAcme()
{
RunCmd("acme.sh --uninstall");
RunCmd("rm -r ~/.acme.sh");
}
private void InstallXrayWithCert()
{
RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install");
if (!FileExists("/usr/local/bin/xray"))
{
WriteOutput("Xray-Core安装失败请联系开发者");
throw new Exception("Xray-Core安装失败请联系开发者");
}
@ -251,6 +363,7 @@ namespace ProxySU_Core.ViewModels.Developers
}
else
{
WriteOutput("安装 acme.sh 失败,请联系开发者!");
throw new Exception("安装 acme.sh 失败,请联系开发者!");
}
@ -275,6 +388,7 @@ namespace ProxySU_Core.ViewModels.Developers
}
else
{
WriteOutput("申请证书失败,请联系开发者!");
throw new Exception("申请证书失败,请联系开发者!");
}
@ -288,6 +402,7 @@ namespace ProxySU_Core.ViewModels.Developers
}
else
{
WriteOutput("安装证书失败,请联系开发者!");
throw new Exception("安装证书失败,请联系开发者!");
}

View file

@ -0,0 +1,192 @@
using Newtonsoft.Json;
using ProxySU_Core.Common;
using ProxySU_Core.Models.Developers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace ProxySU_Core.Models
{
public class ShareLink
{
public static string Build(XrayType xrayType, XraySettings settings)
{
switch (xrayType)
{
case XrayType.VLESS_TCP:
case XrayType.VLESS_TCP_XTLS:
case XrayType.VLESS_WS:
case XrayType.Trojan_TCP:
return BuildVlessShareLink(xrayType, settings);
case XrayType.VMESS_TCP:
case XrayType.VMESS_WS:
case XrayType.VMESS_KCP:
return BuildVmessShareLink(xrayType, settings);
case XrayType.ShadowsocksAEAD:
return BuildShadowSocksShareLink(settings);
default:
return string.Empty;
}
}
private static string BuildShadowSocksShareLink(XraySettings settings)
{
var _method = settings.ShadowsocksMethod;
var _password = settings.ShadowsocksPassword;
var _server = settings.Domain;
var _port = ConfigBuilder.ShadowSocksPort;
var base64URL = Base64.Encode($"{_method}:{_password}@{_server}:{_port}");
return "ss://" + base64URL;
}
private static string BuildVmessShareLink(XrayType xrayType, XraySettings settings)
{
var vmess = new Vmess
{
v = "2",
add = settings.Domain,
port = settings.Port.ToString(),
id = settings.UUID,
aid = "0",
net = "",
type = "none",
host = settings.Domain,
path = "",
tls = "tls",
ps = "",
};
switch (xrayType)
{
case XrayType.VMESS_TCP:
vmess.ps = "vmess-tcp-tls";
vmess.net = "tcp";
vmess.type = "http";
vmess.path = settings.VMESS_TCP_Path;
break;
case XrayType.VMESS_WS:
vmess.ps = "vmess-ws-tls";
vmess.net = "ws";
vmess.type = "none";
vmess.path = settings.VMESS_WS_Path;
break;
case XrayType.VMESS_KCP:
vmess.ps = "vmess-mKCP";
vmess.port = ConfigBuilder.VMESS_mKCP_Port.ToString();
vmess.net = "kcp";
vmess.type = settings.VMESS_KCP_Type;
vmess.path = settings.VMESS_KCP_Seed;
vmess.tls = "";
break;
default:
return string.Empty;
}
var base64Url = Base64.Encode(JsonConvert.SerializeObject(vmess));
return $"vmess://" + base64Url;
}
private static string BuildVlessShareLink(XrayType xrayType, XraySettings settings)
{
var _protocol = string.Empty;
var _uuid = settings.UUID;
var _domain = settings.Domain;
var _port = settings.Port;
var _type = string.Empty;
var _encryption = string.Empty;
var _security = "tls";
var _path = "/";
var _host = settings.Domain;
var _descriptiveText = string.Empty;
switch (xrayType)
{
case XrayType.VLESS_TCP:
_protocol = "vless";
_type = "tcp";
_encryption = "none";
_descriptiveText = "vless-tcp-tls";
break;
case XrayType.VLESS_TCP_XTLS:
_protocol = "vless";
_type = "tcp";
_security = "xtls";
_encryption = "none";
_descriptiveText = "vless-tcp-xtls";
break;
case XrayType.VLESS_WS:
_protocol = "vless";
_type = "ws";
_path = settings.VLESS_WS_Path;
_encryption = "none";
_descriptiveText = "vless-ws-tls";
break;
case XrayType.VMESS_TCP:
_protocol = "vmess";
_type = "tcp";
_path = settings.VMESS_TCP_Path;
_encryption = "auto";
_descriptiveText = "vmess-tcp-tls";
break;
case XrayType.VMESS_WS:
_protocol = "vmess";
_type = "ws";
_path = settings.VMESS_WS_Path;
_encryption = "auto";
_descriptiveText = "vmess-ws-tls";
break;
case XrayType.Trojan_TCP:
_protocol = "trojan";
_uuid = settings.TrojanPassword;
_descriptiveText = "trojan-tcp";
break;
default:
throw new Exception("暂未实现的协议");
}
string parametersURL = string.Empty;
if (xrayType != XrayType.Trojan_TCP)
{
// 4.3 传输层相关段
parametersURL = $"?type={_type}&encryption={_encryption}&security={_security}&host={_host}&path={HttpUtility.UrlEncode(_path)}";
// if mKCP
// if QUIC
// 4.4 TLS 相关段
if (xrayType == XrayType.VLESS_TCP_XTLS)
{
parametersURL += "&flow=xtls-rprx-direct";
}
}
return $"{_protocol}://{HttpUtility.UrlEncode(_uuid)}@{_domain}:{_port}{parametersURL}#{HttpUtility.UrlEncode(_descriptiveText)}";
}
}
class Vmess
{
public string v { get; set; }
public string ps { get; set; }
public string add { get; set; }
public string port { get; set; }
public string id { get; set; }
public string aid { get; set; }
public string net { get; set; }
public string type { get; set; }
public string host { get; set; }
public string path { get; set; }
public string tls { get; set; }
}
}

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
{
@ -15,12 +18,22 @@ namespace ProxySU_Core.Models
var guid = Guid.NewGuid().ToString();
Port = 443;
UUID = guid;
Types = new List<XrayType> { XrayType.VLESS_TCP_XTLS };
Types = new List<XrayType>();
VLESS_WS_Path = "/vlessws";
VLESS_TCP_Path = "/vlesstcp";
VLESS_H2_Path = "/vlessh2";
VMESS_WS_Path = "/vmessws";
VMESS_TCP_Path = "/vmesstcp";
VMESS_H2_Path = "/vmessh2";
VMESS_KCP_Seed = guid;
VMESS_KCP_Type = "none";
TrojanPassword = guid;
Trojan_WS_Path = "/trojanws";
ShadowsocksPassword = guid;
ShadowsocksMethod = "aes-128-gcm";
}
/// <summary>
@ -33,16 +46,19 @@ namespace ProxySU_Core.Models
/// </summary>
public string UUID { get; set; }
#region vless
/// <summary>
/// vless ws路径
/// </summary>
public string VLESS_WS_Path { get; set; }
/// <summary>
/// vless tcp路径
/// vless http2 path
/// </summary>
public string VLESS_TCP_Path { get; set; }
public string VLESS_H2_Path { get; set; }
#endregion
#region vmess
/// <summary>
/// vmess ws路径
/// </summary>
@ -53,11 +69,47 @@ namespace ProxySU_Core.Models
/// </summary>
public string VMESS_TCP_Path { get; set; }
/// <summary>
/// vmess http2 path
/// </summary>
public string VMESS_H2_Path { get; set; }
/// <summary>
/// vmess kcp seed
/// </summary>
public string VMESS_KCP_Seed { get; set; }
/// <summary>
/// vmess kcp type
/// </summary>
public string VMESS_KCP_Type { get; set; }
#endregion
#region Trojan
/// <summary>
/// trojan密码
/// </summary>
public string TrojanPassword { get; set; }
/// <summary>
/// trojan ws path
/// </summary>
public string Trojan_WS_Path { get; set; }
#endregion
#region ShadowsocksAEAD
/// <summary>
/// ss password
/// </summary>
public string ShadowsocksPassword { get; set; }
/// <summary>
/// ss method
/// </summary>
public string ShadowsocksMethod { get; set; }
#endregion
/// <summary>
/// 域名
/// </summary>
@ -78,33 +130,55 @@ namespace ProxySU_Core.Models
{
switch (type)
{
case XrayType.VLESS_TCP_TLS:
return VLESS_TCP_Path;
case XrayType.VLESS_TCP_XTLS:
return VLESS_TCP_Path;
case XrayType.VLESS_WS_TLS:
case XrayType.VLESS_WS:
return VLESS_WS_Path;
case XrayType.VMESS_TCP_TLS:
case XrayType.VLESS_H2:
return VLESS_H2_Path;
case XrayType.VMESS_TCP:
return VMESS_TCP_Path;
case XrayType.VMESS_WS_TLS:
case XrayType.VMESS_WS:
return VMESS_WS_Path;
case XrayType.Trojan_TCP_TLS:
case XrayType.Trojan_WS:
return Trojan_WS_Path;
// no path
case XrayType.VLESS_TCP_XTLS:
case XrayType.VLESS_TCP:
case XrayType.VLESS_KCP:
case XrayType.VMESS_KCP:
case XrayType.Trojan_TCP:
return string.Empty;
default:
return string.Empty;
}
}
}
public enum XrayType
{
VLESS_TCP_TLS,
VLESS_TCP_XTLS,
VLESS_WS_TLS,
// 入口
VLESS_TCP_XTLS = 100,
VMESS_TCP_TLS,
VMESS_WS_TLS,
// vless 101开头
VLESS_TCP = 101,
VLESS_WS = 102,
VLESS_H2 = 103,
VLESS_KCP = 104,
Trojan_TCP_TLS
// vmess 201开头
VMESS_TCP = 201,
VMESS_WS = 202,
VMESS_H2 = 203,
VMESS_KCP = 204,
// trojan 301开头
Trojan_TCP = 301,
Trojan_WS = 302,
// ss
ShadowsocksAEAD = 401
}
}

View file

@ -51,5 +51,5 @@ using System.Windows;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("3.1.0.0")]
[assembly: AssemblyFileVersion("3.1.0.0")]

BIN
ProxySU_Core/ProxySU.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -62,7 +62,10 @@
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>ProxySU.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="ControlzEx, Version=5.0.0.0, Culture=neutral, PublicKeyToken=69f1c32f803d307e, processorArchitecture=MSIL">
@ -117,22 +120,26 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Common\Base64.cs" />
<Compile Include="Converters\LoginSecretTypeConverter.cs" />
<Compile Include="Converters\VisibleConverter.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" />
<Compile Include="Models\LoginSecretType.cs" />
<Compile Include="Models\Record.cs" />
<Compile Include="ViewModels\IdValueViewModel.cs" />
<Compile Include="ViewModels\RecordViewModel.cs" />
<Compile Include="ViewModels\Terminal.cs" />
<Compile Include="ViewModels\XraySettingsViewModel.cs" />
@ -148,6 +155,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" />
@ -233,19 +243,37 @@
<None Include="Templates\xray\server\05_inbounds\05_inbounds.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\Trojan_TCP_TLS.json">
<None Include="Templates\xray\server\05_inbounds\Shadowsocks-AEAD.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\Trojan_TCP.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\Trojan_WS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VLESS_HTTP2.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VLESS_KCP.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">
<None Include="Templates\xray\server\05_inbounds\VLESS_WS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_TCP_TLS.json">
<None Include="Templates\xray\server\05_inbounds\VMESS_HTTP2.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_WS_TLS.json">
<None Include="Templates\xray\server\05_inbounds\VMESS_KCP.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_TCP.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\05_inbounds\VMESS_WS.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Templates\xray\server\06_outbounds\06_outbounds.json">
@ -293,6 +321,10 @@
<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\" />
@ -309,6 +341,12 @@
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\ProxySU.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="ProxySU.ico" />
</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')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,13 @@
{
"port": 12345,
"protocol": "shadowsocks",
"settings": {
"clients": [
{
"password": "",
"method": "aes-128-gcm"
}
],
"network": "tcp,udp"
}
}

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

@ -0,0 +1,23 @@
{
"port": 3456,
"protocol": "vless",
"settings": {
"clients": [
{
"id": ""
}
]
},
"streamSettings": {
"network": "mkcp",
"kcpSettings": {
"uplinkCapacity": 100,
"downlinkCapacity": 100,
"congestion": true,
"header": {
"type": "none"
},
"seed": null
}
}
}

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,6 +15,8 @@
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"allowInsecure": false,
"minVersion": "1.2",
"alpn": [
"http/1.1"
],

View file

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

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

@ -0,0 +1,23 @@
{
"port": 3456,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": ""
}
]
},
"streamSettings": {
"network": "mkcp",
"kcpSettings": {
"uplinkCapacity": 100,
"downlinkCapacity": 100,
"congestion": true,
"header": {
"type": "none"
},
"seed": null
}
}
}

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

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

View file

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProxySU_Core.ViewModels
{
public class IdValueViewModel
{
public IdValueViewModel(int id, string value)
{
Id = id;
Value = value;
}
public int Id { get; set; }
public string Value { get; set; }
}
}

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

@ -1,27 +1,36 @@
using ProxySU_Core.Models;
using ProxySU_Core.ViewModels.Developers;
using Newtonsoft.Json;
using ProxySU_Core.Common;
using ProxySU_Core.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows;
using System.Windows.Controls;
namespace ProxySU_Core.ViewModels
{
public class XraySettingsViewModel : BaseViewModel
public partial class XraySettingsViewModel : BaseViewModel
{
public XraySettings settings;
public XraySettingsViewModel(XraySettings parameters)
{
this.settings = parameters;
Notify("VMESS_KCP_Type");
}
public string UUID
{
get => settings.UUID;
set => settings.UUID = value;
set
{
settings.UUID = value;
Notify("UUID");
}
}
public string Domain
@ -36,203 +45,226 @@ namespace ProxySU_Core.ViewModels
set => settings.MaskDomain = value;
}
public string VLESS_TCP_Path
{
get => settings.VLESS_TCP_Path;
set => settings.VLESS_TCP_Path = value;
}
public string VLESS_WS_Path
{
get => settings.VLESS_WS_Path;
set => settings.VLESS_WS_Path = value;
}
public string VMESS_TCP_Path
{
get => settings.VMESS_TCP_Path;
set => settings.VMESS_TCP_Path = value;
}
public string VMESS_WS_Path
{
get => settings.VMESS_WS_Path;
set => settings.VMESS_WS_Path = value;
}
public string TrojanPassword
{
get => settings.TrojanPassword;
set => settings.TrojanPassword = value;
}
public bool Checked_VLESS_TCP
{
get
{
return settings.Types.Contains(XrayType.VLESS_TCP_TLS);
}
set
{
if (value == true)
{
if (!settings.Types.Contains(XrayType.VLESS_TCP_TLS))
settings.Types.Add(XrayType.VLESS_TCP_TLS);
}
else
{
settings.Types.Remove(XrayType.VLESS_TCP_TLS);
}
Notify("Checked_VLESS_TCP");
Notify("VLESS_TCP_Path_Visibility");
}
}
public bool Checked_VLESS_XTLS
{
get
{
return settings.Types.Contains(XrayType.VLESS_TCP_XTLS);
}
set
{
if (value == true)
{
if (!settings.Types.Contains(XrayType.VLESS_TCP_XTLS))
settings.Types.Add(XrayType.VLESS_TCP_XTLS);
}
else
{
settings.Types.Remove(XrayType.VLESS_TCP_XTLS);
}
Notify("Checked_VLESS_XTLS");
}
}
public bool Checked_VLESS_WS
{
get
{
return settings.Types.Contains(XrayType.VLESS_WS_TLS);
}
set
{
if (value == true)
{
if (!settings.Types.Contains(XrayType.VLESS_WS_TLS))
settings.Types.Add(XrayType.VLESS_WS_TLS);
}
else
{
settings.Types.Remove(XrayType.VLESS_WS_TLS);
}
Notify("Checked_VLESS_WS");
Notify("VLESS_WS_Path_Visibility");
}
}
public bool Checked_VMESS_TCP
{
get
{
return settings.Types.Contains(XrayType.VMESS_TCP_TLS);
}
set
{
if (value == true)
{
if (!settings.Types.Contains(XrayType.VMESS_TCP_TLS))
settings.Types.Add(XrayType.VMESS_TCP_TLS);
}
else
{
settings.Types.Remove(XrayType.VMESS_TCP_TLS);
}
Notify("Checked_VMESS_TCP");
Notify("VMESS_TCP_Path_Visibility");
}
}
public bool Checked_VMESS_WS
{
get
{
return settings.Types.Contains(XrayType.VMESS_WS_TLS);
}
set
{
if (value == true)
{
if (!settings.Types.Contains(XrayType.VMESS_WS_TLS))
settings.Types.Add(XrayType.VMESS_WS_TLS);
}
else
{
settings.Types.Remove(XrayType.VMESS_WS_TLS);
}
Notify("Checked_VMESS_WS");
Notify("VMESS_WS_Path_Visibility");
}
}
public bool Checked_Trojan_TCP
{
get
{
return settings.Types.Contains(XrayType.Trojan_TCP_TLS);
return settings.Types.Contains(XrayType.Trojan_TCP);
}
set
{
if (value == true)
{
if (!settings.Types.Contains(XrayType.Trojan_TCP_TLS))
settings.Types.Add(XrayType.Trojan_TCP_TLS);
if (!settings.Types.Contains(XrayType.Trojan_TCP))
settings.Types.Add(XrayType.Trojan_TCP);
}
else
{
settings.Types.Remove(XrayType.Trojan_TCP_TLS);
settings.Types.Remove(XrayType.Trojan_TCP);
}
Notify("Checked_Trojan_TCP");
Notify("Trojan_TCP_Pwd_Visibility");
}
}
public string Trojan_TCP_ShareLink
{
get => ShareLink.Build(XrayType.Trojan_TCP, settings);
}
public Visibility VLESS_TCP_Path_Visibility
private List<string> _ssMethods = new List<string> { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305" };
public List<string> ShadowSocksMethods => _ssMethods;
public bool CheckedShadowSocks
{
get
get => settings.Types.Contains(XrayType.ShadowsocksAEAD);
set
{
return Checked_VLESS_TCP ? Visibility.Visible : Visibility.Hidden;
CheckBoxChanged(value, XrayType.ShadowsocksAEAD);
Notify("CheckedShadowSocks");
}
}
public Visibility VLESS_WS_Path_Visibility
public string ShadowSocksPassword
{
get
get => settings.ShadowsocksPassword;
set => settings.ShadowsocksPassword = value;
}
public string ShadowSocksMethod
{
get => settings.ShadowsocksMethod;
set
{
return Checked_VLESS_WS ? Visibility.Visible : Visibility.Hidden;
var namespaceStr = typeof(ComboBoxItem).FullName + ":";
var trimValue = value.Replace(namespaceStr, "");
trimValue = trimValue.Trim();
settings.ShadowsocksMethod = trimValue;
Notify("ShadowSocksMethod");
}
}
public Visibility VMESS_TCP_Path_Visibility
public string ShadowSocksShareLink
{
get
{
return Checked_VMESS_TCP ? Visibility.Visible : Visibility.Hidden;
}
get => ShareLink.Build(XrayType.ShadowsocksAEAD, settings);
}
public Visibility VMESS_WS_Path_Visibility
private void CheckBoxChanged(bool value, XrayType type)
{
get
if (value == true)
{
return Checked_VMESS_WS ? Visibility.Visible : Visibility.Hidden;
if (!settings.Types.Contains(type))
{
settings.Types.Add(type);
}
}
}
public Visibility Trojan_TCP_Pwd_Visibility
{
get
else
{
return Checked_Trojan_TCP ? Visibility.Visible : Visibility.Hidden;
settings.Types.RemoveAll(x => x == type);
}
}
}
public partial class XraySettingsViewModel
{
// vmess tcp
public bool Checked_VMESS_TCP
{
get => settings.Types.Contains(XrayType.VMESS_TCP);
set
{
CheckBoxChanged(value, XrayType.VMESS_TCP);
Notify("Checked_VMESS_TCP");
}
}
public string VMESS_TCP_Path
{
get => settings.VMESS_TCP_Path;
set => settings.VMESS_TCP_Path = value;
}
public string VMESS_TCP_ShareLink
{
get => ShareLink.Build(XrayType.VMESS_TCP, settings);
}
// vmess ws
public bool Checked_VMESS_WS
{
get => settings.Types.Contains(XrayType.VMESS_WS);
set
{
CheckBoxChanged(value, XrayType.VMESS_WS);
Notify("Checked_VMESS_WS");
}
}
public string VMESS_WS_Path
{
get => settings.VMESS_WS_Path;
set => settings.VMESS_WS_Path = value;
}
public string VMESS_WS_ShareLink
{
get => ShareLink.Build(XrayType.VMESS_WS, settings);
}
// vmess kcp
public string VMESS_KCP_Seed
{
get => settings.VMESS_KCP_Seed;
set => settings.VMESS_KCP_Seed = value;
}
public string VMESS_KCP_Type
{
get => settings.VMESS_KCP_Type;
set
{
var namespaceStr = typeof(ComboBoxItem).FullName + ":";
var trimValue = value.Replace(namespaceStr, "");
trimValue = trimValue.Trim();
settings.VMESS_KCP_Type = trimValue;
Notify("VMESS_KCP_Type");
}
}
public bool Checked_VMESS_KCP
{
get => settings.Types.Contains(XrayType.VMESS_KCP);
set
{
CheckBoxChanged(value, XrayType.VMESS_KCP);
Notify("Checked_VMESS_KCP");
}
}
public string VMESS_KCP_ShareLink
{
get => ShareLink.Build(XrayType.VMESS_KCP, settings);
}
private List<string> _kcpTypes = new List<string> { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", };
public List<string> KcpTypes => _kcpTypes;
}
public partial class XraySettingsViewModel
{
// vless xtls
public bool Checked_VLESS_TCP_XTLS
{
get => settings.Types.Contains(XrayType.VLESS_TCP_XTLS);
set
{
CheckBoxChanged(value, XrayType.VLESS_TCP_XTLS);
Notify("Checked_VLESS_XTLS");
}
}
public string VLESS_TCP_XTLS_ShareLink
{
get => ShareLink.Build(XrayType.VLESS_TCP_XTLS, settings);
}
// vless tcp
public bool Checked_VLESS_TCP
{
get => settings.Types.Contains(XrayType.VLESS_TCP);
set
{
CheckBoxChanged(value, XrayType.VLESS_TCP);
Notify("Checked_VLESS_TCP");
}
}
public string VLESS_TCP_ShareLink
{
get => ShareLink.Build(XrayType.VLESS_TCP, settings);
}
// vless ws
public string VLESS_WS_Path
{
get => settings.VLESS_WS_Path;
set => settings.VLESS_WS_Path = value;
}
public bool Checked_VLESS_WS
{
get
{
return settings.Types.Contains(XrayType.VLESS_WS);
}
set
{
CheckBoxChanged(value, XrayType.VLESS_WS);
Notify("Checked_VLESS_WS");
}
}
public string VLESS_WS_ShareLink
{
get => ShareLink.Build(XrayType.VLESS_WS, settings);
}
}
}

View file

@ -5,8 +5,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:local="clr-namespace:ProxySU_Core.Views"
xmlns:dev="clr-namespace:ProxySU_Core.Models.Developers"
mc:Ignorable="d"
Title="查看配置" Height="450" Width="800">
Title="查看配置" Height="500" Width="800">
<Grid>
<TabControl
Background="#fff"
@ -34,7 +37,7 @@
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="流控(flow)" Width="120" />
<TextBox Text="xtls-rprx-direct" IsReadOnly="True" Width="200" />
<TextBox Text="xtls-rprx-splice" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
@ -65,7 +68,12 @@
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="xtls" IsReadOnly="True" Width="200" />
</StackPanel>
</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"
@ -122,6 +130,11 @@
<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_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
@ -178,6 +191,11 @@
<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_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
@ -229,12 +247,17 @@
<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_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">
Header="VMESS-WebSocket-TLS">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="地址(address)" Width="120" />
@ -280,6 +303,67 @@
<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_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.Checked_VMESS_WS}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="VMESS-mKCP">
<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="{Binding Source={x:Static dev:ConfigBuilder.VMESS_mKCP_Port},Mode=OneTime}" 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="kcp" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="伪装类型(type)" Width="120" />
<TextBox Text="{Binding Settings.VMESS_KCP_Type}" 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_KCP_Seed}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="传输安全(tls)" Width="120" />
<TextBox Text="" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.VMESS_KCP_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
@ -301,9 +385,44 @@
<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_ShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Width="200"
IsEnabled="{Binding Settings.CheckedShadowSocks}"
Style="{StaticResource MaterialDesignNavigationRailTabItem}"
Header="ShadowSocks">
<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="{Binding Source={x:Static dev:ConfigBuilder.ShadowSocksPort},Mode=OneTime}" IsReadOnly="True" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="密码" Width="120" />
<TextBox Text="{Binding Settings.ShadowSocksPassword}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="加密方式" Width="120" />
<TextBox Text="{Binding Settings.ShadowSocksMethod}" IsReadOnly="True" Width="300" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="分享链接" Width="120" />
<TextBox Text="{Binding Settings.ShadowSocksShareLink,Mode=OneTime}" Width="300" IsReadOnly="True" />
</StackPanel>
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</metro:MetroWindow>

View file

@ -26,6 +26,7 @@
<ComboBox
SelectionChanged="ChangeLanguage"
x:Name="cmbLanguage"
IsEnabled="False"
SelectedIndex="0">
<ComboBoxItem x:Name="zh_cn" Content="{DynamicResource LanguageChinese}"></ComboBoxItem>
<ComboBoxItem x:Name="en" Content="{DynamicResource LanguageEnglish}"></ComboBoxItem>
@ -54,9 +55,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}"
@ -71,6 +84,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"/>
@ -90,10 +107,10 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<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="控制台" FontSize="12" Height="24" Click="Connect" />
<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" />
<Button Content="编辑" FontSize="12" Height="24" Margin="10,0,0,0" Click="EditHost" />
<Button Content="删除" FontSize="12" Height="24" Margin="10,0,0,0" Click="DeleteHost" BorderBrush="IndianRed" Background="IndianRed" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>

View file

@ -1,28 +1,18 @@
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;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
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.Navigation;
using System.Windows.Shapes;
namespace ProxySU_Core
@ -117,6 +107,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)
{

View file

@ -8,23 +8,28 @@
xmlns:local="clr-namespace:ProxySU_Core.Views"
xmlns:converters="clr-namespace:ProxySU_Core.Converters"
mc:Ignorable="d"
Title="编辑主机信息" Height="800" Width="710">
Title="编辑主机信息" Height="600" Width="980">
<Window.Resources>
<converters:LoginSecretTypeConverter x:Key="LoginSecretTypeConverter" />
<converters:ProxyTypeConverter x:Key="ProxyTypeConverter" />
<converters:VisibleConverter x:Key="VisibleConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="320" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="300" />
<RowDefinition Height="5"/>
<RowDefinition Height="400" />
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="0" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="10">
<StackPanel Grid.Column="0" Grid.Row="0" Margin="10">
<GroupBox
Style="{StaticResource MaterialDesignHeaderedContentControl}"
Header="{StaticResource ConnectionGroupName}">
@ -94,7 +99,7 @@
Content="{DynamicResource KeyLogin}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding PasswordVisiblity}">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding Host.PasswordVisiblity}">
<TextBlock
Width="100"
Text="{DynamicResource HostPassword}"
@ -127,7 +132,7 @@
</GroupBox>
<GroupBox
Margin="20,0,0,0"
Margin="0,10,0,0"
Header="{DynamicResource ProxyGroupName}"
Style="{StaticResource MaterialDesignHeaderedContentControl}">
<StackPanel Margin="10">
@ -207,18 +212,19 @@
</GroupBox>
</StackPanel>
<GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" />
<GridSplitter Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" />
<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10">
<GroupBox
Padding="10"
Style="{StaticResource MaterialDesignHeaderedContentControl}"
Header="选择方式">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal" Grid.Column="2" Grid.Row="0" Margin="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<StackPanel>
<CheckBox Content="VLESS OVER TCP with XTLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VLESS_XTLS}"
IsChecked="{Binding Path=Settings.Checked_VLESS_TCP_XTLS}"
Margin="0,10,0,0" />
<Label Content="数倍性能首选方式不支持CDN" Margin="20,0,0,0" />
@ -246,17 +252,34 @@
Margin="0,10,0,0" />
<Label Content="常规支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VMess mKCP"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VMESS_KCP}"
Margin="0,10,0,0" />
<Label Content="低延迟,适用于游戏" Margin="20,0,0,0" />
<CheckBox Content="Trojan over TCP with TLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_Trojan_TCP}"
Margin="0,10,0,0" />
<Label Content="Torjan协议不支持CDN" Margin="20,0,0,0" />
<CheckBox Content="ShadowSocksAEAD"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.CheckedShadowSocks}"
Margin="0,10,0,0" />
<Label Content="俗称SS" Margin="20,0,0,0" />
</StackPanel>
<StackPanel Margin="120,0,0,0">
<StackPanel Margin="60,0,0,0">
<StackPanel Margin="0,0,0,0" Orientation="Horizontal">
<Label Content="UUID" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.UUID}" Width="200" />
<Button Style="{StaticResource MahApps.Styles.Button.Flat}"
Margin="5,0,0,0"
Click="RandomUuid"
Content="随机" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
@ -269,50 +292,109 @@
<TextBox Text="{Binding Path=Settings.MaskDomain}" Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.VLESS_TCP_Path_Visibility}">
<Label Content="VLESS-TCP-Path" Width="120" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.VLESS_TCP_Path}"
IsEnabled="{Binding Checked_VLESS_TCP}"
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.VLESS_WS_Path_Visibility}">
<Label Content="VLESS-WS-Path" Width="120" VerticalAlignment="Center" />
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.Checked_VLESS_WS,
Converter={StaticResource VisibleConverter}
}">
<Label Content="VLESS-WS" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.VLESS_WS_Path}"
IsEnabled="{Binding Checked_VLESS_WS}"
Width="200" />
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.VMESS_TCP_Path_Visibility}">
<Label Content="VMESS-TCP-Path" Width="120" VerticalAlignment="Center" />
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.Checked_VMESS_TCP,
Converter={StaticResource VisibleConverter}
}">
<Label Content="VMESS-TCP" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.VMESS_TCP_Path}"
IsEnabled="{Binding Checked_VMESS_TCP}"
Width="200" />
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.VMESS_WS_Path_Visibility}">
<Label Content="VMESS-WS-Path" Width="120" VerticalAlignment="Center" />
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.Checked_VMESS_WS,
Converter={StaticResource VisibleConverter}
}">
<Label Content="VMESS-WS" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.VMESS_WS_Path}"
IsEnabled="{Binding Checked_VMESS_WS}"
Width="200" />
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.Trojan_TCP_Pwd_Visibility}">
<Label Content="Trojan密码" Width="120" VerticalAlignment="Center" />
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.Checked_Trojan_TCP,
Converter={StaticResource VisibleConverter}
}">
<Label Content="Trojan密码" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.TrojanPassword}"
IsEnabled="{Binding Checked_Trojan_TCP}"
Width="200" />
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.Checked_VMESS_KCP,
Converter={StaticResource VisibleConverter}
}">
<Label Content="KCP伪装" Width="80" VerticalAlignment="Center"/>
<ComboBox Width="200"
ItemsSource="{Binding Path=Settings.KcpTypes}"
SelectedValue="{Binding Settings.VMESS_KCP_Type,Mode=TwoWay}">
</ComboBox>
</StackPanel>
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.Checked_VMESS_KCP,
Converter={StaticResource VisibleConverter}
}">
<Label Content="KCP Seed" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.VMESS_KCP_Seed}"
Width="200"/>
</StackPanel>
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.CheckedShadowSocks,
Converter={StaticResource VisibleConverter}
}">
<Label Content="SS 密码" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.ShadowSocksPassword}"
Width="200"/>
</StackPanel>
<StackPanel Margin="0,10,0,0"
Orientation="Horizontal"
Visibility="{
Binding Path=Settings.CheckedShadowSocks,
Converter={StaticResource VisibleConverter}
}">
<Label Content="SS 加密方式" Width="80" VerticalAlignment="Center" />
<ComboBox Width="200"
ItemsSource="{Binding Settings.ShadowSocksMethods}"
SelectedValue="{Binding Settings.ShadowSocksMethod}">
</ComboBox>
</StackPanel>
</StackPanel>
</StackPanel>
</GroupBox>
<Button Content="保存"
Grid.Row="1"
HorizontalAlignment="Right"
Width="120"
Height="32"
Click="Save" />
</Grid>
</StackPanel>
<Button Content="保存"
Grid.Row="3"
Width="120" Height="32"
Click="Save"
HorizontalAlignment="Right"
Margin="0,0,20,0"></Button>
</Grid>
</metro:MetroWindow>

View file

@ -48,5 +48,11 @@ namespace ProxySU_Core.Views
DialogResult = true;
Close();
}
public void RandomUuid(object sender, RoutedEventArgs e)
{
Settings.UUID = Guid.NewGuid().ToString();
}
}
}

View file

@ -15,47 +15,80 @@
FontSize="14"
FontFamily="Consolas"
x:Name="OutputTextBox"
Height="320"
Height="260"
Text="{Binding Path=OutputText}"
/>
<StackPanel Margin="10"
Orientation="Horizontal"
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"
Click="Install"
Height="32"
IsEnabled="{Binding HasConnected}"
Width="100"/>
<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="32"
IsEnabled="{Binding HasConnected}"
Width="120"/>
<Button Content="更新Xray配置"
Margin="10,0,0,0"
Click="UpdateXraySettings"
Height="26"
IsEnabled="{Binding HasConnected}"
Width="120"/>
<Button Content="申请TLS证书"
Margin="10,0,0,0"
Height="32"
Width="120"
IsEnabled="{Binding HasConnected}"
Click="InstallCert"/>
<Button Content="卸载代理"
Margin="10,0,0,0"
Click="UninstallXray"
Height="26"
Width="120"
IsEnabled="{Binding HasConnected}"/>
</StackPanel>
<Button Content="上传伪装网站"
Margin="10,0,0,0"
Height="32"
Width="120"
IsEnabled="{Binding HasConnected}"
Click="UploadWeb"/>
<StackPanel Orientation="Horizontal"
Margin="0,10,0,0">
<TextBlock Text="证书/网站"
VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Button Content="重装Caddy"
Margin="10,0,0,0"
Click="ReinstallCaddy"
Height="32"
IsEnabled="{Binding HasConnected}"
Width="120"/>
<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">

View file

@ -1,8 +1,8 @@
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;
@ -44,7 +44,6 @@ namespace ProxySU_Core
_vm = new Terminal(record.Host);
DataContext = _vm;
WriteOutput("Connect ...");
Task.Factory.StartNew(() =>
{
try
@ -105,10 +104,21 @@ namespace ProxySU_Core
private void OpenConnect(Host host)
{
WriteOutput("正在登陆服务器 ...");
var conneInfo = CreateConnectionInfo(host);
_sshClient = new SshClient(conneInfo);
_sshClient.Connect();
WriteOutput("Connected");
try
{
_sshClient.Connect();
}
catch (Exception ex)
{
WriteOutput("登陆失败!");
WriteOutput(ex.Message);
return;
}
WriteOutput("登陆服务器成功!");
_vm.HasConnected = true;
project = new XrayProject(_sshClient, Record.Settings, WriteOutput);
@ -135,26 +145,11 @@ namespace ProxySU_Core
});
}
private void InstallCert(object sender, RoutedEventArgs e)
private void UpdateXrayCore(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
project.InstallCert();
});
}
private void UploadWeb(object sender, RoutedEventArgs e)
{
var fileDialog = new OpenFileDialog();
fileDialog.FileOk += OnFileOk;
fileDialog.ShowDialog();
}
private void ReinstallCaddy(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
project.ReinstallCaddy();
project.UpdateXrayCore();
});
}
@ -166,7 +161,47 @@ namespace ProxySU_Core
});
}
private void OnFileOk(object sender, CancelEventArgs e)
private void InstallCert(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
project.InstallCert();
});
}
private void UninstallXray(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
project.Uninstall();
});
}
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(() =>
{
@ -178,6 +213,18 @@ namespace ProxySU_Core
});
}
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;

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