From 8a707cfb903cc9bd0bc640fd732ee989c62ec9b3 Mon Sep 17 00:00:00 2001 From: DHR60 Date: Sat, 13 Sep 2025 10:37:20 +0800 Subject: [PATCH] Refactor --- .../Singbox/CoreConfigSingboxService.cs | 2 +- .../Singbox/SingboxOutboundService.cs | 76 ++++++++++++++++++- .../Singbox/SingboxRoutingService.cs | 2 +- .../V2ray/CoreConfigV2rayService.cs | 2 +- .../CoreConfig/V2ray/V2rayBalancerService.cs | 6 +- .../CoreConfig/V2ray/V2rayOutboundService.cs | 30 +++++++- .../CoreConfig/V2ray/V2rayRoutingService.cs | 2 +- .../ViewModels/AddGroupServerViewModel.cs | 1 - .../v2rayN/Views/AddGroupServerWindow.xaml.cs | 4 +- 9 files changed, 109 insertions(+), 16 deletions(-) diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs index 4c89afec..b1432372 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs @@ -451,7 +451,7 @@ public partial class CoreConfigSingboxService(Config config) ret.Msg = ResUI.FailedGenDefaultConfiguration; return ret; } - await GenOutboundsList(proxyProfiles, singboxConfig, multipleLoad); + await GenOutboundsListWithChain(proxyProfiles, singboxConfig, multipleLoad); await GenDns(null, singboxConfig); await ConvertGeo2Ruleset(singboxConfig); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index d4832ca2..684bebac 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -179,13 +179,21 @@ public partial class CoreConfigSingboxService if (node.ConfigType == EConfigType.WireGuard) { var endpoint = JsonUtils.Deserialize(txtOutbound); - await GenEndpoint(node, endpoint); + var ret = await GenEndpoint(node, endpoint); + if (ret != 0) + { + return null; + } return endpoint; } else { var outbound = JsonUtils.Deserialize(txtOutbound); - await GenOutbound(node, outbound); + var ret = await GenOutbound(node, outbound); + if (ret != 0) + { + return null; + } return outbound; } } @@ -410,7 +418,7 @@ public partial class CoreConfigSingboxService return 0; } - private async Task GenOutboundsList(List nodes, SingboxConfig singboxConfig, EMultipleLoad multipleLoad, string baseTagName = Global.ProxyTag) + private async Task GenOutboundsListWithChain(List nodes, SingboxConfig singboxConfig, EMultipleLoad multipleLoad, string baseTagName = Global.ProxyTag) { try { @@ -458,7 +466,7 @@ public partial class CoreConfigSingboxService var ret = node.ConfigType switch { EConfigType.PolicyGroup => - await GenOutboundsList(childProfiles, singboxConfig, profileGroupItem.MultipleLoad, childBaseTagName), + await GenOutboundsListWithChain(childProfiles, singboxConfig, profileGroupItem.MultipleLoad, childBaseTagName), EConfigType.ProxyChain => await GenChainOutboundsList(childProfiles, singboxConfig, childBaseTagName), _ => throw new NotImplementedException() @@ -612,6 +620,66 @@ public partial class CoreConfigSingboxService return null; } + private async Task GenOutboundsList(List nodes, SingboxConfig singboxConfig, EMultipleLoad multipleLoad, string baseTagName = Global.ProxyTag) + { + var resultOutbounds = new List(); + var resultEndpoints = new List(); // For endpoints + var proxyTags = new List(); // For selector and urltest outbounds + for (var i = 0; i < nodes.Count; i++) + { + var node = nodes[i]; + var server = await GenServer(node); + if (server is null) + { + break; + } + server.tag = baseTagName + (i + 1).ToString(); + if (server is Endpoints4Sbox endpoint) + { + resultEndpoints.Add(endpoint); + } + else if (server is Outbound4Sbox outbound) + { + resultOutbounds.Add(outbound); + } + proxyTags.Add(server.tag); + } + // Add urltest outbound (auto selection based on latency) + if (proxyTags.Count > 0) + { + var outUrltest = new Outbound4Sbox + { + type = "urltest", + tag = $"{baseTagName}-auto", + outbounds = proxyTags, + interrupt_exist_connections = false, + }; + if (multipleLoad == EMultipleLoad.Fallback) + { + outUrltest.tolerance = 5000; + } + // Add selector outbound (manual selection) + var outSelector = new Outbound4Sbox + { + type = "selector", + tag = baseTagName, + outbounds = JsonUtils.DeepCopy(proxyTags), + interrupt_exist_connections = false, + }; + outSelector.outbounds.Insert(0, outUrltest.tag); + // Insert these at the beginning + resultOutbounds.Insert(0, outUrltest); + resultOutbounds.Insert(0, outSelector); + } + singboxConfig.outbounds ??= new(); + resultOutbounds.AddRange(singboxConfig.outbounds); + singboxConfig.outbounds = resultOutbounds; + singboxConfig.endpoints ??= new(); + resultEndpoints.AddRange(singboxConfig.endpoints); + singboxConfig.endpoints = resultEndpoints; + return await Task.FromResult(0); + } + private async Task GenChainOutboundsList(List nodes, SingboxConfig singboxConfig, string baseTagName = Global.ProxyTag) { var resultOutbounds = new List(); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs index 2dd63349..b1a4b44f 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs @@ -403,7 +403,7 @@ public partial class CoreConfigSingboxService var ret = node.ConfigType switch { EConfigType.PolicyGroup => - await GenOutboundsList(childProfiles, singboxConfig, profileGroupItem.MultipleLoad, childBaseTagName), + await GenOutboundsListWithChain(childProfiles, singboxConfig, profileGroupItem.MultipleLoad, childBaseTagName), EConfigType.ProxyChain => await GenChainOutboundsList(childProfiles, singboxConfig, childBaseTagName), _ => throw new NotImplementedException() diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs index 11f4e847..5d1a4d10 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs @@ -180,7 +180,7 @@ public partial class CoreConfigV2rayService(Config config) ret.Msg = ResUI.FailedGenDefaultConfiguration; return ret; } - await GenOutboundsList(proxyProfiles, v2rayConfig); + await GenOutboundsListWithChain(proxyProfiles, v2rayConfig); //add balancers await GenObservatory(v2rayConfig, multipleLoad); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayBalancerService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayBalancerService.cs index f703e8d1..028782e9 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayBalancerService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayBalancerService.cs @@ -2,13 +2,13 @@ namespace ServiceLib.Services.CoreConfig; public partial class CoreConfigV2rayService { - private async Task GenObservatory(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad) + private async Task GenObservatory(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad, string baseTagName = Global.ProxyTag) { if (multipleLoad == EMultipleLoad.LeastPing) { var observatory = new Observatory4Ray { - subjectSelector = [Global.ProxyTag], + subjectSelector = [baseTagName], probeUrl = AppManager.Instance.Config.SpeedTestItem.SpeedPingTestUrl, probeInterval = "3m", enableConcurrency = true, @@ -19,7 +19,7 @@ public partial class CoreConfigV2rayService { var burstObservatory = new BurstObservatory4Ray { - subjectSelector = [Global.ProxyTag], + subjectSelector = [baseTagName], pingConfig = new() { destination = AppManager.Instance.Config.SpeedTestItem.SpeedPingTestUrl, diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs index f383c216..d15d2285 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs @@ -552,7 +552,7 @@ public partial class CoreConfigV2rayService return 0; } - private async Task GenOutboundsList(List nodes, V2rayConfig v2rayConfig, string baseTagName = Global.ProxyTag) + private async Task GenOutboundsListWithChain(List nodes, V2rayConfig v2rayConfig, string baseTagName = Global.ProxyTag) { try { @@ -597,7 +597,7 @@ public partial class CoreConfigV2rayService var ret = node.ConfigType switch { EConfigType.PolicyGroup => - await GenOutboundsList(childProfiles, v2rayConfig, childBaseTagName), + await GenOutboundsListWithChain(childProfiles, v2rayConfig, childBaseTagName), EConfigType.ProxyChain => await GenChainOutboundsList(childProfiles, v2rayConfig, childBaseTagName), _ => throw new NotImplementedException() @@ -721,6 +721,32 @@ public partial class CoreConfigV2rayService return null; } + private async Task GenOutboundsList(List nodes, V2rayConfig v2rayConfig, string baseTagName = Global.ProxyTag) + { + var resultOutbounds = new List(); + for (var i = 0; i < nodes.Count; i++) + { + var node = nodes[i]; + var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound); + if (txtOutbound.IsNullOrEmpty()) + { + break; + } + var outbound = JsonUtils.Deserialize(txtOutbound); + var result = await GenOutbound(node, outbound); + if (result != 0) + { + break; + } + outbound.tag = baseTagName + (i + 1).ToString(); + resultOutbounds.Add(outbound); + } + v2rayConfig.outbounds ??= new(); + resultOutbounds.AddRange(v2rayConfig.outbounds); + v2rayConfig.outbounds = resultOutbounds; + return await Task.FromResult(0); + } + private async Task GenChainOutboundsList(List nodes, V2rayConfig v2RayConfig, string baseTagName = Global.ProxyTag) { var resultOutbounds = new List(); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs index 50862c66..fe939f9a 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs @@ -159,7 +159,7 @@ public partial class CoreConfigV2rayService var ret = node.ConfigType switch { EConfigType.PolicyGroup => - await GenOutboundsList(childProfiles, v2rayConfig, childBaseTagName), + await GenOutboundsListWithChain(childProfiles, v2rayConfig, childBaseTagName), EConfigType.ProxyChain => await GenChainOutboundsList(childProfiles, v2rayConfig, childBaseTagName), _ => throw new NotImplementedException() diff --git a/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs index b54dbe09..4a6af40e 100644 --- a/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs @@ -1,4 +1,3 @@ -using System.Data; using System.Reactive; using DynamicData.Binding; using ReactiveUI; diff --git a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs index cf3fa354..70d8cf1f 100644 --- a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs @@ -1,8 +1,8 @@ +using System.Reactive.Disposables; using System.Windows; using System.Windows.Input; -using ReactiveUI; -using System.Reactive.Disposables; using DynamicData; +using ReactiveUI; namespace v2rayN.Views;