From 499edb402cfce41b7d5eb39573c5863407c7f96a Mon Sep 17 00:00:00 2001 From: k1mlka Date: Sun, 29 Sep 2024 17:33:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=92=84=20=E7=BD=91=E7=BB=9C=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=AD=90=E9=A1=B5=E9=9D=A2ViewModel=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 💄 网络测试子页面NAT检查部分逻辑重构 💄 网络测试子页面ViewModel重构 💄 网络测试子页面NAT检查部分逻辑重构 💄代码Clean,没有引用到的名称空间与枚举类型 💄 网络测试子页面NAT检查部分逻辑重构 💄 网络测试子页面ViewModel重构 💄 网络测试子页面NAT检查部分逻辑重构 💄代码Clean,没有引用到的名称空间与枚举类型 --- .../UI/ViewModels/AcceleratorPageViewModel.cs | 48 +++-- .../AcceleratorPageViewModel.props.cs | 34 ++-- .../NetworkCheckControlViewModel.cs | 183 ++++++++++++++++++ .../UI/Views/Controls/NetworkCheck.axaml | 13 +- .../UI/Views/Controls/NetworkCheck.axaml.cs | 19 +- .../UI/Views/Pages/AcceleratorPage2.axaml | 2 +- .../UI/Views/Pages/AcceleratorPage2.axaml.cs | 25 --- 7 files changed, 262 insertions(+), 62 deletions(-) create mode 100644 src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/NetworkCheckControlViewModel.cs diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs index 8e67da5e5d0..ad9d3045d34 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs @@ -1,8 +1,5 @@ -using AppResources = BD.WTTS.Client.Resources.Strings; - using BD.WTTS.UI.Views.Pages; -using STUN.StunResult; -using STUN.Enums; +using AppResources = BD.WTTS.Client.Resources.Strings; namespace BD.WTTS.UI.ViewModels; @@ -78,22 +75,47 @@ public AcceleratorPageViewModel() var natCheckResult = await networkTestService.TestStunClient3489Async(testServerHostName: SelectedSTUNAddress) ?? new ClassicStunResult { NatType = NatType.Unknown }; var (netSucc, _) = await networkTestService.TestOpenUrlAsync("https://www.baidu.com"); - var natStatus = natCheckResult.NatType switch + var publicEndPoint = natCheckResult.PublicEndPoint?.Address.ToString() ?? "Unknown"; + var localEndPoint = natCheckResult.LocalEndPoint?.Address.ToString() ?? "Unknown"; + + var (natLevel, natTypeTip) = natCheckResult.NatType switch { - NatType.OpenInternet or NatType.FullCone => NatTypeSimple.Open, - NatType.RestrictedCone or NatType.PortRestrictedCone or NatType.SymmetricUdpFirewall => NatTypeSimple.Moderate, - NatType.Symmetric or NatType.UdpBlocked => NatTypeSimple.Strict, - NatType.Unknown or NatType.UnsupportedServer or _ => NatTypeSimple.Unknown, + // Open + NatType.OpenInternet or NatType.FullCone => ("开放 NAT", "您可与在其网络上具有任意 NAT 类型的用户玩多人游戏和发起多人游戏。"), + // Moderate + NatType.RestrictedCone or NatType.PortRestrictedCone or NatType.SymmetricUdpFirewall => ("中等 NAT", "您可与一些用户玩多人游戏;但是,并且通常你将不会被选为比赛的主持人。"), + // Strict + NatType.Symmetric or NatType.UdpBlocked => ("严格 NAT", "您只能与具有开放 NAT 类型的用户玩多人游戏。您不能被选为比赛的主持人。"), + // Unknown + NatType.Unknown or NatType.UnsupportedServer or _ => ("不可用 NAT", "如果 NAT 不可用,您将无法使用群聊天或连接到某些 Xbox 游戏的多人游戏。"), }; - PublicEndPoint = natCheckResult.PublicEndPoint?.Address.ToString() ?? "Unknown"; - LocalEndPoint = natCheckResult.LocalEndPoint?.Address.ToString() ?? "Unknown"; - - return (natStatus, netSucc); + return new NATFetchResult(publicEndPoint, localEndPoint, natLevel, natTypeTip, netSucc); }); NATCheckCommand .IsExecuting .ToPropertyEx(this, x => x.IsNATChecking); + NATCheckCommand + .Select(x => x.PublicEndPoint) + .ToPropertyEx(this, x => x.PublicEndPoint); + NATCheckCommand + .Select(x => x.LocalEndPoint) + .ToPropertyEx(this, x => x.LocalEndPoint); + NATCheckCommand + .Select(x => x.NATLevel) + .ToPropertyEx(this, x => x.NATLevel); + NATCheckCommand + .Select(x => x.NATTypeTip) + .ToPropertyEx(this, x => x.NATTypeTip); + + var hidePingResultStream = NATCheckCommand + .IsExecuting + .Where(x => x == true) + .Select(x => PingStatus.Blank); + NATCheckCommand + .Select(x => x.PingResult == true ? PingStatus.Ok : PingStatus.Error) + .Merge(hidePingResultStream) + .ToPropertyEx(this, x => x.PingResultStatus); DNSCheckCommand = ReactiveCommand.CreateFromTask(async () => { diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs index 7ae8707dd4a..3ae539c4be7 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs @@ -4,12 +4,13 @@ namespace BD.WTTS.UI.ViewModels; public sealed partial class AcceleratorPageViewModel : TabItemViewModel { - public enum NatTypeSimple + public record NATFetchResult(string PublicEndPoint, string LocalEndPoint, string NATLevel, string NATTypeTip, bool PingResult); + + public enum PingStatus { - Unknown, - Open, - Moderate, - Strict, + Blank, + Ok, + Error, } public override string Name => Strings.Welcome; @@ -25,6 +26,21 @@ public enum NatTypeSimple "stun.miwifi.com", ]; + [ObservableAsProperty] + public string NATLevel { get; } = string.Empty; + + [ObservableAsProperty] + public string NATTypeTip { get; } = string.Empty; + + [ObservableAsProperty] + public string LocalEndPoint { get; set; } = string.Empty; + + [ObservableAsProperty] + public string PublicEndPoint { get; set; } = string.Empty; + + [ObservableAsProperty] + public PingStatus PingResultStatus { get; } + [ObservableAsProperty] public bool IsNATChecking { get; } @@ -40,12 +56,6 @@ public enum NatTypeSimple [Reactive] public ReadOnlyCollection? EnableProxyDomainGroupVMs { get; set; } - [Reactive] - public string LocalEndPoint { get; set; } = string.Empty; - - [Reactive] - public string PublicEndPoint { get; set; } = string.Empty; - [Reactive] public string DNSTestDelay { get; set; } = string.Empty; @@ -58,7 +68,7 @@ public enum NatTypeSimple [Reactive] public bool IsSupportIPv6 { get; set; } - public ReactiveCommand NATCheckCommand { get; } + public ReactiveCommand NATCheckCommand { get; } public ReactiveCommand DNSCheckCommand { get; } diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/NetworkCheckControlViewModel.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/NetworkCheckControlViewModel.cs new file mode 100644 index 00000000000..ab7c574cb6a --- /dev/null +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/NetworkCheckControlViewModel.cs @@ -0,0 +1,183 @@ +using STUN.Enums; +using STUN.StunResult; +using System.Reactive; + +namespace BD.WTTS.UI.ViewModels; + +public class NetworkCheckControlViewModel : ViewModelBase +{ + private readonly INetworkTestService _networkTestService = INetworkTestService.Instance; + + public record NATFetchResult(string PublicEndPoint, string LocalEndPoint, string NATLevel, string NATTypeTip, bool PingResult); + + [Reactive] + public string SelectedSTUNAddress { get; set; } + + public string[] STUNAddress { get; } = + [ + "stun.syncthing.net", + "stun.hot-chilli.net", + "stun.fitauto.ru", + "stun.miwifi.com", + ]; + + [ObservableAsProperty] + public string NATLevel { get; } = string.Empty; + + [ObservableAsProperty] + public string NATTypeTip { get; } = string.Empty; + + [ObservableAsProperty] + public string LocalEndPoint { get; } = string.Empty; + + [ObservableAsProperty] + public string PublicEndPoint { get; } = string.Empty; + + [ObservableAsProperty] + public bool PingOkVisible { get; } + + [ObservableAsProperty] + public bool PingErrorVisible { get; } + + [ObservableAsProperty] + public bool IsNATChecking { get; } + + [ObservableAsProperty] + public bool IsDNSChecking { get; } + + [ObservableAsProperty] + public bool IsIPv6Checking { get; } + + [Reactive] + public string DomainPendingTest { get; set; } = string.Empty; + + [Reactive] + public string DNSTestDelay { get; set; } = string.Empty; + + [Reactive] + public string DNSTestResult { get; set; } = string.Empty; + + [Reactive] + public string IPv6Address { get; set; } = string.Empty; + + [Reactive] + public bool IsSupportIPv6 { get; set; } + + public ReactiveCommand NATCheckCommand { get; } + + public ReactiveCommand DNSCheckCommand { get; } + + public ReactiveCommand IPv6CheckCommand { get; } + + public NetworkCheckControlViewModel() + { + SelectedSTUNAddress = STUNAddress[0]; + + NATCheckCommand = ReactiveCommand.CreateFromTask(async () => + { + var natCheckResult = await _networkTestService.TestStunClient3489Async(testServerHostName: SelectedSTUNAddress) ?? new ClassicStunResult { NatType = NatType.Unknown }; + var (netSucc, _) = await _networkTestService.TestOpenUrlAsync("https://www.baidu.com"); + + var publicEndPoint = natCheckResult.PublicEndPoint?.Address.ToString() ?? "Unknown"; + var localEndPoint = natCheckResult.LocalEndPoint?.Address.ToString() ?? "Unknown"; + + var (natLevel, natTypeTip) = natCheckResult.NatType switch + { + // Open + NatType.OpenInternet or NatType.FullCone => ("开放 NAT", "您可与在其网络上具有任意 NAT 类型的用户玩多人游戏和发起多人游戏。"), + // Moderate + NatType.RestrictedCone or NatType.PortRestrictedCone or NatType.SymmetricUdpFirewall => ("中等 NAT", "您可与一些用户玩多人游戏;但是,并且通常你将不会被选为比赛的主持人。"), + // Strict + NatType.Symmetric or NatType.UdpBlocked => ("严格 NAT", "您只能与具有开放 NAT 类型的用户玩多人游戏。您不能被选为比赛的主持人。"), + // Unknown + NatType.Unknown or NatType.UnsupportedServer or _ => ("不可用 NAT", "如果 NAT 不可用,您将无法使用群聊天或连接到某些 Xbox 游戏的多人游戏。"), + }; + + return new NATFetchResult(publicEndPoint, localEndPoint, natLevel, natTypeTip, netSucc); + }); + NATCheckCommand + .IsExecuting + .ToPropertyEx(this, x => x.IsNATChecking); + NATCheckCommand + .Select(x => x.PublicEndPoint) + .ToPropertyEx(this, x => x.PublicEndPoint); + NATCheckCommand + .Select(x => x.LocalEndPoint) + .ToPropertyEx(this, x => x.LocalEndPoint); + NATCheckCommand + .Select(x => x.NATLevel) + .Merge(Observable.Return("未知")) + .ToPropertyEx(this, x => x.NATLevel); + NATCheckCommand + .Select(x => x.NATTypeTip) + .Merge(Observable.Return("未知类型")) + .ToPropertyEx(this, x => x.NATTypeTip); + + var hidePingResultStream = NATCheckCommand + .IsExecuting + .Where(x => x == true) + .Select(x => false); + NATCheckCommand + .Select(x => x.PingResult == true) + .Merge(hidePingResultStream) + .ToPropertyEx(this, x => x.PingOkVisible); + NATCheckCommand + .Select(x => x.PingResult == false) + .Merge(hidePingResultStream) + .ToPropertyEx(this, x => x.PingErrorVisible); + + DNSCheckCommand = ReactiveCommand.CreateFromTask(async () => + { + var testDomain = DomainPendingTest == string.Empty ? "store.steampowered.com" : DomainPendingTest; + try + { + long delayMs; + IPAddress[] address; + if (ProxySettings.UseDoh) + { + var configDoh = ProxySettings.CustomDohAddres2.Value ?? ProxySettingsWindowViewModel.DohAddress.FirstOrDefault() ?? string.Empty; + (delayMs, address) = await _networkTestService.TestDNSOverHttpsAsync(testDomain, configDoh); + } + else + { + var configDns = ProxySettings.ProxyMasterDns.Value ?? string.Empty; + (delayMs, address) = await _networkTestService.TestDNSAsync(testDomain, configDns, 53); + } + if (address.Length == 0) + throw new Exception("Parsing failed. Return empty ip address."); + + DNSTestDelay = delayMs + "ms "; + DNSTestResult = string.Empty + address.FirstOrDefault(); + } + catch (Exception ex) + { + Log.Error(nameof(AcceleratorPageViewModel), ex.ToString()); + DNSTestDelay = string.Empty; + DNSTestResult = "error"; + } + }); + DNSCheckCommand + .IsExecuting + .ToPropertyEx(this, x => x.IsDNSChecking); + + IPv6CheckCommand = ReactiveCommand.CreateFromTask(async () => + { + var result = await IMicroServiceClient.Instance.Accelerate.GetMyIP(ipV6: true); + if (result.IsSuccess) + { + IsSupportIPv6 = true; + IPv6Address = result.Content ?? string.Empty; + } + else + { + IsSupportIPv6 = false; + IPv6Address = string.Empty; + } + }); + IPv6CheckCommand + .IsExecuting + .ToPropertyEx(this, x => x.IsIPv6Checking); + + IPv6CheckCommand.Execute().Subscribe(); + } +} \ No newline at end of file diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml index 952f15c5adf..dd217d38212 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml @@ -11,7 +11,7 @@ xmlns:ui="using:FluentAvalonia.UI.Controls" d:DesignHeight="450" d:DesignWidth="800" - x:DataType="spp:AcceleratorPageViewModel" + x:DataType="spp:NetworkCheckControlViewModel" mc:Ignorable="d"> @@ -63,14 +62,14 @@ x:Name="NATTextBlock" VerticalAlignment="Center" Foreground="Gray" - Text="未知" /> + Text="{Binding NATLevel}" /> - + @@ -126,13 +125,13 @@ + Glyph="" + IsVisible="{Binding PingOkVisible}" /> - + { public NetworkCheck() { InitializeComponent(); + + Loaded += (_, _) => + { + ViewModel = DataContext as AcceleratorPageViewModel; + + this.OneWayBind(ViewModel, vm => vm.PingResultStatus, v => v.PingOK.IsVisible, result => result == AcceleratorPageViewModel.PingStatus.Ok); + this.OneWayBind(ViewModel, vm => vm.PingResultStatus, v => v.PingError.IsVisible, result => result == AcceleratorPageViewModel.PingStatus.Error); + this.OneWayBind(ViewModel, vm => vm.NATLevel, v => v.NATTextBlock.Text); + this.OneWayBind(ViewModel, vm => vm.NATTypeTip, v => v.NATTypeTip.Text); + }; } + + public AcceleratorPageViewModel? ViewModel { get; set; } + + object? IViewFor.ViewModel { get; set; } } \ No newline at end of file diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml index e286f1c7aee..7315660509e 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml @@ -648,7 +648,7 @@ - + diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml.cs index ebf109666a8..441eef8035b 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Pages/AcceleratorPage2.axaml.cs @@ -73,31 +73,6 @@ public AcceleratorPage2() GameAccTab.IsVisible = false; AcceleratorTabs.SelectedIndex = 0; } - - NetworkCheckControl.PingOK.IsVisible = false; - NetworkCheckControl.PingError.IsVisible = false; - NetworkCheckControl.NATCheckButton.Click += (_, _) => NetworkCheckControl.PingError.IsVisible = NetworkCheckControl.PingOK.IsVisible = false; - ViewModel!.NATCheckCommand - .Subscribe(result => - { - (NetworkCheckControl.NATTextBlock.Text, NetworkCheckControl.NATTypeTip.Text) = result.Nat switch - { - AcceleratorPageViewModel.NatTypeSimple.Open => ("开放 NAT", "您可与在其网络上具有任意 NAT 类型的用户玩多人游戏和发起多人游戏。"), - AcceleratorPageViewModel.NatTypeSimple.Moderate => ("中等 NAT", "您可与一些用户玩多人游戏;但是,并且通常你将不会被选为比赛的主持人。"), - AcceleratorPageViewModel.NatTypeSimple.Strict => ("严格 NAT", "您只能与具有开放 NAT 类型的用户玩多人游戏。您不能被选为比赛的主持人。"), - _ => ("不可用 NAT", "如果 NAT 不可用,您将无法使用群聊天或连接到某些 Xbox 游戏的多人游戏。"), - }; - - if (result.PingSuccess) - { - NetworkCheckControl.PingOK.IsVisible = true; - } - else - { - NetworkCheckControl.PingError.IsVisible = true; - } - }).DisposeWith(disposables); - ViewModel.IPv6CheckCommand.Execute().Subscribe(); }); SearchGameBox.DropDownClosed += SearchGameBox_DropDownClosed; From 9a2bd1a6cc711e21d67c1885bcb88077e9fe662e Mon Sep 17 00:00:00 2001 From: k1mlka Date: Tue, 8 Oct 2024 11:40:51 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20=E7=A7=BB=E9=99=A4=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI/ViewModels/AcceleratorPageViewModel.cs | 104 +----------------- .../AcceleratorPageViewModel.props.cs | 65 ----------- .../UI/Views/Controls/NetworkCheck.axaml.cs | 16 +-- 3 files changed, 3 insertions(+), 182 deletions(-) diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs index ad9d3045d34..2dd74a1e1f6 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.cs @@ -5,12 +5,13 @@ namespace BD.WTTS.UI.ViewModels; public sealed partial class AcceleratorPageViewModel { + public NetworkCheckControlViewModel NetworkCheckControlViewModel { get; } = new(); + DateTime _initializeTime; readonly IHostsFileService? hostsFileService; readonly IPlatformService platformService = IPlatformService.Instance; readonly IReverseProxyService reverseProxyService = IReverseProxyService.Constants.Instance; readonly ICertificateManager certificateManager = ICertificateManager.Constants.Instance; - readonly INetworkTestService networkTestService = INetworkTestService.Instance; public AcceleratorPageViewModel() { @@ -68,107 +69,6 @@ public AcceleratorPageViewModel() GameAcceleratorService.Current.LoadGames(); }); - SelectedSTUNAddress = STUNAddress[0]; - - NATCheckCommand = ReactiveCommand.CreateFromTask(async () => - { - var natCheckResult = await networkTestService.TestStunClient3489Async(testServerHostName: SelectedSTUNAddress) ?? new ClassicStunResult { NatType = NatType.Unknown }; - var (netSucc, _) = await networkTestService.TestOpenUrlAsync("https://www.baidu.com"); - - var publicEndPoint = natCheckResult.PublicEndPoint?.Address.ToString() ?? "Unknown"; - var localEndPoint = natCheckResult.LocalEndPoint?.Address.ToString() ?? "Unknown"; - - var (natLevel, natTypeTip) = natCheckResult.NatType switch - { - // Open - NatType.OpenInternet or NatType.FullCone => ("开放 NAT", "您可与在其网络上具有任意 NAT 类型的用户玩多人游戏和发起多人游戏。"), - // Moderate - NatType.RestrictedCone or NatType.PortRestrictedCone or NatType.SymmetricUdpFirewall => ("中等 NAT", "您可与一些用户玩多人游戏;但是,并且通常你将不会被选为比赛的主持人。"), - // Strict - NatType.Symmetric or NatType.UdpBlocked => ("严格 NAT", "您只能与具有开放 NAT 类型的用户玩多人游戏。您不能被选为比赛的主持人。"), - // Unknown - NatType.Unknown or NatType.UnsupportedServer or _ => ("不可用 NAT", "如果 NAT 不可用,您将无法使用群聊天或连接到某些 Xbox 游戏的多人游戏。"), - }; - - return new NATFetchResult(publicEndPoint, localEndPoint, natLevel, natTypeTip, netSucc); - }); - NATCheckCommand - .IsExecuting - .ToPropertyEx(this, x => x.IsNATChecking); - NATCheckCommand - .Select(x => x.PublicEndPoint) - .ToPropertyEx(this, x => x.PublicEndPoint); - NATCheckCommand - .Select(x => x.LocalEndPoint) - .ToPropertyEx(this, x => x.LocalEndPoint); - NATCheckCommand - .Select(x => x.NATLevel) - .ToPropertyEx(this, x => x.NATLevel); - NATCheckCommand - .Select(x => x.NATTypeTip) - .ToPropertyEx(this, x => x.NATTypeTip); - - var hidePingResultStream = NATCheckCommand - .IsExecuting - .Where(x => x == true) - .Select(x => PingStatus.Blank); - NATCheckCommand - .Select(x => x.PingResult == true ? PingStatus.Ok : PingStatus.Error) - .Merge(hidePingResultStream) - .ToPropertyEx(this, x => x.PingResultStatus); - - DNSCheckCommand = ReactiveCommand.CreateFromTask(async () => - { - var testDomain = DomainPendingTest == string.Empty ? "store.steampowered.com" : DomainPendingTest; - try - { - long delayMs; - IPAddress[] address; - if (ProxySettings.UseDoh) - { - var configDoh = ProxySettings.CustomDohAddres2.Value ?? ProxySettingsWindowViewModel.DohAddress.FirstOrDefault() ?? string.Empty; - (delayMs, address) = await networkTestService.TestDNSOverHttpsAsync(testDomain, configDoh); - } - else - { - var configDns = ProxySettings.ProxyMasterDns.Value ?? string.Empty; - (delayMs, address) = await networkTestService.TestDNSAsync(testDomain, configDns, 53); - } - if (address.Length == 0) - throw new Exception("Parsing failed. Return empty ip address."); - - DNSTestDelay = delayMs + "ms "; - DNSTestResult = string.Empty + address.FirstOrDefault(); - } - catch (Exception ex) - { - Log.Error(nameof(AcceleratorPageViewModel), ex.ToString()); - DNSTestDelay = string.Empty; - DNSTestResult = "error"; - } - }); - DNSCheckCommand - .IsExecuting - .ToPropertyEx(this, x => x.IsDNSChecking); - - IPv6CheckCommand = ReactiveCommand.CreateFromTask(async () => - { - var result = await IMicroServiceClient.Instance.Accelerate.GetMyIP(ipV6: true); - if (result.IsSuccess) - { - IsSupportIPv6 = true; - IPv6Address = result.Content ?? string.Empty; - } - else - { - IsSupportIPv6 = false; - IPv6Address = string.Empty; - } - }); - IPv6CheckCommand - .IsExecuting - .ToPropertyEx(this, x => x.IsIPv6Checking); - ProxySettingsCommand = ReactiveCommand.Create(() => { var vm = new ProxySettingsWindowViewModel(); diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs index 3ae539c4be7..d0c4bf29fa9 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/ViewModels/AcceleratorPageViewModel.props.cs @@ -4,76 +4,11 @@ namespace BD.WTTS.UI.ViewModels; public sealed partial class AcceleratorPageViewModel : TabItemViewModel { - public record NATFetchResult(string PublicEndPoint, string LocalEndPoint, string NATLevel, string NATTypeTip, bool PingResult); - - public enum PingStatus - { - Blank, - Ok, - Error, - } - public override string Name => Strings.Welcome; - [Reactive] - public string SelectedSTUNAddress { get; set; } - - public string[] STUNAddress { get; } = - [ - "stun.syncthing.net", - "stun.hot-chilli.net", - "stun.fitauto.ru", - "stun.miwifi.com", - ]; - - [ObservableAsProperty] - public string NATLevel { get; } = string.Empty; - - [ObservableAsProperty] - public string NATTypeTip { get; } = string.Empty; - - [ObservableAsProperty] - public string LocalEndPoint { get; set; } = string.Empty; - - [ObservableAsProperty] - public string PublicEndPoint { get; set; } = string.Empty; - - [ObservableAsProperty] - public PingStatus PingResultStatus { get; } - - [ObservableAsProperty] - public bool IsNATChecking { get; } - - [ObservableAsProperty] - public bool IsDNSChecking { get; } - - [ObservableAsProperty] - public bool IsIPv6Checking { get; } - - [Reactive] - public string DomainPendingTest { get; set; } = string.Empty; - [Reactive] public ReadOnlyCollection? EnableProxyDomainGroupVMs { get; set; } - [Reactive] - public string DNSTestDelay { get; set; } = string.Empty; - - [Reactive] - public string DNSTestResult { get; set; } = string.Empty; - - [Reactive] - public string IPv6Address { get; set; } = string.Empty; - - [Reactive] - public bool IsSupportIPv6 { get; set; } - - public ReactiveCommand NATCheckCommand { get; } - - public ReactiveCommand DNSCheckCommand { get; } - - public ReactiveCommand IPv6CheckCommand { get; } - public ICommand StartProxyCommand { get; } public ICommand RefreshCommand { get; } diff --git a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml.cs b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml.cs index cf39ef283d4..f66a53f222b 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator/UI/Views/Controls/NetworkCheck.axaml.cs @@ -2,24 +2,10 @@ namespace BD.WTTS.UI.Views.Pages; -public partial class NetworkCheck : UserControl, IViewFor +public partial class NetworkCheck : UserControl { public NetworkCheck() { InitializeComponent(); - - Loaded += (_, _) => - { - ViewModel = DataContext as AcceleratorPageViewModel; - - this.OneWayBind(ViewModel, vm => vm.PingResultStatus, v => v.PingOK.IsVisible, result => result == AcceleratorPageViewModel.PingStatus.Ok); - this.OneWayBind(ViewModel, vm => vm.PingResultStatus, v => v.PingError.IsVisible, result => result == AcceleratorPageViewModel.PingStatus.Error); - this.OneWayBind(ViewModel, vm => vm.NATLevel, v => v.NATTextBlock.Text); - this.OneWayBind(ViewModel, vm => vm.NATTypeTip, v => v.NATTypeTip.Text); - }; } - - public AcceleratorPageViewModel? ViewModel { get; set; } - - object? IViewFor.ViewModel { get; set; } } \ No newline at end of file