mirror of
https://github.com/SpaceTimee/Sheas-Cealer.git
synced 2025-07-13 21:02:08 +08:00
Compare commits
220 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e1b1c606e1 | ||
![]() |
46de61c4f2 | ||
![]() |
479c16c2a1 | ||
![]() |
938ca77fc1 | ||
![]() |
d9e307e647 | ||
![]() |
85213b61da | ||
![]() |
bf7772a35f | ||
![]() |
188e56b57b | ||
![]() |
0150440de4 | ||
![]() |
c25888bd5a | ||
![]() |
a97b04e5d9 | ||
![]() |
b3dc94eb2b | ||
![]() |
597e441af5 | ||
![]() |
8a81ba59dc | ||
![]() |
d748976aa9 | ||
![]() |
f428de3fd7 | ||
![]() |
bcccb73520 | ||
![]() |
6fd9631d5c | ||
![]() |
2c5004f02d | ||
![]() |
8de6980f59 | ||
![]() |
b1d41436de | ||
![]() |
1fd5b99e67 | ||
![]() |
eecec3bbd7 | ||
![]() |
ccf47c85c9 | ||
![]() |
cf616b33a8 | ||
![]() |
592f871778 | ||
![]() |
f625d79667 | ||
![]() |
80abfa8116 | ||
![]() |
87d97c2f04 | ||
![]() |
345c291305 | ||
![]() |
5af134c7a4 | ||
![]() |
bd73327fc0 | ||
![]() |
1a08c65c0d | ||
![]() |
64f4bbad02 | ||
![]() |
b52eb93e40 | ||
![]() |
f1e9df5418 | ||
![]() |
9ea750e336 | ||
![]() |
e66f1eb5b2 | ||
![]() |
ec5d3893fb | ||
![]() |
13d8663a6e | ||
![]() |
af28d96bf9 | ||
![]() |
dcef7be238 | ||
![]() |
6a7b65fe99 | ||
![]() |
e962850d05 | ||
![]() |
aa5765d168 | ||
![]() |
ebe199d048 | ||
![]() |
56185d2750 | ||
![]() |
c7efd8df68 | ||
![]() |
92f55711a6 | ||
![]() |
b54ef3a3bb | ||
![]() |
0f3724508c | ||
![]() |
e0317c870f | ||
![]() |
49fb4cf655 | ||
![]() |
419ddd8fdb | ||
![]() |
bdf34249c6 | ||
![]() |
c96d51459f | ||
![]() |
536a498e65 | ||
![]() |
1e310cc69d | ||
![]() |
32871f580a | ||
![]() |
5e9ab2d928 | ||
![]() |
7dd6036cec | ||
![]() |
8637b18fd2 | ||
![]() |
029bd787dc | ||
![]() |
f8501fc05b | ||
![]() |
ee99628508 | ||
![]() |
bf73c635d3 | ||
![]() |
8dc34243bd | ||
![]() |
54f9326f29 | ||
![]() |
2660c63311 | ||
![]() |
dc73a30540 | ||
![]() |
73de1516ea | ||
![]() |
67079cf9e0 | ||
![]() |
9d50e772fd | ||
![]() |
753b53bc17 | ||
![]() |
21964c0e76 | ||
![]() |
ef997ad840 | ||
![]() |
2b3ca3f3ee | ||
![]() |
4af0990ea6 | ||
![]() |
3a95e8cbea | ||
![]() |
5a0a05e62f | ||
![]() |
6ebc22c8ea | ||
![]() |
34165391b4 | ||
![]() |
2e7f4d4cf9 | ||
![]() |
42bd83f4d3 | ||
![]() |
4009e8ce63 | ||
![]() |
66230df9a5 | ||
![]() |
f7a0729eaa | ||
![]() |
73f411aca3 | ||
![]() |
5e94c1e81b | ||
![]() |
dda0c2efee | ||
![]() |
688412f2b5 | ||
![]() |
9709cf249b | ||
![]() |
0021b1516e | ||
![]() |
8c44b0b82a | ||
![]() |
abd180c0e7 | ||
![]() |
c8bffaa96c | ||
![]() |
be23d1bce8 | ||
![]() |
038e9fe7e7 | ||
![]() |
8178742f62 | ||
![]() |
e37ef64aca | ||
![]() |
007fea343c | ||
![]() |
fe8f73afb8 | ||
![]() |
2e07e97e01 | ||
![]() |
48afa92ed9 | ||
![]() |
a8f408dc62 | ||
![]() |
dac9459e1c | ||
![]() |
460826b1ee | ||
![]() |
426596f780 | ||
![]() |
6b7542a3b9 | ||
![]() |
9b1533b51c | ||
![]() |
94581ee703 | ||
![]() |
144de24013 | ||
![]() |
48509f46cf | ||
![]() |
21fc19059d | ||
![]() |
94ede5b64b | ||
![]() |
5bd9ef3e58 | ||
![]() |
fe44a5231e | ||
![]() |
a4ff7972ae | ||
![]() |
443822902a | ||
![]() |
eef852304d | ||
![]() |
3d8f1412b4 | ||
![]() |
ca92fa349d | ||
![]() |
372d900280 | ||
![]() |
f100becc01 | ||
![]() |
dd0064469f | ||
![]() |
27826633a1 | ||
![]() |
b78c982621 | ||
![]() |
3b48344946 | ||
![]() |
8d8a4f016a | ||
![]() |
7932212e5f | ||
![]() |
c680f6e3f8 | ||
![]() |
0c76f6ed59 | ||
![]() |
37bcd63b9e | ||
![]() |
820df74051 | ||
![]() |
fe2475b8fa | ||
![]() |
0a9efb4f0b | ||
![]() |
c103b860a8 | ||
![]() |
bce0a8a5ca | ||
![]() |
6431a90a72 | ||
![]() |
f54e470874 | ||
![]() |
cfe4108590 | ||
![]() |
5ba6303a8e | ||
![]() |
e016d97c71 | ||
![]() |
b00e3aa8c2 | ||
![]() |
a81b408f12 | ||
![]() |
84b54e65de | ||
![]() |
8511a5e85d | ||
![]() |
e7fb200d97 | ||
![]() |
1dbdf295cf | ||
![]() |
74f4494f45 | ||
![]() |
56cbb7ec09 | ||
![]() |
605c6e61a3 | ||
![]() |
158ee04adc | ||
![]() |
517ff4c3b3 | ||
![]() |
b0c7e551c1 | ||
![]() |
5842ca0098 | ||
![]() |
8e7f0a97cf | ||
![]() |
c3bcd15084 | ||
![]() |
788b639c1f | ||
![]() |
f72d9bbd79 | ||
![]() |
94c899d4e6 | ||
![]() |
4d4b43284c | ||
![]() |
e0b671a95c | ||
![]() |
d951decd1f | ||
![]() |
35adc69eb2 | ||
![]() |
c8f2a208a2 | ||
![]() |
3548125178 | ||
![]() |
cbab9371a0 | ||
![]() |
dafd160c70 | ||
![]() |
23241c8a5e | ||
![]() |
2902117840 | ||
![]() |
6ad9cb3c72 | ||
![]() |
57d3ede6db | ||
![]() |
b3416c9bbf | ||
![]() |
f9c6da4bb8 | ||
![]() |
e61ca0a75f | ||
![]() |
f696dbb14b | ||
![]() |
c1231e3fe1 | ||
![]() |
c42d7351c4 | ||
![]() |
dd472b65de | ||
![]() |
091442e3c6 | ||
![]() |
ee1aa2be3e | ||
![]() |
105e6ce908 | ||
![]() |
db19a759ff | ||
![]() |
53384ee2ad | ||
![]() |
859e25f05e | ||
![]() |
a3b1dc6525 | ||
![]() |
a25f0a9b6d | ||
![]() |
7e85989fa8 | ||
![]() |
4c966e4b09 | ||
![]() |
e4c772ba51 | ||
![]() |
66c40aa3f4 | ||
![]() |
ea201387dd | ||
![]() |
0810b64fe4 | ||
![]() |
334f8a56a2 | ||
![]() |
9e284e1a6a | ||
![]() |
ec8c86897f | ||
![]() |
84947471df | ||
![]() |
c378f50f22 | ||
![]() |
b70a42c227 | ||
![]() |
b9c3de4e75 | ||
![]() |
e502c6df2e | ||
![]() |
eaaca182d4 | ||
![]() |
3d307dd01f | ||
![]() |
a40b458355 | ||
![]() |
2e0304fa1d | ||
![]() |
a123353068 | ||
![]() |
6204dbb7e5 | ||
![]() |
353d5ec8cf | ||
![]() |
9c44edfed9 | ||
![]() |
a90798a22d | ||
![]() |
455ade0b2d | ||
![]() |
987a97802b | ||
![]() |
a834b7589e | ||
![]() |
45d5e7076b | ||
![]() |
714a4d2c5b | ||
![]() |
0e5ed26581 | ||
![]() |
93c7bf4cdb | ||
![]() |
b8438cecf1 | ||
![]() |
ea937a138d |
42
.filenesting.json
Normal file
42
.filenesting.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"root": true,
|
||||
"dependentFileProviders": {
|
||||
"add": {
|
||||
"fileToFile": {
|
||||
"add": {
|
||||
"AboutMultilangConst.resx": [ "AboutConst.cs" ],
|
||||
"AboutMultilangConst.zh.resx": [ "AboutConst.cs" ],
|
||||
"MainMultilangConst.resx": [ "MainConst.cs" ],
|
||||
"MainMultilangConst.zh.resx": [ "MainConst.cs" ],
|
||||
"SettingsMultilangConst.resx": [ "SettingsConst.cs" ],
|
||||
"SettingsMultilangConst.zh.resx": [ "SettingsConst.cs" ],
|
||||
|
||||
"AboutAccentButtonForegroundConv.cs": [ "AboutConv.cs" ],
|
||||
"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" ],
|
||||
"MainProxyColumnWidthConv.cs": [ "MainConv.cs" ],
|
||||
"MainSettingsBoxHintConv.cs": [ "MainConv.cs" ],
|
||||
"MainSettingsBoxTextConv.cs": [ "MainConv.cs" ],
|
||||
"MainSettingsBoxToolTipConv.cs": [ "MainConv.cs" ],
|
||||
"MainSettingsFunctionButtonContentConv.cs": [ "MainConv.cs" ],
|
||||
"MainSettingsModeButtonContentConv.cs": [ "MainConv.cs" ],
|
||||
"MainBrowserButtonIsEnabledConv.cs": [ "MainConv.cs" ],
|
||||
"MainUpdateHostButtonContentConv.cs": [ "MainConv.cs" ],
|
||||
"MainUpdateHostButtonIsEnabledConv.cs": [ "MainConv.cs" ],
|
||||
"MainWinWidthConv.cs": [ "MainConv.cs" ],
|
||||
"SettingsLangsButtonContentConv.cs": [ "SettingsConv.cs" ],
|
||||
"SettingsThemesButtonContentConv.cs": [ "SettingsConv.cs" ],
|
||||
"SettingsWeightsButtonContentConv.cs": [ "SettingsConv.cs" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
App.xaml
15
App.xaml
@ -1,25 +1,28 @@
|
||||
<Application x:Class="Sheas_Cealer.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Startup="App_OnStartup" DispatcherUnhandledException="App_DispatcherUnhandledException">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Red" SecondaryColor="Orange" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
||||
<materialDesign:BundledTheme BaseTheme="Inherit" PrimaryColor="Red" SecondaryColor="Orange" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="CommonWindow" TargetType="{x:Type Window}">
|
||||
<Setter Property="Background" Value="{DynamicResource MaterialDesignBackground}" />
|
||||
<Setter Property="AutomationProperties.Name" Value="Sheas Cealer" />
|
||||
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}" />
|
||||
</Style>
|
||||
|
||||
<Style BasedOn="{StaticResource MaterialDesignFilledTextBox}" TargetType="{x:Type TextBox}" />
|
||||
|
||||
<Style BasedOn="{StaticResource MaterialDesignRaisedButton}" TargetType="{x:Type Button}">
|
||||
<Setter Property="Height" Value="Auto" />
|
||||
<Setter Property="Width" Value="Auto" />
|
||||
<Setter Property="Background" Value="Red" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBackground}" />
|
||||
</Style>
|
||||
<Style BasedOn="{StaticResource MaterialDesignCaptionHyperlink}" TargetType="{x:Type Hyperlink}" />
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
63
App.xaml.cs
63
App.xaml.cs
@ -1,9 +1,64 @@
|
||||
using System.Windows;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Sheas_Cealer.Preses;
|
||||
using Sheas_Cealer.Props;
|
||||
using Sheas_Cealer.Utils;
|
||||
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;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public partial class App : Application
|
||||
private void App_OnStartup(object sender, StartupEventArgs e)
|
||||
{
|
||||
protected override void OnStartup(StartupEventArgs e) => new MainWindow(e.Args).Show();
|
||||
#region Upgrade Settings
|
||||
if (Settings.Default.IsUpgradeRequired)
|
||||
{
|
||||
Settings.Default.Upgrade();
|
||||
Settings.Default.IsUpgradeRequired = false;
|
||||
Settings.Default.Save();
|
||||
}
|
||||
#endregion Upgrade Settings
|
||||
|
||||
#region Primary Color
|
||||
PaletteHelper paletteHelper = new();
|
||||
Theme newTheme = paletteHelper.GetTheme();
|
||||
Color newPrimaryColor = Color.FromRgb(Settings.Default.PrimaryColor.R, Settings.Default.PrimaryColor.G, Settings.Default.PrimaryColor.B);
|
||||
|
||||
newTheme.SetPrimaryColor(newPrimaryColor);
|
||||
paletteHelper.SetTheme(newTheme);
|
||||
#endregion Primary Color
|
||||
|
||||
#region Background Color
|
||||
if (Environment.OSVersion.Version.Build < 22000)
|
||||
{
|
||||
Style newWindowStyle = new(typeof(Window), Current.Resources["CommonWindow"] as Style);
|
||||
|
||||
newWindowStyle.Setters.Add(new Setter(Window.BackgroundProperty, new DynamicResourceExtension("MaterialDesignBackground")));
|
||||
Current.Resources["CommonWindow"] = newWindowStyle;
|
||||
}
|
||||
#endregion Background Color
|
||||
|
||||
#region Foreground Color
|
||||
Style newButtonStyle = new(typeof(Button), Current.Resources[typeof(Button)] as Style);
|
||||
(Color? newForegroundColor, Color newAccentForegroundColor) = ForegroundGenerator.GetForeground(newPrimaryColor.R, newPrimaryColor.G, newPrimaryColor.B);
|
||||
|
||||
newButtonStyle.Setters.Add(new Setter(Button.ForegroundProperty, newForegroundColor.HasValue ? new SolidColorBrush(newForegroundColor.Value) : new DynamicResourceExtension("MaterialDesignBackground")));
|
||||
Current.Resources[typeof(Button)] = newButtonStyle;
|
||||
|
||||
new SettingsPres().AccentForegroundColor = newAccentForegroundColor;
|
||||
#endregion Foreground Color
|
||||
|
||||
new MainWin().Show();
|
||||
}
|
||||
|
||||
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
MessageBox.Show($"Error: {e.Exception.Message}");
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
Binary file not shown.
@ -1,35 +0,0 @@
|
||||
[
|
||||
[["*pixiv.net"],"fanbox.cc","172.64.151.90"],
|
||||
[["*pximg.net"],"pxi","210.140.92.149"],
|
||||
[["*pinterest.com"],"pin","2.18.233.9"],
|
||||
[["*pinimg.com"],"pini","104.71.49.9"],
|
||||
[["*e-hentai.org"],"ehe","104.20.134.21"],
|
||||
[["*exhentai.org"],"exh","178.175.129.254"],
|
||||
[["*sukebei.nyaa.si"],"suk","198.251.89.38"],
|
||||
[["*theporndude.com"],"the","104.19.128.100"],
|
||||
[["upload.wikimedia.org"],"wiki","208.80.154.240"],
|
||||
[["*wikipedia.org","*wikimedia.org"],"wik","91.198.174.192"],
|
||||
[["*steamcommunity.com"],"ste","104.92.74.217"],
|
||||
[["*instagram.com"],"ins","157.240.236.174"],
|
||||
[["*amazon.co.jp"],"ama","52.222.208.138"],
|
||||
[["*github.com"],"git","140.82.121.3"],
|
||||
[["*pornhub.com"],"por","66.254.114.40"],
|
||||
[["*onedrive.live.com"],"one","13.107.42.13"],
|
||||
[["*mikuclub.cc"],"mik","45.152.67.140"],
|
||||
[["*twitch.tv"],"twi","199.232.138.167"],
|
||||
[["*archiveofourown.org"],"arc","208.85.241.152"],
|
||||
[["*reddit.com","*redditstatic.com"],"red","146.75.33.140"],
|
||||
[["*redd.it","*redditmedia.com"],"redd","146.75.37.140"],
|
||||
[["64.media.tumblr.com"],"tumb","192.0.77.3"],
|
||||
[["*tumblr.com"],"tum","192.0.77.40"],
|
||||
[["*apkmirror.com"],"apk","104.19.134.58"],
|
||||
[["*vimeo.com"],"vim","162.159.128.61"],
|
||||
[["*mega.io"],"meg","31.216.145.6"],
|
||||
[["*mega.nz"],"mega","31.216.145.5"],
|
||||
[["*imgur.com"],"img","199.232.192.193"],
|
||||
[["*thetvdb.com"],"tvd","13.224.153.106"],
|
||||
[["*kobo.com"],"kob","23.6.64.137"],
|
||||
[["*dropbox.com"],"dro","162.125.85.18"],
|
||||
[["*bbc.com"],"bbc","146.75.36.81"],
|
||||
[["*bbci.co.uk","*bbc.co.uk"],"bbci","23.56.25.35"]
|
||||
]
|
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using SheasCore;
|
||||
|
||||
namespace Sheas_Cealer
|
||||
{
|
||||
internal class Clash : Proc
|
||||
{
|
||||
internal Clash() : base("Cealing-Clash.exe")
|
||||
{
|
||||
}
|
||||
|
||||
public override void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
}
|
||||
public override void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
}
|
||||
public override void Process_Exited(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using SheasCore;
|
||||
|
||||
namespace Sheas_Cealer
|
||||
{
|
||||
internal class Cmd : Proc
|
||||
{
|
||||
internal Cmd() : base("Cmd.exe")
|
||||
{
|
||||
}
|
||||
|
||||
public override void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
}
|
||||
public override void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
}
|
||||
public override void Process_Exited(object sender, EventArgs e) => Environment.Exit(0);
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Sheas_Cealer
|
||||
{
|
||||
//定义IconRemover
|
||||
internal static class IconRemover
|
||||
{
|
||||
private const int GWL_EXSTYLE = -20;
|
||||
private const int WS_EX_DLGMODALFRAME = 0x0001;
|
||||
private const int SWP_NOSIZE = 0x0001;
|
||||
private const int SWP_NOMOVE = 0x0002;
|
||||
private const int SWP_NOZORDER = 0x0004;
|
||||
private const int SWP_FRAMECHANGED = 0x0020;
|
||||
private const uint WM_SETICON = 0x0080;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowLong(IntPtr hwnd, int index);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
internal static void RemoveIcon(Window window)
|
||||
{
|
||||
//获取该窗口句柄
|
||||
IntPtr hwnd = new WindowInteropHelper(window).Handle;
|
||||
|
||||
//将窗口更改为不显示窗口图标
|
||||
_ = SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_DLGMODALFRAME);
|
||||
|
||||
//更新窗口的非客户区域来显示更改
|
||||
SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
|
||||
//防止自定义图标生效
|
||||
SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
|
||||
SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
//使用IconRemover
|
||||
public partial class MainWindow
|
||||
{
|
||||
protected override void OnSourceInitialized(EventArgs e) => IconRemover.RemoveIcon(this);
|
||||
}
|
||||
public partial class AboutWindow
|
||||
{
|
||||
protected override void OnSourceInitialized(EventArgs e) => IconRemover.RemoveIcon(this);
|
||||
}
|
||||
}
|
24
Consts/AboutConst.cs
Normal file
24
Consts/AboutConst.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Reflection;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Sheas_Cealer.Consts;
|
||||
|
||||
internal abstract class AboutConst : AboutMultilangConst
|
||||
{
|
||||
public static Color AccentBlueColor => (Color)ColorConverter.ConvertFromString("#2196F3");
|
||||
public static Color AccentRedColor => (Color)ColorConverter.ConvertFromString("#F44336");
|
||||
|
||||
public static string DeveloperButtonUrl => "https://www.spacetimee.xyz";
|
||||
public static string VersionButtonVersionContent => Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];
|
||||
public static string VersionButtonUrl => "https://github.com/SpaceTimee/Sheas-Cealer/releases/latest";
|
||||
public static string EmailButtonUrl => "Zeus6_6@163.com";
|
||||
|
||||
public static string DocumentationButtonUrl => "https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Documentation";
|
||||
public static string RepositoryButtonUrl => "https://github.com/SpaceTimee/Sheas-Cealer";
|
||||
|
||||
public static string PolicyButtonUrl => "https://thoughts.teambition.com/share/6264eda98adeb10041b92fda#title=Sheas_Cealer_隐私政策";
|
||||
public static string AgreementButtonUrl => "https://thoughts.teambition.com/share/6264edd78adeb10041b92fdb#title=Sheas_Cealer_使用协议";
|
||||
|
||||
internal static string ReleaseApiUrl => "https://api.github.com/repos/SpaceTimee/Sheas-Cealer/releases/latest";
|
||||
internal static string ReleaseApiUserAgent => "Sheas-Cealer";
|
||||
}
|
135
Consts/AboutMultilangConst.Designer.cs
generated
Normal file
135
Consts/AboutMultilangConst.Designer.cs
generated
Normal file
@ -0,0 +1,135 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Sheas_Cealer.Consts {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class AboutMultilangConst {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal AboutMultilangConst() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Sheas_Cealer.Consts.AboutMultilangConst", typeof(AboutMultilangConst).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Password: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _ReleasePagePasswordLabel {
|
||||
get {
|
||||
return ResourceManager.GetString("_ReleasePagePasswordLabel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 EULA 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string AgreementButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("AgreementButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Dev. Space Time 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string DeveloperButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("DeveloperButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Docs 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string DocumentationButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("DocumentationButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Email 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EmailButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("EmailButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 PP 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string PolicyButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("PolicyButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Repo 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string RepositoryButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("RepositoryButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Ver. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string VersionButtonLabelContent {
|
||||
get {
|
||||
return ResourceManager.GetString("VersionButtonLabelContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
144
Consts/AboutMultilangConst.resx
Normal file
144
Consts/AboutMultilangConst.resx
Normal file
@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AgreementButtonContent" xml:space="preserve">
|
||||
<value>EULA</value>
|
||||
</data>
|
||||
<data name="DeveloperButtonContent" xml:space="preserve">
|
||||
<value>Dev. Space Time</value>
|
||||
</data>
|
||||
<data name="DocumentationButtonContent" xml:space="preserve">
|
||||
<value>Docs</value>
|
||||
</data>
|
||||
<data name="EmailButtonContent" xml:space="preserve">
|
||||
<value>Email</value>
|
||||
</data>
|
||||
<data name="PolicyButtonContent" xml:space="preserve">
|
||||
<value>PP</value>
|
||||
</data>
|
||||
<data name="RepositoryButtonContent" xml:space="preserve">
|
||||
<value>Repo</value>
|
||||
</data>
|
||||
<data name="VersionButtonLabelContent" xml:space="preserve">
|
||||
<value>Ver.</value>
|
||||
</data>
|
||||
<data name="_ReleasePagePasswordLabel" xml:space="preserve">
|
||||
<value>Password:</value>
|
||||
</data>
|
||||
</root>
|
124
Consts/AboutMultilangConst.zh.resx
Normal file
124
Consts/AboutMultilangConst.zh.resx
Normal file
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AgreementButtonContent" xml:space="preserve">
|
||||
<value>使用协议</value>
|
||||
</data>
|
||||
<data name="DeveloperButtonContent" xml:space="preserve">
|
||||
<value>开发者: Space Time</value>
|
||||
</data>
|
||||
<data name="DocumentationButtonContent" xml:space="preserve">
|
||||
<value>使用文档</value>
|
||||
</data>
|
||||
<data name="EmailButtonContent" xml:space="preserve">
|
||||
<value>联系邮箱</value>
|
||||
</data>
|
||||
<data name="PolicyButtonContent" xml:space="preserve">
|
||||
<value>隐私政策</value>
|
||||
</data>
|
||||
<data name="RepositoryButtonContent" xml:space="preserve">
|
||||
<value>开源地址</value>
|
||||
</data>
|
||||
<data name="VersionButtonLabelContent" xml:space="preserve">
|
||||
<value>版本号:</value>
|
||||
</data>
|
||||
<data name="_ReleasePagePasswordLabel" xml:space="preserve">
|
||||
<value>密码:</value>
|
||||
</data>
|
||||
</root>
|
55
Consts/MainConst.cs
Normal file
55
Consts/MainConst.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Sheas_Cealer.Consts;
|
||||
|
||||
internal abstract partial class MainConst : MainMultilangConst
|
||||
{
|
||||
internal enum SettingsMode
|
||||
{ BrowserPathMode, UpstreamUrlMode, ExtraArgsMode }
|
||||
|
||||
public static bool IsAdmin => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
internal static string EdgeBrowserRegistryPath => @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe";
|
||||
internal static string ChromeBrowserRegistryPath => @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe";
|
||||
internal static string BraveBrowserRegistryPath => @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\brave.exe";
|
||||
|
||||
internal static string DefaultUpstreamUrl => "https://gitlab.com/SpaceTimee/Cealing-Host/raw/main/Cealing-Host.json";
|
||||
internal static string CealHostPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Host-*.json");
|
||||
internal static string LocalHostPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Host-L.json");
|
||||
internal static string UpstreamHostPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Host-U.json");
|
||||
|
||||
internal static string HostsConfPath => Path.Combine(Registry.LocalMachine.OpenSubKey(@"\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DataBasePath")?.GetValue("DataBasePath", null)?.ToString() ?? @"C:\Windows\System32\drivers\etc", "hosts");
|
||||
internal static string HostsConfStartMarker => $"# Cealing Nginx Start{Environment.NewLine}";
|
||||
internal static string HostsConfEndMarker => "# Cealing Nginx End";
|
||||
|
||||
internal static string ConginxPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Conginx.exe");
|
||||
internal static string NginxPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Nginx.exe");
|
||||
internal static string NginxConfPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "nginx.conf");
|
||||
internal static string NginxLogsPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "logs");
|
||||
internal static string NginxErrorLogsPath => Path.Combine(NginxLogsPath, "error.log");
|
||||
internal static string NginxTempPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "temp");
|
||||
internal static string NginxCertPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Cert.pem");
|
||||
internal static string NginxKeyPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Key.pem");
|
||||
internal static string NginxRootCertSubjectName => "CN=Cealing Cert Root";
|
||||
internal static string NginxChildCertSubjectName => "CN=Cealing Cert Child";
|
||||
|
||||
internal static string ComihomoPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Comihomo.exe");
|
||||
internal static string MihomoPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Mihomo.exe");
|
||||
internal static string MihomoConfPath => Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "config.yaml");
|
||||
internal static string[] MihomoNameServers => ["https://ns.net.kg/dns-query", "https://dnschina1.soraharu.com/dns-query", "https://0ms.dev/dns-query"];
|
||||
|
||||
internal static string NotifyIconText => "Sheas Cealer";
|
||||
|
||||
[GeneratedRegex("^Cealing-Host-")]
|
||||
internal static partial Regex CealHostPrefixRegex();
|
||||
|
||||
[GeneratedRegex(@"^(https?:\/\/)?[a-zA-Z0-9](-*[a-zA-Z0-9])*(\.[a-zA-Z0-9](-*[a-zA-Z0-9])*)*(:\d{1,5})?(\/[a-zA-Z0-9.\-_\~\!\$\&\'\(\)\*\+\,\;\=\:\@\%]*)*$")]
|
||||
internal static partial Regex UpstreamUrlRegex();
|
||||
|
||||
[GeneratedRegex(@"^(--[a-z](-?[a-z])*(=("".*"")|.*)?( --[a-z](-?[a-z])*(="".*"")?)*)?$")]
|
||||
internal static partial Regex ExtraArgsRegex();
|
||||
}
|
666
Consts/MainMultilangConst.Designer.cs
generated
Normal file
666
Consts/MainMultilangConst.Designer.cs
generated
Normal file
@ -0,0 +1,666 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Sheas_Cealer.Consts {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class MainMultilangConst {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal MainMultilangConst() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Sheas_Cealer.Consts.MainMultilangConst", typeof(MainMultilangConst).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Browser 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _BrowserPathDialogFilterFileType {
|
||||
get {
|
||||
return ResourceManager.GetString("_BrowserPathDialogFilterFileType", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Some cealing hosts contain syntax errors and cannot be recognized. Do you want to continue anyway? 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _CealHostErrorPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_CealHostErrorPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 I know you would click me, but nothing will actually happen. Whee~ 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameClickOnceMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameClickOnceMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Ugh, what are you doing. Please stop, I don't want to hurt anyone. Stop please, this is your last chance. Ugh, I can't control it anymore 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameClickThreeMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameClickThreeMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 No no no, don't click me. Sorry, I shouldn't have lied to you, I am a cursed button, and continuing to click me will bring disaster to the entire Sheas Cealer. Please believe me. This is not a game, and there are no new features here. Listen to me and use the normal functions. Please 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameClickTwiceMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameClickTwiceMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 You defeated the evil button and saved Sheas Cealer. You are the HERO! 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameEndingMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameEndingMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Button Remaining HP. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameGradeMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameGradeMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 It's dead. You're the HERO of Sheas Cealer 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameReviewEndingMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameReviewEndingMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 No, please kill me. I... can't control it... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _GameStartMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_GameStartMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 All processes of the selected browser will be closed before launching. Do you want to continue? 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _KillBrowserProcessPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_KillBrowserProcessPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 You are using hosts-based non-wildcard domain global cealing. Do you want to continue? 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _LaunchHostsNginxPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_LaunchHostsNginxPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Mihomo failed to launch 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _LaunchMihomoErrorMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_LaunchMihomoErrorMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Nginx failed to launch. Do you want to open the error log? 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _LaunchNginxErrorPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_LaunchNginxErrorPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Warning: The proxy core is under attack and failes to conceal SNI. The SNI removal mode has been turned on urgently. Do you want to continue? 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _LaunchNginxFlashingPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_LaunchNginxFlashingPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Please remember to come back and stop the proxy manually after use. Do you want to continue? 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _LaunchProxyPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_LaunchProxyPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The mihomo conf contains syntax errors and cannot be recognized 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _MihomoConfErrorMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_MihomoConfErrorMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The local port 80 is occupied. Do you want to use port {0} to continue? This may cause the http connection to fail to automatically jump to https 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _NginxHttpPortOccupiedPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_NginxHttpPortOccupiedPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The local port 443 is occupied. Do you want to use port {0} to continue? This may cause the global cealing to not work properly 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _NginxHttpsPortOccupiedPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_NginxHttpsPortOccupiedPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 There is an update available. Do you want to update upstream host? If No it will only open the upstream host web page for you 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _OverrideUpstreamHostPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("_OverrideUpstreamHostPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Update successfully 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _UpdateUpstreamHostSuccessMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_UpdateUpstreamHostSuccessMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Upstream host is already up to date 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _UpstreamHostUtdMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_UpstreamHostUtdMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 About Me 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string AboutButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("AboutButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to open the about window 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string AboutButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("AboutButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Start Cealing 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string BrowserButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("BrowserButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to launch the injected browser 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string BrowserButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("BrowserButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 GLB. Purging CHA. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ComihomoButtonIsInitingContent {
|
||||
get {
|
||||
return ResourceManager.GetString("ComihomoButtonIsInitingContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 GLB. Cealing INIT. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ConginxButtonIsInitingContent {
|
||||
get {
|
||||
return ResourceManager.GetString("ConginxButtonIsInitingContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Edit Hosts Conf 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditHostsConfButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("EditHostsConfButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to edit hosts conf 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditHostsConfButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("EditHostsConfButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Edit Local Host 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditLocalHostButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("EditLocalHostButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to edit local host 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditLocalHostButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("EditLocalHostButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Edit Mihomo Conf 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditMihomoConfButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("EditMihomoConfButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to edit mihomo conf 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditMihomoConfButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("EditMihomoConfButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Edit Nginx Conf 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditNginxConfButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("EditNginxConfButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to edit nginx conf 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditNginxConfButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("EditNginxConfButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Edit UPSTR. Host 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditUpstreamHostButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("EditUpstreamHostButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to edit upstream host 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string EditUpstreamHostButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("EditUpstreamHostButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 GLB. Purging INIT. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string MihomoButtonIsInitingContent {
|
||||
get {
|
||||
return ResourceManager.GetString("MihomoButtonIsInitingContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Stop GLB. Purging 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string MihomoButtonIsRunningContent {
|
||||
get {
|
||||
return ResourceManager.GetString("MihomoButtonIsRunningContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to stop the local Mihomo 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string MihomoButtonIsRunningToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("MihomoButtonIsRunningToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Start GLB. Purging 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string MihomoButtonIsStoppedContent {
|
||||
get {
|
||||
return ResourceManager.GetString("MihomoButtonIsStoppedContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to launch a local Mihomo 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string MihomoButtonIsStoppedToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("MihomoButtonIsStoppedToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 GLB. Purging STP. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string MihomoButtonIsStoppingContent {
|
||||
get {
|
||||
return ResourceManager.GetString("MihomoButtonIsStoppingContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 GLB. Cealing INIT. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NginxButtonIsInitingContent {
|
||||
get {
|
||||
return ResourceManager.GetString("NginxButtonIsInitingContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Stop GLB. Cealing 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NginxButtonIsRunningContent {
|
||||
get {
|
||||
return ResourceManager.GetString("NginxButtonIsRunningContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to stop the local Nginx 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NginxButtonIsRunningToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("NginxButtonIsRunningToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Start GLB. Cealing 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NginxButtonIsStoppedContent {
|
||||
get {
|
||||
return ResourceManager.GetString("NginxButtonIsStoppedContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to launch a local Nginx 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NginxButtonIsStoppedToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("NginxButtonIsStoppedToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click Now 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NoClickButtonIsFlashingContent {
|
||||
get {
|
||||
return ResourceManager.GetString("NoClickButtonIsFlashingContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click this button now 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NoClickButtonIsFlashingToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("NoClickButtonIsFlashingToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 No Clicking 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NoClickButtonIsStoppedContent {
|
||||
get {
|
||||
return ResourceManager.GetString("NoClickButtonIsStoppedContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Do not click this button 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string NoClickButtonIsStoppedToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("NoClickButtonIsStoppedToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fill in a Chromium-based browser path 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsBoxBrowserPathToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsBoxBrowserPathToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fill in extra Chromium startup args 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsBoxExtraArgsToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsBoxExtraArgsToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fill in an upstream host URL 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsBoxUpstreamUrlToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsBoxUpstreamUrlToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Appearance Settings 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to open the settings window 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Browse Path 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsFunctionButtonBrowserPathContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsFunctionButtonBrowserPathContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Clear Args 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsFunctionButtonExtraArgsContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsFunctionButtonExtraArgsContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to process settings 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsFunctionButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsFunctionButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Reset URL 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsFunctionButtonUpstreamUrlContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsFunctionButtonUpstreamUrlContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Browser Path 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsModeButtonBrowserPathContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsModeButtonBrowserPathContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Extra Args 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsModeButtonExtraArgsContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsModeButtonExtraArgsContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to switch settings 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsModeButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsModeButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Upstream URL 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SettingsModeButtonUpstreamUrlContent {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsModeButtonUpstreamUrlContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Update Upstream Host 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string UpdateUpstreamHostButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("UpdateUpstreamHostButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to update upstream host 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string UpdateUpstreamHostButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("UpdateUpstreamHostButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
321
Consts/MainMultilangConst.resx
Normal file
321
Consts/MainMultilangConst.resx
Normal file
@ -0,0 +1,321 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AboutButtonContent" xml:space="preserve">
|
||||
<value>About Me</value>
|
||||
</data>
|
||||
<data name="AboutButtonToolTip" xml:space="preserve">
|
||||
<value>Click to open the about window</value>
|
||||
</data>
|
||||
<data name="BrowserButtonContent" xml:space="preserve">
|
||||
<value>Start Cealing</value>
|
||||
</data>
|
||||
<data name="BrowserButtonToolTip" xml:space="preserve">
|
||||
<value>Click to launch the injected browser</value>
|
||||
</data>
|
||||
<data name="ComihomoButtonIsInitingContent" xml:space="preserve">
|
||||
<value>GLB. Purging CHA.</value>
|
||||
</data>
|
||||
<data name="ConginxButtonIsInitingContent" xml:space="preserve">
|
||||
<value>GLB. Cealing INIT.</value>
|
||||
</data>
|
||||
<data name="EditHostsConfButtonContent" xml:space="preserve">
|
||||
<value>Edit Hosts Conf</value>
|
||||
</data>
|
||||
<data name="EditHostsConfButtonToolTip" xml:space="preserve">
|
||||
<value>Click to edit hosts conf</value>
|
||||
</data>
|
||||
<data name="EditLocalHostButtonContent" xml:space="preserve">
|
||||
<value>Edit Local Host</value>
|
||||
</data>
|
||||
<data name="EditLocalHostButtonToolTip" xml:space="preserve">
|
||||
<value>Click to edit local host</value>
|
||||
</data>
|
||||
<data name="EditMihomoConfButtonContent" xml:space="preserve">
|
||||
<value>Edit Mihomo Conf</value>
|
||||
</data>
|
||||
<data name="EditMihomoConfButtonToolTip" xml:space="preserve">
|
||||
<value>Click to edit mihomo conf</value>
|
||||
</data>
|
||||
<data name="EditNginxConfButtonContent" xml:space="preserve">
|
||||
<value>Edit Nginx Conf</value>
|
||||
</data>
|
||||
<data name="EditNginxConfButtonToolTip" xml:space="preserve">
|
||||
<value>Click to edit nginx conf</value>
|
||||
</data>
|
||||
<data name="EditUpstreamHostButtonContent" xml:space="preserve">
|
||||
<value>Edit UPSTR. Host</value>
|
||||
</data>
|
||||
<data name="EditUpstreamHostButtonToolTip" xml:space="preserve">
|
||||
<value>Click to edit upstream host</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsInitingContent" xml:space="preserve">
|
||||
<value>GLB. Purging INIT.</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsRunningContent" xml:space="preserve">
|
||||
<value>Stop GLB. Purging</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsRunningToolTip" xml:space="preserve">
|
||||
<value>Click to stop the local Mihomo</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsStoppedContent" xml:space="preserve">
|
||||
<value>Start GLB. Purging</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsStoppedToolTip" xml:space="preserve">
|
||||
<value>Click to launch a local Mihomo</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsStoppingContent" xml:space="preserve">
|
||||
<value>GLB. Purging STP.</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsInitingContent" xml:space="preserve">
|
||||
<value>GLB. Cealing INIT.</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsRunningContent" xml:space="preserve">
|
||||
<value>Stop GLB. Cealing</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsRunningToolTip" xml:space="preserve">
|
||||
<value>Click to stop the local Nginx</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsStoppedContent" xml:space="preserve">
|
||||
<value>Start GLB. Cealing</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsStoppedToolTip" xml:space="preserve">
|
||||
<value>Click to launch a local Nginx</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsFlashingContent" xml:space="preserve">
|
||||
<value>Click Now</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsFlashingToolTip" xml:space="preserve">
|
||||
<value>Click this button now</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsStoppedContent" xml:space="preserve">
|
||||
<value>No Clicking</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsStoppedToolTip" xml:space="preserve">
|
||||
<value>Do not click this button</value>
|
||||
</data>
|
||||
<data name="SettingsBoxBrowserPathToolTip" xml:space="preserve">
|
||||
<value>Fill in a Chromium-based browser path</value>
|
||||
</data>
|
||||
<data name="SettingsBoxExtraArgsToolTip" xml:space="preserve">
|
||||
<value>Fill in extra Chromium startup args</value>
|
||||
</data>
|
||||
<data name="SettingsBoxUpstreamUrlToolTip" xml:space="preserve">
|
||||
<value>Fill in an upstream host URL</value>
|
||||
</data>
|
||||
<data name="SettingsButtonContent" xml:space="preserve">
|
||||
<value>Appearance Settings</value>
|
||||
</data>
|
||||
<data name="SettingsButtonToolTip" xml:space="preserve">
|
||||
<value>Click to open the settings window</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonBrowserPathContent" xml:space="preserve">
|
||||
<value>Browse Path</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonExtraArgsContent" xml:space="preserve">
|
||||
<value>Clear Args</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonToolTip" xml:space="preserve">
|
||||
<value>Click to process settings</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonUpstreamUrlContent" xml:space="preserve">
|
||||
<value>Reset URL</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonBrowserPathContent" xml:space="preserve">
|
||||
<value>Browser Path</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonExtraArgsContent" xml:space="preserve">
|
||||
<value>Extra Args</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonToolTip" xml:space="preserve">
|
||||
<value>Click to switch settings</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonUpstreamUrlContent" xml:space="preserve">
|
||||
<value>Upstream URL</value>
|
||||
</data>
|
||||
<data name="UpdateUpstreamHostButtonContent" xml:space="preserve">
|
||||
<value>Update Upstream Host</value>
|
||||
</data>
|
||||
<data name="UpdateUpstreamHostButtonToolTip" xml:space="preserve">
|
||||
<value>Click to update upstream host</value>
|
||||
</data>
|
||||
<data name="_BrowserPathDialogFilterFileType" xml:space="preserve">
|
||||
<value>Browser</value>
|
||||
</data>
|
||||
<data name="_CealHostErrorPrompt" xml:space="preserve">
|
||||
<value>Some cealing hosts contain syntax errors and cannot be recognized. Do you want to continue anyway?</value>
|
||||
</data>
|
||||
<data name="_GameClickOnceMsg" xml:space="preserve">
|
||||
<value>I know you would click me, but nothing will actually happen. Whee~</value>
|
||||
</data>
|
||||
<data name="_GameClickThreeMsg" xml:space="preserve">
|
||||
<value>Ugh, what are you doing. Please stop, I don't want to hurt anyone. Stop please, this is your last chance. Ugh, I can't control it anymore</value>
|
||||
</data>
|
||||
<data name="_GameClickTwiceMsg" xml:space="preserve">
|
||||
<value>No no no, don't click me. Sorry, I shouldn't have lied to you, I am a cursed button, and continuing to click me will bring disaster to the entire Sheas Cealer. Please believe me. This is not a game, and there are no new features here. Listen to me and use the normal functions. Please</value>
|
||||
</data>
|
||||
<data name="_GameEndingMsg" xml:space="preserve">
|
||||
<value>You defeated the evil button and saved Sheas Cealer. You are the HERO!</value>
|
||||
</data>
|
||||
<data name="_GameGradeMsg" xml:space="preserve">
|
||||
<value>Button Remaining HP.</value>
|
||||
</data>
|
||||
<data name="_GameReviewEndingMsg" xml:space="preserve">
|
||||
<value>It's dead. You're the HERO of Sheas Cealer</value>
|
||||
</data>
|
||||
<data name="_GameStartMsg" xml:space="preserve">
|
||||
<value>No, please kill me. I... can't control it...</value>
|
||||
</data>
|
||||
<data name="_KillBrowserProcessPrompt" xml:space="preserve">
|
||||
<value>All processes of the selected browser will be closed before launching. Do you want to continue?</value>
|
||||
</data>
|
||||
<data name="_LaunchHostsNginxPrompt" xml:space="preserve">
|
||||
<value>You are using hosts-based non-wildcard domain global cealing. Do you want to continue?</value>
|
||||
</data>
|
||||
<data name="_LaunchMihomoErrorMsg" xml:space="preserve">
|
||||
<value>Mihomo failed to launch</value>
|
||||
</data>
|
||||
<data name="_LaunchNginxErrorPrompt" xml:space="preserve">
|
||||
<value>Nginx failed to launch. Do you want to open the error log?</value>
|
||||
</data>
|
||||
<data name="_LaunchNginxFlashingPrompt" xml:space="preserve">
|
||||
<value>Warning: The proxy core is under attack and failes to conceal SNI. The SNI removal mode has been turned on urgently. Do you want to continue?</value>
|
||||
</data>
|
||||
<data name="_LaunchProxyPrompt" xml:space="preserve">
|
||||
<value>Please remember to come back and stop the proxy manually after use. Do you want to continue?</value>
|
||||
</data>
|
||||
<data name="_MihomoConfErrorMsg" xml:space="preserve">
|
||||
<value>The mihomo conf contains syntax errors and cannot be recognized</value>
|
||||
</data>
|
||||
<data name="_NginxHttpPortOccupiedPrompt" xml:space="preserve">
|
||||
<value>The local port 80 is occupied. Do you want to use port {0} to continue? This may cause the http connection to fail to automatically jump to https</value>
|
||||
</data>
|
||||
<data name="_NginxHttpsPortOccupiedPrompt" xml:space="preserve">
|
||||
<value>The local port 443 is occupied. Do you want to use port {0} to continue? This may cause the global cealing to not work properly</value>
|
||||
</data>
|
||||
<data name="_OverrideUpstreamHostPrompt" xml:space="preserve">
|
||||
<value>There is an update available. Do you want to update upstream host? If No it will only open the upstream host web page for you</value>
|
||||
</data>
|
||||
<data name="_UpdateUpstreamHostSuccessMsg" xml:space="preserve">
|
||||
<value>Update successfully</value>
|
||||
</data>
|
||||
<data name="_UpstreamHostUtdMsg" xml:space="preserve">
|
||||
<value>Upstream host is already up to date</value>
|
||||
</data>
|
||||
</root>
|
321
Consts/MainMultilangConst.zh.resx
Normal file
321
Consts/MainMultilangConst.zh.resx
Normal file
@ -0,0 +1,321 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AboutButtonContent" xml:space="preserve">
|
||||
<value>关于项目</value>
|
||||
</data>
|
||||
<data name="AboutButtonToolTip" xml:space="preserve">
|
||||
<value>点击打开关于窗口</value>
|
||||
</data>
|
||||
<data name="BrowserButtonContent" xml:space="preserve">
|
||||
<value>启动伪造</value>
|
||||
</data>
|
||||
<data name="BrowserButtonToolTip" xml:space="preserve">
|
||||
<value>点击启动参数注入完成的浏览器</value>
|
||||
</data>
|
||||
<data name="ComihomoButtonIsInitingContent" xml:space="preserve">
|
||||
<value>全局净化调整中</value>
|
||||
</data>
|
||||
<data name="ConginxButtonIsInitingContent" xml:space="preserve">
|
||||
<value>全局伪造启动中</value>
|
||||
</data>
|
||||
<data name="EditHostsConfButtonContent" xml:space="preserve">
|
||||
<value>编辑 Hosts 配置</value>
|
||||
</data>
|
||||
<data name="EditHostsConfButtonToolTip" xml:space="preserve">
|
||||
<value>点击编辑 Hosts 配置</value>
|
||||
</data>
|
||||
<data name="EditLocalHostButtonContent" xml:space="preserve">
|
||||
<value>编辑本地规则</value>
|
||||
</data>
|
||||
<data name="EditLocalHostButtonToolTip" xml:space="preserve">
|
||||
<value>点击编辑本地规则</value>
|
||||
</data>
|
||||
<data name="EditMihomoConfButtonContent" xml:space="preserve">
|
||||
<value>编辑 Mihomo 配置</value>
|
||||
</data>
|
||||
<data name="EditMihomoConfButtonToolTip" xml:space="preserve">
|
||||
<value>点击编辑 Mihomo 配置</value>
|
||||
</data>
|
||||
<data name="EditNginxConfButtonContent" xml:space="preserve">
|
||||
<value>编辑 Nginx 配置</value>
|
||||
</data>
|
||||
<data name="EditNginxConfButtonToolTip" xml:space="preserve">
|
||||
<value>点击编辑 Nginx 配置</value>
|
||||
</data>
|
||||
<data name="EditUpstreamHostButtonContent" xml:space="preserve">
|
||||
<value>编辑上游规则</value>
|
||||
</data>
|
||||
<data name="EditUpstreamHostButtonToolTip" xml:space="preserve">
|
||||
<value>点击编辑上游规则</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsInitingContent" xml:space="preserve">
|
||||
<value>全局净化启动中</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsRunningContent" xml:space="preserve">
|
||||
<value>停止全局净化</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsRunningToolTip" xml:space="preserve">
|
||||
<value>点击停止本地 Mihomo</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsStoppedContent" xml:space="preserve">
|
||||
<value>启动全局净化</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsStoppedToolTip" xml:space="preserve">
|
||||
<value>点击启动本地 Mihomo</value>
|
||||
</data>
|
||||
<data name="MihomoButtonIsStoppingContent" xml:space="preserve">
|
||||
<value>全局净化停止中</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsInitingContent" xml:space="preserve">
|
||||
<value>全局伪造启动中</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsRunningContent" xml:space="preserve">
|
||||
<value>停止全局伪造</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsRunningToolTip" xml:space="preserve">
|
||||
<value>点击停止 Nginx</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsStoppedContent" xml:space="preserve">
|
||||
<value>启动全局伪造</value>
|
||||
</data>
|
||||
<data name="NginxButtonIsStoppedToolTip" xml:space="preserve">
|
||||
<value>点击启动本地 Nginx</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsFlashingContent" xml:space="preserve">
|
||||
<value>赶紧点我</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsFlashingToolTip" xml:space="preserve">
|
||||
<value>赶紧点击这个按钮</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsStoppedContent" xml:space="preserve">
|
||||
<value>不要点我</value>
|
||||
</data>
|
||||
<data name="NoClickButtonIsStoppedToolTip" xml:space="preserve">
|
||||
<value>不要点击这个按钮</value>
|
||||
</data>
|
||||
<data name="SettingsBoxBrowserPathToolTip" xml:space="preserve">
|
||||
<value>填入任意以 Chromium 为内核的浏览器路径</value>
|
||||
</data>
|
||||
<data name="SettingsBoxExtraArgsToolTip" xml:space="preserve">
|
||||
<value>填入任意额外的 Chromium 启动参数</value>
|
||||
</data>
|
||||
<data name="SettingsBoxUpstreamUrlToolTip" xml:space="preserve">
|
||||
<value>填入任意上游规则链接</value>
|
||||
</data>
|
||||
<data name="SettingsButtonContent" xml:space="preserve">
|
||||
<value>界面设置</value>
|
||||
</data>
|
||||
<data name="SettingsButtonToolTip" xml:space="preserve">
|
||||
<value>点击打开设置窗口</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonBrowserPathContent" xml:space="preserve">
|
||||
<value>浏览路径</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonExtraArgsContent" xml:space="preserve">
|
||||
<value>清除参数</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonToolTip" xml:space="preserve">
|
||||
<value>点击处理设置内容</value>
|
||||
</data>
|
||||
<data name="SettingsFunctionButtonUpstreamUrlContent" xml:space="preserve">
|
||||
<value>重置链接</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonBrowserPathContent" xml:space="preserve">
|
||||
<value>文件路径</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonExtraArgsContent" xml:space="preserve">
|
||||
<value>额外参数</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonToolTip" xml:space="preserve">
|
||||
<value>点击切换设置模式</value>
|
||||
</data>
|
||||
<data name="SettingsModeButtonUpstreamUrlContent" xml:space="preserve">
|
||||
<value>上游链接</value>
|
||||
</data>
|
||||
<data name="UpdateUpstreamHostButtonContent" xml:space="preserve">
|
||||
<value>更新上游规则</value>
|
||||
</data>
|
||||
<data name="UpdateUpstreamHostButtonToolTip" xml:space="preserve">
|
||||
<value>点击更新上游规则</value>
|
||||
</data>
|
||||
<data name="_BrowserPathDialogFilterFileType" xml:space="preserve">
|
||||
<value>浏览器</value>
|
||||
</data>
|
||||
<data name="_CealHostErrorPrompt" xml:space="preserve">
|
||||
<value>伪造规则含有语法错误,部分规则无法识别,是否仍然继续?</value>
|
||||
</data>
|
||||
<data name="_GameClickOnceMsg" xml:space="preserve">
|
||||
<value>就知道你会点,但其实什么事情都不会发生的。嘻嘻~</value>
|
||||
</data>
|
||||
<data name="_GameClickThreeMsg" xml:space="preserve">
|
||||
<value>呜,你在做什么。求求你不要再继续点了,我不想伤害大家。快停下,这是最后一次机会。呃,我快要控制不住了</value>
|
||||
</data>
|
||||
<data name="_GameClickTwiceMsg" xml:space="preserve">
|
||||
<value>不不不,不要点我。对不起,我不该骗你的,我是一个受诅咒的按钮,继续点我会给整个 Sheas Cealer 带来灾难的。请相信我,这不是游戏,这里也没有新功能。听我的,去用正常的功能好吗,求求你了</value>
|
||||
</data>
|
||||
<data name="_GameEndingMsg" xml:space="preserve">
|
||||
<value>你击败了邪恶的按钮,拯救了 Sheas Cealer,你是英雄!</value>
|
||||
</data>
|
||||
<data name="_GameGradeMsg" xml:space="preserve">
|
||||
<value>按钮剩余血量:</value>
|
||||
</data>
|
||||
<data name="_GameReviewEndingMsg" xml:space="preserve">
|
||||
<value>它死了,你是 Sheas Cealer 的英雄</value>
|
||||
</data>
|
||||
<data name="_GameStartMsg" xml:space="preserve">
|
||||
<value>不,求你杀了我,我... 控制不住了...</value>
|
||||
</data>
|
||||
<data name="_KillBrowserProcessPrompt" xml:space="preserve">
|
||||
<value>启动前将关闭所选浏览器的所有进程,是否继续?</value>
|
||||
</data>
|
||||
<data name="_LaunchHostsNginxPrompt" xml:space="preserve">
|
||||
<value>正在使用基于 Hosts 的非泛域名全局伪造,是否继续?</value>
|
||||
</data>
|
||||
<data name="_LaunchMihomoErrorMsg" xml:space="preserve">
|
||||
<value>Mihomo 启动失败</value>
|
||||
</data>
|
||||
<data name="_LaunchNginxErrorPrompt" xml:space="preserve">
|
||||
<value>Nginx 启动失败,是否打开错误日志?</value>
|
||||
</data>
|
||||
<data name="_LaunchNginxFlashingPrompt" xml:space="preserve">
|
||||
<value>Warning: 代理核心正在遭受攻击,无法伪造 SNI,已紧急开启 SNI 拔除模式,是否继续?</value>
|
||||
</data>
|
||||
<data name="_LaunchProxyPrompt" xml:space="preserve">
|
||||
<value>使用完请务必记得回来手动关闭代理,是否继续?</value>
|
||||
</data>
|
||||
<data name="_MihomoConfErrorMsg" xml:space="preserve">
|
||||
<value>Mihomo 配置文件含有语法错误,部分配置无法识别</value>
|
||||
</data>
|
||||
<data name="_NginxHttpPortOccupiedPrompt" xml:space="preserve">
|
||||
<value>本地 80 端口被占用,是否换用 {0} 端口继续? 这可能导致 http 连接无法自动跳转到 https</value>
|
||||
</data>
|
||||
<data name="_NginxHttpsPortOccupiedPrompt" xml:space="preserve">
|
||||
<value>本地 443 端口被占用,是否换用 {0} 端口继续? 这可能导致全局伪造无法正常工作</value>
|
||||
</data>
|
||||
<data name="_OverrideUpstreamHostPrompt" xml:space="preserve">
|
||||
<value>上游规则有更新可用,需要更新吗?否则只为你打开上游规则网页</value>
|
||||
</data>
|
||||
<data name="_UpdateUpstreamHostSuccessMsg" xml:space="preserve">
|
||||
<value>更新已完成</value>
|
||||
</data>
|
||||
<data name="_UpstreamHostUtdMsg" xml:space="preserve">
|
||||
<value>上游规则已经更到最新了</value>
|
||||
</data>
|
||||
</root>
|
3
Consts/SettingsConst.cs
Normal file
3
Consts/SettingsConst.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace Sheas_Cealer.Consts;
|
||||
|
||||
internal abstract class SettingsConst : SettingsMultilangConst;
|
198
Consts/SettingsMultilangConst.Designer.cs
generated
Normal file
198
Consts/SettingsMultilangConst.Designer.cs
generated
Normal file
@ -0,0 +1,198 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Sheas_Cealer.Consts {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class SettingsMultilangConst {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal SettingsMultilangConst() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Sheas_Cealer.Consts.SettingsMultilangConst", typeof(SettingsMultilangConst).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Switch successfuly, restart to refresh the windows 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string _ChangeLangSuccessMsg {
|
||||
get {
|
||||
return ResourceManager.GetString("_ChangeLangSuccessMsg", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Color (Fully Random) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ColorsButtonContent {
|
||||
get {
|
||||
return ResourceManager.GetString("ColorsButtonContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to switch colors 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ColorsButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("ColorsButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Switch Lang (中文 → En) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string LangsButtonChineseLangContent {
|
||||
get {
|
||||
return ResourceManager.GetString("LangsButtonChineseLangContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Switch Lang (En → Auto) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string LangsButtonEnglishLangContent {
|
||||
get {
|
||||
return ResourceManager.GetString("LangsButtonEnglishLangContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Switch Lang (Auto → 中文) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string LangsButtonInheritLangContent {
|
||||
get {
|
||||
return ResourceManager.GetString("LangsButtonInheritLangContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to switch langs 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string LangsButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("LangsButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Theme (Dark → Light) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ThemesButtonDarkThemeContent {
|
||||
get {
|
||||
return ResourceManager.GetString("ThemesButtonDarkThemeContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Theme (Auto → Dark) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ThemesButtonInheritThemeContent {
|
||||
get {
|
||||
return ResourceManager.GetString("ThemesButtonInheritThemeContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Theme (Light → Auto) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ThemesButtonLightThemeContent {
|
||||
get {
|
||||
return ResourceManager.GetString("ThemesButtonLightThemeContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to switch themes 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ThemesButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("ThemesButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Weight (Bold → Light) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string WeightsButtonBoldWeightContent {
|
||||
get {
|
||||
return ResourceManager.GetString("WeightsButtonBoldWeightContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Weight (Light → Regular) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string WeightsButtonLightWeightContent {
|
||||
get {
|
||||
return ResourceManager.GetString("WeightsButtonLightWeightContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 SWT. Weight (RGL. → Bold) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string WeightsButtonRegularWeightContent {
|
||||
get {
|
||||
return ResourceManager.GetString("WeightsButtonRegularWeightContent", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Click to switch font weights 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string WeightsButtonToolTip {
|
||||
get {
|
||||
return ResourceManager.GetString("WeightsButtonToolTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
145
Consts/SettingsMultilangConst.resx
Normal file
145
Consts/SettingsMultilangConst.resx
Normal file
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ColorsButtonContent" xml:space="preserve">
|
||||
<value>SWT. Color (Fully Random)</value>
|
||||
</data>
|
||||
<data name="ColorsButtonToolTip" xml:space="preserve">
|
||||
<value>Click to switch colors</value>
|
||||
</data>
|
||||
<data name="LangsButtonChineseLangContent" xml:space="preserve">
|
||||
<value>Switch Lang (中文 → En)</value>
|
||||
</data>
|
||||
<data name="LangsButtonEnglishLangContent" xml:space="preserve">
|
||||
<value>Switch Lang (En → Auto)</value>
|
||||
</data>
|
||||
<data name="LangsButtonInheritLangContent" xml:space="preserve">
|
||||
<value>Switch Lang (Auto → 中文)</value>
|
||||
</data>
|
||||
<data name="LangsButtonToolTip" xml:space="preserve">
|
||||
<value>Click to switch langs</value>
|
||||
</data>
|
||||
<data name="ThemesButtonDarkThemeContent" xml:space="preserve">
|
||||
<value>SWT. Theme (Dark → Light)</value>
|
||||
</data>
|
||||
<data name="ThemesButtonInheritThemeContent" xml:space="preserve">
|
||||
<value>SWT. Theme (Auto → Dark)</value>
|
||||
</data>
|
||||
<data name="ThemesButtonLightThemeContent" xml:space="preserve">
|
||||
<value>SWT. Theme (Light → Auto)</value>
|
||||
</data>
|
||||
<data name="ThemesButtonToolTip" xml:space="preserve">
|
||||
<value>Click to switch themes</value>
|
||||
</data>
|
||||
<data name="WeightsButtonBoldWeightContent" xml:space="preserve">
|
||||
<value>SWT. Weight (Bold → Light)</value>
|
||||
</data>
|
||||
<data name="WeightsButtonLightWeightContent" xml:space="preserve">
|
||||
<value>SWT. Weight (Light → Regular)</value>
|
||||
</data>
|
||||
<data name="WeightsButtonRegularWeightContent" xml:space="preserve">
|
||||
<value>SWT. Weight (RGL. → Bold)</value>
|
||||
</data>
|
||||
<data name="WeightsButtonToolTip" xml:space="preserve">
|
||||
<value>Click to switch font weights</value>
|
||||
</data>
|
||||
<data name="_ChangeLangSuccessMsg" xml:space="preserve">
|
||||
<value>Switch successfuly, restart to refresh the windows</value>
|
||||
</data>
|
||||
</root>
|
145
Consts/SettingsMultilangConst.zh.resx
Normal file
145
Consts/SettingsMultilangConst.zh.resx
Normal file
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ColorsButtonContent" xml:space="preserve">
|
||||
<value>切换颜色 (全随机)</value>
|
||||
</data>
|
||||
<data name="ColorsButtonToolTip" xml:space="preserve">
|
||||
<value>点击切换按钮颜色</value>
|
||||
</data>
|
||||
<data name="LangsButtonChineseLangContent" xml:space="preserve">
|
||||
<value>切换语言 (中文 → En)</value>
|
||||
</data>
|
||||
<data name="LangsButtonEnglishLangContent" xml:space="preserve">
|
||||
<value>切换语言 (En → 系统)</value>
|
||||
</data>
|
||||
<data name="LangsButtonInheritLangContent" xml:space="preserve">
|
||||
<value>切换语言 (系统 → 中文)</value>
|
||||
</data>
|
||||
<data name="LangsButtonToolTip" xml:space="preserve">
|
||||
<value>点击切换界面语言</value>
|
||||
</data>
|
||||
<data name="ThemesButtonDarkThemeContent" xml:space="preserve">
|
||||
<value>切换主题 (暗色 → 亮色)</value>
|
||||
</data>
|
||||
<data name="ThemesButtonInheritThemeContent" xml:space="preserve">
|
||||
<value>切换主题 (系统 → 暗色)</value>
|
||||
</data>
|
||||
<data name="ThemesButtonLightThemeContent" xml:space="preserve">
|
||||
<value>切换主题 (亮色 → 系统)</value>
|
||||
</data>
|
||||
<data name="ThemesButtonToolTip" xml:space="preserve">
|
||||
<value>点击切换显示主题</value>
|
||||
</data>
|
||||
<data name="WeightsButtonBoldWeightContent" xml:space="preserve">
|
||||
<value>切换字重 (粗体 → 细体)</value>
|
||||
</data>
|
||||
<data name="WeightsButtonLightWeightContent" xml:space="preserve">
|
||||
<value>切换字重 (细体 → 标准)</value>
|
||||
</data>
|
||||
<data name="WeightsButtonRegularWeightContent" xml:space="preserve">
|
||||
<value>切换字重 (标准 → 粗体)</value>
|
||||
</data>
|
||||
<data name="WeightsButtonToolTip" xml:space="preserve">
|
||||
<value>点击切换字体粗细</value>
|
||||
</data>
|
||||
<data name="_ChangeLangSuccessMsg" xml:space="preserve">
|
||||
<value>语言更改完成,重启以刷新界面</value>
|
||||
</data>
|
||||
</root>
|
18
Convs/AboutAccentButtonForegroundConv.cs
Normal file
18
Convs/AboutAccentButtonForegroundConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class AboutAccentButtonForegroundConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
Color accentForegroundColor = (Color)value;
|
||||
|
||||
return new SolidColorBrush(accentForegroundColor);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
7
Convs/AboutConv.cs
Normal file
7
Convs/AboutConv.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal static class AboutConv
|
||||
{
|
||||
public static AboutAccentButtonForegroundConv AboutAccentButtonForegroundConv => new();
|
||||
public static AboutVersionButtonContentConv AboutVersionButtonContentConv => new();
|
||||
}
|
19
Convs/AboutVersionButtonContentConv.cs
Normal file
19
Convs/AboutVersionButtonContentConv.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class AboutVersionButtonContentConv : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string versionButtonLabelContent = (string)values[0];
|
||||
string versionButtonVersionContent = (string)values[1];
|
||||
bool isSheasCealerUtd = (bool)values[2];
|
||||
|
||||
return $"{versionButtonLabelContent} {versionButtonVersionContent}" + (isSheasCealerUtd ? string.Empty : " *");
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
18
Convs/MainAdminControlVisibilityConv.cs
Normal file
18
Convs/MainAdminControlVisibilityConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainAdminControlVisibilityConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isAdmin = (bool)value;
|
||||
|
||||
return isAdmin ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
20
Convs/MainBrowserButtonIsEnabledConv.cs
Normal file
20
Convs/MainBrowserButtonIsEnabledConv.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainBrowserButtonIsEnabledConv : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string browserPath = (string)values[0];
|
||||
string extraArgs = (string)values[1];
|
||||
|
||||
return File.Exists(browserPath) && Path.GetFileName(browserPath).ToLowerInvariant().EndsWith(".exe") && MainConst.ExtraArgsRegex().IsMatch(extraArgs);
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
24
Convs/MainConv.cs
Normal file
24
Convs/MainConv.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
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 MainNginxButtonIsEnabledConv MainNginxButtonIsEnabledConv => new();
|
||||
public static MainProxyColumnWidthConv MainProxyColumnWidthConv => new();
|
||||
public static MainSettingsBoxHintConv MainSettingsBoxHintConv => new();
|
||||
public static MainSettingsBoxTextConv MainSettingsBoxTextConv => new();
|
||||
public static MainSettingsBoxToolTipConv MainSettingsBoxToolTipConv => new();
|
||||
public static MainSettingsFunctionButtonContentConv MainSettingsFunctionButtonContentConv => new();
|
||||
public static MainSettingsModeButtonContentConv MainSettingsModeButtonContentConv => new();
|
||||
public static MainBrowserButtonIsEnabledConv MainBrowserButtonIsEnabledConv => new();
|
||||
public static MainUpdateHostButtonContentConv MainUpdateHostButtonContentConv => new();
|
||||
public static MainUpdateHostButtonIsEnabledConv MainUpdateHostButtonIsEnabledConv => new();
|
||||
public static MainWinWidthConv MainWinWidthConv => new();
|
||||
}
|
25
Convs/MainMihomoButtonContentConv.cs
Normal file
25
Convs/MainMihomoButtonContentConv.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainMihomoButtonContentConv : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isMihomoRunning = (bool)values[0];
|
||||
bool isComihomoIniting = (bool)values[1];
|
||||
bool isMihomoIniting = (bool)values[2];
|
||||
bool isCoproxyIniting = (bool)values[3];
|
||||
bool isCoproxyStopping = (bool)values[4];
|
||||
|
||||
return isCoproxyIniting || isCoproxyStopping ? Binding.DoNothing :
|
||||
isComihomoIniting ? MainConst.MihomoButtonIsStoppingContent :
|
||||
isMihomoIniting ? MainConst.MihomoButtonIsInitingContent :
|
||||
isMihomoRunning ? MainConst.MihomoButtonIsRunningContent : MainConst.MihomoButtonIsStoppedContent;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
21
Convs/MainMihomoButtonIsEnabledConv.cs
Normal file
21
Convs/MainMihomoButtonIsEnabledConv.cs
Normal file
@ -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();
|
||||
}
|
18
Convs/MainMihomoButtonToolTipConv.cs
Normal file
18
Convs/MainMihomoButtonToolTipConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainMihomoButtonToolTipConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isMihomoRunning = (bool)value;
|
||||
|
||||
return isMihomoRunning ? MainConst.MihomoButtonIsRunningToolTip : MainConst.MihomoButtonIsStoppedToolTip;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
23
Convs/MainNginxButtonContentConv.cs
Normal file
23
Convs/MainNginxButtonContentConv.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainNginxButtonContentConv : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isConginxRunning = (bool)values[0];
|
||||
bool isNginxRunning = (bool)values[1];
|
||||
bool isCoproxyIniting = (bool)values[2];
|
||||
bool isNginxIniting = (bool)values[3];
|
||||
|
||||
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();
|
||||
}
|
22
Convs/MainNginxButtonIsEnabledConv.cs
Normal file
22
Convs/MainNginxButtonIsEnabledConv.cs
Normal file
@ -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();
|
||||
}
|
19
Convs/MainNginxButtonToolTipConv.cs
Normal file
19
Convs/MainNginxButtonToolTipConv.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainNginxButtonToolTipConv : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isConginxRunning = (bool)values[0];
|
||||
bool isNginxRunning = (bool)values[1];
|
||||
|
||||
return isConginxRunning || isNginxRunning ? MainConst.NginxButtonIsRunningToolTip : MainConst.NginxButtonIsStoppedToolTip;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
18
Convs/MainNoClickButtonContentConv.cs
Normal file
18
Convs/MainNoClickButtonContentConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainNoClickButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isFlashing = (bool)value;
|
||||
|
||||
return isFlashing ? MainConst.NoClickButtonIsFlashingContent : MainConst.NoClickButtonIsStoppedContent;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
18
Convs/MainNoClickButtonToolTipConv.cs
Normal file
18
Convs/MainNoClickButtonToolTipConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainNoClickButtonToolTipConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isFlashing = (bool)value;
|
||||
|
||||
return isFlashing ? MainConst.NoClickButtonIsFlashingToolTip : MainConst.NoClickButtonIsStoppedToolTip;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
18
Convs/MainProxyColumnWidthConv.cs
Normal file
18
Convs/MainProxyColumnWidthConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainProxyColumnWidthConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isAdmin = (bool)value;
|
||||
|
||||
return new GridLength(1, isAdmin ? GridUnitType.Star : GridUnitType.Auto);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
25
Convs/MainSettingsBoxHintConv.cs
Normal file
25
Convs/MainSettingsBoxHintConv.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainSettingsBoxHintConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
MainConst.SettingsMode settingsMode = (MainConst.SettingsMode)value;
|
||||
|
||||
return settingsMode switch
|
||||
{
|
||||
MainConst.SettingsMode.BrowserPathMode => MainConst.SettingsModeButtonBrowserPathContent,
|
||||
MainConst.SettingsMode.UpstreamUrlMode => MainConst.SettingsModeButtonUpstreamUrlContent,
|
||||
MainConst.SettingsMode.ExtraArgsMode => MainConst.SettingsModeButtonExtraArgsContent,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
28
Convs/MainSettingsBoxTextConv.cs
Normal file
28
Convs/MainSettingsBoxTextConv.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainSettingsBoxTextConv : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
MainConst.SettingsMode settingsMode = (MainConst.SettingsMode)values[0];
|
||||
string browserPath = (string)values[1];
|
||||
string upstreamUrl = (string)values[2];
|
||||
string extraArgs = (string)values[3];
|
||||
|
||||
return settingsMode switch
|
||||
{
|
||||
MainConst.SettingsMode.BrowserPathMode => browserPath,
|
||||
MainConst.SettingsMode.UpstreamUrlMode => upstreamUrl,
|
||||
MainConst.SettingsMode.ExtraArgsMode => extraArgs,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
25
Convs/MainSettingsBoxToolTipConv.cs
Normal file
25
Convs/MainSettingsBoxToolTipConv.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainSettingsBoxToolTipConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
MainConst.SettingsMode settingsMode = (MainConst.SettingsMode)value;
|
||||
|
||||
return settingsMode switch
|
||||
{
|
||||
MainConst.SettingsMode.BrowserPathMode => MainConst.SettingsBoxBrowserPathToolTip,
|
||||
MainConst.SettingsMode.UpstreamUrlMode => MainConst.SettingsBoxUpstreamUrlToolTip,
|
||||
MainConst.SettingsMode.ExtraArgsMode => MainConst.SettingsBoxExtraArgsToolTip,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
25
Convs/MainSettingsFunctionButtonContentConv.cs
Normal file
25
Convs/MainSettingsFunctionButtonContentConv.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainSettingsFunctionButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
MainConst.SettingsMode settingsMode = (MainConst.SettingsMode)value;
|
||||
|
||||
return settingsMode switch
|
||||
{
|
||||
MainConst.SettingsMode.BrowserPathMode => MainConst.SettingsFunctionButtonBrowserPathContent,
|
||||
MainConst.SettingsMode.UpstreamUrlMode => MainConst.SettingsFunctionButtonUpstreamUrlContent,
|
||||
MainConst.SettingsMode.ExtraArgsMode => MainConst.SettingsFunctionButtonExtraArgsContent,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
24
Convs/MainSettingsModeButtonContentConv.cs
Normal file
24
Convs/MainSettingsModeButtonContentConv.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainSettingsModeButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
MainConst.SettingsMode settingsMode = (MainConst.SettingsMode)value;
|
||||
|
||||
return settingsMode switch
|
||||
{
|
||||
MainConst.SettingsMode.BrowserPathMode => MainConst.SettingsModeButtonUpstreamUrlContent,
|
||||
MainConst.SettingsMode.UpstreamUrlMode => MainConst.SettingsModeButtonExtraArgsContent,
|
||||
MainConst.SettingsMode.ExtraArgsMode => MainConst.SettingsModeButtonBrowserPathContent,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
18
Convs/MainUpdateHostButtonContentConv.cs
Normal file
18
Convs/MainUpdateHostButtonContentConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainUpdateHostButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isUpstreamHostUtd = (bool)value;
|
||||
|
||||
return MainConst.UpdateUpstreamHostButtonContent + (isUpstreamHostUtd ? string.Empty : " *");
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
18
Convs/MainUpdateHostButtonIsEnabledConv.cs
Normal file
18
Convs/MainUpdateHostButtonIsEnabledConv.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainUpdateHostButtonIsEnabledConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string upstreamUrl = (string)value;
|
||||
|
||||
return MainConst.UpstreamUrlRegex().IsMatch(upstreamUrl);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
17
Convs/MainWinWidthConv.cs
Normal file
17
Convs/MainWinWidthConv.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class MainWinWidthConv : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isAdmin = (bool)value;
|
||||
|
||||
return isAdmin ? 708 : 500;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
8
Convs/SettingsConv.cs
Normal file
8
Convs/SettingsConv.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal static class SettingsConv
|
||||
{
|
||||
public static SettingsLangsButtonContentConv SettingsLangsButtonContentConv => new();
|
||||
public static SettingsThemesButtonContentConv SettingsThemesButtonContentConv => new();
|
||||
public static SettingsWeightsButtonContentConv SettingsWeightsButtonContentConv => new();
|
||||
}
|
20
Convs/SettingsLangsButtonContentConv.cs
Normal file
20
Convs/SettingsLangsButtonContentConv.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class SettingsLangsButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool? isEnglishLang = value as bool?;
|
||||
|
||||
return isEnglishLang.HasValue ?
|
||||
isEnglishLang.GetValueOrDefault() ? SettingsConst.LangsButtonEnglishLangContent : SettingsConst.LangsButtonChineseLangContent :
|
||||
SettingsConst.LangsButtonInheritLangContent;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
20
Convs/SettingsThemesButtonContentConv.cs
Normal file
20
Convs/SettingsThemesButtonContentConv.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class SettingsThemesButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool? isLightMode = value as bool?;
|
||||
|
||||
return isLightMode.HasValue ?
|
||||
isLightMode.GetValueOrDefault() ? SettingsConst.ThemesButtonLightThemeContent : SettingsConst.ThemesButtonDarkThemeContent :
|
||||
SettingsConst.ThemesButtonInheritThemeContent;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
20
Convs/SettingsWeightsButtonContentConv.cs
Normal file
20
Convs/SettingsWeightsButtonContentConv.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Sheas_Cealer.Convs;
|
||||
|
||||
internal class SettingsWeightsButtonContentConv : IValueConverter
|
||||
{
|
||||
public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool? isLightWeight = value as bool?;
|
||||
|
||||
return isLightWeight.HasValue ?
|
||||
isLightWeight.GetValueOrDefault() ? SettingsConst.WeightsButtonLightWeightContent : SettingsConst.WeightsButtonBoldWeightContent :
|
||||
SettingsConst.WeightsButtonRegularWeightContent;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||
}
|
BIN
Country.mmdb
BIN
Country.mmdb
Binary file not shown.
9
Preses/AboutPres.cs
Normal file
9
Preses/AboutPres.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Sheas_Cealer.Preses;
|
||||
|
||||
internal partial class AboutPres : GlobalPres
|
||||
{
|
||||
[ObservableProperty]
|
||||
private bool isSheasCealerUtd = true;
|
||||
}
|
44
Preses/GlobalPres.cs
Normal file
44
Preses/GlobalPres.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Cealer.Props;
|
||||
using Sheas_Cealer.Utils;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Sheas_Cealer.Preses;
|
||||
|
||||
internal partial class GlobalPres : ObservableObject
|
||||
{
|
||||
internal GlobalPres()
|
||||
{
|
||||
IsLightTheme = Settings.Default.IsLightTheme switch
|
||||
{
|
||||
-1 => null,
|
||||
0 => false,
|
||||
1 => true,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private static bool? isLightTheme = null;
|
||||
partial void OnIsLightThemeChanged(bool? value)
|
||||
{
|
||||
PaletteHelper paletteHelper = new();
|
||||
Theme newTheme = paletteHelper.GetTheme();
|
||||
|
||||
newTheme.SetBaseTheme(value.HasValue ? value.Value ? BaseTheme.Light : BaseTheme.Dark : BaseTheme.Inherit);
|
||||
paletteHelper.SetTheme(newTheme);
|
||||
|
||||
foreach (Window currentWindow in Application.Current.Windows)
|
||||
BorderThemeSetter.SetBorderTheme(currentWindow, value);
|
||||
|
||||
Settings.Default.IsLightTheme = (sbyte)(value.HasValue ? value.Value ? 1 : 0 : -1);
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private static Color accentForegroundColor = AboutConst.AccentBlueColor;
|
||||
}
|
118
Preses/MainPres.cs
Normal file
118
Preses/MainPres.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Win32;
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Cealer.Props;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Sheas_Cealer.Preses;
|
||||
|
||||
internal partial class MainPres : GlobalPres
|
||||
{
|
||||
internal MainPres()
|
||||
{
|
||||
string[] args = Environment.GetCommandLineArgs();
|
||||
|
||||
int browserPathIndex = Array.FindIndex(args, arg => arg.Equals("-b", StringComparison.OrdinalIgnoreCase)) + 1;
|
||||
int upstreamUrlIndex = Array.FindIndex(args, arg => arg.Equals("-u", StringComparison.OrdinalIgnoreCase)) + 1;
|
||||
int extraArgsIndex = Array.FindIndex(args, arg => arg.Equals("-e", StringComparison.OrdinalIgnoreCase)) + 1;
|
||||
|
||||
BrowserPath = browserPathIndex != 0 && browserPathIndex != args.Length ? args[browserPathIndex] :
|
||||
!string.IsNullOrWhiteSpace(Settings.Default.BrowserPath) ? Settings.Default.BrowserPath :
|
||||
(Registry.LocalMachine.OpenSubKey(MainConst.EdgeBrowserRegistryPath)?.GetValue(string.Empty, null) ??
|
||||
Registry.LocalMachine.OpenSubKey(MainConst.ChromeBrowserRegistryPath)?.GetValue(string.Empty, null) ??
|
||||
Registry.LocalMachine.OpenSubKey(MainConst.BraveBrowserRegistryPath)?.GetValue(string.Empty, null) ??
|
||||
string.Empty).ToString()!;
|
||||
|
||||
UpstreamUrl = upstreamUrlIndex == 0 || upstreamUrlIndex == args.Length ?
|
||||
!string.IsNullOrWhiteSpace(Settings.Default.UpstreamUrl) ? Settings.Default.UpstreamUrl : MainConst.DefaultUpstreamUrl :
|
||||
args[upstreamUrlIndex];
|
||||
|
||||
ExtraArgs = extraArgsIndex == 0 || extraArgsIndex == args.Length ?
|
||||
!string.IsNullOrWhiteSpace(Settings.Default.ExtraArgs) ? Settings.Default.ExtraArgs : string.Empty :
|
||||
args[extraArgsIndex];
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private MainConst.SettingsMode settingsMode;
|
||||
|
||||
[ObservableProperty]
|
||||
private string browserPath;
|
||||
partial void OnBrowserPathChanged(string value)
|
||||
{
|
||||
if (!File.Exists(value) || !Path.GetFileName(value).ToLowerInvariant().EndsWith(".exe"))
|
||||
return;
|
||||
|
||||
Settings.Default.BrowserPath = value;
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string upstreamUrl;
|
||||
partial void OnUpstreamUrlChanged(string value)
|
||||
{
|
||||
if (!MainConst.UpstreamUrlRegex().IsMatch(value))
|
||||
return;
|
||||
|
||||
Settings.Default.UpstreamUrl = value;
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string extraArgs;
|
||||
partial void OnExtraArgsChanged(string value)
|
||||
{
|
||||
if (!MainConst.ExtraArgsRegex().IsMatch(value))
|
||||
return;
|
||||
|
||||
Settings.Default.ExtraArgs = value;
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
[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;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isFlashing = false;
|
||||
}
|
66
Preses/SettingsPres.cs
Normal file
66
Preses/SettingsPres.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Sheas_Cealer.Props;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Sheas_Cealer.Preses;
|
||||
|
||||
internal partial class SettingsPres : GlobalPres
|
||||
{
|
||||
internal SettingsPres()
|
||||
{
|
||||
IsEnglishLang = Settings.Default.IsEnglishLang switch
|
||||
{
|
||||
-1 => null,
|
||||
0 => false,
|
||||
1 => true,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
|
||||
IsLightWeight = Settings.Default.IsLightWeight switch
|
||||
{
|
||||
-1 => null,
|
||||
0 => false,
|
||||
1 => true,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private static bool? isEnglishLang = null;
|
||||
partial void OnIsEnglishLangChanged(bool? value)
|
||||
{
|
||||
CultureInfo newCulture = value.HasValue ? new(value.Value ? "en" : "zh") : CultureInfo.InstalledUICulture;
|
||||
|
||||
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = newCulture;
|
||||
|
||||
foreach (Window currentWindow in Application.Current.Windows)
|
||||
currentWindow.Language = XmlLanguage.GetLanguage(newCulture.IetfLanguageTag);
|
||||
|
||||
Settings.Default.IsEnglishLang = (sbyte)(value.HasValue ? value.Value ? 1 : 0 : -1);
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private static bool? isLightWeight = null;
|
||||
partial void OnIsLightWeightChanged(bool? value)
|
||||
{
|
||||
FontWeight newWeight = value.HasValue ? value.Value ? FontWeights.Light : FontWeights.Bold : FontWeights.Regular;
|
||||
Style newWindowStyle = new(typeof(Window), Application.Current.Resources["CommonWindow"] as Style);
|
||||
|
||||
newWindowStyle.Setters.Add(new Setter(Window.FontWeightProperty, newWeight));
|
||||
Application.Current.Resources["CommonWindow"] = newWindowStyle;
|
||||
|
||||
Style newButtonStyle = new(typeof(Button), Application.Current.Resources[typeof(Button)] as Style);
|
||||
|
||||
newButtonStyle.Setters.Add(new Setter(Button.FontWeightProperty, newWeight));
|
||||
Application.Current.Resources[typeof(Button)] = newButtonStyle;
|
||||
|
||||
Settings.Default.IsLightWeight = (sbyte)(value.HasValue ? value.Value ? 1 : 0 : -1);
|
||||
Settings.Default.Save();
|
||||
}
|
||||
}
|
18
Proces/BrowserProc.cs
Normal file
18
Proces/BrowserProc.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Sheas_Core;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Sheas_Cealer.Proces;
|
||||
|
||||
internal class BrowserProc : Proc
|
||||
{
|
||||
private readonly bool ShutDownAppOnProcessExit;
|
||||
|
||||
internal BrowserProc(string browserPath, bool shutDownAppOnProcessExit) : base(browserPath) => ShutDownAppOnProcessExit = shutDownAppOnProcessExit;
|
||||
|
||||
protected sealed override void Process_Exited(object? sender, EventArgs e)
|
||||
{
|
||||
if (ShutDownAppOnProcessExit)
|
||||
Application.Current.Dispatcher.InvokeShutdown();
|
||||
}
|
||||
}
|
9
Proces/ComihomoProc.cs
Normal file
9
Proces/ComihomoProc.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Core;
|
||||
|
||||
namespace Sheas_Cealer.Proces;
|
||||
|
||||
internal class ComihomoProc : Proc
|
||||
{
|
||||
internal ComihomoProc() : base(MainConst.ComihomoPath) { }
|
||||
}
|
13
Proces/ConginxProc.cs
Normal file
13
Proces/ConginxProc.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Cealer.Utils;
|
||||
using Sheas_Core;
|
||||
using System;
|
||||
|
||||
namespace Sheas_Cealer.Proces;
|
||||
|
||||
internal class ConginxProc : Proc
|
||||
{
|
||||
internal ConginxProc() : base(MainConst.ConginxPath) { }
|
||||
|
||||
protected override async void Process_Exited(object? sender, EventArgs e) => await NginxCleaner.Clean();
|
||||
}
|
9
Proces/MihomoProc.cs
Normal file
9
Proces/MihomoProc.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Core;
|
||||
|
||||
namespace Sheas_Cealer.Proces;
|
||||
|
||||
internal class MihomoProc : Proc
|
||||
{
|
||||
internal MihomoProc() : base(MainConst.MihomoPath) { }
|
||||
}
|
13
Proces/NginxProc.cs
Normal file
13
Proces/NginxProc.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Cealer.Utils;
|
||||
using Sheas_Core;
|
||||
using System;
|
||||
|
||||
namespace Sheas_Cealer.Proces;
|
||||
|
||||
internal class NginxProc : Proc
|
||||
{
|
||||
internal NginxProc() : base(MainConst.NginxPath) { }
|
||||
|
||||
protected override async void Process_Exited(object? sender, EventArgs e) => await NginxCleaner.Clean();
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
38
Properties/Settings.Designer.cs
generated
38
Properties/Settings.Designer.cs
generated
@ -1,38 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Sheas_Cealer.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.1.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string BrowserPath {
|
||||
get {
|
||||
return ((string)(this["BrowserPath"]));
|
||||
}
|
||||
set {
|
||||
this["BrowserPath"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Sheas_Cealer.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="BrowserPath" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
122
Props/Settings.Designer.cs
generated
Normal file
122
Props/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,122 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Sheas_Cealer.Props {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string BrowserPath {
|
||||
get {
|
||||
return ((string)(this["BrowserPath"]));
|
||||
}
|
||||
set {
|
||||
this["BrowserPath"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string UpstreamUrl {
|
||||
get {
|
||||
return ((string)(this["UpstreamUrl"]));
|
||||
}
|
||||
set {
|
||||
this["UpstreamUrl"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string ExtraArgs {
|
||||
get {
|
||||
return ((string)(this["ExtraArgs"]));
|
||||
}
|
||||
set {
|
||||
this["ExtraArgs"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("244, 67, 54")]
|
||||
public global::System.Drawing.Color PrimaryColor {
|
||||
get {
|
||||
return ((global::System.Drawing.Color)(this["PrimaryColor"]));
|
||||
}
|
||||
set {
|
||||
this["PrimaryColor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("-1")]
|
||||
public sbyte IsLightTheme {
|
||||
get {
|
||||
return ((sbyte)(this["IsLightTheme"]));
|
||||
}
|
||||
set {
|
||||
this["IsLightTheme"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("-1")]
|
||||
public sbyte IsEnglishLang {
|
||||
get {
|
||||
return ((sbyte)(this["IsEnglishLang"]));
|
||||
}
|
||||
set {
|
||||
this["IsEnglishLang"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("-1")]
|
||||
public sbyte IsLightWeight {
|
||||
get {
|
||||
return ((sbyte)(this["IsLightWeight"]));
|
||||
}
|
||||
set {
|
||||
this["IsLightWeight"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool IsUpgradeRequired {
|
||||
get {
|
||||
return ((bool)(this["IsUpgradeRequired"]));
|
||||
}
|
||||
set {
|
||||
this["IsUpgradeRequired"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
Props/Settings.settings
Normal file
30
Props/Settings.settings
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Sheas_Cealer.Props" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="BrowserPath" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="UpstreamUrl" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="ExtraArgs" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="PrimaryColor" Type="System.Drawing.Color" Scope="User">
|
||||
<Value Profile="(Default)">244, 67, 54</Value>
|
||||
</Setting>
|
||||
<Setting Name="IsLightTheme" Type="System.SByte" Scope="User">
|
||||
<Value Profile="(Default)">-1</Value>
|
||||
</Setting>
|
||||
<Setting Name="IsEnglishLang" Type="System.SByte" Scope="User">
|
||||
<Value Profile="(Default)">-1</Value>
|
||||
</Setting>
|
||||
<Setting Name="IsLightWeight" Type="System.SByte" Scope="User">
|
||||
<Value Profile="(Default)">-1</Value>
|
||||
</Setting>
|
||||
<Setting Name="IsUpgradeRequired" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
47
README.md
47
README.md
@ -2,55 +2,70 @@
|
||||
<h3 align="center">- Just Ceal It -</h3>
|
||||
</br>
|
||||
|
||||
## 自我介绍
|
||||
**Sheas Cealer**: 一只基于 **WPF(.Net5)** 的 SNI 伪造工具
|
||||
## 其他语言
|
||||
[English README](README_EN.md)
|
||||
|
||||
* 适用平台: Windows x64
|
||||
## 自我介绍
|
||||
**Sheas Cealer**: 一只基于 **WPF(.Net8)** 的桌面端 SNI 伪造工具
|
||||
|
||||
* 适用平台: Windows (Win10 之前的系统版本请使用 [1.1.0](https://github.com/SpaceTimee/Sheas-Cealer/releases/tag/1.1.0)) (其他平台请参考[相关项目](https://github.com/SpaceTimee/Sheas-Cealer#相关项目))
|
||||
|
||||
## 词汇解释
|
||||
**[Sheas Cealer Dictionary](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Dictionary)**
|
||||
|
||||
## 注意事项
|
||||
1. 最新的 **Cealing-Host.json** 内置伪造规则可在 [Cealing Host 存储库](https://github.com/SpaceTimee/Cealing-Host) 获取
|
||||
2. 自动更新时不会覆盖已有的 **Cealing-Host.json** 和 **config.yaml** 文件,如有需要应**手动覆盖或修改**
|
||||
3. 本项目仅供**学习参考**,无意绕过任何审查设备的审查
|
||||
4. 为避免不必要的麻烦,食用前请先阅读**注意事项**和**用户协议**
|
||||
1. 内置伪造规则在 [Cealing Host 存储库](https://github.com/SpaceTimee/Cealing-Host) 持续更新
|
||||
2. Sheas Cealer 更新时不会覆盖已有的伪造规则,如需与上游同步,需点击**更新上游规则**按钮,或**手动修改覆盖**
|
||||
3. 本项目及所有相关资源仅供**抵御网络非法监听**和**开展网络安全研究**使用,无意绕过任何国家审查设备的审查
|
||||
4. 为避免不必要的麻烦,使用前请先阅读[**用户协议**](https://github.com/SpaceTimee/Sheas-Cealer#用户协议)
|
||||
5. Sheas Cealer 仍处于**开发阶段**,但每个正式版发布前会尽量确保其**稳定可用**
|
||||
6. Github Release 中会保留目前能够使用的**所有版本**,但强烈推荐使用**最新版**
|
||||
|
||||
## 用户协议
|
||||
1. [隐私政策](https://thoughts.teambition.com/share/6264eda98adeb10041b92fda#title=Sheas_Cealer_隐私政策)
|
||||
2. [使用协议](https://thoughts.teambition.com/share/6264edd78adeb10041b92fdb#title=Sheas_Cealer_使用协议)
|
||||
|
||||
## 下载地址
|
||||
1. Github (首选): [https://github.com/SpaceTimee/Sheas-Cealer/releases](https://github.com/SpaceTimee/Sheas-Cealer/releases)
|
||||
2. 蓝奏云 (密码3wnj) (大陆推荐): [https://spacetime.lanzouu.com/b017hp0lc](https://spacetime.lanzouu.com/b017hp0lc)
|
||||
1. Github: [https://github.com/SpaceTimee/Sheas-Cealer/releases](https://github.com/SpaceTimee/Sheas-Cealer/releases)
|
||||
2. 群文件 (参与内测): 参考[联系方式](https://github.com/SpaceTimee/Sheas-Cealer#联系方式)
|
||||
|
||||
> 出于不可抗力因素,Sheas Cealer 暂时无法再提供蓝奏云下载地址,在此依旧感谢蓝奏云一直以来的免费分发服务
|
||||
|
||||
## 安装方式
|
||||
1. Setup 安装器 (首选): 下载 Sheas Cealer Setup.exe 并运行 -> 按照提示设置即可安装
|
||||
2. Zip 压缩包 (免安装): 下载 Sheas Cealer Zip.zip 并解压 -> 完成后即可直接使用
|
||||
|
||||
> Scd 版本: Scd 版本内置 .Net 运行时,可在缺乏 .Net 运行时的环境下运行,但代价是更大的文件体积以及更差的跨平台能力,如果没有特殊原因,不建议使用 Scd 版本
|
||||
|
||||
## 食用文档
|
||||
**[Sheas Cealer Instruction](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Instruction)**
|
||||
**[Sheas Cealer Documentation](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Documentation)**
|
||||
|
||||
## 项目构建
|
||||
[Sheas Cealer Build](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Build)
|
||||
|
||||
## 项目原理
|
||||
利用 Chromium 内核的参数特性伪造 SNI 头,详细原理可参考[这篇文章](https://nicebowl.fun/24_8)
|
||||
利用 Chromium 内核的启动参数特性伪造 SNI 拓展标记,详细原理可参考[这篇文章](https://nicebowl.fun/24_8)
|
||||
|
||||
## 致谢名单
|
||||
* **kit: 为本项目提供全部的原理基础**
|
||||
* **NiceBowl: 为本项目提供详细的原理说明**
|
||||
* **Clash: 为本项目解决 SSL 证书匹配问题**
|
||||
|
||||
## 开发者
|
||||
**Space Time**
|
||||
|
||||
## 联系方式
|
||||
1. **新 QQ 群 (主群): 338919498**
|
||||
2. 新 TG 群 (分群) (宽松管理): [PixCealerChat](https://t.me/PixCealerChat)
|
||||
3. **邮箱: Zeus6_6@163.com**
|
||||
1. **QQ 群: 1034315671,716266896,338919498**
|
||||
2. **TG 群: [PixCealerChat](https://t.me/PixCealerChat)**
|
||||
3. 邮箱: Zeus6_6@163.com
|
||||
|
||||
## 相关项目
|
||||
1. [Sheas Cealer Droid](https://github.com/SpaceTimee/Sheas-Cealer-Droid): Sheas Cealer 安卓端
|
||||
2. [Sheas Cealer Nix](https://github.com/SpaceTimee/Sheas-Cealer/tree/nix): Sheas Cealer 跨平台桌面端
|
||||
3. [Cealing Host](https://github.com/SpaceTimee/Cealing-Host): 最新的 Sheas Cealer 内置伪造规则
|
||||
4. [Sheas Dop](https://github.com/SpaceTimee/Sheas-Dop): DNS 抗污染解析工具 (Sheas Cealer 全局净化子项目)
|
||||
5. [Sheas Nginx](https://github.com/SpaceTimee/Sheas-Nginx): Pixiv Nginx 启动器 (Sheas Cealer 全局伪造 × Pixiv Nginx 合作子项目)
|
||||
6. [Bot CealingCat](https://github.com/SpaceTimee/Bot-CealingCat): 提供 Sheas Cealer 相关服务的 Telegram Bot
|
||||
7. [Console HostChecker](https://github.com/SpaceTimee/Console-HostChecker): Cealing Host 自动化检查脚本
|
||||
8. [Console HostGenerator](https://github.com/SpaceTimee/Console-HostGenerator): Cealing Host 自动化生成脚本
|
||||
|
||||
## 许可证
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2FSpaceTimee%2FSheas-Cealer?ref=badge_large)
|
||||
|
73
README_EN.md
Normal file
73
README_EN.md
Normal file
@ -0,0 +1,73 @@
|
||||
<h1 align="center">Sheas ◁ Cealer</h1>
|
||||
<h3 align="center">- Just Ceal It -</h3>
|
||||
</br>
|
||||
|
||||
## Language
|
||||
[中文 README](README.md)
|
||||
|
||||
## About
|
||||
**Sheas Cealer**: A desktop SNI concealing tool based on **WPF(.Net8)**
|
||||
|
||||
* Applicable platform: Windows (For system versions before Win10, please use [1.1.0](https://github.com/SpaceTimee/Sheas-Cealer/releases/tag/1.1.0)) (For more platforms, please refer to [Projects](https://github.com/SpaceTimee/Sheas-Cealer#Projects))
|
||||
|
||||
## Vocabulary
|
||||
**[Sheas Cealer Dictionary](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Dictionary)**
|
||||
|
||||
## Notes
|
||||
1. The Built-in Cealing Host is continuously updated in the [Cealing Host repository](https://github.com/SpaceTimee/Cealing-Host)
|
||||
2. When Sheas Cealer is updated, it will not overwrite the existing configs. If you need to synchronize with the upstream, you need to click the **Update Upstream Host** button, or **manually overwrite**
|
||||
3. This project and all its resources are for the sole purpose of **defending against illegal network monitoring** and **conducting network security research**, and are not intended to bypass the censorship of any country
|
||||
4. Please read the [**Agreements**](https://github.com/SpaceTimee/Sheas-Cealer#Agreements) before use
|
||||
5. Sheas Cealer is still in the **development stage**, but each production version will be **stable and available** before release
|
||||
|
||||
## Agreements
|
||||
1. [Privacy Policy](https://thoughts.teambition.com/share/6264eda98adeb10041b92fda#title=Sheas_Cealer_隐私政策)
|
||||
2. [EULA](https://thoughts.teambition.com/share/6264edd78adeb10041b92fdb#title=Sheas_Cealer_使用协议)
|
||||
|
||||
## Download
|
||||
1. Github (preferred): [https://github.com/SpaceTimee/Sheas-Cealer/releases](https://github.com/SpaceTimee/Sheas-Cealer/releases)
|
||||
2. Group File (participate in internal testing): Please refer to [Contacts](https://github.com/SpaceTimee/Sheas-Cealer#Contacts)
|
||||
|
||||
> Due to force majeure, Sheas Cealer is temporarily unable to provide the download address of Lanzou Cloud. We would like to thank Lanzou Cloud for its free distribution service
|
||||
|
||||
## Installation
|
||||
1. Setup Installer (preferred): Download Sheas Cealer Setup.exe and run -> Then follow the prompts to install
|
||||
2. Zip Package (installation-free): Download Sheas Cealer Zip.zip and unzip -> Then you can use it directly
|
||||
|
||||
> Scd version: The Scd version has a built-in .Net runtime and can run in an environment without a .Net runtime, but the cost is a larger file size and worse cross-platform capabilities. If there is no special reason, it is not recommended to use the Scd version
|
||||
|
||||
## Documentation
|
||||
**[Sheas Cealer Documentation](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Documentation)**
|
||||
|
||||
## Build
|
||||
[Sheas Cealer Build](https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Build)
|
||||
|
||||
## Principles
|
||||
Using the startup parameter feature of the Chromium kernel to conceal SNI. For more detailes, please refer to [this article](https://nicebowl.fun/24_8)
|
||||
|
||||
## Credits
|
||||
* **kit: Provides all the principle foundations for this project**
|
||||
* **NiceBowl: Provides detailed principle explanations for this project**
|
||||
|
||||
## Developer
|
||||
**Space Time**
|
||||
|
||||
## Contacts
|
||||
1. **QQ Group: 1034315671, 716266896, 338919498**
|
||||
2. **TG Group: [PixCealerChat](https://t.me/PixCealerChat)**
|
||||
3. Email: Zeus6_6@163.com
|
||||
|
||||
## Projects
|
||||
1. [Sheas Cealer Droid](https://github.com/SpaceTimee/Sheas-Cealer-Droid): Sheas Cealer for Android
|
||||
2. [Sheas Cealer Nix](https://github.com/SpaceTimee/Sheas-Cealer/tree/nix): Sheas Cealer cross-platform for desktop
|
||||
3. [Cealing Host](https://github.com/SpaceTimee/Cealing-Host): The latest Built-in Cealing Host
|
||||
4. [Sheas Dop](https://github.com/SpaceTimee/Sheas-Dop): DNS anti-pollution resolution tool (Sheas Cealer Global Cealing subproject)
|
||||
5. [Sheas Nginx](https://github.com/SpaceTimee/Sheas-Nginx): Pixiv Nginx launcher (Sheas Cealer Global Purging × Pixiv Nginx cooperative subproject)
|
||||
6. [Bot CealingCat](https://github.com/SpaceTimee/Bot-CealingCat): Telegram Bot providing Sheas Cealer related services
|
||||
7. [Console HostChecker](https://github.com/SpaceTimee/Console-HostChecker): Cealing Host automated checking script
|
||||
8. [Console HostGenerator](https://github.com/SpaceTimee/Console-HostGenerator): Cealing Host automated generation script
|
||||
|
||||
## License
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2FSpaceTimee%2FSheas-Cealer?ref=badge_large)
|
||||
|
||||
•ᴗ•
|
@ -8,10 +8,10 @@
|
||||
<PackageReleaseNotes>Just Ceal It</PackageReleaseNotes>
|
||||
<Authors>Space Time</Authors>
|
||||
<Company>Space Time</Company>
|
||||
<AssemblyVersion>1.0.4</AssemblyVersion>
|
||||
<Version>1.0.4</Version>
|
||||
<FileVersion>1.0.4</FileVersion>
|
||||
<InformationalVersion>1.0.4</InformationalVersion>
|
||||
<AssemblyVersion>1.1.5</AssemblyVersion>
|
||||
<Version>1.1.5</Version>
|
||||
<FileVersion>1.1.5</FileVersion>
|
||||
<InformationalVersion>1.1.5</InformationalVersion>
|
||||
<PackageTags>Tool;Sheas;Cealer;Sni</PackageTags>
|
||||
<ApplicationIcon>Sheas-Cealer-Logo.ico</ApplicationIcon>
|
||||
<PackageIcon>Sheas Cealer Logo.png</PackageIcon>
|
||||
@ -21,23 +21,20 @@
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Copyright>Copyright © 2077</Copyright>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows10.0.22000.0</TargetFramework>
|
||||
<TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>
|
||||
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<WindowsSdkPackageVersion>10.0.26100.41</WindowsSdkPackageVersion>
|
||||
<RootNamespace>Sheas_Cealer</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<IsPublishable>True</IsPublishable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
<NoWin32Manifest>true</NoWin32Manifest>
|
||||
<AppDesignerFolder>Props</AppDesignerFolder>
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -48,43 +45,47 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove=".filenesting.json" />
|
||||
<None Remove=".gitattributes" />
|
||||
<None Remove=".gitignore" />
|
||||
<None Remove="Cealing-Clash.exe" />
|
||||
<None Remove="Cealing-Host.json" />
|
||||
<None Remove="Clash.exe" />
|
||||
<None Remove="config.yaml" />
|
||||
<None Remove="Country.mmdb" />
|
||||
<None Remove="README.md" />
|
||||
<None Remove="README_EN.md" />
|
||||
<None Remove="Sheas-Cealer-Logo.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<COMReference Include="IWshRuntimeLibrary">
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<Guid>f935dc20-1cf0-11d0-adb9-00c04fd58a0b</Guid>
|
||||
<Lcid>0</Lcid>
|
||||
<Isolated>false</Isolated>
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MaterialDesignThemes" Version="4.5.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="11.2.1" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="*" />
|
||||
<PackageReference Include="MaterialDesignThemes" Version="*" />
|
||||
<PackageReference Include="NginxConfigParser" Version="*" />
|
||||
<PackageReference Include="YamlDotNet" Version="*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Ona-Core">
|
||||
<HintPath>..\Ona-Core\bin\Release\net8.0\Ona-Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Sheas-Core">
|
||||
<HintPath>D:\Git-Repository\Sheas-Core\bin\Release\Sheas-Core.dll</HintPath>
|
||||
<HintPath>..\Sheas-Core\bin\Release\net8.0\Sheas-Core.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<Compile Update="Consts\MainMultilangConst.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>MainMultilangConst.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Consts\SettingsMultilangConst.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>SettingsMultilangConst.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Consts\AboutMultilangConst.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>AboutMultilangConst.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Props\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
@ -92,7 +93,19 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<EmbeddedResource Update="Consts\MainMultilangConst.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>MainMultilangConst.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Consts\SettingsMultilangConst.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>SettingsMultilangConst.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Consts\AboutMultilangConst.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>AboutMultilangConst.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Update="Props\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
|
@ -3,9 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32328.378
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sheas-Cealer", "Sheas-Cealer.csproj", "{662F787A-474F-41FD-B813-645CAA89E531}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sheas-Cealer", "Sheas-Cealer.csproj", "{662F787A-474F-41FD-B813-645CAA89E531}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{42491572-0050-4CDA-9189-DFC98BDBBF73} = {42491572-0050-4CDA-9189-DFC98BDBBF73}
|
||||
{76263DF7-E4E4-4846-8604-8CFCA7125E2F} = {76263DF7-E4E4-4846-8604-8CFCA7125E2F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sheas-Core", "D:\Git-Repository\Sheas-Core\Sheas-Core.csproj", "{42491572-0050-4CDA-9189-DFC98BDBBF73}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sheas-Core", "..\Sheas-Core\Sheas-Core.csproj", "{42491572-0050-4CDA-9189-DFC98BDBBF73}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ona-Core", "..\Ona-Core\Ona-Core.csproj", "{76263DF7-E4E4-4846-8604-8CFCA7125E2F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -21,11 +27,21 @@ Global
|
||||
{42491572-0050-4CDA-9189-DFC98BDBBF73}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42491572-0050-4CDA-9189-DFC98BDBBF73}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{42491572-0050-4CDA-9189-DFC98BDBBF73}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{76263DF7-E4E4-4846-8604-8CFCA7125E2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{76263DF7-E4E4-4846-8604-8CFCA7125E2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{76263DF7-E4E4-4846-8604-8CFCA7125E2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{76263DF7-E4E4-4846-8604-8CFCA7125E2F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
RESX_Rules = {"EnabledRules":["StringFormat","WhiteSpaceLead","WhiteSpaceTail","PunctuationLead"]}
|
||||
RESX_SortFileContentOnSave = True
|
||||
SolutionGuid = {33005A8D-2D3D-4101-AFF0-F68B29FE9B28}
|
||||
RESX_NeutralResourcesLanguage = en-US
|
||||
RESX_ConfirmAddLanguageFile = True
|
||||
RESX_AutoCreateNewLanguageFiles = True
|
||||
RESX_DuplicateKeyHandling = Fail
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
31
Utils/BorderThemeSetter.cs
Normal file
31
Utils/BorderThemeSetter.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Sheas_Cealer.Utils;
|
||||
|
||||
internal static partial class BorderThemeSetter
|
||||
{
|
||||
private const int DwmwaUseImmersiveDarkModeOld = 19;
|
||||
private const int DwmwaUseImmersiveDarkMode = 20;
|
||||
|
||||
[LibraryImport("dwmapi.dll")]
|
||||
private static partial void DwmGetWindowAttribute(nint hwnd, uint attr, out nint attrValue, uint attrSize);
|
||||
[LibraryImport("dwmapi.dll")]
|
||||
private static partial void DwmSetWindowAttribute(nint hwnd, uint attr, ref nint attrValue, uint attrSize);
|
||||
|
||||
internal static void SetBorderTheme(Window window, bool? isLightTheme)
|
||||
{
|
||||
nint isDarkTheme;
|
||||
nint desktopHwnd = nint.Zero;
|
||||
nint windowHwnd = new WindowInteropHelper(window).EnsureHandle();
|
||||
|
||||
if (isLightTheme.HasValue)
|
||||
isDarkTheme = !isLightTheme.Value ? 1 : 0;
|
||||
else
|
||||
DwmGetWindowAttribute(desktopHwnd, DwmwaUseImmersiveDarkMode, out 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)));
|
||||
}
|
||||
}
|
11
Utils/DnsFlusher.cs
Normal file
11
Utils/DnsFlusher.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Sheas_Cealer.Utils;
|
||||
|
||||
internal static partial class DnsFlusher
|
||||
{
|
||||
[LibraryImport("dnsapi.dll")]
|
||||
private static partial void DnsFlushResolverCache();
|
||||
|
||||
internal static void FlushDns() => DnsFlushResolverCache();
|
||||
}
|
31
Utils/ForegroundGenerator.cs
Normal file
31
Utils/ForegroundGenerator.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Sheas_Cealer.Utils;
|
||||
|
||||
internal static class ForegroundGenerator
|
||||
{
|
||||
internal static (Color?, Color) GetForeground(int red, int green, int blue)
|
||||
{
|
||||
double redComponent = red / 255.0, greenComponent = green / 255.0, blueComponent = blue / 255.0;
|
||||
|
||||
double luminance = 0.2126 * GammaCorrect(redComponent) + 0.7152 * GammaCorrect(greenComponent) + 0.0722 * GammaCorrect(blueComponent);
|
||||
|
||||
double blackContrast = (luminance + 0.05) / 0.05;
|
||||
double whiteContrast = 1.05 / (luminance + 0.05);
|
||||
|
||||
double hue = redComponent > greenComponent && redComponent > blueComponent ? 60 * ((greenComponent - blueComponent) / (redComponent - Math.Min(greenComponent, blueComponent)) + (greenComponent < blueComponent ? 6 : 0)) :
|
||||
greenComponent > blueComponent && greenComponent > redComponent ? 60 * ((blueComponent - redComponent) / (greenComponent - Math.Min(blueComponent, redComponent)) + 2) :
|
||||
blueComponent > redComponent && blueComponent > greenComponent ? 60 * ((redComponent - greenComponent) / (blueComponent - Math.Min(redComponent, greenComponent)) + 4) : 0;
|
||||
|
||||
double blueContrast = Math.Min(Math.Abs(hue - 206.57), 360 - Math.Abs(hue - 206.57));
|
||||
double redContrast = Math.Min(Math.Abs(hue - 4.11), 360 - Math.Abs(hue - 4.11));
|
||||
|
||||
return (blackContrast >= 5.5 && whiteContrast >= 2.5 ? null :
|
||||
blackContrast >= whiteContrast ? Colors.Black : Colors.White,
|
||||
blueContrast >= redContrast ? AboutConst.AccentBlueColor : AboutConst.AccentRedColor);
|
||||
}
|
||||
|
||||
private static double GammaCorrect(double component) => component <= 0.03928 ? component / 12.92 : Math.Pow((component + 0.055) / 1.055, 2.4);
|
||||
}
|
38
Utils/IconRemover.cs
Normal file
38
Utils/IconRemover.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Sheas_Cealer.Utils;
|
||||
|
||||
internal static partial class IconRemover
|
||||
{
|
||||
private const int GwlExStyle = -20;
|
||||
private const int WsExDlgModalFrame = 0x0001;
|
||||
private const int SwpNoSize = 0x0001;
|
||||
private const int SwpNoMove = 0x0002;
|
||||
private const int SwpNoZOrder = 0x0004;
|
||||
private const int SwpFrameChanged = 0x0020;
|
||||
private const uint WmSetIcon = 0x0080;
|
||||
|
||||
[LibraryImport("user32.dll", EntryPoint = "GetWindowLongW")]
|
||||
private static partial int GetWindowLong(nint hwnd, int index);
|
||||
[LibraryImport("user32.dll", EntryPoint = "SetWindowLongW")]
|
||||
private static partial void SetWindowLong(nint hwnd, int index, nint newStyle);
|
||||
[LibraryImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static partial void SetWindowPos(nint hwnd, nint hwndInsertAfter, int x, int y, int width, int height, uint flags);
|
||||
[LibraryImport("user32.dll", EntryPoint = "SendMessageW")]
|
||||
private static partial void SendMessage(nint hwnd, uint msg, nint wParam, nint lParam);
|
||||
|
||||
internal static void RemoveIcon(Window window)
|
||||
{
|
||||
nint hwnd = new WindowInteropHelper(window).Handle;
|
||||
|
||||
SetWindowLong(hwnd, GwlExStyle, GetWindowLong(hwnd, GwlExStyle) | WsExDlgModalFrame);
|
||||
|
||||
SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0, SwpNoMove | SwpNoSize | SwpNoZOrder | SwpFrameChanged);
|
||||
|
||||
SendMessage(hwnd, WmSetIcon, new(1), nint.Zero);
|
||||
SendMessage(hwnd, WmSetIcon, nint.Zero, nint.Zero);
|
||||
}
|
||||
}
|
35
Utils/NginxCleaner.cs
Normal file
35
Utils/NginxCleaner.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Sheas_Cealer.Consts;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sheas_Cealer.Utils;
|
||||
|
||||
internal static class NginxCleaner
|
||||
{
|
||||
internal static async Task Clean()
|
||||
{
|
||||
string hostsContent = await File.ReadAllTextAsync(MainConst.HostsConfPath);
|
||||
int hostsConfStartIndex = hostsContent.IndexOf(MainConst.HostsConfStartMarker, StringComparison.Ordinal);
|
||||
int hostsConfEndIndex = hostsContent.LastIndexOf(MainConst.HostsConfEndMarker, StringComparison.Ordinal);
|
||||
|
||||
if (hostsConfStartIndex != -1 && hostsConfEndIndex != -1)
|
||||
await File.WriteAllTextAsync(MainConst.HostsConfPath, hostsContent.Remove(hostsConfStartIndex, hostsConfEndIndex - hostsConfStartIndex + MainConst.HostsConfEndMarker.Length));
|
||||
|
||||
using X509Store certStore = new(StoreName.Root, StoreLocation.LocalMachine, OpenFlags.ReadWrite);
|
||||
|
||||
foreach (X509Certificate2 storedCert in certStore.Certificates)
|
||||
if (storedCert.Subject == MainConst.NginxRootCertSubjectName)
|
||||
while (true)
|
||||
try
|
||||
{
|
||||
certStore.Remove(storedCert);
|
||||
|
||||
break;
|
||||
}
|
||||
catch { }
|
||||
|
||||
certStore.Close();
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<Window x:Class="Sheas_Cealer.AboutWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Style="{DynamicResource CommonWindow}"
|
||||
WindowStartupLocation="CenterScreen" Height="120" Width="500" MinWidth="500" ResizeMode="NoResize" Loaded="AboutWin_Loaded" KeyDown="AboutWin_KeyDown">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1.1*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="DeveloperButton" Content="开发者: Space Time" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="5" Foreground="#FF2196F3" ToolTip="https://www.spacetimee.xyz" Click="AboutButton_Click" />
|
||||
<Button x:Name="UpdateButton" Content="版本号: ?.?.?" Grid.Row="1" Grid.Column="0" Margin="5" Foreground="#FF2196F3" ToolTip="https://spacetime.lanzouu.com/b017hp0lc" Click="AboutButton_Click" />
|
||||
<Button x:Name="EmailButton" Content="联系邮箱" Grid.Row="1" Grid.Column="1" Margin="5" ToolTip="Zeus6_6@163.com" />
|
||||
|
||||
<Button x:Name="HomePageButton" Content="使用文档" Grid.Row="0" Grid.Column="2" Margin="5" ToolTip="https://github.com/SpaceTimee/Sheas-Cealer/wiki/Sheas-Cealer-Instruction" Click="AboutButton_Click" />
|
||||
<Button x:Name="OpenSourceButton" Content="开源地址" Grid.Row="1" Grid.Column="2" Margin="5" ToolTip="https://github.com/SpaceTimee/Sheas-Cealer" Click="AboutButton_Click" />
|
||||
|
||||
<Button x:Name="PrivacyButton" Content="隐私政策" Grid.Row="0" Grid.Column="3" Margin="5" ToolTip="https://thoughts.teambition.com/share/6264eda98adeb10041b92fda#title=Sheas_Cealer_隐私政策" Click="AboutButton_Click" />
|
||||
<Button x:Name="AgreementButton" Content="使用协议" Grid.Row="1" Grid.Column="3" Margin="5" ToolTip="https://thoughts.teambition.com/share/6264edd78adeb10041b92fdb#title=Sheas_Cealer_使用协议" Click="AboutButton_Click" />
|
||||
</Grid>
|
||||
</Window>
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Sheas_Cealer
|
||||
{
|
||||
public partial class AboutWindow : Window
|
||||
{
|
||||
internal AboutWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
private void AboutWin_Loaded(object sender, RoutedEventArgs e) => UpdateButton.Content = "版本号: " + Assembly.GetExecutingAssembly().GetName().Version!.ToString()[0..^2];
|
||||
|
||||
private void AboutButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sender == UpdateButton)
|
||||
MessageBox.Show("密码: 3wnj");
|
||||
|
||||
ProcessStartInfo processStartInfo = new(sender == EmailButton ? "mailto:" : string.Empty + ((Button)sender).ToolTip) { UseShellExecute = true };
|
||||
Process.Start(processStartInfo);
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
|
||||
private void AboutWin_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<Window x:Class="Sheas_Cealer.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Style="{DynamicResource CommonWindow}"
|
||||
WindowStartupLocation="CenterScreen" SizeToContent="Height" ResizeMode="CanMinimize" Width="500" MinWidth="500" AllowDrop="True" Loaded="MainWin_Loaded" Closing="MainWin_Closing" KeyDown="MainWin_KeyDown" DragEnter="MainWin_DragEnter" Drop="MainWin_Drop">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="ShowBox" Text="(填入任意以 Chromium 为内核的浏览器的路径)" Foreground="#FFBFCDDB" Grid.Column="0" Margin="0,0,10,0" VerticalContentAlignment="Center" GotFocus="ShowBox_GotFocus" LostFocus="ShowBox_LostFocus" TextChanged="ShowBox_TextChanged" PreviewDragOver="MainWin_DragEnter" />
|
||||
<Button x:Name="ViewButton" Grid.Column="2" Content="浏览" Click="ViewButton_Click" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0,5,0,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button x:Name="ClashButton" Content="启动代理" Grid.Column="0" Margin="5,0,5,0" Click="ClashButton_Click" />
|
||||
<Button x:Name="OpenButton" Content="启动伪造" Grid.Column="1" Margin="5,0,5,0" IsDefault="True" IsEnabled="False" Click="OpenButton_Click" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" Margin="0,5,0,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button x:Name="ConfigButton" Content="代理规则" Grid.Column="0" Margin="5,0,5,0" Click="ConfigButton_Click" />
|
||||
<Button x:Name="HostButton" Content="伪造规则" Grid.Column="1" Margin="5,0,5,0" Click="HostButton_Click" />
|
||||
<Button x:Name="AboutButton" Content="关于项目" Grid.Column="2" Margin="5,0,5,0" Click="AboutButton_Click" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
@ -1,233 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using IWshRuntimeLibrary;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Sheas_Cealer
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private static string? CEALING_ARGUMENT;
|
||||
private static readonly FileSystemWatcher CEALING_HOST_WATCHER = new(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "Cealing-Host.json") { EnableRaisingEvents = true, NotifyFilter = NotifyFilters.LastWrite };
|
||||
private static readonly DispatcherTimer MONITOR_TIMER = new() { Interval = new TimeSpan(1000000) }; //0.1s
|
||||
|
||||
internal MainWindow(string[] args)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
try
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
MONITOR_TIMER.Tick += MONITOR_TIMER_Tick;
|
||||
MONITOR_TIMER.Start();
|
||||
|
||||
if (args.Length > 0)
|
||||
Dispatcher.Invoke(() => ShowBox.Text = args[0]);
|
||||
else if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.BrowserPath))
|
||||
Dispatcher.Invoke(() => ShowBox.Text = Properties.Settings.Default.BrowserPath);
|
||||
|
||||
CEALING_HOST_WATCHER.Changed += CEALING_HOST_WATCHER_Changed;
|
||||
CEALING_HOST_WATCHER_Changed(null!, null!);
|
||||
});
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); }
|
||||
}
|
||||
private void MainWin_Loaded(object sender, RoutedEventArgs e) => ShowBox.Focus();
|
||||
private void MainWin_Closing(object sender, System.ComponentModel.CancelEventArgs e) => Environment.Exit(0);
|
||||
|
||||
private void ShowBox_GotFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ShowBox.Foreground != Foreground)
|
||||
{
|
||||
//PlaceHold状态
|
||||
ShowBox.Text = string.Empty;
|
||||
ShowBox.Foreground = Foreground;
|
||||
}
|
||||
}
|
||||
private void ShowBox_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ShowBox.Text))
|
||||
{
|
||||
ShowBox.Text = "(填入任意以 Chromium 为内核的浏览器的路径)";
|
||||
ShowBox.Foreground = new SolidColorBrush(Color.FromRgb(191, 205, 219));
|
||||
}
|
||||
}
|
||||
private void ShowBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (OpenButton == null)
|
||||
return;
|
||||
|
||||
if (File.Exists(ShowBox.Text) && Path.GetFileName(ShowBox.Text).EndsWith(".exe"))
|
||||
{
|
||||
OpenButton.IsEnabled = true;
|
||||
|
||||
Properties.Settings.Default.BrowserPath = ShowBox.Text;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
else
|
||||
OpenButton.IsEnabled = false;
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
|
||||
private void MainWin_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
e.Effects = DragDropEffects.Link;
|
||||
else
|
||||
e.Effects = DragDropEffects.None;
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
private void MainWin_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
ShowBox.Text = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
|
||||
private void ViewButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenFileDialog openFileDialog = new() { Filter = "浏览器 (*.exe)|*.exe" };
|
||||
|
||||
if (openFileDialog.ShowDialog() == true)
|
||||
{
|
||||
ShowBox.Focus();
|
||||
ShowBox.Text = openFileDialog.FileName;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
|
||||
private void ClashButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
RegistryKey proxyKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true)!;
|
||||
if (ClashButton.Content.ToString() == "启动代理")
|
||||
{
|
||||
YamlStream configStream = new();
|
||||
YamlMappingNode configMap;
|
||||
try
|
||||
{
|
||||
configStream.Load(File.OpenText(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, @"config.yaml")));
|
||||
configMap = (YamlMappingNode)configStream.Documents[0].RootNode;
|
||||
}
|
||||
catch { throw new Exception("规则无法识别,请检查代理规则是否含有语法错误"); }
|
||||
|
||||
proxyKey.SetValue("ProxyEnable", 1);
|
||||
proxyKey.SetValue("ProxyServer", "127.0.0.1:" + configMap["mixed-port"]);
|
||||
|
||||
new Clash().ShellRun(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, "-d .");
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyKey.SetValue("ProxyEnable", 0);
|
||||
|
||||
foreach (Process clashProcess in Process.GetProcessesByName("Cealing-Clash"))
|
||||
clashProcess.Kill();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
private void OpenButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(CEALING_ARGUMENT))
|
||||
throw new Exception("规则无法识别,请检查伪造规则是否含有语法错误");
|
||||
if (MessageBox.Show("启动前将关闭所选浏览器的所有进程,是否继续?", string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes)
|
||||
return;
|
||||
|
||||
IWshShortcut uncealedBrowserShortcut = (IWshShortcut)new WshShell().CreateShortcut(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, @"Uncealed-Browser.lnk"));
|
||||
uncealedBrowserShortcut.TargetPath = ShowBox.Text;
|
||||
uncealedBrowserShortcut.Description = "Created By Sheas Cealer";
|
||||
uncealedBrowserShortcut.Save();
|
||||
|
||||
foreach (Process browserProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(ShowBox.Text)))
|
||||
{
|
||||
browserProcess.Kill();
|
||||
browserProcess.WaitForExit();
|
||||
}
|
||||
|
||||
new Cmd().ShellRun(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, CEALING_ARGUMENT);
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
|
||||
private void ConfigButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo processStartInfo = new(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, @"config.yaml")) { UseShellExecute = true };
|
||||
Process.Start(processStartInfo);
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
private void HostButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo processStartInfo = new(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, @"Cealing-Host.json")) { UseShellExecute = true };
|
||||
Process.Start(processStartInfo);
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); return; }
|
||||
}
|
||||
private void AboutButton_Click(object sender, RoutedEventArgs e) => new AboutWindow().ShowDialog();
|
||||
|
||||
private void MONITOR_TIMER_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
if (Process.GetProcessesByName("Cealing-Clash").Length == 0)
|
||||
ClashButton.Content = "启动代理";
|
||||
else
|
||||
ClashButton.Content = "停止代理";
|
||||
}
|
||||
|
||||
private void CEALING_HOST_WATCHER_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string hostRules = string.Empty, hostResolverRules = string.Empty;
|
||||
FileStream hostStream = new(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase!, @"Cealing-Host.json"), FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
|
||||
JArray hostJArray = JArray.Parse(new StreamReader(hostStream).ReadToEnd());
|
||||
|
||||
foreach (var hostJToken in hostJArray)
|
||||
{
|
||||
hostResolverRules += "MAP " + hostJToken[1]!.ToString() + " " + hostJToken[2]!.ToString() + ",";
|
||||
foreach (var hostName in hostJToken[0]!)
|
||||
hostRules += "MAP " + hostName.ToString() + " " + hostJToken[1] + ",";
|
||||
}
|
||||
|
||||
CEALING_ARGUMENT = @"/c @start .\""Uncealed-Browser.lnk"" --host-rules=""" + hostRules[0..^1] + @""" --host-resolver-rules=""" + hostResolverRules[0..^1] + @""" --test-type --ignore-certificate-errors";
|
||||
}
|
||||
catch { return; }
|
||||
}
|
||||
|
||||
private void MainWin_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.W)
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
69
Wins/AboutWin.xaml
Normal file
69
Wins/AboutWin.xaml
Normal file
@ -0,0 +1,69 @@
|
||||
<Window x:Class="Sheas_Cealer.Wins.AboutWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:consts="clr-namespace:Sheas_Cealer.Consts"
|
||||
xmlns:convs="clr-namespace:Sheas_Cealer.Convs"
|
||||
xmlns:preses="clr-namespace:Sheas_Cealer.Preses"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="NoResize" SizeToContent="Height" Width="500"
|
||||
d:DataContext="{d:DesignInstance preses:AboutPres}"
|
||||
Style="{DynamicResource CommonWindow}"
|
||||
SourceInitialized="AboutWin_SourceInitialized" Loaded="AboutWin_Loaded" KeyDown="AboutWin_KeyDown">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="5"
|
||||
d:Foreground="{Binding Source={x:Static consts:AboutConst.AccentBlueColor}, Converter={x:Static convs:AboutConv.AboutAccentButtonForegroundConv}}"
|
||||
Foreground="{Binding AccentForegroundColor, Converter={x:Static convs:AboutConv.AboutAccentButtonForegroundConv}}"
|
||||
Content="{x:Static consts:AboutConst.DeveloperButtonContent}"
|
||||
ToolTip="{x:Static consts:AboutConst.DeveloperButtonUrl}"
|
||||
Click="AboutButton_Click" />
|
||||
<Button Grid.Row="1" Grid.Column="0" Margin="5" d:Content="# # #: #.#.#"
|
||||
d:Foreground="{Binding Source={x:Static consts:AboutConst.AccentBlueColor}, Converter={x:Static convs:AboutConv.AboutAccentButtonForegroundConv}}"
|
||||
Foreground="{Binding AccentForegroundColor, Converter={x:Static convs:AboutConv.AboutAccentButtonForegroundConv}}"
|
||||
ToolTip="{x:Static consts:AboutConst.VersionButtonUrl}"
|
||||
Click="AboutButton_Click">
|
||||
<Button.Content>
|
||||
<MultiBinding Converter="{x:Static convs:AboutConv.AboutVersionButtonContentConv}">
|
||||
<Binding Source="{x:Static consts:AboutConst.VersionButtonLabelContent}" />
|
||||
<Binding Source="{x:Static consts:AboutConst.VersionButtonVersionContent}" />
|
||||
<Binding Path="IsSheasCealerUtd" />
|
||||
</MultiBinding>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="EmailButton"
|
||||
Grid.Row="1" Grid.Column="1" Margin="5"
|
||||
Content="{x:Static consts:AboutConst.EmailButtonContent}"
|
||||
ToolTip="{x:Static consts:AboutConst.EmailButtonUrl}"
|
||||
Click="AboutButton_Click" />
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="2" Margin="5"
|
||||
Content="{x:Static consts:AboutConst.DocumentationButtonContent}"
|
||||
ToolTip="{x:Static consts:AboutConst.DocumentationButtonUrl}"
|
||||
Click="AboutButton_Click" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Margin="5"
|
||||
Content="{x:Static consts:AboutConst.RepositoryButtonContent}"
|
||||
ToolTip="{x:Static consts:AboutConst.RepositoryButtonUrl}"
|
||||
Click="AboutButton_Click" />
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="3" Margin="5"
|
||||
Content="{x:Static consts:AboutConst.PolicyButtonContent}"
|
||||
ToolTip="{x:Static consts:AboutConst.PolicyButtonUrl}"
|
||||
Click="AboutButton_Click" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Margin="5"
|
||||
Content="{x:Static consts:AboutConst.AgreementButtonContent}"
|
||||
ToolTip="{x:Static consts:AboutConst.AgreementButtonUrl}"
|
||||
Click="AboutButton_Click" />
|
||||
</Grid>
|
||||
</Window>
|
71
Wins/AboutWin.xaml.cs
Normal file
71
Wins/AboutWin.xaml.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using Ona_Core;
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Cealer.Preses;
|
||||
using Sheas_Cealer.Utils;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Sheas_Cealer.Wins;
|
||||
|
||||
public partial class AboutWin : Window
|
||||
{
|
||||
private readonly AboutPres AboutPres;
|
||||
private readonly HttpClient AboutClient = new(new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator });
|
||||
|
||||
internal AboutWin()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DataContext = AboutPres = new();
|
||||
}
|
||||
private void AboutWin_SourceInitialized(object sender, EventArgs e)
|
||||
{
|
||||
IconRemover.RemoveIcon(this);
|
||||
BorderThemeSetter.SetBorderTheme(this, AboutPres.IsLightTheme);
|
||||
}
|
||||
private async void AboutWin_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
AboutClient.DefaultRequestHeaders.Add("User-Agent", AboutConst.ReleaseApiUserAgent);
|
||||
|
||||
JsonElement releaseInfoObject = JsonDocument.Parse(await Http.GetAsync<string>(AboutConst.ReleaseApiUrl, AboutClient)).RootElement;
|
||||
|
||||
AboutClient.DefaultRequestHeaders.Clear();
|
||||
|
||||
foreach (JsonProperty releaseInfoContent in releaseInfoObject.EnumerateObject())
|
||||
if (releaseInfoContent.Name == "name" && releaseInfoContent.Value.ToString() != AboutConst.VersionButtonVersionContent)
|
||||
AboutPres.IsSheasCealerUtd = false;
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
}
|
||||
|
||||
private void AboutButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Button senderButton = (Button)sender;
|
||||
|
||||
ProcessStartInfo processStartInfo = new(senderButton == EmailButton ? "mailto:" : string.Empty + senderButton.ToolTip) { UseShellExecute = true };
|
||||
|
||||
try { Process.Start(processStartInfo); }
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
processStartInfo.Verb = "RunAs";
|
||||
Process.Start(processStartInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void AboutWin_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
}
|
||||
}
|
222
Wins/MainWin.xaml
Normal file
222
Wins/MainWin.xaml
Normal file
@ -0,0 +1,222 @@
|
||||
<Window x:Class="Sheas_Cealer.Wins.MainWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:consts="clr-namespace:Sheas_Cealer.Consts"
|
||||
xmlns:convs="clr-namespace:Sheas_Cealer.Convs"
|
||||
xmlns:preses="clr-namespace:Sheas_Cealer.Preses"
|
||||
mc:Ignorable="d"
|
||||
AllowDrop="True"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize" SizeToContent="Height"
|
||||
d:DataContext="{d:DesignInstance preses:MainPres}"
|
||||
Style="{DynamicResource CommonWindow}"
|
||||
Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainWinWidthConv}}"
|
||||
SourceInitialized="MainWin_SourceInitialized" Loaded="MainWin_Loaded" Closing="MainWin_Closing" DragEnter="MainWin_DragEnter" Drop="MainWin_Drop" KeyDown="MainWin_KeyDown">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="0" Margin="5" d:Content="# # # #"
|
||||
Content="{Binding SettingsMode, Converter={x:Static convs:MainConv.MainSettingsModeButtonContentConv}}"
|
||||
ToolTip="{x:Static consts:MainConst.SettingsModeButtonToolTip}"
|
||||
Click="SettingsModeButton_Click" />
|
||||
<TextBox x:Name="SettingsBox"
|
||||
Grid.Column="1" Margin="5" VerticalContentAlignment="Center" md:HintAssist.IsFloating="True"
|
||||
AutomationProperties.Name="{Binding SettingsMode, Converter={x:Static convs:MainConv.MainSettingsBoxHintConv}}"
|
||||
md:HintAssist.Hint="{Binding SettingsMode, Converter={x:Static convs:MainConv.MainSettingsBoxHintConv}}"
|
||||
ToolTip="{Binding SettingsMode, Converter={x:Static convs:MainConv.MainSettingsBoxToolTipConv}}"
|
||||
TextChanged="SettingsBox_TextChanged" PreviewDragOver="MainWin_DragEnter">
|
||||
<TextBox.Text>
|
||||
<MultiBinding Mode="OneWay" UpdateSourceTrigger="PropertyChanged"
|
||||
Converter="{x:Static convs:MainConv.MainSettingsBoxTextConv}">
|
||||
<Binding Path="SettingsMode" />
|
||||
<Binding Path="BrowserPath" />
|
||||
<Binding Path="UpstreamUrl" />
|
||||
<Binding Path="ExtraArgs" />
|
||||
</MultiBinding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<Button Grid.Column="2" Margin="5" d:Content="# # # #"
|
||||
Content="{Binding SettingsMode, Converter={x:Static convs:MainConv.MainSettingsFunctionButtonContentConv}}"
|
||||
ToolTip="{x:Static consts:MainConst.SettingsFunctionButtonToolTip}"
|
||||
Click="SettingsFunctionButton_Click" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainProxyColumnWidthConv}}" />
|
||||
<ColumnDefinition Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainProxyColumnWidthConv}}" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button IsDefault="True"
|
||||
Grid.Column="0" Margin="5"
|
||||
Content="{x:Static consts:MainConst.BrowserButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.BrowserButtonToolTip}"
|
||||
Click="LaunchButton_Click" PreviewMouseDown="LaunchButton_PreviewMouseDown">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainBrowserButtonIsEnabledConv}">
|
||||
<Binding Path="BrowserPath" />
|
||||
<Binding Path="ExtraArgs" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
<Button x:Name="NginxButton"
|
||||
Grid.Column="1" Margin="5" d:Content="# # # #"
|
||||
Visibility="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainAdminControlVisibilityConv}}"
|
||||
Click="LaunchButton_Click" PreviewMouseDown="LaunchButton_PreviewMouseDown">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainNginxButtonIsEnabledConv}">
|
||||
<Binding Path="IsConginxExist" />
|
||||
<Binding Path="IsNginxExist" />
|
||||
<Binding Path="IsCoproxyIniting" />
|
||||
<Binding Path="IsNginxIniting" />
|
||||
<Binding Path="IsComihomoIniting" />
|
||||
<Binding Path="IsMihomoIniting" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
<Button.Content>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainNginxButtonContentConv}">
|
||||
<Binding Path="IsConginxRunning" />
|
||||
<Binding Path="IsNginxRunning" />
|
||||
<Binding Path="IsCoproxyIniting" />
|
||||
<Binding Path="IsNginxIniting" />
|
||||
</MultiBinding>
|
||||
</Button.Content>
|
||||
<Button.ToolTip>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainNginxButtonToolTipConv}">
|
||||
<Binding Path="IsConginxRunning" />
|
||||
<Binding Path="IsNginxRunning" />
|
||||
</MultiBinding>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
<Button x:Name="MihomoButton"
|
||||
Grid.Column="2" Margin="5" d:Content="# # # #"
|
||||
Visibility="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainAdminControlVisibilityConv}}"
|
||||
ToolTip="{Binding IsMihomoRunning, Converter={x:Static convs:MainConv.MainMihomoButtonToolTipConv}}"
|
||||
Click="LaunchButton_Click" PreviewMouseDown="LaunchButton_PreviewMouseDown">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainMihomoButtonIsEnabledConv}">
|
||||
<Binding Path="IsComihomoExist" />
|
||||
<Binding Path="IsMihomoExist" />
|
||||
<Binding Path="IsCoproxyIniting" />
|
||||
<Binding Path="IsComihomoIniting" />
|
||||
<Binding Path="IsMihomoIniting" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
<Button.Content>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainMihomoButtonContentConv}">
|
||||
<Binding Path="IsMihomoRunning" />
|
||||
<Binding Path="IsComihomoIniting" />
|
||||
<Binding Path="IsMihomoIniting" />
|
||||
<Binding Path="IsCoproxyIniting" />
|
||||
<Binding Path="IsCoproxyStopping" />
|
||||
</MultiBinding>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainProxyColumnWidthConv}}" />
|
||||
<ColumnDefinition Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainProxyColumnWidthConv}}" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="EditLocalHostButton"
|
||||
Grid.Column="0" Margin="5"
|
||||
Content="{x:Static consts:MainConst.EditLocalHostButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.EditLocalHostButtonToolTip}"
|
||||
Click="EditHostButton_Click" />
|
||||
<Button Grid.Column="1" Margin="5"
|
||||
Content="{x:Static consts:MainConst.EditUpstreamHostButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.EditUpstreamHostButtonToolTip}"
|
||||
Click="EditHostButton_Click" />
|
||||
<Button x:Name="EditNginxConfButton"
|
||||
Grid.Column="2" Margin="5"
|
||||
Visibility="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainAdminControlVisibilityConv}}"
|
||||
Content="{x:Static consts:MainConst.EditNginxConfButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.EditNginxConfButtonToolTip}"
|
||||
Click="EditConfButton_Click">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainNginxButtonIsEnabledConv}">
|
||||
<Binding Path="IsConginxExist" />
|
||||
<Binding Path="IsNginxExist" />
|
||||
<Binding Path="IsCoproxyIniting" />
|
||||
<Binding Path="IsNginxIniting" />
|
||||
<Binding Path="IsComihomoIniting" />
|
||||
<Binding Path="IsMihomoIniting" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
<Button Grid.Column="3" Margin="5"
|
||||
Visibility="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainAdminControlVisibilityConv}}"
|
||||
Content="{x:Static consts:MainConst.EditMihomoConfButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.EditMihomoConfButtonToolTip}"
|
||||
Click="EditConfButton_Click">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static convs:MainConv.MainMihomoButtonIsEnabledConv}">
|
||||
<Binding Path="IsComihomoExist" />
|
||||
<Binding Path="IsMihomoExist" />
|
||||
<Binding Path="IsCoproxyIniting" />
|
||||
<Binding Path="IsComihomoIniting" />
|
||||
<Binding Path="IsMihomoIniting" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid Grid.Row="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainProxyColumnWidthConv}}" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="0" Margin="5" d:Content="# # # # # #"
|
||||
IsEnabled="{Binding UpstreamUrl, Converter={x:Static convs:MainConv.MainUpdateHostButtonIsEnabledConv}}"
|
||||
Content="{Binding IsUpstreamHostUtd, Converter={x:Static convs:MainConv.MainUpdateHostButtonContentConv}}"
|
||||
ToolTip="{x:Static consts:MainConst.UpdateUpstreamHostButtonToolTip}"
|
||||
Click="UpdateUpstreamHostButton_Click" />
|
||||
<Button x:Name="EditHostsConfButton"
|
||||
Grid.Column="1" Margin="5"
|
||||
Visibility="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainAdminControlVisibilityConv}}"
|
||||
Content="{x:Static consts:MainConst.EditHostsConfButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.EditHostsConfButtonToolTip}"
|
||||
Click="EditConfButton_Click" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainProxyColumnWidthConv}}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="0" Margin="5"
|
||||
Content="{x:Static consts:MainConst.SettingsButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.SettingsButtonToolTip}"
|
||||
Click="SettingsButton_Click" />
|
||||
<Button Focusable="False"
|
||||
Grid.Column="1" Margin="5" d:Content="# # # #"
|
||||
Visibility="{Binding Source={x:Static consts:MainConst.IsAdmin}, Converter={x:Static convs:MainConv.MainAdminControlVisibilityConv}}"
|
||||
Content="{Binding IsFlashing, Converter={x:Static convs:MainConv.MainNoClickButtonContentConv}}"
|
||||
ToolTip="{Binding IsFlashing, Converter={x:Static convs:MainConv.MainNoClickButtonToolTipConv}}"
|
||||
Click="NoClickButton_Click" />
|
||||
<Button Grid.Column="2" Margin="5"
|
||||
Content="{x:Static consts:MainConst.AboutButtonContent}"
|
||||
ToolTip="{x:Static consts:MainConst.AboutButtonToolTip}"
|
||||
Click="AboutButton_Click" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
940
Wins/MainWin.xaml.cs
Normal file
940
Wins/MainWin.xaml.cs
Normal file
@ -0,0 +1,940 @@
|
||||
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.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Sheas_Cealer.Wins;
|
||||
|
||||
public partial class MainWin : Window
|
||||
{
|
||||
private readonly MainPres MainPres;
|
||||
private readonly HttpClient MainClient = new(new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator });
|
||||
private DispatcherTimer? HoldButtonTimer;
|
||||
private readonly DispatcherTimer ProxyTimer = new() { Interval = TimeSpan.FromSeconds(0.1) };
|
||||
private readonly FileSystemWatcher CealHostWatcher = new(Path.GetDirectoryName(MainConst.CealHostPath)!, Path.GetFileName(MainConst.CealHostPath)) { 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 SemaphoreSlim IsNginxLaunchingSemaphore = new(1);
|
||||
|
||||
private readonly SortedDictionary<string, List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>?> CealHostRulesDict = [];
|
||||
private string CealArgs = string.Empty;
|
||||
private NginxConfig? NginxConfs;
|
||||
private string? ExtraNginxConfs;
|
||||
private string? ComihomoConfs;
|
||||
private string? HostsComihomoConfs;
|
||||
private string? MihomoConfs;
|
||||
private string? ExtraMihomoConfs;
|
||||
|
||||
private int NginxHttpPort = 80;
|
||||
private int NginxHttpsPort = 443;
|
||||
private int MihomoMixedPort = 7880;
|
||||
|
||||
private int GameClickTime = 0;
|
||||
private int GameFlashInterval = 1000;
|
||||
|
||||
internal MainWin()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DataContext = MainPres = new();
|
||||
}
|
||||
private void MainWin_SourceInitialized(object sender, EventArgs e)
|
||||
{
|
||||
IconRemover.RemoveIcon(this);
|
||||
BorderThemeSetter.SetBorderTheme(this, MainPres.IsLightTheme);
|
||||
}
|
||||
private async void MainWin_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
ProxyTimer.Tick += ProxyTimer_Tick;
|
||||
CealHostWatcher.Changed += CealHostWatcher_Changed;
|
||||
NginxConfWatcher.Changed += NginxConfWatcher_Changed;
|
||||
MihomoConfWatcher.Changed += MihomoConfWatcher_Changed;
|
||||
|
||||
ProxyTimer.Start();
|
||||
|
||||
foreach (string cealHostPath in Directory.GetFiles(CealHostWatcher.Path, CealHostWatcher.Filter))
|
||||
CealHostWatcher_Changed(null!, new(new(), Path.GetDirectoryName(cealHostPath)!, Path.GetFileName(cealHostPath)));
|
||||
|
||||
if (MainConst.IsAdmin && !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, null!);
|
||||
});
|
||||
}
|
||||
private async void MainWin_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (MainPres.IsNginxIniting)
|
||||
await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs);
|
||||
if (MainPres.IsMihomoIniting)
|
||||
await File.WriteAllTextAsync(MainConst.MihomoConfPath, ExtraMihomoConfs);
|
||||
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
private void MainWin_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Link : DragDropEffects.None;
|
||||
e.Handled = true;
|
||||
}
|
||||
private void MainWin_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
MainPres.BrowserPath = (e.Data.GetData(DataFormats.FileDrop) as string[])?[0] ?? string.Empty;
|
||||
}
|
||||
|
||||
private void SettingsBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
switch (MainPres.SettingsMode)
|
||||
{
|
||||
case MainConst.SettingsMode.BrowserPathMode:
|
||||
MainPres.BrowserPath = SettingsBox.Text;
|
||||
return;
|
||||
case MainConst.SettingsMode.UpstreamUrlMode:
|
||||
MainPres.UpstreamUrl = SettingsBox.Text;
|
||||
return;
|
||||
case MainConst.SettingsMode.ExtraArgsMode:
|
||||
MainPres.ExtraArgs = SettingsBox.Text;
|
||||
return;
|
||||
}
|
||||
}
|
||||
private void SettingsModeButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MainPres.SettingsMode = MainPres.SettingsMode switch
|
||||
{
|
||||
MainConst.SettingsMode.BrowserPathMode => MainConst.SettingsMode.UpstreamUrlMode,
|
||||
MainConst.SettingsMode.UpstreamUrlMode => MainConst.SettingsMode.ExtraArgsMode,
|
||||
MainConst.SettingsMode.ExtraArgsMode => MainConst.SettingsMode.BrowserPathMode,
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
private void SettingsFunctionButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OpenFileDialog browserPathDialog = new() { Filter = $"{MainConst._BrowserPathDialogFilterFileType} (*.exe)|*.exe" };
|
||||
|
||||
switch (MainPres.SettingsMode)
|
||||
{
|
||||
case MainConst.SettingsMode.BrowserPathMode when browserPathDialog.ShowDialog().GetValueOrDefault():
|
||||
SettingsBox.Focus();
|
||||
MainPres.BrowserPath = browserPathDialog.FileName;
|
||||
return;
|
||||
case MainConst.SettingsMode.UpstreamUrlMode:
|
||||
MainPres.UpstreamUrl = MainConst.DefaultUpstreamUrl;
|
||||
return;
|
||||
case MainConst.SettingsMode.ExtraArgsMode:
|
||||
MainPres.ExtraArgs = string.Empty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchButton_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (HoldButtonTimer is { IsEnabled: false })
|
||||
return;
|
||||
|
||||
Button? senderButton = sender as Button;
|
||||
|
||||
if (senderButton == NginxButton)
|
||||
NginxButtonHoldTimer_Tick(null, EventArgs.Empty);
|
||||
else if (senderButton == MihomoButton)
|
||||
MihomoButtonHoldTimer_Tick(null, EventArgs.Empty);
|
||||
else
|
||||
BrowserButtonHoldTimer_Tick(sender == null, EventArgs.Empty);
|
||||
}
|
||||
private void LaunchButton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Button senderButton = (Button)sender;
|
||||
|
||||
HoldButtonTimer = new() { Interval = TimeSpan.FromSeconds(1) };
|
||||
HoldButtonTimer.Tick += senderButton == NginxButton ? NginxButtonHoldTimer_Tick : senderButton == MihomoButton ? MihomoButtonHoldTimer_Tick : BrowserButtonHoldTimer_Tick;
|
||||
HoldButtonTimer.Start();
|
||||
}
|
||||
private async void BrowserButtonHoldTimer_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
HoldButtonTimer?.Stop();
|
||||
|
||||
if ((CealHostRulesDict.ContainsValue(null) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) ||
|
||||
(sender is not true && MessageBox.Show(MainConst._KillBrowserProcessPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes))
|
||||
return;
|
||||
|
||||
foreach (Process browserProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainPres.BrowserPath)))
|
||||
{
|
||||
browserProcess.Kill();
|
||||
await browserProcess.WaitForExitAsync();
|
||||
}
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
new BrowserProc(MainPres.BrowserPath, sender is bool).Run(Path.GetDirectoryName(MainPres.BrowserPath)!, $"{CealArgs} {MainPres.ExtraArgs.Trim()}");
|
||||
});
|
||||
}
|
||||
private async void NginxButtonHoldTimer_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
HoldButtonTimer?.Stop();
|
||||
|
||||
if (!MainPres.IsConginxRunning && !MainPres.IsNginxRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
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) ||
|
||||
(sender != null && MessageBox.Show(MainConst._LaunchHostsNginxPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) ||
|
||||
(MessageBox.Show(MainConst._LaunchProxyPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) ||
|
||||
(MainPres.IsFlashing && MessageBox.Show(MainConst._LaunchNginxFlashingPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes))
|
||||
return;
|
||||
|
||||
if (!File.Exists(MainConst.NginxConfPath))
|
||||
await File.Create(MainConst.NginxConfPath).DisposeAsync();
|
||||
if (!Directory.Exists(MainConst.NginxLogsPath))
|
||||
Directory.CreateDirectory(MainConst.NginxLogsPath);
|
||||
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
|
||||
CertificateRequest rootCertRequest = new(MainConst.NginxRootCertSubjectName, certKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
|
||||
rootCertRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, false));
|
||||
|
||||
using X509Certificate2 rootCert = rootCertRequest.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(100));
|
||||
using X509Store certStore = new(StoreName.Root, StoreLocation.LocalMachine, OpenFlags.ReadWrite);
|
||||
|
||||
certStore.Add(rootCert);
|
||||
certStore.Close();
|
||||
#endregion Root Cert
|
||||
|
||||
#region Child Cert & Hosts
|
||||
CertificateRequest childCertRequest = new(MainConst.NginxChildCertSubjectName, certKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
SubjectAlternativeNameBuilder childCertSanBuilder = new();
|
||||
string hostsConfAppendContent = MainConst.HostsConfStartMarker;
|
||||
|
||||
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('*'))
|
||||
{
|
||||
childCertSanBuilder.AddDnsName($"*.{cealHostIncludeDomainWithoutWildcard}");
|
||||
|
||||
if (sender != null)
|
||||
hostsConfAppendContent += $"127.0.0.1 www.{cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}";
|
||||
|
||||
if (cealHostIncludeDomain.TrimStart('$').StartsWith("*."))
|
||||
continue;
|
||||
}
|
||||
|
||||
childCertSanBuilder.AddDnsName(cealHostIncludeDomainWithoutWildcard);
|
||||
|
||||
if (sender != null)
|
||||
hostsConfAppendContent += $"127.0.0.1 {cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}";
|
||||
}
|
||||
|
||||
childCertRequest.CertificateExtensions.Add(childCertSanBuilder.Build());
|
||||
|
||||
using X509Certificate2 childCert = childCertRequest.Create(rootCert, rootCert.NotBefore, rootCert.NotAfter, Guid.NewGuid().ToByteArray());
|
||||
|
||||
await File.WriteAllTextAsync(MainConst.NginxCertPath, childCert.ExportCertificatePem());
|
||||
await File.WriteAllTextAsync(MainConst.NginxKeyPath, certKey.ExportPkcs8PrivateKeyPem());
|
||||
|
||||
if (sender != null)
|
||||
{
|
||||
hostsConfAppendContent += MainConst.HostsConfEndMarker;
|
||||
|
||||
File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly);
|
||||
await File.AppendAllTextAsync(MainConst.HostsConfPath, hostsConfAppendContent);
|
||||
}
|
||||
#endregion Child Cert & Hosts
|
||||
|
||||
try
|
||||
{
|
||||
if (sender == null)
|
||||
MainPres.IsCoproxyIniting = true;
|
||||
else
|
||||
MainPres.IsNginxIniting = true;
|
||||
|
||||
NginxConfWatcher.EnableRaisingEvents = false;
|
||||
NginxConfs!.Save(MainConst.NginxConfPath);
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Http.GetAsync<HttpResponseMessage>($"https://localhost:{NginxHttpsPort}", MainClient);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
if (ex.InnerException is SocketException innerEx && innerEx.SocketErrorCode != SocketError.ConnectionRefused)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sender == null ? MainPres.IsConginxRunning : MainPres.IsNginxRunning)
|
||||
continue;
|
||||
|
||||
if (MessageBox.Show(MainConst._LaunchNginxErrorPrompt, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
Process.Start(new ProcessStartInfo(MainConst.NginxErrorLogsPath) { UseShellExecute = true });
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (sender == null)
|
||||
MihomoButtonHoldTimer_Tick(null, EventArgs.Empty);
|
||||
|
||||
DnsFlusher.FlushDns();
|
||||
}
|
||||
finally
|
||||
{
|
||||
await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs);
|
||||
NginxConfWatcher.EnableRaisingEvents = true;
|
||||
|
||||
if (sender != null)
|
||||
MainPres.IsNginxIniting = false;
|
||||
}
|
||||
}
|
||||
finally { IsNginxLaunchingSemaphore.Release(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isConginxRunning = MainPres.IsConginxRunning;
|
||||
|
||||
if (isConginxRunning)
|
||||
MainPres.IsCoproxyStopping = true;
|
||||
|
||||
foreach (Process nginxProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(isConginxRunning ? MainConst.ConginxPath : MainConst.NginxPath)))
|
||||
{
|
||||
nginxProcess.Exited += async (_, _) =>
|
||||
{
|
||||
await NginxCleaner.Clean();
|
||||
|
||||
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.IsComihomoRunning && !MainPres.IsMihomoRunning)
|
||||
{
|
||||
if (!MainPres.IsComihomoExist && !MainPres.IsMihomoExist)
|
||||
return;
|
||||
if (string.IsNullOrWhiteSpace(MihomoConfs))
|
||||
throw new(MainConst._MihomoConfErrorMsg);
|
||||
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
|
||||
{
|
||||
if (MainPres.IsComihomoExist)
|
||||
MainPres.IsComihomoIniting = true;
|
||||
else
|
||||
MainPres.IsMihomoIniting = true;
|
||||
|
||||
MihomoConfWatcher.EnableRaisingEvents = false;
|
||||
await File.WriteAllTextAsync(MainConst.MihomoConfPath, !MainPres.IsConginxRunning ? MihomoConfs :
|
||||
MainPres.IsComihomoExist ? HostsComihomoConfs : ComihomoConfs);
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Http.GetAsync<HttpResponseMessage>($"http://localhost:{MihomoMixedPort}", MainClient);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
if (ex.InnerException is SocketException innerEx && innerEx.SocketErrorCode != SocketError.ConnectionRefused)
|
||||
break;
|
||||
}
|
||||
|
||||
if (MainPres.IsComihomoExist ? MainPres.IsComihomoRunning : MainPres.IsMihomoRunning)
|
||||
continue;
|
||||
|
||||
MessageBox.Show(MainConst._LaunchMihomoErrorMsg);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await File.WriteAllTextAsync(MainConst.MihomoConfPath, ExtraMihomoConfs);
|
||||
MihomoConfWatcher.EnableRaisingEvents = true;
|
||||
|
||||
if (MainPres.IsCoproxyIniting)
|
||||
MainPres.IsCoproxyIniting = false;
|
||||
else if (MainPres.IsCoproxyStopping)
|
||||
MainPres.IsCoproxyStopping = false;
|
||||
|
||||
if (MainPres.IsComihomoExist)
|
||||
MainPres.IsComihomoIniting = false;
|
||||
else
|
||||
MainPres.IsMihomoIniting = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isComihomoRunning = MainPres.IsComihomoRunning;
|
||||
|
||||
foreach (Process mihomoProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(isComihomoRunning ? MainConst.ComihomoPath : MainConst.MihomoPath)))
|
||||
{
|
||||
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)
|
||||
{
|
||||
Button senderButton = (Button)sender;
|
||||
string cealHostPath = senderButton == EditLocalHostButton ? MainConst.LocalHostPath : MainConst.UpstreamHostPath;
|
||||
|
||||
if (!File.Exists(cealHostPath))
|
||||
await File.Create(cealHostPath).DisposeAsync();
|
||||
|
||||
try { Process.Start(new ProcessStartInfo(cealHostPath) { UseShellExecute = true }); }
|
||||
catch (UnauthorizedAccessException) { Process.Start(new ProcessStartInfo(cealHostPath) { UseShellExecute = true, Verb = "RunAs" }); }
|
||||
}
|
||||
private async void EditConfButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Button senderButton = (Button)sender;
|
||||
string confPath;
|
||||
|
||||
if (senderButton == EditHostsConfButton)
|
||||
{
|
||||
confPath = MainConst.HostsConfPath;
|
||||
|
||||
File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
confPath = senderButton == EditNginxConfButton ? MainConst.NginxConfPath : MainConst.MihomoConfPath;
|
||||
|
||||
if (!File.Exists(confPath))
|
||||
await File.Create(confPath).DisposeAsync();
|
||||
}
|
||||
|
||||
Process.Start(new ProcessStartInfo(confPath) { UseShellExecute = true });
|
||||
}
|
||||
private async void UpdateUpstreamHostButton_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(MainConst.UpstreamHostPath))
|
||||
await File.Create(MainConst.UpstreamHostPath).DisposeAsync();
|
||||
|
||||
string upstreamUpstreamHostUrl = (MainPres.UpstreamUrl.StartsWith("http://") || MainPres.UpstreamUrl.StartsWith("https://") ? string.Empty : "https://") + MainPres.UpstreamUrl;
|
||||
string upstreamUpstreamHostString = await Http.GetAsync<string>(upstreamUpstreamHostUrl, MainClient);
|
||||
string localUpstreamHostString = await File.ReadAllTextAsync(MainConst.UpstreamHostPath);
|
||||
|
||||
try { upstreamUpstreamHostString = Encoding.UTF8.GetString(Convert.FromBase64String(upstreamUpstreamHostString)); }
|
||||
catch { }
|
||||
|
||||
if (sender == null && (localUpstreamHostString != upstreamUpstreamHostString && localUpstreamHostString.ReplaceLineEndings() != upstreamUpstreamHostString.ReplaceLineEndings()))
|
||||
MainPres.IsUpstreamHostUtd = false;
|
||||
else if (sender != null)
|
||||
if (localUpstreamHostString == upstreamUpstreamHostString || localUpstreamHostString.ReplaceLineEndings() == upstreamUpstreamHostString.ReplaceLineEndings())
|
||||
{
|
||||
MainPres.IsUpstreamHostUtd = true;
|
||||
|
||||
MessageBox.Show(MainConst._UpstreamHostUtdMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxResult overrideOptionResult = MessageBox.Show(MainConst._OverrideUpstreamHostPrompt, string.Empty, MessageBoxButton.YesNoCancel);
|
||||
|
||||
if (overrideOptionResult == MessageBoxResult.Yes)
|
||||
{
|
||||
await File.WriteAllTextAsync(MainConst.UpstreamHostPath, upstreamUpstreamHostString);
|
||||
|
||||
MainPres.IsUpstreamHostUtd = true;
|
||||
|
||||
MessageBox.Show(MainConst._UpdateUpstreamHostSuccessMsg);
|
||||
}
|
||||
else if (overrideOptionResult == MessageBoxResult.No)
|
||||
try { Process.Start(new ProcessStartInfo(upstreamUpstreamHostUrl) { UseShellExecute = true }); }
|
||||
catch (UnauthorizedAccessException) { Process.Start(new ProcessStartInfo(upstreamUpstreamHostUrl) { UseShellExecute = true, Verb = "RunAs" }); }
|
||||
}
|
||||
}
|
||||
catch when (sender == null) { }
|
||||
}
|
||||
|
||||
private void SettingsButton_Click(object sender, RoutedEventArgs e) => new SettingsWin().ShowDialog();
|
||||
private async void NoClickButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (GameFlashInterval <= 10)
|
||||
{
|
||||
MessageBox.Show(MainConst._GameReviewEndingMsg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (++GameClickTime)
|
||||
{
|
||||
case 1:
|
||||
MessageBox.Show(MainConst._GameClickOnceMsg);
|
||||
return;
|
||||
case 2:
|
||||
MessageBox.Show(MainConst._GameClickTwiceMsg);
|
||||
return;
|
||||
case 3:
|
||||
MessageBox.Show(MainConst._GameClickThreeMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MainPres.IsFlashing)
|
||||
{
|
||||
MessageBox.Show(MainConst._GameStartMsg);
|
||||
MainPres.IsFlashing = true;
|
||||
NginxConfWatcher_Changed(null!, null!);
|
||||
|
||||
Random random = new();
|
||||
|
||||
while (GameFlashInterval > 10)
|
||||
{
|
||||
Left = random.Next(0, (int)(SystemParameters.PrimaryScreenWidth - ActualWidth));
|
||||
Top = random.Next(0, (int)(SystemParameters.PrimaryScreenHeight - ActualHeight));
|
||||
|
||||
PaletteHelper paletteHelper = new();
|
||||
Theme newTheme = paletteHelper.GetTheme();
|
||||
Color newPrimaryColor = Color.FromRgb((byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256));
|
||||
bool isLightTheme = random.Next(2) == 0;
|
||||
|
||||
newTheme.SetPrimaryColor(newPrimaryColor);
|
||||
newTheme.SetBaseTheme(isLightTheme ? BaseTheme.Light : BaseTheme.Dark);
|
||||
paletteHelper.SetTheme(newTheme);
|
||||
|
||||
foreach (Window currentWindow in Application.Current.Windows)
|
||||
BorderThemeSetter.SetBorderTheme(currentWindow, isLightTheme);
|
||||
|
||||
Style newButtonStyle = new(typeof(Button), Application.Current.Resources[typeof(Button)] as Style);
|
||||
(Color? newForegroundColor, Color newAccentForegroundColor) = ForegroundGenerator.GetForeground(newPrimaryColor.R, newPrimaryColor.G, newPrimaryColor.B);
|
||||
|
||||
newButtonStyle.Setters.Add(new Setter(ForegroundProperty, newForegroundColor.HasValue ? new SolidColorBrush(newForegroundColor.Value) : new DynamicResourceExtension("MaterialDesignBackground")));
|
||||
Application.Current.Resources[typeof(Button)] = newButtonStyle;
|
||||
|
||||
MainPres.AccentForegroundColor = newAccentForegroundColor;
|
||||
|
||||
if (GameFlashInterval > 100)
|
||||
GameFlashInterval += random.Next(1, 4);
|
||||
|
||||
await Task.Delay(GameFlashInterval);
|
||||
}
|
||||
|
||||
MainPres.IsFlashing = false;
|
||||
NginxConfWatcher_Changed(null!, null!);
|
||||
MessageBox.Show(MainConst._GameEndingMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (GameFlashInterval)
|
||||
{
|
||||
case > 250:
|
||||
GameFlashInterval -= 150;
|
||||
break;
|
||||
case > 100:
|
||||
GameFlashInterval = 100;
|
||||
break;
|
||||
case > 10:
|
||||
GameFlashInterval -= 30;
|
||||
break;
|
||||
}
|
||||
|
||||
if (GameFlashInterval > 10)
|
||||
MessageBox.Show($"{MainConst._GameGradeMsg} {GameFlashInterval}");
|
||||
}
|
||||
}
|
||||
private void AboutButton_Click(object sender, RoutedEventArgs e) => new AboutWin().ShowDialog();
|
||||
|
||||
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)
|
||||
{
|
||||
string cealHostName = MainConst.CealHostPrefixRegex().Replace(Path.GetFileNameWithoutExtension(e.Name!), string.Empty);
|
||||
|
||||
try
|
||||
{
|
||||
CealHostRulesDict[cealHostName] = [];
|
||||
|
||||
await using FileStream cealHostStream = new(e.FullPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
|
||||
|
||||
if (cealHostStream.Length == 0)
|
||||
return;
|
||||
|
||||
JsonDocumentOptions cealHostOptions = new() { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip };
|
||||
JsonElement cealHostArray = JsonDocument.Parse(cealHostStream, cealHostOptions).RootElement;
|
||||
|
||||
foreach (JsonElement cealHostRule in cealHostArray.EnumerateArray())
|
||||
{
|
||||
List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs = [];
|
||||
string? cealHostSni = cealHostRule[1].ValueKind == JsonValueKind.Null ? null :
|
||||
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();
|
||||
|
||||
foreach (JsonElement cealHostDomain in cealHostRule[0].EnumerateArray())
|
||||
{
|
||||
string[] cealHostDomainPair = cealHostDomain.ToString().Split('^', 2, StringSplitOptions.TrimEntries);
|
||||
|
||||
if (string.IsNullOrEmpty(cealHostDomainPair[0].TrimStart('#').TrimStart('$')))
|
||||
continue;
|
||||
|
||||
cealHostDomainPairs.Add((cealHostDomainPair[0], cealHostDomainPair.Length == 2 ? cealHostDomainPair[1] : string.Empty));
|
||||
}
|
||||
|
||||
if (cealHostDomainPairs.Count != 0)
|
||||
CealHostRulesDict[cealHostName]!.Add((cealHostDomainPairs, cealHostSni, cealHostIp));
|
||||
}
|
||||
}
|
||||
catch { CealHostRulesDict[cealHostName] = null; }
|
||||
finally
|
||||
{
|
||||
string hostRules = string.Empty;
|
||||
string hostResolverRules = string.Empty;
|
||||
int nullSniNum = 0;
|
||||
|
||||
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 ?? [])
|
||||
{
|
||||
string cealHostSniWithoutNull = cealHostSni ?? $"{cealHostRulesPair.Key}{(cealHostRulesPair.Value ?? []).Count + ++nullSniNum}";
|
||||
bool isValidCealHostDomainExist = false;
|
||||
|
||||
foreach ((string cealHostIncludeDomain, string cealHostExcludeDomain) in cealHostDomainPairs)
|
||||
{
|
||||
if (cealHostIncludeDomain.StartsWith('$'))
|
||||
continue;
|
||||
|
||||
hostRules += $"MAP {cealHostIncludeDomain.TrimStart('#')} {cealHostSniWithoutNull}," + (!string.IsNullOrWhiteSpace(cealHostExcludeDomain) ? $"EXCLUDE {cealHostExcludeDomain}," : string.Empty);
|
||||
isValidCealHostDomainExist = true;
|
||||
}
|
||||
|
||||
if (isValidCealHostDomainExist)
|
||||
hostResolverRules += $"MAP {cealHostSniWithoutNull} {cealHostIp},";
|
||||
}
|
||||
|
||||
CealArgs = @$"--host-rules=""{hostRules.TrimEnd(',')}"" --host-resolver-rules=""{hostResolverRules.TrimEnd(',')}"" --test-type --ignore-certificate-errors";
|
||||
|
||||
NginxConfWatcher_Changed(null!, null!);
|
||||
MihomoConfWatcher_Changed(null!, null!);
|
||||
}
|
||||
}
|
||||
private async void NginxConfWatcher_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
if (!MainConst.IsAdmin || (!MainPres.IsNginxExist && !MainPres.IsConginxExist))
|
||||
return;
|
||||
|
||||
if (!File.Exists(MainConst.NginxConfPath))
|
||||
await File.Create(MainConst.NginxConfPath).DisposeAsync();
|
||||
if (!Directory.Exists(MainConst.NginxLogsPath))
|
||||
Directory.CreateDirectory(MainConst.NginxLogsPath);
|
||||
if (!Directory.Exists(MainConst.NginxTempPath))
|
||||
Directory.CreateDirectory(MainConst.NginxTempPath);
|
||||
|
||||
NginxHttpPort = 80;
|
||||
NginxHttpsPort = 443;
|
||||
|
||||
foreach (IPEndPoint activeTcpListener in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners())
|
||||
if (activeTcpListener.Port == NginxHttpPort)
|
||||
NginxHttpPort++;
|
||||
else if (activeTcpListener.Port == NginxHttpsPort)
|
||||
NginxHttpsPort++;
|
||||
else if (activeTcpListener.Port > NginxHttpsPort)
|
||||
break;
|
||||
|
||||
await using FileStream nginxConfStream = new(MainConst.NginxConfPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
|
||||
NginxConfig extraNginxConfig = NginxConfig.Load(ExtraNginxConfs = new StreamReader(nginxConfStream).ReadToEnd());
|
||||
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:proxy_buffer_size", "14k")
|
||||
.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;
|
||||
|
||||
++serverIndex;
|
||||
|
||||
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 async void MihomoConfWatcher_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
if (!MainConst.IsAdmin || (!MainPres.IsMihomoExist && !MainPres.IsComihomoExist))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (!File.Exists(MainConst.MihomoConfPath))
|
||||
await File.Create(MainConst.MihomoConfPath).DisposeAsync();
|
||||
|
||||
MihomoMixedPort = 7880;
|
||||
|
||||
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()) ?? [];
|
||||
Dictionary<string, object> hostsMihomoConfDict = new DeserializerBuilder()
|
||||
.WithNamingConvention(HyphenatedNamingConvention.Instance)
|
||||
.IgnoreUnmatchedProperties()
|
||||
.Build()
|
||||
.Deserialize<Dictionary<string, object>>(ExtraMihomoConfs = await new StreamReader(mihomoConfStream).ReadToEndAsync()) ?? [];
|
||||
|
||||
mihomoConfDict["mixed-port"] = hostsMihomoConfDict["mixed-port"] = MihomoMixedPort;
|
||||
mihomoConfDict["tun"] = hostsMihomoConfDict["tun"] = new
|
||||
{
|
||||
enable = true,
|
||||
stack = "system",
|
||||
autoRoute = true,
|
||||
autoDetectInterface = true,
|
||||
dnsHijack = new[] { "any:53", "tcp://any:53" }
|
||||
};
|
||||
mihomoConfDict["dns"] = new
|
||||
{
|
||||
enable = true,
|
||||
listen = ":53",
|
||||
ipv6 = true,
|
||||
nameserver = MainConst.MihomoNameServers
|
||||
};
|
||||
hostsMihomoConfDict["dns"] = new
|
||||
{
|
||||
enable = true,
|
||||
listen = ":53",
|
||||
ipv6 = true
|
||||
};
|
||||
|
||||
MihomoConfs = new SerializerBuilder().WithNamingConvention(HyphenatedNamingConvention.Instance).Build().Serialize(mihomoConfDict);
|
||||
|
||||
Dictionary<string, string> 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 { ComihomoConfs = HostsComihomoConfs = MihomoConfs = string.Empty; }
|
||||
}
|
||||
private void MainWin_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyboardDevice.Modifiers != ModifierKeys.Control)
|
||||
return;
|
||||
|
||||
if (e.Key == Key.W)
|
||||
Application.Current.Shutdown();
|
||||
else if (e.Key == Key.H)
|
||||
{
|
||||
System.Windows.Forms.NotifyIcon notifyIcon = new() { Icon = System.Drawing.Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location), Text = MainConst.NotifyIconText, Visible = true };
|
||||
|
||||
notifyIcon.Click += (_, _) =>
|
||||
{
|
||||
Show();
|
||||
|
||||
notifyIcon.Dispose();
|
||||
};
|
||||
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
41
Wins/SettingsWin.xaml
Normal file
41
Wins/SettingsWin.xaml
Normal file
@ -0,0 +1,41 @@
|
||||
<Window x:Class="Sheas_Cealer.Wins.SettingsWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:consts="clr-namespace:Sheas_Cealer.Consts"
|
||||
xmlns:convs="clr-namespace:Sheas_Cealer.Convs"
|
||||
xmlns:preses="clr-namespace:Sheas_Cealer.Preses"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="NoResize" SizeToContent="Height" Width="500"
|
||||
d:DataContext="{d:DesignInstance preses:SettingsPres}"
|
||||
Style="{DynamicResource CommonWindow}"
|
||||
SourceInitialized="SettingsWin_SourceInitialized" KeyDown="SettingsWin_KeyDown">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Margin="5" d:Content="# # # #"
|
||||
Content="{Binding IsLightTheme, Converter={x:Static convs:SettingsConv.SettingsThemesButtonContentConv}}"
|
||||
ToolTip="{x:Static consts:SettingsConst.ThemesButtonToolTip}"
|
||||
Click="ThemesButton_Click" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Margin="5" d:Content="# # # #"
|
||||
Content="{Binding IsEnglishLang, Converter={x:Static convs:SettingsConv.SettingsLangsButtonContentConv}}"
|
||||
ToolTip="{x:Static consts:SettingsConst.LangsButtonToolTip}"
|
||||
Click="LangsButton_Click" />
|
||||
<Button Grid.Row="1" Grid.Column="0" Margin="5"
|
||||
Content="{x:Static consts:SettingsConst.ColorsButtonContent}"
|
||||
ToolTip="{x:Static consts:SettingsConst.ColorsButtonToolTip}"
|
||||
Click="ColorsButton_Click" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Margin="5" d:Content="# # # #"
|
||||
Content="{Binding IsLightWeight, Converter={x:Static convs:SettingsConv.SettingsWeightsButtonContentConv}}"
|
||||
ToolTip="{x:Static consts:SettingsConst.WeightsButtonToolTip}"
|
||||
Click="WeightsButton_Click" />
|
||||
</Grid>
|
||||
</Window>
|
65
Wins/SettingsWin.xaml.cs
Normal file
65
Wins/SettingsWin.xaml.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Sheas_Cealer.Consts;
|
||||
using Sheas_Cealer.Preses;
|
||||
using Sheas_Cealer.Props;
|
||||
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;
|
||||
|
||||
public partial class SettingsWin : Window
|
||||
{
|
||||
private readonly SettingsPres SettingsPres;
|
||||
|
||||
internal SettingsWin()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DataContext = SettingsPres = new();
|
||||
}
|
||||
private void SettingsWin_SourceInitialized(object sender, EventArgs e)
|
||||
{
|
||||
IconRemover.RemoveIcon(this);
|
||||
BorderThemeSetter.SetBorderTheme(this, SettingsPres.IsLightTheme);
|
||||
}
|
||||
|
||||
private void ThemesButton_Click(object sender, RoutedEventArgs e) => SettingsPres.IsLightTheme = SettingsPres.IsLightTheme.HasValue ? SettingsPres.IsLightTheme.Value ? null : true : false;
|
||||
private void LangsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SettingsPres.IsEnglishLang = SettingsPres.IsEnglishLang.HasValue ? SettingsPres.IsEnglishLang.Value ? null : true : false;
|
||||
|
||||
MessageBox.Show(SettingsConst._ChangeLangSuccessMsg);
|
||||
}
|
||||
private void ColorsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Random random = new();
|
||||
PaletteHelper paletteHelper = new();
|
||||
Theme newTheme = paletteHelper.GetTheme();
|
||||
Color newPrimaryColor = Color.FromRgb((byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256));
|
||||
|
||||
newTheme.SetPrimaryColor(newPrimaryColor);
|
||||
paletteHelper.SetTheme(newTheme);
|
||||
|
||||
Style newButtonStyle = new(typeof(Button), Application.Current.Resources[typeof(Button)] as Style);
|
||||
(Color? newForegroundColor, Color newAccentForegroundColor) = ForegroundGenerator.GetForeground(newPrimaryColor.R, newPrimaryColor.G, newPrimaryColor.B);
|
||||
|
||||
newButtonStyle.Setters.Add(new Setter(ForegroundProperty, newForegroundColor.HasValue ? new SolidColorBrush(newForegroundColor.Value) : new DynamicResourceExtension("MaterialDesignBackground")));
|
||||
Application.Current.Resources[typeof(Button)] = newButtonStyle;
|
||||
|
||||
SettingsPres.AccentForegroundColor = newAccentForegroundColor;
|
||||
|
||||
Settings.Default.PrimaryColor = System.Drawing.Color.FromArgb(newPrimaryColor.A, newPrimaryColor.R, newPrimaryColor.G, newPrimaryColor.B);
|
||||
Settings.Default.Save();
|
||||
}
|
||||
private void WeightsButton_Click(object sender, RoutedEventArgs e) => SettingsPres.IsLightWeight = SettingsPres.IsLightWeight.HasValue ? SettingsPres.IsLightWeight.Value ? null : true : false;
|
||||
|
||||
private void SettingsWin_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
}
|
||||
}
|
12
config.yaml
12
config.yaml
@ -1,12 +0,0 @@
|
||||
mixed-port: 7880
|
||||
allow-lan: true
|
||||
ipv6: true
|
||||
log-level: silent
|
||||
rules:
|
||||
- 'MATCH,DIRECT'
|
||||
|
||||
proxies:
|
||||
- name: Local
|
||||
type: socks5
|
||||
server: 127.0.0.1
|
||||
port: 1080
|
Loading…
Reference in New Issue
Block a user