1
0
mirror of https://github.com/proxysu/ProxySU.git synced 2024-11-28 16:16:07 +03:00

midify new

This commit is contained in:
next-autumn 2021-03-04 16:25:36 +08:00
parent 2fd76baf2f
commit e548affd70
29 changed files with 968 additions and 554 deletions

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProxySU_Core.Models
{
public class Host
{
public Host()
{
Proxy = new LocalProxy();
}
public string Tag { get; set; }
public string Address { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int Port { get; set; } = 22;
public string PrivateKeyPath { get; set; }
public LocalProxy Proxy { get; set; }
public LoginSecretType SecretType { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.Models
{
public class LocalProxy
{
public string Address { get; set; } = "127.0.0.1";
public int Port { get; set; } = 1080;
public LocalProxyType Type { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
}

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.ViewModels
namespace ProxySU_Core.Models
{
public enum LocalProxyType
{

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.ViewModels
namespace ProxySU_Core.Models
{
public enum LoginSecretType
{

View File

@ -0,0 +1,24 @@
using ProxySU_Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.Models
{
public class Record
{
public Record()
{
}
public Record(Host host)
{
this.Host = host;
}
public Host Host { get; set; } = new Host();
public XraySettings Settings { get; set; } = new XraySettings();
}
}

View File

@ -1,11 +1,28 @@
using System;
using ProxySU_Core.ViewModels.Developers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProxySU_Core.ViewModels.Developers
namespace ProxySU_Core.Models
{
public class XrayParameters : IParameters
public class XraySettings : IParameters
{
public XraySettings()
{
Port = 443;
UUID = Guid.NewGuid().ToString();
Types = new List<XrayType> { XrayType.VLESS_TCP_XTLS };
VLESS_WS_Path = "/vlessws";
VLESS_TCP_Path = "/vlesstcp";
VMESS_WS_Path = "/vmessws";
VMESS_TCP_Path = "/vmesstcp";
Trojan_TCP_Path = "/trojan";
TrojanPassword = Guid.NewGuid().ToString();
}
/// <summary>
/// 访问端口
/// </summary>
@ -19,27 +36,27 @@ namespace ProxySU_Core.ViewModels.Developers
/// <summary>
/// vless ws路径
/// </summary>
public string VlessWsPath { get; set; }
public string VLESS_WS_Path { get; set; }
/// <summary>
/// vless tcp路径
/// </summary>
public string VlessTcpPath { get; set; }
public string VLESS_TCP_Path { get; set; }
/// <summary>
/// vmess ws路径
/// </summary>
public string VmessWsPath { get; set; }
public string VMESS_WS_Path { get; set; }
/// <summary>
/// vmess tcp路径
/// </summary>
public string VmessTcpPath { get; set; }
public string VMESS_TCP_Path { get; set; }
/// <summary>
/// trojan tcp路径
/// </summary>
public string TrojanTcpPath { get; set; }
public string Trojan_TCP_Path { get; set; }
/// <summary>
/// trojan密码
@ -59,25 +76,25 @@ namespace ProxySU_Core.ViewModels.Developers
/// <summary>
/// 安装类型
/// </summary>
public XrayType Type { get; set; }
public List<XrayType> Types { get; set; }
public string GetPath()
public string GetPath(XrayType type)
{
switch (Type)
switch (type)
{
case XrayType.VLESS_TCP_TLS:
return VlessTcpPath;
return VLESS_TCP_Path;
case XrayType.VLESS_TCP_XTLS:
return VlessTcpPath;
return VLESS_TCP_Path;
case XrayType.VLESS_WS_TLS:
return VlessWsPath;
return VLESS_WS_Path;
case XrayType.VMESS_TCP_TLS:
return VmessTcpPath;
return VMESS_TCP_Path;
case XrayType.VMESS_WS_TLS:
return VmessWsPath;
return VMESS_WS_Path;
case XrayType.Trojan_TCP_TLS:
return TrojanTcpPath;
return Trojan_TCP_Path;
default:
return string.Empty;
}

View File

@ -182,35 +182,36 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Converters\LoginSecretTypeConverter.cs" />
<Compile Include="Models\Host.cs" />
<Compile Include="Models\XraySettings.cs" />
<Compile Include="Tools\DateTimeUtils.cs" />
<Compile Include="Tools\Extensions.cs" />
<Compile Include="ViewModels\BaseCommand.cs" />
<Compile Include="ViewModels\BaseModel.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\XrayParameters.cs" />
<Compile Include="ViewModels\Developers\XrayProject.cs" />
<Compile Include="ViewModels\Host.cs" />
<Compile Include="ViewModels\LocalProxy.cs" />
<Compile Include="ViewModels\LocalProxyType.cs" />
<Compile Include="ViewModels\LoginSecretType.cs" />
<Compile Include="ViewModels\Record.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\RecordViewModel.cs" />
<Compile Include="ViewModels\Terminal.cs" />
<Compile Include="Views\HostEditorWindow.xaml.cs">
<DependentUpon>HostEditorWindow.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModels\XraySettingsViewModel.cs" />
<Compile Include="Views\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\RecordEditorWindow.xaml.cs">
<DependentUpon>RecordEditorWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\TerminalWindow.xaml.cs">
<DependentUpon>TerminalWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\XrayWindow.xaml.cs">
<DependentUpon>XrayWindow.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Converters\LoginSecretTypeConverter.cs" />
<Compile Include="Converters\ProxyTypeConverter.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
@ -282,22 +283,18 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\HostEditorWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\RecordEditorWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\TerminalWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\XrayWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</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

@ -10,6 +10,7 @@
<sys:String x:Key="Actions">Actions</sys:String>
<sys:String x:Key="Connect">Connect</sys:String>
<sys:String x:Key="Edit">Edit</sys:String>
<sys:String x:Key="EditTemp">Edit Xray</sys:String>
<sys:String x:Key="Delete">Delete</sys:String>
<sys:String x:Key="Install">Install</sys:String>
<sys:String x:Key="Save">Save</sys:String>

View File

@ -11,6 +11,7 @@
<sys:String x:Key="Connect">连接</sys:String>
<sys:String x:Key="Install">安装</sys:String>
<sys:String x:Key="Edit">编辑</sys:String>
<sys:String x:Key="EditTemp">编辑模板</sys:String>
<sys:String x:Key="Delete">删除</sys:String>
<sys:String x:Key="Save">保存</sys:String>
<sys:String x:Key="Info">消息</sys:String>

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace System
{
public static class Extensions
{
// Deep clone
public static T DeepClone<T>(this T obj)
{
if (obj == null)
throw new ArgumentNullException("Object cannot be null");
return (T)Process(obj);
}
static object Process(object obj)
{
if (obj == null)
return null;
Type type = obj.GetType();
if (type.IsValueType || type == typeof(string))
{
return obj;
}
else if (type.IsArray)
{
Type elementType = Type.GetType(
type.FullName.Replace("[]", string.Empty));
var array = obj as Array;
Array copied = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++)
{
copied.SetValue(Process(array.GetValue(i)), i);
}
return Convert.ChangeType(copied, obj.GetType());
}
else if (type.IsClass)
{
object toret = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = type.GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
object fieldValue = field.GetValue(obj);
if (fieldValue == null)
continue;
field.SetValue(toret, Process(fieldValue));
}
return toret;
}
else
throw new ArgumentException("Unknown type");
}
}
}

View File

@ -5,7 +5,7 @@ using System.Text;
namespace ProxySU_Core.ViewModels
{
public abstract class BaseModel : INotifyPropertyChanged
public abstract class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

View File

@ -1,5 +1,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ProxySU_Core.Models;
using System;
using System.Collections.Generic;
using System.IO;
@ -57,11 +58,9 @@ namespace ProxySU_Core.ViewModels.Developers
stats = statsObj["stats"],
reverse = reverseObj["reverse"]
};
}
public static string BuildCaddyConfig(XrayParameters parameters)
public static string BuildCaddyConfig(XraySettings parameters)
{
var caddyStr = File.ReadAllText(Path.Combine(CaddyFileDir, "base.caddyfile"));
caddyStr.Replace("##domain##", parameters.Domain);
@ -77,11 +76,11 @@ namespace ProxySU_Core.ViewModels.Developers
return caddyStr;
}
public static string BuildXrayConfig(XrayParameters parameters)
public static string BuildXrayConfig(XraySettings parameters)
{
var xrayConfig = LoadXrayConfig();
var baseBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_TCP_XTLS.json"));
baseBound["port"] = VLESS_TCP_Port;
baseBound["port"] = parameters.Port;
baseBound["settings"]["fallbacks"].Add(new
{
dest = 80,
@ -89,52 +88,60 @@ namespace ProxySU_Core.ViewModels.Developers
});
xrayConfig["inbounds"].Add(baseBound);
switch (parameters.Type)
if (parameters.Types.Contains(XrayType.VLESS_TCP_XTLS))
{
case XrayType.VLESS_TCP_TLS:
case XrayType.VLESS_TCP_XTLS:
baseBound["settings"]["clients"][0]["id"] = parameters.UUID;
break;
case XrayType.VLESS_WS_TLS:
}
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;
wsInbound["streamSettings"]["wsSettings"]["path"] = parameters.VlessWsPath;
wsInbound["streamSettings"]["wsSettings"]["path"] = parameters.VLESS_WS_Path;
baseBound["settings"]["fallbacks"].Add(new
{
dest = VLESS_WS_Port,
path = parameters.VlessWsPath,
path = parameters.VLESS_WS_Path,
xver = 1,
});
xrayConfig["inbounds"].Add(wsInbound);
break;
case XrayType.VMESS_TCP_TLS:
}
if (parameters.Types.Contains(XrayType.VMESS_TCP_TLS))
{
var mtcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_TCP_TLS.json"));
mtcpBound["port"] = VMESS_TCP_Port;
mtcpBound["settings"]["clients"][0]["id"] = parameters.UUID;
mtcpBound["streamSettings"]["tcpSettings"]["header"]["request"]["path"] = parameters.VmessTcpPath;
mtcpBound["streamSettings"]["tcpSettings"]["header"]["request"]["path"] = parameters.VMESS_TCP_Path;
baseBound["settings"]["fallbacks"].Add(new
{
dest = VMESS_TCP_Port,
path = parameters.VmessTcpPath,
path = parameters.VMESS_TCP_Path,
xver = 1,
});
xrayConfig["inbounds"].Add(mtcpBound);
break;
case XrayType.VMESS_WS_TLS:
}
if (parameters.Types.Contains(XrayType.VMESS_WS_TLS))
{
var mwsBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_WS_TLS.json"));
mwsBound["port"] = VMESS_WS_Port;
mwsBound["settings"]["clients"][0]["id"] = parameters.UUID;
mwsBound["streamSettings"]["wsSettings"]["path"] = parameters.VmessWsPath;
mwsBound["streamSettings"]["wsSettings"]["path"] = parameters.VMESS_WS_Path;
baseBound["settings"]["fallbacks"].Add(new
{
dest = VMESS_WS_Port,
path = parameters.VmessWsPath,
path = parameters.VMESS_WS_Path,
xver = 1,
});
xrayConfig["inbounds"].Add(mwsBound);
break;
case XrayType.Trojan_TCP_TLS:
}
if (parameters.Types.Contains(XrayType.Trojan_TCP_TLS))
{
var trojanTcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "Trojan_TCP_TLS.json"));
trojanTcpBound["port"] = Trojan_TCP_Port;
trojanTcpBound["settings"]["clients"][0]["password"] = parameters.TrojanPassword;
@ -144,9 +151,6 @@ namespace ProxySU_Core.ViewModels.Developers
xver = 1,
};
xrayConfig["inbounds"].Add(trojanTcpBound);
break;
default:
break;
}
return JsonConvert.SerializeObject(xrayConfig, Formatting.Indented);

View File

@ -19,7 +19,7 @@ namespace ProxySU_Core.ViewModels.Developers
Yum
}
public abstract class Project<TParameters> : BaseModel where TParameters : IParameters
public abstract class Project<TParameters> : BaseViewModel where TParameters : IParameters
{
private SshClient _sshClient;

View File

@ -6,10 +6,11 @@ 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<XrayParameters>
public class XrayProject : Project<XraySettings>
{
private const string ServerLogDir = @"Templates\xray\server\00_log";
@ -24,7 +25,7 @@ namespace ProxySU_Core.ViewModels.Developers
private const string ServerReverseDir = @"Templates\xray\server\09_reverse";
private const string CaddyFileDir = @"Templates\xray\caddy";
public XrayProject(SshClient sshClient, XrayParameters parameters, Action<string> writeOutput) : base(sshClient, parameters, writeOutput)
public XrayProject(SshClient sshClient, XraySettings parameters, Action<string> writeOutput) : base(sshClient, parameters, writeOutput)
{
}

View File

@ -1,5 +1,6 @@
using Microsoft.Win32;
using Newtonsoft.Json;
using ProxySU_Core.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -8,66 +9,79 @@ using System.Windows.Input;
namespace ProxySU_Core.ViewModels
{
public class Host : BaseModel
public class HostViewModel : BaseViewModel
{
private LoginSecretType _secretType;
private string tag = string.Empty;
private string _address;
private LocalProxy proxy;
public Host host;
private readonly ICommand _selectKeyCommand;
public Host()
public HostViewModel(Host host)
{
_selectKeyCommand = new BaseCommand(obj => OpenFileDialog(obj));
Proxy = new LocalProxy();
this.host = host;
}
public string Tag
{
get => tag; set
get => host.Tag;
set
{
tag = value;
host.Tag = value;
Notify("Tag");
}
}
public string Address
{
get => _address;
get => host.Address;
set
{
_address = value;
host.Address = value;
Notify("Address");
}
}
public string UserName { get; set; }
public string UserName
{
get => host.UserName;
set => host.UserName = value;
}
public string Password { get; set; }
public string Password
{
get => host.Password;
set => host.Password = value;
}
public int Port { get; set; } = 22;
public int Port
{
get => host.Port;
set => host.Port = value;
}
public string PrivateKeyPath { get; set; }
public string PrivateKeyPath
{
get => host.PrivateKeyPath;
set => host.PrivateKeyPath = value;
}
public LocalProxy Proxy
{
get => proxy; set
get => host.Proxy;
set
{
proxy = value;
host.Proxy = value;
Notify("Proxy");
}
}
public LoginSecretType SecretType
{
get
{
return _secretType;
}
get => host.SecretType;
set
{
_secretType = value;
host.SecretType = value;
Notify("SecretType");
Notify("KeyUploaderVisiblity");
Notify("PasswordVisiblity");

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.ViewModels
{
public class LocalProxy : BaseModel
{
private LocalProxyType type = LocalProxyType.None;
public string Address { get; set; } = "127.0.0.1";
public int Port { get; set; } = 1080;
public LocalProxyType Type
{
get => type; set
{
type = value;
Notify("Type");
}
}
public string UserName { get; set; }
public string Password { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxySU_Core.ViewModels
{
public class Record
{
public Host Host { get; set; }
}
}

View File

@ -0,0 +1,40 @@
using ProxySU_Core.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProxySU_Core.ViewModels
{
public class RecordViewModel : BaseViewModel
{
public Record record;
public RecordViewModel(Record record)
{
this.record = record;
}
public Host Host
{
get => record.Host;
set
{
record.Host = value;
Notify("Host");
}
}
public XraySettings Settings
{
get => record.Settings;
set
{
record.Settings = value;
Notify("Settings");
}
}
}
}

View File

@ -1,11 +1,12 @@
using System;
using ProxySU_Core.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace ProxySU_Core.ViewModels
{
public class Terminal : BaseModel
public class Terminal : BaseViewModel
{
private string outputText;

View File

@ -0,0 +1,237 @@
using ProxySU_Core.Models;
using ProxySU_Core.ViewModels.Developers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace ProxySU_Core.ViewModels
{
public class XraySettingsViewModel : BaseViewModel
{
private XraySettings p;
public XraySettingsViewModel(XraySettings parameters)
{
this.p = parameters;
}
public string UUID
{
get => p.UUID;
set => p.UUID = value;
}
public string Domain
{
get => p.Domain;
set => p.Domain = value;
}
public string MaskDomain
{
get => p.MaskDomain;
set => p.MaskDomain = value;
}
public string VLESS_TCP_Path
{
get => p.VLESS_TCP_Path;
set => p.VLESS_TCP_Path = value;
}
public string VLESS_WS_Path
{
get => p.VLESS_WS_Path;
set => p.VLESS_WS_Path = value;
}
public string VMESS_TCP_Path
{
get => p.VMESS_TCP_Path;
set => p.VMESS_TCP_Path = value;
}
public string VMESS_WS_Path
{
get => p.VMESS_WS_Path;
set => p.VMESS_WS_Path = value;
}
public string Trojan_TCP_Path
{
get => p.Trojan_TCP_Path;
set => p.Trojan_TCP_Path = value;
}
public string TrojanPassword
{
get => p.TrojanPassword;
set => p.TrojanPassword = value;
}
public bool Checked_VLESS_TCP
{
get
{
return p.Types.Contains(XrayType.VLESS_TCP_TLS);
}
set
{
if (value == true)
{
p.Types.Add(XrayType.VLESS_TCP_TLS);
}
else
{
p.Types.Remove(XrayType.VLESS_TCP_TLS);
}
Notify("Checked_VLESS_TCP");
Notify("VLESS_TCP_Path_Visibility");
}
}
public bool Checked_VLESS_XTLS
{
get
{
return p.Types.Contains(XrayType.VLESS_TCP_XTLS);
}
set
{
if (value == true)
{
p.Types.Add(XrayType.VLESS_TCP_XTLS);
}
else
{
p.Types.Remove(XrayType.VLESS_TCP_XTLS);
}
Notify("Checked_VLESS_XTLS");
}
}
public bool Checked_VLESS_WS
{
get
{
return p.Types.Contains(XrayType.VLESS_WS_TLS);
}
set
{
if (value == true)
{
p.Types.Add(XrayType.VLESS_WS_TLS);
}
else
{
p.Types.Remove(XrayType.VLESS_WS_TLS);
}
Notify("Checked_VLESS_WS");
Notify("VLESS_WS_Path_Visibility");
}
}
public bool Checked_VMESS_TCP
{
get
{
return p.Types.Contains(XrayType.VMESS_TCP_TLS);
}
set
{
if (value == true)
{
p.Types.Add(XrayType.VMESS_TCP_TLS);
}
else
{
p.Types.Remove(XrayType.VMESS_TCP_TLS);
}
Notify("Checked_VMESS_TCP");
Notify("VMESS_TCP_Path_Visibility");
}
}
public bool Checked_VMESS_WS
{
get
{
return p.Types.Contains(XrayType.VMESS_WS_TLS);
}
set
{
if (value == true)
{
p.Types.Add(XrayType.VMESS_WS_TLS);
}
else
{
p.Types.Remove(XrayType.VMESS_WS_TLS);
}
Notify("Checked_VMESS_WS");
Notify("VMESS_WS_Path_Visibility");
}
}
public bool Checked_Trojan_TCP
{
get
{
return p.Types.Contains(XrayType.Trojan_TCP_TLS);
}
set
{
if (value == true)
{
p.Types.Add(XrayType.Trojan_TCP_TLS);
}
else
{
p.Types.Remove(XrayType.Trojan_TCP_TLS);
}
Notify("Checked_Trojan_TCP");
Notify("Trojan_TCP_Path_Visibility");
}
}
public Visibility VLESS_TCP_Path_Visibility
{
get
{
return Checked_VLESS_TCP ? Visibility.Visible : Visibility.Hidden;
}
}
public Visibility VLESS_WS_Path_Visibility
{
get
{
return Checked_VLESS_WS ? Visibility.Visible : Visibility.Hidden;
}
}
public Visibility VMESS_TCP_Path_Visibility
{
get
{
return Checked_VMESS_TCP ? Visibility.Visible : Visibility.Hidden;
}
}
public Visibility VMESS_WS_Path_Visibility
{
get
{
return Checked_VMESS_WS ? Visibility.Visible : Visibility.Hidden;
}
}
public Visibility Trojan_TCP_Path_Visibility
{
get
{
return Checked_Trojan_TCP ? Visibility.Visible : Visibility.Hidden;
}
}
}
}

View File

@ -1,206 +0,0 @@
<metro:MetroWindow x:Class="ProxySU_Core.HostEditorWindow"
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:converters="clr-namespace:ProxySU_Core.Converters"
xmlns:models="clr-namespace:ProxySU_Core.ViewModels"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
FontSize="14"
mc:Ignorable="d"
Title="{DynamicResource HostWindowTitle}" Height="650" Width="400">
<Window.Resources>
<converters:LoginSecretTypeConverter x:Key="LoginSecretTypeConverter" />
<converters:ProxyTypeConverter x:Key="ProxyTypeConverter" />
</Window.Resources>
<StackPanel VerticalAlignment="Top" Margin="10">
<GroupBox
Style="{StaticResource MaterialDesignHeaderedContentControl}"
Header="{StaticResource ConnectionGroupName}">
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostTag}"
VerticalAlignment="Center"/>
<TextBox
Text="{Binding Path=Tag}"
Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostAddress}"
VerticalAlignment="Center"/>
<TextBox
Text="{Binding Path=Address}"
Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostPort}"
VerticalAlignment="Center" />
<TextBox
Text="{Binding Path=Port}"
Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostUserName}"
VerticalAlignment="Center" />
<TextBox
Text="{Binding Path=UserName}"
Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostLoginType}"
VerticalAlignment="Center" />
<RadioButton
GroupName="LoginType"
IsChecked="{
Binding Path=SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.Password}
}"
Content="{DynamicResource PasswordLogin}" />
<RadioButton
Margin="10,0,0,0"
GroupName="LoginType"
IsChecked="{
Binding Path=SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.PrivateKey}
}"
Content="{DynamicResource KeyLogin}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0" Visibility="{Binding PasswordVisiblity}">
<TextBlock
Width="100"
Text="{DynamicResource HostPassword}"
VerticalAlignment="Center" />
<TextBox
IsEnabled="{
Binding Path=SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.Password}
}"
Text="{Binding Path=Password}"
Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0" Visibility="{Binding Path=KeyUploaderVisiblity}">
<TextBlock
Width="100"
Text="{DynamicResource KeyLoginField}"
VerticalAlignment="Center" />
<Button
IsEnabled="{
Binding Path=SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.PrivateKey}
}"
Command="{Binding Path=SelectKeyCommand}"
Content="{DynamicResource KeyUpload}" />
</StackPanel>
</StackPanel>
</GroupBox>
<GroupBox
Margin="0,20,0,0"
Header="{DynamicResource ProxyGroupName}"
Style="{StaticResource MaterialDesignHeaderedContentControl}">
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyType}" />
<RadioButton
GroupName="ProxyType"
Content="{StaticResource ProxyTypeNone}"
IsChecked="{
Binding Path=Proxy.Type,
Converter={StaticResource ProxyTypeConverter},
ConverterParameter={x:Static models:LocalProxyType.None}
}"/>
<RadioButton
Margin="10,0,0,0"
GroupName="ProxyType"
Content="{DynamicResource ProxyTypeHttp}"
IsChecked="{
Binding Path=Proxy.Type,
Converter={StaticResource ProxyTypeConverter},
ConverterParameter={x:Static models:LocalProxyType.Http}
}"/>
<RadioButton
Margin="10,0,0,0"
GroupName="ProxyType"
Content="{DynamicResource ProxyTypeSocks5}"
IsChecked="{
Binding Path=Proxy.Type,
Converter={StaticResource ProxyTypeConverter},
ConverterParameter={x:Static models:LocalProxyType.Socks5}
}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyHostName}"
VerticalAlignment="Center" />
<TextBox
Width="200"
Text="{Binding Path=Proxy.Address}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyHostPort}"
VerticalAlignment="Center"/>
<TextBox
Width="200"
Text="{Binding Path=Proxy.Port}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyUserName}"
VerticalAlignment="Center"/>
<TextBox
Width="200"
Text="{Binding Path=Proxy.UserName}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyPassword}"
VerticalAlignment="Center"/>
<TextBox
Width="200"
Text="{Binding Path=Proxy.Password}"/>
</StackPanel>
</StackPanel>
</GroupBox>
<Button
Margin="0,20,0,0"
Click="Save"
Content="{DynamicResource Save}" />
</StackPanel>
</metro:MetroWindow>

View File

@ -1,87 +0,0 @@
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using ProxySU_Core.ViewModels;
using System;
using System.Collections.Generic;
using System.Text;
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
{
/// <summary>
/// HostEditorWindow.xaml 的交互逻辑
/// </summary>
public partial class HostEditorWindow
{
private readonly Host vm;
public event EventHandler<Host> OnSaveEvent;
public HostEditorWindow(Host host = null)
{
ResizeMode = ResizeMode.NoResize;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
InitializeComponent();
vm = host ?? new Host();
DataContext = vm;
}
public void Save(object sender, RoutedEventArgs e)
{
var isValid = ValidateForm();
if (isValid == false) return;
OnSaveEvent?.Invoke(sender, vm);
Close();
}
private bool ValidateForm()
{
var res = Application.Current.Resources.MergedDictionaries[0];
var warning = Application.Current.FindResource("Warning").ToString();
if (string.IsNullOrWhiteSpace(vm.Address))
{
DialogManager.ShowMessageAsync(this,
warning,
res["HostAddressNotNull"].ToString());
return false;
}
if (vm.Port <= 0)
{
DialogManager.ShowMessageAsync(this,
res["Warning"].ToString(),
res["HostPortNotNull"].ToString());
return false;
}
if (vm.Proxy.Type > LocalProxyType.None)
{
if (string.IsNullOrEmpty(vm.Proxy.Address))
{
DialogManager.ShowMessageAsync(this,
res["Warning"].ToString(),
res["HostAddressNotNull"].ToString());
return false;
}
if (vm.Proxy.Port <= 0)
{
DialogManager.ShowMessageAsync(this,
res["Warning"].ToString(),
res["ProxyPortNotNull"].ToString());
return false;
}
}
return true;
}
}
}

View File

@ -5,7 +5,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProxySU_Core"
mc:Ignorable="d"
GlowBrush="{DynamicResource AccentColorBrush}"
BorderThickness="1"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
@ -64,7 +63,7 @@
Width="100"/>
</StackPanel>
<DataGrid ItemsSource="{Binding Path=ProjectList}"
<DataGrid ItemsSource="{Binding Records}"
Margin="0,20,0,0"
IsReadOnly="True"
x:Name="DataGrid"
@ -74,7 +73,6 @@
SelectionUnit="FullRow"
BorderBrush="#eee"
BorderThickness="1"
CopyingRowClipboardContent="DataGrid_CopyingRowClipboardContent"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="{DynamicResource HostTag}"

View File

@ -1,6 +1,9 @@
using MahApps.Metro.Controls.Dialogs;
using Newtonsoft.Json;
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;
@ -30,21 +33,26 @@ namespace ProxySU_Core
{
private const string RecordPath = @"Data\Record.json";
public ObservableCollection<Record> ProjectList { get; set; }
public ObservableCollection<RecordViewModel> Records { get; set; }
public MainWindow()
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
InitializeComponent();
ProjectList = new ObservableCollection<Record>();
Records = new ObservableCollection<RecordViewModel>();
if (File.Exists(RecordPath))
{
var recordsJson = File.ReadAllText(RecordPath, Encoding.UTF8);
var records = JsonConvert.DeserializeObject<List<Record>>(recordsJson);
records.ForEach(item => ProjectList.Add(item));
records.ForEach(item =>
{
Records.Add(new RecordViewModel(item));
});
}
DataContext = this;
}
@ -90,40 +98,31 @@ namespace ProxySU_Core
Application.Current.Resources.MergedDictionaries[0] = resource;
}
private void DataGrid_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e)
{
var currentCell = e.ClipboardRowContent[DataGrid.CurrentCell.Column.DisplayIndex];
e.ClipboardRowContent.Clear();
e.ClipboardRowContent.Add(currentCell);
}
private void AddHost(object sender, RoutedEventArgs e)
{
var hostWindow = new HostEditorWindow();
hostWindow.OnSaveEvent += (s, host) =>
{
ProjectList.Add(new Record() { Host = host });
};
var hostWindow = new RecordEditorWindow(new Record());
hostWindow.ShowDialog();
}
private void EditHost(object sender, RoutedEventArgs e)
{
if (DataGrid.SelectedItem is Record project)
if (DataGrid.SelectedItem is RecordViewModel project)
{
var hostWindow = new HostEditorWindow(project.Host);
var hostWindow = new RecordEditorWindow(project.record);
hostWindow.ShowDialog();
}
}
private void DeleteHost(object sender, RoutedEventArgs e)
{
if (DataGrid.SelectedItem is Record project)
if (DataGrid.SelectedItem is RecordViewModel project)
{
var result = MessageBox.Show($"您确认删除主机{project.Host.Tag}吗?", "提示", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
ProjectList.Remove(project);
Records.Remove(project);
}
}

View File

@ -0,0 +1,320 @@
<metro:MetroWindow x:Class="ProxySU_Core.Views.RecordEditorWindow"
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:models="clr-namespace:ProxySU_Core.Models"
xmlns:local="clr-namespace:ProxySU_Core.Views"
xmlns:converters="clr-namespace:ProxySU_Core.Converters"
mc:Ignorable="d"
Title="RecordEditorWindow" Height="800" Width="710">
<Window.Resources>
<converters:LoginSecretTypeConverter x:Key="LoginSecretTypeConverter" />
<converters:ProxyTypeConverter x:Key="ProxyTypeConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="300" />
<RowDefinition Height="5"/>
<RowDefinition Height="400" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="10">
<GroupBox
Style="{StaticResource MaterialDesignHeaderedContentControl}"
Header="{StaticResource ConnectionGroupName}">
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostTag}"
VerticalAlignment="Center"/>
<TextBox
Text="{Binding Path=Host.Tag}"
Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostAddress}"
VerticalAlignment="Center"/>
<TextBox
Text="{Binding Path=Host.Address}"
Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostPort}"
VerticalAlignment="Center" />
<TextBox
Text="{Binding Path=Host.Port}"
Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostUserName}"
VerticalAlignment="Center" />
<TextBox
Text="{Binding Path=Host.UserName}"
Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource HostLoginType}"
VerticalAlignment="Center" />
<RadioButton
GroupName="LoginType"
IsChecked="{
Binding Path=Host.SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.Password}
}"
Content="{DynamicResource PasswordLogin}" />
<RadioButton
Margin="10,0,0,0"
GroupName="LoginType"
IsChecked="{
Binding Path=Host.SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.PrivateKey}
}"
Content="{DynamicResource KeyLogin}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding PasswordVisiblity}">
<TextBlock
Width="100"
Text="{DynamicResource HostPassword}"
VerticalAlignment="Center" />
<TextBox
IsEnabled="{
Binding Path=Host.SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.Password}
}"
Text="{Binding Path=Host.Password}"
Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding Path=Host.KeyUploaderVisiblity}">
<TextBlock
Width="100"
Text="{DynamicResource KeyLoginField}"
VerticalAlignment="Center" />
<Button
IsEnabled="{
Binding Path=Host.SecretType,
Converter={StaticResource LoginSecretTypeConverter},
ConverterParameter={x:Static models:LoginSecretType.PrivateKey}
}"
Command="{Binding Path=Host.SelectKeyCommand}"
Content="{DynamicResource KeyUpload}" />
</StackPanel>
</StackPanel>
</GroupBox>
<GroupBox
Margin="20,0,0,0"
Header="{DynamicResource ProxyGroupName}"
Style="{StaticResource MaterialDesignHeaderedContentControl}">
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyType}" />
<RadioButton
GroupName="ProxyType"
Content="{StaticResource ProxyTypeNone}"
IsChecked="{
Binding Path=Host.Proxy.Type,
Converter={StaticResource ProxyTypeConverter},
ConverterParameter={x:Static models:LocalProxyType.None}
}"/>
<RadioButton
Margin="10,0,0,0"
GroupName="ProxyType"
Content="{DynamicResource ProxyTypeHttp}"
IsChecked="{
Binding Path=Host.Proxy.Type,
Converter={StaticResource ProxyTypeConverter},
ConverterParameter={x:Static models:LocalProxyType.Http}
}"/>
<RadioButton
Margin="10,0,0,0"
GroupName="ProxyType"
Content="{DynamicResource ProxyTypeSocks5}"
IsChecked="{
Binding Path=Host.Proxy.Type,
Converter={StaticResource ProxyTypeConverter},
ConverterParameter={x:Static models:LocalProxyType.Socks5}
}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyHostName}"
VerticalAlignment="Center" />
<TextBox
Width="200"
Text="{Binding Path=Host.Proxy.Address}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyHostPort}"
VerticalAlignment="Center"/>
<TextBox
Width="200"
Text="{Binding Path=Host.Proxy.Port}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyUserName}"
VerticalAlignment="Center"/>
<TextBox
Width="200"
Text="{Binding Path=Host.Proxy.UserName}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock
Width="100"
Text="{DynamicResource ProxyPassword}"
VerticalAlignment="Center"/>
<TextBox
Width="200"
Text="{Binding Path=Host.Proxy.Password}"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
<GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" />
<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10">
<GroupBox
Padding="10"
Style="{StaticResource MaterialDesignHeaderedContentControl}"
Header="选择方式">
<StackPanel Orientation="Horizontal">
<StackPanel>
<CheckBox Content="VLESS OVER TCP with XTLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VLESS_XTLS}"
Margin="0,10,0,0" />
<Label Content="数倍性能首选方式不支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VLESS over TCP with TLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VLESS_TCP}"
Margin="0,10,0,0" />
<Label Content="不支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VLESS over WS with TLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VLESS_WS}"
Margin="0,10,0,0" />
<Label Content="推荐支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VMess over TCP with TLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VMESS_TCP}"
Margin="0,10,0,0" />
<Label Content="不推荐" Margin="20,0,0,0" Foreground="Red" />
<CheckBox Content="VMess over WS with TLS"
Style="{StaticResource MahApps.Styles.CheckBox}"
IsChecked="{Binding Path=Settings.Checked_VMESS_WS}"
Margin="0,10,0,0" />
<Label Content="常规支持CDN" 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" />
</StackPanel>
<StackPanel Margin="120,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" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
<Label Content="域名" Width="80" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.Domain}" Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
<Label Content="伪装域名" Width="80" VerticalAlignment="Center" />
<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" />
<TextBox Text="{Binding Path=Settings.VLESS_WS_Path}"
IsEnabled="{Binding Checked_VLESS_WS}"
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" />
<TextBox Text="{Binding Path=Settings.VMESS_TCP_Path}"
IsEnabled="{Binding Checked_VMESS_TCP}"
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" />
<TextBox Text="{Binding Path=Settings.VMESS_WS_Path}"
IsEnabled="{Binding Checked_VMESS_WS}"
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.Trojan_TCP_Path_Visibility}">
<Label Content="Trojan密码" Width="120" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.TrojanPassword}"
IsEnabled="{Binding Checked_Trojan_TCP}"
Width="200" />
</StackPanel>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" Visibility="{Binding Settings.Trojan_TCP_Path_Visibility}">
<Label Content="Trojan Path" Width="120" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=Settings.TrojanPath}"
IsEnabled="{Binding Checked_Trojan_TCP}"
Width="200" />
</StackPanel>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
<Button Content="保存" Grid.Row="3" Width="120" Height="32" HorizontalAlignment="Right" Margin="0,0,20,0"></Button>
</Grid>
</metro:MetroWindow>

View File

@ -0,0 +1,42 @@
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>
/// RecordEditorWindow.xaml 的交互逻辑
/// </summary>
public partial class RecordEditorWindow
{
public Record Record { get; set; }
public HostViewModel Host { get; set; }
public XraySettingsViewModel Settings { get; set; }
public RecordEditorWindow(Record record)
{
InitializeComponent();
ResizeMode = ResizeMode.NoResize;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.Record = record;
Host = new HostViewModel(record.Host.DeepClone());
Settings = new XraySettingsViewModel(record.Settings.DeepClone());
this.DataContext = this;
}
}
}

View File

@ -1,4 +1,5 @@
using MahApps.Metro.Controls.Dialogs;
using ProxySU_Core.Models;
using ProxySU_Core.ViewModels;
using ProxySU_Core.ViewModels.Developers;
using ProxySU_Core.Views;
@ -30,6 +31,8 @@ namespace ProxySU_Core
public TerminalWindow(Record project)
{
InitializeComponent();
ResizeMode = ResizeMode.NoResize;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
_vm = new Terminal(project.Host);
DataContext = _vm;
@ -107,9 +110,6 @@ namespace ProxySU_Core
private void Install(object sender, RoutedEventArgs e)
{
var xrayWindow = new XrayWindow();
xrayWindow.ShowDialog();
}

View File

@ -1,35 +0,0 @@
<metro:MetroWindow x:Class="ProxySU_Core.Views.XrayWindow"
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="XrayWindow" Height="450" Width="800">
<StackPanel Orientation="Horizontal">
<StackPanel Margin="20">
<CheckBox Content="VLESS OVER TCP with XTLS" Style="{StaticResource MahApps.Styles.CheckBox}" />
<Label Content="数倍性能首选方式不支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VLESS over TCP with TLS" Style="{StaticResource MahApps.Styles.CheckBox}" Margin="0,10,0,0" />
<Label Content="不支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VLESS over WS with TLS" Style="{StaticResource MahApps.Styles.CheckBox}" Margin="0,10,0,0" />
<Label Content="推荐支持CDN" Margin="20,0,0,0" />
<CheckBox Content="VMess over TCP with TLS" Style="{StaticResource MahApps.Styles.CheckBox}" Margin="0,10,0,0" />
<Label Content="不推荐" Margin="20,0,0,0" Foreground="Red" />
<CheckBox Content="VMess over WS with TLS" Style="{StaticResource MahApps.Styles.CheckBox}" Margin="0,10,0,0" />
<Label Content="常规支持CDN" Margin="20,0,0,0" />
<CheckBox Content="Trojan over TCP with TLS" Style="{StaticResource MahApps.Styles.CheckBox}" Margin="0,10,0,0" />
<Label Content="Torjan协议不支持CDN" Margin="20,0,0,0" />
</StackPanel>
<StackPanel>
<Label Content="选择方式" />
</StackPanel>
</StackPanel>
</metro:MetroWindow>

View File

@ -1,27 +0,0 @@
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>
/// XrayWindow.xaml 的交互逻辑
/// </summary>
public partial class XrayWindow
{
public XrayWindow()
{
InitializeComponent();
}
}
}