From 5093082fc4e15954a4ce04b28f0a25dc1b1c4b1a Mon Sep 17 00:00:00 2001 From: next-autumn Date: Thu, 20 May 2021 18:32:17 +0800 Subject: [PATCH] save --- .../Models/Projects/IProjectSettings.cs | 10 +- .../Models/Projects/NaiveProxySettings.cs | 19 ++ .../Models/Projects/TrojanGoSettings.cs | 29 ++- .../Models/Projects/XraySettings.cs | 8 +- ProxySuper.Core/Models/Record.cs | 37 +++- ProxySuper.Core/ProxySuper.Core.csproj | 4 + ProxySuper.Core/Services/XrayProject.cs | 5 +- .../ViewModels/TrojanGoInstallerViewModel.cs | 45 +++++ .../ViewModels/XrayInstallerViewModel.cs | 47 +++++ ProxySuper.WPF/ProxySuper.WPF.csproj | 17 ++ ProxySuper.WPF/Resources/Languages/en.xaml | 8 + ProxySuper.WPF/Resources/Languages/zh_cn.xaml | 9 + ProxySuper.WPF/Views/HomeView.xaml | 2 +- ProxySuper.WPF/Views/HomeView.xaml.cs | 8 +- ProxySuper.WPF/Views/TrojanGoEditorView.xaml | 21 +- .../Views/TrojanGoInstallerView.xaml | 41 ++++ .../Views/TrojanGoInstallerView.xaml.cs | 136 +++++++++++++ ProxySuper.WPF/Views/XrayEditorView.xaml.cs | 5 + ProxySuper.WPF/Views/XrayInstallerView.xaml | 42 ++++ .../Views/XrayInstallerView.xaml.cs | 183 ++++++++++++++++++ ProxySuper.WPF/packages.config | 1 + 21 files changed, 648 insertions(+), 29 deletions(-) create mode 100644 ProxySuper.Core/Models/Projects/NaiveProxySettings.cs create mode 100644 ProxySuper.Core/ViewModels/TrojanGoInstallerViewModel.cs create mode 100644 ProxySuper.Core/ViewModels/XrayInstallerViewModel.cs create mode 100644 ProxySuper.WPF/Views/TrojanGoInstallerView.xaml create mode 100644 ProxySuper.WPF/Views/TrojanGoInstallerView.xaml.cs create mode 100644 ProxySuper.WPF/Views/XrayInstallerView.xaml create mode 100644 ProxySuper.WPF/Views/XrayInstallerView.xaml.cs diff --git a/ProxySuper.Core/Models/Projects/IProjectSettings.cs b/ProxySuper.Core/Models/Projects/IProjectSettings.cs index 45b45eb..6bd2874 100644 --- a/ProxySuper.Core/Models/Projects/IProjectSettings.cs +++ b/ProxySuper.Core/Models/Projects/IProjectSettings.cs @@ -6,26 +6,26 @@ using System.Threading.Tasks; namespace ProxySuper.Core.Models.Projects { - public class IProjectSettings + public interface IProjectSettings { /// /// 端口 /// - public virtual int Port { get; set; } + int Port { get; set; } /// /// 域名 /// - public virtual string Domain { get; set; } + string Domain { get; set; } /// /// 额外需要开放的端口 /// - public virtual List FreePorts { get; } + List FreePorts { get; } /// /// 类型 /// - public virtual ProjectType Type { get; set; } + ProjectType Type { get; set; } } } diff --git a/ProxySuper.Core/Models/Projects/NaiveProxySettings.cs b/ProxySuper.Core/Models/Projects/NaiveProxySettings.cs new file mode 100644 index 0000000..55d2f27 --- /dev/null +++ b/ProxySuper.Core/Models/Projects/NaiveProxySettings.cs @@ -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 FreePorts => throw new NotImplementedException(); + + public ProjectType Type { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + } +} diff --git a/ProxySuper.Core/Models/Projects/TrojanGoSettings.cs b/ProxySuper.Core/Models/Projects/TrojanGoSettings.cs index 71ef261..6e10b9b 100644 --- a/ProxySuper.Core/Models/Projects/TrojanGoSettings.cs +++ b/ProxySuper.Core/Models/Projects/TrojanGoSettings.cs @@ -8,7 +8,7 @@ namespace ProxySuper.Core.Models.Projects { public class TrojanGoSettings : IProjectSettings { - public override List FreePorts + public List 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; /// /// 域名 /// - public override string Domain { get; set; } + public string Domain { get; set; } /// /// 端口 /// - public override int Port { get; set; } + public int Port { get; set; } /// /// 密码 @@ -37,5 +37,26 @@ namespace ProxySuper.Core.Models.Projects /// 伪装域名 /// public string MaskDomain { get; set; } + + /// + /// 是否开启WebSocket + /// + public bool EnableWebSocket + { + get + { + return !string.IsNullOrEmpty(WebSocketPath) && !string.IsNullOrEmpty(WebSocketDomain); + } + } + + /// + /// websocket路径 + /// + public string WebSocketPath { get; set; } + + /// + /// websocket域名 + /// + public string WebSocketDomain { get; set; } } } diff --git a/ProxySuper.Core/Models/Projects/XraySettings.cs b/ProxySuper.Core/Models/Projects/XraySettings.cs index 45d83ab..9fe47fc 100644 --- a/ProxySuper.Core/Models/Projects/XraySettings.cs +++ b/ProxySuper.Core/Models/Projects/XraySettings.cs @@ -8,7 +8,7 @@ namespace ProxySuper.Core.Models.Projects { public partial class XraySettings : IProjectSettings { - public override List FreePorts + public List 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; /// /// 端口 /// - public override int Port { get; set; } + public int Port { get; set; } /// /// 域名 /// - public override string Domain { get; set; } + public string Domain { get; set; } /// /// UUID diff --git a/ProxySuper.Core/Models/Record.cs b/ProxySuper.Core/Models/Record.cs index 992be07..518c3ea 100644 --- a/ProxySuper.Core/Models/Record.cs +++ b/ProxySuper.Core/Models/Record.cs @@ -40,15 +40,34 @@ namespace ProxySuper.Core.Models } } + [JsonIgnore] + public IMvxNavigationService _navigationService; + [JsonIgnore] + public IMvxNavigationService NavigationService + { + get + { + if (_navigationService == null) + { + _navigationService = Mvx.IoCProvider.Resolve(); + } + 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(); if (Type == ProjectType.Xray) { - var result = await nav.Navigate(this); + var result = await NavigationService.Navigate(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(this); + var result = await NavigationService.Navigate(this); if (result == null) return; this.Host = result.Host; this.TrojanGoSettings = result.TrojanGoSettings; } } + + public async Task NavigateToInstaller() + { + if (Type == ProjectType.Xray) + { + await NavigationService.Navigate(this); + } + if (Type == ProjectType.TrojanGo) + { + await NavigationService.Navigate(this); + } + } } } diff --git a/ProxySuper.Core/ProxySuper.Core.csproj b/ProxySuper.Core/ProxySuper.Core.csproj index a2ea264..bf0272d 100644 --- a/ProxySuper.Core/ProxySuper.Core.csproj +++ b/ProxySuper.Core/ProxySuper.Core.csproj @@ -55,6 +55,7 @@ + @@ -67,6 +68,7 @@ + @@ -86,7 +88,9 @@ + + diff --git a/ProxySuper.Core/Services/XrayProject.cs b/ProxySuper.Core/Services/XrayProject.cs index b01068f..de8b3e4 100644 --- a/ProxySuper.Core/Services/XrayProject.cs +++ b/ProxySuper.Core/Services/XrayProject.cs @@ -245,7 +245,10 @@ namespace ProxySuper.Core.Services WriteOutput("************ 上传网站模板完成 ************"); } - + /// + /// 上传Caddy文件 + /// + /// private void UploadCaddyFile(bool useCustomWeb = false) { var configJson = XrayConfigBuilder.BuildCaddyConfig(Parameters, useCustomWeb); diff --git a/ProxySuper.Core/ViewModels/TrojanGoInstallerViewModel.cs b/ProxySuper.Core/ViewModels/TrojanGoInstallerViewModel.cs new file mode 100644 index 0000000..55c3d99 --- /dev/null +++ b/ProxySuper.Core/ViewModels/TrojanGoInstallerViewModel.cs @@ -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 + { + 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; } + + + } +} diff --git a/ProxySuper.Core/ViewModels/XrayInstallerViewModel.cs b/ProxySuper.Core/ViewModels/XrayInstallerViewModel.cs new file mode 100644 index 0000000..39c9f61 --- /dev/null +++ b/ProxySuper.Core/ViewModels/XrayInstallerViewModel.cs @@ -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 + { + + 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; } + } +} diff --git a/ProxySuper.WPF/ProxySuper.WPF.csproj b/ProxySuper.WPF/ProxySuper.WPF.csproj index 03bb44f..31fab7b 100644 --- a/ProxySuper.WPF/ProxySuper.WPF.csproj +++ b/ProxySuper.WPF/ProxySuper.WPF.csproj @@ -43,6 +43,9 @@ ..\packages\MvvmCross.Platforms.Wpf.7.1.2\lib\net461\MvvmCross.Platforms.Wpf.dll + + ..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll + @@ -88,9 +91,15 @@ TrojanGoEditorView.xaml + + TrojanGoInstallerView.xaml + XrayEditorView.xaml + + XrayInstallerView.xaml + Designer MSBuild:Compile @@ -130,10 +139,18 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + diff --git a/ProxySuper.WPF/Resources/Languages/en.xaml b/ProxySuper.WPF/Resources/Languages/en.xaml index 93faa66..cf9abac 100644 --- a/ProxySuper.WPF/Resources/Languages/en.xaml +++ b/ProxySuper.WPF/Resources/Languages/en.xaml @@ -78,4 +78,12 @@ Trojan Pwd xray Port default port is 443 + + + Address + Port + Password + GuiseHost + WS Path + WS Domain \ No newline at end of file diff --git a/ProxySuper.WPF/Resources/Languages/zh_cn.xaml b/ProxySuper.WPF/Resources/Languages/zh_cn.xaml index 0f69a67..e86d0c9 100644 --- a/ProxySuper.WPF/Resources/Languages/zh_cn.xaml +++ b/ProxySuper.WPF/Resources/Languages/zh_cn.xaml @@ -78,4 +78,13 @@ Trojan密码 xray端口 默认端口443,不建议修改 + + + + 域名 + 端口 + 密码 + 伪装网址 + WS 路径 + WS 域名 \ No newline at end of file diff --git a/ProxySuper.WPF/Views/HomeView.xaml b/ProxySuper.WPF/Views/HomeView.xaml index dc91294..e8f646c 100644 --- a/ProxySuper.WPF/Views/HomeView.xaml +++ b/ProxySuper.WPF/Views/HomeView.xaml @@ -67,7 +67,7 @@ - + + + + + + + + diff --git a/ProxySuper.WPF/Views/TrojanGoInstallerView.xaml.cs b/ProxySuper.WPF/Views/TrojanGoInstallerView.xaml.cs new file mode 100644 index 0000000..610f258 --- /dev/null +++ b/ProxySuper.WPF/Views/TrojanGoInstallerView.xaml.cs @@ -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 +{ + /// + /// TrojanGoInstallerView.xaml 的交互逻辑 + /// + [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) { } + + } +} diff --git a/ProxySuper.WPF/Views/XrayEditorView.xaml.cs b/ProxySuper.WPF/Views/XrayEditorView.xaml.cs index df3f90c..d9f60d6 100644 --- a/ProxySuper.WPF/Views/XrayEditorView.xaml.cs +++ b/ProxySuper.WPF/Views/XrayEditorView.xaml.cs @@ -26,5 +26,10 @@ namespace ProxySuper.WPF.Views { InitializeComponent(); } + + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + } } } diff --git a/ProxySuper.WPF/Views/XrayInstallerView.xaml b/ProxySuper.WPF/Views/XrayInstallerView.xaml new file mode 100644 index 0000000..3d73fb0 --- /dev/null +++ b/ProxySuper.WPF/Views/XrayInstallerView.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/ProxySuper.WPF/Views/XrayInstallerView.xaml.cs b/ProxySuper.WPF/Views/XrayInstallerView.xaml.cs new file mode 100644 index 0000000..f55302e --- /dev/null +++ b/ProxySuper.WPF/Views/XrayInstallerView.xaml.cs @@ -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 +{ + /// + /// XrayInstallerView.xaml 的交互逻辑 + /// + [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); + } + }); + } + + } +} diff --git a/ProxySuper.WPF/packages.config b/ProxySuper.WPF/packages.config index 536b481..3d9117f 100644 --- a/ProxySuper.WPF/packages.config +++ b/ProxySuper.WPF/packages.config @@ -2,6 +2,7 @@ +