1.1.3 -> 1.1.4 第82次更新

This commit is contained in:
Space Time 2024-12-20 00:00:54 +08:00
parent e962850d05
commit 6a7b65fe99
32 changed files with 265 additions and 263 deletions

View File

@ -1,13 +1,13 @@
using System; using MaterialDesignThemes.Wpf;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using MaterialDesignThemes.Wpf;
using Sheas_Cealer.Preses; using Sheas_Cealer.Preses;
using Sheas_Cealer.Props; using Sheas_Cealer.Props;
using Sheas_Cealer.Utils; using Sheas_Cealer.Utils;
using Sheas_Cealer.Wins; using Sheas_Cealer.Wins;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace Sheas_Cealer; namespace Sheas_Cealer;

View File

@ -2,7 +2,7 @@
namespace Sheas_Cealer.Consts; namespace Sheas_Cealer.Consts;
internal class AboutConst : AboutMultilangConst internal abstract class AboutConst : AboutMultilangConst
{ {
public static string DeveloperButtonUrl => "https://www.spacetimee.xyz"; public static string DeveloperButtonUrl => "https://www.spacetimee.xyz";
public static string VersionButtonVersionContent => Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2]; public static string VersionButtonVersionContent => Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];

View File

@ -1,12 +1,12 @@
using System; using Microsoft.Win32;
using System;
using System.IO; using System.IO;
using System.Security.Principal; using System.Security.Principal;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
namespace Sheas_Cealer.Consts; namespace Sheas_Cealer.Consts;
internal partial class MainConst : MainMultilangConst internal abstract partial class MainConst : MainMultilangConst
{ {
internal enum SettingsMode internal enum SettingsMode
{ BrowserPathMode, UpstreamUrlMode, ExtraArgsMode }; { BrowserPathMode, UpstreamUrlMode, ExtraArgsMode };

View File

@ -1,3 +1,3 @@
namespace Sheas_Cealer.Consts; namespace Sheas_Cealer.Consts;
internal class SettingsConst : SettingsMultilangConst; internal abstract class SettingsConst : SettingsMultilangConst;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,8 +1,8 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,8 +1,8 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,8 +1,8 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,8 +1,8 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;

View File

@ -1,13 +1,13 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;
internal class SettingsLangsButtonContentConv : IValueConverter internal class SettingsLangsButtonContentConv : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
{ {
bool? isEnglishLang = value as bool?; bool? isEnglishLang = value as bool?;

View File

@ -1,13 +1,13 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;
internal class SettingsThemesButtonContentConv : IValueConverter internal class SettingsThemesButtonContentConv : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
{ {
bool? isLightMode = value as bool?; bool? isLightMode = value as bool?;

View File

@ -1,13 +1,13 @@
using System; using Sheas_Cealer.Consts;
using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using Sheas_Cealer.Consts;
namespace Sheas_Cealer.Convs; namespace Sheas_Cealer.Convs;
internal class SettingsWeightsButtonContentConv : IValueConverter internal class SettingsWeightsButtonContentConv : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
{ {
bool? isLightWeight = value as bool?; bool? isLightWeight = value as bool?;

View File

@ -1,10 +1,10 @@
using System.Diagnostics; using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using MaterialDesignThemes.Wpf; using MaterialDesignThemes.Wpf;
using Sheas_Cealer.Props; using Sheas_Cealer.Props;
using Sheas_Cealer.Utils; using Sheas_Cealer.Utils;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
namespace Sheas_Cealer.Preses; namespace Sheas_Cealer.Preses;

View File

@ -1,10 +1,10 @@
using System; using CommunityToolkit.Mvvm.ComponentModel;
using System.Diagnostics;
using System.IO;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Win32; using Microsoft.Win32;
using Sheas_Cealer.Consts; using Sheas_Cealer.Consts;
using Sheas_Cealer.Props; using Sheas_Cealer.Props;
using System;
using System.Diagnostics;
using System.IO;
using File = System.IO.File; using File = System.IO.File;
namespace Sheas_Cealer.Preses; namespace Sheas_Cealer.Preses;
@ -42,33 +42,33 @@ internal partial class MainPres : GlobalPres
private string browserPath; private string browserPath;
partial void OnBrowserPathChanged(string value) partial void OnBrowserPathChanged(string value)
{ {
if (File.Exists(value) && Path.GetFileName(value).ToLowerInvariant().EndsWith(".exe")) if (!File.Exists(value) || !Path.GetFileName(value).ToLowerInvariant().EndsWith(".exe"))
{ return;
Settings.Default.BrowserPath = value;
Settings.Default.Save(); Settings.Default.BrowserPath = value;
} Settings.Default.Save();
} }
[ObservableProperty] [ObservableProperty]
private string upstreamUrl; private string upstreamUrl;
partial void OnUpstreamUrlChanged(string value) partial void OnUpstreamUrlChanged(string value)
{ {
if (MainConst.UpstreamUrlRegex().IsMatch(value)) if (!MainConst.UpstreamUrlRegex().IsMatch(value))
{ return;
Settings.Default.UpstreamUrl = value;
Settings.Default.Save(); Settings.Default.UpstreamUrl = value;
} Settings.Default.Save();
} }
[ObservableProperty] [ObservableProperty]
private string extraArgs; private string extraArgs;
partial void OnExtraArgsChanged(string value) partial void OnExtraArgsChanged(string value)
{ {
if (MainConst.ExtraArgsRegex().IsMatch(value)) if (!MainConst.ExtraArgsRegex().IsMatch(value))
{ return;
Settings.Default.ExtraArgs = value;
Settings.Default.Save(); Settings.Default.ExtraArgs = value;
} Settings.Default.Save();
} }
[ObservableProperty] [ObservableProperty]

View File

@ -1,11 +1,11 @@
using System.Diagnostics; using CommunityToolkit.Mvvm.ComponentModel;
using Sheas_Cealer.Props;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Threading; using System.Threading;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Markup; using System.Windows.Markup;
using CommunityToolkit.Mvvm.ComponentModel;
using Sheas_Cealer.Props;
namespace Sheas_Cealer.Preses; namespace Sheas_Cealer.Preses;

View File

@ -1,6 +1,6 @@
using System; using Sheas_Core;
using System;
using System.Windows; using System.Windows;
using Sheas_Core;
namespace Sheas_Cealer.Proces; namespace Sheas_Cealer.Proces;
@ -15,7 +15,7 @@ internal class BrowserProc : Proc
Process_Exited(null!, null!); Process_Exited(null!, null!);
} }
public override void Process_Exited(object sender, EventArgs e) protected sealed override void Process_Exited(object sender, EventArgs e)
{ {
if (ShutDownAppOnProcessExit) if (ShutDownAppOnProcessExit)
Application.Current.Dispatcher.InvokeShutdown(); Application.Current.Dispatcher.InvokeShutdown();

View File

@ -1,7 +1,7 @@
using System; using Sheas_Cealer.Consts;
using Sheas_Cealer.Consts;
using Sheas_Cealer.Utils; using Sheas_Cealer.Utils;
using Sheas_Core; using Sheas_Core;
using System;
namespace Sheas_Cealer.Proces; namespace Sheas_Cealer.Proces;
@ -9,5 +9,5 @@ internal class NginxProc : Proc
{ {
internal NginxProc() : base(MainConst.NginxPath) { } internal NginxProc() : base(MainConst.NginxPath) { }
public override void Process_Exited(object sender, EventArgs e) => NginxCleaner.Clean(); protected override async void Process_Exited(object sender, EventArgs e) => await NginxCleaner.Clean();
} }

View File

@ -10,9 +10,9 @@ internal static partial class BorderThemeSetter
private const int DwmwaUseImmersiveDarkMode = 20; private const int DwmwaUseImmersiveDarkMode = 20;
[LibraryImport("dwmapi.dll")] [LibraryImport("dwmapi.dll")]
private static partial int DwmGetWindowAttribute(nint hwnd, uint attr, out nint attrValue, uint attrSize); private static partial void DwmGetWindowAttribute(nint hwnd, uint attr, out nint attrValue, uint attrSize);
[LibraryImport("dwmapi.dll")] [LibraryImport("dwmapi.dll")]
private static partial int DwmSetWindowAttribute(nint hwnd, uint attr, ref nint attrValue, uint attrSize); private static partial void DwmSetWindowAttribute(nint hwnd, uint attr, ref nint attrValue, uint attrSize);
internal static void SetBorderTheme(Window window, bool? isLightTheme) internal static void SetBorderTheme(Window window, bool? isLightTheme)
{ {
@ -25,7 +25,7 @@ internal static partial class BorderThemeSetter
else else
DwmGetWindowAttribute(desktopHwnd, DwmwaUseImmersiveDarkMode, out isDarkTheme, (uint)Marshal.SizeOf(typeof(nint))); DwmGetWindowAttribute(desktopHwnd, DwmwaUseImmersiveDarkMode, out isDarkTheme, (uint)Marshal.SizeOf(typeof(nint)));
_ = DwmSetWindowAttribute(windowHwnd, DwmwaUseImmersiveDarkModeOld, ref isDarkTheme, (uint)Marshal.SizeOf(typeof(nint))); DwmSetWindowAttribute(windowHwnd, DwmwaUseImmersiveDarkModeOld, ref isDarkTheme, (uint)Marshal.SizeOf(typeof(nint)));
_ = DwmSetWindowAttribute(windowHwnd, DwmwaUseImmersiveDarkMode, ref isDarkTheme, (uint)Marshal.SizeOf(typeof(nint))); DwmSetWindowAttribute(windowHwnd, DwmwaUseImmersiveDarkMode, ref isDarkTheme, (uint)Marshal.SizeOf(typeof(nint)));
} }
} }

View File

@ -17,18 +17,18 @@ internal static partial class IconRemover
[LibraryImport("user32.dll", EntryPoint = "GetWindowLongW")] [LibraryImport("user32.dll", EntryPoint = "GetWindowLongW")]
private static partial int GetWindowLong(nint hwnd, int index); private static partial int GetWindowLong(nint hwnd, int index);
[LibraryImport("user32.dll", EntryPoint = "SetWindowLongW")] [LibraryImport("user32.dll", EntryPoint = "SetWindowLongW")]
private static partial int SetWindowLong(nint hwnd, int index, nint newStyle); private static partial void SetWindowLong(nint hwnd, int index, nint newStyle);
[LibraryImport("user32.dll")] [LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
private static partial bool SetWindowPos(nint hwnd, nint hwndInsertAfter, int x, int y, int width, int height, uint flags); private static partial void SetWindowPos(nint hwnd, nint hwndInsertAfter, int x, int y, int width, int height, uint flags);
[LibraryImport("user32.dll", EntryPoint = "SendMessageW")] [LibraryImport("user32.dll", EntryPoint = "SendMessageW")]
private static partial nint SendMessage(nint hwnd, uint msg, nint wParam, nint lParam); private static partial void SendMessage(nint hwnd, uint msg, nint wParam, nint lParam);
internal static void RemoveIcon(Window window) internal static void RemoveIcon(Window window)
{ {
nint hwnd = new WindowInteropHelper(window).Handle; nint hwnd = new WindowInteropHelper(window).Handle;
_ = SetWindowLong(hwnd, GwlExStyle, GetWindowLong(hwnd, GwlExStyle) | WsExDlgModalFrame); SetWindowLong(hwnd, GwlExStyle, GetWindowLong(hwnd, GwlExStyle) | WsExDlgModalFrame);
SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0, SwpNoMove | SwpNoSize | SwpNoZOrder | SwpFrameChanged); SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0, SwpNoMove | SwpNoSize | SwpNoZOrder | SwpFrameChanged);

View File

@ -1,7 +1,9 @@
using System.IO; using Sheas_Cealer.Consts;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using Sheas_Cealer.Consts; using System.Threading.Tasks;
namespace Sheas_Cealer.Utils namespace Sheas_Cealer.Utils
{ {
@ -9,19 +11,19 @@ namespace Sheas_Cealer.Utils
{ {
private static readonly object IsCleaningLock = new(); private static readonly object IsCleaningLock = new();
internal static void Clean() internal static async Task Clean()
{ {
if (!Monitor.TryEnter(IsCleaningLock)) if (!Monitor.TryEnter(IsCleaningLock))
return; return;
try try
{ {
string hostsContent = File.ReadAllText(MainConst.HostsConfPath); string hostsContent = await File.ReadAllTextAsync(MainConst.HostsConfPath);
int hostsConfStartIndex = hostsContent.IndexOf(MainConst.HostsConfStartMarker); int hostsConfStartIndex = hostsContent.IndexOf(MainConst.HostsConfStartMarker, StringComparison.Ordinal);
int hostsConfEndIndex = hostsContent.LastIndexOf(MainConst.HostsConfEndMarker); int hostsConfEndIndex = hostsContent.LastIndexOf(MainConst.HostsConfEndMarker, StringComparison.Ordinal);
if (hostsConfStartIndex != -1 && hostsConfEndIndex != -1) if (hostsConfStartIndex != -1 && hostsConfEndIndex != -1)
File.WriteAllText(MainConst.HostsConfPath, hostsContent.Remove(hostsConfStartIndex, hostsConfEndIndex - hostsConfStartIndex + MainConst.HostsConfEndMarker.Length)); await File.WriteAllTextAsync(MainConst.HostsConfPath, hostsContent.Remove(hostsConfStartIndex, hostsConfEndIndex - hostsConfStartIndex + MainConst.HostsConfEndMarker.Length));
using X509Store certStore = new(StoreName.Root, StoreLocation.CurrentUser, OpenFlags.ReadWrite); using X509Store certStore = new(StoreName.Root, StoreLocation.CurrentUser, OpenFlags.ReadWrite);

View File

@ -1,4 +1,8 @@
using System; using Ona_Core;
using Sheas_Cealer.Consts;
using Sheas_Cealer.Preses;
using Sheas_Cealer.Utils;
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Net.Http; using System.Net.Http;
using System.Text.Json; using System.Text.Json;
@ -6,10 +10,6 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Ona_Core;
using Sheas_Cealer.Consts;
using Sheas_Cealer.Preses;
using Sheas_Cealer.Utils;
namespace Sheas_Cealer.Wins; namespace Sheas_Cealer.Wins;

View File

@ -1,4 +1,12 @@
using System; using MaterialDesignThemes.Wpf;
using Microsoft.Win32;
using NginxConfigParser;
using Ona_Core;
using Sheas_Cealer.Consts;
using Sheas_Cealer.Preses;
using Sheas_Cealer.Proces;
using Sheas_Cealer.Utils;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
@ -17,14 +25,6 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using MaterialDesignThemes.Wpf;
using Microsoft.Win32;
using NginxConfigParser;
using Ona_Core;
using Sheas_Cealer.Consts;
using Sheas_Cealer.Preses;
using Sheas_Cealer.Proces;
using Sheas_Cealer.Utils;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;
using File = System.IO.File; using File = System.IO.File;
@ -41,7 +41,7 @@ public partial class MainWin : Window
private readonly FileSystemWatcher NginxConfWatcher = new(Path.GetDirectoryName(MainConst.NginxConfPath)!, Path.GetFileName(MainConst.NginxConfPath)) { EnableRaisingEvents = true, NotifyFilter = NotifyFilters.LastWrite }; private readonly FileSystemWatcher NginxConfWatcher = new(Path.GetDirectoryName(MainConst.NginxConfPath)!, Path.GetFileName(MainConst.NginxConfPath)) { EnableRaisingEvents = true, NotifyFilter = NotifyFilters.LastWrite };
private readonly FileSystemWatcher MihomoConfWatcher = new(Path.GetDirectoryName(MainConst.MihomoConfPath)!, Path.GetFileName(MainConst.MihomoConfPath)) { EnableRaisingEvents = true, NotifyFilter = NotifyFilters.LastWrite }; private readonly FileSystemWatcher MihomoConfWatcher = new(Path.GetDirectoryName(MainConst.MihomoConfPath)!, Path.GetFileName(MainConst.MihomoConfPath)) { EnableRaisingEvents = true, NotifyFilter = NotifyFilters.LastWrite };
private readonly SortedDictionary<string, List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>> CealHostRulesDict = []; private readonly SortedDictionary<string, List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>?> CealHostRulesDict = [];
private string CealArgs = string.Empty; private string CealArgs = string.Empty;
private NginxConfig? NginxConfs; private NginxConfig? NginxConfs;
private string? ExtraNginxConfs; private string? ExtraNginxConfs;
@ -68,7 +68,7 @@ public partial class MainWin : Window
} }
private async void MainWin_Loaded(object sender, RoutedEventArgs e) private async void MainWin_Loaded(object sender, RoutedEventArgs e)
{ {
await Task.Run(() => await Task.Run(async () =>
{ {
ProxyTimer.Tick += ProxyTimer_Tick; ProxyTimer.Tick += ProxyTimer_Tick;
CealHostWatcher.Changed += CealHostWatcher_Changed; CealHostWatcher.Changed += CealHostWatcher_Changed;
@ -83,7 +83,7 @@ public partial class MainWin : Window
MihomoConfWatcher_Changed(null!, null!); MihomoConfWatcher_Changed(null!, null!);
if (!MainPres.IsNginxRunning) if (!MainPres.IsNginxRunning)
NginxCleaner.Clean(); await NginxCleaner.Clean();
if (Array.Exists(Environment.GetCommandLineArgs(), arg => arg.Equals("-s", StringComparison.OrdinalIgnoreCase))) if (Array.Exists(Environment.GetCommandLineArgs(), arg => arg.Equals("-s", StringComparison.OrdinalIgnoreCase)))
StartButton_Click(null!, null!); StartButton_Click(null!, null!);
@ -91,12 +91,12 @@ public partial class MainWin : Window
UpdateUpstreamHostButton_Click(null!, null!); UpdateUpstreamHostButton_Click(null!, null!);
}); });
} }
private void MainWin_Closing(object sender, CancelEventArgs e) private async void MainWin_Closing(object sender, CancelEventArgs e)
{ {
if (MainPres.IsNginxIniting) if (MainPres.IsNginxIniting)
File.WriteAllText(MainConst.NginxConfPath, ExtraNginxConfs); await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs);
if (MainPres.IsMihomoIniting) if (MainPres.IsMihomoIniting)
File.WriteAllText(MainConst.MihomoConfPath, ExtraMihomoConfs); await File.WriteAllTextAsync(MainConst.MihomoConfPath, ExtraMihomoConfs);
Application.Current.Shutdown(); Application.Current.Shutdown();
} }
@ -109,7 +109,7 @@ public partial class MainWin : Window
private void MainWin_Drop(object sender, DragEventArgs e) private void MainWin_Drop(object sender, DragEventArgs e)
{ {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) if (e.Data.GetDataPresent(DataFormats.FileDrop))
MainPres.BrowserPath = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; MainPres.BrowserPath = (e.Data.GetData(DataFormats.FileDrop) as string[])?[0] ?? string.Empty;
} }
private void SettingsBox_TextChanged(object sender, TextChangedEventArgs e) private void SettingsBox_TextChanged(object sender, TextChangedEventArgs e)
@ -156,7 +156,7 @@ public partial class MainWin : Window
} }
} }
private void StartButton_Click(object sender, RoutedEventArgs e) private void StartButton_Click(object? sender, RoutedEventArgs e)
{ {
if (HoldButtonTimer == null || HoldButtonTimer.IsEnabled) if (HoldButtonTimer == null || HoldButtonTimer.IsEnabled)
StartButtonHoldTimer_Tick(sender == null, null!); StartButtonHoldTimer_Tick(sender == null, null!);
@ -172,7 +172,7 @@ public partial class MainWin : Window
HoldButtonTimer?.Stop(); HoldButtonTimer?.Stop();
if ((CealHostRulesDict.ContainsValue(null!) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || if ((CealHostRulesDict.ContainsValue(null!) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) ||
(!(sender is bool isSilent && isSilent) && MessageBox.Show(MainConst._KillBrowserProcessPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes)) (sender is not true && MessageBox.Show(MainConst._KillBrowserProcessPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes))
return; return;
foreach (Process browserProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainPres.BrowserPath))) foreach (Process browserProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainPres.BrowserPath)))
@ -211,7 +211,7 @@ public partial class MainWin : Window
return; return;
if (!File.Exists(MainConst.NginxConfPath)) if (!File.Exists(MainConst.NginxConfPath))
File.Create(MainConst.NginxConfPath).Dispose(); await File.Create(MainConst.NginxConfPath).DisposeAsync();
if (!Directory.Exists(MainConst.NginxLogsPath)) if (!Directory.Exists(MainConst.NginxLogsPath))
Directory.CreateDirectory(MainConst.NginxLogsPath); Directory.CreateDirectory(MainConst.NginxLogsPath);
if (!Directory.Exists(MainConst.NginxTempPath)) if (!Directory.Exists(MainConst.NginxTempPath))
@ -236,7 +236,7 @@ public partial class MainWin : Window
SubjectAlternativeNameBuilder childCertSanBuilder = new(); SubjectAlternativeNameBuilder childCertSanBuilder = new();
string hostsConfAppendContent = MainConst.HostsConfStartMarker; string hostsConfAppendContent = MainConst.HostsConfStartMarker;
foreach (List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)> cealHostRules in CealHostRulesDict.Values) 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 ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, _, _) in cealHostRules ?? [])
foreach ((string cealHostIncludeDomain, _) in cealHostDomainPairs) foreach ((string cealHostIncludeDomain, _) in cealHostDomainPairs)
{ {
@ -262,13 +262,13 @@ public partial class MainWin : Window
using X509Certificate2 childCert = childCertRequest.Create(rootCert, rootCert.NotBefore, rootCert.NotAfter, Guid.NewGuid().ToByteArray()); using X509Certificate2 childCert = childCertRequest.Create(rootCert, rootCert.NotBefore, rootCert.NotAfter, Guid.NewGuid().ToByteArray());
File.WriteAllText(MainConst.NginxCertPath, childCert.ExportCertificatePem()); await File.WriteAllTextAsync(MainConst.NginxCertPath, childCert.ExportCertificatePem());
File.WriteAllText(MainConst.NginxKeyPath, certKey.ExportPkcs8PrivateKeyPem()); await File.WriteAllTextAsync(MainConst.NginxKeyPath, certKey.ExportPkcs8PrivateKeyPem());
hostsConfAppendContent += MainConst.HostsConfEndMarker; hostsConfAppendContent += MainConst.HostsConfEndMarker;
File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly); File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly);
File.AppendAllText(MainConst.HostsConfPath, hostsConfAppendContent); await File.AppendAllTextAsync(MainConst.HostsConfPath, hostsConfAppendContent);
#endregion Child Cert & Hosts #endregion Child Cert & Hosts
try try
@ -296,18 +296,18 @@ public partial class MainWin : Window
break; break;
} }
if (!MainPres.IsNginxRunning) if (MainPres.IsNginxRunning)
{ continue;
if (MessageBox.Show(MainConst._LaunchNginxErrorPrompt, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
Process.Start(new ProcessStartInfo(MainConst.NginxErrorLogsPath) { UseShellExecute = true });
break; if (MessageBox.Show(MainConst._LaunchNginxErrorPrompt, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
} Process.Start(new ProcessStartInfo(MainConst.NginxErrorLogsPath) { UseShellExecute = true });
break;
} }
} }
finally finally
{ {
File.WriteAllText(MainConst.NginxConfPath, ExtraNginxConfs); await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs);
NginxConfWatcher.EnableRaisingEvents = true; NginxConfWatcher.EnableRaisingEvents = true;
MainPres.IsNginxIniting = false; MainPres.IsNginxIniting = false;
} }
@ -320,7 +320,7 @@ public partial class MainWin : Window
nginxProcess.WaitForExit(); nginxProcess.WaitForExit();
} }
NginxCleaner.Clean(); await NginxCleaner.Clean();
NginxHttpPort = 80; NginxHttpPort = 80;
NginxHttpsPort = 443; NginxHttpsPort = 443;
@ -350,13 +350,13 @@ public partial class MainWin : Window
return; return;
if (!File.Exists(MainConst.MihomoConfPath)) if (!File.Exists(MainConst.MihomoConfPath))
File.Create(MainConst.MihomoConfPath).Dispose(); await File.Create(MainConst.MihomoConfPath).DisposeAsync();
try try
{ {
MainPres.IsMihomoIniting = true; MainPres.IsMihomoIniting = true;
MihomoConfWatcher.EnableRaisingEvents = false; MihomoConfWatcher.EnableRaisingEvents = false;
File.WriteAllText(MainConst.MihomoConfPath, MihomoConfs); await File.WriteAllTextAsync(MainConst.MihomoConfPath, MihomoConfs);
await Task.Run(() => await Task.Run(() =>
{ {
@ -377,17 +377,17 @@ public partial class MainWin : Window
break; break;
} }
if (!MainPres.IsMihomoRunning) if (MainPres.IsMihomoRunning)
{ continue;
MessageBox.Show(MainConst._LaunchMihomoErrorMsg);
break; MessageBox.Show(MainConst._LaunchMihomoErrorMsg);
}
break;
} }
} }
finally finally
{ {
File.WriteAllText(MainConst.MihomoConfPath, ExtraMihomoConfs); await File.WriteAllTextAsync(MainConst.MihomoConfPath, ExtraMihomoConfs);
MihomoConfWatcher.EnableRaisingEvents = true; MihomoConfWatcher.EnableRaisingEvents = true;
MainPres.IsMihomoIniting = false; MainPres.IsMihomoIniting = false;
} }
@ -405,18 +405,18 @@ public partial class MainWin : Window
} }
} }
private void EditHostButton_Click(object sender, RoutedEventArgs e) private async void EditHostButton_Click(object sender, RoutedEventArgs e)
{ {
Button senderButton = (Button)sender; Button senderButton = (Button)sender;
string cealHostPath = senderButton == EditLocalHostButton ? MainConst.LocalHostPath : MainConst.UpstreamHostPath; string cealHostPath = senderButton == EditLocalHostButton ? MainConst.LocalHostPath : MainConst.UpstreamHostPath;
if (!File.Exists(cealHostPath)) if (!File.Exists(cealHostPath))
File.Create(cealHostPath).Dispose(); await File.Create(cealHostPath).DisposeAsync();
try { Process.Start(new ProcessStartInfo(cealHostPath) { UseShellExecute = true }); } try { Process.Start(new ProcessStartInfo(cealHostPath) { UseShellExecute = true }); }
catch (UnauthorizedAccessException) { Process.Start(new ProcessStartInfo(cealHostPath) { UseShellExecute = true, Verb = "RunAs" }); } catch (UnauthorizedAccessException) { Process.Start(new ProcessStartInfo(cealHostPath) { UseShellExecute = true, Verb = "RunAs" }); }
} }
private void EditConfButton_Click(object sender, RoutedEventArgs e) private async void EditConfButton_Click(object sender, RoutedEventArgs e)
{ {
Button senderButton = (Button)sender; Button senderButton = (Button)sender;
string confPath; string confPath;
@ -432,21 +432,21 @@ public partial class MainWin : Window
confPath = senderButton == EditNginxConfButton ? MainConst.NginxConfPath : MainConst.MihomoConfPath; confPath = senderButton == EditNginxConfButton ? MainConst.NginxConfPath : MainConst.MihomoConfPath;
if (!File.Exists(confPath)) if (!File.Exists(confPath))
File.Create(confPath).Dispose(); await File.Create(confPath).DisposeAsync();
} }
Process.Start(new ProcessStartInfo(confPath) { UseShellExecute = true }); Process.Start(new ProcessStartInfo(confPath) { UseShellExecute = true });
} }
private async void UpdateUpstreamHostButton_Click(object sender, RoutedEventArgs e) private async void UpdateUpstreamHostButton_Click(object? sender, RoutedEventArgs e)
{ {
try try
{ {
if (!File.Exists(MainConst.UpstreamHostPath)) if (!File.Exists(MainConst.UpstreamHostPath))
File.Create(MainConst.UpstreamHostPath).Dispose(); await File.Create(MainConst.UpstreamHostPath).DisposeAsync();
string upstreamUpstreamHostUrl = (MainPres.UpstreamUrl.StartsWith("http://") || MainPres.UpstreamUrl.StartsWith("https://") ? string.Empty : "https://") + MainPres.UpstreamUrl; string upstreamUpstreamHostUrl = (MainPres.UpstreamUrl.StartsWith("http://") || MainPres.UpstreamUrl.StartsWith("https://") ? string.Empty : "https://") + MainPres.UpstreamUrl;
string upstreamUpstreamHostString = await Http.GetAsync<string>(upstreamUpstreamHostUrl, MainClient); string upstreamUpstreamHostString = await Http.GetAsync<string>(upstreamUpstreamHostUrl, MainClient);
string localUpstreamHostString = File.ReadAllText(MainConst.UpstreamHostPath); string localUpstreamHostString = await File.ReadAllTextAsync(MainConst.UpstreamHostPath);
try { upstreamUpstreamHostString = Encoding.UTF8.GetString(Convert.FromBase64String(upstreamUpstreamHostString)); } try { upstreamUpstreamHostString = Encoding.UTF8.GetString(Convert.FromBase64String(upstreamUpstreamHostString)); }
catch { } catch { }
@ -466,7 +466,7 @@ public partial class MainWin : Window
if (overrideOptionResult == MessageBoxResult.Yes) if (overrideOptionResult == MessageBoxResult.Yes)
{ {
File.WriteAllText(MainConst.UpstreamHostPath, upstreamUpstreamHostString); await File.WriteAllTextAsync(MainConst.UpstreamHostPath, upstreamUpstreamHostString);
MainPres.IsUpstreamHostUtd = true; MainPres.IsUpstreamHostUtd = true;
@ -574,7 +574,7 @@ public partial class MainWin : Window
MainPres.IsMihomoExist = File.Exists(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, Path.GetFileName(MainConst.MihomoPath))); MainPres.IsMihomoExist = File.Exists(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, Path.GetFileName(MainConst.MihomoPath)));
MainPres.IsMihomoRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.MihomoPath)).Length != 0; MainPres.IsMihomoRunning = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.MihomoPath)).Length != 0;
} }
private void CealHostWatcher_Changed(object sender, FileSystemEventArgs e) private async void CealHostWatcher_Changed(object sender, FileSystemEventArgs e)
{ {
string cealHostName = e.Name!.TrimStart("Cealing-Host-".ToCharArray()).TrimEnd(".json".ToCharArray()); string cealHostName = e.Name!.TrimStart("Cealing-Host-".ToCharArray()).TrimEnd(".json".ToCharArray());
@ -582,19 +582,19 @@ public partial class MainWin : Window
{ {
CealHostRulesDict[cealHostName] = []; CealHostRulesDict[cealHostName] = [];
using FileStream cealHostStream = new(e.FullPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); await using FileStream cealHostStream = new(e.FullPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
if (cealHostStream.Length == 0) if (cealHostStream.Length == 0)
return; return;
JsonDocumentOptions cealHostOptions = new() { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }; JsonDocumentOptions cealHostOptions = new() { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip };
JsonElement cealHostArray = JsonDocument.Parse(cealHostStream, cealHostOptions).RootElement; JsonElement cealHostArray = (await JsonDocument.ParseAsync(cealHostStream, cealHostOptions)).RootElement;
foreach (JsonElement cealHostRule in cealHostArray.EnumerateArray()) foreach (JsonElement cealHostRule in cealHostArray.EnumerateArray())
{ {
List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs = []; List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs = [];
string? cealHostSni = cealHostRule[1].ValueKind == JsonValueKind.Null ? null : string? cealHostSni = cealHostRule[1].ValueKind == JsonValueKind.Null ? null :
string.IsNullOrWhiteSpace(cealHostRule[1].ToString()) ? $"{cealHostName}{CealHostRulesDict[cealHostName].Count}" : cealHostRule[1].ToString().Trim(); string.IsNullOrWhiteSpace(cealHostRule[1].ToString()) ? $"{cealHostName}{CealHostRulesDict[cealHostName]!.Count}" : cealHostRule[1].ToString().Trim();
string cealHostIp = string.IsNullOrWhiteSpace(cealHostRule[2].ToString()) ? "127.0.0.1" : cealHostRule[2].ToString().Trim(); string cealHostIp = string.IsNullOrWhiteSpace(cealHostRule[2].ToString()) ? "127.0.0.1" : cealHostRule[2].ToString().Trim();
foreach (JsonElement cealHostDomain in cealHostRule[0].EnumerateArray()) foreach (JsonElement cealHostDomain in cealHostRule[0].EnumerateArray())
@ -608,17 +608,17 @@ public partial class MainWin : Window
} }
if (cealHostDomainPairs.Count != 0) if (cealHostDomainPairs.Count != 0)
CealHostRulesDict[cealHostName].Add((cealHostDomainPairs, cealHostSni, cealHostIp)); CealHostRulesDict[cealHostName]!.Add((cealHostDomainPairs, cealHostSni, cealHostIp));
} }
} }
catch { CealHostRulesDict[cealHostName] = null!; } catch { CealHostRulesDict[cealHostName] = null; }
finally finally
{ {
string hostRules = string.Empty; string hostRules = string.Empty;
string hostResolverRules = string.Empty; string hostResolverRules = string.Empty;
int nullSniNum = 0; int nullSniNum = 0;
foreach (KeyValuePair<string, List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>> cealHostRulesPair in CealHostRulesDict) foreach (KeyValuePair<string, List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>?> cealHostRulesPair in CealHostRulesDict)
foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp) in cealHostRulesPair.Value ?? []) foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp) in cealHostRulesPair.Value ?? [])
{ {
string cealHostSniWithoutNull = cealHostSni ?? $"{cealHostRulesPair.Key}{(cealHostRulesPair.Value ?? []).Count + ++nullSniNum}"; string cealHostSniWithoutNull = cealHostSni ?? $"{cealHostRulesPair.Key}{(cealHostRulesPair.Value ?? []).Count + ++nullSniNum}";
@ -642,123 +642,123 @@ public partial class MainWin : Window
NginxConfWatcher_Changed(null!, null!); NginxConfWatcher_Changed(null!, null!);
} }
} }
private void NginxConfWatcher_Changed(object sender, FileSystemEventArgs e) private async void NginxConfWatcher_Changed(object sender, FileSystemEventArgs e)
{ {
if (MainConst.IsAdmin && MainPres.IsNginxExist) if (!MainConst.IsAdmin || !MainPres.IsNginxExist)
{ return;
if (!File.Exists(MainConst.NginxConfPath))
File.Create(MainConst.NginxConfPath).Dispose();
if (!Directory.Exists(MainConst.NginxLogsPath))
Directory.CreateDirectory(MainConst.NginxLogsPath);
if (!Directory.Exists(MainConst.NginxTempPath))
Directory.CreateDirectory(MainConst.NginxTempPath);
foreach (IPEndPoint activeTcpListener in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()) if (!File.Exists(MainConst.NginxConfPath))
if (activeTcpListener.Port == NginxHttpPort) await File.Create(MainConst.NginxConfPath).DisposeAsync();
NginxHttpPort++; if (!Directory.Exists(MainConst.NginxLogsPath))
else if (activeTcpListener.Port == NginxHttpsPort) Directory.CreateDirectory(MainConst.NginxLogsPath);
NginxHttpsPort++; if (!Directory.Exists(MainConst.NginxTempPath))
else if (activeTcpListener.Port > NginxHttpsPort) Directory.CreateDirectory(MainConst.NginxTempPath);
break;
using FileStream nginxConfStream = new(MainConst.NginxConfPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); foreach (IPEndPoint activeTcpListener in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners())
NginxConfig extraNginxConfig = NginxConfig.Load(ExtraNginxConfs = new StreamReader(nginxConfStream).ReadToEnd()); if (activeTcpListener.Port == NginxHttpPort)
int serverIndex = 0; NginxHttpPort++;
else if (activeTcpListener.Port == NginxHttpsPort)
NginxHttpsPort++;
else if (activeTcpListener.Port > NginxHttpsPort)
break;
foreach (IToken extraNginxConfigToken in extraNginxConfig.GetTokens()) await using FileStream nginxConfStream = new(MainConst.NginxConfPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
if (extraNginxConfigToken is GroupToken extraNginxConfigGroupToken && extraNginxConfigGroupToken.Key.Equals("http", StringComparison.InvariantCultureIgnoreCase)) NginxConfig extraNginxConfig = NginxConfig.Load(ExtraNginxConfs = await new StreamReader(nginxConfStream).ReadToEndAsync());
int serverIndex = 0;
foreach (IToken extraNginxConfigToken in extraNginxConfig.GetTokens())
if (extraNginxConfigToken is GroupToken extraNginxConfigGroupToken && extraNginxConfigGroupToken.Key.Equals("http", StringComparison.InvariantCultureIgnoreCase))
{
foreach (IToken serverToken in extraNginxConfigGroupToken.Tokens)
if (serverToken is GroupToken serverGroupToken && serverGroupToken.Key.Equals("server", StringComparison.InvariantCultureIgnoreCase))
++serverIndex;
break;
}
NginxConfs = extraNginxConfig
.AddOrUpdate("worker_processes", "auto")
.AddOrUpdate("events:worker_connections", "65536")
.AddOrUpdate("http:proxy_set_header", "Host $http_host")
.AddOrUpdate("http:proxy_ssl_server_name", !MainPres.IsFlashing ? "on" : "off")
.AddOrUpdate($"http:server[{serverIndex}]:listen", $"{NginxHttpPort} default_server")
.AddOrUpdate($"http:server[{serverIndex}]:return", "https://$host$request_uri");
foreach (List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>? cealHostRules in CealHostRulesDict.Values)
foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp) in cealHostRules ?? [])
{
string serverName = "~";
foreach ((string cealHostIncludeDomain, string cealHostExcludeDomain) in cealHostDomainPairs)
{ {
foreach (IToken serverToken in extraNginxConfigGroupToken.Tokens) if (cealHostIncludeDomain.StartsWith('#'))
if (serverToken is GroupToken serverGroupToken && serverGroupToken.Key.Equals("server", StringComparison.InvariantCultureIgnoreCase))
++serverIndex;
break;
}
NginxConfs = extraNginxConfig
.AddOrUpdate("worker_processes", "auto")
.AddOrUpdate("events:worker_connections", "65536")
.AddOrUpdate("http:proxy_set_header", "Host $http_host")
.AddOrUpdate("http:proxy_ssl_server_name", !MainPres.IsFlashing ? "on" : "off")
.AddOrUpdate($"http:server[{serverIndex}]:listen", $"{NginxHttpPort} default_server")
.AddOrUpdate($"http:server[{serverIndex}]:return", "https://$host$request_uri");
foreach (List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)> cealHostRules in CealHostRulesDict.Values)
foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp) in cealHostRules ?? [])
{
string serverName = "~";
foreach ((string cealHostIncludeDomain, string cealHostExcludeDomain) in cealHostDomainPairs)
{
if (cealHostIncludeDomain.StartsWith('#'))
continue;
serverName += "^" + (!string.IsNullOrWhiteSpace(cealHostExcludeDomain) ? $"(?!{cealHostExcludeDomain.Replace(".", "\\.").Replace("*", ".*")})" : string.Empty) +
cealHostIncludeDomain.TrimStart('$').Replace(".", "\\.").Replace("*", ".*") + "$|";
}
if (serverName == "~")
continue; continue;
++serverIndex; serverName += "^" + (!string.IsNullOrWhiteSpace(cealHostExcludeDomain) ? $"(?!{cealHostExcludeDomain.Replace(".", "\\.").Replace("*", ".*")})" : string.Empty) +
cealHostIncludeDomain.TrimStart('$').Replace(".", "\\.").Replace("*", ".*") + "$|";
NginxConfs = NginxConfs
.AddOrUpdate($"http:server[{serverIndex}]:server_name", serverName.TrimEnd('|'))
.AddOrUpdate($"http:server[{serverIndex}]:listen", $"{NginxHttpsPort} ssl")
.AddOrUpdate($"http:server[{serverIndex}]:ssl_certificate", Path.GetFileName(MainConst.NginxCertPath))
.AddOrUpdate($"http:server[{serverIndex}]:ssl_certificate_key", Path.GetFileName(MainConst.NginxKeyPath))
.AddOrUpdate($"http:server[{serverIndex}]:location", "/", true)
.AddOrUpdate($"http:server[{serverIndex}]:location:proxy_pass", $"https://{cealHostIp}");
NginxConfs = cealHostSni == null ?
NginxConfs.AddOrUpdate($"http:server[{serverIndex}]:proxy_ssl_server_name", "off") :
NginxConfs.AddOrUpdate($"http:server[{serverIndex}]:proxy_ssl_name", cealHostSni);
} }
}
}
private void MihomoConfWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (MainConst.IsAdmin && MainPres.IsMihomoExist)
{
try
{
if (!File.Exists(MainConst.MihomoConfPath))
File.Create(MainConst.MihomoConfPath).Dispose();
foreach (IPEndPoint activeTcpListener in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()) if (serverName == "~")
if (activeTcpListener.Port == MihomoMixedPort) continue;
MihomoMixedPort++;
else if (activeTcpListener.Port > MihomoMixedPort)
break;
using FileStream mihomoConfStream = new(MainConst.MihomoConfPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); ++serverIndex;
Dictionary<string, object> mihomoConfDict = new DeserializerBuilder()
.WithNamingConvention(HyphenatedNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build()
.Deserialize<Dictionary<string, object>>(ExtraMihomoConfs = new StreamReader(mihomoConfStream).ReadToEnd()) ?? [];
mihomoConfDict["mixed-port"] = MihomoMixedPort; NginxConfs = NginxConfs
mihomoConfDict["dns"] = new .AddOrUpdate($"http:server[{serverIndex}]:server_name", serverName.TrimEnd('|'))
{ .AddOrUpdate($"http:server[{serverIndex}]:listen", $"{NginxHttpsPort} ssl")
enable = true, .AddOrUpdate($"http:server[{serverIndex}]:ssl_certificate", Path.GetFileName(MainConst.NginxCertPath))
listen = ":53", .AddOrUpdate($"http:server[{serverIndex}]:ssl_certificate_key", Path.GetFileName(MainConst.NginxKeyPath))
enhancedMode = "redir-host", .AddOrUpdate($"http:server[{serverIndex}]:location", "/", true)
nameserver = MainConst.MihomoNameServers .AddOrUpdate($"http:server[{serverIndex}]:location:proxy_pass", $"https://{cealHostIp}");
};
mihomoConfDict["tun"] = new
{
enable = true,
stack = "system",
autoRoute = true,
autoDetectInterface = true,
dnsHijack = new[] { "any:53", "tcp://any:53" }
};
MihomoConfs = new SerializerBuilder().WithNamingConvention(HyphenatedNamingConvention.Instance).Build().Serialize(mihomoConfDict); NginxConfs = cealHostSni == null ?
NginxConfs.AddOrUpdate($"http:server[{serverIndex}]:proxy_ssl_server_name", "off") :
NginxConfs.AddOrUpdate($"http:server[{serverIndex}]:proxy_ssl_name", cealHostSni);
} }
catch { MihomoConfs = string.Empty; } }
private async void MihomoConfWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (!MainConst.IsAdmin || !MainPres.IsMihomoExist)
return;
try
{
if (!File.Exists(MainConst.MihomoConfPath))
await File.Create(MainConst.MihomoConfPath).DisposeAsync();
foreach (IPEndPoint activeTcpListener in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners())
if (activeTcpListener.Port == MihomoMixedPort)
MihomoMixedPort++;
else if (activeTcpListener.Port > MihomoMixedPort)
break;
await using FileStream mihomoConfStream = new(MainConst.MihomoConfPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
Dictionary<string, object> mihomoConfDict = new DeserializerBuilder()
.WithNamingConvention(HyphenatedNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build()
.Deserialize<Dictionary<string, object>>(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
{
enable = true,
stack = "system",
autoRoute = true,
autoDetectInterface = true,
dnsHijack = new[] { "any:53", "tcp://any:53" }
};
MihomoConfs = new SerializerBuilder().WithNamingConvention(HyphenatedNamingConvention.Instance).Build().Serialize(mihomoConfDict);
} }
catch { MihomoConfs = string.Empty; }
} }
private void MainWin_KeyDown(object sender, KeyEventArgs e) private void MainWin_KeyDown(object sender, KeyEventArgs e)
{ {

View File

@ -1,13 +1,13 @@
using System; using MaterialDesignThemes.Wpf;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using MaterialDesignThemes.Wpf;
using Sheas_Cealer.Consts; using Sheas_Cealer.Consts;
using Sheas_Cealer.Preses; using Sheas_Cealer.Preses;
using Sheas_Cealer.Props; using Sheas_Cealer.Props;
using Sheas_Cealer.Utils; using Sheas_Cealer.Utils;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace Sheas_Cealer.Wins; namespace Sheas_Cealer.Wins;