From 3885ff8b31d99c82c44059c05b441cd31d0b23cb Mon Sep 17 00:00:00 2001 From: DHR60 Date: Mon, 8 Dec 2025 19:55:27 +0800 Subject: [PATCH] Fix Shadowsocks Fmt (#8462) --- .../ServiceLib/Handler/Fmt/ShadowsocksFmt.cs | 23 +++++++++++++++---- .../Singbox/SingboxOutboundService.cs | 10 +++++--- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs index f7941527..62f9e120 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs @@ -57,7 +57,10 @@ public class ShadowsocksFmt : BaseFmt { pluginArgs += "mode=websocket;"; pluginArgs += $"host={item.RequestHost};"; - pluginArgs += $"path={item.Path};"; + // https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172 + // Equal signs and commas [and backslashes] must be escaped with a backslash. + var path = item.Path.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,"); + pluginArgs += $"path={path};"; } else if (item.Network == nameof(ETransport.quic)) { @@ -75,8 +78,6 @@ public class ShadowsocksFmt : BaseFmt 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("=", "\\="); pluginArgs += $"certRaw={base64Content};"; @@ -85,6 +86,7 @@ public class ShadowsocksFmt : BaseFmt if (pluginArgs.Length > 0) { plugin = "v2ray-plugin"; + pluginArgs += "mux=0;"; } } @@ -222,6 +224,7 @@ public class ShadowsocksFmt : BaseFmt var path = pluginParts.FirstOrDefault(t => t.StartsWith("path=")); var hasTls = pluginParts.Any(t => t == "tls"); var certRaw = pluginParts.FirstOrDefault(t => t.StartsWith("certRaw=")); + var mux = pluginParts.FirstOrDefault(t => t.StartsWith("mux=")); var modeValue = mode.Replace("mode=", ""); if (modeValue == "websocket") @@ -234,7 +237,9 @@ public class ShadowsocksFmt : BaseFmt } if (!path.IsNullOrEmpty()) { - item.Path = path.Replace("path=", ""); + var pathValue = path.Replace("path=", ""); + pathValue = pathValue.Replace("\\=", "=").Replace("\\,", ",").Replace("\\\\", "\\"); + item.Path = pathValue; } } else if (modeValue == "quic") @@ -258,6 +263,16 @@ public class ShadowsocksFmt : BaseFmt item.Cert = certPem; } } + + if (!mux.IsNullOrEmpty()) + { + var muxValue = mux.Replace("mux=", ""); + var muxCount = muxValue.ToInt(); + if (muxCount > 0) + { + return null; + } + } } } diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index f18f833c..79b10176 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -46,7 +46,10 @@ public partial class CoreConfigSingboxService { pluginArgs += "mode=websocket;"; pluginArgs += $"host={node.RequestHost};"; - pluginArgs += $"path={node.Path};"; + // https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172 + // Equal signs and commas [and backslashes] must be escaped with a backslash. + var path = node.Path.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,"); + pluginArgs += $"path={path};"; } else if (node.Network == nameof(ETransport.quic)) { @@ -64,8 +67,6 @@ public partial class CoreConfigSingboxService 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("=", "\\="); pluginArgs += $"certRaw={base64Content};"; @@ -74,6 +75,9 @@ public partial class CoreConfigSingboxService if (pluginArgs.Length > 0) { outbound.plugin = "v2ray-plugin"; + pluginArgs += "mux=0;"; + // pluginStr remove last ';' + pluginArgs = pluginArgs[..^1]; outbound.plugin_opts = pluginArgs; } }