diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 0e874ae0..f54502e6 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -64,8 +64,6 @@ namespace ServiceLib public const string GrpcGunMode = "gun"; public const string GrpcMultiMode = "multi"; public const int MaxPort = 65536; - public const string DelayUnit = ""; - public const string SpeedUnit = ""; public const int MinFontSize = 8; public const string RebootAs = "rebootas"; public const string AvaAssets = "avares://v2rayN/Assets/"; @@ -105,10 +103,10 @@ namespace ServiceLib public static readonly List<string> SpeedTestUrls = [ - @"https://speed.cloudflare.com/__down?bytes=100000000", - @"https://speed.cloudflare.com/__down?bytes=50000000", + @"https://cachefly.cachefly.net/50mb.test", @"https://speed.cloudflare.com/__down?bytes=10000000", - @"https://cachefly.cachefly.net/50mb.test" + @"https://speed.cloudflare.com/__down?bytes=50000000", + @"https://speed.cloudflare.com/__down?bytes=100000000", ]; public static readonly List<string> SpeedPingTestUrls = diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index e454b461..464a8222 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -754,9 +754,9 @@ namespace ServiceLib.Handler Security = t.Security, Network = t.Network, StreamSecurity = t.StreamSecurity, - Delay = t33 == null ? 0 : t33.Delay, - Speed = t33 == null ? 0 : t33.Speed, - Sort = t33 == null ? 0 : t33.Sort + Delay = t33?.Delay ?? 0, + Speed = t33?.Speed ?? 0, + Sort = t33?.Sort ?? 0 }).ToList(); Enum.TryParse(colName, true, out EServerColName name); diff --git a/v2rayN/ServiceLib/Handler/ProfileExHandler.cs b/v2rayN/ServiceLib/Handler/ProfileExHandler.cs index e7e2fef5..4743696d 100644 --- a/v2rayN/ServiceLib/Handler/ProfileExHandler.cs +++ b/v2rayN/ServiceLib/Handler/ProfileExHandler.cs @@ -1,4 +1,4 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; //using System.Reactive.Linq; @@ -8,7 +8,7 @@ namespace ServiceLib.Handler { private static readonly Lazy<ProfileExHandler> _instance = new(() => new()); private ConcurrentBag<ProfileExItem> _lstProfileEx = []; - private Queue<string> _queIndexIds = new(); + private readonly Queue<string> _queIndexIds = new(); public static ProfileExHandler Instance => _instance.Value; private static readonly string _tag = "ProfileExHandler"; @@ -59,7 +59,7 @@ namespace ServiceLib.Handler List<ProfileExItem> lstInserts = []; List<ProfileExItem> lstUpdates = []; - for (int i = 0; i < cnt; i++) + for (var i = 0; i < cnt; i++) { var id = _queIndexIds.Dequeue(); var item = lstExists.FirstOrDefault(t => t.IndexId == id); @@ -78,13 +78,18 @@ namespace ServiceLib.Handler lstInserts.Add(itemNew); } } + try { - if (lstInserts.Count() > 0) + if (lstInserts.Count > 0) + { await SQLiteHelper.Instance.InsertAllAsync(lstInserts); + } - if (lstUpdates.Count() > 0) + if (lstUpdates.Count > 0) + { await SQLiteHelper.Instance.UpdateAllAsync(lstUpdates); + } } catch (Exception ex) { @@ -93,17 +98,24 @@ namespace ServiceLib.Handler } } - private void AddProfileEx(string indexId, ref ProfileExItem? profileEx) + private ProfileExItem AddProfileEx(string indexId) { - profileEx = new() + var profileEx = new ProfileExItem() { IndexId = indexId, Delay = 0, Speed = 0, - Sort = 0 + Sort = 0, + Message = string.Empty }; _lstProfileEx.Add(profileEx); IndexIdEnqueue(indexId); + return profileEx; + } + + private ProfileExItem GetProfileExItem(string? indexId) + { + return _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId) ?? AddProfileEx(indexId); } public async Task ClearAll() @@ -124,39 +136,34 @@ namespace ServiceLib.Handler } } - public void SetTestDelay(string indexId, string delayVal) + public void SetTestDelay(string indexId, int delay) { - var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId); - if (profileEx == null) - { - AddProfileEx(indexId, ref profileEx); - } + var profileEx = GetProfileExItem(indexId); - int.TryParse(delayVal, out int delay); profileEx.Delay = delay; IndexIdEnqueue(indexId); } - public void SetTestSpeed(string indexId, string speedVal) + public void SetTestSpeed(string indexId, decimal speed) { - var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId); - if (profileEx == null) - { - AddProfileEx(indexId, ref profileEx); - } + var profileEx = GetProfileExItem(indexId); - decimal.TryParse(speedVal, out decimal speed); profileEx.Speed = speed; IndexIdEnqueue(indexId); } + public void SetTestMessage(string indexId, string message) + { + var profileEx = GetProfileExItem(indexId); + + profileEx.Message = message; + IndexIdEnqueue(indexId); + } + public void SetSort(string indexId, int sort) { - var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId); - if (profileEx == null) - { - AddProfileEx(indexId, ref profileEx); - } + var profileEx = GetProfileExItem(indexId); + profileEx.Sort = sort; IndexIdEnqueue(indexId); } @@ -180,4 +187,4 @@ namespace ServiceLib.Handler return _lstProfileEx.Max(t => t == null ? 0 : t.Sort); } } -} \ No newline at end of file +} diff --git a/v2rayN/ServiceLib/Models/ProfileExItem.cs b/v2rayN/ServiceLib/Models/ProfileExItem.cs index afa7918d..c1c7174c 100644 --- a/v2rayN/ServiceLib/Models/ProfileExItem.cs +++ b/v2rayN/ServiceLib/Models/ProfileExItem.cs @@ -1,4 +1,4 @@ -using SQLite; +using SQLite; namespace ServiceLib.Models { @@ -11,5 +11,6 @@ namespace ServiceLib.Models public int Delay { get; set; } public decimal Speed { get; set; } public int Sort { get; set; } + public string? Message { get; set; } } -} \ No newline at end of file +} diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 57379b85..8305d33d 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -196,7 +196,7 @@ namespace ServiceLib.Resx { } /// <summary> - /// 查找类似 Failed to run Core, please see the log 的本地化字符串。 + /// 查找类似 Failed to run Core, please check the prompt information 的本地化字符串。 /// </summary> public static string FailedToRunCore { get { diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 35e917d7..d8539c5d 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -926,7 +926,7 @@ <value>Speed(M/s)</value> </data> <data name="FailedToRunCore" xml:space="preserve"> - <value>Failed to run Core, please see the log</value> + <value>Failed to run Core, please check the prompt information</value> </data> <data name="LvFilter" xml:space="preserve"> <value>Remarks regular filter</value> diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index b92c348f..6acb7575 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -926,7 +926,7 @@ <value>速度(M/s)</value> </data> <data name="FailedToRunCore" xml:space="preserve"> - <value>运行Core失败,请查看日志</value> + <value>运行 Core 失败,请查看提示信息</value> </data> <data name="LvFilter" xml:space="preserve"> <value>别名正则过滤</value> diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 8b23f65d..49f1af36 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -927,7 +927,7 @@ <value>速度(M/s)</value> </data> <data name="FailedToRunCore" xml:space="preserve"> - <value>執行Core失敗,請查閲日誌</value> + <value>執行Core失敗,請查看提示訊息</value> </data> <data name="LvFilter" xml:space="preserve"> <value>別名正則過濾</value> diff --git a/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayN/ServiceLib/Services/SpeedtestService.cs index 6fe94284..ede19c1e 100644 --- a/v2rayN/ServiceLib/Services/SpeedtestService.cs +++ b/v2rayN/ServiceLib/Services/SpeedtestService.cs @@ -62,7 +62,7 @@ namespace ServiceLib.Services break; case ESpeedActionType.Mixedtest: - await RunMixedTestAsync(lstSelected, 5, exitLoopKey); + await RunMixedTestAsync(lstSelected, 6, exitLoopKey); break; } } @@ -100,18 +100,18 @@ namespace ServiceLib.Services case ESpeedActionType.Tcping: case ESpeedActionType.Realping: UpdateFunc(it.IndexId, ResUI.Speedtesting, ""); - ProfileExHandler.Instance.SetTestDelay(it.IndexId, "0"); + ProfileExHandler.Instance.SetTestDelay(it.IndexId, 0); break; case ESpeedActionType.Speedtest: UpdateFunc(it.IndexId, "", ResUI.SpeedtestingWait); - ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "0"); + ProfileExHandler.Instance.SetTestSpeed(it.IndexId, 0); break; case ESpeedActionType.Mixedtest: UpdateFunc(it.IndexId, ResUI.Speedtesting, ResUI.SpeedtestingWait); - ProfileExHandler.Instance.SetTestDelay(it.IndexId, "0"); - ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "0"); + ProfileExHandler.Instance.SetTestDelay(it.IndexId, 0); + ProfileExHandler.Instance.SetTestSpeed(it.IndexId, 0); break; } } @@ -132,11 +132,10 @@ namespace ServiceLib.Services { try { - var time = await GetTcpingTime(it.Address, it.Port); - var output = FormatOut(time, Global.DelayUnit); + var responseTime = await GetTcpingTime(it.Address, it.Port); - ProfileExHandler.Instance.SetTestDelay(it.IndexId, output); - UpdateFunc(it.IndexId, output); + ProfileExHandler.Instance.SetTestDelay(it.IndexId, responseTime); + UpdateFunc(it.IndexId, responseTime.ToString()); } catch (Exception ex) { @@ -145,6 +144,7 @@ namespace ServiceLib.Services })); } Task.WaitAll([.. tasks]); + await Task.CompletedTask; } private async Task RunRealPingBatchAsync(List<ServerTestItem> lstSelected, string exitLoopKey, int pageSize = 0) @@ -282,15 +282,13 @@ namespace ServiceLib.Services { var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}"); var responseTime = await downloadHandle.GetRealPingTime(_config.SpeedTestItem.SpeedPingTestUrl, webProxy, 10); - var output = FormatOut(responseTime, Global.DelayUnit); - ProfileExHandler.Instance.SetTestDelay(it.IndexId, output); - UpdateFunc(it.IndexId, output); + ProfileExHandler.Instance.SetTestDelay(it.IndexId, responseTime); + UpdateFunc(it.IndexId, responseTime.ToString()); } private async Task DoSpeedTest(DownloadService downloadHandle, ServerTestItem it) { - ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1"); UpdateFunc(it.IndexId, "", ResUI.Speedtesting); var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}"); @@ -301,7 +299,7 @@ namespace ServiceLib.Services decimal.TryParse(msg, out var dec); if (dec > 0) { - ProfileExHandler.Instance.SetTestSpeed(it.IndexId, msg); + ProfileExHandler.Instance.SetTestSpeed(it.IndexId, dec); } UpdateFunc(it.IndexId, "", msg); }); @@ -326,7 +324,10 @@ namespace ServiceLib.Services var result = clientSocket.BeginConnect(endPoint, null, null); if (!result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5))) + { throw new TimeoutException("connect timeout (5s): " + url); + } + clientSocket.EndConnect(result); timer.Stop(); @@ -357,14 +358,13 @@ namespace ServiceLib.Services return lstTest; } - private string FormatOut(object time, string unit) - { - return $"{time}"; - } - private void UpdateFunc(string indexId, string delay, string speed = "") { _updateFunc?.Invoke(new() { IndexId = indexId, Delay = delay, Speed = speed }); + if (indexId.IsNotEmpty() && speed.IsNotEmpty()) + { + ProfileExHandler.Instance.SetTestMessage(indexId, speed); + } } } } diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index e3106307..6aa7c17d 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -269,20 +269,22 @@ namespace ServiceLib.ViewModels return; } var item = _profileItems.FirstOrDefault(it => it.IndexId == result.IndexId); - if (item != null) + if (item == null) { - if (Utils.IsNotEmpty(result.Delay)) - { - int.TryParse(result.Delay, out int temp); - item.Delay = temp; - item.DelayVal = $"{result.Delay} {Global.DelayUnit}"; - } - if (Utils.IsNotEmpty(result.Speed)) - { - item.SpeedVal = $"{result.Speed} {Global.SpeedUnit}"; - } - _profileItems.Replace(item, JsonUtils.DeepCopy(item)); + return; } + + if (Utils.IsNotEmpty(result.Delay)) + { + int.TryParse(result.Delay, out var temp); + item.Delay = temp; + item.DelayVal = result.Delay ?? string.Empty; + } + if (Utils.IsNotEmpty(result.Speed)) + { + item.SpeedVal = result.Speed ?? string.Empty; + } + _profileItems.Replace(item, JsonUtils.DeepCopy(item)); } public void UpdateStatistics(ServerSpeedItem update) @@ -421,10 +423,11 @@ namespace ServiceLib.ViewModels Subid = t.Subid, SubRemarks = t.SubRemarks, IsActive = t.IndexId == _config.IndexId, - Sort = t33 == null ? 0 : t33.Sort, - Delay = t33 == null ? 0 : t33.Delay, - DelayVal = t33?.Delay != 0 ? $"{t33?.Delay} {Global.DelayUnit}" : string.Empty, - SpeedVal = t33?.Speed != 0 ? $"{t33?.Speed} {Global.SpeedUnit}" : string.Empty, + Sort = t33?.Sort ?? 0, + Delay = t33?.Delay ?? 0, + Speed = t33?.Speed ?? 0, + DelayVal = t33?.Delay != 0 ? $"{t33?.Delay}" : string.Empty, + SpeedVal = t33?.Speed > 0 ? $"{t33?.Speed}" : t33?.Message ?? string.Empty, TodayDown = t22 == null ? "" : Utils.HumanFy(t22.TodayDown), TodayUp = t22 == null ? "" : Utils.HumanFy(t22.TodayUp), TotalDown = t22 == null ? "" : Utils.HumanFy(t22.TotalDown),