Compare commits

..

11 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
2dust
6a17c539d1 up 7.13.2 2025-07-18 20:07:10 +08:00
2dust
f8a4f946e4 Fixed the issue of missing files when updating GeoFiles
https://github.com/2dust/v2rayN/issues/7585
2025-07-18 19:56:18 +08:00
trojan-uma
0715fa85ce 改进 zh-Hans 描述 (#7579)
* 统一 zh-Hans 文字描述的括号

* 改进描述
2025-07-16 20:35:09 +08:00
2dust
1360051f0c Improve and optimize 2025-07-15 20:17:01 +08:00
2dust
42c4f9a6c6 Bug fix
https://github.com/2dust/v2rayN/issues/7582
2025-07-15 18:37:10 +08:00
43 changed files with 376 additions and 528 deletions

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>7.13.1</Version>
<Version>7.13.3</Version>
</PropertyGroup>
<PropertyGroup>

View File

@@ -10,7 +10,7 @@
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.2" />
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.2" />
<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="MaterialDesignThemes" Version="5.2.1" />
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
@@ -27,4 +27,4 @@
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
</ItemGroup>
</Project>
</Project>

View File

@@ -26,7 +26,7 @@ public class DownloaderHelper
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
MaxTryAgainOnFailure = 2,
RequestConfiguration =
{
Headers = headers,
@@ -64,7 +64,7 @@ public class DownloaderHelper
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
MaxTryAgainOnFailure = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,
@@ -135,7 +135,7 @@ public class DownloaderHelper
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
MaxTryAgainOnFailure = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,

View File

@@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis;
namespace ServiceLib.Common;
public static class StringEx
public static class Extension
{
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;
}
public static List<string> AppendEmpty(this IEnumerable<string> source)
{
return source.Concat(new[] { string.Empty }).ToList();
}
}

View File

@@ -323,6 +323,14 @@ public class Utils
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
#region

View File

@@ -528,5 +528,12 @@ public class Global
@""
];
public static readonly List<string> OutboundTags =
[
ProxyTag,
DirectTag,
BlockTag
];
#endregion const
}

View File

@@ -9,6 +9,7 @@ public class CoreAdminHandler
private static readonly Lazy<CoreAdminHandler> _instance = new(() => new());
public static CoreAdminHandler Instance => _instance.Value;
private Config _config;
private readonly string _sudoAccessText = "SUDO_ACCESS_VERIFIED";
private Action<bool, string>? _updateFunc;
private int _linuxSudoPid = -1;
@@ -50,27 +51,30 @@ public class CoreAdminHandler
}
};
proc.OutputDataReceived += (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.ErrorDataReceived += (sender, e) =>
var sudoVerified = false;
DataReceivedEventHandler dataHandler = (sender, e) =>
{
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);
}
};
proc.OutputDataReceived += dataHandler;
proc.ErrorDataReceived += dataHandler;
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync();
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
@@ -115,7 +119,7 @@ public class CoreAdminHandler
}
else
{
sb.AppendLine($"sudo -S {cmdLine}");
sb.AppendLine($"sudo -S echo \"{_sudoAccessText}\" && sudo -S {cmdLine}");
}
await File.WriteAllTextAsync(shFilePath, sb.ToString());

View File

@@ -280,20 +280,15 @@ public class CoreHandler
if (displayLog)
{
proc.OutputDataReceived += (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.ErrorDataReceived += (sender, e) =>
DataReceivedEventHandler dataHandler = (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.OutputDataReceived += dataHandler;
proc.ErrorDataReceived += dataHandler;
}
proc.Start();

View File

@@ -24,7 +24,7 @@ public class Hysteria2Fmt : BaseFmt
item.Path = Utils.UrlDecode(query["obfs-password"] ?? "");
item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false";
item.Ports = Utils.UrlDecode(query["mport"] ?? "").Replace('-', ':');
item.Ports = Utils.UrlDecode(query["mport"] ?? "");
return item;
}

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>
/// 查找类似 Address 的本地化字符串。
/// </summary>
@@ -3193,7 +3211,7 @@ namespace ServiceLib.Resx {
}
/// <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>
public static string TbSettingsLinuxSudoPasswordTip {
get {

View File

@@ -1318,7 +1318,7 @@
<value>رمز عبور sudo سیستم</value>
</data>
<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 name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*حالت xhttp</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</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>

View File

@@ -1318,7 +1318,7 @@
<value>Rendszer sudo jelszó</value>
</data>
<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 name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp mód</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</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>

View File

@@ -1318,7 +1318,7 @@
<value>System sudo password</value>
</data>
<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 name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp mode</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</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>

View File

@@ -1318,7 +1318,7 @@
<value>Пароль sudo системы</value>
</data>
<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 name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*XHTTP-режим</value>
@@ -1395,4 +1395,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</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>

View File

@@ -703,7 +703,7 @@
<value>例外:对于下列字符开头的地址,不使用代理配置文件。使用分号 (;) 分隔。</value>
</data>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>显示实时速度需重启</value>
<value>显示实时速度 (需重启)</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>去重时保留序号较小的项</value>
@@ -739,7 +739,7 @@
<value>开机启动 (可能会不成功)</value>
</data>
<data name="TbSettingsStatistics" xml:space="preserve">
<value>启用流量统计需重启</value>
<value>启用流量统计 (需重启)</value>
</data>
<data name="TbSettingsSubConvert" xml:space="preserve">
<value>订阅转换网址 (可选)</value>
@@ -886,7 +886,7 @@
<value>仅限路由 (routeOnly)</value>
</data>
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
<value>请勿将代理服务器用于本地Intranet地址</value>
<value>请勿将代理服务器用于本地 (Intranet) 地址</value>
</data>
<data name="menuMixedTestServer" xml:space="preserve">
<value>一键多线程测试延迟和速度 (Ctrl+E)</value>
@@ -919,7 +919,7 @@
<value>移至订阅分组</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>启用配置文件拖放排序需重启</value>
<value>启用配置文件拖放排序 (需重启)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>自动刷新</value>
@@ -946,10 +946,10 @@
<value>仅对 tcp/http、ws 协议生效</value>
</data>
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
<value>当前字体需重启</value>
<value>当前字体 (需重启)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>拷贝字体 TTF/TTC 文件到目录 guiFonts重启设置</value>
<value>拷贝字体 TTF/TTC 文件到目录 guiFonts重启生效</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>Pac 端口 = +3Xray API 端口 = +4mihomo API 端口 = +5</value>
@@ -979,10 +979,10 @@
<value>SpiderX</value>
</data>
<data name="TbSettingsEnableHWA" xml:space="preserve">
<value>启用硬件加速需重启</value>
<value>启用硬件加速 (需重启)</value>
</data>
<data name="SpeedtestingWait" xml:space="preserve">
<value>等待测试中按 ESC 终止...</value>
<value>等待测试中 (按 ESC 终止)...</value>
</data>
<data name="TipDisplayLog" xml:space="preserve">
<value>当有异常断流时请关闭</value>
@@ -1075,7 +1075,7 @@
<value>Reserved (2,3,4)</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>Address (Ipv4,Ipv6)</value>
<value>Address (IPv4,IPv6)</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>混淆密码 (obfs password)</value>
@@ -1105,10 +1105,10 @@
<value>使用 Xray 且非 Tun 模式启用,和分组前置代理冲突</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>启用分片Fragment</value>
<value>启用分片 (Fragment)</value>
</data>
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
<value>启用 sing-box规则集文件的缓存文件</value>
<value>启用 sing-box (规则集文件) 的缓存文件</value>
</data>
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
<value>自定义 sing-box rule-set</value>
@@ -1201,7 +1201,7 @@
<value>Outbound 默认解析策略</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>主界面布局方向需重启</value>
<value>主界面布局方向 (需重启)</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Outbound 域名解析地址</value>
@@ -1303,7 +1303,7 @@
<value>请不要使用不安全的 HTTP 协议订阅地址</value>
</data>
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
<value>安装字体到系统中,选择或填入字体名称,重启设置</value>
<value>安装字体到系统中,选择或填入字体名称,重启生效</value>
</data>
<data name="menuExitTips" xml:space="preserve">
<value>是否确定退出?</value>
@@ -1315,10 +1315,10 @@
<value>系统的 sudo 密码</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>输入的密码无法校验,所以请确保输入正确。如果因为输入错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
<value>密码将调用命令行校验,如果因为校验错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp 模式</value>
<value>*XHTTP 模式</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>XHTTP Extra 原始 JSON格式 { XHTTPObject }</value>
@@ -1339,7 +1339,7 @@
<value>开启第二个本地监听端口</value>
</data>
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks本地端口socks2第二个本地端口socks3局域网端口</value>
<value>Socks本地端口Socks2第二个本地端口Socks3局域网端口</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>主题</value>
@@ -1372,13 +1372,13 @@
<value>多配置文件随机 Xray</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>多配置文件负载均衡  Xray</value>
<value>多配置文件负载均衡 Xray</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>多配置文件最低延迟  Xray</value>
<value>多配置文件最低延迟 Xray</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>多配置文件最稳定  Xray</value>
<value>多配置文件最稳定 Xray</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>多配置文件最低延迟 sing-box</value>
@@ -1392,4 +1392,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填写配置文件别名,请确保存在并唯一</value>
</data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>sudo 密码已经验证成功,请忽略错误密码提示!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>密码错误,请重试。</value>
</data>
</root>

View File

@@ -1315,7 +1315,7 @@
<value>系統的 sudo 密碼</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>輸入的密碼無法校驗,所以請確保輸入正確。如果因為輸入錯誤導致無法正常運時,請重新啟動本應用。 密碼不會存,每次重啟後都需要再次輸入。</value>
<value>密碼將調用命令行校驗,如果因為校驗錯誤導致無法正常運時,請重本應用。密碼不會存,每次重啟後都需要再次輸入。</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp 模式</value>
@@ -1392,4 +1392,10 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填寫設定檔別名,請確保存在並唯一</value>
</data>
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>sudo 密碼已經驗證成功,請忽略錯誤密碼提示!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>密碼錯誤,請重試。</value>
</data>
</root>

View File

@@ -706,12 +706,17 @@ public class CoreConfigSingboxService
outbound.up_mbps = _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : 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_ports = node.Ports.Split(',')
.Where(p => p.Trim().IsNotEmpty())
.Select(p => p.Replace('-', ':'))
.Select(p => p.Trim())
.Where(p => p.IsNotEmpty())
.Select(p =>
{
var port = p.Replace('-', ':');
return port.Contains(':') ? port : $"{port}:{port}";
})
.ToList();
outbound.hop_interval = _config.HysteriaItem.HopInterval > 0 ? $"{_config.HysteriaItem.HopInterval}s" : null;
}
@@ -1369,7 +1374,7 @@ public class CoreConfigSingboxService
private async Task<string?> GenRoutingUserRuleOutbound(string outboundTag, SingboxConfig singboxConfig)
{
if (outboundTag is Global.ProxyTag or Global.DirectTag or Global.BlockTag)
if (Global.OutboundTags.Contains(outboundTag))
{
return outboundTag;
}

View File

@@ -631,7 +631,7 @@ public class CoreConfigV2rayService
private async Task<string?> GenRoutingUserRuleOutbound(string outboundTag, V2rayConfig v2rayConfig)
{
if (outboundTag is Global.ProxyTag or Global.DirectTag or Global.BlockTag)
if (Global.OutboundTags.Contains(outboundTag))
{
return outboundTag;
}

View File

@@ -536,6 +536,11 @@ public class UpdateService
}
}
//append dns items TODO
geoSiteFiles.Add("cn");
geoSiteFiles.Add("geolocation-cn");
geoSiteFiles.Add("category-ads-all");
var path = Utils.GetBinPath("srss");
if (!Directory.Exists(path))
{

View File

@@ -436,30 +436,34 @@ public class StatusBarViewModel : MyReactiveObject
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
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;
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
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()

View File

@@ -61,11 +61,7 @@ internal class Program
//.WithInterFont()
.WithFontByDefault()
.LogToTrace()
#if OS_OSX
.UseReactiveUI()
.With(new MacOSPlatformOptions { ShowInDock = AppHandler.Instance.Config.UiItem.MacOSShowInDock });
#else
.UseReactiveUI();
#endif
}
}

View File

@@ -21,13 +21,7 @@ public partial class AddServer2Window : WindowBase<AddServer2ViewModel>
btnCancel.Click += (s, e) => this.Close();
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
{
if (it == ECoreType.v2rayN)
continue;
cmbCoreType.Items.Add(it.ToString());
}
cmbCoreType.Items.Add(string.Empty);
cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
this.WhenActivated(disposables =>
{

View File

@@ -26,41 +26,22 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
Global.CoreTypes.ForEach(it =>
{
cmbCoreType.Items.Add(it);
});
cmbCoreType.Items.Add(string.Empty);
cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
cmbNetwork.ItemsSource = Global.Networks;
cmbFingerprint.ItemsSource = Global.Fingerprints;
cmbFingerprint2.ItemsSource = Global.Fingerprints;
cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
cmbAlpn.ItemsSource = Global.Alpns;
cmbStreamSecurity.Items.Add(string.Empty);
cmbStreamSecurity.Items.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);
});
var lstStreamSecurity = new List<string>();
lstStreamSecurity.Add(string.Empty);
lstStreamSecurity.Add(Global.StreamSecurity);
switch (profileItem.ConfigType)
{
case EConfigType.VMess:
gridVMess.IsVisible = true;
Global.VmessSecurities.ForEach(it =>
{
cmbSecurity.Items.Add(it);
});
cmbSecurity.ItemsSource = Global.VmessSecurities;
if (profileItem.Security.IsNullOrEmpty())
{
profileItem.Security = Global.DefaultSecurity;
@@ -69,10 +50,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.Shadowsocks:
gridSs.IsVisible = true;
AppHandler.Instance.GetShadowsocksSecurities(profileItem).ForEach(it =>
{
cmbSecurity3.Items.Add(it);
});
cmbSecurity3.ItemsSource = AppHandler.Instance.GetShadowsocksSecurities(profileItem);
break;
case EConfigType.SOCKS:
@@ -82,11 +60,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.VLESS:
gridVLESS.IsVisible = true;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it =>
{
cmbFlow5.Items.Add(it);
});
lstStreamSecurity.Add(Global.StreamSecurityReality);
cmbFlow5.ItemsSource = Global.Flows;
if (profileItem.Security.IsNullOrEmpty())
{
profileItem.Security = Global.None;
@@ -95,11 +70,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.Trojan:
gridTrojan.IsVisible = true;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it =>
{
cmbFlow6.Items.Add(it);
});
lstStreamSecurity.Add(Global.StreamSecurityReality);
cmbFlow6.ItemsSource = Global.Flows;
break;
case EConfigType.Hysteria2:
@@ -119,10 +91,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
cmbFingerprint.IsEnabled = false;
cmbFingerprint.SelectedValue = string.Empty;
Global.TuicCongestionControls.ForEach(it =>
{
cmbHeaderType8.Items.Add(it);
});
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
break;
case EConfigType.WireGuard:
@@ -134,6 +103,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
break;
}
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
gridTlsMore.IsVisible = false;
@@ -272,44 +242,41 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
private void SetHeaderType()
{
cmbHeaderType.Items.Clear();
var lstHeaderType = new List<string>();
var network = cmbNetwork.SelectedItem.ToString();
if (network.IsNullOrEmpty())
{
cmbHeaderType.Items.Add(Global.None);
lstHeaderType.Add(Global.None);
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0;
return;
}
if (network == nameof(ETransport.tcp))
{
cmbHeaderType.Items.Add(Global.None);
cmbHeaderType.Items.Add(Global.TcpHeaderHttp);
lstHeaderType.Add(Global.None);
lstHeaderType.Add(Global.TcpHeaderHttp);
}
else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic))
{
cmbHeaderType.Items.Add(Global.None);
Global.KcpHeaderTypes.ForEach(it =>
{
cmbHeaderType.Items.Add(it);
});
lstHeaderType.Add(Global.None);
lstHeaderType.AddRange(Global.KcpHeaderTypes);
}
else if (network is nameof(ETransport.xhttp))
{
Global.XhttpMode.ForEach(it =>
{
cmbHeaderType.Items.Add(it);
});
lstHeaderType.AddRange(Global.XhttpMode);
}
else if (network == nameof(ETransport.grpc))
{
cmbHeaderType.Items.Add(Global.GrpcGunMode);
cmbHeaderType.Items.Add(Global.GrpcMultiMode);
lstHeaderType.Add(Global.GrpcGunMode);
lstHeaderType.Add(Global.GrpcMultiMode);
}
else
{
cmbHeaderType.Items.Add(Global.None);
lstHeaderType.Add(Global.None);
}
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0;
}

View File

@@ -17,22 +17,10 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
btnCancel.Click += (s, e) => this.Close();
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
Global.DomainStrategy4Freedoms.ForEach(it =>
{
cmbdomainStrategy4Freedom.Items.Add(it);
});
Global.SingboxDomainStrategy4Out.ForEach(it =>
{
cmbdomainStrategy4Out.Items.Add(it);
});
Global.DomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress.Items.Add(it);
});
Global.SingboxDomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress2.Items.Add(it);
});
cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
this.WhenActivated(disposables =>
{

View File

@@ -134,7 +134,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
break;
}
});
if (Utils.IsWindows())
{

View File

@@ -19,87 +19,39 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
Global.destOverrideProtocols.ForEach(it =>
{
clbdestOverride.Items.Add(it);
});
clbdestOverride.ItemsSource = Global.destOverrideProtocols;
_config.Inbound.First().DestOverride?.ForEach(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 =>
{
cmbMtu.Items.Add(it);
});
Global.TunStacks.ForEach(it =>
{
cmbStack.Items.Add(it);
});
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);
});
cmbsystemProxyAdvancedProtocol.ItemsSource = Global.IEProxyProtocols;
cmbloglevel.ItemsSource = Global.LogLevels;
cmbdefFingerprint.ItemsSource = Global.Fingerprints;
cmbdefUserAgent.ItemsSource = Global.UserAgent;
cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
cmbMtu.ItemsSource = Global.TunMtus;
cmbStack.ItemsSource = Global.TunStacks;
for (var i = 2; i <= 8; i++)
{
cmbMixedConcurrencyCount.Items.Add(i);
}
for (var i = 2; i <= 6; i++)
{
cmbSpeedTestTimeout.Items.Add(i * 5);
}
cmbCoreType1.ItemsSource = Global.CoreTypes;
cmbCoreType2.ItemsSource = Global.CoreTypes;
cmbCoreType3.ItemsSource = Global.CoreTypes;
cmbCoreType4.ItemsSource = Global.CoreTypes;
cmbCoreType5.ItemsSource = Global.CoreTypes;
cmbCoreType6.ItemsSource = Global.CoreTypes;
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;
cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls;
cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls;
cmbGetFilesSourceUrl.ItemsSource = Global.GeoFilesSources;
cmbSrsFilesSourceUrl.ItemsSource = Global.SingboxRulesetSources;
cmbRoutingRulesSourceUrl.ItemsSource = Global.RoutingRulesSources;
cmbIPAPIUrl.ItemsSource = Global.IPAPIUrls;
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());
}
cmbMainGirdOrientation.ItemsSource = Utils.GetEnumNames<EGirdOrientation>();
this.WhenActivated(disposables =>
{

View File

@@ -23,19 +23,11 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
cmbOutboundTag.ItemsSource = new List<string> { Global.ProxyTag, Global.DirectTag, Global.BlockTag };
Global.RuleProtocols.ForEach(it =>
{
clbProtocol.Items.Add(it);
});
Global.InboundTags.ForEach(it =>
{
clbInboundTag.Items.Add(it);
});
Global.RuleNetworks.ForEach(it =>
{
cmbNetwork.Items.Add(it);
});
cmbOutboundTag.ItemsSource = Global.OutboundTags;
clbProtocol.ItemsSource = Global.RuleProtocols;
clbInboundTag.ItemsSource = Global.InboundTags;
cmbNetwork.ItemsSource = Global.RuleNetworks;
if (!rulesItem.Id.IsNullOrEmpty())
{

View File

@@ -30,15 +30,9 @@ public partial class RoutingRuleSettingWindow : WindowBase<RoutingRuleSettingVie
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync;
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
Global.DomainStrategies.ForEach(it =>
{
cmbdomainStrategy.Items.Add(it);
});
cmbdomainStrategy.Items.Add(string.Empty);
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
cmbdomainStrategy.ItemsSource = Global.DomainStrategies.AppendEmpty();
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
this.WhenActivated(disposables =>
{

View File

@@ -26,18 +26,9 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
Global.DomainStrategies.ForEach(it =>
{
cmbdomainStrategy.Items.Add(it);
});
Global.DomainMatchers.ForEach(it =>
{
cmbdomainMatcher.Items.Add(it);
});
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
this.WhenActivated(disposables =>
{

View File

@@ -104,13 +104,15 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
{
var dialog = new SudoPasswordInputView();
var obj = await DialogHost.Show(dialog);
if (obj == null)
var password = obj?.ToString();
if (password.IsNullOrEmpty())
{
togEnableTun.IsChecked = false;
return false;
}
AppHandler.Instance.LinuxSudoPwd = obj.ToString() ?? string.Empty;
AppHandler.Instance.LinuxSudoPwd = password;
return true;
}

View File

@@ -22,10 +22,7 @@ public partial class SubEditWindow : WindowBase<SubEditViewModel>
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
Global.SubConvertTargets.ForEach(it =>
{
cmbConvertTarget.Items.Add(it);
});
cmbConvertTarget.ItemsSource = Global.SubConvertTargets;
this.WhenActivated(disposables =>
{

View File

@@ -1,5 +1,6 @@
using Avalonia.Controls;
using Avalonia.Threading;
using CliWrap.Buffered;
using DialogHostAvalonia;
namespace v2rayN.Desktop.Views;
@@ -12,22 +13,71 @@ public partial class SudoPasswordInputView : UserControl
this.Loaded += (s, e) => txtPassword.Focus();
btnSave.Click += (_, _) =>
{
if (string.IsNullOrEmpty(txtPassword.Text))
{
txtPassword.Focus();
return;
}
Dispatcher.UIThread.Post(() =>
{
DialogHost.Close(null, txtPassword.Text);
});
};
btnSave.Click += async (_, _) => await SavePasswordAsync();
btnCancel.Click += (_, _) =>
{
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;
}
}
}

View File

@@ -16,20 +16,9 @@ public partial class ThemeSettingView : ReactiveUserControl<ThemeSettingViewMode
InitializeComponent();
ViewModel = new ThemeSettingViewModel();
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
{
cmbCurrentTheme.Items.Add(it.ToString());
}
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
{
cmbCurrentFontSize.Items.Add(i);
}
Global.Languages.ForEach(it =>
{
cmbCurrentLanguage.Items.Add(it);
});
cmbCurrentTheme.ItemsSource = Utils.GetEnumNames<ETheme>();
cmbCurrentFontSize.ItemsSource = Enumerable.Range(Global.MinFontSize, 11).ToList();
cmbCurrentLanguage.ItemsSource = Global.Languages;
this.WhenActivated(disposables =>
{

View File

@@ -14,13 +14,7 @@ public partial class AddServer2Window
this.Loaded += Window_Loaded;
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
{
if (it == ECoreType.v2rayN)
continue;
cmbCoreType.Items.Add(it.ToString());
}
cmbCoreType.Items.Add(string.Empty);
cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
this.WhenActivated(disposables =>
{

View File

@@ -20,41 +20,22 @@ public partial class AddServerWindow
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
Global.CoreTypes.ForEach(it =>
{
cmbCoreType.Items.Add(it);
});
cmbCoreType.Items.Add(string.Empty);
cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
cmbNetwork.ItemsSource = Global.Networks;
cmbFingerprint.ItemsSource = Global.Fingerprints;
cmbFingerprint2.ItemsSource = Global.Fingerprints;
cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
cmbAlpn.ItemsSource = Global.Alpns;
cmbStreamSecurity.Items.Add(string.Empty);
cmbStreamSecurity.Items.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);
});
var lstStreamSecurity = new List<string>();
lstStreamSecurity.Add(string.Empty);
lstStreamSecurity.Add(Global.StreamSecurity);
switch (profileItem.ConfigType)
{
case EConfigType.VMess:
gridVMess.Visibility = Visibility.Visible;
Global.VmessSecurities.ForEach(it =>
{
cmbSecurity.Items.Add(it);
});
cmbSecurity.ItemsSource = Global.VmessSecurities;
if (profileItem.Security.IsNullOrEmpty())
{
profileItem.Security = Global.DefaultSecurity;
@@ -63,10 +44,7 @@ public partial class AddServerWindow
case EConfigType.Shadowsocks:
gridSs.Visibility = Visibility.Visible;
AppHandler.Instance.GetShadowsocksSecurities(profileItem).ForEach(it =>
{
cmbSecurity3.Items.Add(it);
});
cmbSecurity3.ItemsSource = AppHandler.Instance.GetShadowsocksSecurities(profileItem);
break;
case EConfigType.SOCKS:
@@ -76,11 +54,8 @@ public partial class AddServerWindow
case EConfigType.VLESS:
gridVLESS.Visibility = Visibility.Visible;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it =>
{
cmbFlow5.Items.Add(it);
});
lstStreamSecurity.Add(Global.StreamSecurityReality);
cmbFlow5.ItemsSource = Global.Flows;
if (profileItem.Security.IsNullOrEmpty())
{
profileItem.Security = Global.None;
@@ -89,11 +64,8 @@ public partial class AddServerWindow
case EConfigType.Trojan:
gridTrojan.Visibility = Visibility.Visible;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
Global.Flows.ForEach(it =>
{
cmbFlow6.Items.Add(it);
});
lstStreamSecurity.Add(Global.StreamSecurityReality);
cmbFlow6.ItemsSource = Global.Flows;
break;
case EConfigType.Hysteria2:
@@ -113,10 +85,7 @@ public partial class AddServerWindow
cmbFingerprint.IsEnabled = false;
cmbFingerprint.Text = string.Empty;
Global.TuicCongestionControls.ForEach(it =>
{
cmbHeaderType8.Items.Add(it);
});
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
break;
case EConfigType.WireGuard:
@@ -128,6 +97,7 @@ public partial class AddServerWindow
break;
}
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
gridTlsMore.Visibility = Visibility.Hidden;
@@ -267,44 +237,41 @@ public partial class AddServerWindow
private void SetHeaderType()
{
cmbHeaderType.Items.Clear();
var lstHeaderType = new List<string>();
var network = cmbNetwork.SelectedItem.ToString();
if (network.IsNullOrEmpty())
{
cmbHeaderType.Items.Add(Global.None);
lstHeaderType.Add(Global.None);
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0;
return;
}
if (network == nameof(ETransport.tcp))
{
cmbHeaderType.Items.Add(Global.None);
cmbHeaderType.Items.Add(Global.TcpHeaderHttp);
lstHeaderType.Add(Global.None);
lstHeaderType.Add(Global.TcpHeaderHttp);
}
else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic))
{
cmbHeaderType.Items.Add(Global.None);
Global.KcpHeaderTypes.ForEach(it =>
{
cmbHeaderType.Items.Add(it);
});
lstHeaderType.Add(Global.None);
lstHeaderType.AddRange(Global.KcpHeaderTypes);
}
else if (network is nameof(ETransport.xhttp))
{
Global.XhttpMode.ForEach(it =>
{
cmbHeaderType.Items.Add(it);
});
lstHeaderType.AddRange(Global.XhttpMode);
}
else if (network == nameof(ETransport.grpc))
{
cmbHeaderType.Items.Add(Global.GrpcGunMode);
cmbHeaderType.Items.Add(Global.GrpcMultiMode);
lstHeaderType.Add(Global.GrpcGunMode);
lstHeaderType.Add(Global.GrpcMultiMode);
}
else
{
cmbHeaderType.Items.Add(Global.None);
lstHeaderType.Add(Global.None);
}
cmbHeaderType.ItemsSource = lstHeaderType;
cmbHeaderType.SelectedIndex = 0;
}

View File

@@ -17,22 +17,10 @@ public partial class DNSSettingWindow
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
Global.DomainStrategy4Freedoms.ForEach(it =>
{
cmbdomainStrategy4Freedom.Items.Add(it);
});
Global.SingboxDomainStrategy4Out.ForEach(it =>
{
cmbdomainStrategy4Out.Items.Add(it);
});
Global.DomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress.Items.Add(it);
});
Global.SingboxDomainDNSAddress.ForEach(it =>
{
cmbdomainDNSAddress2.Items.Add(it);
});
cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
this.WhenActivated(disposables =>
{

View File

@@ -25,11 +25,8 @@ public partial class MsgView
menuMsgViewCopy.Click += menuMsgViewCopy_Click;
menuMsgViewCopyAll.Click += menuMsgViewCopyAll_Click;
menuMsgViewClear.Click += menuMsgViewClear_Click;
Global.PresetMsgFilters.ForEach(it =>
{
cmbMsgFilter.Items.Add(it);
});
cmbMsgFilter.ItemsSource = Global.PresetMsgFilters;
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -21,94 +21,39 @@ public partial class OptionSettingWindow
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
Global.destOverrideProtocols.ForEach(it =>
{
clbdestOverride.Items.Add(it);
});
clbdestOverride.ItemsSource = Global.destOverrideProtocols;
_config.Inbound.First().DestOverride?.ForEach(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 =>
{
cmbMtu.Items.Add(it);
});
Global.TunStacks.ForEach(it =>
{
cmbStack.Items.Add(it);
});
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);
});
cmbsystemProxyAdvancedProtocol.ItemsSource = Global.IEProxyProtocols;
cmbloglevel.ItemsSource = Global.LogLevels;
cmbdefFingerprint.ItemsSource = Global.Fingerprints;
cmbdefUserAgent.ItemsSource = Global.UserAgent;
cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
cmbMtu.ItemsSource = Global.TunMtus;
cmbStack.ItemsSource = Global.TunStacks;
for (var i = 2; i <= 8; i++)
{
cmbMixedConcurrencyCount.Items.Add(i);
}
for (var i = 2; i <= 6; i++)
{
cmbSpeedTestTimeout.Items.Add(i * 5);
}
Global.SpeedTestUrls.ForEach(it =>
{
cmbSpeedTestUrl.Items.Add(it);
});
Global.SpeedPingTestUrls.ForEach(it =>
{
cmbSpeedPingTestUrl.Items.Add(it);
});
Global.SubConvertUrls.ForEach(it =>
{
cmbSubConvertUrl.Items.Add(it);
});
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());
}
cmbCoreType1.ItemsSource = Global.CoreTypes;
cmbCoreType2.ItemsSource = Global.CoreTypes;
cmbCoreType3.ItemsSource = Global.CoreTypes;
cmbCoreType4.ItemsSource = Global.CoreTypes;
cmbCoreType5.ItemsSource = Global.CoreTypes;
cmbCoreType6.ItemsSource = Global.CoreTypes;
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;
cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls;
cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls;
cmbGetFilesSourceUrl.ItemsSource = Global.GeoFilesSources;
cmbSrsFilesSourceUrl.ItemsSource = Global.SingboxRulesetSources;
cmbRoutingRulesSourceUrl.ItemsSource = Global.RoutingRulesSources;
cmbIPAPIUrl.ItemsSource = Global.IPAPIUrls;
cmbMainGirdOrientation.ItemsSource = Utils.GetEnumNames<EGirdOrientation>();
this.WhenActivated(disposables =>
{
@@ -209,8 +154,7 @@ public partial class OptionSettingWindow
private async Task InitSettingFont()
{
var lstFonts = await GetFonts(Utils.GetFontsPath());
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
cmbcurrentFontFamily.Items.Add(string.Empty);
cmbcurrentFontFamily.ItemsSource = lstFonts.AppendEmpty();
}
private async Task<List<string>> GetFonts(string path)

View File

@@ -16,21 +16,11 @@ public partial class RoutingRuleDetailsWindow
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
cmbOutboundTag.Items.Add(Global.ProxyTag);
cmbOutboundTag.Items.Add(Global.DirectTag);
cmbOutboundTag.Items.Add(Global.BlockTag);
Global.RuleProtocols.ForEach(it =>
{
clbProtocol.Items.Add(it);
});
Global.InboundTags.ForEach(it =>
{
clbInboundTag.Items.Add(it);
});
Global.RuleNetworks.ForEach(it =>
{
cmbNetwork.Items.Add(it);
});
cmbOutboundTag.ItemsSource = Global.OutboundTags;
clbProtocol.ItemsSource = Global.RuleProtocols;
clbInboundTag.ItemsSource = Global.InboundTags;
cmbNetwork.ItemsSource = Global.RuleNetworks;
if (!rulesItem.Id.IsNullOrEmpty())
{

View File

@@ -21,15 +21,9 @@ public partial class RoutingRuleSettingWindow
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_Click;
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
Global.DomainStrategies.ForEach(it =>
{
cmbdomainStrategy.Items.Add(it);
});
cmbdomainStrategy.Items.Add(string.Empty);
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
cmbdomainStrategy.ItemsSource = Global.DomainStrategies.AppendEmpty();
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
this.WhenActivated(disposables =>
{

View File

@@ -21,18 +21,9 @@ public partial class RoutingSettingWindow
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
Global.DomainStrategies.ForEach(it =>
{
cmbdomainStrategy.Items.Add(it);
});
Global.DomainMatchers.ForEach(it =>
{
cmbdomainMatcher.Items.Add(it);
});
Global.DomainStrategies4Singbox.ForEach(it =>
{
cmbdomainStrategy4Singbox.Items.Add(it);
});
cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
this.WhenActivated(disposables =>
{

View File

@@ -15,10 +15,7 @@ public partial class SubEditWindow
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
Global.SubConvertTargets.ForEach(it =>
{
cmbConvertTarget.Items.Add(it);
});
cmbConvertTarget.ItemsSource = Global.SubConvertTargets;
this.WhenActivated(disposables =>
{

View File

@@ -13,22 +13,10 @@ public partial class ThemeSettingView
{
InitializeComponent();
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++)
{
cmbCurrentFontSize.Items.Add(i.ToString());
}
Global.Languages.ForEach(it =>
{
cmbCurrentLanguage.Items.Add(it);
});
cmbCurrentTheme.ItemsSource = Utils.GetEnumNames<ETheme>().Take(3).ToList();
cmbCurrentFontSize.ItemsSource = Enumerable.Range(Global.MinFontSize, 11).ToList();
cmbCurrentLanguage.ItemsSource = Global.Languages;
this.WhenActivated(disposables =>
{