From 5b82f1799582c19edfd2f0e8b6fe360e4f729ab8 Mon Sep 17 00:00:00 2001 From: DHR60 Date: Fri, 21 Nov 2025 15:56:42 +0800 Subject: [PATCH] Fix (#8363) * Fix * AI-optimized code --- .../ServiceLib/Handler/Fmt/ShadowsocksFmt.cs | 8 ++- .../Manager/ActionPrecheckManager.cs | 50 +++++++++++++------ .../Singbox/SingboxOutboundService.cs | 6 +-- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs index 04f52232..a17a8bd8 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs @@ -73,13 +73,11 @@ public class ShadowsocksFmt : BaseFmt const string beginMarker = "-----BEGIN CERTIFICATE-----\n"; const string endMarker = "\n-----END CERTIFICATE-----"; - var base64Start = beginMarker.Length; - var endIndex = cert.IndexOf(endMarker, base64Start, StringComparison.Ordinal); - var base64Content = cert.Substring(base64Start, endIndex - base64Start); + var base64Content = cert.Replace(beginMarker, "").Replace(endMarker, "").Trim(); // https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172 // Equal signs and commas [and backslashes] must be escaped with a backslash. - base64Content = base64Content.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,"); + base64Content = base64Content.Replace("=", "\\="); pluginArgs += $"certRaw={base64Content};"; } @@ -251,7 +249,7 @@ public class ShadowsocksFmt : BaseFmt { var certBase64 = certRaw.Replace("certRaw=", ""); - certBase64 = certBase64.Replace("\\=", "=").Replace("\\,", ",").Replace("\\\\", "\\"); + certBase64 = certBase64.Replace("\\=", "="); const string beginMarker = "-----BEGIN CERTIFICATE-----\n"; const string endMarker = "\n-----END CERTIFICATE-----"; diff --git a/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs b/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs index 75e3e00e..7b665816 100644 --- a/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs +++ b/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs @@ -10,6 +10,13 @@ public class ActionPrecheckManager(Config config) private readonly Config _config = config; + // sing-box supported transports for different protocol types + private static readonly HashSet SingboxUnsupportedTransports = [nameof(ETransport.kcp), nameof(ETransport.xhttp)]; + private static readonly HashSet SingboxTransportSupportedProtocols = + [EConfigType.VMess, EConfigType.VLESS, EConfigType.Trojan, EConfigType.Shadowsocks]; + private static readonly HashSet SingboxShadowsocksAllowedTransports = + [nameof(ETransport.tcp), nameof(ETransport.ws), nameof(ETransport.quic)]; + public async Task> Check(string? indexId) { if (indexId.IsNullOrEmpty()) @@ -174,26 +181,16 @@ public class ActionPrecheckManager(Config config) return errors; } - var net = item.GetNetwork() ?? item.Network; + var net = item.GetNetwork(); if (coreType == ECoreType.sing_box) { - // sing-box does not support xhttp / kcp - // sing-box does not support transports like ws/http/httpupgrade/etc. when the node is not vmess/trojan/vless - if (net is nameof(ETransport.kcp) or nameof(ETransport.xhttp)) + var transportError = ValidateSingboxTransport(item.ConfigType, net); + if (transportError != null) { - errors.Add(string.Format(ResUI.CoreNotSupportNetwork, nameof(ECoreType.sing_box), net)); + errors.Add(transportError); return errors; } - - if (item.ConfigType is not (EConfigType.VMess or EConfigType.VLESS or EConfigType.Trojan)) - { - if (net is nameof(ETransport.ws) or nameof(ETransport.http) or nameof(ETransport.h2) or nameof(ETransport.quic) or nameof(ETransport.httpupgrade)) - { - errors.Add(string.Format(ResUI.CoreNotSupportProtocolTransport, nameof(ECoreType.sing_box), item.ConfigType.ToString(), net)); - return errors; - } - } } else if (coreType is ECoreType.Xray) { @@ -209,6 +206,31 @@ public class ActionPrecheckManager(Config config) return errors; } + private static string? ValidateSingboxTransport(EConfigType configType, string net) + { + // sing-box does not support xhttp / kcp transports + if (SingboxUnsupportedTransports.Contains(net)) + { + return string.Format(ResUI.CoreNotSupportNetwork, nameof(ECoreType.sing_box), net); + } + + // sing-box does not support non-tcp transports for protocols other than vmess/trojan/vless/shadowsocks + if (!SingboxTransportSupportedProtocols.Contains(configType) && net != nameof(ETransport.tcp)) + { + return string.Format(ResUI.CoreNotSupportProtocolTransport, + nameof(ECoreType.sing_box), configType.ToString(), net); + } + + // sing-box shadowsocks only supports tcp/ws/quic transports + if (configType == EConfigType.Shadowsocks && !SingboxShadowsocksAllowedTransports.Contains(net)) + { + return string.Format(ResUI.CoreNotSupportProtocolTransport, + nameof(ECoreType.sing_box), configType.ToString(), net); + } + + return null; + } + private async Task> ValidateRelatedNodesExistAndValid(ProfileItem? item) { var errors = new List(); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index 1bda5981..5188d177 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -62,13 +62,11 @@ public partial class CoreConfigSingboxService const string beginMarker = "-----BEGIN CERTIFICATE-----\n"; const string endMarker = "\n-----END CERTIFICATE-----"; - var base64Start = beginMarker.Length; - var endIndex = cert.IndexOf(endMarker, base64Start, StringComparison.Ordinal); - var base64Content = cert.Substring(base64Start, endIndex - base64Start); + var base64Content = cert.Replace(beginMarker, "").Replace(endMarker, "").Trim(); // https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172 // Equal signs and commas [and backslashes] must be escaped with a backslash. - base64Content = base64Content.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,"); + base64Content = base64Content.Replace("=", "\\="); pluginArgs += $"certRaw={base64Content};"; }