mirror of
				https://github.com/2dust/v2rayN.git
				synced 2025-10-29 19:42:51 +00:00 
			
		
		
		
	Merge 86bdd20fe3 into c669e72189
				
					
				
			This commit is contained in:
		
						commit
						0988cd0ff3
					
				
					 51 changed files with 4115 additions and 406 deletions
				
			
		|  | @ -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); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -466,11 +466,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; | ||||
|             } | ||||
|  |  | |||
|  | @ -11,5 +11,6 @@ public enum EConfigType | |||
|     Hysteria2 = 7, | ||||
|     TUIC = 8, | ||||
|     WireGuard = 9, | ||||
|     HTTP = 10 | ||||
|     HTTP = 10, | ||||
|     Anytls = 11 | ||||
| } | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ public enum EViewAction | |||
|     DNSSettingWindow, | ||||
|     RoutingSettingWindow, | ||||
|     OptionSettingWindow, | ||||
|     CustomConfigWindow, | ||||
|     GlobalHotkeySettingWindow, | ||||
|     SubSettingWindow, | ||||
|     DispatcherSpeedTest, | ||||
|  |  | |||
|  | @ -76,6 +76,13 @@ public class Global | |||
|     public const int SpeedTestPageSize = 1000; | ||||
|     public const string LinuxBash = "/bin/bash"; | ||||
| 
 | ||||
|     public const string SingboxDirectDNSTag = "direct_dns"; | ||||
|     public const string SingboxRemoteDNSTag = "remote_dns"; | ||||
|     public const string SingboxOutboundResolverTag = "outbound_resolver"; | ||||
|     public const string SingboxFinalResolverTag = "final_resolver"; | ||||
|     public const string SingboxHostsDNSTag = "hosts_dns"; | ||||
|     public const string SingboxFakeDNSTag = "fake_dns"; | ||||
| 
 | ||||
|     public static readonly List<string> IEProxyProtocols = | ||||
|     [ | ||||
|         "{ip}:{http_port}", | ||||
|  | @ -169,7 +176,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() | ||||
|  | @ -182,7 +190,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 = | ||||
|  | @ -349,25 +358,42 @@ public class Global | |||
| 
 | ||||
|     public static readonly List<string> SingboxDomainStrategy4Out = | ||||
|     [ | ||||
|         "ipv4_only", | ||||
|         "", | ||||
|             "ipv4_only", | ||||
|             "prefer_ipv4", | ||||
|             "prefer_ipv6", | ||||
|             "ipv6_only", | ||||
|             "" | ||||
|             "ipv6_only" | ||||
|     ]; | ||||
| 
 | ||||
|     public static readonly List<string> DomainDNSAddress = | ||||
|     public static readonly List<string> DomainDirectDNSAddress = | ||||
|     [ | ||||
|         "223.5.5.5", | ||||
|             "223.6.6.6", | ||||
|         "https://dns.alidns.com/dns-query", | ||||
|             "https://doh.pub/dns-query", | ||||
|             "223.5.5.5", | ||||
|             "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 = | ||||
|  | @ -537,5 +563,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 | ||||
| } | ||||
|  |  | |||
|  | @ -64,6 +64,7 @@ public sealed class AppHandler | |||
|         SQLiteHelper.Instance.CreateTable<RoutingItem>(); | ||||
|         SQLiteHelper.Instance.CreateTable<ProfileExItem>(); | ||||
|         SQLiteHelper.Instance.CreateTable<DNSItem>(); | ||||
|         SQLiteHelper.Instance.CreateTable<CustomConfigItem>(); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|  | @ -203,6 +204,16 @@ public sealed class AppHandler | |||
|         return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType); | ||||
|     } | ||||
| 
 | ||||
|     public async Task<List<CustomConfigItem>?> CustomConfigItem() | ||||
|     { | ||||
|         return await SQLiteHelper.Instance.TableAsync<CustomConfigItem>().ToListAsync(); | ||||
|     } | ||||
| 
 | ||||
|     public async Task<CustomConfigItem?> GetCustomConfigItem(ECoreType eCoreType) | ||||
|     { | ||||
|         return await SQLiteHelper.Instance.TableAsync<CustomConfigItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType); | ||||
|     } | ||||
| 
 | ||||
|     #endregion SqliteHelper | ||||
| 
 | ||||
|     #region Core Type | ||||
|  |  | |||
|  | @ -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) | ||||
|         { | ||||
|  | @ -262,6 +267,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; | ||||
|  | @ -786,6 +792,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 | ||||
|  | @ -1295,6 +1330,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, | ||||
|             }; | ||||
| 
 | ||||
|  | @ -2063,18 +2099,38 @@ public class ConfigHandler | |||
|     /// <summary> | ||||
|     /// Initialize built-in DNS configurations | ||||
|     /// Creates default DNS items for V2Ray and sing-box | ||||
|     /// Also checks existing DNS items and disables those with empty NormalDNS | ||||
|     /// </summary> | ||||
|     /// <param name="config">Current configuration</param> | ||||
|     /// <returns>0 if successful</returns> | ||||
|     public static async Task<int> InitBuiltinDNS(Config config) | ||||
|     { | ||||
|         var items = await AppHandler.Instance.DNSItems(); | ||||
|          | ||||
|         // Check existing DNS items and disable those with empty NormalDNS | ||||
|         var needsUpdate = false; | ||||
|         foreach (var existingItem in items) | ||||
|         { | ||||
|             if (existingItem.NormalDNS.IsNullOrEmpty() && existingItem.Enabled) | ||||
|             { | ||||
|                 existingItem.Enabled = false; | ||||
|                 needsUpdate = true; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         // Update items if any changes were made | ||||
|         if (needsUpdate) | ||||
|         { | ||||
|             await SQLiteHelper.Instance.UpdateAllAsync(items); | ||||
|         } | ||||
|          | ||||
|         if (items.Count <= 0) | ||||
|         { | ||||
|             var item = new DNSItem() | ||||
|             { | ||||
|                 Remarks = "V2ray", | ||||
|                 CoreType = ECoreType.Xray, | ||||
|                 Enabled = false, | ||||
|             }; | ||||
|             await SaveDNSItems(config, item); | ||||
| 
 | ||||
|  | @ -2082,6 +2138,7 @@ public class ConfigHandler | |||
|             { | ||||
|                 Remarks = "sing-box", | ||||
|                 CoreType = ECoreType.sing_box, | ||||
|                 Enabled = false, | ||||
|             }; | ||||
|             await SaveDNSItems(config, item2); | ||||
|         } | ||||
|  | @ -2153,6 +2210,86 @@ 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 Custom Config | ||||
| 
 | ||||
|     public static async Task<int> InitBuiltinCustomConfig(Config config) | ||||
|     { | ||||
|         var items = await AppHandler.Instance.CustomConfigItem(); | ||||
|         if (items.Count <= 0) | ||||
|         { | ||||
|             var item = new CustomConfigItem() | ||||
|             { | ||||
|                 Remarks = "V2ray", | ||||
|                 CoreType = ECoreType.Xray, | ||||
|             }; | ||||
|             await SaveCustomConfigItem(config, item); | ||||
| 
 | ||||
|             var item2 = new CustomConfigItem() | ||||
|             { | ||||
|                 Remarks = "sing-box", | ||||
|                 CoreType = ECoreType.sing_box, | ||||
|             }; | ||||
|             await SaveCustomConfigItem(config, item2); | ||||
|         } | ||||
| 
 | ||||
|         return 0; | ||||
|     } | ||||
|     public static async Task<int> SaveCustomConfigItem(Config config, CustomConfigItem item) | ||||
|     { | ||||
|         if (item == null) | ||||
|         { | ||||
|             return -1; | ||||
|         } | ||||
| 
 | ||||
|         if (item.Id.IsNullOrEmpty()) | ||||
|         { | ||||
|             item.Id = Utils.GetGuid(false); | ||||
|         } | ||||
| 
 | ||||
|         if (await SQLiteHelper.Instance.ReplaceAsync(item) > 0) | ||||
|         { | ||||
|             return 0; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #endregion Custom Config | ||||
| 
 | ||||
|     #region Regional Presets | ||||
| 
 | ||||
|     /// <summary> | ||||
|  | @ -2174,6 +2311,8 @@ public class ConfigHandler | |||
|                 await SQLiteHelper.Instance.DeleteAllAsync<DNSItem>(); | ||||
|                 await InitBuiltinDNS(config); | ||||
| 
 | ||||
|                 InitBuiltinSimpleDNS(config); | ||||
| 
 | ||||
|                 return true; | ||||
| 
 | ||||
|             case EPresetType.Russia: | ||||
|  | @ -2184,6 +2323,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: | ||||
|  | @ -2194,6 +2335,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; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -103,7 +103,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); | ||||
|  |  | |||
							
								
								
									
										49
									
								
								v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs
									
									
									
									
									
										Normal 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); | ||||
|     } | ||||
| } | ||||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
|  |  | |||
|  | @ -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; } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										18
									
								
								v2rayN/ServiceLib/Models/CustomConfigItem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								v2rayN/ServiceLib/Models/CustomConfigItem.cs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| using SQLite; | ||||
| 
 | ||||
| namespace ServiceLib.Models; | ||||
| 
 | ||||
| [Serializable] | ||||
| public class CustomConfigItem | ||||
| { | ||||
|     [PrimaryKey] | ||||
|     public string Id { get; set; } | ||||
| 
 | ||||
|     public string Remarks { get; set; } | ||||
|     public bool Enabled { get; set; } = false; | ||||
|     public ECoreType CoreType { get; set; } | ||||
|     public string? Config { get; set; } | ||||
|     public string? TunConfig { get; set; } | ||||
|     public bool? AddProxyOnly { get; set; } = false; | ||||
|     public string? ProxyDetour { get; set; } | ||||
| } | ||||
|  | @ -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; } | ||||
|  |  | |||
|  | @ -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; } | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										288
									
								
								v2rayN/ServiceLib/Resx/ResUI.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										288
									
								
								v2rayN/ServiceLib/Resx/ResUI.Designer.cs
									
									
									
										generated
									
									
									
								
							|  | @ -186,6 +186,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Please fill in the correct custom config 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string FillCorrectConfigText { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("FillCorrectConfigText", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Please fill in the correct custom DNS 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -654,6 +663,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> | ||||
|  | @ -843,6 +861,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Custom Config 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string menuCustomConfig { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("menuCustomConfig", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 DNS Settings 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2211,6 +2238,24 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Add Common DNS Hosts 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbAddCommonDNSHosts { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbAddCommonDNSHosts", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Do Not Add Non-Proxy Protocol Outbound 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbAddProxyProtocolOutboundOnly { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbAddProxyProtocolOutboundOnly", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Address 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2247,6 +2292,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> | ||||
|  | @ -2274,6 +2328,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Block SVCB and HTTPS Queries 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbBlockSVCBHTTPSQueries { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbBlockSVCBHTTPSQueries", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Browse 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2328,6 +2391,42 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Enable Custom Config 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbCustomConfigEnable { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbCustomConfigEnable", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 sing-box Custom Config 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbCustomConfigSingbox { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbCustomConfigSingbox", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Enable Custom DNS 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbCustomDNSEnable { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbCustomDNSEnable", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Custom DNS Enabled, This Page's Settings Invalid 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbCustomDNSEnabledPageInvalid { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbCustomDNSEnabledPageInvalid", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Display GUI 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2346,6 +2445,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 DNS Hosts: ("domain1 ip1 ip2" per line) 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbDNSHostsConfig { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbDNSHostsConfig", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Supports DNS Object; Click to view documentation 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2391,6 +2499,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Domestic DNS 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbDomesticDNS { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbDomesticDNS", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Edit 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2409,6 +2526,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 FakeIP 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbFakeIP { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbFakeIP", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Fingerprint 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2607,6 +2733,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Prevent DNS Leaks 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbPreventDNSLeaks { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbPreventDNSLeaks", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Private Key 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2634,6 +2769,24 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 v2ray Custom Config 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbRayCustomConfig { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbRayCustomConfig", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Add Outbound Config Only, routing.balancers and routing.rules.outboundTag 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbRayCustomConfigDesc { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbRayCustomConfigDesc", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Alias (remarks) 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2643,6 +2796,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Remote DNS 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbRemoteDNS { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbRemoteDNS", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Camouflage domain(host) 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -2751,6 +2913,78 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Add Outbound and Endpoint Config Only 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbSBCustomConfigDesc { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbSBCustomConfigDesc", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <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> | ||||
|  | @ -3534,6 +3768,15 @@ namespace ServiceLib.Resx { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Set Upstream Proxy Tag 的本地化字符串。 | ||||
|         /// </summary> | ||||
|         public static string TbSetUpstreamProxyDetour { | ||||
|             get { | ||||
|                 return ResourceManager.GetString("TbSetUpstreamProxyDetour", resourceCulture); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///   查找类似 Short Id 的本地化字符串。 | ||||
|         /// </summary> | ||||
|  | @ -3696,6 +3939,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> | ||||
|  | @ -3705,6 +3975,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> | ||||
|  |  | |||
|  | @ -1401,4 +1401,100 @@ | |||
|   <data name="TbMldsa65Verify" xml:space="preserve"> | ||||
|     <value>Mldsa65Verify</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> | ||||
|   <data name="FillCorrectConfigText" xml:space="preserve"> | ||||
|     <value>Please fill in the correct custom config</value> | ||||
|   </data> | ||||
|   <data name="menuCustomConfig" xml:space="preserve"> | ||||
|     <value>Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigEnable" xml:space="preserve"> | ||||
|     <value>Enable Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfig" xml:space="preserve"> | ||||
|     <value>v2ray Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigSingbox" xml:space="preserve"> | ||||
|     <value>sing-box Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value> | ||||
|   </data> | ||||
|   <data name="TbSBCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound and Endpoint Config Only</value> | ||||
|   </data> | ||||
|   <data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve"> | ||||
|     <value>Do Not Add Non-Proxy Protocol Outbound</value> | ||||
|   </data> | ||||
|   <data name="TbSetUpstreamProxyDetour" xml:space="preserve"> | ||||
|     <value>Set Upstream Proxy Tag</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1401,4 +1401,100 @@ | |||
|   <data name="TbMldsa65Verify" xml:space="preserve"> | ||||
|     <value>Mldsa65Verify</value> | ||||
|   </data> | ||||
|   <data name="menuAddAnytlsServer" xml:space="preserve"> | ||||
|     <value>[Anytls] konfiguráció hozzáadása</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> | ||||
|   <data name="FillCorrectConfigText" xml:space="preserve"> | ||||
|     <value>Please fill in the correct custom config</value> | ||||
|   </data> | ||||
|   <data name="menuCustomConfig" xml:space="preserve"> | ||||
|     <value>Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigEnable" xml:space="preserve"> | ||||
|     <value>Enable Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfig" xml:space="preserve"> | ||||
|     <value>v2ray Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigSingbox" xml:space="preserve"> | ||||
|     <value>sing-box Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value> | ||||
|   </data> | ||||
|   <data name="TbSBCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound and Endpoint Config Only</value> | ||||
|   </data> | ||||
|   <data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve"> | ||||
|     <value>Do Not Add Non-Proxy Protocol Outbound</value> | ||||
|   </data> | ||||
|   <data name="TbSetUpstreamProxyDetour" xml:space="preserve"> | ||||
|     <value>Set Upstream Proxy Tag</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1401,4 +1401,100 @@ | |||
|   <data name="TbMldsa65Verify" xml:space="preserve"> | ||||
|     <value>Mldsa65Verify</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> | ||||
|   <data name="FillCorrectConfigText" xml:space="preserve"> | ||||
|     <value>Please fill in the correct custom config</value> | ||||
|   </data> | ||||
|   <data name="menuCustomConfig" xml:space="preserve"> | ||||
|     <value>Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigEnable" xml:space="preserve"> | ||||
|     <value>Enable Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfig" xml:space="preserve"> | ||||
|     <value>v2ray Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigSingbox" xml:space="preserve"> | ||||
|     <value>sing-box Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value> | ||||
|   </data> | ||||
|   <data name="TbSBCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound and Endpoint Config Only</value> | ||||
|   </data> | ||||
|   <data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve"> | ||||
|     <value>Do Not Add Non-Proxy Protocol Outbound</value> | ||||
|   </data> | ||||
|   <data name="TbSetUpstreamProxyDetour" xml:space="preserve"> | ||||
|     <value>Set Upstream Proxy Tag</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -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> | ||||
|  | @ -1401,4 +1401,100 @@ | |||
|   <data name="TbMldsa65Verify" xml:space="preserve"> | ||||
|     <value>Mldsa65Verify</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> | ||||
|   <data name="FillCorrectConfigText" xml:space="preserve"> | ||||
|     <value>Please fill in the correct custom config</value> | ||||
|   </data> | ||||
|   <data name="menuCustomConfig" xml:space="preserve"> | ||||
|     <value>Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigEnable" xml:space="preserve"> | ||||
|     <value>Enable Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfig" xml:space="preserve"> | ||||
|     <value>v2ray Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigSingbox" xml:space="preserve"> | ||||
|     <value>sing-box Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value> | ||||
|   </data> | ||||
|   <data name="TbSBCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound and Endpoint Config Only</value> | ||||
|   </data> | ||||
|   <data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve"> | ||||
|     <value>Do Not Add Non-Proxy Protocol Outbound</value> | ||||
|   </data> | ||||
|   <data name="TbSetUpstreamProxyDetour" xml:space="preserve"> | ||||
|     <value>Set Upstream Proxy Tag</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1398,4 +1398,100 @@ | |||
|   <data name="TbMldsa65Verify" xml:space="preserve"> | ||||
|     <value>Mldsa65Verify</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> | ||||
|   <data name="FillCorrectConfigText" xml:space="preserve"> | ||||
|     <value>请填写正确的自定义配置</value> | ||||
|   </data> | ||||
|   <data name="menuCustomConfig" xml:space="preserve"> | ||||
|     <value>自定义配置</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigEnable" xml:space="preserve"> | ||||
|     <value>启用自定义配置</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfig" xml:space="preserve"> | ||||
|     <value>v2ray 自定义配置</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigSingbox" xml:space="preserve"> | ||||
|     <value>sing-box 自定义配置</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>仅添加出站配置,routing.balancers 和 routing.rules.outboundTag</value> | ||||
|   </data> | ||||
|   <data name="TbSBCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>仅添加出站和端点配置</value> | ||||
|   </data> | ||||
|   <data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve"> | ||||
|     <value>不添加非代理协议出站</value> | ||||
|   </data> | ||||
|   <data name="TbSetUpstreamProxyDetour" xml:space="preserve"> | ||||
|     <value>设置上游代理 tag</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -1398,4 +1398,100 @@ | |||
|   <data name="TbMldsa65Verify" xml:space="preserve"> | ||||
|     <value>Mldsa65Verify</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> | ||||
|   <data name="FillCorrectConfigText" xml:space="preserve"> | ||||
|     <value>Please fill in the correct custom config</value> | ||||
|   </data> | ||||
|   <data name="menuCustomConfig" xml:space="preserve"> | ||||
|     <value>Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigEnable" xml:space="preserve"> | ||||
|     <value>Enable Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfig" xml:space="preserve"> | ||||
|     <value>v2ray Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbCustomConfigSingbox" xml:space="preserve"> | ||||
|     <value>sing-box Custom Config</value> | ||||
|   </data> | ||||
|   <data name="TbRayCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value> | ||||
|   </data> | ||||
|   <data name="TbSBCustomConfigDesc" xml:space="preserve"> | ||||
|     <value>Add Outbound and Endpoint Config Only</value> | ||||
|   </data> | ||||
|   <data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve"> | ||||
|     <value>Do Not Add Non-Proxy Protocol Outbound</value> | ||||
|   </data> | ||||
|   <data name="TbSetUpstreamProxyDetour" xml:space="preserve"> | ||||
|     <value>Set Upstream Proxy Tag</value> | ||||
|   </data> | ||||
| </root> | ||||
|  | @ -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" | ||||
| 			} | ||||
| 		] | ||||
| 	} | ||||
| } | ||||
|  | @ -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" | ||||
| } | ||||
|  |  | |||
|  | @ -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" | ||||
| } | ||||
|  | @ -8,13 +8,13 @@ | |||
|       139, | ||||
|       5353 | ||||
|     ], | ||||
|     "outbound": "block" | ||||
|     "action": "reject" | ||||
|   }, | ||||
|   { | ||||
|     "ip_cidr": [ | ||||
|       "224.0.0.0/3", | ||||
|       "ff00::/8" | ||||
|     ], | ||||
|     "outbound": "block" | ||||
|     "action": "reject" | ||||
|   } | ||||
| ] | ||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,6 +1,9 @@ | |||
| using System.Net; | ||||
| using System.Net.NetworkInformation; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Nodes; | ||||
| using System.Text.Json.Serialization; | ||||
| using ServiceLib.Models; | ||||
| 
 | ||||
| namespace ServiceLib.Services.CoreConfig; | ||||
| 
 | ||||
|  | @ -66,7 +69,9 @@ public class CoreConfigV2rayService | |||
| 
 | ||||
|             ret.Msg = string.Format(ResUI.SuccessfulConfiguration, ""); | ||||
|             ret.Success = true; | ||||
|             ret.Data = JsonUtils.Serialize(v2rayConfig); | ||||
| 
 | ||||
|             var customConfig = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray); | ||||
|             ret.Data = await ApplyCustomConfig(customConfig, v2rayConfig); | ||||
|             return ret; | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|  | @ -120,7 +125,7 @@ public class CoreConfigV2rayService | |||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC) | ||||
|                 if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
|  | @ -195,7 +200,9 @@ public class CoreConfigV2rayService | |||
|             } | ||||
| 
 | ||||
|             ret.Success = true; | ||||
|             ret.Data = JsonUtils.Serialize(v2rayConfig); | ||||
| 
 | ||||
|             var customConfig = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray); | ||||
|             ret.Data = await ApplyCustomConfig(customConfig, v2rayConfig, true); | ||||
|             return ret; | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|  | @ -640,7 +647,8 @@ public class CoreConfigV2rayService | |||
|         if (node == null | ||||
|             || node.ConfigType == EConfigType.Custom | ||||
|             || node.ConfigType == EConfigType.Hysteria2 | ||||
|             || node.ConfigType == EConfigType.TUIC) | ||||
|             || node.ConfigType == EConfigType.TUIC | ||||
|             || node.ConfigType == EConfigType.Anytls) | ||||
|         { | ||||
|             return Global.ProxyTag; | ||||
|         } | ||||
|  | @ -1133,6 +1141,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 or EConfigType.Anytls) && | ||||
|                         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 | ||||
|         { | ||||
|  | @ -1175,22 +1441,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>(JsonUtils.Serialize(obj)); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|  | @ -1199,7 +1476,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) | ||||
|         { | ||||
|  | @ -1242,7 +1519,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 | ||||
|                 }; | ||||
|  | @ -1350,7 +1627,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); | ||||
|  | @ -1425,7 +1703,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); | ||||
|  | @ -1494,7 +1773,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) | ||||
|                 { | ||||
|  | @ -1564,5 +1844,83 @@ public class CoreConfigV2rayService | |||
|         return await Task.FromResult(0); | ||||
|     } | ||||
| 
 | ||||
|     private async Task<string> ApplyCustomConfig(CustomConfigItem customConfig, V2rayConfig v2rayConfig, bool handleBalancerAndRules = false) | ||||
|     { | ||||
|         if (!customConfig.Enabled || customConfig.Config.IsNullOrEmpty()) | ||||
|         { | ||||
|             return JsonUtils.Serialize(v2rayConfig); | ||||
|         } | ||||
| 
 | ||||
|         var customConfigNode = JsonNode.Parse(customConfig.Config); | ||||
|         if (customConfigNode == null) | ||||
|         { | ||||
|             return JsonUtils.Serialize(v2rayConfig); | ||||
|         } | ||||
| 
 | ||||
|         // Handle balancer and rules modifications (for multiple load scenarios) | ||||
|         if (handleBalancerAndRules && v2rayConfig.routing?.balancers?.Count > 0) | ||||
|         { | ||||
|             var balancer = v2rayConfig.routing.balancers.First(); | ||||
| 
 | ||||
|             // Modify existing rules in custom config | ||||
|             var rulesNode = customConfigNode["routing"]?["rules"]; | ||||
|             if (rulesNode != null) | ||||
|             { | ||||
|                 foreach (var rule in rulesNode.AsArray()) | ||||
|                 { | ||||
|                     if (rule["outboundTag"]?.GetValue<string>() == Global.ProxyTag) | ||||
|                     { | ||||
|                         rule.AsObject().Remove("outboundTag"); | ||||
|                         rule["balancerTag"] = balancer.tag; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // Ensure routing node exists | ||||
|             if (customConfigNode["routing"] == null) | ||||
|             { | ||||
|                 customConfigNode["routing"] = new JsonObject(); | ||||
|             } | ||||
| 
 | ||||
|             // Handle balancers - append instead of override | ||||
|             if (customConfigNode["routing"]["balancers"] is JsonArray customBalancersNode) | ||||
|             { | ||||
|                 if (JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.routing.balancers)) is JsonArray newBalancers) | ||||
|                 { | ||||
|                     foreach (var balancerNode in newBalancers) | ||||
|                     { | ||||
|                         customBalancersNode.Add(balancerNode?.DeepClone()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 customConfigNode["routing"]["balancers"] = JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.routing.balancers)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Handle outbounds - append instead of override | ||||
|         var customOutboundsNode = customConfigNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray(); | ||||
|         foreach (var outbound in v2rayConfig.outbounds) | ||||
|         { | ||||
|             if (outbound.protocol.ToLower() is "blackhole" or "dns" or "freedom") | ||||
|             { | ||||
|                 if (customConfig.AddProxyOnly == true) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
|             else if ((outbound.streamSettings?.sockopt?.dialerProxy.IsNullOrEmpty() == true) && (!customConfig.ProxyDetour.IsNullOrEmpty()) && !(Utils.IsPrivateNetwork(outbound.settings?.servers?.FirstOrDefault()?.address ?? string.Empty) || Utils.IsPrivateNetwork(outbound.settings?.vnext?.FirstOrDefault()?.address ?? string.Empty))) | ||||
|             { | ||||
|                 outbound.streamSettings ??= new StreamSettings4Ray(); | ||||
|                 outbound.streamSettings.sockopt ??= new Sockopt4Ray(); | ||||
|                 outbound.streamSettings.sockopt.dialerProxy = customConfig.ProxyDetour; | ||||
|             } | ||||
|             customOutboundsNode.Add(JsonUtils.DeepCopy(outbound)); | ||||
|         } | ||||
| 
 | ||||
|         return await Task.FromResult(JsonUtils.Serialize(customConfigNode)); | ||||
|     } | ||||
| 
 | ||||
|     #endregion private gen function | ||||
| } | ||||
|  |  | |||
|  | @ -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++) | ||||
|         { | ||||
|  |  | |||
							
								
								
									
										110
									
								
								v2rayN/ServiceLib/ViewModels/CustomConfigViewModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								v2rayN/ServiceLib/ViewModels/CustomConfigViewModel.cs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,110 @@ | |||
| using System.Reactive; | ||||
| using DynamicData.Binding; | ||||
| using ReactiveUI; | ||||
| using ReactiveUI.Fody.Helpers; | ||||
| 
 | ||||
| namespace ServiceLib.ViewModels; | ||||
| public class CustomConfigViewModel : MyReactiveObject | ||||
| { | ||||
|     #region Reactive | ||||
|     [Reactive] | ||||
|     public bool EnableCustomConfig4Ray { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public bool EnableCustomConfig4Singbox { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public string CustomConfig4Ray { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public string CustomConfig4Singbox { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public string CustomTunConfig4Singbox { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public bool AddProxyOnly4Ray { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public bool AddProxyOnly4Singbox { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public string ProxyDetour4Ray { get; set; } | ||||
| 
 | ||||
|     [Reactive] | ||||
|     public string ProxyDetour4Singbox { get; set; } | ||||
| 
 | ||||
|     public ReactiveCommand<Unit, Unit> SaveCmd { get; } | ||||
|     #endregion Reactive | ||||
| 
 | ||||
|     public CustomConfigViewModel(Func<EViewAction, object?, Task<bool>>? updateView) | ||||
|     { | ||||
|         _config = AppHandler.Instance.Config; | ||||
|         _updateView = updateView; | ||||
|         SaveCmd = ReactiveCommand.CreateFromTask(async () => | ||||
|         { | ||||
|             await SaveSettingAsync(); | ||||
|         }); | ||||
| 
 | ||||
|         _ = Init(); | ||||
|     } | ||||
|     private async Task Init() | ||||
|     { | ||||
|         var item = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray); | ||||
|         EnableCustomConfig4Ray = item?.Enabled ?? false; | ||||
|         CustomConfig4Ray = item?.Config ?? string.Empty; | ||||
|         AddProxyOnly4Ray = item?.AddProxyOnly ?? false; | ||||
|         ProxyDetour4Ray = item?.ProxyDetour ?? string.Empty; | ||||
| 
 | ||||
|         var item2 = await AppHandler.Instance.GetCustomConfigItem(ECoreType.sing_box); | ||||
|         EnableCustomConfig4Singbox = item2?.Enabled ?? false; | ||||
|         CustomConfig4Singbox = item2?.Config ?? string.Empty; | ||||
|         CustomTunConfig4Singbox = item2?.TunConfig ?? string.Empty; | ||||
|         AddProxyOnly4Singbox = item2?.AddProxyOnly ?? false; | ||||
|         ProxyDetour4Singbox = item2?.ProxyDetour ?? string.Empty; | ||||
|     } | ||||
| 
 | ||||
|     private async Task SaveSettingAsync() | ||||
|     { | ||||
|         if (!await SaveXrayConfigAsync()) | ||||
|             return; | ||||
| 
 | ||||
|         if (!await SaveSingboxConfigAsync()) | ||||
|             return; | ||||
| 
 | ||||
|         NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); | ||||
|         _ = _updateView?.Invoke(EViewAction.CloseWindow, null); | ||||
|     } | ||||
| 
 | ||||
|     private async Task<bool> SaveXrayConfigAsync() | ||||
|     { | ||||
|         var item = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray); | ||||
|         item.Enabled = EnableCustomConfig4Ray; | ||||
|         item.Config = null; | ||||
| 
 | ||||
|         item.Config = CustomConfig4Ray; | ||||
| 
 | ||||
|         item.AddProxyOnly = AddProxyOnly4Ray; | ||||
|         item.ProxyDetour = ProxyDetour4Ray; | ||||
| 
 | ||||
|         await ConfigHandler.SaveCustomConfigItem(_config, item); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     private async Task<bool> SaveSingboxConfigAsync() | ||||
|     { | ||||
|         var item = await AppHandler.Instance.GetCustomConfigItem(ECoreType.sing_box); | ||||
|         item.Enabled = EnableCustomConfig4Singbox; | ||||
|         item.Config = null; | ||||
|         item.TunConfig = null; | ||||
| 
 | ||||
|         item.Config = CustomConfig4Singbox; | ||||
|         item.TunConfig = CustomTunConfig4Singbox; | ||||
| 
 | ||||
|         item.AddProxyOnly = AddProxyOnly4Singbox; | ||||
|         item.ProxyDetour = ProxyDetour4Singbox; | ||||
| 
 | ||||
|         await ConfigHandler.SaveCustomConfigItem(_config, item); | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
|  | @ -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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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; } | ||||
|  | @ -38,6 +39,7 @@ public class MainWindowViewModel : MyReactiveObject | |||
| 
 | ||||
|     public ReactiveCommand<Unit, Unit> RoutingSettingCmd { get; } | ||||
|     public ReactiveCommand<Unit, Unit> DNSSettingCmd { get; } | ||||
|     public ReactiveCommand<Unit, Unit> CustomConfigCmd { get; } | ||||
|     public ReactiveCommand<Unit, Unit> GlobalHotkeySettingCmd { get; } | ||||
|     public ReactiveCommand<Unit, Unit> RebootAsAdminCmd { get; } | ||||
|     public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; } | ||||
|  | @ -111,6 +113,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); | ||||
|  | @ -164,6 +170,10 @@ public class MainWindowViewModel : MyReactiveObject | |||
|         { | ||||
|             await DNSSettingAsync(); | ||||
|         }); | ||||
|         CustomConfigCmd = ReactiveCommand.CreateFromTask(async () => | ||||
|         { | ||||
|             await CustomConfigAsync(); | ||||
|         }); | ||||
|         GlobalHotkeySettingCmd = ReactiveCommand.CreateFromTask(async () => | ||||
|         { | ||||
|             if (await _updateView?.Invoke(EViewAction.GlobalHotkeySettingWindow, null) == true) | ||||
|  | @ -215,6 +225,7 @@ public class MainWindowViewModel : MyReactiveObject | |||
| 
 | ||||
|         await ConfigHandler.InitBuiltinRouting(_config); | ||||
|         await ConfigHandler.InitBuiltinDNS(_config); | ||||
|         await ConfigHandler.InitBuiltinCustomConfig(_config); | ||||
|         await ProfileExHandler.Instance.Init(); | ||||
|         await CoreHandler.Instance.Init(_config, UpdateHandler); | ||||
|         TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler); | ||||
|  | @ -503,6 +514,15 @@ public class MainWindowViewModel : MyReactiveObject | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private async Task CustomConfigAsync() | ||||
|     { | ||||
|         var ret = await _updateView?.Invoke(EViewAction.CustomConfigWindow, null); | ||||
|         if (ret == true) | ||||
|         { | ||||
|             await Reload(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public async Task RebootAsAdmin() | ||||
|     { | ||||
|         ProcUtils.RebootAsAdmin(); | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -102,6 +102,12 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel> | |||
|                 gridTls.IsVisible = false; | ||||
| 
 | ||||
|                 break; | ||||
| 
 | ||||
|             case EConfigType.Anytls: | ||||
|                 gridAnytls.IsVisible = true; | ||||
|                 lstStreamSecurity.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); | ||||
|  |  | |||
							
								
								
									
										182
									
								
								v2rayN/v2rayN.Desktop/Views/CustomConfigWindow.axaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								v2rayN/v2rayN.Desktop/Views/CustomConfigWindow.axaml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,182 @@ | |||
| <Window | ||||
|     x:Class="v2rayN.Desktop.Views.CustomConfigWindow" | ||||
|     xmlns="https://github.com/avaloniaui" | ||||
|     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||
|     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" | ||||
|     xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" | ||||
|     Title="{x:Static resx:ResUI.menuCustomConfig}" | ||||
|     Width="900" | ||||
|     Height="600" | ||||
|     x:DataType="vms:CustomConfigViewModel" | ||||
|     ShowInTaskbar="False" | ||||
|     WindowStartupLocation="CenterScreen" | ||||
|     mc:Ignorable="d"> | ||||
|     <DockPanel Margin="{StaticResource Margin8}"> | ||||
|         <StackPanel | ||||
|             Margin="{StaticResource Margin4}" | ||||
|             HorizontalAlignment="Center" | ||||
|             DockPanel.Dock="Bottom" | ||||
|             Orientation="Horizontal"> | ||||
|             <Button | ||||
|                 x:Name="btnSave" | ||||
|                 Width="100" | ||||
|                 Content="{x:Static resx:ResUI.TbConfirm}" | ||||
|                 Cursor="Hand" | ||||
|                 IsDefault="True" /> | ||||
|             <Button | ||||
|                 x:Name="btnCancel" | ||||
|                 Width="100" | ||||
|                 Margin="{StaticResource MarginLr8}" | ||||
|                 Content="{x:Static resx:ResUI.TbCancel}" | ||||
|                 Cursor="Hand" | ||||
|                 IsCancel="True" /> | ||||
|         </StackPanel> | ||||
| 
 | ||||
|         <TabControl HorizontalContentAlignment="Stretch"> | ||||
|             <TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRayCustomConfig}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin4}"> | ||||
|                     <Grid DockPanel.Dock="Top" RowDefinitions="Auto,Auto"> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="0" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Grid.Row="0" | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbRayCustomConfigDesc}" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="1" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbCustomConfigEnable}" /> | ||||
|                             <ToggleSwitch | ||||
|                                 x:Name="rayCustomConfigEnable" | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
|                     </Grid> | ||||
| 
 | ||||
|                     <WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal"> | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbAddProxyProtocolOutboundOnly}" /> | ||||
|                             <ToggleSwitch | ||||
|                                 x:Name="togAddProxyProtocolOutboundOnly4Ray" | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbSetUpstreamProxyDetour}" /> | ||||
|                             <TextBox | ||||
|                                 x:Name="txtProxyDetour4Ray" | ||||
|                                 Width="200" | ||||
|                                 Margin="{StaticResource Margin4}" /> | ||||
|                         </StackPanel> | ||||
|                     </WrapPanel> | ||||
| 
 | ||||
|                     <HeaderedContentControl | ||||
|                         Margin="{StaticResource Margin4}" | ||||
|                         BorderBrush="Gray" | ||||
|                         BorderThickness="1" | ||||
|                         Header="xray json config"> | ||||
|                         <TextBox | ||||
|                             x:Name="rayCustomConfig" | ||||
|                             VerticalAlignment="Stretch" | ||||
|                             Classes="TextArea" | ||||
|                             MinLines="10" | ||||
|                             TextWrapping="Wrap" /> | ||||
|                     </HeaderedContentControl> | ||||
|                 </DockPanel> | ||||
|             </TabItem> | ||||
|             <TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbCustomConfigSingbox}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin4}"> | ||||
|                     <Grid DockPanel.Dock="Top" RowDefinitions="Auto,Auto"> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="0" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Grid.Row="0" | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbSBCustomConfigDesc}" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="1" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbCustomConfigEnable}" /> | ||||
|                             <ToggleSwitch | ||||
|                                 x:Name="sbCustomConfigEnable" | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
|                     </Grid> | ||||
| 
 | ||||
|                     <WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal"> | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbAddProxyProtocolOutboundOnly}" /> | ||||
|                             <ToggleSwitch | ||||
|                                 x:Name="togAddProxyProtocolOutboundOnly4Singbox" | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin4}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Text="{x:Static resx:ResUI.TbSetUpstreamProxyDetour}" /> | ||||
|                             <TextBox | ||||
|                                 x:Name="txtProxyDetour4Singbox" | ||||
|                                 Width="200" | ||||
|                                 Margin="{StaticResource Margin4}" /> | ||||
|                         </StackPanel> | ||||
|                     </WrapPanel> | ||||
| 
 | ||||
|                     <Grid Margin="{StaticResource Margin4}" ColumnDefinitions="*,10,*"> | ||||
| 
 | ||||
|                         <HeaderedContentControl | ||||
|                             Grid.Column="0" | ||||
|                             BorderBrush="Gray" | ||||
|                             BorderThickness="1" | ||||
|                             Header="sing-box json config"> | ||||
|                             <TextBox | ||||
|                                 x:Name="sbCustomConfig" | ||||
|                                 VerticalAlignment="Stretch" | ||||
|                                 Classes="TextArea" | ||||
|                                 MinLines="10" | ||||
|                                 TextWrapping="Wrap" /> | ||||
|                         </HeaderedContentControl> | ||||
| 
 | ||||
|                         <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> | ||||
| 
 | ||||
|                         <HeaderedContentControl | ||||
|                             Grid.Column="2" | ||||
|                             BorderBrush="Gray" | ||||
|                             BorderThickness="1" | ||||
|                             Header="sing-box json tun config"> | ||||
|                             <TextBox | ||||
|                                 x:Name="sbCustomTunConfig" | ||||
|                                 VerticalAlignment="Stretch" | ||||
|                                 Classes="TextArea" | ||||
|                                 MinLines="10" | ||||
|                                 TextWrapping="Wrap" /> | ||||
|                         </HeaderedContentControl> | ||||
|                     </Grid> | ||||
|                 </DockPanel> | ||||
|             </TabItem> | ||||
|         </TabControl> | ||||
|     </DockPanel> | ||||
| </Window> | ||||
							
								
								
									
										46
									
								
								v2rayN/v2rayN.Desktop/Views/CustomConfigWindow.axaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								v2rayN/v2rayN.Desktop/Views/CustomConfigWindow.axaml.cs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| using System.Reactive.Disposables; | ||||
| using Avalonia.Interactivity; | ||||
| using ReactiveUI; | ||||
| using v2rayN.Desktop.Base; | ||||
| 
 | ||||
| namespace v2rayN.Desktop.Views; | ||||
| 
 | ||||
| public partial class CustomConfigWindow : WindowBase<CustomConfigViewModel> | ||||
| { | ||||
|     private static Config _config; | ||||
| 
 | ||||
|     public CustomConfigWindow() | ||||
|     { | ||||
|         InitializeComponent(); | ||||
| 
 | ||||
|         _config = AppHandler.Instance.Config; | ||||
|         btnCancel.Click += (s, e) => this.Close(); | ||||
|         ViewModel = new CustomConfigViewModel(UpdateViewHandler); | ||||
| 
 | ||||
|         this.WhenActivated(disposables => | ||||
|         { | ||||
|             this.Bind(ViewModel, vm => vm.EnableCustomConfig4Ray, v => v.rayCustomConfigEnable.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.CustomConfig4Ray, v => v.rayCustomConfig.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.AddProxyOnly4Ray, v => v.togAddProxyProtocolOutboundOnly4Ray.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.ProxyDetour4Ray, v => v.txtProxyDetour4Ray.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.EnableCustomConfig4Singbox, v => v.sbCustomConfigEnable.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.CustomConfig4Singbox, v => v.sbCustomConfig.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.CustomTunConfig4Singbox, v => v.sbCustomTunConfig.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.AddProxyOnly4Singbox, v => v.togAddProxyProtocolOutboundOnly4Singbox.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.ProxyDetour4Singbox, v => v.txtProxyDetour4Singbox.Text).DisposeWith(disposables); | ||||
| 
 | ||||
|             this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) | ||||
|     { | ||||
|         switch (action) | ||||
|         { | ||||
|             case EViewAction.CloseWindow: | ||||
|                 this.Close(true); | ||||
|                 break; | ||||
|         } | ||||
|         return await Task.FromResult(true); | ||||
|     } | ||||
| } | ||||
|  | @ -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,25 +36,298 @@ | |||
|         </StackPanel> | ||||
| 
 | ||||
|         <TabControl HorizontalContentAlignment="Stretch"> | ||||
|             <TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin8}"> | ||||
|                     <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> | ||||
|             <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.TbSettingsRemoteDNS}" /> | ||||
|                             Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" /> | ||||
|                          | ||||
|                         <TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center"> | ||||
|                             <HyperlinkButton Classes="WithIcon" Click="linkDnsObjectDoc_Click"> | ||||
|                                 <TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" /> | ||||
|                             </HyperlinkButton> | ||||
|                         </TextBlock> | ||||
|                         <Button | ||||
|                             x:Name="btnImportDefConfig4V2ray" | ||||
|                         <TextBlock | ||||
|                             Grid.Row="1" | ||||
|                             Grid.Column="0" | ||||
|                             Margin="{StaticResource Margin4}" | ||||
|                             Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}" | ||||
|                             Cursor="Hand" /> | ||||
|                     </StackPanel> | ||||
|                             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}"> | ||||
|                     <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" | ||||
|                                 Text="{x:Static resx:ResUI.TbSettingsRemoteDNS}" /> | ||||
| 
 | ||||
|                             <TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center"> | ||||
|                                 <HyperlinkButton Classes="WithIcon" Click="linkDnsObjectDoc_Click"> | ||||
|                                     <TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" /> | ||||
|                                 </HyperlinkButton> | ||||
|                             </TextBlock> | ||||
|                             <Button | ||||
|                                 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"> | ||||
|                         <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" | ||||
|                             Margin="{StaticResource Margin4}" | ||||
|                             Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}" | ||||
|                             Cursor="Hand" /> | ||||
|                     </StackPanel> | ||||
|                     <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="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" | ||||
|  |  | |||
|  | @ -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); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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"> | ||||
|  | @ -71,6 +72,7 @@ | |||
|                         <MenuItem x:Name="menuOptionSetting" Header="{x:Static resx:ResUI.menuOptionSetting}" /> | ||||
|                         <MenuItem x:Name="menuRoutingSetting" Header="{x:Static resx:ResUI.menuRoutingSetting}" /> | ||||
|                         <MenuItem x:Name="menuDNSSetting" Header="{x:Static resx:ResUI.menuDNSSetting}" /> | ||||
|                         <MenuItem x:Name="menuCustomConfig" Header="{x:Static resx:ResUI.menuCustomConfig}" /> | ||||
|                         <MenuItem x:Name="menuGlobalHotkeySetting" Header="{x:Static resx:ResUI.menuGlobalHotkeySetting}" /> | ||||
|                         <Separator /> | ||||
|                         <MenuItem x:Name="menuRebootAsAdmin" Header="{x:Static resx:ResUI.menuRebootAsAdmin}" /> | ||||
|  |  | |||
|  | @ -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); | ||||
|  | @ -99,6 +100,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel> | |||
|             this.BindCommand(ViewModel, vm => vm.OptionSettingCmd, v => v.menuOptionSetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.RoutingSettingCmd, v => v.menuRoutingSetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.DNSSettingCmd, v => v.menuDNSSetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.CustomConfigCmd, v => v.menuCustomConfig).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.GlobalHotkeySettingCmd, v => v.menuGlobalHotkeySetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.RebootAsAdminCmd, v => v.menuRebootAsAdmin).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables); | ||||
|  | @ -189,6 +191,9 @@ public partial class MainWindow : WindowBase<MainWindowViewModel> | |||
|             case EViewAction.DNSSettingWindow: | ||||
|                 return await new DNSSettingWindow().ShowDialog<bool>(this); | ||||
| 
 | ||||
|             case EViewAction.CustomConfigWindow: | ||||
|                 return await new CustomConfigWindow().ShowDialog<bool>(this); | ||||
| 
 | ||||
|             case EViewAction.RoutingSettingWindow: | ||||
|                 return await new RoutingSettingWindow().ShowDialog<bool>(this); | ||||
| 
 | ||||
|  |  | |||
|  | @ -117,7 +117,7 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel> | |||
| 
 | ||||
|     private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e) | ||||
|     { | ||||
|         ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy"); | ||||
|         ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy"); | ||||
|     } | ||||
| 
 | ||||
|     private void btnCancel_Click(object? sender, RoutedEventArgs e) | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -96,6 +96,12 @@ public partial class AddServerWindow | |||
|                 gridTls.Visibility = Visibility.Collapsed; | ||||
| 
 | ||||
|                 break; | ||||
| 
 | ||||
|             case EConfigType.Anytls: | ||||
|                 gridAnytls.Visibility = Visibility.Visible; | ||||
|                 cmbCoreType.IsEnabled = false; | ||||
|                 lstStreamSecurity.Add(Global.StreamSecurityReality); | ||||
|                 break; | ||||
|         } | ||||
|         cmbStreamSecurity.ItemsSource = lstStreamSecurity; | ||||
| 
 | ||||
|  | @ -161,6 +167,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); | ||||
|  |  | |||
							
								
								
									
										205
									
								
								v2rayN/v2rayN/Views/CustomConfigWindow.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								v2rayN/v2rayN/Views/CustomConfigWindow.xaml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,205 @@ | |||
| <base:WindowBase | ||||
|     x:Class="v2rayN.Views.CustomConfigWindow" | ||||
|     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||
|     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||
|     xmlns:base="clr-namespace:v2rayN.Base" | ||||
|     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||||
|     xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" | ||||
|     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||||
|     xmlns:reactiveui="http://reactiveui.net" | ||||
|     xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" | ||||
|     xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" | ||||
|     Title="{x:Static resx:ResUI.menuCustomConfig}" | ||||
|     Width="1000" | ||||
|     Height="700" | ||||
|     x:TypeArguments="vms:CustomConfigViewModel" | ||||
|     ShowInTaskbar="False" | ||||
|     Style="{StaticResource WindowGlobal}" | ||||
|     WindowStartupLocation="CenterScreen" | ||||
|     mc:Ignorable="d"> | ||||
|     <DockPanel Margin="{StaticResource Margin8}"> | ||||
|         <StackPanel | ||||
|             Margin="{StaticResource Margin4}" | ||||
|             HorizontalAlignment="Center" | ||||
|             DockPanel.Dock="Bottom" | ||||
|             Orientation="Horizontal"> | ||||
|             <Button | ||||
|                 x:Name="btnSave" | ||||
|                 Width="100" | ||||
|                 Content="{x:Static resx:ResUI.TbConfirm}" | ||||
|                 Cursor="Hand" | ||||
|                 IsDefault="True" | ||||
|                 Style="{StaticResource DefButton}" /> | ||||
|             <Button | ||||
|                 x:Name="btnCancel" | ||||
|                 Width="100" | ||||
|                 Margin="{StaticResource MarginLeftRight8}" | ||||
|                 Content="{x:Static resx:ResUI.TbCancel}" | ||||
|                 Cursor="Hand" | ||||
|                 IsCancel="true" | ||||
|                 Style="{StaticResource DefButton}" /> | ||||
|         </StackPanel> | ||||
| 
 | ||||
|         <TabControl HorizontalContentAlignment="Left"> | ||||
|             <TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRayCustomConfig}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin8}"> | ||||
|                     <Grid DockPanel.Dock="Top"> | ||||
|                         <Grid.RowDefinitions> | ||||
|                             <RowDefinition Height="Auto" /> | ||||
|                             <RowDefinition Height="Auto" /> | ||||
|                         </Grid.RowDefinitions> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="0" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Grid.Row="0" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbRayCustomConfigDesc}" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="1" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbCustomConfigEnable}" /> | ||||
|                             <ToggleButton | ||||
|                                 x:Name="rayCustomConfigEnable" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
|                     </Grid> | ||||
| 
 | ||||
|                     <WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal"> | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbAddProxyProtocolOutboundOnly}" /> | ||||
|                             <ToggleButton | ||||
|                                 x:Name="togAddProxyProtocolOutboundOnly4Ray" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbSetUpstreamProxyDetour}" /> | ||||
|                             <TextBox | ||||
|                                 x:Name="txtProxyDetour4Ray" | ||||
|                                 Width="200" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 Style="{StaticResource DefTextBox}" /> | ||||
|                         </StackPanel> | ||||
|                     </WrapPanel> | ||||
| 
 | ||||
|                     <TextBox | ||||
|                         x:Name="rayCustomConfig" | ||||
|                         Margin="{StaticResource Margin8}" | ||||
|                         VerticalAlignment="Stretch" | ||||
|                         materialDesign:HintAssist.Hint="xray json config" | ||||
|                         AcceptsReturn="True" | ||||
|                         BorderThickness="1" | ||||
|                         Style="{StaticResource MaterialDesignOutlinedTextBox}" | ||||
|                         TextWrapping="Wrap" | ||||
|                         VerticalScrollBarVisibility="Auto" /> | ||||
|                 </DockPanel> | ||||
|             </TabItem> | ||||
|             <TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbCustomConfigSingbox}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin8}"> | ||||
|                     <Grid DockPanel.Dock="Top"> | ||||
|                         <Grid.RowDefinitions> | ||||
|                             <RowDefinition Height="Auto" /> | ||||
|                             <RowDefinition Height="Auto" /> | ||||
|                         </Grid.RowDefinitions> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="0" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Grid.Row="0" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbSBCustomConfigDesc}" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Grid.Row="1" Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbCustomConfigEnable}" /> | ||||
|                             <ToggleButton | ||||
|                                 x:Name="sbCustomConfigEnable" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
|                     </Grid> | ||||
| 
 | ||||
|                     <WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal"> | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbAddProxyProtocolOutboundOnly}" /> | ||||
|                             <ToggleButton | ||||
|                                 x:Name="togAddProxyProtocolOutboundOnly4Singbox" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 HorizontalAlignment="Left" /> | ||||
|                         </StackPanel> | ||||
| 
 | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbSetUpstreamProxyDetour}" /> | ||||
|                             <TextBox | ||||
|                                 x:Name="txtProxyDetour4Singbox" | ||||
|                                 Width="200" | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 Style="{StaticResource DefTextBox}" /> | ||||
|                         </StackPanel> | ||||
|                     </WrapPanel> | ||||
| 
 | ||||
|                     <Grid Margin="{StaticResource Margin8}"> | ||||
|                         <Grid.ColumnDefinitions> | ||||
|                             <ColumnDefinition Width="1*" /> | ||||
|                             <ColumnDefinition Width="10" /> | ||||
|                             <ColumnDefinition Width="1*" /> | ||||
|                         </Grid.ColumnDefinitions> | ||||
| 
 | ||||
|                         <TextBox | ||||
|                             x:Name="sbCustomConfig" | ||||
|                             Grid.Column="0" | ||||
|                             VerticalAlignment="Stretch" | ||||
|                             materialDesign:HintAssist.Hint="sing-box json config" | ||||
|                             AcceptsReturn="True" | ||||
|                             BorderThickness="1" | ||||
|                             Style="{StaticResource MaterialDesignOutlinedTextBox}" | ||||
|                             TextWrapping="Wrap" | ||||
|                             VerticalScrollBarVisibility="Auto" /> | ||||
| 
 | ||||
|                         <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> | ||||
| 
 | ||||
|                         <TextBox | ||||
|                             x:Name="sbCustomTunConfig" | ||||
|                             Grid.Column="2" | ||||
|                             VerticalAlignment="Stretch" | ||||
|                             materialDesign:HintAssist.Hint="sing-box json tun config" | ||||
|                             AcceptsReturn="True" | ||||
|                             BorderThickness="1" | ||||
|                             Style="{StaticResource MaterialDesignOutlinedTextBox}" | ||||
|                             TextWrapping="Wrap" | ||||
|                             VerticalScrollBarVisibility="Auto" /> | ||||
|                     </Grid> | ||||
|                 </DockPanel> | ||||
|             </TabItem> | ||||
|         </TabControl> | ||||
|     </DockPanel> | ||||
| </base:WindowBase> | ||||
							
								
								
									
										47
									
								
								v2rayN/v2rayN/Views/CustomConfigWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								v2rayN/v2rayN/Views/CustomConfigWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | |||
| using System.Reactive.Disposables; | ||||
| using System.Windows; | ||||
| using ReactiveUI; | ||||
| 
 | ||||
| namespace v2rayN.Views; | ||||
| 
 | ||||
| public partial class CustomConfigWindow | ||||
| { | ||||
|     private static Config _config; | ||||
| 
 | ||||
|     public CustomConfigWindow() | ||||
|     { | ||||
|         InitializeComponent(); | ||||
| 
 | ||||
|         this.Owner = Application.Current.MainWindow; | ||||
|         _config = AppHandler.Instance.Config; | ||||
| 
 | ||||
|         ViewModel = new CustomConfigViewModel(UpdateViewHandler); | ||||
| 
 | ||||
|         this.WhenActivated(disposables => | ||||
|         { | ||||
|             this.Bind(ViewModel, vm => vm.EnableCustomConfig4Ray, v => v.rayCustomConfigEnable.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.CustomConfig4Ray, v => v.rayCustomConfig.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.AddProxyOnly4Ray, v => v.togAddProxyProtocolOutboundOnly4Ray.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.ProxyDetour4Ray, v => v.txtProxyDetour4Ray.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.EnableCustomConfig4Singbox, v => v.sbCustomConfigEnable.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.CustomConfig4Singbox, v => v.sbCustomConfig.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.CustomTunConfig4Singbox, v => v.sbCustomTunConfig.Text).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.AddProxyOnly4Singbox, v => v.togAddProxyProtocolOutboundOnly4Singbox.IsChecked).DisposeWith(disposables); | ||||
|             this.Bind(ViewModel, vm => vm.ProxyDetour4Singbox, v => v.txtProxyDetour4Singbox.Text).DisposeWith(disposables); | ||||
| 
 | ||||
|             this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); | ||||
|         }); | ||||
|         WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme); | ||||
|     } | ||||
| 
 | ||||
|     private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) | ||||
|     { | ||||
|         switch (action) | ||||
|         { | ||||
|             case EViewAction.CloseWindow: | ||||
|                 this.DialogResult = true; | ||||
|                 break; | ||||
|         } | ||||
|         return await Task.FromResult(true); | ||||
|     } | ||||
| } | ||||
|  | @ -41,31 +41,361 @@ | |||
|         </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> | ||||
| 
 | ||||
|             <TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin8}"> | ||||
|                     <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> | ||||
|                         <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.TbSettingsRemoteDNS}" /> | ||||
|                             Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" /> | ||||
| 
 | ||||
|                         <TextBlock | ||||
|                             Grid.Row="1" | ||||
|                             Grid.Column="0" | ||||
|                             Margin="{StaticResource Margin8}" | ||||
|                             VerticalAlignment="Center" | ||||
|                             Style="{StaticResource ToolbarTextBlock}"> | ||||
|                             <Hyperlink Click="linkDnsObjectDoc_Click"> | ||||
|                                 <TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" /> | ||||
|                                 <materialDesign:PackIcon Kind="Link" /> | ||||
|                             </Hyperlink> | ||||
|                         </TextBlock> | ||||
|                         <Button | ||||
|                             x:Name="btnImportDefConfig4V2ray" | ||||
|                             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}" | ||||
|                             Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}" | ||||
|                             Cursor="Hand" | ||||
|                             Style="{StaticResource DefButton}" /> | ||||
|                     </StackPanel> | ||||
|                             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}"> | ||||
|                     <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" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}" | ||||
|                                 Text="{x:Static resx:ResUI.TbSettingsRemoteDNS}" /> | ||||
|                             <TextBlock | ||||
|                                 Margin="{StaticResource Margin8}" | ||||
|                                 VerticalAlignment="Center" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}"> | ||||
|                                 <Hyperlink Click="linkDnsObjectDoc_Click"> | ||||
|                                     <TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" /> | ||||
|                                     <materialDesign:PackIcon Kind="Link" /> | ||||
|                                 </Hyperlink> | ||||
|                             </TextBlock> | ||||
|                             <Button | ||||
|                                 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,23 +453,42 @@ | |||
| 
 | ||||
|             <TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}"> | ||||
|                 <DockPanel Margin="{StaticResource Margin8}"> | ||||
|                     <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> | ||||
|                         <TextBlock | ||||
|                             Margin="{StaticResource Margin8}" | ||||
|                             VerticalAlignment="Center" | ||||
|                             Style="{StaticResource ToolbarTextBlock}"> | ||||
|                             <Hyperlink Click="linkDnsSingboxObjectDoc_Click"> | ||||
|                                 <TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" /> | ||||
|                                 <materialDesign:PackIcon Kind="Link" /> | ||||
|                             </Hyperlink> | ||||
|                         </TextBlock> | ||||
|                         <Button | ||||
|                             x:Name="btnImportDefConfig4Singbox" | ||||
|                             Margin="{StaticResource Margin8}" | ||||
|                             Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}" | ||||
|                             Cursor="Hand" | ||||
|                             Style="{StaticResource DefButton}" /> | ||||
|                     </StackPanel> | ||||
|                     <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" | ||||
|                                 Style="{StaticResource ToolbarTextBlock}"> | ||||
|                                 <Hyperlink Click="linkDnsSingboxObjectDoc_Click"> | ||||
|                                     <TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" /> | ||||
|                                     <materialDesign:PackIcon Kind="Link" /> | ||||
|                                 </Hyperlink> | ||||
|                             </TextBlock> | ||||
|                             <Button | ||||
|                                 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}" | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
|  |  | |||
|  | @ -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 /> | ||||
|  | @ -169,6 +173,10 @@ | |||
|                                     x:Name="menuDNSSetting" | ||||
|                                     Height="{StaticResource MenuItemHeight}" | ||||
|                                     Header="{x:Static resx:ResUI.menuDNSSetting}" /> | ||||
|                                 <MenuItem | ||||
|                                     x:Name="menuCustomConfig" | ||||
|                                     Height="{StaticResource MenuItemHeight}" | ||||
|                                     Header="{x:Static resx:ResUI.menuCustomConfig}" /> | ||||
|                                 <MenuItem | ||||
|                                     x:Name="menuGlobalHotkeySetting" | ||||
|                                     Height="{StaticResource MenuItemHeight}" | ||||
|  |  | |||
|  | @ -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); | ||||
|  | @ -96,6 +97,7 @@ public partial class MainWindow | |||
|             this.BindCommand(ViewModel, vm => vm.OptionSettingCmd, v => v.menuOptionSetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.RoutingSettingCmd, v => v.menuRoutingSetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.DNSSettingCmd, v => v.menuDNSSetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.CustomConfigCmd, v => v.menuCustomConfig).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.GlobalHotkeySettingCmd, v => v.menuGlobalHotkeySetting).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.RebootAsAdminCmd, v => v.menuRebootAsAdmin).DisposeWith(disposables); | ||||
|             this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables); | ||||
|  | @ -185,6 +187,9 @@ public partial class MainWindow | |||
|             case EViewAction.OptionSettingWindow: | ||||
|                 return (new OptionSettingWindow().ShowDialog() ?? false); | ||||
| 
 | ||||
|             case EViewAction.CustomConfigWindow: | ||||
|                 return (new CustomConfigWindow().ShowDialog() ?? false); | ||||
| 
 | ||||
|             case EViewAction.GlobalHotkeySettingWindow: | ||||
|                 return (new GlobalHotkeySettingWindow().ShowDialog() ?? false); | ||||
| 
 | ||||
|  |  | |||
|  | @ -122,7 +122,7 @@ public partial class RoutingSettingWindow | |||
| 
 | ||||
|     private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e) | ||||
|     { | ||||
|         ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy"); | ||||
|         ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy"); | ||||
|     } | ||||
| 
 | ||||
|     private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 DHR60
						DHR60