mirror of
https://github.com/2dust/v2rayN.git
synced 2026-10-01 11:02:07 +03:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 50023a5976 | |||
| c659ca8af8 | |||
| 7d6a967c18 | |||
| 6c2edcb382 |
@@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.25.3</Version>
|
<Version>7.25.4</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="12.0.0" />
|
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="12.0.0" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="12.1.2" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="12.1.2" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="12.1.3" />
|
<PackageVersion Include="Avalonia.Desktop" Version="12.1.2" />
|
||||||
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
|
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
|
||||||
<PackageVersion Include="DialogHost.Avalonia" Version="0.12.3" />
|
<PackageVersion Include="DialogHost.Avalonia" Version="0.12.3" />
|
||||||
<PackageVersion Include="IPNetwork2" Version="4.3.0" />
|
<PackageVersion Include="IPNetwork2" Version="4.3.0" />
|
||||||
|
|||||||
@@ -501,6 +501,31 @@ public class Utils
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<(string, string)> ParseHeaders(string? headers)
|
||||||
|
{
|
||||||
|
var result = new List<(string, string)>();
|
||||||
|
if (headers.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
var lines = headers.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
var parts = line.Split(new[] { ':' }, 2);
|
||||||
|
if (parts.Length != 2)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var key = parts[0].Trim();
|
||||||
|
var value = parts[1].Trim();
|
||||||
|
if (!string.IsNullOrEmpty(key))
|
||||||
|
{
|
||||||
|
result.Add((key, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Conversion Functions
|
#endregion Conversion Functions
|
||||||
|
|
||||||
#region Data Checks
|
#region Data Checks
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public enum EConfigType
|
|||||||
Anytls = 11,
|
Anytls = 11,
|
||||||
Naive = 12,
|
Naive = 12,
|
||||||
Outbound = 13,
|
Outbound = 13,
|
||||||
|
MASQUE = 14,
|
||||||
PolicyGroup = 101,
|
PolicyGroup = 101,
|
||||||
ProxyChain = 102,
|
ProxyChain = 102,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,7 +261,8 @@ public class Global
|
|||||||
{ EConfigType.TUIC, "tuic" },
|
{ EConfigType.TUIC, "tuic" },
|
||||||
{ EConfigType.WireGuard, "wireguard" },
|
{ EConfigType.WireGuard, "wireguard" },
|
||||||
{ EConfigType.Anytls, "anytls" },
|
{ EConfigType.Anytls, "anytls" },
|
||||||
{ EConfigType.Naive, "naive" }
|
{ EConfigType.Naive, "naive" },
|
||||||
|
{ EConfigType.MASQUE, "masque" },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> VmessSecurities =
|
public static readonly List<string> VmessSecurities =
|
||||||
@@ -371,6 +372,7 @@ public class Global
|
|||||||
EConfigType.Trojan,
|
EConfigType.Trojan,
|
||||||
EConfigType.Hysteria2,
|
EConfigType.Hysteria2,
|
||||||
EConfigType.WireGuard,
|
EConfigType.WireGuard,
|
||||||
|
EConfigType.MASQUE,
|
||||||
EConfigType.SOCKS,
|
EConfigType.SOCKS,
|
||||||
EConfigType.HTTP,
|
EConfigType.HTTP,
|
||||||
];
|
];
|
||||||
@@ -386,6 +388,7 @@ public class Global
|
|||||||
EConfigType.Anytls,
|
EConfigType.Anytls,
|
||||||
EConfigType.Naive,
|
EConfigType.Naive,
|
||||||
EConfigType.WireGuard,
|
EConfigType.WireGuard,
|
||||||
|
EConfigType.MASQUE,
|
||||||
EConfigType.SOCKS,
|
EConfigType.SOCKS,
|
||||||
EConfigType.HTTP,
|
EConfigType.HTTP,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public class CoreConfigContextBuilder
|
|||||||
RoutingItem = await ConfigHandler.GetDefaultRouting(config),
|
RoutingItem = await ConfigHandler.GetDefaultRouting(config),
|
||||||
IsWindows = Utils.IsWindows(),
|
IsWindows = Utils.IsWindows(),
|
||||||
IsMacOS = Utils.IsMacOS(),
|
IsMacOS = Utils.IsMacOS(),
|
||||||
|
IsLinux = Utils.IsLinux(),
|
||||||
HasGlobalIPv6Address = Utils.HasGlobalIPv6Address(),
|
HasGlobalIPv6Address = Utils.HasGlobalIPv6Address(),
|
||||||
ProtectCoreTypeList = config.TunModeItem.EnableTun ? [ECoreType.Xray, ECoreType.sing_box] : []
|
ProtectCoreTypeList = config.TunModeItem.EnableTun ? [ECoreType.Xray, ECoreType.sing_box] : []
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ public static class ConfigHandler
|
|||||||
EConfigType.WireGuard => await AddWireguardServer(config, item),
|
EConfigType.WireGuard => await AddWireguardServer(config, item),
|
||||||
EConfigType.Anytls => await AddAnytlsServer(config, item),
|
EConfigType.Anytls => await AddAnytlsServer(config, item),
|
||||||
EConfigType.Naive => await AddNaiveServer(config, item),
|
EConfigType.Naive => await AddNaiveServer(config, item),
|
||||||
|
EConfigType.MASQUE => await AddMasqueServer(config, item),
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
@@ -992,6 +993,29 @@ public static class ConfigHandler
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<int> AddMasqueServer(Config config, ProfileItem profileItem, bool toFile = true)
|
||||||
|
{
|
||||||
|
profileItem.ConfigType = EConfigType.MASQUE;
|
||||||
|
|
||||||
|
profileItem.Address = profileItem.Address.TrimEx();
|
||||||
|
profileItem.Username = profileItem.Username.TrimEx();
|
||||||
|
profileItem.Password = profileItem.Password.TrimEx();
|
||||||
|
profileItem.Fingerprint = string.Empty;
|
||||||
|
profileItem.Alpn = string.Empty;
|
||||||
|
profileItem.Network = string.Empty;
|
||||||
|
profileItem.AllowInsecure = string.Empty;
|
||||||
|
if (profileItem.StreamSecurity.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
profileItem.StreamSecurity = Global.StreamSecurity;
|
||||||
|
}
|
||||||
|
if (profileItem.Password.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
await AddServerCommon(config, profileItem, toFile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sort the server list by the specified column
|
/// Sort the server list by the specified column
|
||||||
/// Updates the sort order in the profile extension data
|
/// Updates the sort order in the profile extension data
|
||||||
@@ -1684,6 +1708,7 @@ public static class ConfigHandler
|
|||||||
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
|
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
|
||||||
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
|
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
|
||||||
EConfigType.Naive => await AddNaiveServer(config, profileItem, false),
|
EConfigType.Naive => await AddNaiveServer(config, profileItem, false),
|
||||||
|
EConfigType.MASQUE => await AddMasqueServer(config, profileItem, false),
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public record CoreConfigContext
|
|||||||
|
|
||||||
public bool IsWindows { get; init; }
|
public bool IsWindows { get; init; }
|
||||||
public bool IsMacOS { get; init; }
|
public bool IsMacOS { get; init; }
|
||||||
|
public bool IsLinux { get; init; }
|
||||||
|
|
||||||
// Defaults to true so that a context built without this flag keeps routing IPv6 into the
|
// Defaults to true so that a context built without this flag keeps routing IPv6 into the
|
||||||
// tunnel; only a positive detection of the host having no global IPv6 address turns it off.
|
// tunnel; only a positive detection of the host having no global IPv6 address turns it off.
|
||||||
|
|||||||
@@ -128,8 +128,6 @@ public class User4Sbox
|
|||||||
|
|
||||||
public class Outbound4Sbox : BaseServer4Sbox
|
public class Outbound4Sbox : BaseServer4Sbox
|
||||||
{
|
{
|
||||||
public string? server { get; set; }
|
|
||||||
public int? server_port { get; set; }
|
|
||||||
public List<string>? server_ports { get; set; }
|
public List<string>? server_ports { get; set; }
|
||||||
public string? uuid { get; set; }
|
public string? uuid { get; set; }
|
||||||
public string? security { get; set; }
|
public string? security { get; set; }
|
||||||
@@ -171,6 +169,10 @@ public class Endpoints4Sbox : BaseServer4Sbox
|
|||||||
public string? udp_timeout { get; set; }
|
public string? udp_timeout { get; set; }
|
||||||
public int? workers { get; set; }
|
public int? workers { get; set; }
|
||||||
public List<Peer4Sbox> peers { get; set; }
|
public List<Peer4Sbox> peers { get; set; }
|
||||||
|
public string? username { get; set; }
|
||||||
|
public string? password { get; set; }
|
||||||
|
public string? path { get; set; }
|
||||||
|
public Dictionary<string, List<string>>? headers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Peer4Sbox
|
public class Peer4Sbox
|
||||||
@@ -271,10 +273,8 @@ public class Server4Sbox : BaseServer4Sbox
|
|||||||
public string? inet4_range { get; set; }
|
public string? inet4_range { get; set; }
|
||||||
public string? inet6_range { get; set; }
|
public string? inet6_range { get; set; }
|
||||||
public string? client_subnet { get; set; }
|
public string? client_subnet { get; set; }
|
||||||
public string? server { get; set; }
|
|
||||||
public new string? domain_resolver { get; set; }
|
public new string? domain_resolver { get; set; }
|
||||||
[JsonPropertyName("interface")] public string? Interface { get; set; }
|
[JsonPropertyName("interface")] public string? Interface { get; set; }
|
||||||
public int? server_port { get; set; }
|
|
||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
public Headers4Sbox? headers { get; set; }
|
public Headers4Sbox? headers { get; set; }
|
||||||
|
|
||||||
@@ -359,4 +359,6 @@ public abstract class BaseServer4Sbox : DialFields4Sbox
|
|||||||
{
|
{
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
|
public string? server { get; set; }
|
||||||
|
public int? server_port { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,10 @@ public class Inboundsettings4Ray
|
|||||||
public string? autoOutboundsInterface { get; set; }
|
public string? autoOutboundsInterface { get; set; }
|
||||||
|
|
||||||
public List<string>? dns { get; set; }
|
public List<string>? dns { get; set; }
|
||||||
|
|
||||||
|
public bool? autoSystemDnsToGateway { get; set; }
|
||||||
|
|
||||||
|
public List<string>? autoSystemWfpBlockLeak { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Sniffing4Ray
|
public class Sniffing4Ray
|
||||||
@@ -315,6 +319,7 @@ public class StreamSettings4Ray
|
|||||||
public GrpcSettings4Ray? grpcSettings { get; set; }
|
public GrpcSettings4Ray? grpcSettings { get; set; }
|
||||||
|
|
||||||
public HysteriaSettings4Ray? hysteriaSettings { get; set; }
|
public HysteriaSettings4Ray? hysteriaSettings { get; set; }
|
||||||
|
public MasqueSettings4Ray? masqueSettings { get; set; }
|
||||||
|
|
||||||
public object? finalmask { get; set; }
|
public object? finalmask { get; set; }
|
||||||
|
|
||||||
@@ -443,6 +448,12 @@ public class HysteriaSettings4Ray
|
|||||||
public string? auth { get; set; }
|
public string? auth { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MasqueSettings4Ray
|
||||||
|
{
|
||||||
|
public string? path { get; set; }
|
||||||
|
public Dictionary<string, string>? headers { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class UdpHop4Ray
|
public class UdpHop4Ray
|
||||||
{
|
{
|
||||||
public string? ports { get; set; }
|
public string? ports { get; set; }
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ public record ProtocolExtraItem
|
|||||||
public int? InsecureConcurrency { get; init; }
|
public int? InsecureConcurrency { get; init; }
|
||||||
public bool? NaiveQuic { get; init; }
|
public bool? NaiveQuic { get; init; }
|
||||||
|
|
||||||
|
// MASQUE
|
||||||
|
public string? MasquePath { get; init; }
|
||||||
|
public string? MasqueHeaders { get; init; }
|
||||||
|
|
||||||
// group profile
|
// group profile
|
||||||
public string? GroupType { get; init; }
|
public string? GroupType { get; init; }
|
||||||
public string? ChildItems { get; init; }
|
public string? ChildItems { get; init; }
|
||||||
|
|||||||
Generated
+9
@@ -789,6 +789,15 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Add [MASQUE] 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuAddMasqueServer {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuAddMasqueServer", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Add [NaïveProxy] 的本地化字符串。
|
/// 查找类似 Add [NaïveProxy] 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1899,4 +1899,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||||||
<data name="TbSortingProcess" xml:space="preserve">
|
<data name="TbSortingProcess" xml:space="preserve">
|
||||||
<value>Process</value>
|
<value>Process</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddMasqueServer" xml:space="preserve">
|
||||||
|
<value>Add [MASQUE]</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1891,4 +1891,7 @@
|
|||||||
<data name="TbSortingProcess" xml:space="preserve">
|
<data name="TbSortingProcess" xml:space="preserve">
|
||||||
<value>进程</value>
|
<value>进程</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddMasqueServer" xml:space="preserve">
|
||||||
|
<value>添加 [MASQUE]</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -77,7 +77,7 @@ public partial class CoreConfigSingboxService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_node.ConfigType == EConfigType.WireGuard)
|
if (_node.ConfigType is EConfigType.WireGuard or EConfigType.MASQUE)
|
||||||
{
|
{
|
||||||
var endpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
|
var endpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
|
||||||
FillEndpoint(endpoint);
|
FillEndpoint(endpoint);
|
||||||
@@ -350,13 +350,13 @@ public partial class CoreConfigSingboxService
|
|||||||
{
|
{
|
||||||
var protocolExtra = _node.GetProtocolExtra();
|
var protocolExtra = _node.GetProtocolExtra();
|
||||||
|
|
||||||
endpoint.address = Utils.String2List(protocolExtra.WgInterfaceAddress)?.Select(s => s.Trim()).ToList() ?? ["172.16.0.2/32"];
|
|
||||||
endpoint.type = Global.ProtocolTypes[_node.ConfigType];
|
endpoint.type = Global.ProtocolTypes[_node.ConfigType];
|
||||||
|
|
||||||
switch (_node.ConfigType)
|
switch (_node.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.WireGuard:
|
case EConfigType.WireGuard:
|
||||||
{
|
{
|
||||||
|
endpoint.address = Utils.String2List(protocolExtra.WgInterfaceAddress)?.Select(s => s.Trim()).ToList() ?? ["172.16.0.2/32"];
|
||||||
var peer = new Peer4Sbox
|
var peer = new Peer4Sbox
|
||||||
{
|
{
|
||||||
public_key = protocolExtra.WgPublicKey ?? string.Empty,
|
public_key = protocolExtra.WgPublicKey ?? string.Empty,
|
||||||
@@ -371,6 +371,28 @@ public partial class CoreConfigSingboxService
|
|||||||
endpoint.peers = [peer];
|
endpoint.peers = [peer];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EConfigType.MASQUE:
|
||||||
|
{
|
||||||
|
endpoint.type = "masque-client";
|
||||||
|
endpoint.server = _node.Address;
|
||||||
|
endpoint.server_port = _node.Port;
|
||||||
|
endpoint.username = _node.Username;
|
||||||
|
endpoint.password = _node.Password;
|
||||||
|
endpoint.path = protocolExtra?.MasquePath.NullIfEmpty();
|
||||||
|
if (!string.IsNullOrEmpty(protocolExtra?.MasqueHeaders))
|
||||||
|
{
|
||||||
|
var headers = Utils.ParseHeaders(protocolExtra.MasqueHeaders)
|
||||||
|
.GroupBy(x => x.Item1, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToDictionary(
|
||||||
|
g => g.Key,
|
||||||
|
g => g.Select(x => x.Item2).ToList(),
|
||||||
|
StringComparer.OrdinalIgnoreCase
|
||||||
|
);
|
||||||
|
endpoint.headers = headers.Count > 0 ? headers : null;
|
||||||
|
}
|
||||||
|
FillOutboundTls(endpoint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -402,7 +424,7 @@ public partial class CoreConfigSingboxService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillOutboundTls(Outbound4Sbox outbound)
|
private void FillOutboundTls(BaseServer4Sbox server)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -476,7 +498,7 @@ public partial class CoreConfigSingboxService
|
|||||||
{
|
{
|
||||||
tls.ech = ech;
|
tls.ech = ech;
|
||||||
}
|
}
|
||||||
outbound.tls = tls;
|
server.tls = tls;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,6 +90,15 @@ public partial class CoreConfigV2rayService
|
|||||||
// tunInbound.sniffing.routeOnly = inbound.sniffing.routeOnly;
|
// tunInbound.sniffing.routeOnly = inbound.sniffing.routeOnly;
|
||||||
tunInbound.sniffing.routeOnly = true;
|
tunInbound.sniffing.routeOnly = true;
|
||||||
|
|
||||||
|
if (context.IsWindows && _config.TunModeItem.StrictRoute == true)
|
||||||
|
{
|
||||||
|
tunInbound.settings.autoSystemWfpBlockLeak = ["dns", "misconfigtun"];
|
||||||
|
}
|
||||||
|
if (context.IsLinux)
|
||||||
|
{
|
||||||
|
tunInbound.settings.autoSystemDnsToGateway = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_config.TunModeItem.RouteExcludeAddress is { Count: > 0 })
|
if (_config.TunModeItem.RouteExcludeAddress is { Count: > 0 })
|
||||||
{
|
{
|
||||||
var wholeInternet = IPNetwork2.Parse("0.0.0.0/0");
|
var wholeInternet = IPNetwork2.Parse("0.0.0.0/0");
|
||||||
|
|||||||
@@ -182,6 +182,12 @@ public partial class CoreConfigV2rayService
|
|||||||
outboundSettings.version = 2;
|
outboundSettings.version = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EConfigType.MASQUE:
|
||||||
|
{
|
||||||
|
outboundSettings.address = _node.Address;
|
||||||
|
outboundSettings.port = _node.Port;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case EConfigType.WireGuard:
|
case EConfigType.WireGuard:
|
||||||
{
|
{
|
||||||
var address = _node.Address;
|
var address = _node.Address;
|
||||||
@@ -257,8 +263,13 @@ public partial class CoreConfigV2rayService
|
|||||||
{
|
{
|
||||||
network = "hysteria";
|
network = "hysteria";
|
||||||
}
|
}
|
||||||
|
else if (_node.ConfigType == EConfigType.MASQUE)
|
||||||
|
{
|
||||||
|
network = "masque";
|
||||||
|
}
|
||||||
streamSettings.network = network;
|
streamSettings.network = network;
|
||||||
var transport = _node.GetTransportExtra();
|
var transport = _node.GetTransportExtra();
|
||||||
|
var protocolExtra = _node.GetProtocolExtra();
|
||||||
var host = string.Empty;
|
var host = string.Empty;
|
||||||
var path = string.Empty;
|
var path = string.Empty;
|
||||||
var kcpSeed = string.Empty;
|
var kcpSeed = string.Empty;
|
||||||
@@ -502,7 +513,6 @@ public partial class CoreConfigV2rayService
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "hysteria":
|
case "hysteria":
|
||||||
var protocolExtra = _node.GetProtocolExtra();
|
|
||||||
var ports = protocolExtra?.Ports;
|
var ports = protocolExtra?.Ports;
|
||||||
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
|
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
|
||||||
? su
|
? su
|
||||||
@@ -574,6 +584,32 @@ public partial class CoreConfigV2rayService
|
|||||||
streamSettings.finalmask = hy2Finalmask;
|
streamSettings.finalmask = hy2Finalmask;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "masque":
|
||||||
|
var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var authValue = $"Basic {Utils.Base64Encode($"{_node.Username}:{_node.Password}")}";
|
||||||
|
headers.Add("Authorization", authValue);
|
||||||
|
if (!string.IsNullOrEmpty(protocolExtra?.MasqueHeaders))
|
||||||
|
{
|
||||||
|
var userHeaders = Utils.ParseHeaders(protocolExtra.MasqueHeaders)
|
||||||
|
.GroupBy(x => x.Item1, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToDictionary(
|
||||||
|
g => g.Key,
|
||||||
|
g => string.Join(", ", g.Select(x => x.Item2)),
|
||||||
|
StringComparer.OrdinalIgnoreCase
|
||||||
|
);
|
||||||
|
if (userHeaders.TryGetValue("Authorization", out var userAuthValue))
|
||||||
|
{
|
||||||
|
headers["Authorization"] = userAuthValue;
|
||||||
|
}
|
||||||
|
headers = userHeaders;
|
||||||
|
}
|
||||||
|
streamSettings.masqueSettings = new()
|
||||||
|
{
|
||||||
|
path = protocolExtra?.MasquePath.NullIfEmpty(),
|
||||||
|
headers = headers.Count > 0 ? headers : null,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// raw
|
// raw
|
||||||
if (headerType == Global.RawHeaderHttp)
|
if (headerType == Global.RawHeaderHttp)
|
||||||
|
|||||||
@@ -97,6 +97,12 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
|||||||
[Reactive]
|
[Reactive]
|
||||||
public partial int GeckoMaxPacketSize { get; set; }
|
public partial int GeckoMaxPacketSize { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public partial string MasquePath { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public partial string MasqueHeaders { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public partial string RawHeaderType { get; set; }
|
public partial string RawHeaderType { get; set; }
|
||||||
|
|
||||||
@@ -322,6 +328,8 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
|||||||
Hy2RealmUrl = protocolExtra.Hy2RealmUrl ?? string.Empty;
|
Hy2RealmUrl = protocolExtra.Hy2RealmUrl ?? string.Empty;
|
||||||
GeckoMinPacketSize = protocolExtra.GeckoMinPacketSize.ToInt();
|
GeckoMinPacketSize = protocolExtra.GeckoMinPacketSize.ToInt();
|
||||||
GeckoMaxPacketSize = protocolExtra.GeckoMaxPacketSize.ToInt();
|
GeckoMaxPacketSize = protocolExtra.GeckoMaxPacketSize.ToInt();
|
||||||
|
MasquePath = protocolExtra.MasquePath ?? string.Empty;
|
||||||
|
MasqueHeaders = protocolExtra.MasqueHeaders ?? string.Empty;
|
||||||
|
|
||||||
RawHeaderType = transport.RawHeaderType ?? Global.None;
|
RawHeaderType = transport.RawHeaderType ?? Global.None;
|
||||||
Host = transport.Host ?? string.Empty;
|
Host = transport.Host ?? string.Empty;
|
||||||
@@ -443,6 +451,8 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
|||||||
Hy2RealmUrl = realm?.ToUri().NullIfEmpty(),
|
Hy2RealmUrl = realm?.ToUri().NullIfEmpty(),
|
||||||
GeckoMinPacketSize = GeckoMinPacketSize > 0 ? GeckoMinPacketSize.ToString() : null,
|
GeckoMinPacketSize = GeckoMinPacketSize > 0 ? GeckoMinPacketSize.ToString() : null,
|
||||||
GeckoMaxPacketSize = GeckoMaxPacketSize > 0 ? GeckoMaxPacketSize.ToString() : null,
|
GeckoMaxPacketSize = GeckoMaxPacketSize > 0 ? GeckoMaxPacketSize.ToString() : null,
|
||||||
|
MasquePath = MasquePath.NullIfEmpty(),
|
||||||
|
MasqueHeaders = MasqueHeaders.NullIfEmpty(),
|
||||||
});
|
});
|
||||||
SelectedSource.SetTransportExtra(transport);
|
SelectedSource.SetTransportExtra(transport);
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public partial class MainWindowViewModel : MyReactiveObject
|
|||||||
public ReactiveCommand<RxVoid, RxVoid> AddWireguardServerCmd { get; }
|
public ReactiveCommand<RxVoid, RxVoid> AddWireguardServerCmd { get; }
|
||||||
public ReactiveCommand<RxVoid, RxVoid> AddAnytlsServerCmd { get; }
|
public ReactiveCommand<RxVoid, RxVoid> AddAnytlsServerCmd { get; }
|
||||||
public ReactiveCommand<RxVoid, RxVoid> AddNaiveServerCmd { get; }
|
public ReactiveCommand<RxVoid, RxVoid> AddNaiveServerCmd { get; }
|
||||||
|
public ReactiveCommand<RxVoid, RxVoid> AddMasqueServerCmd { get; }
|
||||||
public ReactiveCommand<RxVoid, RxVoid> AddCustomServerCmd { get; }
|
public ReactiveCommand<RxVoid, RxVoid> AddCustomServerCmd { get; }
|
||||||
public ReactiveCommand<RxVoid, RxVoid> AddCustomOutboundServerCmd { get; }
|
public ReactiveCommand<RxVoid, RxVoid> AddCustomOutboundServerCmd { get; }
|
||||||
public ReactiveCommand<RxVoid, RxVoid> AddPolicyGroupServerCmd { get; }
|
public ReactiveCommand<RxVoid, RxVoid> AddPolicyGroupServerCmd { get; }
|
||||||
@@ -140,6 +141,10 @@ public partial class MainWindowViewModel : MyReactiveObject
|
|||||||
{
|
{
|
||||||
await AddServerAsync(EConfigType.Naive);
|
await AddServerAsync(EConfigType.Naive);
|
||||||
});
|
});
|
||||||
|
AddMasqueServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
|
{
|
||||||
|
await AddServerAsync(EConfigType.MASQUE);
|
||||||
|
});
|
||||||
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await AddServerAsync(EConfigType.Custom);
|
await AddServerAsync(EConfigType.Custom);
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public partial class OptionSettingViewModel : MyReactiveObject, ICloseable
|
|||||||
[Reactive] public partial string CoreType6 { get; set; }
|
[Reactive] public partial string CoreType6 { get; set; }
|
||||||
[Reactive] public partial string CoreType7 { get; set; }
|
[Reactive] public partial string CoreType7 { get; set; }
|
||||||
[Reactive] public partial string CoreType9 { get; set; }
|
[Reactive] public partial string CoreType9 { get; set; }
|
||||||
|
[Reactive] public partial string CoreType14 { get; set; }
|
||||||
|
|
||||||
#endregion CoreType
|
#endregion CoreType
|
||||||
|
|
||||||
@@ -283,6 +284,10 @@ public partial class OptionSettingViewModel : MyReactiveObject, ICloseable
|
|||||||
case 9:
|
case 9:
|
||||||
CoreType9 = type;
|
CoreType9 = type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 14:
|
||||||
|
CoreType14 = type;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
@@ -451,6 +456,10 @@ public partial class OptionSettingViewModel : MyReactiveObject, ICloseable
|
|||||||
type = CoreType9;
|
type = CoreType9;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 14:
|
||||||
|
type = CoreType14;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -783,6 +783,70 @@
|
|||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
x:Name="gridMasque"
|
||||||
|
Grid.Row="2"
|
||||||
|
ColumnDefinitions="300,Auto"
|
||||||
|
IsVisible="False"
|
||||||
|
RowDefinitions="Auto,Auto,Auto,Auto,Auto">
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbUsername}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtId14"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtSecurity14"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbPath}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtPath14"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbHttpOutboundHeaders}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtHttpHeaders14"
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
Classes="TextArea"
|
||||||
|
PlaceholderText="Header: Value"
|
||||||
|
TextWrapping="NoWrap" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
|
|||||||
@@ -141,6 +141,14 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
|||||||
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(currentTypeDisposables);
|
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(currentTypeDisposables);
|
||||||
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(currentTypeDisposables);
|
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(currentTypeDisposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.MASQUE:
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.MasquePath, v => v.txtPath14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.MasqueHeaders, v => v.txtHttpHeaders14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
@@ -284,6 +292,14 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
|||||||
|
|
||||||
cmbCongestionControl12.ItemsSource = Global.NaiveCongestionControls;
|
cmbCongestionControl12.ItemsSource = Global.NaiveCongestionControls;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.MASQUE:
|
||||||
|
gridMasque.IsVisible = true;
|
||||||
|
sepa2.IsVisible = false;
|
||||||
|
gridTransport.IsVisible = false;
|
||||||
|
cmbFingerprint.IsEnabled = false;
|
||||||
|
cmbAlpn.IsEnabled = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||||
cmbStreamSecurity.SelectedItem = profileItem.StreamSecurity;
|
cmbStreamSecurity.SelectedItem = profileItem.StreamSecurity;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
<MenuItem x:Name="menuAddTrojanServer" Header="{x:Static resx:ResUI.menuAddTrojanServer}" />
|
<MenuItem x:Name="menuAddTrojanServer" Header="{x:Static resx:ResUI.menuAddTrojanServer}" />
|
||||||
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
||||||
<MenuItem x:Name="menuAddWireguardServer" Header="{x:Static resx:ResUI.menuAddWireguardServer}" />
|
<MenuItem x:Name="menuAddWireguardServer" Header="{x:Static resx:ResUI.menuAddWireguardServer}" />
|
||||||
|
<MenuItem x:Name="menuAddMasqueServer" Header="{x:Static resx:ResUI.menuAddMasqueServer}" />
|
||||||
<MenuItem x:Name="menuAddSocksServer" Header="{x:Static resx:ResUI.menuAddSocksServer}" />
|
<MenuItem x:Name="menuAddSocksServer" Header="{x:Static resx:ResUI.menuAddSocksServer}" />
|
||||||
<MenuItem x:Name="menuAddHttpServer" Header="{x:Static resx:ResUI.menuAddHttpServer}" />
|
<MenuItem x:Name="menuAddHttpServer" Header="{x:Static resx:ResUI.menuAddHttpServer}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
|||||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.AddMasqueServerCmd, v => v.menuAddMasqueServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddCustomOutboundServerCmd, v => v.menuAddCustomOutboundServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddCustomOutboundServerCmd, v => v.menuAddCustomOutboundServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
||||||
|
|||||||
@@ -1192,7 +1192,7 @@
|
|||||||
<Grid
|
<Grid
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
ColumnDefinitions="Auto,Auto"
|
ColumnDefinitions="Auto,Auto"
|
||||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
@@ -1296,6 +1296,19 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="9"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="MASQUE" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbCoreType14"
|
||||||
|
Grid.Row="9"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
|||||||
cmbCoreType6.ItemsSource = Global.CoreTypes;
|
cmbCoreType6.ItemsSource = Global.CoreTypes;
|
||||||
cmbCoreType7.ItemsSource = Global.CoreTypes;
|
cmbCoreType7.ItemsSource = Global.CoreTypes;
|
||||||
cmbCoreType9.ItemsSource = Global.CoreTypes;
|
cmbCoreType9.ItemsSource = Global.CoreTypes;
|
||||||
|
cmbCoreType14.ItemsSource = Global.CoreTypes;
|
||||||
|
|
||||||
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(Global.SpeedTestConcurrencyCountMin, 20).ToList();
|
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(Global.SpeedTestConcurrencyCountMin, 20).ToList();
|
||||||
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
|
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
|
||||||
@@ -145,6 +146,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
|||||||
this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType7, v => v.cmbCoreType7.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType7, v => v.cmbCoreType7.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.SelectedValue).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.CoreType14, v => v.cmbCoreType14.SelectedValue).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1000,6 +1000,89 @@
|
|||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
x:Name="gridMasque"
|
||||||
|
Grid.Row="2"
|
||||||
|
Visibility="Collapsed">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="300" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbUsername}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtId14"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtSecurity14"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbPath}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtPath14"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbHttpOutboundHeaders}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtHeaders14"
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
materialDesign:HintAssist.Hint="Header: Value"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
MaxLines="12"
|
||||||
|
MinLines="3"
|
||||||
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
|
|||||||
@@ -139,6 +139,13 @@ public partial class AddServerWindow
|
|||||||
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(currentTypeDisposables);
|
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(currentTypeDisposables);
|
||||||
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(currentTypeDisposables);
|
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(currentTypeDisposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.MASQUE:
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.MasquePath, v => v.txtPath14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.MasqueHeaders, v => v.txtHeaders14.Text).DisposeWith(currentTypeDisposables);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
@@ -284,6 +291,14 @@ public partial class AddServerWindow
|
|||||||
|
|
||||||
cmbCongestionControl12.ItemsSource = Global.NaiveCongestionControls;
|
cmbCongestionControl12.ItemsSource = Global.NaiveCongestionControls;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.MASQUE:
|
||||||
|
gridMasque.Visibility = Visibility.Visible;
|
||||||
|
sepa2.Visibility = Visibility.Collapsed;
|
||||||
|
gridTransport.Visibility = Visibility.Collapsed;
|
||||||
|
cmbFingerprint.IsEnabled = false;
|
||||||
|
cmbAlpn.IsEnabled = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||||
cmbStreamSecurity.SelectedItem = profileItem.StreamSecurity;
|
cmbStreamSecurity.SelectedItem = profileItem.StreamSecurity;
|
||||||
|
|||||||
@@ -112,6 +112,10 @@
|
|||||||
x:Name="menuAddWireguardServer"
|
x:Name="menuAddWireguardServer"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuAddWireguardServer}" />
|
Header="{x:Static resx:ResUI.menuAddWireguardServer}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuAddMasqueServer"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuAddMasqueServer}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuAddSocksServer"
|
x:Name="menuAddSocksServer"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public partial class MainWindow
|
|||||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.AddMasqueServerCmd, v => v.menuAddMasqueServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddCustomOutboundServerCmd, v => v.menuAddCustomOutboundServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddCustomOutboundServerCmd, v => v.menuAddCustomOutboundServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
||||||
|
|||||||
@@ -1473,6 +1473,7 @@
|
|||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -1597,6 +1598,21 @@
|
|||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="9"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="MASQUE" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbCoreType14"
|
||||||
|
Grid.Row="9"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
Style="{StaticResource DefComboBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public partial class OptionSettingWindow
|
|||||||
cmbCoreType6.ItemsSource = Global.CoreTypes;
|
cmbCoreType6.ItemsSource = Global.CoreTypes;
|
||||||
cmbCoreType7.ItemsSource = Global.CoreTypes;
|
cmbCoreType7.ItemsSource = Global.CoreTypes;
|
||||||
cmbCoreType9.ItemsSource = Global.CoreTypes;
|
cmbCoreType9.ItemsSource = Global.CoreTypes;
|
||||||
|
cmbCoreType14.ItemsSource = Global.CoreTypes;
|
||||||
|
|
||||||
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(Global.SpeedTestConcurrencyCountMin, 20).ToList();
|
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(Global.SpeedTestConcurrencyCountMin, 20).ToList();
|
||||||
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
|
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
|
||||||
@@ -141,6 +142,7 @@ public partial class OptionSettingWindow
|
|||||||
this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType7, v => v.cmbCoreType7.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType7, v => v.cmbCoreType7.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.CoreType14, v => v.cmbCoreType14.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user