Compare commits

..

6 Commits

Author SHA1 Message Date
2dust 47c509faf6 up 7.13.3 2025-07-27 10:59:23 +08:00
2dust 8704942209 Improve sudo password interaction experience 2025-07-27 10:56:58 +08:00
2dust e8cdc29bb5 Add sudo password verification success message prompt 2025-07-26 20:55:55 +08:00
DHR60 191a7a6574 Fixes Hysteria2 ports (#7649) 2025-07-26 15:07:07 +08:00
2dust ad5d21db5a Upgrade Downloader package 2025-07-20 15:06:08 +08:00
2dust 569e939492 Optimizing and improving code 2025-07-20 14:16:19 +08:00
39 changed files with 342 additions and 505 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>7.13.2</Version> <Version>7.13.3</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
+1 -1
View File
@@ -10,7 +10,7 @@
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.2" /> <PackageVersion Include="Avalonia.Diagnostics" Version="11.3.2" />
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.2" /> <PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.2" />
<PackageVersion Include="CliWrap" Version="3.9.0" /> <PackageVersion Include="CliWrap" Version="3.9.0" />
<PackageVersion Include="Downloader" Version="3.3.4" /> <PackageVersion Include="Downloader" Version="4.0.2" />
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" /> <PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" /> <PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" /> <PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
+3 -3
View File
@@ -26,7 +26,7 @@ public class DownloaderHelper
var downloadOpt = new DownloadConfiguration() var downloadOpt = new DownloadConfiguration()
{ {
Timeout = timeout * 1000, Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2, MaxTryAgainOnFailure = 2,
RequestConfiguration = RequestConfiguration =
{ {
Headers = headers, Headers = headers,
@@ -64,7 +64,7 @@ public class DownloaderHelper
var downloadOpt = new DownloadConfiguration() var downloadOpt = new DownloadConfiguration()
{ {
Timeout = timeout * 1000, Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2, MaxTryAgainOnFailure = 2,
RequestConfiguration = RequestConfiguration =
{ {
Timeout= timeout * 1000, Timeout= timeout * 1000,
@@ -135,7 +135,7 @@ public class DownloaderHelper
var downloadOpt = new DownloadConfiguration() var downloadOpt = new DownloadConfiguration()
{ {
Timeout = timeout * 1000, Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2, MaxTryAgainOnFailure = 2,
RequestConfiguration = RequestConfiguration =
{ {
Timeout= timeout * 1000, Timeout= timeout * 1000,
@@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis;
namespace ServiceLib.Common; namespace ServiceLib.Common;
public static class StringEx public static class Extension
{ {
public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value) public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value)
{ {
@@ -79,4 +79,9 @@ public static class StringEx
{ {
return int.TryParse(value, out var result) ? result : defaultValue; return int.TryParse(value, out var result) ? result : defaultValue;
} }
public static List<string> AppendEmpty(this IEnumerable<string> source)
{
return source.Concat(new[] { string.Empty }).ToList();
}
} }
+8
View File
@@ -323,6 +323,14 @@ public class Utils
return text.Replace(",", ",").Replace(Environment.NewLine, ","); return text.Replace(",", ",").Replace(Environment.NewLine, ",");
} }
public static List<string> GetEnumNames<TEnum>() where TEnum : Enum
{
return Enum.GetValues(typeof(TEnum))
.Cast<TEnum>()
.Select(e => e.ToString())
.ToList();
}
#endregion 转换函数 #endregion 转换函数
#region 数据检查 #region 数据检查
+14 -10
View File
@@ -9,6 +9,7 @@ public class CoreAdminHandler
private static readonly Lazy<CoreAdminHandler> _instance = new(() => new()); private static readonly Lazy<CoreAdminHandler> _instance = new(() => new());
public static CoreAdminHandler Instance => _instance.Value; public static CoreAdminHandler Instance => _instance.Value;
private Config _config; private Config _config;
private readonly string _sudoAccessText = "SUDO_ACCESS_VERIFIED";
private Action<bool, string>? _updateFunc; private Action<bool, string>? _updateFunc;
private int _linuxSudoPid = -1; private int _linuxSudoPid = -1;
@@ -50,27 +51,30 @@ public class CoreAdminHandler
} }
}; };
proc.OutputDataReceived += (sender, e) => var sudoVerified = false;
{ DataReceivedEventHandler dataHandler = (sender, e) =>
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.ErrorDataReceived += (sender, e) =>
{ {
if (e.Data.IsNotEmpty()) if (e.Data.IsNotEmpty())
{ {
if (!sudoVerified && e.Data.Contains(_sudoAccessText))
{
sudoVerified = true;
UpdateFunc(false, ResUI.SudoPwdVerfiedSuccessTip + Environment.NewLine);
return;
}
UpdateFunc(false, e.Data + Environment.NewLine); UpdateFunc(false, e.Data + Environment.NewLine);
} }
}; };
proc.OutputDataReceived += dataHandler;
proc.ErrorDataReceived += dataHandler;
proc.Start(); proc.Start();
proc.BeginOutputReadLine(); proc.BeginOutputReadLine();
proc.BeginErrorReadLine(); proc.BeginErrorReadLine();
await Task.Delay(10); await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(); await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
await Task.Delay(10); await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd); await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
@@ -115,7 +119,7 @@ public class CoreAdminHandler
} }
else else
{ {
sb.AppendLine($"sudo -S {cmdLine}"); sb.AppendLine($"sudo -S echo \"{_sudoAccessText}\" && sudo -S {cmdLine}");
} }
await File.WriteAllTextAsync(shFilePath, sb.ToString()); await File.WriteAllTextAsync(shFilePath, sb.ToString());
+3 -8
View File
@@ -280,20 +280,15 @@ public class CoreHandler
if (displayLog) if (displayLog)
{ {
proc.OutputDataReceived += (sender, e) => DataReceivedEventHandler dataHandler = (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.ErrorDataReceived += (sender, e) =>
{ {
if (e.Data.IsNotEmpty()) if (e.Data.IsNotEmpty())
{ {
UpdateFunc(false, e.Data + Environment.NewLine); UpdateFunc(false, e.Data + Environment.NewLine);
} }
}; };
proc.OutputDataReceived += dataHandler;
proc.ErrorDataReceived += dataHandler;
} }
proc.Start(); proc.Start();
@@ -24,7 +24,7 @@ public class Hysteria2Fmt : BaseFmt
item.Path = Utils.UrlDecode(query["obfs-password"] ?? ""); item.Path = Utils.UrlDecode(query["obfs-password"] ?? "");
item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false"; item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false";
item.Ports = Utils.UrlDecode(query["mport"] ?? "").Replace('-', ':'); item.Ports = Utils.UrlDecode(query["mport"] ?? "");
return item; return item;
} }
+19 -1
View File
@@ -2202,6 +2202,24 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Incorrect password, please try again. 的本地化字符串。
/// </summary>
public static string SudoIncorrectPasswordTip {
get {
return ResourceManager.GetString("SudoIncorrectPasswordTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Sudo password has been verified successfully, please ignore the incorrect password prompts! 的本地化字符串。
/// </summary>
public static string SudoPwdVerfiedSuccessTip {
get {
return ResourceManager.GetString("SudoPwdVerfiedSuccessTip", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Address 的本地化字符串。 /// 查找类似 Address 的本地化字符串。
/// </summary> /// </summary>
@@ -3193,7 +3211,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart. 的本地化字符串。 /// 查找类似 The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart. 的本地化字符串。
/// </summary> /// </summary>
public static string TbSettingsLinuxSudoPasswordTip { public static string TbSettingsLinuxSudoPasswordTip {
get { get {
+7 -1
View File
@@ -1318,7 +1318,7 @@
<value>رمز عبور sudo سیستم</value> <value>رمز عبور sudo سیستم</value>
</data> </data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve"> <data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>رمز عبوری که وارد کرده اید تایید نمی شود، بنابراین مطمئن شوید که آن را به درستی وارد کرده اید. اگر برنامه به دلیل ورودی نادرست به درستی کار نمی کند، لطفاً برنامه را مجدداً راه اندازی کنید. رمز عبور ذخیره نمی شود و پس از هر بار راه اندازی مجدد باید آن را دوباره وارد کنید.</value> <value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data> </data>
<data name="TransportHeaderTypeTip5" xml:space="preserve"> <data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*حالت xhttp</value> <value>*حالت xhttp</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve"> <data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value> <value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data> </data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root> </root>
+7 -1
View File
@@ -1318,7 +1318,7 @@
<value>Rendszer sudo jelszó</value> <value>Rendszer sudo jelszó</value>
</data> </data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve"> <data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.</value> <value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data> </data>
<data name="TransportHeaderTypeTip5" xml:space="preserve"> <data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp mód</value> <value>*xhttp mód</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve"> <data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value> <value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data> </data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root> </root>
+7 -1
View File
@@ -1318,7 +1318,7 @@
<value>System sudo password</value> <value>System sudo password</value>
</data> </data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve"> <data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.</value> <value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data> </data>
<data name="TransportHeaderTypeTip5" xml:space="preserve"> <data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp mode</value> <value>*xhttp mode</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve"> <data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value> <value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data> </data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root> </root>
+7 -1
View File
@@ -1318,7 +1318,7 @@
<value>Пароль sudo системы</value> <value>Пароль sudo системы</value>
</data> </data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve"> <data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>Введенный вами пароль не может быть подтвержден, поэтому убедитесь, что вы ввели его правильно. Если приложение не работает должным образом из-за неправильного ввода, то перезапустите его. Пароль не будет сохранен, и вам придется вводить его заново после каждого перезапуска</value> <value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data> </data>
<data name="TransportHeaderTypeTip5" xml:space="preserve"> <data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*XHTTP-режим</value> <value>*XHTTP-режим</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve"> <data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value> <value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data> </data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root> </root>
+7 -1
View File
@@ -1315,7 +1315,7 @@
<value>系统的 sudo 密码</value> <value>系统的 sudo 密码</value>
</data> </data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve"> <data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>输入的密码无法校验,所以请确保输入正确。如果因为输入错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value> <value>密码将调用命令行校验,如果因为校验错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
</data> </data>
<data name="TransportHeaderTypeTip5" xml:space="preserve"> <data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*XHTTP 模式</value> <value>*XHTTP 模式</value>
@@ -1392,4 +1392,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve"> <data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填写配置文件别名,请确保存在并唯一</value> <value>可以填写配置文件别名,请确保存在并唯一</value>
</data> </data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>sudo 密码已经验证成功,请忽略错误密码提示!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>密码错误,请重试。</value>
</data>
</root> </root>
+7 -1
View File
@@ -1315,7 +1315,7 @@
<value>系統的 sudo 密碼</value> <value>系統的 sudo 密碼</value>
</data> </data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve"> <data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>輸入的密碼無法校驗,所以請確保輸入正確。如果因為輸入錯誤導致無法正常運作時,請重新啟動本應用。 密碼不會儲存,每次重啟後都需要再次輸入。</value> <value>密碼將調用命令行校驗,如果因為校驗錯誤導致無法正常運行時,請重啟本應用。密碼不會存儲,每次重啟後都需要再次輸入。</value>
</data> </data>
<data name="TransportHeaderTypeTip5" xml:space="preserve"> <data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp 模式</value> <value>*xhttp 模式</value>
@@ -1392,4 +1392,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve"> <data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填寫設定檔別名,請確保存在並唯一</value> <value>可以填寫設定檔別名,請確保存在並唯一</value>
</data> </data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>sudo 密碼已經驗證成功,請忽略錯誤密碼提示!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>密碼錯誤,請重試。</value>
</data>
</root> </root>
@@ -706,12 +706,17 @@ public class CoreConfigSingboxService
outbound.up_mbps = _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null; outbound.up_mbps = _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null;
outbound.down_mbps = _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null; outbound.down_mbps = _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null;
if (node.Ports.IsNotEmpty()) if (node.Ports.IsNotEmpty() && (node.Ports.Contains(':') || node.Ports.Contains('-') || node.Ports.Contains(',')))
{ {
outbound.server_port = null; outbound.server_port = null;
outbound.server_ports = node.Ports.Split(',') outbound.server_ports = node.Ports.Split(',')
.Where(p => p.Trim().IsNotEmpty()) .Select(p => p.Trim())
.Select(p => p.Replace('-', ':')) .Where(p => p.IsNotEmpty())
.Select(p =>
{
var port = p.Replace('-', ':');
return port.Contains(':') ? port : $"{port}:{port}";
})
.ToList(); .ToList();
outbound.hop_interval = _config.HysteriaItem.HopInterval > 0 ? $"{_config.HysteriaItem.HopInterval}s" : null; outbound.hop_interval = _config.HysteriaItem.HopInterval > 0 ? $"{_config.HysteriaItem.HopInterval}s" : null;
} }
@@ -436,30 +436,34 @@ public class StatusBarViewModel : MyReactiveObject
private async Task DoEnableTun(bool c) private async Task DoEnableTun(bool c)
{ {
if (_config.TunModeItem.EnableTun != EnableTun) if (_config.TunModeItem.EnableTun == EnableTun)
{
return;
}
_config.TunModeItem.EnableTun = EnableTun;
if (EnableTun && AllowEnableTun() == false)
{ {
_config.TunModeItem.EnableTun = EnableTun;
// When running as a non-administrator, reboot to administrator mode // When running as a non-administrator, reboot to administrator mode
if (EnableTun && AllowEnableTun() == false) if (Utils.IsWindows())
{ {
if (Utils.IsWindows()) _config.TunModeItem.EnableTun = false;
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return;
}
else
{
bool? passwordResult = await _updateView?.Invoke(EViewAction.PasswordInput, null);
if (passwordResult == false)
{ {
_config.TunModeItem.EnableTun = false; _config.TunModeItem.EnableTun = false;
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return; return;
} }
else
{
if (await _updateView?.Invoke(EViewAction.PasswordInput, null) == false)
{
_config.TunModeItem.EnableTun = false;
return;
}
}
} }
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
} }
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
} }
private bool AllowEnableTun() private bool AllowEnableTun()
@@ -21,13 +21,7 @@ public partial class AddServer2Window : WindowBase<AddServer2ViewModel>
btnCancel.Click += (s, e) => this.Close(); btnCancel.Click += (s, e) => this.Close();
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler); ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType))) cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
{
if (it == ECoreType.v2rayN)
continue;
cmbCoreType.Items.Add(it.ToString());
}
cmbCoreType.Items.Add(string.Empty);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -26,41 +26,22 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler); ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
Global.CoreTypes.ForEach(it => cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
{ cmbNetwork.ItemsSource = Global.Networks;
cmbCoreType.Items.Add(it); cmbFingerprint.ItemsSource = Global.Fingerprints;
}); cmbFingerprint2.ItemsSource = Global.Fingerprints;
cmbCoreType.Items.Add(string.Empty); cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
cmbAlpn.ItemsSource = Global.Alpns;
cmbStreamSecurity.Items.Add(string.Empty); var lstStreamSecurity = new List<string>();
cmbStreamSecurity.Items.Add(Global.StreamSecurity); lstStreamSecurity.Add(string.Empty);
lstStreamSecurity.Add(Global.StreamSecurity);
Global.Networks.ForEach(it =>
{
cmbNetwork.Items.Add(it);
});
Global.Fingerprints.ForEach(it =>
{
cmbFingerprint.Items.Add(it);
cmbFingerprint2.Items.Add(it);
});
Global.AllowInsecure.ForEach(it =>
{
cmbAllowInsecure.Items.Add(it);
});
Global.Alpns.ForEach(it =>
{
cmbAlpn.Items.Add(it);
});
switch (profileItem.ConfigType) switch (profileItem.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
gridVMess.IsVisible = true; gridVMess.IsVisible = true;
Global.VmessSecurities.ForEach(it => cmbSecurity.ItemsSource = Global.VmessSecurities;
{
cmbSecurity.Items.Add(it);
});
if (profileItem.Security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.Security = Global.DefaultSecurity; profileItem.Security = Global.DefaultSecurity;
@@ -69,10 +50,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
gridSs.IsVisible = true; gridSs.IsVisible = true;
AppHandler.Instance.GetShadowsocksSecurities(profileItem).ForEach(it => cmbSecurity3.ItemsSource = AppHandler.Instance.GetShadowsocksSecurities(profileItem);
{
cmbSecurity3.Items.Add(it);
});
break; break;
case EConfigType.SOCKS: case EConfigType.SOCKS:
@@ -82,11 +60,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.VLESS: case EConfigType.VLESS:
gridVLESS.IsVisible = true; gridVLESS.IsVisible = true;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality); lstStreamSecurity.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it => cmbFlow5.ItemsSource = Global.Flows;
{
cmbFlow5.Items.Add(it);
});
if (profileItem.Security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.Security = Global.None; profileItem.Security = Global.None;
@@ -95,11 +70,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.Trojan: case EConfigType.Trojan:
gridTrojan.IsVisible = true; gridTrojan.IsVisible = true;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality); lstStreamSecurity.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it => cmbFlow6.ItemsSource = Global.Flows;
{
cmbFlow6.Items.Add(it);
});
break; break;
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
@@ -119,10 +91,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
cmbFingerprint.IsEnabled = false; cmbFingerprint.IsEnabled = false;
cmbFingerprint.SelectedValue = string.Empty; cmbFingerprint.SelectedValue = string.Empty;
Global.TuicCongestionControls.ForEach(it => cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
{
cmbHeaderType8.Items.Add(it);
});
break; break;
case EConfigType.WireGuard: case EConfigType.WireGuard:
@@ -134,6 +103,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
break; break;
} }
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
gridTlsMore.IsVisible = false; gridTlsMore.IsVisible = false;
@@ -272,44 +242,41 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
private void SetHeaderType() private void SetHeaderType()
{ {
cmbHeaderType.Items.Clear(); var lstHeaderType = new List<string>();
var network = cmbNetwork.SelectedItem.ToString(); var network = cmbNetwork.SelectedItem.ToString();
if (network.IsNullOrEmpty()) if (network.IsNullOrEmpty())
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0;
return; return;
} }
if (network == nameof(ETransport.tcp)) if (network == nameof(ETransport.tcp))
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
cmbHeaderType.Items.Add(Global.TcpHeaderHttp); lstHeaderType.Add(Global.TcpHeaderHttp);
} }
else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic)) else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic))
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
Global.KcpHeaderTypes.ForEach(it => lstHeaderType.AddRange(Global.KcpHeaderTypes);
{
cmbHeaderType.Items.Add(it);
});
} }
else if (network is nameof(ETransport.xhttp)) else if (network is nameof(ETransport.xhttp))
{ {
Global.XhttpMode.ForEach(it => lstHeaderType.AddRange(Global.XhttpMode);
{
cmbHeaderType.Items.Add(it);
});
} }
else if (network == nameof(ETransport.grpc)) else if (network == nameof(ETransport.grpc))
{ {
cmbHeaderType.Items.Add(Global.GrpcGunMode); lstHeaderType.Add(Global.GrpcGunMode);
cmbHeaderType.Items.Add(Global.GrpcMultiMode); lstHeaderType.Add(Global.GrpcMultiMode);
} }
else else
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
} }
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0; cmbHeaderType.SelectedIndex = 0;
} }
@@ -17,22 +17,10 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
btnCancel.Click += (s, e) => this.Close(); btnCancel.Click += (s, e) => this.Close();
ViewModel = new DNSSettingViewModel(UpdateViewHandler); ViewModel = new DNSSettingViewModel(UpdateViewHandler);
Global.DomainStrategy4Freedoms.ForEach(it => cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
{ cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainStrategy4Freedom.Items.Add(it); cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
}); cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
Global.SingboxDomainStrategy4Out.ForEach(it =>
{
cmbdomainStrategy4Out.Items.Add(it);
});
Global.DomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress.Items.Add(it);
});
Global.SingboxDomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress2.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -135,7 +135,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
} }
}); });
if (Utils.IsWindows()) if (Utils.IsWindows())
{ {
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}"; this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
@@ -19,87 +19,39 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
ViewModel = new OptionSettingViewModel(UpdateViewHandler); ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged; clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
Global.destOverrideProtocols.ForEach(it => clbdestOverride.ItemsSource = Global.destOverrideProtocols;
{
clbdestOverride.Items.Add(it);
});
_config.Inbound.First().DestOverride?.ForEach(it => _config.Inbound.First().DestOverride?.ForEach(it =>
{ {
clbdestOverride.SelectedItems.Add(it); clbdestOverride.SelectedItems.Add(it);
}); });
Global.IEProxyProtocols.ForEach(it =>
{
cmbsystemProxyAdvancedProtocol.Items.Add(it);
});
Global.LogLevels.ForEach(it =>
{
cmbloglevel.Items.Add(it);
});
Global.Fingerprints.ForEach(it =>
{
cmbdefFingerprint.Items.Add(it);
});
Global.UserAgent.ForEach(it =>
{
cmbdefUserAgent.Items.Add(it);
});
Global.SingboxMuxs.ForEach(it =>
{
cmbmux4SboxProtocol.Items.Add(it);
});
Global.TunMtus.ForEach(it => cmbsystemProxyAdvancedProtocol.ItemsSource = Global.IEProxyProtocols;
{ cmbloglevel.ItemsSource = Global.LogLevels;
cmbMtu.Items.Add(it); cmbdefFingerprint.ItemsSource = Global.Fingerprints;
}); cmbdefUserAgent.ItemsSource = Global.UserAgent;
Global.TunStacks.ForEach(it => cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
{ cmbMtu.ItemsSource = Global.TunMtus;
cmbStack.Items.Add(it); cmbStack.ItemsSource = Global.TunStacks;
});
Global.CoreTypes.ForEach(it =>
{
cmbCoreType1.Items.Add(it);
cmbCoreType2.Items.Add(it);
cmbCoreType3.Items.Add(it);
cmbCoreType4.Items.Add(it);
cmbCoreType5.Items.Add(it);
cmbCoreType6.Items.Add(it);
cmbCoreType9.Items.Add(it);
});
for (var i = 2; i <= 8; i++) cmbCoreType1.ItemsSource = Global.CoreTypes;
{ cmbCoreType2.ItemsSource = Global.CoreTypes;
cmbMixedConcurrencyCount.Items.Add(i); cmbCoreType3.ItemsSource = Global.CoreTypes;
} cmbCoreType4.ItemsSource = Global.CoreTypes;
for (var i = 2; i <= 6; i++) cmbCoreType5.ItemsSource = Global.CoreTypes;
{ cmbCoreType6.ItemsSource = Global.CoreTypes;
cmbSpeedTestTimeout.Items.Add(i * 5); cmbCoreType9.ItemsSource = Global.CoreTypes;
}
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList();
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
cmbSpeedTestUrl.ItemsSource = Global.SpeedTestUrls; cmbSpeedTestUrl.ItemsSource = Global.SpeedTestUrls;
cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls; cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls;
cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls; cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls;
cmbGetFilesSourceUrl.ItemsSource = Global.GeoFilesSources;
cmbSrsFilesSourceUrl.ItemsSource = Global.SingboxRulesetSources;
cmbRoutingRulesSourceUrl.ItemsSource = Global.RoutingRulesSources;
cmbIPAPIUrl.ItemsSource = Global.IPAPIUrls;
Global.GeoFilesSources.ForEach(it => cmbMainGirdOrientation.ItemsSource = Utils.GetEnumNames<EGirdOrientation>();
{
cmbGetFilesSourceUrl.Items.Add(it);
});
Global.SingboxRulesetSources.ForEach(it =>
{
cmbSrsFilesSourceUrl.Items.Add(it);
});
Global.RoutingRulesSources.ForEach(it =>
{
cmbRoutingRulesSourceUrl.Items.Add(it);
});
Global.IPAPIUrls.ForEach(it =>
{
cmbIPAPIUrl.Items.Add(it);
});
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
{
cmbMainGirdOrientation.Items.Add(it.ToString());
}
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -25,18 +25,9 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler); ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
cmbOutboundTag.ItemsSource = Global.OutboundTags; cmbOutboundTag.ItemsSource = Global.OutboundTags;
Global.RuleProtocols.ForEach(it => clbProtocol.ItemsSource = Global.RuleProtocols;
{ clbInboundTag.ItemsSource = Global.InboundTags;
clbProtocol.Items.Add(it); cmbNetwork.ItemsSource = Global.RuleNetworks;
});
Global.InboundTags.ForEach(it =>
{
clbInboundTag.Items.Add(it);
});
Global.RuleNetworks.ForEach(it =>
{
cmbNetwork.Items.Add(it);
});
if (!rulesItem.Id.IsNullOrEmpty()) if (!rulesItem.Id.IsNullOrEmpty())
{ {
@@ -30,15 +30,9 @@ public partial class RoutingRuleSettingWindow : WindowBase<RoutingRuleSettingVie
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync; btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync;
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler); ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
Global.DomainStrategies.ForEach(it =>
{ cmbdomainStrategy.ItemsSource = Global.DomainStrategies.AppendEmpty();
cmbdomainStrategy.Items.Add(it); cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
});
cmbdomainStrategy.Items.Add(string.Empty);
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -26,18 +26,9 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
ViewModel = new RoutingSettingViewModel(UpdateViewHandler); ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
Global.DomainStrategies.ForEach(it => cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
{ cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
cmbdomainStrategy.Items.Add(it); cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
});
Global.DomainMatchers.ForEach(it =>
{
cmbdomainMatcher.Items.Add(it);
});
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -104,13 +104,15 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
{ {
var dialog = new SudoPasswordInputView(); var dialog = new SudoPasswordInputView();
var obj = await DialogHost.Show(dialog); var obj = await DialogHost.Show(dialog);
if (obj == null)
var password = obj?.ToString();
if (password.IsNullOrEmpty())
{ {
togEnableTun.IsChecked = false; togEnableTun.IsChecked = false;
return false; return false;
} }
AppHandler.Instance.LinuxSudoPwd = obj.ToString() ?? string.Empty; AppHandler.Instance.LinuxSudoPwd = password;
return true; return true;
} }
@@ -22,10 +22,7 @@ public partial class SubEditWindow : WindowBase<SubEditViewModel>
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler); ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
Global.SubConvertTargets.ForEach(it => cmbConvertTarget.ItemsSource = Global.SubConvertTargets;
{
cmbConvertTarget.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -1,5 +1,6 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Threading; using Avalonia.Threading;
using CliWrap.Buffered;
using DialogHostAvalonia; using DialogHostAvalonia;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;
@@ -12,22 +13,71 @@ public partial class SudoPasswordInputView : UserControl
this.Loaded += (s, e) => txtPassword.Focus(); this.Loaded += (s, e) => txtPassword.Focus();
btnSave.Click += (_, _) => btnSave.Click += async (_, _) => await SavePasswordAsync();
{
if (string.IsNullOrEmpty(txtPassword.Text))
{
txtPassword.Focus();
return;
}
Dispatcher.UIThread.Post(() =>
{
DialogHost.Close(null, txtPassword.Text);
});
};
btnCancel.Click += (_, _) => btnCancel.Click += (_, _) =>
{ {
DialogHost.Close(null); DialogHost.Close(null);
}; };
} }
private async Task SavePasswordAsync()
{
if (txtPassword.Text.IsNullOrEmpty())
{
txtPassword.Focus();
return;
}
var password = txtPassword.Text;
btnSave.IsEnabled = false;
try
{
// Verify if the password is correct
if (await CheckSudoPasswordAsync(password))
{
// Password verification successful, return password and close dialog
await Dispatcher.UIThread.InvokeAsync(() =>
{
DialogHost.Close(null, password);
});
}
else
{
// Password verification failed, display error and let user try again
NoticeHandler.Instance.Enqueue(ResUI.SudoIncorrectPasswordTip);
txtPassword.Focus();
}
}
catch (Exception ex)
{
Logging.SaveLog("SudoPassword", ex);
}
finally
{
btnSave.IsEnabled = true;
}
}
private async Task<bool> CheckSudoPasswordAsync(string password)
{
try
{
// Use sudo -S echo command to verify password
var arg = new List<string>() { "-c", "sudo -S echo SUDO_CHECK" };
var result = await CliWrap.Cli
.Wrap(Global.LinuxBash)
.WithArguments(arg)
.WithStandardInputPipe(CliWrap.PipeSource.FromString(password))
.ExecuteBufferedAsync();
return result.ExitCode == 0;
}
catch (Exception ex)
{
Logging.SaveLog("CheckSudoPassword", ex);
return false;
}
}
} }
@@ -16,20 +16,9 @@ public partial class ThemeSettingView : ReactiveUserControl<ThemeSettingViewMode
InitializeComponent(); InitializeComponent();
ViewModel = new ThemeSettingViewModel(); ViewModel = new ThemeSettingViewModel();
foreach (ETheme it in Enum.GetValues(typeof(ETheme))) cmbCurrentTheme.ItemsSource = Utils.GetEnumNames<ETheme>();
{ cmbCurrentFontSize.ItemsSource = Enumerable.Range(Global.MinFontSize, 11).ToList();
cmbCurrentTheme.Items.Add(it.ToString()); cmbCurrentLanguage.ItemsSource = Global.Languages;
}
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
{
cmbCurrentFontSize.Items.Add(i);
}
Global.Languages.ForEach(it =>
{
cmbCurrentLanguage.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
+1 -7
View File
@@ -14,13 +14,7 @@ public partial class AddServer2Window
this.Loaded += Window_Loaded; this.Loaded += Window_Loaded;
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler); ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType))) cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
{
if (it == ECoreType.v2rayN)
continue;
cmbCoreType.Items.Add(it.ToString());
}
cmbCoreType.Items.Add(string.Empty);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
+30 -63
View File
@@ -20,41 +20,22 @@ public partial class AddServerWindow
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler); ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
Global.CoreTypes.ForEach(it => cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
{ cmbNetwork.ItemsSource = Global.Networks;
cmbCoreType.Items.Add(it); cmbFingerprint.ItemsSource = Global.Fingerprints;
}); cmbFingerprint2.ItemsSource = Global.Fingerprints;
cmbCoreType.Items.Add(string.Empty); cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
cmbAlpn.ItemsSource = Global.Alpns;
cmbStreamSecurity.Items.Add(string.Empty); var lstStreamSecurity = new List<string>();
cmbStreamSecurity.Items.Add(Global.StreamSecurity); lstStreamSecurity.Add(string.Empty);
lstStreamSecurity.Add(Global.StreamSecurity);
Global.Networks.ForEach(it =>
{
cmbNetwork.Items.Add(it);
});
Global.Fingerprints.ForEach(it =>
{
cmbFingerprint.Items.Add(it);
cmbFingerprint2.Items.Add(it);
});
Global.AllowInsecure.ForEach(it =>
{
cmbAllowInsecure.Items.Add(it);
});
Global.Alpns.ForEach(it =>
{
cmbAlpn.Items.Add(it);
});
switch (profileItem.ConfigType) switch (profileItem.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
gridVMess.Visibility = Visibility.Visible; gridVMess.Visibility = Visibility.Visible;
Global.VmessSecurities.ForEach(it => cmbSecurity.ItemsSource = Global.VmessSecurities;
{
cmbSecurity.Items.Add(it);
});
if (profileItem.Security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.Security = Global.DefaultSecurity; profileItem.Security = Global.DefaultSecurity;
@@ -63,10 +44,7 @@ public partial class AddServerWindow
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
gridSs.Visibility = Visibility.Visible; gridSs.Visibility = Visibility.Visible;
AppHandler.Instance.GetShadowsocksSecurities(profileItem).ForEach(it => cmbSecurity3.ItemsSource = AppHandler.Instance.GetShadowsocksSecurities(profileItem);
{
cmbSecurity3.Items.Add(it);
});
break; break;
case EConfigType.SOCKS: case EConfigType.SOCKS:
@@ -76,11 +54,8 @@ public partial class AddServerWindow
case EConfigType.VLESS: case EConfigType.VLESS:
gridVLESS.Visibility = Visibility.Visible; gridVLESS.Visibility = Visibility.Visible;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality); lstStreamSecurity.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it => cmbFlow5.ItemsSource = Global.Flows;
{
cmbFlow5.Items.Add(it);
});
if (profileItem.Security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.Security = Global.None; profileItem.Security = Global.None;
@@ -89,11 +64,8 @@ public partial class AddServerWindow
case EConfigType.Trojan: case EConfigType.Trojan:
gridTrojan.Visibility = Visibility.Visible; gridTrojan.Visibility = Visibility.Visible;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality); lstStreamSecurity.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it => cmbFlow6.ItemsSource = Global.Flows;
{
cmbFlow6.Items.Add(it);
});
break; break;
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
@@ -113,10 +85,7 @@ public partial class AddServerWindow
cmbFingerprint.IsEnabled = false; cmbFingerprint.IsEnabled = false;
cmbFingerprint.Text = string.Empty; cmbFingerprint.Text = string.Empty;
Global.TuicCongestionControls.ForEach(it => cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
{
cmbHeaderType8.Items.Add(it);
});
break; break;
case EConfigType.WireGuard: case EConfigType.WireGuard:
@@ -128,6 +97,7 @@ public partial class AddServerWindow
break; break;
} }
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
gridTlsMore.Visibility = Visibility.Hidden; gridTlsMore.Visibility = Visibility.Hidden;
@@ -267,44 +237,41 @@ public partial class AddServerWindow
private void SetHeaderType() private void SetHeaderType()
{ {
cmbHeaderType.Items.Clear(); var lstHeaderType = new List<string>();
var network = cmbNetwork.SelectedItem.ToString(); var network = cmbNetwork.SelectedItem.ToString();
if (network.IsNullOrEmpty()) if (network.IsNullOrEmpty())
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0;
return; return;
} }
if (network == nameof(ETransport.tcp)) if (network == nameof(ETransport.tcp))
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
cmbHeaderType.Items.Add(Global.TcpHeaderHttp); lstHeaderType.Add(Global.TcpHeaderHttp);
} }
else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic)) else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic))
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
Global.KcpHeaderTypes.ForEach(it => lstHeaderType.AddRange(Global.KcpHeaderTypes);
{
cmbHeaderType.Items.Add(it);
});
} }
else if (network is nameof(ETransport.xhttp)) else if (network is nameof(ETransport.xhttp))
{ {
Global.XhttpMode.ForEach(it => lstHeaderType.AddRange(Global.XhttpMode);
{
cmbHeaderType.Items.Add(it);
});
} }
else if (network == nameof(ETransport.grpc)) else if (network == nameof(ETransport.grpc))
{ {
cmbHeaderType.Items.Add(Global.GrpcGunMode); lstHeaderType.Add(Global.GrpcGunMode);
cmbHeaderType.Items.Add(Global.GrpcMultiMode); lstHeaderType.Add(Global.GrpcMultiMode);
} }
else else
{ {
cmbHeaderType.Items.Add(Global.None); lstHeaderType.Add(Global.None);
} }
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0; cmbHeaderType.SelectedIndex = 0;
} }
+4 -16
View File
@@ -17,22 +17,10 @@ public partial class DNSSettingWindow
ViewModel = new DNSSettingViewModel(UpdateViewHandler); ViewModel = new DNSSettingViewModel(UpdateViewHandler);
Global.DomainStrategy4Freedoms.ForEach(it => cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
{ cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainStrategy4Freedom.Items.Add(it); cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
}); cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
Global.SingboxDomainStrategy4Out.ForEach(it =>
{
cmbdomainStrategy4Out.Items.Add(it);
});
Global.DomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress.Items.Add(it);
});
Global.SingboxDomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress2.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
+1 -4
View File
@@ -26,10 +26,7 @@ public partial class MsgView
menuMsgViewCopyAll.Click += menuMsgViewCopyAll_Click; menuMsgViewCopyAll.Click += menuMsgViewCopyAll_Click;
menuMsgViewClear.Click += menuMsgViewClear_Click; menuMsgViewClear.Click += menuMsgViewClear_Click;
Global.PresetMsgFilters.ForEach(it => cmbMsgFilter.ItemsSource = Global.PresetMsgFilters;
{
cmbMsgFilter.Items.Add(it);
});
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
+28 -84
View File
@@ -21,94 +21,39 @@ public partial class OptionSettingWindow
ViewModel = new OptionSettingViewModel(UpdateViewHandler); ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged; clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
Global.destOverrideProtocols.ForEach(it => clbdestOverride.ItemsSource = Global.destOverrideProtocols;
{
clbdestOverride.Items.Add(it);
});
_config.Inbound.First().DestOverride?.ForEach(it => _config.Inbound.First().DestOverride?.ForEach(it =>
{ {
clbdestOverride.SelectedItems.Add(it); clbdestOverride.SelectedItems.Add(it);
}); });
Global.IEProxyProtocols.ForEach(it =>
{
cmbsystemProxyAdvancedProtocol.Items.Add(it);
});
Global.LogLevels.ForEach(it =>
{
cmbloglevel.Items.Add(it);
});
Global.Fingerprints.ForEach(it =>
{
cmbdefFingerprint.Items.Add(it);
});
Global.UserAgent.ForEach(it =>
{
cmbdefUserAgent.Items.Add(it);
});
Global.SingboxMuxs.ForEach(it =>
{
cmbmux4SboxProtocol.Items.Add(it);
});
Global.TunMtus.ForEach(it => cmbsystemProxyAdvancedProtocol.ItemsSource = Global.IEProxyProtocols;
{ cmbloglevel.ItemsSource = Global.LogLevels;
cmbMtu.Items.Add(it); cmbdefFingerprint.ItemsSource = Global.Fingerprints;
}); cmbdefUserAgent.ItemsSource = Global.UserAgent;
Global.TunStacks.ForEach(it => cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
{ cmbMtu.ItemsSource = Global.TunMtus;
cmbStack.Items.Add(it); cmbStack.ItemsSource = Global.TunStacks;
});
Global.CoreTypes.ForEach(it =>
{
cmbCoreType1.Items.Add(it);
cmbCoreType2.Items.Add(it);
cmbCoreType3.Items.Add(it);
cmbCoreType4.Items.Add(it);
cmbCoreType5.Items.Add(it);
cmbCoreType6.Items.Add(it);
cmbCoreType9.Items.Add(it);
});
for (var i = 2; i <= 8; i++) cmbCoreType1.ItemsSource = Global.CoreTypes;
{ cmbCoreType2.ItemsSource = Global.CoreTypes;
cmbMixedConcurrencyCount.Items.Add(i); cmbCoreType3.ItemsSource = Global.CoreTypes;
} cmbCoreType4.ItemsSource = Global.CoreTypes;
for (var i = 2; i <= 6; i++) cmbCoreType5.ItemsSource = Global.CoreTypes;
{ cmbCoreType6.ItemsSource = Global.CoreTypes;
cmbSpeedTestTimeout.Items.Add(i * 5); cmbCoreType9.ItemsSource = Global.CoreTypes;
}
Global.SpeedTestUrls.ForEach(it => cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList();
{ cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
cmbSpeedTestUrl.Items.Add(it); cmbSpeedTestUrl.ItemsSource = Global.SpeedTestUrls;
}); cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls;
Global.SpeedPingTestUrls.ForEach(it => cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls;
{ cmbGetFilesSourceUrl.ItemsSource = Global.GeoFilesSources;
cmbSpeedPingTestUrl.Items.Add(it); cmbSrsFilesSourceUrl.ItemsSource = Global.SingboxRulesetSources;
}); cmbRoutingRulesSourceUrl.ItemsSource = Global.RoutingRulesSources;
Global.SubConvertUrls.ForEach(it => cmbIPAPIUrl.ItemsSource = Global.IPAPIUrls;
{
cmbSubConvertUrl.Items.Add(it); cmbMainGirdOrientation.ItemsSource = Utils.GetEnumNames<EGirdOrientation>();
});
Global.GeoFilesSources.ForEach(it =>
{
cmbGetFilesSourceUrl.Items.Add(it);
});
Global.SingboxRulesetSources.ForEach(it =>
{
cmbSrsFilesSourceUrl.Items.Add(it);
});
Global.RoutingRulesSources.ForEach(it =>
{
cmbRoutingRulesSourceUrl.Items.Add(it);
});
Global.IPAPIUrls.ForEach(it =>
{
cmbIPAPIUrl.Items.Add(it);
});
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
{
cmbMainGirdOrientation.Items.Add(it.ToString());
}
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -209,8 +154,7 @@ public partial class OptionSettingWindow
private async Task InitSettingFont() private async Task InitSettingFont()
{ {
var lstFonts = await GetFonts(Utils.GetFontsPath()); var lstFonts = await GetFonts(Utils.GetFontsPath());
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); }); cmbcurrentFontFamily.ItemsSource = lstFonts.AppendEmpty();
cmbcurrentFontFamily.Items.Add(string.Empty);
} }
private async Task<List<string>> GetFonts(string path) private async Task<List<string>> GetFonts(string path)
@@ -17,22 +17,10 @@ public partial class RoutingRuleDetailsWindow
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler); ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
Global.OutboundTags.ForEach(it => cmbOutboundTag.ItemsSource = Global.OutboundTags;
{ clbProtocol.ItemsSource = Global.RuleProtocols;
cmbOutboundTag.Items.Add(it); clbInboundTag.ItemsSource = Global.InboundTags;
}); cmbNetwork.ItemsSource = Global.RuleNetworks;
Global.RuleProtocols.ForEach(it =>
{
clbProtocol.Items.Add(it);
});
Global.InboundTags.ForEach(it =>
{
clbInboundTag.Items.Add(it);
});
Global.RuleNetworks.ForEach(it =>
{
cmbNetwork.Items.Add(it);
});
if (!rulesItem.Id.IsNullOrEmpty()) if (!rulesItem.Id.IsNullOrEmpty())
{ {
@@ -21,15 +21,9 @@ public partial class RoutingRuleSettingWindow
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_Click; btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_Click;
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler); ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
Global.DomainStrategies.ForEach(it =>
{ cmbdomainStrategy.ItemsSource = Global.DomainStrategies.AppendEmpty();
cmbdomainStrategy.Items.Add(it); cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
});
cmbdomainStrategy.Items.Add(string.Empty);
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -21,18 +21,9 @@ public partial class RoutingSettingWindow
ViewModel = new RoutingSettingViewModel(UpdateViewHandler); ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
Global.DomainStrategies.ForEach(it => cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
{ cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
cmbdomainStrategy.Items.Add(it); cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
});
Global.DomainMatchers.ForEach(it =>
{
cmbdomainMatcher.Items.Add(it);
});
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
+1 -4
View File
@@ -15,10 +15,7 @@ public partial class SubEditWindow
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler); ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
Global.SubConvertTargets.ForEach(it => cmbConvertTarget.ItemsSource = Global.SubConvertTargets;
{
cmbConvertTarget.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
+3 -15
View File
@@ -13,22 +13,10 @@ public partial class ThemeSettingView
{ {
InitializeComponent(); InitializeComponent();
ViewModel = new ThemeSettingViewModel(); ViewModel = new ThemeSettingViewModel();
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
{
if ((int)it > 2)
continue;
cmbCurrentTheme.Items.Add(it.ToString());
}
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++) cmbCurrentTheme.ItemsSource = Utils.GetEnumNames<ETheme>().Take(3).ToList();
{ cmbCurrentFontSize.ItemsSource = Enumerable.Range(Global.MinFontSize, 11).ToList();
cmbCurrentFontSize.Items.Add(i.ToString()); cmbCurrentLanguage.ItemsSource = Global.Languages;
}
Global.Languages.ForEach(it =>
{
cmbCurrentLanguage.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {