Compare commits

..

No commits in common. "9f9b90cb9753e76ba18cfd26acf21ace5f75b30a" and "fe183798b6bc673249875f0fc0afdd136fc40d31" have entirely different histories.

33 changed files with 45 additions and 411 deletions

View file

@ -300,7 +300,6 @@ public class Global
EConfigType.VLESS, EConfigType.VLESS,
EConfigType.Shadowsocks, EConfigType.Shadowsocks,
EConfigType.Trojan, EConfigType.Trojan,
EConfigType.Hysteria2,
EConfigType.WireGuard, EConfigType.WireGuard,
EConfigType.SOCKS, EConfigType.SOCKS,
EConfigType.HTTP, EConfigType.HTTP,

View file

@ -253,7 +253,6 @@ public static class ConfigHandler
item.Extra = profileItem.Extra; item.Extra = profileItem.Extra;
item.MuxEnabled = profileItem.MuxEnabled; item.MuxEnabled = profileItem.MuxEnabled;
item.Cert = profileItem.Cert; item.Cert = profileItem.Cert;
item.CertSha = profileItem.CertSha;
item.EchConfigList = profileItem.EchConfigList; item.EchConfigList = profileItem.EchConfigList;
item.EchForceQuery = profileItem.EchForceQuery; item.EchForceQuery = profileItem.EchForceQuery;
} }
@ -703,7 +702,7 @@ public static class ConfigHandler
public static async Task<int> AddHysteria2Server(Config config, ProfileItem profileItem, bool toFile = true) public static async Task<int> AddHysteria2Server(Config config, ProfileItem profileItem, bool toFile = true)
{ {
profileItem.ConfigType = EConfigType.Hysteria2; profileItem.ConfigType = EConfigType.Hysteria2;
//profileItem.CoreType = ECoreType.sing_box; profileItem.CoreType = ECoreType.sing_box;
profileItem.Address = profileItem.Address.TrimEx(); profileItem.Address = profileItem.Address.TrimEx();
profileItem.Id = profileItem.Id.TrimEx(); profileItem.Id = profileItem.Id.TrimEx();

View file

@ -74,10 +74,6 @@ public class BaseFmt
{ {
dicQuery.Add("ech", Utils.UrlEncode(item.EchConfigList)); dicQuery.Add("ech", Utils.UrlEncode(item.EchConfigList));
} }
if (item.CertSha.IsNotEmpty())
{
dicQuery.Add("pcs", Utils.UrlEncode(item.CertSha));
}
dicQuery.Add("type", item.Network.IsNotEmpty() ? item.Network : nameof(ETransport.tcp)); dicQuery.Add("type", item.Network.IsNotEmpty() ? item.Network : nameof(ETransport.tcp));
@ -218,7 +214,6 @@ public class BaseFmt
item.SpiderX = GetQueryDecoded(query, "spx"); item.SpiderX = GetQueryDecoded(query, "spx");
item.Mldsa65Verify = GetQueryDecoded(query, "pqv"); item.Mldsa65Verify = GetQueryDecoded(query, "pqv");
item.EchConfigList = GetQueryDecoded(query, "ech"); item.EchConfigList = GetQueryDecoded(query, "ech");
item.CertSha = GetQueryDecoded(query, "pcs");
if (_allowInsecureArray.Any(k => GetQueryDecoded(query, k) == "1")) if (_allowInsecureArray.Any(k => GetQueryDecoded(query, k) == "1"))
{ {

View file

@ -25,10 +25,6 @@ public class Hysteria2Fmt : BaseFmt
ResolveUriQuery(query, ref item); ResolveUriQuery(query, ref item);
item.Path = GetQueryDecoded(query, "obfs-password"); item.Path = GetQueryDecoded(query, "obfs-password");
item.Ports = GetQueryDecoded(query, "mport"); item.Ports = GetQueryDecoded(query, "mport");
if (item.CertSha.IsNullOrEmpty())
{
item.CertSha = GetQueryDecoded(query, "pinSHA256");
}
return item; return item;
} }
@ -59,16 +55,6 @@ public class Hysteria2Fmt : BaseFmt
{ {
dicQuery.Add("mport", Utils.UrlEncode(item.Ports.Replace(':', '-'))); dicQuery.Add("mport", Utils.UrlEncode(item.Ports.Replace(':', '-')));
} }
if (!item.CertSha.IsNullOrEmpty())
{
var sha = item.CertSha;
var idx = sha.IndexOf('~');
if (idx > 0)
{
sha = sha[..idx];
}
dicQuery.Add("pinSHA256", Utils.UrlEncode(sha));
}
return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark); return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark);
} }

View file

@ -168,9 +168,7 @@ public class ActionPrecheckManager
if (item.StreamSecurity == Global.StreamSecurity) if (item.StreamSecurity == Global.StreamSecurity)
{ {
// check certificate validity // check certificate validity
if (!item.Cert.IsNullOrEmpty() if ((!item.Cert.IsNullOrEmpty()) && (CertPemManager.ParsePemChain(item.Cert).Count == 0))
&& (CertPemManager.ParsePemChain(item.Cert).Count == 0)
&& !item.CertSha.IsNullOrEmpty())
{ {
errors.Add(string.Format(ResUI.InvalidProperty, "TLS Certificate")); errors.Add(string.Format(ResUI.InvalidProperty, "TLS Certificate"));
} }

View file

@ -416,22 +416,4 @@ public class CertPemManager
return string.Concat(pemList); return string.Concat(pemList);
} }
public static string GetCertSha256Thumbprint(string pemCert, bool includeColon = false)
{
try
{
var cert = X509Certificate2.CreateFromPem(pemCert);
var thumbprint = cert.GetCertHashString(HashAlgorithmName.SHA256);
if (includeColon)
{
return string.Join(":", thumbprint.Chunk(2).Select(c => new string(c)));
}
return thumbprint;
}
catch
{
return string.Empty;
}
}
} }

View file

@ -43,12 +43,9 @@ public sealed class WebDavManager
_webDir = _config.WebDavItem.DirName.TrimEx(); _webDir = _config.WebDavItem.DirName.TrimEx();
} }
// Ensure BaseAddress URL ends with a trailing slash
var baseUrl = _config.WebDavItem.Url.Trim().TrimEnd('/') + "/";
var clientParams = new WebDavClientParams var clientParams = new WebDavClientParams
{ {
BaseAddress = new Uri(baseUrl), BaseAddress = new Uri(_config.WebDavItem.Url),
Credentials = new NetworkCredential(_config.WebDavItem.UserName, _config.WebDavItem.Password) Credentials = new NetworkCredential(_config.WebDavItem.UserName, _config.WebDavItem.Password)
}; };
_client = new WebDavClient(clientParams); _client = new WebDavClient(clientParams);

View file

@ -161,7 +161,6 @@ public class ProfileItem : ReactiveObject
public string Extra { get; set; } public string Extra { get; set; }
public bool? MuxEnabled { get; set; } public bool? MuxEnabled { get; set; }
public string Cert { get; set; } public string Cert { get; set; }
public string CertSha { get; set; }
public string EchConfigList { get; set; } public string EchConfigList { get; set; }
public string EchForceQuery { get; set; } public string EchForceQuery { get; set; }
} }

View file

@ -68,7 +68,6 @@ public class Rule4Sbox
public List<string>? ip_cidr { get; set; } public List<string>? ip_cidr { get; set; }
public List<string>? source_ip_cidr { get; set; } public List<string>? source_ip_cidr { get; set; }
public List<string>? process_name { get; set; } public List<string>? process_name { get; set; }
public List<string>? process_path { get; set; }
public List<string>? rule_set { get; set; } public List<string>? rule_set { get; set; }
public List<Rule4Sbox>? rules { get; set; } public List<Rule4Sbox>? rules { get; set; }
public string? action { get; set; } public string? action { get; set; }

View file

@ -128,8 +128,7 @@ public class Outboundsettings4Ray
public string? secretKey { get; set; } public string? secretKey { get; set; }
public Object? address { get; set; } public List<string>? address { get; set; }
public int? port { get; set; }
public List<WireguardPeer4Ray>? peers { get; set; } public List<WireguardPeer4Ray>? peers { get; set; }
@ -140,8 +139,6 @@ public class Outboundsettings4Ray
public List<int>? reserved { get; set; } public List<int>? reserved { get; set; }
public int? workers { get; set; } public int? workers { get; set; }
public int? version { get; set; }
} }
public class WireguardPeer4Ray public class WireguardPeer4Ray
@ -259,8 +256,6 @@ public class RulesItem4Ray
public List<string>? domain { get; set; } public List<string>? domain { get; set; }
public List<string>? protocol { get; set; } public List<string>? protocol { get; set; }
public List<string>? process { get; set; }
} }
public class BalancersItem4Ray public class BalancersItem4Ray
@ -341,10 +336,6 @@ public class StreamSettings4Ray
public GrpcSettings4Ray? grpcSettings { get; set; } public GrpcSettings4Ray? grpcSettings { get; set; }
public HysteriaSettings4Ray? hysteriaSettings { get; set; }
public List<UdpMasks4Ray>? udpmasks { get; set; }
public Sockopt4Ray? sockopt { get; set; } public Sockopt4Ray? sockopt { get; set; }
} }
@ -364,7 +355,6 @@ public class TlsSettings4Ray
public string? spiderX { get; set; } public string? spiderX { get; set; }
public string? mldsa65Verify { get; set; } public string? mldsa65Verify { get; set; }
public List<CertificateSettings4Ray>? certificates { get; set; } public List<CertificateSettings4Ray>? certificates { get; set; }
public string? pinnedPeerCertSha256 { get; set; }
public bool? disableSystemRoot { get; set; } public bool? disableSystemRoot { get; set; }
public string? echConfigList { get; set; } public string? echConfigList { get; set; }
public string? echForceQuery { get; set; } public string? echForceQuery { get; set; }
@ -469,32 +459,6 @@ public class GrpcSettings4Ray
public int? initial_windows_size { get; set; } public int? initial_windows_size { get; set; }
} }
public class HysteriaSettings4Ray
{
public int version { get; set; }
public string? auth { get; set; }
public string? up { get; set; }
public string? down { get; set; }
public HysteriaUdpHop4Ray? udphop { get; set; }
}
public class HysteriaUdpHop4Ray
{
public string? ports { get; set; }
public int? interval { get; set; }
}
public class UdpMasks4Ray
{
public string type { get; set; }
public UdpMasksSettings4Ray? settings { get; set; }
}
public class UdpMasksSettings4Ray
{
public string? password { get; set; }
}
public class AccountsItem4Ray public class AccountsItem4Ray
{ {
public string user { get; set; } public string user { get; set; }

View file

@ -2617,7 +2617,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Pinned certificate (fill in either one) /// 查找类似 Server Certificate (PEM format, optional)
///When specified, the certificate will be pinned, and &quot;Allow Insecure&quot; will be disabled. ///When specified, the certificate will be pinned, and &quot;Allow Insecure&quot; will be disabled.
/// ///
///The &quot;Get Certificate&quot; action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. 的本地化字符串。 ///The &quot;Get Certificate&quot; action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. 的本地化字符串。
@ -2628,15 +2628,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Certificate fingerprint (SHA-256) 的本地化字符串。
/// </summary>
public static string TbCertSha256Tips {
get {
return ResourceManager.GetString("TbCertSha256Tips", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Clear system proxy 的本地化字符串。 /// 查找类似 Clear system proxy 的本地化字符串。
/// </summary> /// </summary>
@ -2898,15 +2889,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Full certificate (chain), PEM format 的本地化字符串。
/// </summary>
public static string TbFullCertTips {
get {
return ResourceManager.GetString("TbFullCertTips", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core&apos;s basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you. 的本地化字符串。 /// 查找类似 This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core&apos;s basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you. 的本地化字符串。
/// </summary> /// </summary>
@ -3286,7 +3268,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Process (Tun mode) 的本地化字符串。 /// 查找类似 Full process name (Tun mode) 的本地化字符串。
/// </summary> /// </summary>
public static string TbRoutingRuleProcess { public static string TbRoutingRuleProcess {
get { get {

View file

@ -1027,7 +1027,7 @@
<value>پروتکل sing-box Mux</value> <value>پروتکل sing-box Mux</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Process (Tun mode)</value> <value>نام کامل فرانید (حالت Tun)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP or IP CIDR</value> <value>IP or IP CIDR</value>
@ -1647,10 +1647,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>Full certificate (chain), PEM format</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>Certificate fingerprint (SHA-256)</value>
</data>
</root> </root>

View file

@ -1024,7 +1024,7 @@
<value>Protocole de multiplexage Mux (sing-box)</value> <value>Protocole de multiplexage Mux (sing-box)</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Process (Tun mode)</value> <value>Nom complet du processus (mode Tun)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP ou IP CIDR</value> <value>IP ou IP CIDR</value>
@ -1606,10 +1606,10 @@
<value>Certificate Pinning</value> <value>Certificate Pinning</value>
</data> </data>
<data name="TbCertPinningTips" xml:space="preserve"> <data name="TbCertPinningTips" xml:space="preserve">
<value>Pinned certificate (fill in either one) <value>Certificat serveur (format PEM, facultatif)
When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. Si le certificat est défini, il est fixé et loption « Ignorer la vérification » est désactivée.
The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value> Si un certificat auto-signé est utilisé ou si le système contient une CA non fiable ou malveillante, laction « Obtenir le certificat » peut échouer.</value>
</data> </data>
<data name="TbFetchCert" xml:space="preserve"> <data name="TbFetchCert" xml:space="preserve">
<value>Obtenir le certificat</value> <value>Obtenir le certificat</value>
@ -1644,10 +1644,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>Full certificate (chain), PEM format</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>Certificate fingerprint (SHA-256)</value>
</data>
</root> </root>

View file

@ -1027,7 +1027,7 @@
<value>sing-box Mux protokoll</value> <value>sing-box Mux protokoll</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Process (Tun mode)</value> <value>Teljes folyamatnév (Tun mód)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP vagy IP CIDR</value> <value>IP vagy IP CIDR</value>
@ -1609,7 +1609,7 @@
<value>Certificate Pinning</value> <value>Certificate Pinning</value>
</data> </data>
<data name="TbCertPinningTips" xml:space="preserve"> <data name="TbCertPinningTips" xml:space="preserve">
<value>Pinned certificate (fill in either one) <value>Server Certificate (PEM format, optional)
When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. When specified, the certificate will be pinned, and "Allow Insecure" will be disabled.
The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value> The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value>
@ -1647,10 +1647,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>Full certificate (chain), PEM format</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>Certificate fingerprint (SHA-256)</value>
</data>
</root> </root>

View file

@ -1027,7 +1027,7 @@
<value>sing-box Mux Protocol</value> <value>sing-box Mux Protocol</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Process (Tun mode)</value> <value>Full process name (Tun mode)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP or IP CIDR</value> <value>IP or IP CIDR</value>
@ -1609,7 +1609,7 @@
<value>Certificate Pinning</value> <value>Certificate Pinning</value>
</data> </data>
<data name="TbCertPinningTips" xml:space="preserve"> <data name="TbCertPinningTips" xml:space="preserve">
<value>Pinned certificate (fill in either one) <value>Server Certificate (PEM format, optional)
When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. When specified, the certificate will be pinned, and "Allow Insecure" will be disabled.
The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value> The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value>
@ -1647,10 +1647,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>Full certificate (chain), PEM format</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>Certificate fingerprint (SHA-256)</value>
</data>
</root> </root>

View file

@ -1027,7 +1027,7 @@
<value>Протокол Mux для sing-box</value> <value>Протокол Mux для sing-box</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Process (Tun mode)</value> <value>Полное имя процесса (режим TUN)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP-адрес или сеть CIDR</value> <value>IP-адрес или сеть CIDR</value>
@ -1609,7 +1609,7 @@
<value>Certificate Pinning</value> <value>Certificate Pinning</value>
</data> </data>
<data name="TbCertPinningTips" xml:space="preserve"> <data name="TbCertPinningTips" xml:space="preserve">
<value>Pinned certificate (fill in either one) <value>Server Certificate (PEM format, optional)
When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. When specified, the certificate will be pinned, and "Allow Insecure" will be disabled.
The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value> The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value>
@ -1647,10 +1647,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>Full certificate (chain), PEM format</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>Certificate fingerprint (SHA-256)</value>
</data>
</root> </root>

View file

@ -1024,7 +1024,7 @@
<value>sing-box Mux 多路复用协议</value> <value>sing-box Mux 多路复用协议</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>进程 (Tun 模式)</value> <value>进程名全称 (Tun 模式)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP 或 IP CIDR</value> <value>IP 或 IP CIDR</value>
@ -1606,10 +1606,10 @@
<value>固定证书</value> <value>固定证书</value>
</data> </data>
<data name="TbCertPinningTips" xml:space="preserve"> <data name="TbCertPinningTips" xml:space="preserve">
<value>固定证书(二选一填写即可 <value>服务器证书PEM 格式,可选
当指定此证书后,将固定该证书,并禁用“跳过证书验证”选项。 当指定此证书后,将固定该证书,并禁用“跳过证书验证”选项。
“获取证书”操作可能失败,原因包括使用了自签名证书,或系统中存在不受信任甚至恶意的 CA。</value> “获取证书”操作可能失败,原因可能是使用了自签证书,或系统中存在不受信任或恶意的 CA。</value>
</data> </data>
<data name="TbFetchCert" xml:space="preserve"> <data name="TbFetchCert" xml:space="preserve">
<value>获取证书</value> <value>获取证书</value>
@ -1644,10 +1644,4 @@
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>完整证书PEM 格式</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>证书指纹SHA-256</value>
</data>
</root> </root>

View file

@ -1024,7 +1024,7 @@
<value>sing-box Mux 多路復用協定</value> <value>sing-box Mux 多路復用協定</value>
</data> </data>
<data name="TbRoutingRuleProcess" xml:space="preserve"> <data name="TbRoutingRuleProcess" xml:space="preserve">
<value>行程 (Tun 模式)</value> <value>行程名全稱 (Tun 模式)</value>
</data> </data>
<data name="TbRoutingRuleIP" xml:space="preserve"> <data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP 或 IP CIDR</value> <value>IP 或 IP CIDR</value>
@ -1606,7 +1606,7 @@
<value>憑證綁定</value> <value>憑證綁定</value>
</data> </data>
<data name="TbCertPinningTips" xml:space="preserve"> <data name="TbCertPinningTips" xml:space="preserve">
<value>固定憑證(二選一填寫即可 <value>伺服器憑證PEM 格式,可選
若已指定,憑證將會被綁定,並且「跳過憑證驗證」將被停用。 若已指定,憑證將會被綁定,並且「跳過憑證驗證」將被停用。
若使用自簽憑證,或系統中存在不受信任或惡意的 CA「取得憑證」動作可能會失敗。</value> 若使用自簽憑證,或系統中存在不受信任或惡意的 CA「取得憑證」動作可能會失敗。</value>
@ -1644,10 +1644,4 @@
<data name="TbEchForceQuery" xml:space="preserve"> <data name="TbEchForceQuery" xml:space="preserve">
<value>EchForceQuery</value> <value>EchForceQuery</value>
</data> </data>
<data name="TbFullCertTips" xml:space="preserve">
<value>Full certificate (chain), PEM format</value>
</data>
<data name="TbCertSha256Tips" xml:space="preserve">
<value>Certificate fingerprint (SHA-256)</value>
</data>
</root> </root>

View file

@ -280,49 +280,9 @@ public partial class CoreConfigSingboxService
if (_config.TunModeItem.EnableTun && item.Process?.Count > 0) if (_config.TunModeItem.EnableTun && item.Process?.Count > 0)
{ {
var ruleProcName = JsonUtils.DeepCopy(rule3); rule3.process_name = item.Process;
var ruleProcPath = JsonUtils.DeepCopy(rule3); rules.Add(rule3);
foreach (var process in item.Process) hasDomainIp = true;
{
// sing-box doesn't support this, fall back to process name match
if (process is "self/" or "xray/")
{
ruleProcName.process_name.Add(Utils.GetExeName("sing-box"));
continue;
}
if (process.Contains('/') || process.Contains('\\'))
{
var procPath = process;
if (Utils.IsWindows())
{
procPath = procPath.Replace('/', '\\');
}
ruleProcPath.process_path.Add(procPath);
continue;
}
// sing-box strictly matches the exe suffix on Windows
var procName = process;
if (Utils.IsWindows() && !procName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
{
procName += ".exe";
}
ruleProcName.process_name.Add(procName);
}
if (ruleProcName.process_name.Count > 0)
{
rules.Add(ruleProcName);
hasDomainIp = true;
}
if (ruleProcPath.process_path.Count > 0)
{
rules.Add(ruleProcPath);
hasDomainIp = true;
}
} }
if (!hasDomainIp if (!hasDomainIp

View file

@ -178,18 +178,6 @@ public partial class CoreConfigV2rayService
outbound.settings.vnext = null; outbound.settings.vnext = null;
break; break;
} }
case EConfigType.Hysteria2:
{
outbound.settings = new()
{
version = 2,
address = node.Address,
port = node.Port,
};
outbound.settings.vnext = null;
outbound.settings.servers = null;
break;
}
case EConfigType.WireGuard: case EConfigType.WireGuard:
{ {
var address = node.Address; var address = node.Address;
@ -218,10 +206,6 @@ public partial class CoreConfigV2rayService
} }
outbound.protocol = Global.ProtocolTypes[node.ConfigType]; outbound.protocol = Global.ProtocolTypes[node.ConfigType];
if (node.ConfigType == EConfigType.Hysteria2)
{
outbound.protocol = "hysteria";
}
await GenBoundStreamSettings(node, outbound); await GenBoundStreamSettings(node, outbound);
} }
catch (Exception ex) catch (Exception ex)
@ -262,12 +246,7 @@ public partial class CoreConfigV2rayService
try try
{ {
var streamSettings = outbound.streamSettings; var streamSettings = outbound.streamSettings;
var network = node.GetNetwork(); streamSettings.network = node.GetNetwork();
if (node.ConfigType == EConfigType.Hysteria2)
{
network = "hysteria";
}
streamSettings.network = network;
var host = node.RequestHost.TrimEx(); var host = node.RequestHost.TrimEx();
var path = node.Path.TrimEx(); var path = node.Path.TrimEx();
var sni = node.Sni.TrimEx(); var sni = node.Sni.TrimEx();
@ -322,10 +301,6 @@ public partial class CoreConfigV2rayService
tlsSettings.disableSystemRoot = true; tlsSettings.disableSystemRoot = true;
tlsSettings.allowInsecure = false; tlsSettings.allowInsecure = false;
} }
else if (!node.CertSha.IsNullOrEmpty())
{
tlsSettings.pinnedPeerCertSha256 = node.CertSha;
}
streamSettings.tlsSettings = tlsSettings; streamSettings.tlsSettings = tlsSettings;
} }
@ -349,7 +324,7 @@ public partial class CoreConfigV2rayService
} }
//streamSettings //streamSettings
switch (network) switch (node.GetNetwork())
{ {
case nameof(ETransport.kcp): case nameof(ETransport.kcp):
KcpSettings4Ray kcpSettings = new() KcpSettings4Ray kcpSettings = new()
@ -488,35 +463,6 @@ public partial class CoreConfigV2rayService
streamSettings.grpcSettings = grpcSettings; streamSettings.grpcSettings = grpcSettings;
break; break;
case "hysteria":
HysteriaUdpHop4Ray? udpHop = null;
if (node.Ports.IsNotEmpty() &&
(node.Ports.Contains(':') || node.Ports.Contains('-') || node.Ports.Contains(',')))
{
udpHop = new()
{
ports = node.Ports.Replace(':', '-'),
interval = _config.HysteriaItem.HopInterval > 0
? _config.HysteriaItem.HopInterval
: null,
};
}
HysteriaSettings4Ray hysteriaSettings = new()
{
version = 2,
auth = node.Id,
up = _config.HysteriaItem.UpMbps > 0 ? $"{_config.HysteriaItem.UpMbps}mbps" : null,
down = _config.HysteriaItem.DownMbps > 0 ? $"{_config.HysteriaItem.DownMbps}mbps" : null,
udphop = udpHop,
};
streamSettings.hysteriaSettings = hysteriaSettings;
if (node.Path.IsNotEmpty())
{
streamSettings.udpmasks =
[new() { type = "salamander", settings = new() { password = node.Path.TrimEx(), } }];
}
break;
default: default:
//tcp //tcp
if (node.HeaderType == Global.TcpHeaderHttp) if (node.HeaderType == Global.TcpHeaderHttp)

View file

@ -77,17 +77,12 @@ public partial class CoreConfigV2rayService
{ {
rule.inboundTag = null; rule.inboundTag = null;
} }
if (rule.process?.Count == 0)
{
rule.process = null;
}
var hasDomainIp = false; var hasDomainIp = false;
if (rule.domain?.Count > 0) if (rule.domain?.Count > 0)
{ {
var it = JsonUtils.DeepCopy(rule); var it = JsonUtils.DeepCopy(rule);
it.ip = null; it.ip = null;
it.process = null;
it.type = "field"; it.type = "field";
for (var k = it.domain.Count - 1; k >= 0; k--) for (var k = it.domain.Count - 1; k >= 0; k--)
{ {
@ -104,16 +99,6 @@ public partial class CoreConfigV2rayService
{ {
var it = JsonUtils.DeepCopy(rule); var it = JsonUtils.DeepCopy(rule);
it.domain = null; it.domain = null;
it.process = null;
it.type = "field";
v2rayConfig.routing.rules.Add(it);
hasDomainIp = true;
}
if (_config.TunModeItem.EnableTun && rule.process?.Count > 0)
{
var it = JsonUtils.DeepCopy(rule);
it.domain = null;
it.ip = null;
it.type = "field"; it.type = "field";
v2rayConfig.routing.rules.Add(it); v2rayConfig.routing.rules.Add(it);
hasDomainIp = true; hasDomainIp = true;

View file

@ -14,9 +14,6 @@ public class AddServerViewModel : MyReactiveObject
[Reactive] [Reactive]
public string CertTip { get; set; } public string CertTip { get; set; }
[Reactive]
public string CertSha { get; set; }
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; } public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; } public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
@ -42,12 +39,6 @@ public class AddServerViewModel : MyReactiveObject
this.WhenAnyValue(x => x.Cert) this.WhenAnyValue(x => x.Cert)
.Subscribe(_ => UpdateCertTip()); .Subscribe(_ => UpdateCertTip());
this.WhenAnyValue(x => x.CertSha)
.Subscribe(_ => UpdateCertTip());
this.WhenAnyValue(x => x.Cert)
.Subscribe(_ => UpdateCertSha());
if (profileItem.IndexId.IsNullOrEmpty()) if (profileItem.IndexId.IsNullOrEmpty())
{ {
profileItem.Network = Global.DefaultNetwork; profileItem.Network = Global.DefaultNetwork;
@ -106,8 +97,7 @@ public class AddServerViewModel : MyReactiveObject
} }
} }
SelectedSource.CoreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType); SelectedSource.CoreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
SelectedSource.Cert = Cert.IsNullOrEmpty() ? string.Empty : Cert; SelectedSource.Cert = Cert.IsNullOrEmpty() ? null : Cert;
SelectedSource.CertSha = CertSha.IsNullOrEmpty() ? string.Empty : CertSha;
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0) if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
{ {
@ -123,36 +113,10 @@ public class AddServerViewModel : MyReactiveObject
private void UpdateCertTip(string? errorMessage = null) private void UpdateCertTip(string? errorMessage = null)
{ {
CertTip = errorMessage.IsNullOrEmpty() CertTip = errorMessage.IsNullOrEmpty()
? ((Cert.IsNullOrEmpty() && CertSha.IsNullOrEmpty()) ? ResUI.CertNotSet : ResUI.CertSet) ? (Cert.IsNullOrEmpty() ? ResUI.CertNotSet : ResUI.CertSet)
: errorMessage; : errorMessage;
} }
private void UpdateCertSha()
{
if (Cert.IsNullOrEmpty())
{
return;
}
var certList = CertPemManager.ParsePemChain(Cert);
if (certList.Count == 0)
{
return;
}
List<string> shaList = new();
foreach (var cert in certList)
{
var sha = CertPemManager.GetCertSha256Thumbprint(cert);
if (sha.IsNullOrEmpty())
{
return;
}
shaList.Add(sha);
}
CertSha = string.Join('~', shaList);
}
private async Task FetchCert() private async Task FetchCert()
{ {
if (SelectedSource.StreamSecurity != Global.StreamSecurity) if (SelectedSource.StreamSecurity != Global.StreamSecurity)
@ -178,8 +142,8 @@ public class AddServerViewModel : MyReactiveObject
{ {
domain += $":{SelectedSource.Port}"; domain += $":{SelectedSource.Port}";
} }
string certError;
(Cert, var certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName); (Cert, certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName);
UpdateCertTip(certError); UpdateCertTip(certError);
} }
@ -208,8 +172,8 @@ public class AddServerViewModel : MyReactiveObject
{ {
domain += $":{SelectedSource.Port}"; domain += $":{SelectedSource.Port}";
} }
string certError;
var (certs, certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName); (var certs, certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName);
Cert = CertPemManager.ConcatenatePemChain(certs); Cert = CertPemManager.ConcatenatePemChain(certs);
UpdateCertTip(certError); UpdateCertTip(certError);
} }

View file

@ -108,7 +108,6 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public string CoreType4 { get; set; } [Reactive] public string CoreType4 { get; set; }
[Reactive] public string CoreType5 { get; set; } [Reactive] public string CoreType5 { get; set; }
[Reactive] public string CoreType6 { get; set; } [Reactive] public string CoreType6 { get; set; }
[Reactive] public string CoreType7 { get; set; }
[Reactive] public string CoreType9 { get; set; } [Reactive] public string CoreType9 { get; set; }
#endregion CoreType #endregion CoreType
@ -277,10 +276,6 @@ public class OptionSettingViewModel : MyReactiveObject
CoreType6 = type; CoreType6 = type;
break; break;
case 7:
CoreType7 = type;
break;
case 9: case 9:
CoreType9 = type; CoreType9 = type;
break; break;
@ -432,10 +427,6 @@ public class OptionSettingViewModel : MyReactiveObject
type = CoreType6; type = CoreType6;
break; break;
case 7:
type = CoreType7;
break;
case 9: case 9:
type = CoreType9; type = CoreType9;
break; break;

View file

@ -841,23 +841,6 @@
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
Content="{x:Static resx:ResUI.TbFetchCertChain}" /> Content="{x:Static resx:ResUI.TbFetchCertChain}" />
</StackPanel> </StackPanel>
<TextBlock
Width="400"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbCertSha256Tips}"
TextWrapping="Wrap" />
<TextBox
x:Name="txtCertSha256Pinning"
Width="400"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Width="400"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbFullCertTips}"
TextWrapping="Wrap" />
<TextBox <TextBox
x:Name="txtCert" x:Name="txtCert"
Width="400" Width="400"

View file

@ -75,6 +75,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
gridHysteria2.IsVisible = true; gridHysteria2.IsVisible = true;
sepa2.IsVisible = false; sepa2.IsVisible = false;
gridTransport.IsVisible = false; gridTransport.IsVisible = false;
cmbCoreType.IsEnabled = false;
cmbFingerprint.IsEnabled = false; cmbFingerprint.IsEnabled = false;
cmbFingerprint.SelectedValue = string.Empty; cmbFingerprint.SelectedValue = string.Empty;
break; break;
@ -185,7 +186,6 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
this.Bind(ViewModel, vm => vm.SelectedSource.AllowInsecure, v => v.cmbAllowInsecure.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AllowInsecure, v => v.cmbAllowInsecure.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Alpn, v => v.cmbAlpn.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Alpn, v => v.cmbAlpn.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CertSha, v => v.txtCertSha256Pinning.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.EchConfigList, v => v.txtEchConfigList.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.EchConfigList, v => v.txtEchConfigList.Text).DisposeWith(disposables);

View file

@ -43,11 +43,11 @@
<MenuItem x:Name="menuAddVlessServer" Header="{x:Static resx:ResUI.menuAddVlessServer}" /> <MenuItem x:Name="menuAddVlessServer" Header="{x:Static resx:ResUI.menuAddVlessServer}" />
<MenuItem x:Name="menuAddShadowsocksServer" Header="{x:Static resx:ResUI.menuAddShadowsocksServer}" /> <MenuItem x:Name="menuAddShadowsocksServer" Header="{x:Static resx:ResUI.menuAddShadowsocksServer}" />
<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="menuAddWireguardServer" Header="{x:Static resx:ResUI.menuAddWireguardServer}" /> <MenuItem x:Name="menuAddWireguardServer" Header="{x:Static resx:ResUI.menuAddWireguardServer}" />
<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 />
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
<MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" /> <MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" />
<MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" /> <MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
</MenuItem> </MenuItem>

View file

@ -463,7 +463,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding BlIsLinux}" IsVisible="{Binding BlIsLinux}"
Text="{x:Static resx:ResUI.TbSettingsHide2TrayWhenCloseTip}" /> Text="{x:Static resx:ResUI.TbSettingsHide2TrayWhenCloseTip}" />
<TextBlock <TextBlock
Grid.Row="10" Grid.Row="10"
Grid.Column="0" Grid.Column="0"
@ -477,7 +477,7 @@
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
IsVisible="{Binding BlIsIsMacOS}" /> IsVisible="{Binding BlIsIsMacOS}"/>
<TextBlock <TextBlock
Grid.Row="11" Grid.Row="11"
@ -876,7 +876,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">
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
@ -960,23 +960,10 @@
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="Hysteria2" />
<ComboBox
x:Name="cmbCoreType7"
Grid.Row="7"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}" />
<TextBlock
Grid.Row="8"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="Wireguard" /> Text="Wireguard" />
<ComboBox <ComboBox
x:Name="cmbCoreType9" x:Name="cmbCoreType9"
Grid.Row="8" Grid.Row="7"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin4}" /> Margin="{StaticResource Margin4}" />

View file

@ -41,7 +41,6 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
cmbCoreType4.ItemsSource = Global.CoreTypes; cmbCoreType4.ItemsSource = Global.CoreTypes;
cmbCoreType5.ItemsSource = Global.CoreTypes; cmbCoreType5.ItemsSource = Global.CoreTypes;
cmbCoreType6.ItemsSource = Global.CoreTypes; cmbCoreType6.ItemsSource = Global.CoreTypes;
cmbCoreType7.ItemsSource = Global.CoreTypes;
cmbCoreType9.ItemsSource = Global.CoreTypes; cmbCoreType9.ItemsSource = Global.CoreTypes;
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList(); cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList();
@ -123,7 +122,6 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
this.Bind(ViewModel, vm => vm.CoreType4, v => v.cmbCoreType4.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType4, v => v.cmbCoreType4.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.SelectedValue).DisposeWith(disposables);
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.CoreType9, v => v.cmbCoreType9.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.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);

View file

@ -1072,26 +1072,6 @@
Content="{x:Static resx:ResUI.TbFetchCertChain}" Content="{x:Static resx:ResUI.TbFetchCertChain}"
Style="{StaticResource DefButton}" /> Style="{StaticResource DefButton}" />
</StackPanel> </StackPanel>
<TextBlock
Width="400"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbCertSha256Tips}"
TextWrapping="Wrap" />
<TextBox
x:Name="txtCertSha256Pinning"
Width="400"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
Width="400"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbFullCertTips}"
TextWrapping="Wrap" />
<TextBox <TextBox
x:Name="txtCert" x:Name="txtCert"
Width="400" Width="400"

View file

@ -70,6 +70,7 @@ public partial class AddServerWindow
gridHysteria2.Visibility = Visibility.Visible; gridHysteria2.Visibility = Visibility.Visible;
sepa2.Visibility = Visibility.Collapsed; sepa2.Visibility = Visibility.Collapsed;
gridTransport.Visibility = Visibility.Collapsed; gridTransport.Visibility = Visibility.Collapsed;
cmbCoreType.IsEnabled = false;
cmbFingerprint.IsEnabled = false; cmbFingerprint.IsEnabled = false;
cmbFingerprint.Text = string.Empty; cmbFingerprint.Text = string.Empty;
break; break;
@ -180,7 +181,6 @@ public partial class AddServerWindow
this.Bind(ViewModel, vm => vm.SelectedSource.AllowInsecure, v => v.cmbAllowInsecure.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AllowInsecure, v => v.cmbAllowInsecure.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Alpn, v => v.cmbAlpn.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Alpn, v => v.cmbAlpn.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CertSha, v => v.txtCertSha256Pinning.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);

View file

@ -99,10 +99,6 @@
x:Name="menuAddTrojanServer" x:Name="menuAddTrojanServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddTrojanServer}" /> Header="{x:Static resx:ResUI.menuAddTrojanServer}" />
<MenuItem
x:Name="menuAddHysteria2Server"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
<MenuItem <MenuItem
x:Name="menuAddWireguardServer" x:Name="menuAddWireguardServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
@ -116,6 +112,10 @@
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddHttpServer}" /> Header="{x:Static resx:ResUI.menuAddHttpServer}" />
<Separator Margin="-40,5" /> <Separator Margin="-40,5" />
<MenuItem
x:Name="menuAddHysteria2Server"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
<MenuItem <MenuItem
x:Name="menuAddTuicServer" x:Name="menuAddTuicServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"

View file

@ -1138,7 +1138,6 @@
<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" />
@ -1240,25 +1239,10 @@
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="Hysteria2" />
<ComboBox
x:Name="cmbCoreType7"
Grid.Row="7"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="8"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Wireguard" /> Text="Wireguard" />
<ComboBox <ComboBox
x:Name="cmbCoreType9" x:Name="cmbCoreType9"
Grid.Row="8" Grid.Row="7"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"

View file

@ -38,7 +38,6 @@ public partial class OptionSettingWindow
cmbCoreType4.ItemsSource = Global.CoreTypes; cmbCoreType4.ItemsSource = Global.CoreTypes;
cmbCoreType5.ItemsSource = Global.CoreTypes; cmbCoreType5.ItemsSource = Global.CoreTypes;
cmbCoreType6.ItemsSource = Global.CoreTypes; cmbCoreType6.ItemsSource = Global.CoreTypes;
cmbCoreType7.ItemsSource = Global.CoreTypes;
cmbCoreType9.ItemsSource = Global.CoreTypes; cmbCoreType9.ItemsSource = Global.CoreTypes;
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList(); cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList();
@ -128,7 +127,6 @@ public partial class OptionSettingWindow
this.Bind(ViewModel, vm => vm.CoreType4, v => v.cmbCoreType4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType4, v => v.cmbCoreType4.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.Text).DisposeWith(disposables);
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.CoreType9, v => v.cmbCoreType9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.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);