From f37127736243be5270b443435788ef8b43ac6584 Mon Sep 17 00:00:00 2001 From: test Date: Mon, 27 Feb 2023 17:26:55 +0800 Subject: [PATCH] add hysteria editor --- .../Models/Projects/HysteriaSettings.cs | 10 +- ProxySuper.Core/ProxySuper.Core.csproj | 1 + ProxySuper.Core/Services/HysteriaService.cs | 168 ++++++++++++++++++ ProxySuper.Core/ViewModels/HomeViewModel.cs | 17 ++ .../ViewModels/HysteriaInstallViewModel.cs | 51 +++++- ProxySuper.WPF/ProxySuper.WPF.csproj | 3 + ProxySuper.WPF/Templates/Hysteria/config.json | 10 ++ ProxySuper.WPF/Views/HomeView.xaml | 1 + .../Views/Hysteria/HysteriaEditorView.xaml | 17 +- .../Views/Hysteria/HysteriaEditorView.xaml.cs | 10 +- 10 files changed, 269 insertions(+), 19 deletions(-) create mode 100644 ProxySuper.Core/Services/HysteriaService.cs create mode 100644 ProxySuper.WPF/Templates/Hysteria/config.json diff --git a/ProxySuper.Core/Models/Projects/HysteriaSettings.cs b/ProxySuper.Core/Models/Projects/HysteriaSettings.cs index 9363741..4f7f9ed 100644 --- a/ProxySuper.Core/Models/Projects/HysteriaSettings.cs +++ b/ProxySuper.Core/Models/Projects/HysteriaSettings.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace ProxySuper.Core.Models.Projects { - public class HysteriaSettings + public class HysteriaSettings : IProjectSettings { public string Domain { get; set; } = ""; @@ -21,5 +21,13 @@ namespace ProxySuper.Core.Models.Projects public int UpMbps { get; set; } = 300; public int DownMbps { get; set; } = 300; + + public List FreePorts + { + get + { + return new List { Port }; + } + } } } diff --git a/ProxySuper.Core/ProxySuper.Core.csproj b/ProxySuper.Core/ProxySuper.Core.csproj index d181519..5f54766 100644 --- a/ProxySuper.Core/ProxySuper.Core.csproj +++ b/ProxySuper.Core/ProxySuper.Core.csproj @@ -108,6 +108,7 @@ + diff --git a/ProxySuper.Core/Services/HysteriaService.cs b/ProxySuper.Core/Services/HysteriaService.cs new file mode 100644 index 0000000..3c5b48b --- /dev/null +++ b/ProxySuper.Core/Services/HysteriaService.cs @@ -0,0 +1,168 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using ProxySuper.Core.Models.Hosts; +using ProxySuper.Core.Models.Projects; +using Renci.SshNet.Messages; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace ProxySuper.Core.Services +{ + public class HysteriaService : ServiceBase + { + public HysteriaService(Host host, HysteriaSettings settings) : base(host, settings) + { + } + + + public void Install() + { + try + { + Progress.Step = "安装Hysteria"; + Progress.Percentage = 0; + + + Progress.Desc = "检测系统环境"; + EnsureRootUser(); + EnsureSystemEnv(); + Progress.Percentage = 20; + + Progress.Desc = "安装必要的系统工具"; + InstallSystemTools(); + Progress.Percentage = 40; + + Progress.Desc = "配置防火墙"; + ConfigFirewalld(); + Progress.Percentage = 50; + + Progress.Step = "检测网络环境"; + EnsureNetwork(); + Progress.Percentage = 60; + + + Progress.Desc = "检测域名是否绑定本机IP"; + ValidateDomain(); + Progress.Percentage = 80; + + Progress.Step = "上传Hysteria配置文件"; + UploadConfigFile(); + Progress.Step = "安装Hysteria服务"; + InstallHysteria(); + + Progress.Percentage = 100; + Progress.Step = "安装Hysteria成功"; + Progress.Desc = "安装Hysteria成功"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + + public void Uninstall() + { + Task.Factory.StartNew(() => + { + try + { + Progress.Step = "卸载Hysteria"; + Progress.Percentage = 0; + + Progress.Desc = "停止Hysteria服务"; + RunCmd("systemctl stop Hysteria"); + RunCmd("systemctl disable Hysteria"); + Progress.Percentage = 30; + + Progress.Desc = "删除Hysteria相关文件"; + RunCmd("rm -rf /etc/systemd/system/Hysteria.service"); + RunCmd("rm -rf /usr/bin/Hysteria"); + Progress.Percentage = 80; + + Progress.Desc = "重置防火墙设置"; + ResetFirewalld(); + + Progress.Percentage = 100; + Progress.Desc = "卸载完成"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + }); + } + + private string HysteriaServiceTemp = @" + [Unit] + Description=hysteria service + After=network.target syslog.target + Wants=network.target + + [Service] + Type=simple + ExecStart=##run_cmd## + + [Install] + WantedBy=multi-user.target"; + + private void InstallHysteria() + { + Progress.Desc = "执行Hysteria安装文件"; + string url = "https://github.com/apernet/hysteria/releases/download/v1.3.3/hysteria-linux-386"; + string targetPath = "/user/bin/hysteria/hysteria-linux-386"; + + if (ArchType == ArchType.arm) + { + url = url.Replace("hysteria-linux-386", "hysteria-linux-arm"); + targetPath = targetPath.Replace("hysteria-linux-386", "hysteria-linux-arm"); + } + + RunCmd($"curl -L {url} -o /usr/bin/hysteria"); + RunCmd("chmod +x /usr/bin/hysteria"); + + Progress.Desc = "设置Hysteria服务"; + var cmd = targetPath + " server"; + var hysteriaService = HysteriaServiceTemp.Replace("##run_cmd##", cmd); + + RunCmd("rm -rf /etc/systemd/system/hysteria.service"); + RunCmd("touch /etc/systemd/system/hysteria.service"); + + RunCmd($"echo \"{hysteriaService}\" > /etc/systemd/system/hysteria.service"); + RunCmd("sudo chmod 777 /etc/systemd/system/hysteria.service"); + + + Progress.Desc = "启动Hysteria服务"; + RunCmd("systemctl enable hysteria"); + RunCmd("systemctl restart hysteria"); + } + + private const string ConfigFilePath = @"Templates\Hysteria\config.json"; + private void UploadConfigFile() + { + var text = File.ReadAllText(ConfigFilePath, Encoding.UTF8); + var json = JsonConvert.DeserializeObject(text); + var obj = JToken.FromObject(json) as dynamic; + + + obj["listen"] = Settings.Port; + obj["acme"]["domains"][0] = Settings.Domain; + obj["email"] = Settings.Email; + obj["obfs"] = Settings.Obfs; + + var configJson = JsonConvert.SerializeObject( + obj, + Formatting.Indented, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }); + + WriteToFile(configJson, "/user/bin/hysteria/config.json"); + } + } +} diff --git a/ProxySuper.Core/ViewModels/HomeViewModel.cs b/ProxySuper.Core/ViewModels/HomeViewModel.cs index 2ba60a8..5c5c1ec 100644 --- a/ProxySuper.Core/ViewModels/HomeViewModel.cs +++ b/ProxySuper.Core/ViewModels/HomeViewModel.cs @@ -108,6 +108,8 @@ namespace ProxySuper.Core.ViewModels public IMvxCommand AddBrookCommand => new MvxAsyncCommand(AddBrookRecord); + public IMvxCommand AddHysteriaCommand => new MvxAsyncCommand(AddHysteriaRecord); + public IMvxCommand RemoveCommand => new MvxAsyncCommand(DeleteRecord); public IMvxCommand EditCommand => new MvxAsyncCommand(EditRecord); @@ -204,6 +206,21 @@ namespace ProxySuper.Core.ViewModels SaveToJson(); } + public async Task AddHysteriaRecord() + { + Record record = new Record(); + record.Id = Utils.GetTickID(); + record.Host = new Host(); + record.HysteriaSettings = new HysteriaSettings(); + + var result = await _navigationService.Navigate(record); + if (result == null) return; + + Records.Add(result); + + SaveToJson(); + } + public async Task EditRecord(string id) { diff --git a/ProxySuper.Core/ViewModels/HysteriaInstallViewModel.cs b/ProxySuper.Core/ViewModels/HysteriaInstallViewModel.cs index ec0d49d..3977e0d 100644 --- a/ProxySuper.Core/ViewModels/HysteriaInstallViewModel.cs +++ b/ProxySuper.Core/ViewModels/HysteriaInstallViewModel.cs @@ -1,9 +1,12 @@ -using MvvmCross.ViewModels; +using MvvmCross.Commands; +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.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -12,14 +15,52 @@ namespace ProxySuper.Core.ViewModels { public class HysteriaInstallViewModel : MvxViewModel { - public Host Host { get; set; } + public Host _host { get; set; } - public HysteriaSettings Settings { get; set; } + public HysteriaSettings _settings { get; set; } + + public HysteriaService _service { get; set; } public override void Prepare(Record parameter) { - Host = parameter.Host; - Settings = parameter.HysteriaSettings; + _host = parameter.Host; + _settings = parameter.HysteriaSettings; + } + + public override Task Initialize() + { + _service = new HysteriaService(_host, _settings); + _service.Progress.StepUpdate = () => RaisePropertyChanged("Progress"); + _service.Progress.LogsUpdate = () => RaisePropertyChanged("Logs"); + _service.Connect(); + return base.Initialize(); + } + + public override void ViewDestroy(bool viewFinishing = true) + { + _service.Disconnect(); + this.SaveInstallLog(); + base.ViewDestroy(viewFinishing); + } + + public ProjectProgress Progress => _service.Progress; + + public string Logs => _service.Progress.Logs; + + public IMvxCommand InstallCommand => new MvxCommand(_service.Install); + + public IMvxCommand UninstallCommand => new MvxCommand(_service.Uninstall); + + + private void SaveInstallLog() + { + if (!Directory.Exists("Logs")) + { + Directory.CreateDirectory("Logs"); + } + + var fileName = System.IO.Path.Combine("Logs", DateTime.Now.ToString("yyyy-MM-dd hh-mm") + ".hysteria.txt"); + File.WriteAllText(fileName, Logs); } } } diff --git a/ProxySuper.WPF/ProxySuper.WPF.csproj b/ProxySuper.WPF/ProxySuper.WPF.csproj index a167206..aab901b 100644 --- a/ProxySuper.WPF/ProxySuper.WPF.csproj +++ b/ProxySuper.WPF/ProxySuper.WPF.csproj @@ -413,6 +413,9 @@ SettingsSingleFileGenerator Settings.Designer.cs + + PreserveNewest + PreserveNewest diff --git a/ProxySuper.WPF/Templates/Hysteria/config.json b/ProxySuper.WPF/Templates/Hysteria/config.json new file mode 100644 index 0000000..a25268b --- /dev/null +++ b/ProxySuper.WPF/Templates/Hysteria/config.json @@ -0,0 +1,10 @@ +{ + "listen": ":36712", + "acme": { + "domains": [ + "your.domain.com" + ], + "email": "your@email.com" + }, + "obfs": "8ZuA2Zpqhuk8yakXvMjDqEXBwY" +} \ No newline at end of file diff --git a/ProxySuper.WPF/Views/HomeView.xaml b/ProxySuper.WPF/Views/HomeView.xaml index 34c5ff3..1e64f25 100644 --- a/ProxySuper.WPF/Views/HomeView.xaml +++ b/ProxySuper.WPF/Views/HomeView.xaml @@ -21,6 +21,7 @@ + diff --git a/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml b/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml index 1d1b65a..dd63cec 100644 --- a/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml +++ b/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml @@ -1,4 +1,5 @@ - - + diff --git a/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml.cs b/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml.cs index 66e790c..d790ec3 100644 --- a/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml.cs +++ b/ProxySuper.WPF/Views/Hysteria/HysteriaEditorView.xaml.cs @@ -1,4 +1,6 @@ -using System; +using MvvmCross.Platforms.Wpf.Presenters.Attributes; +using MvvmCross.Platforms.Wpf.Views; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -14,10 +16,8 @@ using System.Windows.Shapes; namespace ProxySuper.WPF.Views.Hysteria { - /// - /// HysteriaEditorView.xaml 的交互逻辑 - /// - public partial class HysteriaEditorView : Window + [MvxWindowPresentation] + public partial class HysteriaEditorView : MvxWindow { public HysteriaEditorView() {