DHR60 2025-07-23 12:25:46 +08:00 committed by GitHub
commit 782f484116
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 3004 additions and 385 deletions

View File

@ -128,5 +128,8 @@ public class JsonUtils
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static JsonNode? SerializeToNode(object? obj) => JsonSerializer.SerializeToNode(obj);
public static JsonNode? SerializeToNode(object? obj, JsonSerializerOptions? options = null)
{
return JsonSerializer.SerializeToNode(obj, options);
}
}

View File

@ -435,11 +435,11 @@ public class Utils
return false;
}
public static int GetFreePort(int defaultPort = 9090)
public static int GetFreePort(int defaultPort = 0)
{
try
{
if (!Utils.PortInUse(defaultPort))
if (!(defaultPort == 0 || Utils.PortInUse(defaultPort)))
{
return defaultPort;
}

View File

@ -11,5 +11,6 @@ public enum EConfigType
Hysteria2 = 7,
TUIC = 8,
WireGuard = 9,
HTTP = 10
HTTP = 10,
Anytls = 11
}

View File

@ -167,7 +167,8 @@ public class Global
{ EConfigType.Trojan, "trojan://" },
{ EConfigType.Hysteria2, "hysteria2://" },
{ EConfigType.TUIC, "tuic://" },
{ EConfigType.WireGuard, "wireguard://" }
{ EConfigType.WireGuard, "wireguard://" },
{ EConfigType.Anytls, "anytls://" }
};
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
@ -180,7 +181,8 @@ public class Global
{ EConfigType.Trojan, "trojan" },
{ EConfigType.Hysteria2, "hysteria2" },
{ EConfigType.TUIC, "tuic" },
{ EConfigType.WireGuard, "wireguard" }
{ EConfigType.WireGuard, "wireguard" },
{ EConfigType.Anytls, "anytls" }
};
public static readonly List<string> VmessSecurities =
@ -347,25 +349,42 @@ public class Global
public static readonly List<string> SingboxDomainStrategy4Out =
[
"",
"ipv4_only",
"prefer_ipv4",
"prefer_ipv6",
"ipv6_only",
""
"ipv6_only"
];
public static readonly List<string> DomainDNSAddress =
public static readonly List<string> DomainDirectDNSAddress =
[
"https://dns.alidns.com/dns-query",
"https://doh.pub/dns-query",
"223.5.5.5",
"223.6.6.6",
"119.29.29.29",
"localhost"
];
public static readonly List<string> SingboxDomainDNSAddress =
public static readonly List<string> DomainRemoteDNSAddress =
[
"https://cloudflare-dns.com/dns-query",
"https://dns.cloudflare.com/dns-query",
"https://dns.google/dns-query",
"https://doh.dns.sb/dns-query",
"https://doh.opendns.com/dns-query",
"https://common.dot.dns.yandex.net",
"8.8.8.8",
"1.1.1.1",
"185.222.222.222",
"208.67.222.222",
"77.88.8.8"
];
public static readonly List<string> DomainPureIPDNSAddress =
[
"223.5.5.5",
"223.6.6.6",
"dhcp://auto"
"119.29.29.29",
"localhost"
];
public static readonly List<string> Languages =
@ -535,5 +554,30 @@ public class Global
BlockTag
];
public static readonly Dictionary<string, List<string>> PredefinedHosts = new()
{
{ "dns.google", new List<string> { "8.8.8.8", "8.8.4.4", "2001:4860:4860::8888", "2001:4860:4860::8844" } },
{ "dns.alidns.com", new List<string> { "223.5.5.5", "223.6.6.6", "2400:3200::1", "2400:3200:baba::1" } },
{ "one.one.one.one", new List<string> { "1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001" } },
{ "1dot1dot1dot1.cloudflare-dns.com", new List<string> { "1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001" } },
{ "cloudflare-dns.com", new List<string> { "104.16.249.249", "104.16.248.249", "2606:4700::6810:f8f9", "2606:4700::6810:f9f9" } },
{ "dns.cloudflare.com", new List<string> { "104.16.132.229", "104.16.133.229", "2606:4700::6810:84e5", "2606:4700::6810:85e5" } },
{ "dot.pub", new List<string> { "1.12.12.12", "120.53.53.53" } },
{ "dns.quad9.net", new List<string> { "9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9" } },
{ "dns.yandex.net", new List<string> { "77.88.8.8", "77.88.8.1", "2a02:6b8::feed:0ff", "2a02:6b8:0:1::feed:0ff" } },
{ "dns.sb", new List<string> { "185.222.222.222", "2a09::" } },
{ "dns.umbrella.com", new List<string> { "208.67.220.220", "208.67.222.222", "2620:119:35::35", "2620:119:53::53" } },
{ "dns.sse.cisco.com", new List<string> { "208.67.220.220", "208.67.222.222", "2620:119:35::35", "2620:119:53::53" } },
{ "engage.cloudflareclient.com", new List<string> { "162.159.192.1", "2606:4700:d0::a29f:c001" } }
};
public static readonly List<string> ExpectedIPs =
[
"geoip:cn",
"geoip:ir",
"geoip:ru",
""
];
#endregion const
}

View File

@ -112,6 +112,11 @@ public class ConfigHandler
config.ConstItem ??= new ConstItem();
if (config.SimpleDNSItem == null)
{
InitBuiltinSimpleDNS(config);
}
config.SpeedTestItem ??= new();
if (config.SpeedTestItem.SpeedTestTimeout < 10)
{
@ -261,6 +266,7 @@ public class ConfigHandler
EConfigType.Hysteria2 => await AddHysteria2Server(config, item),
EConfigType.TUIC => await AddTuicServer(config, item),
EConfigType.WireGuard => await AddWireguardServer(config, item),
EConfigType.Anytls => await AddAnytlsServer(config, item),
_ => -1,
};
return ret;
@ -785,6 +791,35 @@ public class ConfigHandler
return 0;
}
/// <summary>
/// Add or edit a Anytls server
/// Validates and processes Anytls-specific settings
/// </summary>
/// <param name="config">Current configuration</param>
/// <param name="profileItem">Anytls profile to add</param>
/// <param name="toFile">Whether to save to file</param>
/// <returns>0 if successful, -1 if failed</returns>
public static async Task<int> AddAnytlsServer(Config config, ProfileItem profileItem, bool toFile = true)
{
profileItem.ConfigType = EConfigType.Anytls;
profileItem.CoreType = ECoreType.sing_box;
profileItem.Address = profileItem.Address.TrimEx();
profileItem.Id = profileItem.Id.TrimEx();
profileItem.Security = profileItem.Security.TrimEx();
profileItem.Network = string.Empty;
if (profileItem.StreamSecurity.IsNullOrEmpty())
{
profileItem.StreamSecurity = Global.StreamSecurity;
}
if (profileItem.Id.IsNullOrEmpty())
{
return -1;
}
await AddServerCommon(config, profileItem, toFile);
return 0;
}
/// <summary>
/// Sort the server list by the specified column
/// Updates the sort order in the profile extension data
@ -1294,6 +1329,7 @@ public class ConfigHandler
EConfigType.Hysteria2 => await AddHysteria2Server(config, profileItem, false),
EConfigType.TUIC => await AddTuicServer(config, profileItem, false),
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
_ => -1,
};
@ -2152,6 +2188,38 @@ public class ConfigHandler
#endregion DNS
#region Simple DNS
public static int InitBuiltinSimpleDNS(Config config)
{
config.SimpleDNSItem = new SimpleDNSItem()
{
UseSystemHosts = false,
AddCommonHosts = true,
FakeIP = false,
BlockBindingQuery = true,
DirectDNS = Global.DomainDirectDNSAddress.FirstOrDefault(),
RemoteDNS = Global.DomainRemoteDNSAddress.FirstOrDefault(),
SingboxOutboundsResolveDNS = Global.DomainDirectDNSAddress.FirstOrDefault(),
SingboxFinalResolveDNS = Global.DomainPureIPDNSAddress.FirstOrDefault()
};
return 0;
}
public static async Task<SimpleDNSItem> GetExternalSimpleDNSItem(string url)
{
var downloadHandle = new DownloadService();
var templateContent = await downloadHandle.TryDownloadString(url, true, "");
if (templateContent.IsNullOrEmpty())
return null;
var template = JsonUtils.Deserialize<SimpleDNSItem>(templateContent);
if (template == null)
return null;
return template;
}
#endregion Simple DNS
#region Regional Presets
/// <summary>
@ -2173,6 +2241,8 @@ public class ConfigHandler
await SQLiteHelper.Instance.DeleteAllAsync<DNSItem>();
await InitBuiltinDNS(config);
InitBuiltinSimpleDNS(config);
return true;
case EPresetType.Russia:
@ -2183,6 +2253,8 @@ public class ConfigHandler
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json"));
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
config.SimpleDNSItem = await GetExternalSimpleDNSItem(Global.DNSTemplateSources[1] + "simple_dns.json");
return true;
case EPresetType.Iran:
@ -2193,6 +2265,8 @@ public class ConfigHandler
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[2] + "v2ray.json"));
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[2] + "sing_box.json"));
config.SimpleDNSItem = await GetExternalSimpleDNSItem(Global.DNSTemplateSources[2] + "simple_dns.json");
return true;
}

View File

@ -101,7 +101,7 @@ public class CoreHandler
public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
{
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC) ? ECoreType.sing_box : ECoreType.Xray;
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls) ? ECoreType.sing_box : ECoreType.Xray;
var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
var configPath = Utils.GetBinConfigPath(fileName);
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);

View File

@ -0,0 +1,49 @@
using static QRCoder.PayloadGenerator;
namespace ServiceLib.Handler.Fmt;
public class AnytlsFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{
msg = ResUI.ConfigurationFormatIncorrect;
var parsedUrl = Utils.TryUri(str);
if (parsedUrl == null)
{
return null;
}
ProfileItem item = new()
{
ConfigType = EConfigType.Anytls,
Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
Address = parsedUrl.IdnHost,
Port = parsedUrl.Port,
};
var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo);
item.Id = rawUserInfo;
var query = Utils.ParseQueryString(parsedUrl.Query);
_ = ResolveStdTransport(query, ref item);
return item;
}
public static string? ToUri(ProfileItem? item)
{
if (item == null)
{
return null;
}
var remark = string.Empty;
if (item.Remarks.IsNotEmpty())
{
remark = "#" + Utils.UrlEncode(item.Remarks);
}
var pw = item.Id;
var dicQuery = new Dictionary<string, string>();
_ = GetStdTransport(item, Global.None, ref dicQuery);
return ToUri(EConfigType.Anytls, item.Address, item.Port, pw, dicQuery, remark);
}
}

View File

@ -18,6 +18,7 @@ public class FmtHandler
EConfigType.Hysteria2 => Hysteria2Fmt.ToUri(item),
EConfigType.TUIC => TuicFmt.ToUri(item),
EConfigType.WireGuard => WireguardFmt.ToUri(item),
EConfigType.Anytls => AnytlsFmt.ToUri(item),
_ => null,
};
@ -75,6 +76,10 @@ public class FmtHandler
{
return WireguardFmt.Resolve(str, out msg);
}
else if (str.StartsWith(Global.ProtocolShares[EConfigType.Anytls]))
{
return AnytlsFmt.Resolve(str, out msg);
}
else
{
msg = ResUI.NonvmessOrssProtocol;

View File

@ -48,6 +48,7 @@ public class Config
public List<InItem> Inbound { get; set; }
public List<KeyEventItem> GlobalHotkeys { get; set; }
public List<CoreTypeItem> CoreTypeItem { get; set; }
public SimpleDNSItem SimpleDNSItem { get; set; }
#endregion other entities
}

View File

@ -253,3 +253,21 @@ public class WindowSizeItem
public int Width { get; set; }
public int Height { get; set; }
}
[Serializable]
public class SimpleDNSItem
{
public bool? UseSystemHosts { get; set; }
public bool? AddCommonHosts { get; set; }
public bool? FakeIP { get; set; }
public bool? BlockBindingQuery { get; set; }
public string? DirectDNS { get; set; }
public string? RemoteDNS { get; set; }
public string? SingboxOutboundsResolveDNS { get; set; }
public string? SingboxFinalResolveDNS { get; set; }
public string? RayStrategy4Freedom { get; set; }
public string? SingboxStrategy4Direct { get; set; }
public string? SingboxStrategy4Proxy { get; set; }
public string? Hosts { get; set; }
public string? DirectExpectedIPs { get; set; }
}

View File

@ -9,7 +9,7 @@ public class DNSItem
public string Id { get; set; }
public string Remarks { get; set; }
public bool Enabled { get; set; } = true;
public bool Enabled { get; set; } = false;
public ECoreType CoreType { get; set; }
public bool UseSystemHosts { get; set; }
public string? NormalDNS { get; set; }

View File

@ -1,3 +1,5 @@
using System.Text.Json.Serialization;
namespace ServiceLib.Models;
public class SingboxConfig
@ -6,6 +8,7 @@ public class SingboxConfig
public Dns4Sbox? dns { get; set; }
public List<Inbound4Sbox> inbounds { get; set; }
public List<Outbound4Sbox> outbounds { get; set; }
public List<Endpoints4Sbox>? endpoints { get; set; }
public Route4Sbox route { get; set; }
public Experimental4Sbox? experimental { get; set; }
}
@ -29,14 +32,15 @@ public class Dns4Sbox
public bool? independent_cache { get; set; }
public bool? reverse_mapping { get; set; }
public string? client_subnet { get; set; }
public Fakeip4Sbox? fakeip { get; set; }
}
public class Route4Sbox
{
public Rule4Sbox? default_domain_resolver { get; set; } // or string
public bool? auto_detect_interface { get; set; }
public List<Rule4Sbox> rules { get; set; }
public List<Ruleset4Sbox>? rule_set { get; set; }
public string? final { get; set; }
}
[Serializable]
@ -49,6 +53,7 @@ public class Rule4Sbox
public string? mode { get; set; }
public bool? ip_is_private { get; set; }
public string? client_subnet { get; set; }
public int? rewrite_ttl { get; set; }
public bool? invert { get; set; }
public string? clash_mode { get; set; }
public List<string>? inbound { get; set; }
@ -67,6 +72,27 @@ public class Rule4Sbox
public List<string>? process_name { get; set; }
public List<string>? rule_set { get; set; }
public List<Rule4Sbox>? rules { get; set; }
public string? action { get; set; }
public string? strategy { get; set; }
public List<string>? sniffer { get; set; }
public string? rcode { get; set; }
public List<int>? query_type { get; set; }
public List<string>? answer { get; set; }
public List<string>? ns { get; set; }
public List<string>? extra { get; set; }
public string? method { get; set; }
public bool? no_drop { get; set; }
public bool? source_ip_is_private { get; set; }
public bool? ip_accept_any { get; set; }
public int? source_port { get; set; }
public List<string>? source_port_range { get; set; }
public List<string>? network_type { get; set; }
public bool? network_is_expensive { get; set; }
public bool? network_is_constrained { get; set; }
public List<string>? wifi_ssid { get; set; }
public List<string>? wifi_bssid { get; set; }
public bool? rule_set_ip_cidr_match_source { get; set; }
public bool? rule_set_ip_cidr_accept_empty { get; set; }
}
[Serializable]
@ -76,7 +102,6 @@ public class Inbound4Sbox
public string tag { get; set; }
public string listen { get; set; }
public int? listen_port { get; set; }
public string? domain_strategy { get; set; }
public string interface_name { get; set; }
public List<string>? address { get; set; }
public int? mtu { get; set; }
@ -84,8 +109,6 @@ public class Inbound4Sbox
public bool? strict_route { get; set; }
public bool? endpoint_independent_nat { get; set; }
public string? stack { get; set; }
public bool? sniff { get; set; }
public bool? sniff_override_destination { get; set; }
public List<User4Sbox> users { get; set; }
}
@ -95,10 +118,8 @@ public class User4Sbox
public string password { get; set; }
}
public class Outbound4Sbox
public class Outbound4Sbox : BaseServer4Sbox
{
public string type { get; set; }
public string tag { get; set; }
public string? server { get; set; }
public int? server_port { get; set; }
public List<string>? server_ports { get; set; }
@ -113,7 +134,6 @@ public class Outbound4Sbox
public int? recv_window_conn { get; set; }
public int? recv_window { get; set; }
public bool? disable_mtu_discovery { get; set; }
public string? detour { get; set; }
public string? method { get; set; }
public string? username { get; set; }
public string? password { get; set; }
@ -121,21 +141,36 @@ public class Outbound4Sbox
public string? version { get; set; }
public string? network { get; set; }
public string? packet_encoding { get; set; }
public List<string>? local_address { get; set; }
public string? private_key { get; set; }
public string? peer_public_key { get; set; }
public List<int>? reserved { get; set; }
public int? mtu { get; set; }
public string? plugin { get; set; }
public string? plugin_opts { get; set; }
public Tls4Sbox? tls { get; set; }
public Multiplex4Sbox? multiplex { get; set; }
public Transport4Sbox? transport { get; set; }
public HyObfs4Sbox? obfs { get; set; }
public List<string>? outbounds { get; set; }
public bool? interrupt_exist_connections { get; set; }
}
public class Endpoints4Sbox : BaseServer4Sbox
{
public bool? system { get; set; }
public string? name { get; set; }
public int? mtu { get; set; }
public List<string> address { get; set; }
public string private_key { get; set; }
public int? listen_port { get; set; }
public string? udp_timeout { get; set; }
public int? workers { get; set; }
public List<Peer4Sbox> peers { get; set; }
}
public class Peer4Sbox
{
public string address { get; set; }
public int port { get; set; }
public string public_key { get; set; }
public string? pre_shared_key { get; set; }
public List<string> allowed_ips { get; set; }
public int? persistent_keepalive_interval { get; set; }
public List<int> reserved { get; set; }
}
public class Tls4Sbox
{
public bool enabled { get; set; }
@ -191,15 +226,25 @@ public class HyObfs4Sbox
public string? password { get; set; }
}
public class Server4Sbox
public class Server4Sbox : BaseServer4Sbox
{
public string? tag { get; set; }
public string? inet4_range { get; set; }
public string? inet6_range { get; set; }
public string? client_subnet { get; set; }
public string? server { get; set; }
public new string? domain_resolver { get; set; }
[JsonPropertyName("interface")] public string? Interface { get; set; }
public int? server_port { get; set; }
public string? path { get; set; }
public Headers4Sbox? headers { get; set; }
// public List<string>? path { get; set; } // hosts
public Dictionary<string, List<string>>? predefined { get; set; }
// Deprecated
public string? address { get; set; }
public string? address_resolver { get; set; }
public string? address_strategy { get; set; }
public string? strategy { get; set; }
public string? detour { get; set; }
public string? client_subnet { get; set; }
// Deprecated End
}
public class Experimental4Sbox
@ -229,13 +274,6 @@ public class Stats4Sbox
public List<string>? users { get; set; }
}
public class Fakeip4Sbox
{
public bool enabled { get; set; }
public string inet4_range { get; set; }
public string inet6_range { get; set; }
}
public class CacheFile4Sbox
{
public bool enabled { get; set; }
@ -254,3 +292,33 @@ public class Ruleset4Sbox
public string? download_detour { get; set; }
public string? update_interval { get; set; }
}
public abstract class DialFields4Sbox
{
public string? detour { get; set; }
public string? bind_interface { get; set; }
public string? inet4_bind_address { get; set; }
public string? inet6_bind_address { get; set; }
public int? routing_mark { get; set; }
public bool? reuse_addr { get; set; }
public string? netns { get; set; }
public string? connect_timeout { get; set; }
public bool? tcp_fast_open { get; set; }
public bool? tcp_multi_path { get; set; }
public bool? udp_fragment { get; set; }
public Rule4Sbox? domain_resolver { get; set; } // or string
public string? network_strategy { get; set; }
public List<string>? network_type { get; set; }
public List<string>? fallback_network_type { get; set; }
public string? fallback_delay { get; set; }
public Tls4Sbox? tls { get; set; }
public Multiplex4Sbox? multiplex { get; set; }
public Transport4Sbox? transport { get; set; }
public HyObfs4Sbox? obfs { get; set; }
}
public abstract class BaseServer4Sbox : DialFields4Sbox
{
public string type { get; set; }
public string tag { get; set; }
}

View File

@ -5,7 +5,7 @@ namespace ServiceLib.Models;
public class V2rayConfig
{
public Log4Ray log { get; set; }
public object dns { get; set; }
public Dns4Ray dns { get; set; }
public List<Inbounds4Ray> inbounds { get; set; }
public List<Outbounds4Ray> outbounds { get; set; }
public Routing4Ray routing { get; set; }
@ -203,7 +203,8 @@ public class Response4Ray
public class Dns4Ray
{
public List<string> servers { get; set; }
public Dictionary<string, List<string>>? hosts { get; set; }
public List<object> servers { get; set; }
}
public class DnsServer4Ray
@ -211,6 +212,8 @@ public class DnsServer4Ray
public string? address { get; set; }
public List<string>? domains { get; set; }
public bool? skipFallback { get; set; }
public List<string>? expectedIPs { get; set; }
public List<string>? unexpectedIPs { get; set; }
}
public class Routing4Ray

View File

@ -654,6 +654,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Add [Anytls] Configuration 的本地化字符串。
/// </summary>
public static string menuAddAnytlsServer {
get {
return ResourceManager.GetString("menuAddAnytlsServer", resourceCulture);
}
}
/// <summary>
/// 查找类似 Add a custom configuration Configuration 的本地化字符串。
/// </summary>
@ -2202,6 +2211,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Add Common DNS Hosts 的本地化字符串。
/// </summary>
public static string TbAddCommonDNSHosts {
get {
return ResourceManager.GetString("TbAddCommonDNSHosts", resourceCulture);
}
}
/// <summary>
/// 查找类似 Address 的本地化字符串。
/// </summary>
@ -2238,6 +2256,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Apply to Proxy Domains Only 的本地化字符串。
/// </summary>
public static string TbApplyProxyDomainsOnly {
get {
return ResourceManager.GetString("TbApplyProxyDomainsOnly", resourceCulture);
}
}
/// <summary>
/// 查找类似 Auto refresh 的本地化字符串。
/// </summary>
@ -2265,6 +2292,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Block SVCB and HTTPS Queries 的本地化字符串。
/// </summary>
public static string TbBlockSVCBHTTPSQueries {
get {
return ResourceManager.GetString("TbBlockSVCBHTTPSQueries", resourceCulture);
}
}
/// <summary>
/// 查找类似 Browse 的本地化字符串。
/// </summary>
@ -2319,6 +2355,24 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Enable Custom DNS 的本地化字符串。
/// </summary>
public static string TbCustomDNSEnable {
get {
return ResourceManager.GetString("TbCustomDNSEnable", resourceCulture);
}
}
/// <summary>
/// 查找类似 Custom DNS Enabled, This Page&apos;s Settings Invalid 的本地化字符串。
/// </summary>
public static string TbCustomDNSEnabledPageInvalid {
get {
return ResourceManager.GetString("TbCustomDNSEnabledPageInvalid", resourceCulture);
}
}
/// <summary>
/// 查找类似 Display GUI 的本地化字符串。
/// </summary>
@ -2337,6 +2391,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 DNS Hosts: (&quot;domain1 ip1 ip2&quot; per line) 的本地化字符串。
/// </summary>
public static string TbDNSHostsConfig {
get {
return ResourceManager.GetString("TbDNSHostsConfig", resourceCulture);
}
}
/// <summary>
/// 查找类似 Supports DNS Object; Click to view documentation 的本地化字符串。
/// </summary>
@ -2382,6 +2445,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Domestic DNS 的本地化字符串。
/// </summary>
public static string TbDomesticDNS {
get {
return ResourceManager.GetString("TbDomesticDNS", resourceCulture);
}
}
/// <summary>
/// 查找类似 Edit 的本地化字符串。
/// </summary>
@ -2400,6 +2472,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 FakeIP 的本地化字符串。
/// </summary>
public static string TbFakeIP {
get {
return ResourceManager.GetString("TbFakeIP", resourceCulture);
}
}
/// <summary>
/// 查找类似 Fingerprint 的本地化字符串。
/// </summary>
@ -2589,6 +2670,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Prevent DNS Leaks 的本地化字符串。
/// </summary>
public static string TbPreventDNSLeaks {
get {
return ResourceManager.GetString("TbPreventDNSLeaks", resourceCulture);
}
}
/// <summary>
/// 查找类似 Private Key 的本地化字符串。
/// </summary>
@ -2625,6 +2715,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Remote DNS 的本地化字符串。
/// </summary>
public static string TbRemoteDNS {
get {
return ResourceManager.GetString("TbRemoteDNS", resourceCulture);
}
}
/// <summary>
/// 查找类似 Camouflage domain(host) 的本地化字符串。
/// </summary>
@ -2733,6 +2832,69 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 sing-box Direct Resolution Strategy 的本地化字符串。
/// </summary>
public static string TbSBDirectResolveStrategy {
get {
return ResourceManager.GetString("TbSBDirectResolveStrategy", resourceCulture);
}
}
/// <summary>
/// 查找类似 The sing-box DoH resolution server can be overwritten 的本地化字符串。
/// </summary>
public static string TbSBDoHOverride {
get {
return ResourceManager.GetString("TbSBDoHOverride", resourceCulture);
}
}
/// <summary>
/// 查找类似 sing-box DoH Resolver Server 的本地化字符串。
/// </summary>
public static string TbSBDoHResolverServer {
get {
return ResourceManager.GetString("TbSBDoHResolverServer", resourceCulture);
}
}
/// <summary>
/// 查找类似 Fallback DNS Resolution, Suggest IP 的本地化字符串。
/// </summary>
public static string TbSBFallbackDNSResolve {
get {
return ResourceManager.GetString("TbSBFallbackDNSResolve", resourceCulture);
}
}
/// <summary>
/// 查找类似 Resolve Outbound Domains 的本地化字符串。
/// </summary>
public static string TbSBOutboundDomainResolve {
get {
return ResourceManager.GetString("TbSBOutboundDomainResolve", resourceCulture);
}
}
/// <summary>
/// 查找类似 Outbound DNS Resolution (sing-box) 的本地化字符串。
/// </summary>
public static string TbSBOutboundsResolverDNS {
get {
return ResourceManager.GetString("TbSBOutboundsResolverDNS", resourceCulture);
}
}
/// <summary>
/// 查找类似 sing-box Remote Resolution Strategy 的本地化字符串。
/// </summary>
public static string TbSBRemoteResolveStrategy {
get {
return ResourceManager.GetString("TbSBRemoteResolveStrategy", resourceCulture);
}
}
/// <summary>
/// 查找类似 Encryption method (security) 的本地化字符串。
/// </summary>
@ -3678,6 +3840,33 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Validate Regional Domain IPs 的本地化字符串。
/// </summary>
public static string TbValidateDirectExpectedIPs {
get {
return ResourceManager.GetString("TbValidateDirectExpectedIPs", resourceCulture);
}
}
/// <summary>
/// 查找类似 When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs 的本地化字符串。
/// </summary>
public static string TbValidateDirectExpectedIPsDesc {
get {
return ResourceManager.GetString("TbValidateDirectExpectedIPsDesc", resourceCulture);
}
}
/// <summary>
/// 查找类似 xray Freedom Resolution Strategy 的本地化字符串。
/// </summary>
public static string TbXrayFreedomResolveStrategy {
get {
return ResourceManager.GetString("TbXrayFreedomResolveStrategy", resourceCulture);
}
}
/// <summary>
/// 查找类似 The delay: {0} ms, {1} 的本地化字符串。
/// </summary>
@ -3687,6 +3876,24 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Advanced DNS Settings 的本地化字符串。
/// </summary>
public static string ThAdvancedDNSSettings {
get {
return ResourceManager.GetString("ThAdvancedDNSSettings", resourceCulture);
}
}
/// <summary>
/// 查找类似 Basic DNS Settings 的本地化字符串。
/// </summary>
public static string ThBasicDNSSettings {
get {
return ResourceManager.GetString("ThBasicDNSSettings", resourceCulture);
}
}
/// <summary>
/// 查找类似 Active 的本地化字符串。
/// </summary>

View File

@ -1395,4 +1395,73 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
<data name="menuAddAnytlsServer" xml:space="preserve">
<value>Add [Anytls] Configuration</value>
</data>
<data name="TbRemoteDNS" xml:space="preserve">
<value>Remote DNS</value>
</data>
<data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value>
</data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value>
</data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBDoHResolverServer" xml:space="preserve">
<value>sing-box DoH Resolver Server</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Fallback DNS Resolution, Suggest IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value>
</data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
<value>sing-box Direct Resolution Strategy</value>
</data>
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
<value>sing-box Remote Resolution Strategy</value>
</data>
<data name="TbAddCommonDNSHosts" xml:space="preserve">
<value>Add Common DNS Hosts</value>
</data>
<data name="TbSBDoHOverride" xml:space="preserve">
<value>The sing-box DoH resolution server can be overwritten</value>
</data>
<data name="TbFakeIP" xml:space="preserve">
<value>FakeIP</value>
</data>
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
<value>Block SVCB and HTTPS Queries</value>
</data>
<data name="TbPreventDNSLeaks" xml:space="preserve">
<value>Prevent DNS Leaks</value>
</data>
<data name="TbDNSHostsConfig" xml:space="preserve">
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
</data>
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
<value>Apply to Proxy Domains Only</value>
</data>
<data name="ThBasicDNSSettings" xml:space="preserve">
<value>Basic DNS Settings</value>
</data>
<data name="ThAdvancedDNSSettings" xml:space="preserve">
<value>Advanced DNS Settings</value>
</data>
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
<value>Validate Regional Domain IPs</value>
</data>
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
</data>
<data name="TbCustomDNSEnable" xml:space="preserve">
<value>Enable Custom DNS</value>
</data>
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data>
</root>

View File

@ -1395,4 +1395,73 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
<data name="menuAddAnytlsServer" xml:space="preserve">
<value>Add [Anytls] Configuration</value>
</data>
<data name="TbRemoteDNS" xml:space="preserve">
<value>Remote DNS</value>
</data>
<data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value>
</data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value>
</data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBDoHResolverServer" xml:space="preserve">
<value>sing-box DoH Resolver Server</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Fallback DNS Resolution, Suggest IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value>
</data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
<value>sing-box Direct Resolution Strategy</value>
</data>
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
<value>sing-box Remote Resolution Strategy</value>
</data>
<data name="TbAddCommonDNSHosts" xml:space="preserve">
<value>Add Common DNS Hosts</value>
</data>
<data name="TbSBDoHOverride" xml:space="preserve">
<value>The sing-box DoH resolution server can be overwritten</value>
</data>
<data name="TbFakeIP" xml:space="preserve">
<value>FakeIP</value>
</data>
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
<value>Block SVCB and HTTPS Queries</value>
</data>
<data name="TbPreventDNSLeaks" xml:space="preserve">
<value>Prevent DNS Leaks</value>
</data>
<data name="TbDNSHostsConfig" xml:space="preserve">
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
</data>
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
<value>Apply to Proxy Domains Only</value>
</data>
<data name="ThBasicDNSSettings" xml:space="preserve">
<value>Basic DNS Settings</value>
</data>
<data name="ThAdvancedDNSSettings" xml:space="preserve">
<value>Advanced DNS Settings</value>
</data>
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
<value>Validate Regional Domain IPs</value>
</data>
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
</data>
<data name="TbCustomDNSEnable" xml:space="preserve">
<value>Enable Custom DNS</value>
</data>
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data>
</root>

View File

@ -1395,4 +1395,73 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
<data name="menuAddAnytlsServer" xml:space="preserve">
<value>Add [Anytls] Configuration</value>
</data>
<data name="TbRemoteDNS" xml:space="preserve">
<value>Remote DNS</value>
</data>
<data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value>
</data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value>
</data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBDoHResolverServer" xml:space="preserve">
<value>sing-box DoH Resolver Server</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Fallback DNS Resolution, Suggest IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value>
</data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
<value>sing-box Direct Resolution Strategy</value>
</data>
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
<value>sing-box Remote Resolution Strategy</value>
</data>
<data name="TbAddCommonDNSHosts" xml:space="preserve">
<value>Add Common DNS Hosts</value>
</data>
<data name="TbSBDoHOverride" xml:space="preserve">
<value>The sing-box DoH resolution server can be overwritten</value>
</data>
<data name="TbFakeIP" xml:space="preserve">
<value>FakeIP</value>
</data>
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
<value>Block SVCB and HTTPS Queries</value>
</data>
<data name="TbPreventDNSLeaks" xml:space="preserve">
<value>Prevent DNS Leaks</value>
</data>
<data name="TbDNSHostsConfig" xml:space="preserve">
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
</data>
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
<value>Apply to Proxy Domains Only</value>
</data>
<data name="ThBasicDNSSettings" xml:space="preserve">
<value>Basic DNS Settings</value>
</data>
<data name="ThAdvancedDNSSettings" xml:space="preserve">
<value>Advanced DNS Settings</value>
</data>
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
<value>Validate Regional Domain IPs</value>
</data>
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
</data>
<data name="TbCustomDNSEnable" xml:space="preserve">
<value>Enable Custom DNS</value>
</data>
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data>
</root>

View File

@ -807,9 +807,6 @@
<data name="menuMoveUp" xml:space="preserve">
<value>Вверх (U)</value>
</data>
<data name="menuMoveTo" xml:space="preserve">
<value>Переместить вверх/вниз</value>
</data>
<data name="MsgFilterTitle" xml:space="preserve">
<value>Фильтр, поддерживает regex</value>
</data>
@ -969,6 +966,9 @@
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>URL для тестирования скорости</value>
</data>
<data name="menuMoveTo" xml:space="preserve">
<value>Переместить вверх/вниз</value>
</data>
<data name="TbPublicKey" xml:space="preserve">
<value>PublicKey</value>
</data>
@ -1395,4 +1395,73 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
</data>
<data name="menuAddAnytlsServer" xml:space="preserve">
<value>Add [Anytls] Configuration</value>
</data>
<data name="TbRemoteDNS" xml:space="preserve">
<value>Remote DNS</value>
</data>
<data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value>
</data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value>
</data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBDoHResolverServer" xml:space="preserve">
<value>sing-box DoH Resolver Server</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Fallback DNS Resolution, Suggest IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value>
</data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
<value>sing-box Direct Resolution Strategy</value>
</data>
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
<value>sing-box Remote Resolution Strategy</value>
</data>
<data name="TbAddCommonDNSHosts" xml:space="preserve">
<value>Add Common DNS Hosts</value>
</data>
<data name="TbSBDoHOverride" xml:space="preserve">
<value>The sing-box DoH resolution server can be overwritten</value>
</data>
<data name="TbFakeIP" xml:space="preserve">
<value>FakeIP</value>
</data>
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
<value>Block SVCB and HTTPS Queries</value>
</data>
<data name="TbPreventDNSLeaks" xml:space="preserve">
<value>Prevent DNS Leaks</value>
</data>
<data name="TbDNSHostsConfig" xml:space="preserve">
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
</data>
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
<value>Apply to Proxy Domains Only</value>
</data>
<data name="ThBasicDNSSettings" xml:space="preserve">
<value>Basic DNS Settings</value>
</data>
<data name="ThAdvancedDNSSettings" xml:space="preserve">
<value>Advanced DNS Settings</value>
</data>
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
<value>Validate Regional Domain IPs</value>
</data>
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
</data>
<data name="TbCustomDNSEnable" xml:space="preserve">
<value>Enable Custom DNS</value>
</data>
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data>
</root>

View File

@ -1392,4 +1392,73 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填写配置文件别名,请确保存在并唯一</value>
</data>
<data name="menuAddAnytlsServer" xml:space="preserve">
<value>添加 [Anytls] 配置文件</value>
</data>
<data name="TbRemoteDNS" xml:space="preserve">
<value>远程 DNS</value>
</data>
<data name="TbDomesticDNS" xml:space="preserve">
<value>直连 DNS</value>
</data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
<value>出站 DNS 解析sing-box</value>
</data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
<value>解析出站域名</value>
</data>
<data name="TbSBDoHResolverServer" xml:space="preserve">
<value>sing-box DoH 解析服务器</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>兜底解析其他 DNS 域名,建议设为 ip</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray freedom 解析策略</value>
</data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
<value>sing-box 直连解析策略</value>
</data>
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
<value>sing-box 远程解析策略</value>
</data>
<data name="TbAddCommonDNSHosts" xml:space="preserve">
<value>添加常用 DNS Hosts</value>
</data>
<data name="TbSBDoHOverride" xml:space="preserve">
<value>开启后可覆盖 sing-box DoH 解析服务器</value>
</data>
<data name="TbFakeIP" xml:space="preserve">
<value>FakeIP</value>
</data>
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
<value>阻止 SVCB 和 HTTPS 查询</value>
</data>
<data name="TbPreventDNSLeaks" xml:space="preserve">
<value>避免 DNS 泄漏</value>
</data>
<data name="TbDNSHostsConfig" xml:space="preserve">
<value>DNS Hosts“域名1 ip1 ip2” 一行一个)</value>
</data>
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
<value>仅对代理域名生效</value>
</data>
<data name="ThBasicDNSSettings" xml:space="preserve">
<value>DNS 基础设置</value>
</data>
<data name="ThAdvancedDNSSettings" xml:space="preserve">
<value>DNS 进阶设置</value>
</data>
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
<value>校验相应地区域名 IP</value>
</data>
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
<value>配置后,会对相应地区域名(如 geosite:cn的返回 IP 进行校验,仅返回期望 IP</value>
</data>
<data name="TbCustomDNSEnable" xml:space="preserve">
<value>启用自定义 DNS</value>
</data>
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
<value>自定义 DNS 已启用,此页面配置将无效</value>
</data>
</root>

View File

@ -1392,4 +1392,73 @@
<data name="TbRuleOutboundTagTip" xml:space="preserve">
<value>可以填寫設定檔別名,請確保存在並唯一</value>
</data>
<data name="menuAddAnytlsServer" xml:space="preserve">
<value>新增 [Anytls] 設定檔</value>
</data>
<data name="TbRemoteDNS" xml:space="preserve">
<value>Remote DNS</value>
</data>
<data name="TbDomesticDNS" xml:space="preserve">
<value>Domestic DNS</value>
</data>
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
<value>Outbound DNS Resolution (sing-box)</value>
</data>
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
<value>Resolve Outbound Domains</value>
</data>
<data name="TbSBDoHResolverServer" xml:space="preserve">
<value>sing-box DoH Resolver Server</value>
</data>
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
<value>Fallback DNS Resolution, Suggest IP</value>
</data>
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
<value>xray Freedom Resolution Strategy</value>
</data>
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
<value>sing-box Direct Resolution Strategy</value>
</data>
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
<value>sing-box Remote Resolution Strategy</value>
</data>
<data name="TbAddCommonDNSHosts" xml:space="preserve">
<value>Add Common DNS Hosts</value>
</data>
<data name="TbSBDoHOverride" xml:space="preserve">
<value>The sing-box DoH resolution server can be overwritten</value>
</data>
<data name="TbFakeIP" xml:space="preserve">
<value>FakeIP</value>
</data>
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
<value>Block SVCB and HTTPS Queries</value>
</data>
<data name="TbPreventDNSLeaks" xml:space="preserve">
<value>Prevent DNS Leaks</value>
</data>
<data name="TbDNSHostsConfig" xml:space="preserve">
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
</data>
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
<value>Apply to Proxy Domains Only</value>
</data>
<data name="ThBasicDNSSettings" xml:space="preserve">
<value>Basic DNS Settings</value>
</data>
<data name="ThAdvancedDNSSettings" xml:space="preserve">
<value>Advanced DNS Settings</value>
</data>
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
<value>Validate Regional Domain IPs</value>
</data>
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
</data>
<data name="TbCustomDNSEnable" xml:space="preserve">
<value>Enable Custom DNS</value>
</data>
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
</data>
</root>

View File

@ -1,4 +1,4 @@
{
{
"log": {
"level": "debug",
"timestamp": true
@ -14,22 +14,10 @@
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
},
{
"tag": "dns_out",
"type": "dns"
}
],
"route": {
"rules": [
{
"protocol": [ "dns" ],
"outbound": "dns_out"
}
]
}
}

View File

@ -2,28 +2,33 @@
"servers": [
{
"tag": "remote",
"address": "tcp://8.8.8.8",
"strategy": "prefer_ipv4",
"type": "tcp",
"server": "8.8.8.8",
"detour": "proxy"
},
{
"tag": "local",
"address": "223.5.5.5",
"strategy": "prefer_ipv4",
"detour": "direct"
},
{
"tag": "block",
"address": "rcode://success"
"type": "udp",
"server": "223.5.5.5"
}
],
"rules": [
{
"domain_suffix": [
"googleapis.cn",
"gstatic.com"
],
"server": "remote",
"strategy": "prefer_ipv4"
},
{
"rule_set": [
"geosite-cn"
],
"server": "local"
"server": "local",
"strategy": "prefer_ipv4"
}
],
"final": "remote"
"final": "remote",
"strategy": "prefer_ipv4"
}

View File

@ -2,29 +2,33 @@
"servers": [
{
"tag": "remote",
"address": "tcp://8.8.8.8",
"strategy": "prefer_ipv4",
"type": "tcp",
"server": "8.8.8.8",
"detour": "proxy"
},
{
"tag": "local",
"address": "223.5.5.5",
"strategy": "prefer_ipv4",
"detour": "direct"
},
{
"tag": "block",
"address": "rcode://success"
"type": "udp",
"server": "223.5.5.5"
}
],
"rules": [
{
"rule_set": [
"geosite-cn",
"geosite-geolocation-cn"
"domain_suffix": [
"googleapis.cn",
"gstatic.com"
],
"server": "local"
"server": "remote",
"strategy": "prefer_ipv4"
},
{
"rule_set": [
"geosite-cn"
],
"server": "local",
"strategy": "prefer_ipv4"
}
],
"final": "remote"
"final": "remote",
"strategy": "prefer_ipv4"
}

View File

@ -8,13 +8,13 @@
139,
5353
],
"outbound": "block"
"action": "reject"
},
{
"ip_cidr": [
"224.0.0.0/3",
"ff00::/8"
],
"outbound": "block"
"action": "reject"
}
]

View File

@ -1,6 +1,8 @@
using System.Net;
using System.Net.NetworkInformation;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace ServiceLib.Services.CoreConfig;
@ -1132,6 +1134,264 @@ public class CoreConfigV2rayService
}
private async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
{
try
{
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
if (item != null && item.Enabled == true)
{
return await GenDnsCompatible(node, v2rayConfig);
}
var simpleDNSItem = _config.SimpleDNSItem;
var domainStrategy4Freedom = simpleDNSItem?.RayStrategy4Freedom;
//Outbound Freedom domainStrategy
if (domainStrategy4Freedom.IsNotEmpty())
{
var outbound = v2rayConfig.outbounds.FirstOrDefault(t => t is { protocol: "freedom", tag: Global.DirectTag });
if (outbound != null)
{
outbound.settings = new()
{
domainStrategy = domainStrategy4Freedom,
userLevel = 0
};
}
}
await GenDnsServers(node, v2rayConfig, simpleDNSItem);
await GenDnsHosts(v2rayConfig, simpleDNSItem);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return 0;
}
private async Task<int> GenDnsServers(ProfileItem? node, V2rayConfig v2rayConfig, SimpleDNSItem simpleDNSItem)
{
static List<string> ParseDnsAddresses(string? dnsInput, string defaultAddress)
{
var addresses = dnsInput?.Split(dnsInput.Contains(',') ? ',' : ';')
.Select(addr => addr.Trim())
.Where(addr => !string.IsNullOrEmpty(addr))
.Select(addr => addr.StartsWith("dhcp", StringComparison.OrdinalIgnoreCase) ? "localhost" : addr)
.Distinct()
.ToList() ?? new List<string> { defaultAddress };
return addresses.Count > 0 ? addresses : new List<string> { defaultAddress };
}
static object CreateDnsServer(string dnsAddress, List<string> domains, List<string>? expectedIPs = null)
{
var dnsServer = new DnsServer4Ray
{
address = dnsAddress,
skipFallback = true,
domains = domains.Count > 0 ? domains : null,
expectedIPs = expectedIPs?.Count > 0 ? expectedIPs : null
};
return JsonUtils.SerializeToNode(dnsServer, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
});
}
var directDNSAddress = ParseDnsAddresses(simpleDNSItem?.DirectDNS, Global.DomainDirectDNSAddress.FirstOrDefault());
var remoteDNSAddress = ParseDnsAddresses(simpleDNSItem?.RemoteDNS, Global.DomainRemoteDNSAddress.FirstOrDefault());
var directDomainList = new List<string>();
var directGeositeList = new List<string>();
var proxyDomainList = new List<string>();
var proxyGeositeList = new List<string>();
var expectedDomainList = new List<string>();
var expectedIPs = new List<string>();
var regionNames = new HashSet<string>();
if (!string.IsNullOrEmpty(simpleDNSItem?.DirectExpectedIPs))
{
expectedIPs = simpleDNSItem.DirectExpectedIPs
.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim())
.Where(s => !string.IsNullOrEmpty(s))
.ToList();
foreach (var ip in expectedIPs)
{
if (ip.StartsWith("geoip:", StringComparison.OrdinalIgnoreCase))
{
var region = ip["geoip:".Length..];
if (!string.IsNullOrEmpty(region))
{
regionNames.Add($"geosite:{region}");
regionNames.Add($"geosite:geolocation-{region}");
regionNames.Add($"geosite:tld-{region}");
}
}
}
}
var routing = await ConfigHandler.GetDefaultRouting(_config);
List<RulesItem>? rules = null;
if (routing != null)
{
rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
foreach (var item in rules)
{
if (!item.Enabled || item.Domain is null || item.Domain.Count == 0)
{
continue;
}
foreach (var domain in item.Domain)
{
if (domain.StartsWith('#'))
continue;
var normalizedDomain = domain.Replace(Global.RoutingRuleComma, ",");
if (item.OutboundTag == Global.DirectTag)
{
if (normalizedDomain.StartsWith("geosite:"))
{
(regionNames.Contains(normalizedDomain) ? expectedDomainList : directGeositeList).Add(normalizedDomain);
}
else
{
directDomainList.Add(normalizedDomain);
}
}
else if (item.OutboundTag == Global.ProxyTag)
{
if (normalizedDomain.StartsWith("geosite:"))
{
proxyGeositeList.Add(normalizedDomain);
}
else
{
proxyDomainList.Add(normalizedDomain);
}
}
}
}
}
if (Utils.IsDomain(node?.Address))
{
directDomainList.Add(node.Address);
}
if (node?.Subid is not null)
{
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
if (subItem is not null)
{
foreach (var profile in new[] { subItem.PrevProfile, subItem.NextProfile })
{
var profileNode = await AppHandler.Instance.GetProfileItemViaRemarks(profile);
if (profileNode is not null &&
profileNode.ConfigType is not (EConfigType.Custom or EConfigType.Hysteria2 or EConfigType.TUIC) &&
Utils.IsDomain(profileNode.Address))
{
directDomainList.Add(profileNode.Address);
}
}
}
}
v2rayConfig.dns ??= new Dns4Ray();
v2rayConfig.dns.servers ??= new List<object>();
void AddDnsServers(List<string> dnsAddresses, List<string> domains, List<string>? expectedIPs = null)
{
if (domains.Count > 0)
{
foreach (var dnsAddress in dnsAddresses)
{
v2rayConfig.dns.servers.Add(CreateDnsServer(dnsAddress, domains, expectedIPs));
}
}
}
AddDnsServers(remoteDNSAddress, proxyDomainList);
AddDnsServers(directDNSAddress, directDomainList);
AddDnsServers(remoteDNSAddress, proxyGeositeList);
AddDnsServers(directDNSAddress, directGeositeList);
AddDnsServers(directDNSAddress, expectedDomainList, expectedIPs);
var useDirectDns = rules?.LastOrDefault() is { } lastRule &&
lastRule.OutboundTag == Global.DirectTag &&
(lastRule.Port == "0-65535" ||
lastRule.Network == "tcp,udp" ||
lastRule.Ip?.Contains("0.0.0.0/0") == true);
var defaultDnsServers = useDirectDns ? directDNSAddress : remoteDNSAddress;
v2rayConfig.dns.servers.AddRange(defaultDnsServers);
return 0;
}
private async Task<int> GenDnsHosts(V2rayConfig v2rayConfig, SimpleDNSItem simpleDNSItem)
{
if (simpleDNSItem.AddCommonHosts == false && simpleDNSItem.UseSystemHosts == false && simpleDNSItem.Hosts.IsNullOrEmpty())
{
return await Task.FromResult(0);
}
v2rayConfig.dns ??= new Dns4Ray();
v2rayConfig.dns.hosts ??= new Dictionary<string, List<string>>();
if (simpleDNSItem.AddCommonHosts == true)
{
v2rayConfig.dns.hosts = Global.PredefinedHosts;
}
if (simpleDNSItem.UseSystemHosts == true)
{
var systemHosts = Utils.GetSystemHosts();
if (systemHosts.Count > 0)
{
var normalHost = v2rayConfig.dns.hosts;
if (normalHost != null)
{
foreach (var host in systemHosts)
{
if (normalHost[host.Key] != null)
{
continue;
}
normalHost[host.Key] = new List<string> { host.Value };
}
}
}
}
var userHostsMap = simpleDNSItem.Hosts?
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Where(line => !string.IsNullOrWhiteSpace(line))
.Where(line => line.Contains(' '))
.ToDictionary(
line =>
{
var parts = line.Trim().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
return parts[0];
},
line =>
{
var parts = line.Trim().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
var values = parts.Skip(1).ToList();
return values;
}
);
if (userHostsMap != null)
{
foreach (var kvp in userHostsMap)
{
v2rayConfig.dns.hosts[kvp.Key] = kvp.Value;
}
}
return await Task.FromResult(0);
}
private async Task<int> GenDnsCompatible(ProfileItem? node, V2rayConfig v2rayConfig)
{
try
{
@ -1174,22 +1434,33 @@ public class CoreConfigV2rayService
var systemHosts = Utils.GetSystemHosts();
if (systemHosts.Count > 0)
{
var normalHost = obj["hosts"];
if (normalHost != null)
var normalHost1 = obj["hosts"];
if (normalHost1 != null)
{
foreach (var host in systemHosts)
{
if (normalHost[host.Key] != null)
if (normalHost1[host.Key] != null)
continue;
normalHost[host.Key] = host.Value;
normalHost1[host.Key] = host.Value;
}
}
}
}
var normalHost = obj["hosts"];
if (normalHost != null)
{
foreach (var hostProp in normalHost.AsObject().ToList())
{
if (hostProp.Value is JsonValue value && value.TryGetValue<string>(out var ip))
{
normalHost[hostProp.Key] = new JsonArray(ip);
}
}
}
await GenDnsDomains(node, obj, item);
await GenDnsDomainsCompatible(node, obj, item);
v2rayConfig.dns = obj;
v2rayConfig.dns = JsonUtils.Deserialize<Dns4Ray>(obj.ToJsonString());
}
catch (Exception ex)
{
@ -1198,7 +1469,7 @@ public class CoreConfigV2rayService
return 0;
}
private async Task<int> GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
private async Task<int> GenDnsDomainsCompatible(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
{
if (node == null)
{
@ -1241,7 +1512,7 @@ public class CoreConfigV2rayService
{
var dnsServer = new DnsServer4Ray()
{
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
skipFallback = true,
domains = domainList
};
@ -1349,7 +1620,8 @@ public class CoreConfigV2rayService
if (prevNode is not null
&& prevNode.ConfigType != EConfigType.Custom
&& prevNode.ConfigType != EConfigType.Hysteria2
&& prevNode.ConfigType != EConfigType.TUIC)
&& prevNode.ConfigType != EConfigType.TUIC
&& prevNode.ConfigType != EConfigType.Anytls)
{
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
await GenOutbound(prevNode, prevOutbound);
@ -1424,7 +1696,8 @@ public class CoreConfigV2rayService
if (prevNode is not null
&& prevNode.ConfigType != EConfigType.Custom
&& prevNode.ConfigType != EConfigType.Hysteria2
&& prevNode.ConfigType != EConfigType.TUIC)
&& prevNode.ConfigType != EConfigType.TUIC
&& prevNode.ConfigType != EConfigType.Anytls)
{
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
await GenOutbound(prevNode, prevOutbound);
@ -1493,7 +1766,8 @@ public class CoreConfigV2rayService
if (nextNode is not null
&& nextNode.ConfigType != EConfigType.Custom
&& nextNode.ConfigType != EConfigType.Hysteria2
&& nextNode.ConfigType != EConfigType.TUIC)
&& nextNode.ConfigType != EConfigType.TUIC
&& nextNode.ConfigType != EConfigType.Anytls)
{
if (nextOutbound == null)
{

View File

@ -358,8 +358,8 @@ public class SpeedtestService
private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
{
List<List<ServerTestItem>> lstTest = new();
var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC)).ToList();
var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC).ToList();
var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls)).ToList();
var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls).ToList();
for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++)
{

View File

@ -6,39 +6,52 @@ namespace ServiceLib.ViewModels;
public class DNSSettingViewModel : MyReactiveObject
{
[Reactive] public bool UseSystemHosts { get; set; }
[Reactive] public string DomainStrategy4Freedom { get; set; }
[Reactive] public string DomainDNSAddress { get; set; }
[Reactive] public string NormalDNS { get; set; }
[Reactive] public bool? UseSystemHosts { get; set; }
[Reactive] public bool? AddCommonHosts { get; set; }
[Reactive] public bool? FakeIP { get; set; }
[Reactive] public bool? BlockBindingQuery { get; set; }
[Reactive] public string? DirectDNS { get; set; }
[Reactive] public string? RemoteDNS { get; set; }
[Reactive] public string? SingboxOutboundsResolveDNS { get; set; }
[Reactive] public string? SingboxFinalResolveDNS { get; set; }
[Reactive] public string? RayStrategy4Freedom { get; set; }
[Reactive] public string? SingboxStrategy4Direct { get; set; }
[Reactive] public string? SingboxStrategy4Proxy { get; set; }
[Reactive] public string? Hosts { get; set; }
[Reactive] public string? DirectExpectedIPs { get; set; }
[Reactive] public string DomainStrategy4Freedom2 { get; set; }
[Reactive] public string DomainDNSAddress2 { get; set; }
[Reactive] public string NormalDNS2 { get; set; }
[Reactive] public string TunDNS2 { get; set; }
[Reactive] public bool UseSystemHostsCompatible { get; set; }
[Reactive] public string DomainStrategy4FreedomCompatible { get; set; }
[Reactive] public string DomainDNSAddressCompatible { get; set; }
[Reactive] public string NormalDNSCompatible { get; set; }
[Reactive] public string DomainStrategy4Freedom2Compatible { get; set; }
[Reactive] public string DomainDNSAddress2Compatible { get; set; }
[Reactive] public string NormalDNS2Compatible { get; set; }
[Reactive] public string TunDNS2Compatible { get; set; }
[Reactive] public bool RayCustomDNSEnableCompatible { get; set; }
[Reactive] public bool SBCustomDNSEnableCompatible { get; set; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCompatibleCmd { get; }
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCompatibleCmd { get; }
public DNSSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{
_config = AppHandler.Instance.Config;
_updateView = updateView;
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveSettingAsync();
});
SaveCmd = ReactiveCommand.CreateFromTask(SaveSettingAsync);
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
ImportDefConfig4V2rayCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
{
NormalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
NormalDNSCompatible = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
await Task.CompletedTask;
});
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
ImportDefConfig4SingboxCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
{
NormalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
TunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
NormalDNS2Compatible = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
TunDNS2Compatible = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
await Task.CompletedTask;
});
@ -47,48 +60,80 @@ public class DNSSettingViewModel : MyReactiveObject
private async Task Init()
{
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
_config = AppHandler.Instance.Config;
var item = _config.SimpleDNSItem;
UseSystemHosts = item.UseSystemHosts;
DomainStrategy4Freedom = item?.DomainStrategy4Freedom ?? string.Empty;
DomainDNSAddress = item?.DomainDNSAddress ?? string.Empty;
NormalDNS = item?.NormalDNS ?? string.Empty;
AddCommonHosts = item.AddCommonHosts;
FakeIP = item.FakeIP;
BlockBindingQuery = item.BlockBindingQuery;
DirectDNS = item.DirectDNS;
RemoteDNS = item.RemoteDNS;
RayStrategy4Freedom = item.RayStrategy4Freedom;
SingboxOutboundsResolveDNS = item.SingboxOutboundsResolveDNS;
SingboxFinalResolveDNS = item.SingboxFinalResolveDNS;
SingboxStrategy4Direct = item.SingboxStrategy4Direct;
SingboxStrategy4Proxy = item.SingboxStrategy4Proxy;
Hosts = item.Hosts;
DirectExpectedIPs = item.DirectExpectedIPs;
var item1 = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
RayCustomDNSEnableCompatible = item1.Enabled;
UseSystemHostsCompatible = item1.UseSystemHosts;
DomainStrategy4FreedomCompatible = item1?.DomainStrategy4Freedom ?? string.Empty;
DomainDNSAddressCompatible = item1?.DomainDNSAddress ?? string.Empty;
NormalDNSCompatible = item1?.NormalDNS ?? string.Empty;
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
DomainStrategy4Freedom2 = item2?.DomainStrategy4Freedom ?? string.Empty;
DomainDNSAddress2 = item2?.DomainDNSAddress ?? string.Empty;
NormalDNS2 = item2?.NormalDNS ?? string.Empty;
TunDNS2 = item2?.TunDNS ?? string.Empty;
SBCustomDNSEnableCompatible = item2.Enabled;
DomainStrategy4Freedom2Compatible = item2?.DomainStrategy4Freedom ?? string.Empty;
DomainDNSAddress2Compatible = item2?.DomainDNSAddress ?? string.Empty;
NormalDNS2Compatible = item2?.NormalDNS ?? string.Empty;
TunDNS2Compatible = item2?.TunDNS ?? string.Empty;
}
private async Task SaveSettingAsync()
{
if (NormalDNS.IsNotEmpty())
_config.SimpleDNSItem.UseSystemHosts = UseSystemHosts;
_config.SimpleDNSItem.AddCommonHosts = AddCommonHosts;
_config.SimpleDNSItem.FakeIP = FakeIP;
_config.SimpleDNSItem.BlockBindingQuery = BlockBindingQuery;
_config.SimpleDNSItem.DirectDNS = DirectDNS;
_config.SimpleDNSItem.RemoteDNS = RemoteDNS;
_config.SimpleDNSItem.RayStrategy4Freedom = RayStrategy4Freedom;
_config.SimpleDNSItem.SingboxOutboundsResolveDNS = SingboxOutboundsResolveDNS;
_config.SimpleDNSItem.SingboxFinalResolveDNS = SingboxFinalResolveDNS;
_config.SimpleDNSItem.SingboxStrategy4Direct = SingboxStrategy4Direct;
_config.SimpleDNSItem.SingboxStrategy4Proxy = SingboxStrategy4Proxy;
_config.SimpleDNSItem.Hosts = Hosts;
_config.SimpleDNSItem.DirectExpectedIPs = DirectExpectedIPs;
if (NormalDNSCompatible.IsNotEmpty())
{
var obj = JsonUtils.ParseJson(NormalDNS);
var obj = JsonUtils.ParseJson(NormalDNSCompatible);
if (obj != null && obj["servers"] != null)
{
}
else
{
if (NormalDNS.Contains('{') || NormalDNS.Contains('}'))
if (NormalDNSCompatible.Contains('{') || NormalDNSCompatible.Contains('}'))
{
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
return;
}
}
}
if (NormalDNS2.IsNotEmpty())
if (NormalDNS2Compatible.IsNotEmpty())
{
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2);
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2Compatible);
if (obj2 == null)
{
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
return;
}
}
if (TunDNS2.IsNotEmpty())
if (TunDNS2Compatible.IsNotEmpty())
{
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(TunDNS2);
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(TunDNS2Compatible);
if (obj2 == null)
{
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
@ -96,21 +141,26 @@ public class DNSSettingViewModel : MyReactiveObject
}
}
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
item.DomainStrategy4Freedom = DomainStrategy4Freedom;
item.DomainDNSAddress = DomainDNSAddress;
item.UseSystemHosts = UseSystemHosts;
item.NormalDNS = NormalDNS;
await ConfigHandler.SaveDNSItems(_config, item);
var item1 = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
item1.Enabled = RayCustomDNSEnableCompatible;
item1.DomainStrategy4Freedom = DomainStrategy4FreedomCompatible;
item1.DomainDNSAddress = DomainDNSAddressCompatible;
item1.UseSystemHosts = UseSystemHostsCompatible;
item1.NormalDNS = NormalDNSCompatible;
await ConfigHandler.SaveDNSItems(_config, item1);
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2;
item2.DomainDNSAddress = DomainDNSAddress2;
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2));
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2));
item2.Enabled = RayCustomDNSEnableCompatible;
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2Compatible;
item2.DomainDNSAddress = DomainDNSAddress2Compatible;
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2Compatible));
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2Compatible));
await ConfigHandler.SaveDNSItems(_config, item2);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
_ = _updateView?.Invoke(EViewAction.CloseWindow, null);
await ConfigHandler.SaveConfig(_config);
if (_updateView != null)
{
await _updateView(EViewAction.CloseWindow, null);
}
}
}

View File

@ -20,6 +20,7 @@ public class MainWindowViewModel : MyReactiveObject
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddAnytlsServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
@ -111,6 +112,10 @@ public class MainWindowViewModel : MyReactiveObject
{
await AddServerAsync(true, EConfigType.WireGuard);
});
AddAnytlsServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
await AddServerAsync(true, EConfigType.Anytls);
});
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
await AddServerAsync(true, EConfigType.Custom);

View File

@ -533,6 +533,26 @@
HorizontalAlignment="Left"
Watermark="1500" />
</Grid>
<Grid
x:Name="gridAnytls"
Grid.Row="2"
ColumnDefinitions="180,Auto"
IsVisible="False"
RowDefinitions="Auto,Auto,Auto">
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbId3}" />
<TextBox
x:Name="txtId10"
Grid.Row="1"
Grid.Column="1"
Width="400"
Margin="{StaticResource Margin4}" />
</Grid>
<Separator
x:Name="sepa2"

View File

@ -102,6 +102,12 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
gridTls.IsVisible = false;
break;
case EConfigType.Anytls:
gridAnytls.IsVisible = true;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
cmbCoreType.IsEnabled = false;
break;
}
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
@ -167,6 +173,10 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
break;
case EConfigType.Anytls:
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId10.Text).DisposeWith(disposables);
break;
}
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);

View File

@ -2,6 +2,7 @@
x:Class="v2rayN.Desktop.Views.DNSSettingWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:v2rayN.Desktop.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
@ -35,9 +36,281 @@
</StackPanel>
<TabControl HorizontalContentAlignment="Stretch">
<TabItem Header="{x:Static resx:ResUI.ThBasicDNSSettings}">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid
Margin="{StaticResource Margin4}"
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<TextBlock
x:Name="txtBasicDNSSettingsInvalid"
Grid.Row="0"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbDomesticDNS}" />
<ctrls:AutoCompleteBox
x:Name="cmbDirectDNS"
Grid.Row="1"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Text="{Binding DirectDNS, Mode=TwoWay}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRemoteDNS}" />
<ctrls:AutoCompleteBox
x:Name="cmbRemoteDNS"
Grid.Row="2"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Text="{Binding RemoteDNS, Mode=TwoWay}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBOutboundsResolverDNS}" />
<ctrls:AutoCompleteBox
x:Name="cmbSBResolverDNS"
Grid.Row="3"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Text="{Binding SingboxOutboundsResolveDNS, Mode=TwoWay}" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBOutboundDomainResolve}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBDoHResolverServer}" />
<ctrls:AutoCompleteBox
x:Name="cmbSBFinalResolverDNS"
Grid.Row="4"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Text="{Binding SingboxFinalResolveDNS, Mode=TwoWay}" />
<TextBlock
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBFallbackDNSResolve}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbXrayFreedomResolveStrategy}" />
<ComboBox
x:Name="cmbRayFreedomDNSStrategy"
Grid.Row="5"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
PlaceholderText="Default" />
<TextBlock
Grid.Row="6"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" />
<ComboBox
x:Name="cmbSBDirectDNSStrategy"
Grid.Row="6"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
PlaceholderText="Default" />
<TextBlock
Grid.Row="7"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" />
<ComboBox
x:Name="cmbSBRemoteDNSStrategy"
Grid.Row="7"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
PlaceholderText="Default" />
<TextBlock
Grid.Row="8"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" />
<ToggleSwitch
x:Name="togAddCommonHosts"
Grid.Row="8"
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="8"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSBDoHOverride}" />
</Grid>
</ScrollViewer>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.ThAdvancedDNSSettings}">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid
Margin="{StaticResource Margin4}"
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,*">
<TextBlock
x:Name="txtAdvancedDNSSettingsInvalid"
Grid.Row="0"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
<ToggleSwitch
x:Name="togUseSystemHosts"
Grid.Row="1"
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbFakeIP}" />
<ToggleSwitch
x:Name="togFakeIP"
Grid.Row="2"
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="2"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbApplyProxyDomainsOnly}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbBlockSVCBHTTPSQueries}" />
<ToggleSwitch
x:Name="togBlockBindingQuery"
Grid.Row="3"
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbPreventDNSLeaks}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbValidateDirectExpectedIPs}" />
<ctrls:AutoCompleteBox
x:Name="cmbDirectExpectedIPs"
Grid.Row="4"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Text="{Binding DirectExpectedIPs, Mode=TwoWay}" />
<TextBlock
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbValidateDirectExpectedIPsDesc}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbDNSHostsConfig}" />
<TextBox
x:Name="txtHosts"
Grid.Row="6"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="{StaticResource Margin4}"
VerticalAlignment="Stretch"
Watermark="{x:Static resx:ResUI.TbDNSHostsConfig}"
BorderThickness="1"
Classes="TextArea"
TextWrapping="Wrap" />
</Grid>
</ScrollViewer>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
<DockPanel Margin="{StaticResource Margin8}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
<ToggleSwitch
x:Name="togRayCustomDNSEnableCompatible"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
@ -49,11 +322,12 @@
</HyperlinkButton>
</TextBlock>
<Button
x:Name="btnImportDefConfig4V2ray"
x:Name="btnImportDefConfig4V2rayCompatible"
Margin="{StaticResource Margin4}"
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
Cursor="Hand" />
</StackPanel>
</Grid>
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
@ -62,7 +336,7 @@
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
<ToggleSwitch
x:Name="togUseSystemHosts"
x:Name="togUseSystemHostsCompatible"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
</StackPanel>
@ -73,7 +347,7 @@
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
<ComboBox
x:Name="cmbdomainStrategy4Freedom"
x:Name="cmbdomainStrategy4FreedomCompatible"
Width="150"
Margin="{StaticResource Margin4}" />
</StackPanel>
@ -83,10 +357,11 @@
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
<ComboBox
x:Name="cmbdomainDNSAddress"
<ctrls:AutoCompleteBox
x:Name="cmbdomainDNSAddressCompatible"
Width="150"
Margin="{StaticResource Margin4}" />
Margin="{StaticResource Margin4}"
Text="{Binding DomainDNSAddressCompatible, Mode=TwoWay}" />
</StackPanel>
</WrapPanel>
@ -96,7 +371,7 @@
BorderThickness="1"
Header="HTTP/SOCKS">
<TextBox
Name="txtnormalDNS"
Name="txtnormalDNSCompatible"
VerticalAlignment="Stretch"
Classes="TextArea"
MinLines="10"
@ -107,18 +382,36 @@
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
<DockPanel Margin="{StaticResource Margin8}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
<ToggleSwitch
x:Name="togSBCustomDNSEnableCompatible"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkDnsSingboxObjectDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
</HyperlinkButton>
</TextBlock>
<Button
x:Name="btnImportDefConfig4Singbox"
x:Name="btnImportDefConfig4SingboxCompatible"
Margin="{StaticResource Margin4}"
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
Cursor="Hand" />
</StackPanel>
</Grid>
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
@ -127,7 +420,7 @@
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
<ComboBox
x:Name="cmbdomainStrategy4Out"
x:Name="cmbdomainStrategy4OutCompatible"
Width="150"
Margin="{StaticResource Margin4}" />
</StackPanel>
@ -137,10 +430,11 @@
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
<ComboBox
x:Name="cmbdomainDNSAddress2"
<ctrls:AutoCompleteBox
x:Name="cmbdomainDNSAddress2Compatible"
Width="150"
Margin="{StaticResource Margin4}" />
Margin="{StaticResource Margin4}"
Text="{Binding DomainDNSAddress2Compatible, Mode=TwoWay}" />
</StackPanel>
</WrapPanel>
@ -152,7 +446,7 @@
BorderThickness="1"
Header="HTTP/SOCKS">
<TextBox
Name="txtnormalDNS2"
Name="txtnormalDNS2Compatible"
VerticalAlignment="Stretch"
Classes="TextArea"
MinLines="10"
@ -167,7 +461,7 @@
BorderThickness="1"
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
<TextBox
Name="txttunDNS2"
Name="txttunDNS2Compatible"
VerticalAlignment="Stretch"
Classes="TextArea"
MinLines="10"

View File

@ -1,4 +1,5 @@
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using ReactiveUI;
using v2rayN.Desktop.Base;
@ -17,26 +18,64 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
btnCancel.Click += (s, e) => this.Close();
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress;
cmbSBResolverDNS.ItemsSource = Global.DomainDirectDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress;
cmbSBFinalResolverDNS.ItemsSource = Global.DomainPureIPDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs;
cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms;
cmbdomainStrategy4OutCompatible.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainDNSAddressCompatible.ItemsSource = Global.DomainPureIPDNSAddress;
cmbdomainDNSAddress2Compatible.ItemsSource = Global.DomainPureIPDNSAddress;
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AddCommonHosts, v => v.togAddCommonHosts.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FakeIP, v => v.togFakeIP.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Hosts, v => v.txtHosts.Text).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.DirectExpectedIPs, v => v.cmbDirectExpectedIPs.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RayCustomDNSEnableCompatible, v => v.togRayCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SBCustomDNSEnableCompatible, v => v.togSBCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.UseSystemHostsCompatible, v => v.togUseSystemHostsCompatible.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4FreedomCompatible, v => v.cmbdomainStrategy4FreedomCompatible.SelectedItem).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.DomainDNSAddressCompatible, v => v.cmbdomainDNSAddressCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNSCompatible, v => v.txtnormalDNSCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2Compatible, v => v.cmbdomainStrategy4OutCompatible.SelectedItem).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.DomainDNSAddress2Compatible, v => v.cmbdomainDNSAddress2Compatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNS2Compatible, v => v.txtnormalDNS2Compatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDNS2Compatible, v => v.txttunDNS2Compatible.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables);
this.WhenAnyValue(
x => x.ViewModel.RayCustomDNSEnableCompatible,
x => x.ViewModel.SBCustomDNSEnableCompatible,
(ray, sb) => ray && sb
).BindTo(this.FindControl<TextBlock>("txtBasicDNSSettingsInvalid"), t => t.IsVisible);
this.WhenAnyValue(
x => x.ViewModel.RayCustomDNSEnableCompatible,
x => x.ViewModel.SBCustomDNSEnableCompatible,
(ray, sb) => ray && sb
).BindTo(this.FindControl<TextBlock>("txtAdvancedDNSSettingsInvalid"), t => t.IsVisible);
});
}

View File

@ -46,6 +46,7 @@
<Separator />
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
<MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" />
<MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
</MenuItem>
<MenuItem Padding="8,0">

View File

@ -83,6 +83,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).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.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);

View File

@ -707,6 +707,35 @@
materialDesign:HintAssist.Hint="1500"
Style="{StaticResource DefTextBox}" />
</Grid>
<Grid
x:Name="gridAnytls"
Grid.Row="2"
Visibility="Hidden">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<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.TbId3}" />
<TextBox
x:Name="txtId10"
Grid.Row="1"
Grid.Column="1"
Width="400"
Margin="{StaticResource Margin4}"
Style="{StaticResource DefTextBox}" />
</Grid>
<Separator
x:Name="sepa2"

View File

@ -95,6 +95,11 @@ public partial class AddServerWindow
gridTransport.Visibility = Visibility.Collapsed;
gridTls.Visibility = Visibility.Collapsed;
break;
case EConfigType.Anytls:
gridAnytls.Visibility = Visibility.Visible;
cmbCoreType.IsEnabled = false;
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
break;
}
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
@ -161,6 +166,10 @@ public partial class AddServerWindow
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
break;
case EConfigType.Anytls:
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId10.Text).DisposeWith(disposables);
break;
}
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.Text).DisposeWith(disposables);

View File

@ -41,10 +41,339 @@
</StackPanel>
<TabControl HorizontalContentAlignment="Left">
<TabItem Header="{x:Static resx:ResUI.ThBasicDNSSettings}">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid Margin="{StaticResource Margin8}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="txtBasicDNSSettingsInvalid"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbDomesticDNS}" />
<ComboBox
x:Name="cmbDirectDNS"
Grid.Row="1"
Grid.Column="1"
Width="200"
IsEditable="True"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbRemoteDNS}" />
<ComboBox
x:Name="cmbRemoteDNS"
Grid.Row="2"
Grid.Column="1"
Width="200"
IsEditable="True"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBOutboundsResolverDNS}" />
<ComboBox
x:Name="cmbSBResolverDNS"
Grid.Row="3"
Grid.Column="1"
Width="200"
IsEditable="True"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBOutboundDomainResolve}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBDoHResolverServer}" />
<ComboBox
x:Name="cmbSBFinalResolverDNS"
Grid.Row="4"
Grid.Column="1"
Width="200"
IsEditable="True"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBFallbackDNSResolve}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbXrayFreedomResolveStrategy}" />
<ComboBox
x:Name="cmbRayFreedomDNSStrategy"
Grid.Row="5"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
materialDesign:HintAssist.Hint="Default"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="6"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" />
<ComboBox
x:Name="cmbSBDirectDNSStrategy"
Grid.Row="6"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
materialDesign:HintAssist.Hint="Default"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="7"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" />
<ComboBox
x:Name="cmbSBRemoteDNSStrategy"
Grid.Row="7"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
materialDesign:HintAssist.Hint="Default"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="8"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" />
<ToggleButton
x:Name="togAddCommonHosts"
Grid.Row="8"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="8"
Grid.Column="3"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSBDoHOverride}" />
</Grid>
</ScrollViewer>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.ThAdvancedDNSSettings}">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid Margin="{StaticResource Margin8}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="txtAdvancedDNSSettingsInvalid"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
<ToggleButton
x:Name="togUseSystemHosts"
Grid.Row="1"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbFakeIP}" />
<ToggleButton
x:Name="togFakeIP"
Grid.Row="2"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="2"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbApplyProxyDomainsOnly}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbBlockSVCBHTTPSQueries}" />
<ToggleButton
x:Name="togBlockBindingQuery"
Grid.Row="3"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbPreventDNSLeaks}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbValidateDirectExpectedIPs}" />
<ComboBox
x:Name="cmbDirectExpectedIPs"
Grid.Row="4"
Grid.Column="1"
Width="200"
IsEditable="True"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbValidateDirectExpectedIPsDesc}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbDNSHostsConfig}" />
<TextBox
x:Name="txtHosts"
Grid.Row="6"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="{StaticResource Margin8}"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbDNSHostsConfig}"
AcceptsReturn="True"
BorderThickness="1"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
</Grid>
</ScrollViewer>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
<DockPanel Margin="{StaticResource Margin8}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
<ToggleButton
x:Name="togRayCustomDNSEnableCompatible"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -60,12 +389,13 @@
</Hyperlink>
</TextBlock>
<Button
x:Name="btnImportDefConfig4V2ray"
x:Name="btnImportDefConfig4V2rayCompatible"
Margin="{StaticResource Margin8}"
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
Cursor="Hand"
Style="{StaticResource DefButton}" />
</StackPanel>
</Grid>
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
@ -75,7 +405,7 @@
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
<ToggleButton
x:Name="togUseSystemHosts"
x:Name="togUseSystemHostsCompatible"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
</StackPanel>
@ -87,7 +417,7 @@
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
<ComboBox
x:Name="cmbdomainStrategy4Freedom"
x:Name="cmbdomainStrategy4FreedomCompatible"
Width="150"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
@ -100,7 +430,7 @@
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
<ComboBox
x:Name="cmbdomainDNSAddress"
x:Name="cmbdomainDNSAddressCompatible"
Width="150"
Margin="{StaticResource Margin8}"
IsEditable="True"
@ -109,7 +439,7 @@
</WrapPanel>
<TextBox
x:Name="txtnormalDNS"
x:Name="txtnormalDNSCompatible"
Margin="{StaticResource Margin8}"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="HTTP/SOCKS"
@ -123,7 +453,25 @@
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
<DockPanel Margin="{StaticResource Margin8}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
<ToggleButton
x:Name="togSBCustomDNSEnableCompatible"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -134,12 +482,13 @@
</Hyperlink>
</TextBlock>
<Button
x:Name="btnImportDefConfig4Singbox"
x:Name="btnImportDefConfig4SingboxCompatible"
Margin="{StaticResource Margin8}"
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
Cursor="Hand"
Style="{StaticResource DefButton}" />
</StackPanel>
</Grid>
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
@ -149,7 +498,7 @@
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
<ComboBox
x:Name="cmbdomainStrategy4Out"
x:Name="cmbdomainStrategy4OutCompatible"
Width="150"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
@ -162,7 +511,7 @@
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
<ComboBox
x:Name="cmbdomainDNSAddress2"
x:Name="cmbdomainDNSAddress2Compatible"
Width="150"
Margin="{StaticResource Margin8}"
IsEditable="True"
@ -178,7 +527,7 @@
</Grid.ColumnDefinitions>
<TextBox
x:Name="txtnormalDNS2"
x:Name="txtnormalDNS2Compatible"
Grid.Column="0"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="HTTP/SOCKS"
@ -191,7 +540,7 @@
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<TextBox
x:Name="txttunDNS2"
x:Name="txttunDNS2Compatible"
Grid.Column="2"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsTunMode}"

View File

@ -17,26 +17,66 @@ public partial class DNSSettingWindow
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress;
cmbSBResolverDNS.ItemsSource = Global.DomainDirectDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress;
cmbSBFinalResolverDNS.ItemsSource = Global.DomainPureIPDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs;
cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms;
cmbdomainStrategy4OutCompatible.ItemsSource = Global.SingboxDomainStrategy4Out;
cmbdomainDNSAddressCompatible.ItemsSource = Global.DomainPureIPDNSAddress;
cmbdomainDNSAddress2Compatible.ItemsSource = Global.DomainPureIPDNSAddress;
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AddCommonHosts, v => v.togAddCommonHosts.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FakeIP, v => v.togFakeIP.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Hosts, v => v.txtHosts.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DirectExpectedIPs, v => v.cmbDirectExpectedIPs.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RayCustomDNSEnableCompatible, v => v.togRayCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SBCustomDNSEnableCompatible, v => v.togSBCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.UseSystemHostsCompatible, v => v.togUseSystemHostsCompatible.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4FreedomCompatible, v => v.cmbdomainStrategy4FreedomCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddressCompatible, v => v.cmbdomainDNSAddressCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNSCompatible, v => v.txtnormalDNSCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2Compatible, v => v.cmbdomainStrategy4OutCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress2Compatible, v => v.cmbdomainDNSAddress2Compatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNS2Compatible, v => v.txtnormalDNS2Compatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDNS2Compatible, v => v.txttunDNS2Compatible.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables);
this.WhenAnyValue(
x => x.ViewModel.RayCustomDNSEnableCompatible,
x => x.ViewModel.SBCustomDNSEnableCompatible,
(ray, sb) => ray && sb ? Visibility.Visible : Visibility.Collapsed)
.BindTo(this, x => x.txtBasicDNSSettingsInvalid.Visibility)
.DisposeWith(disposables);
this.WhenAnyValue(
x => x.ViewModel.RayCustomDNSEnableCompatible,
x => x.ViewModel.SBCustomDNSEnableCompatible,
(ray, sb) => ray && sb ? Visibility.Visible : Visibility.Collapsed)
.BindTo(this, x => x.txtAdvancedDNSSettingsInvalid.Visibility)
.DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}

View File

@ -108,6 +108,10 @@
x:Name="menuAddTuicServer"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddTuicServer}" />
<MenuItem
x:Name="menuAddAnytlsServer"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
</MenuItem>
</Menu>
<Separator />

View File

@ -80,6 +80,7 @@ public partial class MainWindow
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).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.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);