From eecec3bbd7836ea10a2e1730a24a0172fbaed8b4 Mon Sep 17 00:00:00 2001 From: Space Time Date: Fri, 27 Dec 2024 22:10:50 +0800 Subject: [PATCH] =?UTF-8?q?1.1.4=20->=201.1.5=20=E7=AC=AC8=E6=AC=A1?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .filenesting.json | 3 +- Consts/MainMultilangConst.Designer.cs | 18 ++ Consts/MainMultilangConst.resx | 18 +- Consts/MainMultilangConst.zh.resx | 18 +- Convs/MainConv.cs | 3 +- Convs/MainMihomoButtonContentConv.cs | 5 +- Convs/MainMihomoButtonIsEnabledConv.cs | 21 +++ Convs/MainNginxButtonContentConv.cs | 11 +- Convs/MainNginxButtonIsEnabledConv.cs | 22 +++ Convs/MainNginxButtonToolTipConv.cs | 11 +- Convs/MainProxyButtonIsEnabledConv.cs | 18 -- Preses/MainPres.cs | 21 +++ Wins/MainWin.xaml | 33 +++- Wins/MainWin.xaml.cs | 235 ++++++++++++++++++++----- 14 files changed, 350 insertions(+), 87 deletions(-) create mode 100644 Convs/MainMihomoButtonIsEnabledConv.cs create mode 100644 Convs/MainNginxButtonIsEnabledConv.cs delete mode 100644 Convs/MainProxyButtonIsEnabledConv.cs diff --git a/.filenesting.json b/.filenesting.json index 43ed449..b286b50 100644 --- a/.filenesting.json +++ b/.filenesting.json @@ -15,12 +15,13 @@ "AboutVersionButtonContentConv.cs": [ "AboutConv.cs" ], "MainAdminControlVisibilityConv.cs": [ "MainConv.cs" ], "MainMihomoButtonContentConv.cs": [ "MainConv.cs" ], + "MainMihomoButtonIsEnabledConv.cs": [ "MainConv.cs" ], "MainMihomoButtonToolTipConv.cs": [ "MainConv.cs" ], "MainNginxButtonContentConv.cs": [ "MainConv.cs" ], + "MainNginxButtonIsEnabledConv.cs": [ "MainConv.cs" ], "MainNginxButtonToolTipConv.cs": [ "MainConv.cs" ], "MainNoClickButtonContentConv.cs": [ "MainConv.cs" ], "MainNoClickButtonToolTipConv.cs": [ "MainConv.cs" ], - "MainProxyButtonIsEnabledConv.cs": [ "MainConv.cs" ], "MainProxyColumnWidthConv.cs": [ "MainConv.cs" ], "MainSettingsBoxHintConv.cs": [ "MainConv.cs" ], "MainSettingsBoxTextConv.cs": [ "MainConv.cs" ], diff --git a/Consts/MainMultilangConst.Designer.cs b/Consts/MainMultilangConst.Designer.cs index 68b8470..804637b 100644 --- a/Consts/MainMultilangConst.Designer.cs +++ b/Consts/MainMultilangConst.Designer.cs @@ -276,6 +276,24 @@ namespace Sheas_Cealer.Consts { } } + /// + /// 查找类似 GLB. Purging CHA. 的本地化字符串。 + /// + public static string ComihomoButtonIsInitingContent { + get { + return ResourceManager.GetString("ComihomoButtonIsInitingContent", resourceCulture); + } + } + + /// + /// 查找类似 GLB. Cealing INIT. 的本地化字符串。 + /// + public static string ConginxButtonIsInitingContent { + get { + return ResourceManager.GetString("ConginxButtonIsInitingContent", resourceCulture); + } + } + /// /// 查找类似 Edit Hosts Conf 的本地化字符串。 /// diff --git a/Consts/MainMultilangConst.resx b/Consts/MainMultilangConst.resx index 56bf11d..c53eea8 100644 --- a/Consts/MainMultilangConst.resx +++ b/Consts/MainMultilangConst.resx @@ -123,6 +123,18 @@ Click to open the about window + + Start Cealing + + + Click to launch the injected browser + + + GLB. Purging CHA. + + + GLB. Cealing INIT. + Edit Hosts Conf @@ -234,12 +246,6 @@ Upstream URL - - Start Cealing - - - Click to launch the injected browser - Update Upstream Host diff --git a/Consts/MainMultilangConst.zh.resx b/Consts/MainMultilangConst.zh.resx index 28664a0..d616d26 100644 --- a/Consts/MainMultilangConst.zh.resx +++ b/Consts/MainMultilangConst.zh.resx @@ -123,6 +123,18 @@ 点击打开关于窗口 + + 启动伪造 + + + 点击启动参数注入完成的浏览器 + + + 全局净化调整中 + + + 全局伪造启动中 + 编辑 Hosts 配置 @@ -234,12 +246,6 @@ 上游链接 - - 启动伪造 - - - 点击启动参数注入完成的浏览器 - 更新上游规则 diff --git a/Convs/MainConv.cs b/Convs/MainConv.cs index 9c3a9aa..e337cc6 100644 --- a/Convs/MainConv.cs +++ b/Convs/MainConv.cs @@ -4,12 +4,13 @@ internal static class MainConv { public static MainAdminControlVisibilityConv MainAdminControlVisibilityConv => new(); public static MainMihomoButtonContentConv MainMihomoButtonContentConv => new(); + public static MainMihomoButtonIsEnabledConv MainMihomoButtonIsEnabledConv => new(); public static MainMihomoButtonToolTipConv MainMihomoButtonToolTipConv => new(); public static MainNginxButtonContentConv MainNginxButtonContentConv => new(); public static MainNginxButtonToolTipConv MainNginxButtonToolTipConv => new(); public static MainNoClickButtonContentConv MainNoClickButtonContentConv => new(); public static MainNoClickButtonToolTipConv MainNoClickButtonToolTipConv => new(); - public static MainProxyButtonIsEnabledConv MainProxyButtonIsEnabledConv => new(); + public static MainNginxButtonIsEnabledConv MainNginxButtonIsEnabledConv => new(); public static MainProxyColumnWidthConv MainProxyColumnWidthConv => new(); public static MainSettingsBoxHintConv MainSettingsBoxHintConv => new(); public static MainSettingsBoxTextConv MainSettingsBoxTextConv => new(); diff --git a/Convs/MainMihomoButtonContentConv.cs b/Convs/MainMihomoButtonContentConv.cs index adf4ea5..a09aea8 100644 --- a/Convs/MainMihomoButtonContentConv.cs +++ b/Convs/MainMihomoButtonContentConv.cs @@ -11,8 +11,11 @@ internal class MainMihomoButtonContentConv : IMultiValueConverter { bool isMihomoRunning = (bool)values[0]; bool isMihomoIniting = (bool)values[1]; + bool isCoproxyIniting = (bool)values[2]; + bool isCoproxyStopping = (bool)values[3]; - return isMihomoIniting ? MainConst.MihomoButtonIsInitingContent : + return isCoproxyIniting || isCoproxyStopping ? Binding.DoNothing : + isMihomoIniting ? MainConst.MihomoButtonIsInitingContent : isMihomoRunning ? MainConst.MihomoButtonIsRunningContent : MainConst.MihomoButtonIsStoppedContent; } diff --git a/Convs/MainMihomoButtonIsEnabledConv.cs b/Convs/MainMihomoButtonIsEnabledConv.cs new file mode 100644 index 0000000..baca53a --- /dev/null +++ b/Convs/MainMihomoButtonIsEnabledConv.cs @@ -0,0 +1,21 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace Sheas_Cealer.Convs; + +internal class MainMihomoButtonIsEnabledConv : IMultiValueConverter +{ + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + bool isCoMihomoExist = (bool)values[0]; + bool isMihomoExist = (bool)values[1]; + bool isCoproxyIniting = (bool)values[2]; + bool isComihomoIniting = (bool)values[3]; + bool isMihomoIniting = (bool)values[4]; + + return !isCoproxyIniting && !isComihomoIniting && !isMihomoIniting && (isCoMihomoExist || isMihomoExist); + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException(); +} \ No newline at end of file diff --git a/Convs/MainNginxButtonContentConv.cs b/Convs/MainNginxButtonContentConv.cs index bdb279f..f1d6ff5 100644 --- a/Convs/MainNginxButtonContentConv.cs +++ b/Convs/MainNginxButtonContentConv.cs @@ -9,11 +9,14 @@ internal class MainNginxButtonContentConv : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { - bool isNginxRunning = (bool)values[0]; - bool isNginxIniting = (bool)values[1]; + bool isConginxRunning = (bool)values[0]; + bool isNginxRunning = (bool)values[1]; + bool isCoproxyIniting = (bool)values[2]; + bool isNginxIniting = (bool)values[3]; - return isNginxIniting ? MainConst.NginxButtonIsInitingContent : - isNginxRunning ? MainConst.NginxButtonIsRunningContent : MainConst.NginxButtonIsStoppedContent; + return isCoproxyIniting ? MainConst.ConginxButtonIsInitingContent : + isNginxIniting ? MainConst.NginxButtonIsInitingContent : + isConginxRunning || isNginxRunning ? MainConst.NginxButtonIsRunningContent : MainConst.NginxButtonIsStoppedContent; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException(); diff --git a/Convs/MainNginxButtonIsEnabledConv.cs b/Convs/MainNginxButtonIsEnabledConv.cs new file mode 100644 index 0000000..d69336a --- /dev/null +++ b/Convs/MainNginxButtonIsEnabledConv.cs @@ -0,0 +1,22 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace Sheas_Cealer.Convs; + +internal class MainNginxButtonIsEnabledConv : IMultiValueConverter +{ + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + bool isConginxExist = (bool)values[0]; + bool isNginxExist = (bool)values[1]; + bool isCoproxyIniting = (bool)values[2]; + bool isNginxIniting = (bool)values[3]; + bool isComihomoIniting = (bool)values[4]; + bool isMihomoIniting = (bool)values[5]; + + return !isCoproxyIniting && !isNginxIniting && !isComihomoIniting && !isMihomoIniting && (isConginxExist || isNginxExist); + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException(); +} \ No newline at end of file diff --git a/Convs/MainNginxButtonToolTipConv.cs b/Convs/MainNginxButtonToolTipConv.cs index 10d6af9..0a20b9f 100644 --- a/Convs/MainNginxButtonToolTipConv.cs +++ b/Convs/MainNginxButtonToolTipConv.cs @@ -5,14 +5,15 @@ using System.Windows.Data; namespace Sheas_Cealer.Convs; -internal class MainNginxButtonToolTipConv : IValueConverter +internal class MainNginxButtonToolTipConv : IMultiValueConverter { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { - bool isNginxRunning = (bool)value; + bool isConginxRunning = (bool)values[0]; + bool isNginxRunning = (bool)values[1]; - return isNginxRunning ? MainConst.NginxButtonIsRunningToolTip : MainConst.NginxButtonIsStoppedToolTip; + return isConginxRunning || isNginxRunning ? MainConst.NginxButtonIsRunningToolTip : MainConst.NginxButtonIsStoppedToolTip; } - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException(); } \ No newline at end of file diff --git a/Convs/MainProxyButtonIsEnabledConv.cs b/Convs/MainProxyButtonIsEnabledConv.cs deleted file mode 100644 index bcb28b1..0000000 --- a/Convs/MainProxyButtonIsEnabledConv.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; - -namespace Sheas_Cealer.Convs; - -internal class MainProxyButtonIsEnabledConv : IMultiValueConverter -{ - public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) - { - bool isProxyExist = (bool)values[0]; - bool isProxyIniting = (bool)values[1]; - - return !isProxyIniting && isProxyExist; - } - - public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException(); -} \ No newline at end of file diff --git a/Preses/MainPres.cs b/Preses/MainPres.cs index 4b13c9a..a12c950 100644 --- a/Preses/MainPres.cs +++ b/Preses/MainPres.cs @@ -74,21 +74,42 @@ internal partial class MainPres : GlobalPres [ObservableProperty] private bool isUpstreamHostUtd = true; + [ObservableProperty] + private bool isCoproxyIniting = false; + + [ObservableProperty] + private bool isCoproxyStopping = false; + + [ObservableProperty] + private bool isConginxExist = File.Exists(MainConst.ConginxPath); + [ObservableProperty] private bool isNginxExist = File.Exists(MainConst.NginxPath); [ObservableProperty] private bool isNginxIniting = false; + [ObservableProperty] + private bool isConginxRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.ConginxPath)).Length != 0; + [ObservableProperty] private bool isNginxRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.NginxPath)).Length != 0; + [ObservableProperty] + private bool isComihomoExist = File.Exists(MainConst.ComihomoPath); + [ObservableProperty] private bool isMihomoExist = File.Exists(MainConst.MihomoPath); + [ObservableProperty] + private bool isComihomoIniting = false; + [ObservableProperty] private bool isMihomoIniting = false; + [ObservableProperty] + private bool isComihomoRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.ComihomoPath)).Length != 0; + [ObservableProperty] private bool isMihomoRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.MihomoPath)).Length != 0; diff --git a/Wins/MainWin.xaml b/Wins/MainWin.xaml index f09f5dc..c111372 100644 --- a/Wins/MainWin.xaml +++ b/Wins/MainWin.xaml @@ -77,20 +77,31 @@ @@ -135,9 +151,13 @@ ToolTip="{x:Static consts:MainConst.EditNginxConfButtonToolTip}" Click="EditConfButton_Click"> - + + + + + @@ -147,8 +167,11 @@ ToolTip="{x:Static consts:MainConst.EditMihomoConfButtonToolTip}" Click="EditConfButton_Click"> - + + + + diff --git a/Wins/MainWin.xaml.cs b/Wins/MainWin.xaml.cs index 6e971a0..62cb021 100644 --- a/Wins/MainWin.xaml.cs +++ b/Wins/MainWin.xaml.cs @@ -48,6 +48,8 @@ public partial class MainWin : Window private string CealArgs = string.Empty; private NginxConfig? NginxConfs; private string? ExtraNginxConfs; + private string? ComihomoConfs; + private string? HostsComihomoConfs; private string? MihomoConfs; private string? ExtraMihomoConfs; @@ -83,15 +85,15 @@ public partial class MainWin : Window foreach (string cealHostPath in Directory.GetFiles(CealHostWatcher.Path, CealHostWatcher.Filter)) CealHostWatcher_Changed(null!, new(new(), Path.GetDirectoryName(cealHostPath)!, Path.GetFileName(cealHostPath))); - MihomoConfWatcher_Changed(null!, (FileSystemEventArgs)FileSystemEventArgs.Empty); + MihomoConfWatcher_Changed(null!, null!); - if (!MainPres.IsNginxRunning) + if (!MainPres.IsConginxRunning && !MainPres.IsNginxRunning) await NginxCleaner.Clean(); if (Array.Exists(Environment.GetCommandLineArgs(), arg => arg.Equals("-s", StringComparison.OrdinalIgnoreCase))) LaunchButton_Click(null, (RoutedEventArgs)RoutedEventArgs.Empty); - UpdateUpstreamHostButton_Click(null, (RoutedEventArgs)RoutedEventArgs.Empty); + UpdateUpstreamHostButton_Click(null, null!); }); } private async void MainWin_Closing(object sender, CancelEventArgs e) @@ -204,14 +206,15 @@ public partial class MainWin : Window { HoldButtonTimer?.Stop(); - if (!MainPres.IsNginxRunning) + if (!MainPres.IsConginxRunning && !MainPres.IsNginxRunning) { if (NginxCleaner.IsNginxCleaningSemaphore.CurrentCount == 0 || !await IsNginxLaunchingSemaphore.WaitAsync(0)) return; try { - if ((CealHostRulesDict.ContainsValue(null!) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || + if ((!MainPres.IsConginxExist && !MainPres.IsNginxExist) || + (CealHostRulesDict.ContainsValue(null!) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || (NginxHttpsPort != 443 && MessageBox.Show(string.Format(MainConst._NginxHttpsPortOccupiedPrompt, NginxHttpsPort), string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || (NginxHttpPort != 80 && MessageBox.Show(string.Format(MainConst._NginxHttpPortOccupiedPrompt, NginxHttpPort), string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || (MessageBox.Show(MainConst._LaunchProxyPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || @@ -225,6 +228,9 @@ public partial class MainWin : Window if (!Directory.Exists(MainConst.NginxTempPath)) Directory.CreateDirectory(MainConst.NginxTempPath); + if (sender == null) + File.Move(MainConst.NginxPath, MainConst.ConginxPath); + RSA certKey = RSA.Create(2048); #region Root Cert @@ -256,14 +262,18 @@ public partial class MainWin : Window if (cealHostIncludeDomain.TrimStart('$').StartsWith('*')) { childCertSanBuilder.AddDnsName($"*.{cealHostIncludeDomainWithoutWildcard}"); - hostsConfAppendContent += $"127.0.0.1 www.{cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; + + if (sender != null) + hostsConfAppendContent += $"127.0.0.1 www.{cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; if (cealHostIncludeDomain.TrimStart('$').StartsWith("*.")) continue; } childCertSanBuilder.AddDnsName(cealHostIncludeDomainWithoutWildcard); - hostsConfAppendContent += $"127.0.0.1 {cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; + + if (sender != null) + hostsConfAppendContent += $"127.0.0.1 {cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; } childCertRequest.CertificateExtensions.Add(childCertSanBuilder.Build()); @@ -273,21 +283,31 @@ public partial class MainWin : Window await File.WriteAllTextAsync(MainConst.NginxCertPath, childCert.ExportCertificatePem()); await File.WriteAllTextAsync(MainConst.NginxKeyPath, certKey.ExportPkcs8PrivateKeyPem()); - hostsConfAppendContent += MainConst.HostsConfEndMarker; + if (sender != null) + { + hostsConfAppendContent += MainConst.HostsConfEndMarker; - File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly); - await File.AppendAllTextAsync(MainConst.HostsConfPath, hostsConfAppendContent); + File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly); + await File.AppendAllTextAsync(MainConst.HostsConfPath, hostsConfAppendContent); + } #endregion Child Cert & Hosts try { - MainPres.IsNginxIniting = true; + if (sender == null) + MainPres.IsCoproxyIniting = true; + else + MainPres.IsNginxIniting = true; + NginxConfWatcher.EnableRaisingEvents = false; NginxConfs!.Save(MainConst.NginxConfPath); await Task.Run(() => { - new NginxProc().Run(Path.GetDirectoryName(MainConst.NginxPath)!, @$"-c ""{Path.GetRelativePath(Path.GetDirectoryName(MainConst.NginxPath)!, MainConst.NginxConfPath)}"""); + if (sender == null) + new ConginxProc().Run(Path.GetDirectoryName(MainConst.ConginxPath)!, @$"-c ""{Path.GetRelativePath(Path.GetDirectoryName(MainConst.ConginxPath)!, MainConst.NginxConfPath)}"""); + else + new NginxProc().Run(Path.GetDirectoryName(MainConst.NginxPath)!, @$"-c ""{Path.GetRelativePath(Path.GetDirectoryName(MainConst.NginxPath)!, MainConst.NginxConfPath)}"""); }); while (true) @@ -304,7 +324,7 @@ public partial class MainWin : Window break; } - if (MainPres.IsNginxRunning) + if (sender == null ? MainPres.IsConginxRunning : MainPres.IsNginxRunning) continue; if (MessageBox.Show(MainConst._LaunchNginxErrorPrompt, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) @@ -312,52 +332,104 @@ public partial class MainWin : Window break; } + + if (sender == null) + MihomoButtonHoldTimer_Tick(null, EventArgs.Empty); } finally { await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs); NginxConfWatcher.EnableRaisingEvents = true; - MainPres.IsNginxIniting = false; + + if (sender != null) + MainPres.IsNginxIniting = false; } } finally { IsNginxLaunchingSemaphore.Release(); } } else - foreach (Process nginxProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.NginxPath))) + { + MainPres.IsCoproxyStopping = true; + + bool isConginxRunning = MainPres.IsConginxRunning; + + foreach (Process nginxProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(isConginxRunning ? MainConst.ConginxPath : MainConst.NginxPath))) { nginxProcess.Exited += async (_, _) => { await NginxCleaner.Clean(); - NginxConfWatcher_Changed(null!, (FileSystemEventArgs)FileSystemEventArgs.Empty); + NginxConfWatcher_Changed(null!, null!); }; nginxProcess.Kill(); } + + if (isConginxRunning) + { + MainPres.IsConginxRunning = false; + + File.Move(MainConst.ConginxPath, MainConst.NginxPath); + + MihomoButtonHoldTimer_Tick(null, EventArgs.Empty); + } + else + MainPres.IsNginxRunning = false; + } } private async void MihomoButtonHoldTimer_Tick(object? sender, EventArgs e) { HoldButtonTimer?.Stop(); - if (!MainPres.IsMihomoRunning) + if (!MainPres.IsComihomoRunning && !MainPres.IsMihomoRunning) { + if (!MainPres.IsComihomoExist && !MainPres.IsMihomoExist) + return; if (string.IsNullOrWhiteSpace(MihomoConfs)) throw new(MainConst._MihomoConfErrorMsg); - if (MessageBox.Show(MainConst._LaunchProxyPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) + if (!MainPres.IsConginxRunning && !MainPres.IsCoproxyStopping && MessageBox.Show(MainConst._LaunchProxyPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; if (!File.Exists(MainConst.MihomoConfPath)) await File.Create(MainConst.MihomoConfPath).DisposeAsync(); + if (MainPres.IsConginxRunning) + if (MainPres.IsMihomoExist) + { + File.Move(MainConst.MihomoPath, MainConst.ComihomoPath); + MainPres.IsComihomoExist = true; + MainPres.IsMihomoExist = false; + } + else if (MainPres.IsComihomoExist) + { + File.Move(MainConst.ComihomoPath, MainConst.MihomoPath); + MainPres.IsComihomoExist = false; + MainPres.IsMihomoExist = true; + } + try { - MainPres.IsMihomoIniting = true; + if (MainPres.IsComihomoExist) + MainPres.IsComihomoIniting = true; + else + MainPres.IsMihomoIniting = true; + MihomoConfWatcher.EnableRaisingEvents = false; - await File.WriteAllTextAsync(MainConst.MihomoConfPath, MihomoConfs); + await File.WriteAllTextAsync(MainConst.MihomoConfPath, !MainPres.IsConginxRunning ? MihomoConfs : + MainPres.IsComihomoExist ? HostsComihomoConfs : ComihomoConfs); await Task.Run(() => { - new MihomoProc().Run(Path.GetDirectoryName(MainConst.MihomoPath)!, @$"-d ""{Path.GetDirectoryName(MainConst.MihomoConfPath)}"""); + if (MainPres.IsComihomoExist) + { + new ComihomoProc().Run(Path.GetDirectoryName(MainConst.ComihomoPath)!, @$"-d ""{Path.GetDirectoryName(MainConst.MihomoConfPath)}"""); + MainPres.IsComihomoRunning = true; + } + else + { + new MihomoProc().Run(Path.GetDirectoryName(MainConst.MihomoPath)!, @$"-d ""{Path.GetDirectoryName(MainConst.MihomoConfPath)}"""); + MainPres.IsMihomoRunning = true; + } }); while (true) @@ -374,7 +446,7 @@ public partial class MainWin : Window break; } - if (MainPres.IsMihomoRunning) + if (MainPres.IsComihomoExist ? MainPres.IsComihomoRunning : MainPres.IsMihomoRunning) continue; MessageBox.Show(MainConst._LaunchMihomoErrorMsg); @@ -386,16 +458,59 @@ public partial class MainWin : Window { await File.WriteAllTextAsync(MainConst.MihomoConfPath, ExtraMihomoConfs); MihomoConfWatcher.EnableRaisingEvents = true; - MainPres.IsMihomoIniting = false; + + if (MainPres.IsCoproxyIniting) + MainPres.IsCoproxyIniting = false; + else if (MainPres.IsCoproxyStopping) + MainPres.IsCoproxyStopping = false; + + if (MainPres.IsComihomoExist) + MainPres.IsComihomoIniting = false; + else + MainPres.IsMihomoIniting = false; } } else - foreach (Process mihomoProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.MihomoPath))) + { + bool isComihomoRunning = MainPres.IsComihomoRunning; + + foreach (Process mihomoProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(isComihomoRunning ? MainConst.ComihomoPath : MainConst.MihomoPath))) { - mihomoProcess.Exited += (_, _) => MihomoConfWatcher_Changed(null!, (FileSystemEventArgs)FileSystemEventArgs.Empty); + mihomoProcess.Exited += (_, _) => MihomoConfWatcher_Changed(null!, null!); mihomoProcess.Kill(); } + + if (isComihomoRunning) + MainPres.IsComihomoRunning = false; + else + MainPres.IsMihomoRunning = false; + + if (MainPres.IsConginxRunning) + { + if (MainPres.IsCoproxyIniting) + { + File.Move(MainConst.MihomoPath, MainConst.ComihomoPath); + MainPres.IsComihomoExist = true; + MainPres.IsMihomoExist = false; + } + + MihomoButtonHoldTimer_Tick(null, EventArgs.Empty); + + return; + } + + if (MainPres.IsComihomoExist) + { + File.Move(MainConst.ComihomoPath, MainConst.MihomoPath); + MainPres.IsComihomoExist = false; + MainPres.IsMihomoExist = true; + + MainPres.IsCoproxyStopping = false; + } + else if (MainPres.IsCoproxyStopping) + MihomoButtonHoldTimer_Tick(null, EventArgs.Empty); + } } private async void EditHostButton_Click(object sender, RoutedEventArgs e) @@ -500,7 +615,7 @@ public partial class MainWin : Window { MessageBox.Show(MainConst._GameStartMsg); MainPres.IsFlashing = true; - NginxConfWatcher_Changed(null!, (FileSystemEventArgs)FileSystemEventArgs.Empty); + NginxConfWatcher_Changed(null!, null!); Random random = new(); @@ -536,7 +651,7 @@ public partial class MainWin : Window } MainPres.IsFlashing = false; - NginxConfWatcher_Changed(null!, (FileSystemEventArgs)FileSystemEventArgs.Empty); + NginxConfWatcher_Changed(null!, null!); MessageBox.Show(MainConst._GameEndingMsg); } else @@ -562,9 +677,13 @@ public partial class MainWin : Window private void ProxyTimer_Tick(object? sender, EventArgs e) { + MainPres.IsConginxExist = File.Exists(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, Path.GetFileName(MainConst.ConginxPath))); MainPres.IsNginxExist = File.Exists(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, Path.GetFileName(MainConst.NginxPath))); + MainPres.IsConginxRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.ConginxPath)).Length != 0; MainPres.IsNginxRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.NginxPath)).Length != 0; + MainPres.IsComihomoExist = File.Exists(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, Path.GetFileName(MainConst.ComihomoPath))); MainPres.IsMihomoExist = File.Exists(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, Path.GetFileName(MainConst.MihomoPath))); + MainPres.IsComihomoRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.ComihomoPath)).Length != 0; MainPres.IsMihomoRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.MihomoPath)).Length != 0; } private async void CealHostWatcher_Changed(object sender, FileSystemEventArgs e) @@ -632,12 +751,12 @@ public partial class MainWin : Window CealArgs = @$"--host-rules=""{hostRules.TrimEnd(',')}"" --host-resolver-rules=""{hostResolverRules.TrimEnd(',')}"" --test-type --ignore-certificate-errors"; - NginxConfWatcher_Changed(null!, (FileSystemEventArgs)FileSystemEventArgs.Empty); + NginxConfWatcher_Changed(null!, null!); } } private async void NginxConfWatcher_Changed(object sender, FileSystemEventArgs e) { - if (!MainConst.IsAdmin || !MainPres.IsNginxExist) + if (!MainConst.IsAdmin || (!MainPres.IsNginxExist && !MainPres.IsConginxExist)) return; if (!File.Exists(MainConst.NginxConfPath)) @@ -715,7 +834,7 @@ public partial class MainWin : Window } private async void MihomoConfWatcher_Changed(object sender, FileSystemEventArgs e) { - if (!MainConst.IsAdmin || !MainPres.IsMihomoExist) + if (!MainConst.IsAdmin || (!MainPres.IsMihomoExist && !MainPres.IsComihomoExist)) return; try @@ -737,16 +856,14 @@ public partial class MainWin : Window .IgnoreUnmatchedProperties() .Build() .Deserialize>(ExtraMihomoConfs = await new StreamReader(mihomoConfStream).ReadToEndAsync()) ?? []; + Dictionary hostsMihomoConfDict = new DeserializerBuilder() + .WithNamingConvention(HyphenatedNamingConvention.Instance) + .IgnoreUnmatchedProperties() + .Build() + .Deserialize>(ExtraMihomoConfs = await new StreamReader(mihomoConfStream).ReadToEndAsync()) ?? []; - mihomoConfDict["mixed-port"] = MihomoMixedPort; - mihomoConfDict["dns"] = new - { - enable = true, - listen = ":53", - enhancedMode = "redir-host", - nameserver = MainConst.MihomoNameServers - }; - mihomoConfDict["tun"] = new + mihomoConfDict["mixed-port"] = hostsMihomoConfDict["mixed-port"] = MihomoMixedPort; + mihomoConfDict["tun"] = hostsMihomoConfDict["tun"] = new { enable = true, stack = "system", @@ -754,10 +871,48 @@ public partial class MainWin : Window autoDetectInterface = true, dnsHijack = new[] { "any:53", "tcp://any:53" } }; + mihomoConfDict["dns"] = new + { + enable = true, + listen = ":53", + nameserver = MainConst.MihomoNameServers + }; + hostsMihomoConfDict["dns"] = new + { + enable = true, + listen = ":53" + }; MihomoConfs = new SerializerBuilder().WithNamingConvention(HyphenatedNamingConvention.Instance).Build().Serialize(mihomoConfDict); + + Dictionary mihomoHostsDict = []; + + foreach (List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>? cealHostRules in CealHostRulesDict.Values) + foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, _, _) in cealHostRules ?? []) + foreach ((string cealHostIncludeDomain, _) in cealHostDomainPairs) + { + string cealHostIncludeDomainWithoutWildcard = cealHostIncludeDomain.TrimStart('$').TrimStart('*').TrimStart('.'); + + if (cealHostIncludeDomain.StartsWith('#') || cealHostIncludeDomainWithoutWildcard.Contains('*') || string.IsNullOrWhiteSpace(cealHostIncludeDomainWithoutWildcard)) + continue; + + if (cealHostIncludeDomain.TrimStart('$').StartsWith('*')) + { + mihomoHostsDict.TryAdd($"*.{cealHostIncludeDomainWithoutWildcard}", "127.0.0.1"); + + if (cealHostIncludeDomain.TrimStart('$').StartsWith("*.")) + continue; + } + + mihomoHostsDict.TryAdd(cealHostIncludeDomainWithoutWildcard, "127.0.0.1"); + } + + mihomoConfDict["hosts"] = hostsMihomoConfDict["hosts"] = mihomoHostsDict; + + ComihomoConfs = new SerializerBuilder().WithNamingConvention(HyphenatedNamingConvention.Instance).Build().Serialize(mihomoConfDict); + HostsComihomoConfs = new SerializerBuilder().WithNamingConvention(HyphenatedNamingConvention.Instance).Build().Serialize(hostsMihomoConfDict); } - catch { MihomoConfs = string.Empty; } + catch { ComihomoConfs = HostsComihomoConfs = MihomoConfs = string.Empty; } } private void MainWin_KeyDown(object sender, KeyEventArgs e) {