mirror of
https://github.com/proxysu/ProxySU.git
synced 2024-11-28 16:16:07 +03:00
midify new
This commit is contained in:
parent
2fd76baf2f
commit
e548affd70
35
ProxySU_Core/Models/Host.cs
Normal file
35
ProxySU_Core/Models/Host.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
20
ProxySU_Core/Models/LocalProxy.cs
Normal file
20
ProxySU_Core/Models/LocalProxy.cs
Normal 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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace ProxySU_Core.ViewModels
|
namespace ProxySU_Core.Models
|
||||||
{
|
{
|
||||||
public enum LocalProxyType
|
public enum LocalProxyType
|
||||||
{
|
{
|
@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace ProxySU_Core.ViewModels
|
namespace ProxySU_Core.Models
|
||||||
{
|
{
|
||||||
public enum LoginSecretType
|
public enum LoginSecretType
|
||||||
{
|
{
|
24
ProxySU_Core/Models/Record.cs
Normal file
24
ProxySU_Core/Models/Record.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,28 @@
|
|||||||
using System;
|
using ProxySU_Core.ViewModels.Developers;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
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>
|
||||||
/// 访问端口
|
/// 访问端口
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -19,27 +36,27 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// vless ws路径
|
/// vless ws路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string VlessWsPath { get; set; }
|
public string VLESS_WS_Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// vless tcp路径
|
/// vless tcp路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string VlessTcpPath { get; set; }
|
public string VLESS_TCP_Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// vmess ws路径
|
/// vmess ws路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string VmessWsPath { get; set; }
|
public string VMESS_WS_Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// vmess tcp路径
|
/// vmess tcp路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string VmessTcpPath { get; set; }
|
public string VMESS_TCP_Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// trojan tcp路径
|
/// trojan tcp路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TrojanTcpPath { get; set; }
|
public string Trojan_TCP_Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// trojan密码
|
/// trojan密码
|
||||||
@ -59,25 +76,25 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 安装类型
|
/// 安装类型
|
||||||
/// </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:
|
case XrayType.VLESS_TCP_TLS:
|
||||||
return VlessTcpPath;
|
return VLESS_TCP_Path;
|
||||||
case XrayType.VLESS_TCP_XTLS:
|
case XrayType.VLESS_TCP_XTLS:
|
||||||
return VlessTcpPath;
|
return VLESS_TCP_Path;
|
||||||
case XrayType.VLESS_WS_TLS:
|
case XrayType.VLESS_WS_TLS:
|
||||||
return VlessWsPath;
|
return VLESS_WS_Path;
|
||||||
case XrayType.VMESS_TCP_TLS:
|
case XrayType.VMESS_TCP_TLS:
|
||||||
return VmessTcpPath;
|
return VMESS_TCP_Path;
|
||||||
case XrayType.VMESS_WS_TLS:
|
case XrayType.VMESS_WS_TLS:
|
||||||
return VmessWsPath;
|
return VMESS_WS_Path;
|
||||||
case XrayType.Trojan_TCP_TLS:
|
case XrayType.Trojan_TCP_TLS:
|
||||||
return TrojanTcpPath;
|
return Trojan_TCP_Path;
|
||||||
default:
|
default:
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
@ -182,35 +182,36 @@
|
|||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Converters\LoginSecretTypeConverter.cs" />
|
||||||
|
<Compile Include="Models\Host.cs" />
|
||||||
|
<Compile Include="Models\XraySettings.cs" />
|
||||||
<Compile Include="Tools\DateTimeUtils.cs" />
|
<Compile Include="Tools\DateTimeUtils.cs" />
|
||||||
|
<Compile Include="Tools\Extensions.cs" />
|
||||||
<Compile Include="ViewModels\BaseCommand.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\ConfigBuilder.cs" />
|
||||||
<Compile Include="ViewModels\Developers\IParameters.cs" />
|
<Compile Include="ViewModels\Developers\IParameters.cs" />
|
||||||
<Compile Include="ViewModels\Developers\Project.cs" />
|
<Compile Include="ViewModels\Developers\Project.cs" />
|
||||||
<Compile Include="ViewModels\Developers\XrayParameters.cs" />
|
|
||||||
<Compile Include="ViewModels\Developers\XrayProject.cs" />
|
<Compile Include="ViewModels\Developers\XrayProject.cs" />
|
||||||
<Compile Include="ViewModels\Host.cs" />
|
<Compile Include="ViewModels\HostViewModel.cs" />
|
||||||
<Compile Include="ViewModels\LocalProxy.cs" />
|
<Compile Include="Models\LocalProxy.cs" />
|
||||||
<Compile Include="ViewModels\LocalProxyType.cs" />
|
<Compile Include="Models\LocalProxyType.cs" />
|
||||||
<Compile Include="ViewModels\LoginSecretType.cs" />
|
<Compile Include="Models\LoginSecretType.cs" />
|
||||||
<Compile Include="ViewModels\Record.cs" />
|
<Compile Include="Models\Record.cs" />
|
||||||
|
<Compile Include="ViewModels\RecordViewModel.cs" />
|
||||||
<Compile Include="ViewModels\Terminal.cs" />
|
<Compile Include="ViewModels\Terminal.cs" />
|
||||||
<Compile Include="Views\HostEditorWindow.xaml.cs">
|
<Compile Include="ViewModels\XraySettingsViewModel.cs" />
|
||||||
<DependentUpon>HostEditorWindow.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Views\MainWindow.xaml.cs">
|
<Compile Include="Views\MainWindow.xaml.cs">
|
||||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Views\RecordEditorWindow.xaml.cs">
|
||||||
|
<DependentUpon>RecordEditorWindow.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Views\TerminalWindow.xaml.cs">
|
<Compile Include="Views\TerminalWindow.xaml.cs">
|
||||||
<DependentUpon>TerminalWindow.xaml</DependentUpon>
|
<DependentUpon>TerminalWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Views\XrayWindow.xaml.cs">
|
|
||||||
<DependentUpon>XrayWindow.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Converters\LoginSecretTypeConverter.cs" />
|
|
||||||
<Compile Include="Converters\ProxyTypeConverter.cs" />
|
<Compile Include="Converters\ProxyTypeConverter.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs">
|
<Compile Include="Properties\AssemblyInfo.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
@ -282,22 +283,18 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Views\HostEditorWindow.xaml">
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</Page>
|
|
||||||
<Page Include="Views\MainWindow.xaml">
|
<Page Include="Views\MainWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Views\RecordEditorWindow.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Views\TerminalWindow.xaml">
|
<Page Include="Views\TerminalWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Views\XrayWindow.xaml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<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')" />
|
<Import Project="..\packages\MaterialDesignThemes.4.0.0\build\MaterialDesignThemes.targets" Condition="Exists('..\packages\MaterialDesignThemes.4.0.0\build\MaterialDesignThemes.targets')" />
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<sys:String x:Key="Actions">Actions</sys:String>
|
<sys:String x:Key="Actions">Actions</sys:String>
|
||||||
<sys:String x:Key="Connect">Connect</sys:String>
|
<sys:String x:Key="Connect">Connect</sys:String>
|
||||||
<sys:String x:Key="Edit">Edit</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="Delete">Delete</sys:String>
|
||||||
<sys:String x:Key="Install">Install</sys:String>
|
<sys:String x:Key="Install">Install</sys:String>
|
||||||
<sys:String x:Key="Save">Save</sys:String>
|
<sys:String x:Key="Save">Save</sys:String>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<sys:String x:Key="Connect">连接</sys:String>
|
<sys:String x:Key="Connect">连接</sys:String>
|
||||||
<sys:String x:Key="Install">安装</sys:String>
|
<sys:String x:Key="Install">安装</sys:String>
|
||||||
<sys:String x:Key="Edit">编辑</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="Delete">删除</sys:String>
|
||||||
<sys:String x:Key="Save">保存</sys:String>
|
<sys:String x:Key="Save">保存</sys:String>
|
||||||
<sys:String x:Key="Info">消息</sys:String>
|
<sys:String x:Key="Info">消息</sys:String>
|
||||||
|
62
ProxySU_Core/Tools/Extensions.cs
Normal file
62
ProxySU_Core/Tools/Extensions.cs
Normal 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace ProxySU_Core.ViewModels
|
namespace ProxySU_Core.ViewModels
|
||||||
{
|
{
|
||||||
public abstract class BaseModel : INotifyPropertyChanged
|
public abstract class BaseViewModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using ProxySU_Core.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -57,11 +58,9 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
stats = statsObj["stats"],
|
stats = statsObj["stats"],
|
||||||
reverse = reverseObj["reverse"]
|
reverse = reverseObj["reverse"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BuildCaddyConfig(XrayParameters parameters)
|
public static string BuildCaddyConfig(XraySettings parameters)
|
||||||
{
|
{
|
||||||
var caddyStr = File.ReadAllText(Path.Combine(CaddyFileDir, "base.caddyfile"));
|
var caddyStr = File.ReadAllText(Path.Combine(CaddyFileDir, "base.caddyfile"));
|
||||||
caddyStr.Replace("##domain##", parameters.Domain);
|
caddyStr.Replace("##domain##", parameters.Domain);
|
||||||
@ -77,11 +76,11 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
return caddyStr;
|
return caddyStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BuildXrayConfig(XrayParameters parameters)
|
public static string BuildXrayConfig(XraySettings parameters)
|
||||||
{
|
{
|
||||||
var xrayConfig = LoadXrayConfig();
|
var xrayConfig = LoadXrayConfig();
|
||||||
var baseBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_TCP_XTLS.json"));
|
var baseBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_TCP_XTLS.json"));
|
||||||
baseBound["port"] = VLESS_TCP_Port;
|
baseBound["port"] = parameters.Port;
|
||||||
baseBound["settings"]["fallbacks"].Add(new
|
baseBound["settings"]["fallbacks"].Add(new
|
||||||
{
|
{
|
||||||
dest = 80,
|
dest = 80,
|
||||||
@ -89,52 +88,60 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
});
|
});
|
||||||
xrayConfig["inbounds"].Add(baseBound);
|
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;
|
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"));
|
var wsInbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_WS_TLS.json"));
|
||||||
wsInbound["port"] = VLESS_WS_Port;
|
wsInbound["port"] = VLESS_WS_Port;
|
||||||
wsInbound["settings"]["clients"][0]["id"] = parameters.UUID;
|
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
|
baseBound["settings"]["fallbacks"].Add(new
|
||||||
{
|
{
|
||||||
dest = VLESS_WS_Port,
|
dest = VLESS_WS_Port,
|
||||||
path = parameters.VlessWsPath,
|
path = parameters.VLESS_WS_Path,
|
||||||
xver = 1,
|
xver = 1,
|
||||||
});
|
});
|
||||||
xrayConfig["inbounds"].Add(wsInbound);
|
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"));
|
var mtcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_TCP_TLS.json"));
|
||||||
mtcpBound["port"] = VMESS_TCP_Port;
|
mtcpBound["port"] = VMESS_TCP_Port;
|
||||||
mtcpBound["settings"]["clients"][0]["id"] = parameters.UUID;
|
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
|
baseBound["settings"]["fallbacks"].Add(new
|
||||||
{
|
{
|
||||||
dest = VMESS_TCP_Port,
|
dest = VMESS_TCP_Port,
|
||||||
path = parameters.VmessTcpPath,
|
path = parameters.VMESS_TCP_Path,
|
||||||
xver = 1,
|
xver = 1,
|
||||||
});
|
});
|
||||||
xrayConfig["inbounds"].Add(mtcpBound);
|
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"));
|
var mwsBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_WS_TLS.json"));
|
||||||
mwsBound["port"] = VMESS_WS_Port;
|
mwsBound["port"] = VMESS_WS_Port;
|
||||||
mwsBound["settings"]["clients"][0]["id"] = parameters.UUID;
|
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
|
baseBound["settings"]["fallbacks"].Add(new
|
||||||
{
|
{
|
||||||
dest = VMESS_WS_Port,
|
dest = VMESS_WS_Port,
|
||||||
path = parameters.VmessWsPath,
|
path = parameters.VMESS_WS_Path,
|
||||||
xver = 1,
|
xver = 1,
|
||||||
});
|
});
|
||||||
xrayConfig["inbounds"].Add(mwsBound);
|
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"));
|
var trojanTcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "Trojan_TCP_TLS.json"));
|
||||||
trojanTcpBound["port"] = Trojan_TCP_Port;
|
trojanTcpBound["port"] = Trojan_TCP_Port;
|
||||||
trojanTcpBound["settings"]["clients"][0]["password"] = parameters.TrojanPassword;
|
trojanTcpBound["settings"]["clients"][0]["password"] = parameters.TrojanPassword;
|
||||||
@ -144,9 +151,6 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
xver = 1,
|
xver = 1,
|
||||||
};
|
};
|
||||||
xrayConfig["inbounds"].Add(trojanTcpBound);
|
xrayConfig["inbounds"].Add(trojanTcpBound);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsonConvert.SerializeObject(xrayConfig, Formatting.Indented);
|
return JsonConvert.SerializeObject(xrayConfig, Formatting.Indented);
|
||||||
|
@ -19,7 +19,7 @@ namespace ProxySU_Core.ViewModels.Developers
|
|||||||
Yum
|
Yum
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class Project<TParameters> : BaseModel where TParameters : IParameters
|
public abstract class Project<TParameters> : BaseViewModel where TParameters : IParameters
|
||||||
{
|
{
|
||||||
private SshClient _sshClient;
|
private SshClient _sshClient;
|
||||||
|
|
||||||
|
@ -6,10 +6,11 @@ using System.Text;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using ProxySU_Core.Models;
|
||||||
|
|
||||||
namespace ProxySU_Core.ViewModels.Developers
|
namespace ProxySU_Core.ViewModels.Developers
|
||||||
{
|
{
|
||||||
public class XrayProject : Project<XrayParameters>
|
public class XrayProject : Project<XraySettings>
|
||||||
{
|
{
|
||||||
|
|
||||||
private const string ServerLogDir = @"Templates\xray\server\00_log";
|
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 ServerReverseDir = @"Templates\xray\server\09_reverse";
|
||||||
private const string CaddyFileDir = @"Templates\xray\caddy";
|
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using ProxySU_Core.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@ -8,66 +9,79 @@ using System.Windows.Input;
|
|||||||
|
|
||||||
namespace ProxySU_Core.ViewModels
|
namespace ProxySU_Core.ViewModels
|
||||||
{
|
{
|
||||||
public class Host : BaseModel
|
public class HostViewModel : BaseViewModel
|
||||||
{
|
{
|
||||||
private LoginSecretType _secretType;
|
public Host host;
|
||||||
private string tag = string.Empty;
|
|
||||||
private string _address;
|
|
||||||
private LocalProxy proxy;
|
|
||||||
private readonly ICommand _selectKeyCommand;
|
private readonly ICommand _selectKeyCommand;
|
||||||
|
|
||||||
public Host()
|
public HostViewModel(Host host)
|
||||||
{
|
{
|
||||||
_selectKeyCommand = new BaseCommand(obj => OpenFileDialog(obj));
|
_selectKeyCommand = new BaseCommand(obj => OpenFileDialog(obj));
|
||||||
Proxy = new LocalProxy();
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public string Tag
|
public string Tag
|
||||||
{
|
{
|
||||||
get => tag; set
|
get => host.Tag;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
tag = value;
|
host.Tag = value;
|
||||||
Notify("Tag");
|
Notify("Tag");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Address
|
public string Address
|
||||||
{
|
{
|
||||||
get => _address;
|
get => host.Address;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_address = value;
|
host.Address = value;
|
||||||
Notify("Address");
|
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
|
public LocalProxy Proxy
|
||||||
{
|
{
|
||||||
get => proxy; set
|
get => host.Proxy;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
proxy = value;
|
host.Proxy = value;
|
||||||
Notify("Proxy");
|
Notify("Proxy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginSecretType SecretType
|
public LoginSecretType SecretType
|
||||||
{
|
{
|
||||||
get
|
get => host.SecretType;
|
||||||
{
|
|
||||||
return _secretType;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_secretType = value;
|
host.SecretType = value;
|
||||||
Notify("SecretType");
|
Notify("SecretType");
|
||||||
Notify("KeyUploaderVisiblity");
|
Notify("KeyUploaderVisiblity");
|
||||||
Notify("PasswordVisiblity");
|
Notify("PasswordVisiblity");
|
@ -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; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
40
ProxySU_Core/ViewModels/RecordViewModel.cs
Normal file
40
ProxySU_Core/ViewModels/RecordViewModel.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
using System;
|
using ProxySU_Core.Models;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace ProxySU_Core.ViewModels
|
namespace ProxySU_Core.ViewModels
|
||||||
{
|
{
|
||||||
public class Terminal : BaseModel
|
public class Terminal : BaseViewModel
|
||||||
{
|
{
|
||||||
private string outputText;
|
private string outputText;
|
||||||
|
|
||||||
|
237
ProxySU_Core/ViewModels/XraySettingsViewModel.cs
Normal file
237
ProxySU_Core/ViewModels/XraySettingsViewModel.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,7 +5,6 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:ProxySU_Core"
|
xmlns:local="clr-namespace:ProxySU_Core"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
GlowBrush="{DynamicResource AccentColorBrush}"
|
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
|
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
|
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
|
||||||
@ -64,7 +63,7 @@
|
|||||||
Width="100"/>
|
Width="100"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<DataGrid ItemsSource="{Binding Path=ProjectList}"
|
<DataGrid ItemsSource="{Binding Records}"
|
||||||
Margin="0,20,0,0"
|
Margin="0,20,0,0"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
x:Name="DataGrid"
|
x:Name="DataGrid"
|
||||||
@ -74,7 +73,6 @@
|
|||||||
SelectionUnit="FullRow"
|
SelectionUnit="FullRow"
|
||||||
BorderBrush="#eee"
|
BorderBrush="#eee"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CopyingRowClipboardContent="DataGrid_CopyingRowClipboardContent"
|
|
||||||
AutoGenerateColumns="False">
|
AutoGenerateColumns="False">
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
<DataGridTextColumn Header="{DynamicResource HostTag}"
|
<DataGridTextColumn Header="{DynamicResource HostTag}"
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
using MahApps.Metro.Controls.Dialogs;
|
using MahApps.Metro.Controls.Dialogs;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using ProxySU_Core.Models;
|
||||||
using ProxySU_Core.ViewModels;
|
using ProxySU_Core.ViewModels;
|
||||||
|
using ProxySU_Core.ViewModels.Developers;
|
||||||
|
using ProxySU_Core.Views;
|
||||||
using Renci.SshNet;
|
using Renci.SshNet;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -30,21 +33,26 @@ namespace ProxySU_Core
|
|||||||
{
|
{
|
||||||
private const string RecordPath = @"Data\Record.json";
|
private const string RecordPath = @"Data\Record.json";
|
||||||
|
|
||||||
public ObservableCollection<Record> ProjectList { get; set; }
|
public ObservableCollection<RecordViewModel> Records { get; set; }
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
ProjectList = new ObservableCollection<Record>();
|
|
||||||
|
Records = new ObservableCollection<RecordViewModel>();
|
||||||
|
|
||||||
if (File.Exists(RecordPath))
|
if (File.Exists(RecordPath))
|
||||||
{
|
{
|
||||||
var recordsJson = File.ReadAllText(RecordPath, Encoding.UTF8);
|
var recordsJson = File.ReadAllText(RecordPath, Encoding.UTF8);
|
||||||
var records = JsonConvert.DeserializeObject<List<Record>>(recordsJson);
|
var records = JsonConvert.DeserializeObject<List<Record>>(recordsJson);
|
||||||
records.ForEach(item => ProjectList.Add(item));
|
records.ForEach(item =>
|
||||||
|
{
|
||||||
|
Records.Add(new RecordViewModel(item));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,40 +98,31 @@ namespace ProxySU_Core
|
|||||||
Application.Current.Resources.MergedDictionaries[0] = resource;
|
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)
|
private void AddHost(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var hostWindow = new HostEditorWindow();
|
var hostWindow = new RecordEditorWindow(new Record());
|
||||||
hostWindow.OnSaveEvent += (s, host) =>
|
|
||||||
{
|
|
||||||
ProjectList.Add(new Record() { Host = host });
|
|
||||||
};
|
|
||||||
hostWindow.ShowDialog();
|
hostWindow.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditHost(object sender, RoutedEventArgs e)
|
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();
|
hostWindow.ShowDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void DeleteHost(object sender, RoutedEventArgs e)
|
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);
|
var result = MessageBox.Show($"您确认删除主机{project.Host.Tag}吗?", "提示", MessageBoxButton.OKCancel);
|
||||||
if (result == MessageBoxResult.OK)
|
if (result == MessageBoxResult.OK)
|
||||||
{
|
{
|
||||||
ProjectList.Remove(project);
|
Records.Remove(project);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
320
ProxySU_Core/Views/RecordEditorWindow.xaml
Normal file
320
ProxySU_Core/Views/RecordEditorWindow.xaml
Normal 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>
|
42
ProxySU_Core/Views/RecordEditorWindow.xaml.cs
Normal file
42
ProxySU_Core/Views/RecordEditorWindow.xaml.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using MahApps.Metro.Controls.Dialogs;
|
using MahApps.Metro.Controls.Dialogs;
|
||||||
|
using ProxySU_Core.Models;
|
||||||
using ProxySU_Core.ViewModels;
|
using ProxySU_Core.ViewModels;
|
||||||
using ProxySU_Core.ViewModels.Developers;
|
using ProxySU_Core.ViewModels.Developers;
|
||||||
using ProxySU_Core.Views;
|
using ProxySU_Core.Views;
|
||||||
@ -30,6 +31,8 @@ namespace ProxySU_Core
|
|||||||
public TerminalWindow(Record project)
|
public TerminalWindow(Record project)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
ResizeMode = ResizeMode.NoResize;
|
||||||
|
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
|
|
||||||
_vm = new Terminal(project.Host);
|
_vm = new Terminal(project.Host);
|
||||||
DataContext = _vm;
|
DataContext = _vm;
|
||||||
@ -107,9 +110,6 @@ namespace ProxySU_Core
|
|||||||
|
|
||||||
private void Install(object sender, RoutedEventArgs e)
|
private void Install(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var xrayWindow = new XrayWindow();
|
|
||||||
xrayWindow.ShowDialog();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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>
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user