1
0
mirror of https://github.com/proxysu/ProxySU.git synced 2024-11-22 13:16:09 +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 namespace ProxySuper.Core.Models.Projects
{ {
public class IProjectSettings public interface IProjectSettings
{ {
/// <summary> /// <summary>
/// 端口 /// 端口
/// </summary> /// </summary>
public virtual int Port { get; set; } int Port { get; set; }
/// <summary> /// <summary>
/// 域名 /// 域名
/// </summary> /// </summary>
public virtual string Domain { get; set; } string Domain { get; set; }
/// <summary> /// <summary>
/// 额外需要开放的端口 /// 额外需要开放的端口
/// </summary> /// </summary>
public virtual List<int> FreePorts { get; } List<int> FreePorts { get; }
/// <summary> /// <summary>
/// 类型 /// 类型
/// </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 class TrojanGoSettings : IProjectSettings
{ {
public override List<int> FreePorts public List<int> FreePorts
{ {
get 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>
/// 域名 /// 域名
/// </summary> /// </summary>
public override string Domain { get; set; } public string Domain { get; set; }
/// <summary> /// <summary>
/// 端口 /// 端口
/// </summary> /// </summary>
public override int Port { get; set; } public int Port { get; set; }
/// <summary> /// <summary>
/// 密码 /// 密码
@ -37,5 +37,26 @@ namespace ProxySuper.Core.Models.Projects
/// 伪装域名 /// 伪装域名
/// </summary> /// </summary>
public string MaskDomain { get; set; } 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 partial class XraySettings : IProjectSettings
{ {
public override List<int> FreePorts public List<int> FreePorts
{ {
get 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>
/// 端口 /// 端口
/// </summary> /// </summary>
public override int Port { get; set; } public int Port { get; set; }
/// <summary> /// <summary>
/// 域名 /// 域名
/// </summary> /// </summary>
public override string Domain { get; set; } public string Domain { get; set; }
/// <summary> /// <summary>
/// UUID /// 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 IMvxCommand NavToEditorCommand => new MvxAsyncCommand(NavigateToEditor);
public async Task NavigateToEditor() public async Task NavigateToEditor()
{ {
var nav = Mvx.IoCProvider.Resolve<IMvxNavigationService>();
if (Type == ProjectType.Xray) 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; if (result == null) return;
this.Host = result.Host; this.Host = result.Host;
@ -59,12 +78,24 @@ namespace ProxySuper.Core.Models
if (Type == ProjectType.TrojanGo) 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; if (result == null) return;
this.Host = result.Host; this.Host = result.Host;
this.TrojanGoSettings = result.TrojanGoSettings; 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.Data" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="App.cs" /> <Compile Include="App.cs" />
@ -67,6 +68,7 @@
<Compile Include="Models\Hosts\LoginSecretType.cs" /> <Compile Include="Models\Hosts\LoginSecretType.cs" />
<Compile Include="Models\Projects\IProjectSettings.cs" /> <Compile Include="Models\Projects\IProjectSettings.cs" />
<Compile Include="Models\Hosts\LocalProxy.cs" /> <Compile Include="Models\Hosts\LocalProxy.cs" />
<Compile Include="Models\Projects\NaiveProxySettings.cs" />
<Compile Include="Models\Projects\ProjectType.cs" /> <Compile Include="Models\Projects\ProjectType.cs" />
<Compile Include="Models\Projects\TrojanGoSettings.cs" /> <Compile Include="Models\Projects\TrojanGoSettings.cs" />
<Compile Include="Models\Projects\XraySettings_SS.cs" /> <Compile Include="Models\Projects\XraySettings_SS.cs" />
@ -86,7 +88,9 @@
<Compile Include="Services\XrayProject.cs" /> <Compile Include="Services\XrayProject.cs" />
<Compile Include="ViewModels\HomeViewModel.cs" /> <Compile Include="ViewModels\HomeViewModel.cs" />
<Compile Include="ViewModels\TrojanGoEditorViewModel.cs" /> <Compile Include="ViewModels\TrojanGoEditorViewModel.cs" />
<Compile Include="ViewModels\TrojanGoInstallerViewModel.cs" />
<Compile Include="ViewModels\XrayEditorViewModel.cs" /> <Compile Include="ViewModels\XrayEditorViewModel.cs" />
<Compile Include="ViewModels\XrayInstallerViewModel.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />

View File

@ -245,7 +245,10 @@ namespace ProxySuper.Core.Services
WriteOutput("************ 上传网站模板完成 ************"); WriteOutput("************ 上传网站模板完成 ************");
} }
/// <summary>
/// 上传Caddy文件
/// </summary>
/// <param name="useCustomWeb"></param>
private void UploadCaddyFile(bool useCustomWeb = false) private void UploadCaddyFile(bool useCustomWeb = false)
{ {
var configJson = XrayConfigBuilder.BuildCaddyConfig(Parameters, useCustomWeb); 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"> <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> <HintPath>..\packages\MvvmCross.Platforms.Wpf.7.1.2\lib\net461\MvvmCross.Platforms.Wpf.dll</HintPath>
</Reference> </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" />
<Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@ -88,9 +91,15 @@
<Compile Include="Views\TrojanGoEditorView.xaml.cs"> <Compile Include="Views\TrojanGoEditorView.xaml.cs">
<DependentUpon>TrojanGoEditorView.xaml</DependentUpon> <DependentUpon>TrojanGoEditorView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\TrojanGoInstallerView.xaml.cs">
<DependentUpon>TrojanGoInstallerView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\XrayEditorView.xaml.cs"> <Compile Include="Views\XrayEditorView.xaml.cs">
<DependentUpon>XrayEditorView.xaml</DependentUpon> <DependentUpon>XrayEditorView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\XrayInstallerView.xaml.cs">
<DependentUpon>XrayInstallerView.xaml</DependentUpon>
</Compile>
<Page Include="Controls\HostControl.xaml"> <Page Include="Controls\HostControl.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@ -130,10 +139,18 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\TrojanGoInstallerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\XrayEditorView.xaml"> <Page Include="Views\XrayEditorView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\XrayInstallerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs"> <Compile Include="Properties\AssemblyInfo.cs">

View File

@ -78,4 +78,12 @@
<sys:String x:Key="TrojanPassword">Trojan Pwd</sys:String> <sys:String x:Key="TrojanPassword">Trojan Pwd</sys:String>
<sys:String x:Key="XrayPort">xray Port</sys:String> <sys:String x:Key="XrayPort">xray Port</sys:String>
<sys:String x:Key="XrayPortDefault">default port is 443</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> </ResourceDictionary>

View File

@ -78,4 +78,13 @@
<sys:String x:Key="TrojanPassword">Trojan密码</sys:String> <sys:String x:Key="TrojanPassword">Trojan密码</sys:String>
<sys:String x:Key="XrayPort">xray端口</sys:String> <sys:String x:Key="XrayPort">xray端口</sys:String>
<sys:String x:Key="XrayPortDefault">默认端口443不建议修改</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> </ResourceDictionary>

View File

@ -67,7 +67,7 @@
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<ItemContainerTemplate> <ItemContainerTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Button Click="NavToEditor" <Button Command="{Binding NavToInstallerCommand}"
Margin="5,0" Margin="5,0"
Padding="12,3" Padding="12,3"
Content="{DynamicResource MainDataGridColumnActionInstall}" /> 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) private void LaunchGitHubSite(object sender, RoutedEventArgs e)
@ -46,12 +46,12 @@ namespace ProxySuper.WPF.Views
private void NavToEditor(object sender, RoutedEventArgs e) 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) protected override void Dispose(bool disposing)
{ {
VM.SaveRecords(); ViewModel.SaveRecords();
base.Dispose(disposing); base.Dispose(disposing);
} }

View File

@ -31,23 +31,30 @@
<RowDefinition Height="36" /> <RowDefinition Height="36" />
<RowDefinition Height="36" /> <RowDefinition Height="36" />
<RowDefinition Height="36" /> <RowDefinition Height="36" />
<RowDefinition Height="36" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="80" /> <ColumnDefinition Width="120" />
<ColumnDefinition Width="200" /> <ColumnDefinition Width="200" />
</Grid.ColumnDefinitions> </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" /> <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" /> <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" /> <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" /> <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> </Grid>
<Border BorderBrush="#eee" BorderThickness="0,1,0,0"> <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(); 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> <packages>
<package id="MvvmCross" version="7.1.2" targetFramework="net461" /> <package id="MvvmCross" version="7.1.2" targetFramework="net461" />
<package id="MvvmCross.Platforms.Wpf" 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.Console" version="4.3.1" targetFramework="net461" />
<package id="System.Runtime.WindowsRuntime" version="4.6.0" targetFramework="net461" /> <package id="System.Runtime.WindowsRuntime" version="4.6.0" targetFramework="net461" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" /> <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />