mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-29 19:06:06 +00:00
Code clean
Some checks failed
release Linux / build (push) Has been cancelled
release Linux / build and release deb x64 & arm64 (push) Has been cancelled
release Linux / build and release rpm x64 & arm64 (push) Has been cancelled
release Linux / build and release rpm riscv64 (push) Has been cancelled
release macOS / build (push) Has been cancelled
release Windows desktop (Avalonia UI) / build (push) Has been cancelled
release Windows / build (push) Has been cancelled
release Linux / release-zip (push) Has been cancelled
release macOS / release-zip (push) Has been cancelled
release macOS / package and release macOS dmg (push) Has been cancelled
release Windows desktop (Avalonia UI) / release-zip (push) Has been cancelled
release Windows / release-zip (push) Has been cancelled
Some checks failed
release Linux / build (push) Has been cancelled
release Linux / build and release deb x64 & arm64 (push) Has been cancelled
release Linux / build and release rpm x64 & arm64 (push) Has been cancelled
release Linux / build and release rpm riscv64 (push) Has been cancelled
release macOS / build (push) Has been cancelled
release Windows desktop (Avalonia UI) / build (push) Has been cancelled
release Windows / build (push) Has been cancelled
release Linux / release-zip (push) Has been cancelled
release macOS / release-zip (push) Has been cancelled
release macOS / package and release macOS dmg (push) Has been cancelled
release Windows desktop (Avalonia UI) / release-zip (push) Has been cancelled
release Windows / release-zip (push) Has been cancelled
This commit is contained in:
parent
ae662a628d
commit
05e349e45c
18 changed files with 148 additions and 99 deletions
|
|
@ -9,105 +9,105 @@ namespace ServiceLib.Tests.CoreConfig.Context;
|
||||||
|
|
||||||
public class CoreConfigContextBuilderTests
|
public class CoreConfigContextBuilderTests
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ResolveNodeAsync_DirectCycleDependency_ShouldFailWithCycleError()
|
public async Task ResolveNodeAsync_DirectCycleDependency_ShouldFailWithCycleError()
|
||||||
{
|
{
|
||||||
var config = CoreConfigTestFactory.CreateConfig();
|
var config = CoreConfigTestFactory.CreateConfig();
|
||||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||||
|
|
||||||
var groupAId = NewId("group-a");
|
var groupAId = NewId("group-a");
|
||||||
var groupBId = NewId("group-b");
|
var groupBId = NewId("group-b");
|
||||||
var groupA = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupAId, "group-a", [groupBId]);
|
var groupA = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupAId, "group-a", [groupBId]);
|
||||||
var groupB = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupBId, "group-b", [groupAId]);
|
var groupB = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupBId, "group-b", [groupAId]);
|
||||||
|
|
||||||
await UpsertProfilesAsync(groupA, groupB);
|
await UpsertProfilesAsync(groupA, groupB);
|
||||||
|
|
||||||
var context = CoreConfigTestFactory.CreateContext(config, groupA, ECoreType.Xray);
|
var context = CoreConfigTestFactory.CreateContext(config, groupA, ECoreType.Xray);
|
||||||
context.AllProxiesMap.Clear();
|
context.AllProxiesMap.Clear();
|
||||||
|
|
||||||
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
|
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
|
||||||
|
|
||||||
validatorResult.Success.Should().BeFalse();
|
validatorResult.Success.Should().BeFalse();
|
||||||
validatorResult.Errors.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
|
validatorResult.Errors.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
|
||||||
context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
|
context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
|
||||||
context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
|
context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ResolveNodeAsync_IndirectCycleDependency_ShouldFailWithCycleError()
|
public async Task ResolveNodeAsync_IndirectCycleDependency_ShouldFailWithCycleError()
|
||||||
{
|
{
|
||||||
var config = CoreConfigTestFactory.CreateConfig();
|
var config = CoreConfigTestFactory.CreateConfig();
|
||||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||||
|
|
||||||
var groupAId = NewId("group-a");
|
var groupAId = NewId("group-a");
|
||||||
var groupBId = NewId("group-b");
|
var groupBId = NewId("group-b");
|
||||||
var groupCId = NewId("group-c");
|
var groupCId = NewId("group-c");
|
||||||
var groupA = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupAId, "group-a", [groupBId]);
|
var groupA = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupAId, "group-a", [groupBId]);
|
||||||
var groupB = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupBId, "group-b", [groupCId]);
|
var groupB = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupBId, "group-b", [groupCId]);
|
||||||
var groupC = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupCId, "group-c", [groupAId]);
|
var groupC = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupCId, "group-c", [groupAId]);
|
||||||
|
|
||||||
await UpsertProfilesAsync(groupA, groupB, groupC);
|
await UpsertProfilesAsync(groupA, groupB, groupC);
|
||||||
|
|
||||||
var context = CoreConfigTestFactory.CreateContext(config, groupA, ECoreType.Xray);
|
var context = CoreConfigTestFactory.CreateContext(config, groupA, ECoreType.Xray);
|
||||||
context.AllProxiesMap.Clear();
|
context.AllProxiesMap.Clear();
|
||||||
|
|
||||||
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
|
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
|
||||||
|
|
||||||
validatorResult.Success.Should().BeFalse();
|
validatorResult.Success.Should().BeFalse();
|
||||||
validatorResult.Errors.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
|
validatorResult.Errors.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
|
||||||
context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
|
context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
|
||||||
context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
|
context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
|
||||||
context.AllProxiesMap.Should().NotContainKey(groupC.IndexId);
|
context.AllProxiesMap.Should().NotContainKey(groupC.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ResolveNodeAsync_CycleWithValidBranch_ShouldSkipCycleAndKeepValidChild()
|
public async Task ResolveNodeAsync_CycleWithValidBranch_ShouldSkipCycleAndKeepValidChild()
|
||||||
{
|
{
|
||||||
var config = CoreConfigTestFactory.CreateConfig();
|
var config = CoreConfigTestFactory.CreateConfig();
|
||||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||||
|
|
||||||
var groupAId = NewId("group-a");
|
var groupAId = NewId("group-a");
|
||||||
var groupBId = NewId("group-b");
|
var groupBId = NewId("group-b");
|
||||||
var leafId = NewId("leaf");
|
var leafId = NewId("leaf");
|
||||||
var groupA = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupAId, "group-a", [groupBId, leafId]);
|
var groupA = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupAId, "group-a", [groupBId, leafId]);
|
||||||
var groupB = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupBId, "group-b", [groupAId]);
|
var groupB = CoreConfigTestFactory.CreatePolicyGroupNode(ECoreType.Xray, groupBId, "group-b", [groupAId]);
|
||||||
var leaf = CoreConfigTestFactory.CreateSocksNode(ECoreType.Xray, leafId, "leaf");
|
var leaf = CoreConfigTestFactory.CreateSocksNode(ECoreType.Xray, leafId, "leaf");
|
||||||
|
|
||||||
await UpsertProfilesAsync(groupA, groupB, leaf);
|
await UpsertProfilesAsync(groupA, groupB, leaf);
|
||||||
|
|
||||||
var context = CoreConfigTestFactory.CreateContext(config, groupA, ECoreType.Xray);
|
var context = CoreConfigTestFactory.CreateContext(config, groupA, ECoreType.Xray);
|
||||||
context.AllProxiesMap.Clear();
|
context.AllProxiesMap.Clear();
|
||||||
|
|
||||||
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
|
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
|
||||||
|
|
||||||
validatorResult.Success.Should().BeTrue();
|
validatorResult.Success.Should().BeTrue();
|
||||||
validatorResult.Errors.Should().BeEmpty();
|
validatorResult.Errors.Should().BeEmpty();
|
||||||
validatorResult.Warnings.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
|
validatorResult.Warnings.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
|
||||||
|
|
||||||
context.AllProxiesMap.Should().ContainKey(leaf.IndexId);
|
context.AllProxiesMap.Should().ContainKey(leaf.IndexId);
|
||||||
context.AllProxiesMap.Should().ContainKey(groupA.IndexId);
|
context.AllProxiesMap.Should().ContainKey(groupA.IndexId);
|
||||||
context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
|
context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
|
||||||
groupA.GetProtocolExtra().ChildItems.Should().Be(leaf.IndexId);
|
groupA.GetProtocolExtra().ChildItems.Should().Be(leaf.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string NewId(string prefix)
|
private static string NewId(string prefix)
|
||||||
{
|
{
|
||||||
return $"{prefix}-{Guid.NewGuid():N}";
|
return $"{prefix}-{Guid.NewGuid():N}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ContainsCycleDependencyMessage(string message)
|
private static bool ContainsCycleDependencyMessage(string message)
|
||||||
{
|
{
|
||||||
return message.Contains("cycle dependency", StringComparison.OrdinalIgnoreCase)
|
return message.Contains("cycle dependency", StringComparison.OrdinalIgnoreCase)
|
||||||
|| message.Contains("循环依赖", StringComparison.Ordinal)
|
|| message.Contains("循环依赖", StringComparison.Ordinal)
|
||||||
|| message.Contains("循環依賴", StringComparison.Ordinal);
|
|| message.Contains("循環依賴", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task UpsertProfilesAsync(params ProfileItem[] profiles)
|
private static async Task UpsertProfilesAsync(params ProfileItem[] profiles)
|
||||||
{
|
{
|
||||||
SQLiteHelper.Instance.CreateTable<ProfileItem>();
|
SQLiteHelper.Instance.CreateTable<ProfileItem>();
|
||||||
foreach (var profile in profiles)
|
foreach (var profile in profiles)
|
||||||
{
|
{
|
||||||
await SQLiteHelper.Instance.ReplaceAsync(profile);
|
await SQLiteHelper.Instance.ReplaceAsync(profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
using System.Reflection;
|
||||||
using ServiceLib.Enums;
|
using ServiceLib.Enums;
|
||||||
using ServiceLib.Manager;
|
using ServiceLib.Manager;
|
||||||
using ServiceLib.Models;
|
using ServiceLib.Models;
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace ServiceLib.Tests.CoreConfig;
|
namespace ServiceLib.Tests.CoreConfig;
|
||||||
|
|
||||||
|
|
@ -33,7 +33,10 @@ internal static class CoreConfigTestFactory
|
||||||
UiItem =
|
UiItem =
|
||||||
new UIItem
|
new UIItem
|
||||||
{
|
{
|
||||||
CurrentLanguage = "en", CurrentFontFamily = "sans", MainColumnItem = [], WindowSizeItem = []
|
CurrentLanguage = "en",
|
||||||
|
CurrentFontFamily = "sans",
|
||||||
|
MainColumnItem = [],
|
||||||
|
WindowSizeItem = []
|
||||||
},
|
},
|
||||||
ConstItem = new ConstItem(),
|
ConstItem = new ConstItem(),
|
||||||
SpeedTestItem = new SpeedTestItem
|
SpeedTestItem = new SpeedTestItem
|
||||||
|
|
@ -51,7 +54,8 @@ internal static class CoreConfigTestFactory
|
||||||
SystemProxyItem =
|
SystemProxyItem =
|
||||||
new SystemProxyItem
|
new SystemProxyItem
|
||||||
{
|
{
|
||||||
SystemProxyExceptions = string.Empty, SystemProxyAdvancedProtocol = string.Empty
|
SystemProxyExceptions = string.Empty,
|
||||||
|
SystemProxyAdvancedProtocol = string.Empty
|
||||||
},
|
},
|
||||||
WebDavItem = new WebDavItem(),
|
WebDavItem = new WebDavItem(),
|
||||||
CheckUpdateItem = new CheckUpdateItem(),
|
CheckUpdateItem = new CheckUpdateItem(),
|
||||||
|
|
@ -131,11 +135,15 @@ internal static class CoreConfigTestFactory
|
||||||
{
|
{
|
||||||
var node = new ProfileItem
|
var node = new ProfileItem
|
||||||
{
|
{
|
||||||
IndexId = indexId, ConfigType = EConfigType.PolicyGroup, CoreType = coreType, Remarks = remarks,
|
IndexId = indexId,
|
||||||
|
ConfigType = EConfigType.PolicyGroup,
|
||||||
|
CoreType = coreType,
|
||||||
|
Remarks = remarks,
|
||||||
};
|
};
|
||||||
node.SetProtocolExtra(node.GetProtocolExtra() with
|
node.SetProtocolExtra(node.GetProtocolExtra() with
|
||||||
{
|
{
|
||||||
GroupType = nameof(EConfigType.PolicyGroup), ChildItems = string.Join(",", childIndexIds),
|
GroupType = nameof(EConfigType.PolicyGroup),
|
||||||
|
ChildItems = string.Join(",", childIndexIds),
|
||||||
});
|
});
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|
@ -146,11 +154,15 @@ internal static class CoreConfigTestFactory
|
||||||
{
|
{
|
||||||
var node = new ProfileItem
|
var node = new ProfileItem
|
||||||
{
|
{
|
||||||
IndexId = indexId, ConfigType = EConfigType.ProxyChain, CoreType = coreType, Remarks = remarks,
|
IndexId = indexId,
|
||||||
|
ConfigType = EConfigType.ProxyChain,
|
||||||
|
CoreType = coreType,
|
||||||
|
Remarks = remarks,
|
||||||
};
|
};
|
||||||
node.SetProtocolExtra(node.GetProtocolExtra() with
|
node.SetProtocolExtra(node.GetProtocolExtra() with
|
||||||
{
|
{
|
||||||
GroupType = nameof(EConfigType.ProxyChain), ChildItems = string.Join(",", childIndexIds),
|
GroupType = nameof(EConfigType.ProxyChain),
|
||||||
|
ChildItems = string.Join(",", childIndexIds),
|
||||||
});
|
});
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using AwesomeAssertions;
|
using AwesomeAssertions;
|
||||||
|
using ServiceLib.Enums;
|
||||||
using ServiceLib.Handler.Fmt;
|
using ServiceLib.Handler.Fmt;
|
||||||
using ServiceLib.Models;
|
using ServiceLib.Models;
|
||||||
using ServiceLib.Enums;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace ServiceLib.Tests.Fmt;
|
namespace ServiceLib.Tests.Fmt;
|
||||||
|
|
@ -92,7 +92,7 @@ public class FmtHandlerTests
|
||||||
var uri = FmtHandler.GetShareUri(source);
|
var uri = FmtHandler.GetShareUri(source);
|
||||||
|
|
||||||
uri.Should().NotBeNullOrWhiteSpace();
|
uri.Should().NotBeNullOrWhiteSpace();
|
||||||
(uri!.StartsWith(Global.ProtocolShares[source.ConfigType], StringComparison.OrdinalIgnoreCase)).Should()
|
uri!.StartsWith(Global.ProtocolShares[source.ConfigType], StringComparison.OrdinalIgnoreCase).Should()
|
||||||
.BeTrue();
|
.BeTrue();
|
||||||
|
|
||||||
var resolved = FmtHandler.ResolveConfig(uri, out var msg);
|
var resolved = FmtHandler.ResolveConfig(uri, out var msg);
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,9 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
|
|
||||||
var clientAddrForSocks = new Socks5AddressData
|
var clientAddrForSocks = new Socks5AddressData
|
||||||
{
|
{
|
||||||
AddressType = Socks5AddressData.AddrTypeIPv4, Host = "0.0.0.0", Port = 0
|
AddressType = Socks5AddressData.AddrTypeIPv4,
|
||||||
|
Host = "0.0.0.0",
|
||||||
|
Port = 0
|
||||||
};
|
};
|
||||||
using var udpAssociateReqMs = new MemoryStream();
|
using var udpAssociateReqMs = new MemoryStream();
|
||||||
udpAssociateReqMs.WriteByte(Socks5Version);
|
udpAssociateReqMs.WriteByte(Socks5Version);
|
||||||
|
|
@ -267,7 +269,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion SOCKS5 Connection Handling
|
||||||
|
|
||||||
#region SOCKS5 Address Handling
|
#region SOCKS5 Address Handling
|
||||||
|
|
||||||
|
|
@ -298,6 +300,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddrTypeDomain:
|
case AddrTypeDomain:
|
||||||
if (string.IsNullOrEmpty(Host))
|
if (string.IsNullOrEmpty(Host))
|
||||||
{
|
{
|
||||||
|
|
@ -311,6 +314,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddrTypeIPv6:
|
case AddrTypeIPv6:
|
||||||
if (IPAddress.TryParse(Host, out var ip6) && ip6.AddressFamily == AddressFamily.InterNetworkV6)
|
if (IPAddress.TryParse(Host, out var ip6) && ip6.AddressFamily == AddressFamily.InterNetworkV6)
|
||||||
{
|
{
|
||||||
|
|
@ -322,6 +326,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"SOCKS5 address type {AddressType} not supported.");
|
throw new NotSupportedException($"SOCKS5 address type {AddressType} not supported.");
|
||||||
}
|
}
|
||||||
|
|
@ -355,6 +360,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
|
|
||||||
addr.Host = new IPAddress(ipv4Bytes).ToString();
|
addr.Host = new IPAddress(ipv4Bytes).ToString();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddrTypeDomain:
|
case AddrTypeDomain:
|
||||||
var lenByte = new byte[1];
|
var lenByte = new byte[1];
|
||||||
if (await stream.ReadAsync(lenByte.AsMemory(0, 1), ct).ConfigureAwait(false) < 1)
|
if (await stream.ReadAsync(lenByte.AsMemory(0, 1), ct).ConfigureAwait(false) < 1)
|
||||||
|
|
@ -379,6 +385,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddrTypeIPv6:
|
case AddrTypeIPv6:
|
||||||
var ipv6Bytes = new byte[16];
|
var ipv6Bytes = new byte[16];
|
||||||
if (await stream.ReadAsync(ipv6Bytes.AsMemory(0, 16), ct).ConfigureAwait(false) < 16)
|
if (await stream.ReadAsync(ipv6Bytes.AsMemory(0, 16), ct).ConfigureAwait(false) < 16)
|
||||||
|
|
@ -388,6 +395,7 @@ public class Socks5UdpChannel(string socks5Host, int socks5TcpPort) : IDisposabl
|
||||||
|
|
||||||
addr.Host = new IPAddress(ipv6Bytes).ToString();
|
addr.Host = new IPAddress(ipv6Bytes).ToString();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ public class DnsService : IUdpTest
|
||||||
{
|
{
|
||||||
private const int DnsDefaultPort = 53;
|
private const int DnsDefaultPort = 53;
|
||||||
private const string DnsDefaultServer = "8.8.8.8"; // Google Public DNS
|
private const string DnsDefaultServer = "8.8.8.8"; // Google Public DNS
|
||||||
|
|
||||||
private static readonly byte[] DnsQueryPacket =
|
private static readonly byte[] DnsQueryPacket =
|
||||||
[
|
[
|
||||||
// Header: ID=0x1234, Standard query with RD set, QDCOUNT=1
|
// Header: ID=0x1234, Standard query with RD set, QDCOUNT=1
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ namespace ServiceLib.UdpTest.Tester;
|
||||||
public interface IUdpTest
|
public interface IUdpTest
|
||||||
{
|
{
|
||||||
public byte[] BuildUdpRequestPacket();
|
public byte[] BuildUdpRequestPacket();
|
||||||
|
|
||||||
public bool VerifyAndExtractUdpResponse(byte[] udpResponseBytes);
|
public bool VerifyAndExtractUdpResponse(byte[] udpResponseBytes);
|
||||||
|
|
||||||
public ushort GetDefaultTargetPort();
|
public ushort GetDefaultTargetPort();
|
||||||
|
|
||||||
public string GetDefaultTargetHost();
|
public string GetDefaultTargetHost();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ public class McBeService : IUdpTest
|
||||||
{
|
{
|
||||||
private const int McBeDefaultPort = 19132;
|
private const int McBeDefaultPort = 19132;
|
||||||
private const string McBeDefaultServer = "pms.mc-complex.com";
|
private const string McBeDefaultServer = "pms.mc-complex.com";
|
||||||
|
|
||||||
// 0x01 | client alive time in ms (unsigned long long) | magic | client GUID
|
// 0x01 | client alive time in ms (unsigned long long) | magic | client GUID
|
||||||
private static readonly byte[] McBeQueryPacket =
|
private static readonly byte[] McBeQueryPacket =
|
||||||
[
|
[
|
||||||
|
|
@ -18,11 +19,13 @@ public class McBeService : IUdpTest
|
||||||
0x66, 0x0E, 0xAB, 0xBC, 0x61, 0x0D, 0x1F, 0x4E,
|
0x66, 0x0E, 0xAB, 0xBC, 0x61, 0x0D, 0x1F, 0x4E,
|
||||||
0xA4, 0x40, 0x8C, 0x65, 0xC1, 0xBE, 0xF5, 0x4B
|
0xA4, 0x40, 0x8C, 0x65, 0xC1, 0xBE, 0xF5, 0x4B
|
||||||
];
|
];
|
||||||
|
|
||||||
private static readonly byte[] McBeMagicBytes =
|
private static readonly byte[] McBeMagicBytes =
|
||||||
[
|
[
|
||||||
0x00, 0xFF, 0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFE,
|
0x00, 0xFF, 0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||||
0xFD, 0xFD, 0xFD, 0xFD, 0x12, 0x34, 0x56, 0x78
|
0xFD, 0xFD, 0xFD, 0xFD, 0x12, 0x34, 0x56, 0x78
|
||||||
];
|
];
|
||||||
|
|
||||||
private static readonly List<string> ValidGameModes =
|
private static readonly List<string> ValidGameModes =
|
||||||
[
|
[
|
||||||
"Survival",
|
"Survival",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ public class StunService : IUdpTest
|
||||||
{
|
{
|
||||||
private const int StunDefaultPort = 3478;
|
private const int StunDefaultPort = 3478;
|
||||||
private const string StunDefaultServer = "stun.voztovoice.org";
|
private const string StunDefaultServer = "stun.voztovoice.org";
|
||||||
|
|
||||||
private static readonly byte[] StunBindingRequestPacket =
|
private static readonly byte[] StunBindingRequestPacket =
|
||||||
[
|
[
|
||||||
// STUN Binding Request
|
// STUN Binding Request
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace ServiceLib.Handler.Fmt;
|
||||||
public class BaseFmt
|
public class BaseFmt
|
||||||
{
|
{
|
||||||
private static readonly string[] _allowInsecureArray = new[] { "insecure", "allowInsecure", "allow_insecure" };
|
private static readonly string[] _allowInsecureArray = new[] { "insecure", "allowInsecure", "allow_insecure" };
|
||||||
|
|
||||||
private static string UrlEncodeSafe(string? value) => Utils.UrlEncode(value ?? string.Empty);
|
private static string UrlEncodeSafe(string? value) => Utils.UrlEncode(value ?? string.Empty);
|
||||||
|
|
||||||
protected static string GetIpv6(string address)
|
protected static string GetIpv6(string address)
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,7 @@ public class Transport4Sbox
|
||||||
public class Headers4Sbox
|
public class Headers4Sbox
|
||||||
{
|
{
|
||||||
public string? Host { get; set; }
|
public string? Host { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("User-Agent")]
|
[JsonPropertyName("User-Agent")]
|
||||||
public string UserAgent { get; set; }
|
public string UserAgent { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -500,12 +500,16 @@ public class MaskSettings4Ray
|
||||||
{
|
{
|
||||||
public string? password { get; set; }
|
public string? password { get; set; }
|
||||||
public string? domain { get; set; }
|
public string? domain { get; set; }
|
||||||
|
|
||||||
// fragment
|
// fragment
|
||||||
public string? packets { get; set; }
|
public string? packets { get; set; }
|
||||||
|
|
||||||
public string? length { get; set; }
|
public string? length { get; set; }
|
||||||
public string? delay { get; set; }
|
public string? delay { get; set; }
|
||||||
|
|
||||||
// noise
|
// noise
|
||||||
public int? reset { get; set; }
|
public int? reset { get; set; }
|
||||||
|
|
||||||
public List<NoiseMask4Ray>? noise { get; set; }
|
public List<NoiseMask4Ray>? noise { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -533,6 +537,7 @@ public class AccountsItem4Ray
|
||||||
public class Sockopt4Ray
|
public class Sockopt4Ray
|
||||||
{
|
{
|
||||||
public string? dialerProxy { get; set; }
|
public string? dialerProxy { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("interface")]
|
[JsonPropertyName("interface")]
|
||||||
public string? Interface { get; set; }
|
public string? Interface { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -548,6 +548,7 @@ public partial class CoreConfigV2rayService
|
||||||
FillOutboundMux(outbound);
|
FillOutboundMux(outbound);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.grpc):
|
case nameof(ETransport.grpc):
|
||||||
GrpcSettings4Ray grpcSettings = new()
|
GrpcSettings4Ray grpcSettings = new()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,6 @@ public class UpdateService(Config config, Func<bool, string, Task> updateFunc)
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Utils.IsLinux())
|
else if (Utils.IsLinux())
|
||||||
{
|
{
|
||||||
var arch = RuntimeInformation.ProcessArchitecture;
|
var arch = RuntimeInformation.ProcessArchitecture;
|
||||||
|
|
@ -314,7 +313,6 @@ public class UpdateService(Config config, Func<bool, string, Task> updateFunc)
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Utils.IsMacOS())
|
else if (Utils.IsMacOS())
|
||||||
{
|
{
|
||||||
return RuntimeInformation.ProcessArchitecture switch
|
return RuntimeInformation.ProcessArchitecture switch
|
||||||
|
|
|
||||||
|
|
@ -338,21 +338,27 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
case nameof(ETransport.raw):
|
case nameof(ETransport.raw):
|
||||||
gridTransportRaw.IsVisible = true;
|
gridTransportRaw.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.kcp):
|
case nameof(ETransport.kcp):
|
||||||
gridTransportKcp.IsVisible = true;
|
gridTransportKcp.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
gridTransportWs.IsVisible = true;
|
gridTransportWs.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
gridTransportHttpupgrade.IsVisible = true;
|
gridTransportHttpupgrade.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
gridTransportXhttp.IsVisible = true;
|
gridTransportXhttp.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.grpc):
|
case nameof(ETransport.grpc):
|
||||||
gridTransportGrpc.IsVisible = true;
|
gridTransportGrpc.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gridTransportRaw.IsVisible = true;
|
gridTransportRaw.IsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,10 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
|
|
||||||
private void RoutingSettingWindow_Closing(object? sender, WindowClosingEventArgs e)
|
private void RoutingSettingWindow_Closing(object? sender, WindowClosingEventArgs e)
|
||||||
{
|
{
|
||||||
if (_closed) return;
|
if (_closed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// DomainStrategy is auto-saved reactively; just ensure the caller knows changes were made
|
// DomainStrategy is auto-saved reactively; just ensure the caller knows changes were made
|
||||||
if (ViewModel?.IsModified == true)
|
if (ViewModel?.IsModified == true)
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ public class ThemeSettingViewModel : MyReactiveObject
|
||||||
|
|
||||||
private void ModifyFontSize()
|
private void ModifyFontSize()
|
||||||
{
|
{
|
||||||
double size = (long)CurrentFontSize;
|
double size = CurrentFontSize;
|
||||||
if (size < Global.MinFontSize)
|
if (size < Global.MinFontSize)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -340,21 +340,27 @@ public partial class AddServerWindow
|
||||||
case nameof(ETransport.raw):
|
case nameof(ETransport.raw):
|
||||||
gridTransportRaw.Visibility = Visibility.Visible;
|
gridTransportRaw.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.kcp):
|
case nameof(ETransport.kcp):
|
||||||
gridTransportKcp.Visibility = Visibility.Visible;
|
gridTransportKcp.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
gridTransportWs.Visibility = Visibility.Visible;
|
gridTransportWs.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
gridTransportHttpupgrade.Visibility = Visibility.Visible;
|
gridTransportHttpupgrade.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
gridTransportXhttp.Visibility = Visibility.Visible;
|
gridTransportXhttp.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.grpc):
|
case nameof(ETransport.grpc):
|
||||||
gridTransportGrpc.Visibility = Visibility.Visible;
|
gridTransportGrpc.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gridTransportRaw.Visibility = Visibility.Visible;
|
gridTransportRaw.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -170,10 +170,10 @@ public partial class MainWindow
|
||||||
|
|
||||||
private void OnProgramStarted(object state, bool timeout)
|
private void OnProgramStarted(object state, bool timeout)
|
||||||
{
|
{
|
||||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
Application.Current?.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
ShowHideWindow(true);
|
ShowHideWindow(true);
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DelegateSnackMsg(string content)
|
private async Task DelegateSnackMsg(string content)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue