diff --git a/v2rayN/ServiceLib.Tests/Fmt/ShadowsocksFmtTests.cs b/v2rayN/ServiceLib.Tests/Fmt/ShadowsocksFmtTests.cs index f43cc73e..f57a28a9 100644 --- a/v2rayN/ServiceLib.Tests/Fmt/ShadowsocksFmtTests.cs +++ b/v2rayN/ServiceLib.Tests/Fmt/ShadowsocksFmtTests.cs @@ -2,6 +2,38 @@ namespace ServiceLib.Tests.Fmt; public class ShadowsocksFmtTests { + [Test] + [Arguments("8388", true)] + [Arguments("\"8388\"", true)] + [Arguments("8388", false)] + [Arguments("\"8388\"", false)] + public async Task ResolveSip008_ObjectAndArrayDocuments_ShouldPreserveServerFields(string port, bool useObject) + { + var server = $$""" + { + "id": "27b8a625-4f4b-4428-9f0f-8a2317db7c79", + "remarks": "SIP008 server", + "server": "example.com", + "server_port": {{port}}, + "password": "example", + "method": "chacha20-ietf-poly1305" + } + """; + var document = useObject + ? $$"""{"version": 1, "servers": [{{server}}]}""" + : $"[{server}]"; + + var resolved = ShadowsocksFmt.ResolveSip008(document); + + await resolved.Should().NotBeNull(); + await resolved!.Should().HaveCount(1); + await resolved[0].Remarks.Should().BeEqualTo("SIP008 server"); + await resolved[0].Address.Should().BeEqualTo("example.com"); + await resolved[0].Port.Should().BeEqualTo(8388); + await resolved[0].Password.Should().BeEqualTo("example"); + await resolved[0].GetProtocolExtra().SsMethod.Should().BeEqualTo("chacha20-ietf-poly1305"); + } + // SIP002 user info that is not base64 is "method:password", percent-encoded once. [Test] [Arguments("ss://2022-blake3-aes-128-gcm:p%2541ss@1.2.3.4:8388#demo", "p%41ss")] diff --git a/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs index a003540a..dd101223 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs @@ -282,7 +282,7 @@ public class ShadowsocksFmt : BaseFmt { //SsSIP008 var lstSsServer = JsonUtils.Deserialize>(result); - if (lstSsServer?.Count <= 0) + if (lstSsServer == null || lstSsServer.Count == 0) { var ssSIP008 = JsonUtils.Deserialize(result); if (ssSIP008?.servers?.Count > 0) @@ -301,7 +301,7 @@ public class ShadowsocksFmt : BaseFmt Remarks = it.remarks, Password = it.password, Address = it.server, - Port = it.server_port.ToInt() + Port = it.server_port }; ssItem.SetProtocolExtra(new ProtocolExtraItem() { SsMethod = it.method }); lst.Add(ssItem); diff --git a/v2rayN/ServiceLib/Models/Dto/SsSIP008.cs b/v2rayN/ServiceLib/Models/Dto/SsSIP008.cs index 73b7bcf8..32951d7a 100644 --- a/v2rayN/ServiceLib/Models/Dto/SsSIP008.cs +++ b/v2rayN/ServiceLib/Models/Dto/SsSIP008.cs @@ -9,7 +9,8 @@ public class SsServer { public string? remarks { get; set; } public string? server { get; set; } - public string? server_port { get; set; } + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] + public int server_port { get; set; } public string? method { get; set; } public string? password { get; set; } public string? plugin { get; set; }