From 7ea8fae2dadf925eb3a0a51dea1ecf6c89619e15 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 8 Feb 2025 16:43:40 +0800 Subject: [PATCH] Improve test logic Retest the failed part of the test and call it recursively. Remove the number of batches that are automatically divided when testing parameters. --- v2rayN/ServiceLib/Global.cs | 1 + v2rayN/ServiceLib/Handler/CoreHandler.cs | 2 +- v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 9 ++ v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 5 +- v2rayN/ServiceLib/Resx/ResUI.hu.resx | 3 + v2rayN/ServiceLib/Resx/ResUI.resx | 3 + v2rayN/ServiceLib/Resx/ResUI.ru.resx | 3 + v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 3 + v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 3 + .../ServiceLib/Services/SpeedtestService.cs | 136 +++++++++++------- .../ViewModels/OptionSettingViewModel.cs | 6 +- .../ViewModels/ProfilesViewModel.cs | 15 +- .../Views/OptionSettingWindow.axaml | 8 +- .../Views/OptionSettingWindow.axaml.cs | 2 +- v2rayN/v2rayN/Views/OptionSettingWindow.xaml | 8 +- .../v2rayN/Views/OptionSettingWindow.xaml.cs | 2 +- 16 files changed, 134 insertions(+), 75 deletions(-) diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 13d6850b..eb4da4ab 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -72,6 +72,7 @@ namespace ServiceLib public const string LocalAppData = "V2RAYN_LOCAL_APPLICATION_DATA"; public const string V2RayLocalAsset = "V2RAY_LOCATION_ASSET"; public const string XrayLocalAsset = "XRAY_LOCATION_ASSET"; + public const int SpeedTestPageSize = 1000; public static readonly List IEProxyProtocols = [ diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs index 6247704e..dbd93081 100644 --- a/v2rayN/ServiceLib/Handler/CoreHandler.cs +++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs @@ -287,7 +287,7 @@ namespace ServiceLib.Handler catch (Exception ex) { Logging.SaveLog(_tag, ex); - UpdateFunc(true, ex.Message); + UpdateFunc(mayNeedSudo, ex.Message); return null; } } diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 002a10ed..57379b85 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -2094,6 +2094,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Starting retesting failed parts, {0} remaining. Press ESC to terminate... 的本地化字符串。 + /// + public static string SpeedtestingTestFailedPart { + get { + return ResourceManager.GetString("SpeedtestingTestFailedPart", resourceCulture); + } + } + /// /// 查找类似 Waiting for testing (press ESC to terminate)... 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index c412a26e..30bfe20a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1393,4 +1393,7 @@ کپی کردن دستور پروکسی در کلیپ بورد - + + Starting retesting failed parts, {0} remaining. Press ESC to terminate... + + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index dc69d9a5..644cd27a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1393,4 +1393,7 @@ Copy proxy command to clipboard + + Starting retesting failed parts, {0} remaining. Press ESC to terminate... + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 7bc65cf7..35e917d7 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1393,4 +1393,7 @@ Copy proxy command to clipboard + + Starting retesting failed parts, {0} remaining. Press ESC to terminate... + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 190b9fed..1ffbc926 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1393,4 +1393,7 @@ Copy proxy command to clipboard + + Starting retesting failed parts, {0} remaining. Press ESC to terminate... + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 0d62bc6e..b92c348f 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1390,4 +1390,7 @@ 复制终端代理命令至剪贴板 + + 开始对失败部分进行重新测试,剩余 {0} 个。可按 ESC 终止... + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 12f0887c..8b23f65d 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1391,4 +1391,7 @@ 複製終端代理指令至剪貼簿 + + 開始對失敗部分進行重新測試,剩餘 {0} 個。可按 ESC 終止... + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayN/ServiceLib/Services/SpeedtestService.cs index 10c070ea..be08cbdb 100644 --- a/v2rayN/ServiceLib/Services/SpeedtestService.cs +++ b/v2rayN/ServiceLib/Services/SpeedtestService.cs @@ -13,11 +13,69 @@ namespace ServiceLib.Services private bool _exitLoop = false; private static readonly string _tag = "SpeedtestService"; - public SpeedtestService(Config config, List selecteds, ESpeedActionType actionType, Action updateFunc) + public SpeedtestService(Config config, ESpeedActionType actionType, List selecteds, Action updateFunc) { _config = config; _updateFunc = updateFunc; + MessageBus.Current.Listen(EMsgCommand.StopSpeedtest.ToString()).Subscribe(ExitLoop); + + Task.Run(async () => + { + var lstSelected = GetClearItem(actionType, selecteds); + await RunAsync(actionType, lstSelected); + UpdateFunc("", ResUI.SpeedtestingCompleted); + }); + } + + private async Task RunAsync(ESpeedActionType actionType, List lstSelected, int pageSize = 0) + { + if (actionType == ESpeedActionType.Tcping) + { + await RunTcpingAsync(lstSelected); + return; + } + + if (pageSize <= 0) + { + pageSize = lstSelected.Count < Global.SpeedTestPageSize ? lstSelected.Count : Global.SpeedTestPageSize; + } + var lstTest = GetTestBatchItem(lstSelected, pageSize); + + List lstFailed = new(); + foreach (var lst in lstTest) + { + var ret = actionType switch + { + ESpeedActionType.Realping => await RunRealPingAsync(lst), + ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst), + ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst), + _ => true + }; + if (ret == false) + { + lstFailed.AddRange(lst); + } + await Task.Delay(100); + } + + //Retest the failed part + var pageSizeNext = pageSize / 2; + if (lstFailed.Count > 0 && pageSizeNext > 0) + { + if (_exitLoop) + { + UpdateFunc("", ResUI.SpeedtestingSkip); + return; + } + + UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count)); + await RunAsync(actionType, lstFailed, pageSizeNext); + } + } + + private List GetClearItem(ESpeedActionType actionType, List selecteds) + { var lstSelected = new List(); foreach (var it in selecteds) { @@ -25,10 +83,12 @@ namespace ServiceLib.Services { continue; } + if (it.Port <= 0) { continue; } + lstSelected.Add(new ServerTestItem() { IndexId = it.IndexId, @@ -62,25 +122,11 @@ namespace ServiceLib.Services } } - MessageBus.Current.Listen(EMsgCommand.StopSpeedtest.ToString()).Subscribe(ExitLoop); - - Task.Run(async () => { await RunAsync(actionType, lstSelected); }); + return lstSelected; } - private async Task RunAsync(ESpeedActionType actionType, List lstSelected) + private List> GetTestBatchItem(List lstSelected, int pageSize) { - if (actionType == ESpeedActionType.Tcping) - { - await RunTcpingAsync(lstSelected); - return; - } - - var pageSize = _config.SpeedTestItem.SpeedTestPageSize; - if (pageSize is <= 0 or > 1000) - { - pageSize = 1000; - } - List> lstTest = new(); var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard)).ToList(); var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard).ToList(); @@ -94,27 +140,7 @@ namespace ServiceLib.Services lstTest.Add(lst2.Skip(num * pageSize).Take(pageSize).ToList()); } - foreach (var lst in lstTest) - { - switch (actionType) - { - case ESpeedActionType.Realping: - await RunRealPingAsync(lst); - break; - - case ESpeedActionType.Speedtest: - await RunSpeedTestAsync(lst); - break; - - case ESpeedActionType.Mixedtest: - await RunMixedTestAsync(lst); - break; - } - - await Task.Delay(100); - } - - UpdateFunc("", ResUI.SpeedtestingCompleted); + return lstTest; } private void ExitLoop(string x) @@ -164,7 +190,7 @@ namespace ServiceLib.Services } } - private async Task RunRealPingAsync(List selecteds) + private async Task RunRealPingAsync(List selecteds) { var pid = -1; try @@ -172,8 +198,7 @@ namespace ServiceLib.Services pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); if (pid < 0) { - UpdateFunc("", ResUI.FailedToRunCore); - return; + return false; } var downloadHandle = new DownloadService(); @@ -221,16 +246,16 @@ namespace ServiceLib.Services } await ProfileExHandler.Instance.SaveTo(); } + return true; } - private async Task RunSpeedTestAsync(List selecteds) + private async Task RunSpeedTestAsync(List selecteds) { var pid = -1; pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); if (pid < 0) { - UpdateFunc("", ResUI.FailedToRunCore); - return; + return false; } var url = _config.SpeedTestItem.SpeedTestUrl; @@ -283,16 +308,16 @@ namespace ServiceLib.Services await ProcUtils.ProcessKill(pid); } await ProfileExHandler.Instance.SaveTo(); + return true; } - private async Task RunSpeedTestMulti(List selecteds) + private async Task RunSpeedTestMulti(List selecteds) { var pid = -1; pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); if (pid < 0) { - UpdateFunc("", ResUI.FailedToRunCore); - return; + return false; } var url = _config.SpeedTestItem.SpeedTestUrl; @@ -348,21 +373,30 @@ namespace ServiceLib.Services await ProcUtils.ProcessKill(pid); } await ProfileExHandler.Instance.SaveTo(); + return true; } - private async Task RunMixedTestAsync(List selecteds) + private async Task RunMixedTestAsync(List selecteds) { - await RunRealPingAsync(selecteds); + var ret = await RunRealPingAsync(selecteds); + if (ret == false) + { + return false; + } await Task.Delay(1000); - await RunSpeedTestMulti(selecteds); + var ret2 = await RunSpeedTestMulti(selecteds); + if (ret2 == false) + { + return false; + } + return true; } private async Task GetRealPingTime(DownloadService downloadHandle, IWebProxy webProxy) { var responseTime = await downloadHandle.GetRealPingTime(_config.SpeedTestItem.SpeedPingTestUrl, webProxy, 10); - //string output = Utile.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status; return FormatOut(responseTime, Global.DelayUnit); } diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 6dfa40c3..6e94c381 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -63,7 +63,7 @@ namespace ServiceLib.ViewModels [Reactive] public int SpeedTestTimeout { get; set; } [Reactive] public string SpeedTestUrl { get; set; } [Reactive] public string SpeedPingTestUrl { get; set; } - [Reactive] public int SpeedTestPageSize { get; set; } + //[Reactive] public int SpeedTestPageSize { get; set; } [Reactive] public bool EnableHWA { get; set; } [Reactive] public string SubConvertUrl { get; set; } [Reactive] public int MainGirdOrientation { get; set; } @@ -178,7 +178,7 @@ namespace ServiceLib.ViewModels CurrentFontFamily = _config.UiItem.CurrentFontFamily; SpeedTestTimeout = _config.SpeedTestItem.SpeedTestTimeout; SpeedTestUrl = _config.SpeedTestItem.SpeedTestUrl; - SpeedTestPageSize = _config.SpeedTestItem.SpeedTestPageSize; + //SpeedTestPageSize = _config.SpeedTestItem.SpeedTestPageSize; SpeedPingTestUrl = _config.SpeedTestItem.SpeedPingTestUrl; EnableHWA = _config.GuiItem.EnableHWA; SubConvertUrl = _config.ConstItem.SubConvertUrl; @@ -332,7 +332,7 @@ namespace ServiceLib.ViewModels _config.GuiItem.TrayMenuServersLimit = TrayMenuServersLimit; _config.UiItem.CurrentFontFamily = CurrentFontFamily; _config.SpeedTestItem.SpeedTestTimeout = SpeedTestTimeout; - _config.SpeedTestItem.SpeedTestPageSize = SpeedTestPageSize; + //_config.SpeedTestItem.SpeedTestPageSize = SpeedTestPageSize; _config.SpeedTestItem.SpeedTestUrl = SpeedTestUrl; _config.SpeedTestItem.SpeedPingTestUrl = SpeedPingTestUrl; _config.GuiItem.EnableHWA = EnableHWA; diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index 759ab34d..bfaadf0b 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -259,11 +259,6 @@ namespace ServiceLib.ViewModels Locator.Current.GetService()?.Reload(); } - private void UpdateSpeedtestHandler(SpeedTestResult result) - { - _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result); - } - public void SetSpeedTestResult(SpeedTestResult result) { if (Utils.IsNullOrEmpty(result.IndexId)) @@ -272,7 +267,7 @@ namespace ServiceLib.ViewModels NoticeHandler.Instance.Enqueue(result.Delay); return; } - var item = _profileItems.Where(it => it.IndexId == result.IndexId).FirstOrDefault(); + var item = _profileItems.FirstOrDefault(it => it.IndexId == result.IndexId); if (item != null) { if (Utils.IsNotEmpty(result.Delay)) @@ -293,7 +288,7 @@ namespace ServiceLib.ViewModels { try { - var item = _profileItems.Where(it => it.IndexId == update.IndexId).FirstOrDefault(); + var item = _profileItems.FirstOrDefault(it => it.IndexId == update.IndexId); if (item != null) { item.TodayDown = Utils.HumanFy(update.TodayDown); @@ -726,9 +721,11 @@ namespace ServiceLib.ViewModels { return; } - //ClearTestResult(); - _ = new SpeedtestService(_config, lstSelecteds, actionType, UpdateSpeedtestHandler); + _ = new SpeedtestService(_config, actionType, lstSelecteds, (SpeedTestResult result) => + { + _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result); + }); } public void ServerSpeedtestStop() diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index 88c8e2aa..de3b5229 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -1,4 +1,4 @@ - - + - \ No newline at end of file + diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs index 3b08d8be..95da6e78 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs @@ -139,7 +139,7 @@ namespace v2rayN.Desktop.Views this.Bind(ViewModel, vm => vm.SpeedTestTimeout, v => v.cmbSpeedTestTimeout.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SpeedTestUrl, v => v.cmbSpeedTestUrl.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SpeedPingTestUrl, v => v.cmbSpeedPingTestUrl.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.SpeedTestPageSize, v => v.txtSpeedTestPageSize.Text).DisposeWith(disposables); + //this.Bind(ViewModel, vm => vm.SpeedTestPageSize, v => v.txtSpeedTestPageSize.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.MainGirdOrientation, v => v.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.GeoFileSourceUrl, v => v.cmbGetFilesSourceUrl.SelectedValue).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml index 606b91d2..b7a4310a 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -1,4 +1,4 @@ - - + - \ No newline at end of file + diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs index f5c63608..4d2bb23e 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs @@ -150,7 +150,7 @@ namespace v2rayN.Views this.Bind(ViewModel, vm => vm.SpeedTestTimeout, v => v.cmbSpeedTestTimeout.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SpeedTestUrl, v => v.cmbSpeedTestUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SpeedPingTestUrl, v => v.cmbSpeedPingTestUrl.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.SpeedTestPageSize, v => v.txtSpeedTestPageSize.Text).DisposeWith(disposables); + //this.Bind(ViewModel, vm => vm.SpeedTestPageSize, v => v.txtSpeedTestPageSize.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableHWA, v => v.togEnableHWA.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.MainGirdOrientation, v => v.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables);