1
0
mirror of https://github.com/proxysu/ProxySU.git synced 2024-11-22 05:06:08 +03:00
This commit is contained in:
next-autumn 2021-05-20 18:32:17 +08:00
parent eeada87602
commit 5093082fc4
21 changed files with 648 additions and 29 deletions

View File

@ -6,26 +6,26 @@ using System.Threading.Tasks;
namespace ProxySuper.Core.Models.Projects
{
public class IProjectSettings
public interface IProjectSettings
{
/// <summary>
/// 端口
/// </summary>
public virtual int Port { get; set; }
int Port { get; set; }
/// <summary>
/// 域名
/// </summary>
public virtual string Domain { get; set; }
string Domain { get; set; }
/// <summary>
/// 额外需要开放的端口
/// </summary>
public virtual List<int> FreePorts { get; }
List<int> FreePorts { get; }
/// <summary>
/// 类型
/// </summary>
public virtual ProjectType Type { get; set; }
ProjectType Type { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProxySuper.Core.Models.Projects
{
public class NaiveProxySettings : IProjectSettings
{
public int Port { get; set; }
public string Domain { get; set; }
public List<int> FreePorts => throw new NotImplementedException();
public ProjectType Type { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}
}

View File

@ -8,7 +8,7 @@ namespace ProxySuper.Core.Models.Projects
{
public class TrojanGoSettings : IProjectSettings
{
public override List<int> FreePorts
public List<int> FreePorts
{
get
{
@ -16,17 +16,17 @@ namespace ProxySuper.Core.Models.Projects
}
}
public override ProjectType Type { get; set; } = ProjectType.TrojanGo;
public ProjectType Type { get; set; } = ProjectType.TrojanGo;
/// <summary>
/// 域名
/// </summary>
public override string Domain { get; set; }
public string Domain { get; set; }
/// <summary>
/// 端口
/// </summary>
public override int Port { get; set; }
public int Port { get; set; }
/// <summary>
/// 密码
@ -37,5 +37,26 @@ namespace ProxySuper.Core.Models.Projects
/// 伪装域名
/// </summary>
public string MaskDomain { get; set; }
/// <summary>
/// 是否开启WebSocket
/// </summary>
public bool EnableWebSocket
{
get
{
return !string.IsNullOrEmpty(WebSocketPath) && !string.IsNullOrEmpty(WebSocketDomain);
}
}
/// <summary>
/// websocket路径
/// </summary>
public string WebSocketPath { get; set; }
/// <summary>
/// websocket域名
/// </summary>
public string WebSocketDomain { get; set; }
}
}

View File

@ -8,7 +8,7 @@ namespace ProxySuper.Core.Models.Projects
{
public partial class XraySettings : IProjectSettings
{
public override List<int> FreePorts
public List<int> FreePorts
{
get
{
@ -21,17 +21,17 @@ namespace ProxySuper.Core.Models.Projects
}
}
public override ProjectType Type { get; set; } = ProjectType.Xray;
public ProjectType Type { get; set; } = ProjectType.Xray;
/// <summary>
/// 端口
/// </summary>
public override int Port { get; set; }
public int Port { get; set; }
/// <summary>
/// 域名
/// </summary>
public override string Domain { get; set; }
public string Domain { get; set; }
/// <summary>
/// UUID

View File

@ -40,15 +40,34 @@ namespace ProxySuper.Core.Models
}
}
[JsonIgnore]
public IMvxNavigationService _navigationService;
[JsonIgnore]
public IMvxNavigationService NavigationService
{
get
{
if (_navigationService == null)
{
_navigationService = Mvx.IoCProvider.Resolve<IMvxNavigationService>();
}
return _navigationService;
}
}
[JsonIgnore]
public IMvxCommand NavToInstallerCommand => new MvxAsyncCommand(NavigateToInstaller);
[JsonIgnore]
public IMvxCommand NavToEditorCommand => new MvxAsyncCommand(NavigateToEditor);
public async Task NavigateToEditor()
{
var nav = Mvx.IoCProvider.Resolve<IMvxNavigationService>();
if (Type == ProjectType.Xray)
{
var result = await nav.Navigate<XrayEditorViewModel, Record, Record>(this);
var result = await NavigationService.Navigate<XrayEditorViewModel, Record, Record>(this);
if (result == null) return;
this.Host = result.Host;
@ -59,12 +78,24 @@ namespace ProxySuper.Core.Models
if (Type == ProjectType.TrojanGo)
{
var result = await nav.Navigate<TrojanGoEditorViewModel, Record, Record>(this);
var result = await NavigationService.Navigate<TrojanGoEditorViewModel, Record, Record>(this);
if (result == null) return;
this.Host = result.Host;
this.TrojanGoSettings = result.TrojanGoSettings;
}
}
public async Task NavigateToInstaller()
{
if (Type == ProjectType.Xray)
{
await NavigationService.Navigate<XrayInstallerViewModel, Record>(this);
}
if (Type == ProjectType.TrojanGo)
{
await NavigationService.Navigate<TrojanGoInstallerViewModel, Record>(this);
}
}
}
}

View File

@ -55,6 +55,7 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="App.cs" />
@ -67,6 +68,7 @@
<Compile Include="Models\Hosts\LoginSecretType.cs" />
<Compile Include="Models\Projects\IProjectSettings.cs" />
<Compile Include="Models\Hosts\LocalProxy.cs" />
<Compile Include="Models\Projects\NaiveProxySettings.cs" />
<Compile Include="Models\Projects\ProjectType.cs" />
<Compile Include="Models\Projects\TrojanGoSettings.cs" />
<Compile Include="Models\Projects\XraySettings_SS.cs" />
@ -86,7 +88,9 @@
<Compile Include="Services\XrayProject.cs" />
<Compile Include="ViewModels\HomeViewModel.cs" />
<Compile Include="ViewModels\TrojanGoEditorViewModel.cs" />
<Compile Include="ViewModels\TrojanGoInstallerViewModel.cs" />
<Compile Include="ViewModels\XrayEditorViewModel.cs" />
<Compile Include="ViewModels\XrayInstallerViewModel.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@ -245,7 +245,10 @@ namespace ProxySuper.Core.Services
WriteOutput("************ 上传网站模板完成 ************");
}
/// <summary>
/// 上传Caddy文件
/// </summary>
/// <param name="useCustomWeb"></param>
private void UploadCaddyFile(bool useCustomWeb = false)
{
var configJson = XrayConfigBuilder.BuildCaddyConfig(Parameters, useCustomWeb);

View File

@ -0,0 +1,45 @@
using MvvmCross.ViewModels;
using ProxySuper.Core.Models;
using ProxySuper.Core.Models.Hosts;
using ProxySuper.Core.Models.Projects;
using ProxySuper.Core.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProxySuper.Core.ViewModels
{
public class TrojanGoInstallerViewModel : MvxViewModel<Record>
{
public Host Host { get; set; }
public TrojanGoSettings Settings { get; set; }
public override void Prepare(Record parameter)
{
var record = Utils.DeepClone(parameter);
Host = record.Host;
Settings = record.TrojanGoSettings;
}
private bool _connected;
public bool Connected
{
get
{
return _connected;
}
set
{
_connected = value;
RaisePropertyChanged("Connected");
}
}
public string CommandText { get; set; }
}
}

View File

@ -0,0 +1,47 @@
using MvvmCross.ViewModels;
using ProxySuper.Core.Models;
using ProxySuper.Core.Models.Hosts;
using ProxySuper.Core.Models.Projects;
using ProxySuper.Core.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Renci.SshNet;
using System.Windows.Threading;
namespace ProxySuper.Core.ViewModels
{
public class XrayInstallerViewModel : MvxViewModel<Record>
{
public Host Host { get; set; }
public XraySettings Settings { get; set; }
public override void Prepare(Record parameter)
{
var record = Utils.DeepClone(parameter);
Host = record.Host;
Settings = record.XraySettings;
}
private bool _connected;
public bool Connected
{
get
{
return _connected;
}
set
{
_connected = value;
RaisePropertyChanged("HasConnected");
}
}
public string CommandText { get; set; }
}
}

View File

@ -43,6 +43,9 @@
<Reference Include="MvvmCross.Platforms.Wpf, Version=7.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmCross.Platforms.Wpf.7.1.2\lib\net461\MvvmCross.Platforms.Wpf.dll</HintPath>
</Reference>
<Reference Include="Renci.SshNet, Version=2020.0.1.0, Culture=neutral, PublicKeyToken=1cee9f8bde3db106, processorArchitecture=MSIL">
<HintPath>..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
@ -88,9 +91,15 @@
<Compile Include="Views\TrojanGoEditorView.xaml.cs">
<DependentUpon>TrojanGoEditorView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\TrojanGoInstallerView.xaml.cs">
<DependentUpon>TrojanGoInstallerView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\XrayEditorView.xaml.cs">
<DependentUpon>XrayEditorView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\XrayInstallerView.xaml.cs">
<DependentUpon>XrayInstallerView.xaml</DependentUpon>
</Compile>
<Page Include="Controls\HostControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -130,10 +139,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\TrojanGoInstallerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\XrayEditorView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\XrayInstallerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">

View File

@ -78,4 +78,12 @@
<sys:String x:Key="TrojanPassword">Trojan Pwd</sys:String>
<sys:String x:Key="XrayPort">xray Port</sys:String>
<sys:String x:Key="XrayPortDefault">default port is 443</sys:String>
<!--Trojan-GO-->
<sys:String x:Key="TrojanGoDomain">Address</sys:String>
<sys:String x:Key="TrojanGoPort">Port</sys:String>
<sys:String x:Key="TrojanGoPassword">Password</sys:String>
<sys:String x:Key="TrojanGoMaskDomain">GuiseHost</sys:String>
<sys:String x:Key="TrojanGoWebSocketPath">WS Path</sys:String>
<sys:String x:Key="TrojanGoWebSocketDomain">WS Domain</sys:String>
</ResourceDictionary>

View File

@ -78,4 +78,13 @@
<sys:String x:Key="TrojanPassword">Trojan密码</sys:String>
<sys:String x:Key="XrayPort">xray端口</sys:String>
<sys:String x:Key="XrayPortDefault">默认端口443不建议修改</sys:String>
<!--Trojan-GO-->
<sys:String x:Key="TrojanGoDomain">域名</sys:String>
<sys:String x:Key="TrojanGoPort">端口</sys:String>
<sys:String x:Key="TrojanGoPassword">密码</sys:String>
<sys:String x:Key="TrojanGoMaskDomain">伪装网址</sys:String>
<sys:String x:Key="TrojanGoWebSocketPath">WS 路径</sys:String>
<sys:String x:Key="TrojanGoWebSocketDomain">WS 域名</sys:String>
</ResourceDictionary>

View File

@ -67,7 +67,7 @@
<DataGridTemplateColumn.CellTemplate>
<ItemContainerTemplate>
<StackPanel Orientation="Horizontal">
<Button Click="NavToEditor"
<Button Command="{Binding NavToInstallerCommand}"
Margin="5,0"
Padding="12,3"
Content="{DynamicResource MainDataGridColumnActionInstall}" />

View File

@ -34,9 +34,9 @@ namespace ProxySuper.WPF.Views
}
public HomeViewModel VM
public new HomeViewModel ViewModel
{
get { return (HomeViewModel)ViewModel; }
get { return (HomeViewModel)base.ViewModel; }
}
private void LaunchGitHubSite(object sender, RoutedEventArgs e)
@ -46,12 +46,12 @@ namespace ProxySuper.WPF.Views
private void NavToEditor(object sender, RoutedEventArgs e)
{
NavigationService.Navigate<XrayEditorViewModel, Record, Record>(VM.Records[0]);
NavigationService.Navigate<XrayEditorViewModel, Record, Record>(ViewModel.Records[0]);
}
protected override void Dispose(bool disposing)
{
VM.SaveRecords();
ViewModel.SaveRecords();
base.Dispose(disposing);
}

View File

@ -31,23 +31,30 @@
<RowDefinition Height="36" />
<RowDefinition Height="36" />
<RowDefinition Height="36" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Label Content="域名" Grid.Row="0" Grid.Column="0" />
<Label Content="{DynamicResource TrojanGoDomain}" Grid.Row="0" Grid.Column="0" />
<TextBox Text="{Binding Settings.Domain}" Grid.Row="0" Grid.Column="1" />
<Label Content="端口" Grid.Row="1" Grid.Column="0" />
<Label Content="{DynamicResource TrojanGoPort}" Grid.Row="1" Grid.Column="0" />
<TextBox Text="{Binding Settings.Port}" Grid.Row="1" Grid.Column="1" />
<Label Content="密码" Grid.Row="2" Grid.Column="0" />
<Label Content="{DynamicResource TrojanGoPassword}" Grid.Row="2" Grid.Column="0" />
<TextBox Text="{Binding Settings.Password}" Grid.Row="2" Grid.Column="1" />
<Label Content="伪装域名" Grid.Row="3" Grid.Column="0" />
<Label Content="{DynamicResource TrojanGoMaskDomain}" Grid.Row="3" Grid.Column="0" />
<TextBox Text="{Binding Settings.MaskDomain}" Grid.Row="3" Grid.Column="1" />
<Label Content="{DynamicResource TrojanGoWebSocketPath}" Grid.Row="4" Grid.Column="0" />
<TextBox Text="{Binding Settings.WebSocketPath}" Grid.Row="4" Grid.Column="1" />
<Label Content="{DynamicResource TrojanGoWebSocketDomain}" Grid.Row="5" Grid.Column="0" />
<TextBox Text="{Binding Settings.WebSocketDomain}" Grid.Row="5" Grid.Column="1" />
</Grid>
<Border BorderBrush="#eee" BorderThickness="0,1,0,0">

View File

@ -0,0 +1,41 @@
<views:MvxWindow x:Class="ProxySuper.WPF.Views.TrojanGoInstallerView"
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:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
xmlns:local="clr-namespace:ProxySuper.WPF.Views"
mc:Ignorable="d"
Icon="/Resources/ProxySU.ico"
Title="TrojanGoInstallerView" Height="450" Width="800">
<Grid>
<TextBox IsReadOnly="True"
Block.LineHeight="18"
Background="#000"
Foreground="LawnGreen"
FontSize="14"
FontFamily="Consolas"
x:Name="OutputTextBox"
Height="260"
Padding="10"
BorderThickness="0"
VerticalAlignment="Top"
VerticalContentAlignment="Top"
Text="{Binding Path=OutputText}"
/>
<StackPanel Margin="10" Orientation="Horizontal">
<Label Content="安装" />
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="Install">一键安装</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UpdateSettings">更新配置</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="Uninstall">卸载代理</Button>
</StackPanel>
<StackPanel Margin="10" Orientation="Horizontal">
<Label Content="配置" />
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="InstallCert">重新申请证书</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UploadWeb">上传伪装网站</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UploadCert">上传自有证书</Button>
</StackPanel>
</Grid>
</views:MvxWindow>

View File

@ -0,0 +1,136 @@
using MvvmCross.Platforms.Wpf.Presenters.Attributes;
using MvvmCross.Platforms.Wpf.Views;
using ProxySuper.Core.Models.Hosts;
using ProxySuper.Core.Services;
using ProxySuper.Core.ViewModels;
using Renci.SshNet;
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 ProxySuper.WPF.Views
{
/// <summary>
/// TrojanGoInstallerView.xaml 的交互逻辑
/// </summary>
[MvxWindowPresentation(Identifier = nameof(TrojanGoInstallerView), Modal = true)]
public partial class TrojanGoInstallerView : MvxWindow
{
public TrojanGoInstallerView()
{
InitializeComponent();
}
public new TrojanGoInstallerViewModel ViewModel
{
get
{
return (TrojanGoInstallerViewModel)base.ViewModel;
}
}
public TrojanGoProject Project { get; set; }
private SshClient _sshClient;
private void OpenConnect()
{
WriteOutput("正在登陆服务器 ...");
var conneInfo = CreateConnectionInfo(ViewModel.Host);
_sshClient = new SshClient(conneInfo);
try
{
_sshClient.Connect();
}
catch (Exception ex)
{
WriteOutput("登陆失败!");
WriteOutput(ex.Message);
return;
}
WriteOutput("登陆服务器成功!");
ViewModel.Connected = true;
Project = new TrojanGoProject(_sshClient, ViewModel.Settings, WriteOutput);
}
private void WriteOutput(string outShell)
{
if (!outShell.EndsWith("\n"))
{
outShell += "\n";
}
Dispatcher.Invoke(() =>
{
OutputTextBox.AppendText(outShell);
OutputTextBox.ScrollToEnd();
});
}
private ConnectionInfo CreateConnectionInfo(Host host)
{
AuthenticationMethod auth = null;
if (host.SecretType == LoginSecretType.Password)
{
auth = new PasswordAuthenticationMethod(host.UserName, host.Password);
}
else if (host.SecretType == LoginSecretType.PrivateKey)
{
auth = new PrivateKeyAuthenticationMethod(host.UserName, new PrivateKeyFile(host.PrivateKeyPath));
}
if (host.Proxy.Type == LocalProxyType.None)
{
return new ConnectionInfo(host.Address, host.Port, host.UserName, auth);
}
else
{
return new ConnectionInfo(
host: host.Address,
port: host.Port,
username: host.UserName,
proxyType: (ProxyTypes)(int)host.Proxy.Type,
proxyHost: host.Proxy.Address,
proxyPort: host.Proxy.Port,
proxyUsername: host.Proxy.UserName,
proxyPassword: host.Proxy.Password,
authenticationMethods: auth);
}
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
base.Loaded += (sender, arg) =>
{
Task.Factory.StartNew(OpenConnect);
};
}
private void Install(object sender, RoutedEventArgs e) { }
private void UpdateSettings(object sender, RoutedEventArgs e) { }
private void Uninstall(object sender, RoutedEventArgs e) { }
private void UploadWeb(object sender, RoutedEventArgs e) { }
private void UploadCert(object sender, RoutedEventArgs e) { }
private void InstallCert(object sender, RoutedEventArgs e) { }
}
}

View File

@ -26,5 +26,10 @@ namespace ProxySuper.WPF.Views
{
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
}
}
}

View File

@ -0,0 +1,42 @@
<views:MvxWindow x:Class="ProxySuper.WPF.Views.XrayInstallerView"
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:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
xmlns:local="clr-namespace:ProxySuper.WPF.Views"
mc:Ignorable="d"
Icon="/Resources/ProxySU.ico"
Title="XrayInstallerView" Height="450" Width="800">
<StackPanel>
<TextBox IsReadOnly="True"
Block.LineHeight="18"
Background="#000"
Foreground="LawnGreen"
FontSize="14"
FontFamily="Consolas"
x:Name="OutputTextBox"
Height="260"
Padding="10"
BorderThickness="0"
VerticalAlignment="Top"
VerticalContentAlignment="Top"
Text="{Binding Path=OutputText}"
/>
<StackPanel Margin="10" Orientation="Horizontal">
<Label Content="安装" />
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="Install">一键安装</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UpdateXraySettings">更新配置</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UpdateXrayCore">更新内核</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UninstallXray">卸载代理</Button>
</StackPanel>
<StackPanel Margin="10" Orientation="Horizontal">
<Label Content="配置" />
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="InstallCert">重新申请证书</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UploadWeb">上传伪装网站</Button>
<Button Height="24" Padding="10,0" Margin="10,0,0,0" IsEnabled="{Binding Connected}" Click="UploadCert">上传自有证书</Button>
</StackPanel>
</StackPanel>
</views:MvxWindow>

View File

@ -0,0 +1,183 @@
using Microsoft.Win32;
using MvvmCross.Platforms.Wpf.Presenters.Attributes;
using MvvmCross.Platforms.Wpf.Views;
using ProxySuper.Core.Models.Hosts;
using ProxySuper.Core.Services;
using ProxySuper.Core.ViewModels;
using Renci.SshNet;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Threading;
namespace ProxySuper.WPF.Views
{
/// <summary>
/// XrayInstallerView.xaml 的交互逻辑
/// </summary>
[MvxWindowPresentation(Identifier = nameof(XrayInstallerView), Modal = true)]
public partial class XrayInstallerView : MvxWindow
{
public XrayInstallerView()
{
InitializeComponent();
}
public new XrayInstallerViewModel ViewModel
{
get
{
var t = base.ViewModel;
return (XrayInstallerViewModel)base.ViewModel;
}
}
public XrayProject Project { get; set; }
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
base.Loaded += (sender, arg) =>
{
Task.Factory.StartNew(OpenConnect);
};
}
private SshClient _sshClient;
private void OpenConnect()
{
WriteOutput("正在登陆服务器 ...");
var conneInfo = CreateConnectionInfo(ViewModel.Host);
_sshClient = new SshClient(conneInfo);
try
{
_sshClient.Connect();
}
catch (Exception ex)
{
WriteOutput("登陆失败!");
WriteOutput(ex.Message);
return;
}
WriteOutput("登陆服务器成功!");
ViewModel.Connected = true;
Project = new XrayProject(_sshClient, ViewModel.Settings, WriteOutput);
}
private void WriteOutput(string outShell)
{
if (!outShell.EndsWith("\n"))
{
outShell += "\n";
}
Dispatcher.Invoke(() =>
{
OutputTextBox.AppendText(outShell);
OutputTextBox.ScrollToEnd();
});
}
private ConnectionInfo CreateConnectionInfo(Host host)
{
AuthenticationMethod auth = null;
if (host.SecretType == LoginSecretType.Password)
{
auth = new PasswordAuthenticationMethod(host.UserName, host.Password);
}
else if (host.SecretType == LoginSecretType.PrivateKey)
{
auth = new PrivateKeyAuthenticationMethod(host.UserName, new PrivateKeyFile(host.PrivateKeyPath));
}
if (host.Proxy.Type == LocalProxyType.None)
{
return new ConnectionInfo(host.Address, host.Port, host.UserName, auth);
}
else
{
return new ConnectionInfo(
host: host.Address,
port: host.Port,
username: host.UserName,
proxyType: (ProxyTypes)(int)host.Proxy.Type,
proxyHost: host.Proxy.Address,
proxyPort: host.Proxy.Port,
proxyUsername: host.Proxy.UserName,
proxyPassword: host.Proxy.Password,
authenticationMethods: auth);
}
}
private void Install(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(Project.Install);
}
private void UpdateXrayCore(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(Project.UpdateXrayCore);
}
private void UpdateXraySettings(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(Project.UpdateXraySettings);
}
private void InstallCert(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(Project.InstallCertToXray);
}
private void UninstallXray(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(Project.UninstallProxy);
}
private void UploadCert(object sender, RoutedEventArgs e)
{
var fileDialog = new OpenFileDialog();
fileDialog.Filter = "压缩文件|*.zip";
fileDialog.FileOk += DoUploadCert;
fileDialog.ShowDialog();
}
private void UploadWeb(object sender, RoutedEventArgs e)
{
var fileDialog = new OpenFileDialog();
fileDialog.Filter = "压缩文件|*.zip";
fileDialog.FileOk += DoUploadWeb;
fileDialog.ShowDialog();
}
private void DoUploadWeb(object sender, CancelEventArgs e)
{
Task.Factory.StartNew(() =>
{
var file = sender as OpenFileDialog;
using (var stream = file.OpenFile())
{
Project.UploadWeb(stream);
}
});
}
private void DoUploadCert(object sender, CancelEventArgs e)
{
Task.Factory.StartNew(() =>
{
var file = sender as OpenFileDialog;
using (var stream = file.OpenFile())
{
Project.UploadCert(stream);
}
});
}
}
}

View File

@ -2,6 +2,7 @@
<packages>
<package id="MvvmCross" version="7.1.2" targetFramework="net461" />
<package id="MvvmCross.Platforms.Wpf" version="7.1.2" targetFramework="net461" />
<package id="SSH.NET" version="2020.0.1" targetFramework="net461" />
<package id="System.Console" version="4.3.1" targetFramework="net461" />
<package id="System.Runtime.WindowsRuntime" version="4.6.0" targetFramework="net461" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />