mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-29 11:32:53 +00:00
Compare commits
15 commits
cf503da469
...
5c2370edb8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c2370edb8 | ||
|
|
10ac9cfeea | ||
|
|
916e6d2050 | ||
|
|
b2f9ec4464 | ||
|
|
7b650383d7 | ||
|
|
3101f2f8b6 | ||
|
|
105701ed9f | ||
|
|
4367f02a74 | ||
|
|
fe4710a8fd | ||
|
|
dffc6d9a9b | ||
|
|
c9989108bd | ||
|
|
386c86bfa6 | ||
|
|
925cf16c50 | ||
|
|
c561916b67 | ||
|
|
d41a73b44b |
40 changed files with 2705 additions and 696 deletions
|
|
@ -128,5 +128,8 @@ public class JsonUtils
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="obj"></param>
|
/// <param name="obj"></param>
|
||||||
/// <returns></returns>
|
/// <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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public enum EViewAction
|
||||||
DNSSettingWindow,
|
DNSSettingWindow,
|
||||||
RoutingSettingWindow,
|
RoutingSettingWindow,
|
||||||
OptionSettingWindow,
|
OptionSettingWindow,
|
||||||
CustomConfigWindow,
|
FullConfigTemplateWindow,
|
||||||
GlobalHotkeySettingWindow,
|
GlobalHotkeySettingWindow,
|
||||||
SubSettingWindow,
|
SubSettingWindow,
|
||||||
DispatcherSpeedTest,
|
DispatcherSpeedTest,
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,13 @@ public class Global
|
||||||
public const int SpeedTestPageSize = 1000;
|
public const int SpeedTestPageSize = 1000;
|
||||||
public const string LinuxBash = "/bin/bash";
|
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 =
|
public static readonly List<string> IEProxyProtocols =
|
||||||
[
|
[
|
||||||
"{ip}:{http_port}",
|
"{ip}:{http_port}",
|
||||||
|
|
@ -131,22 +138,22 @@ public class Global
|
||||||
public static readonly List<string> SingboxRulesetSources =
|
public static readonly List<string> SingboxRulesetSources =
|
||||||
[
|
[
|
||||||
"",
|
"",
|
||||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-rules-dat@release/sing-box/rule-set-{0}/{1}.srs",
|
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/release/sing-box/rule-set-{0}/{1}.srs",
|
||||||
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-sing-box-rules@rule-set/{1}.srs"
|
@"https://raw.githubusercontent.com/chocolate4u/Iran-sing-box-rules/rule-set/{1}.srs"
|
||||||
];
|
];
|
||||||
|
|
||||||
public static readonly List<string> RoutingRulesSources =
|
public static readonly List<string> RoutingRulesSources =
|
||||||
[
|
[
|
||||||
"",
|
"",
|
||||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/template.json",
|
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-custom-routing-list/main/v2rayN/template.json",
|
||||||
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/template.json"
|
@"https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/main/v2rayN/template.json"
|
||||||
];
|
];
|
||||||
|
|
||||||
public static readonly List<string> DNSTemplateSources =
|
public static readonly List<string> DNSTemplateSources =
|
||||||
[
|
[
|
||||||
"",
|
"",
|
||||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/",
|
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-custom-routing-list/main/v2rayN/",
|
||||||
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/"
|
@"https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/main/v2rayN/"
|
||||||
];
|
];
|
||||||
|
|
||||||
public static readonly Dictionary<string, string> UserAgentTexts = new()
|
public static readonly Dictionary<string, string> UserAgentTexts = new()
|
||||||
|
|
@ -351,25 +358,42 @@ public class Global
|
||||||
|
|
||||||
public static readonly List<string> SingboxDomainStrategy4Out =
|
public static readonly List<string> SingboxDomainStrategy4Out =
|
||||||
[
|
[
|
||||||
|
"",
|
||||||
"ipv4_only",
|
"ipv4_only",
|
||||||
"prefer_ipv4",
|
"prefer_ipv4",
|
||||||
"prefer_ipv6",
|
"prefer_ipv6",
|
||||||
"ipv6_only",
|
"ipv6_only"
|
||||||
""
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public static readonly List<string> DomainDNSAddress =
|
public static readonly List<string> DomainDirectDNSAddress =
|
||||||
[
|
[
|
||||||
|
"https://dns.alidns.com/dns-query",
|
||||||
|
"https://doh.pub/dns-query",
|
||||||
"223.5.5.5",
|
"223.5.5.5",
|
||||||
"223.6.6.6",
|
"119.29.29.29",
|
||||||
"localhost"
|
"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.5.5.5",
|
||||||
"223.6.6.6",
|
"119.29.29.29",
|
||||||
"dhcp://auto"
|
"localhost"
|
||||||
];
|
];
|
||||||
|
|
||||||
public static readonly List<string> Languages =
|
public static readonly List<string> Languages =
|
||||||
|
|
@ -539,5 +563,30 @@ public class Global
|
||||||
BlockTag
|
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
|
#endregion const
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ public sealed class AppHandler
|
||||||
SQLiteHelper.Instance.CreateTable<RoutingItem>();
|
SQLiteHelper.Instance.CreateTable<RoutingItem>();
|
||||||
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
|
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
|
||||||
SQLiteHelper.Instance.CreateTable<DNSItem>();
|
SQLiteHelper.Instance.CreateTable<DNSItem>();
|
||||||
SQLiteHelper.Instance.CreateTable<CustomConfigItem>();
|
SQLiteHelper.Instance.CreateTable<FullConfigTemplateItem>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,14 +204,14 @@ public sealed class AppHandler
|
||||||
return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<CustomConfigItem>?> CustomConfigItem()
|
public async Task<List<FullConfigTemplateItem>?> FullConfigTemplateItem()
|
||||||
{
|
{
|
||||||
return await SQLiteHelper.Instance.TableAsync<CustomConfigItem>().ToListAsync();
|
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CustomConfigItem?> GetCustomConfigItem(ECoreType eCoreType)
|
public async Task<FullConfigTemplateItem?> GetFullConfigTemplateItem(ECoreType eCoreType)
|
||||||
{
|
{
|
||||||
return await SQLiteHelper.Instance.TableAsync<CustomConfigItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion SqliteHelper
|
#endregion SqliteHelper
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,8 @@ public class ConfigHandler
|
||||||
|
|
||||||
config.ConstItem ??= new ConstItem();
|
config.ConstItem ??= new ConstItem();
|
||||||
|
|
||||||
|
config.SimpleDNSItem ??= InitBuiltinSimpleDNS();
|
||||||
|
|
||||||
config.SpeedTestItem ??= new();
|
config.SpeedTestItem ??= new();
|
||||||
if (config.SpeedTestItem.SpeedTestTimeout < 10)
|
if (config.SpeedTestItem.SpeedTestTimeout < 10)
|
||||||
{
|
{
|
||||||
|
|
@ -2094,18 +2096,38 @@ public class ConfigHandler
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize built-in DNS configurations
|
/// Initialize built-in DNS configurations
|
||||||
/// Creates default DNS items for V2Ray and sing-box
|
/// Creates default DNS items for V2Ray and sing-box
|
||||||
|
/// Also checks existing DNS items and disables those with empty NormalDNS
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config">Current configuration</param>
|
/// <param name="config">Current configuration</param>
|
||||||
/// <returns>0 if successful</returns>
|
/// <returns>0 if successful</returns>
|
||||||
public static async Task<int> InitBuiltinDNS(Config config)
|
public static async Task<int> InitBuiltinDNS(Config config)
|
||||||
{
|
{
|
||||||
var items = await AppHandler.Instance.DNSItems();
|
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)
|
if (items.Count <= 0)
|
||||||
{
|
{
|
||||||
var item = new DNSItem()
|
var item = new DNSItem()
|
||||||
{
|
{
|
||||||
Remarks = "V2ray",
|
Remarks = "V2ray",
|
||||||
CoreType = ECoreType.Xray,
|
CoreType = ECoreType.Xray,
|
||||||
|
Enabled = false,
|
||||||
};
|
};
|
||||||
await SaveDNSItems(config, item);
|
await SaveDNSItems(config, item);
|
||||||
|
|
||||||
|
|
@ -2113,6 +2135,7 @@ public class ConfigHandler
|
||||||
{
|
{
|
||||||
Remarks = "sing-box",
|
Remarks = "sing-box",
|
||||||
CoreType = ECoreType.sing_box,
|
CoreType = ECoreType.sing_box,
|
||||||
|
Enabled = false,
|
||||||
};
|
};
|
||||||
await SaveDNSItems(config, item2);
|
await SaveDNSItems(config, item2);
|
||||||
}
|
}
|
||||||
|
|
@ -2184,31 +2207,62 @@ public class ConfigHandler
|
||||||
|
|
||||||
#endregion DNS
|
#endregion DNS
|
||||||
|
|
||||||
|
#region Simple DNS
|
||||||
|
|
||||||
|
public static SimpleDNSItem InitBuiltinSimpleDNS()
|
||||||
|
{
|
||||||
|
return 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()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#region Custom Config
|
||||||
|
|
||||||
public static async Task<int> InitBuiltinCustomConfig(Config config)
|
public static async Task<int> InitBuiltinFullConfigTemplate(Config config)
|
||||||
{
|
{
|
||||||
var items = await AppHandler.Instance.CustomConfigItem();
|
var items = await AppHandler.Instance.FullConfigTemplateItem();
|
||||||
if (items.Count <= 0)
|
if (items.Count <= 0)
|
||||||
{
|
{
|
||||||
var item = new CustomConfigItem()
|
var item = new FullConfigTemplateItem()
|
||||||
{
|
{
|
||||||
Remarks = "V2ray",
|
Remarks = "V2ray",
|
||||||
CoreType = ECoreType.Xray,
|
CoreType = ECoreType.Xray,
|
||||||
};
|
};
|
||||||
await SaveCustomConfigItem(config, item);
|
await SaveFullConfigTemplate(config, item);
|
||||||
|
|
||||||
var item2 = new CustomConfigItem()
|
var item2 = new FullConfigTemplateItem()
|
||||||
{
|
{
|
||||||
Remarks = "sing-box",
|
Remarks = "sing-box",
|
||||||
CoreType = ECoreType.sing_box,
|
CoreType = ECoreType.sing_box,
|
||||||
};
|
};
|
||||||
await SaveCustomConfigItem(config, item2);
|
await SaveFullConfigTemplate(config, item2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public static async Task<int> SaveCustomConfigItem(Config config, CustomConfigItem item)
|
public static async Task<int> SaveFullConfigTemplate(Config config, FullConfigTemplateItem item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
|
|
@ -2253,7 +2307,8 @@ public class ConfigHandler
|
||||||
await SQLiteHelper.Instance.DeleteAllAsync<DNSItem>();
|
await SQLiteHelper.Instance.DeleteAllAsync<DNSItem>();
|
||||||
await InitBuiltinDNS(config);
|
await InitBuiltinDNS(config);
|
||||||
|
|
||||||
return true;
|
config.SimpleDNSItem = InitBuiltinSimpleDNS();
|
||||||
|
break;
|
||||||
|
|
||||||
case EPresetType.Russia:
|
case EPresetType.Russia:
|
||||||
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[1];
|
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[1];
|
||||||
|
|
@ -2263,7 +2318,8 @@ public class ConfigHandler
|
||||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json"));
|
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"));
|
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
|
||||||
|
|
||||||
return true;
|
config.SimpleDNSItem = await GetExternalSimpleDNSItem(Global.DNSTemplateSources[1] + "simple_dns.json") ?? InitBuiltinSimpleDNS();
|
||||||
|
break;
|
||||||
|
|
||||||
case EPresetType.Iran:
|
case EPresetType.Iran:
|
||||||
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[2];
|
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[2];
|
||||||
|
|
@ -2273,10 +2329,11 @@ public class ConfigHandler
|
||||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[2] + "v2ray.json"));
|
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"));
|
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[2] + "sing_box.json"));
|
||||||
|
|
||||||
return true;
|
config.SimpleDNSItem = await GetExternalSimpleDNSItem(Global.DNSTemplateSources[2] + "simple_dns.json") ?? InitBuiltinSimpleDNS();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Regional Presets
|
#endregion Regional Presets
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using static QRCoder.PayloadGenerator;
|
|
||||||
|
|
||||||
namespace ServiceLib.Handler.Fmt;
|
namespace ServiceLib.Handler.Fmt;
|
||||||
|
|
||||||
public class AnytlsFmt : BaseFmt
|
public class AnytlsFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ public class Config
|
||||||
public List<InItem> Inbound { get; set; }
|
public List<InItem> Inbound { get; set; }
|
||||||
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
||||||
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
||||||
|
public SimpleDNSItem SimpleDNSItem { get; set; }
|
||||||
|
|
||||||
#endregion other entities
|
#endregion other entities
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -253,3 +253,21 @@ public class WindowSizeItem
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
public int Height { 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; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ public class DNSItem
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
public string Remarks { 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 ECoreType CoreType { get; set; }
|
||||||
public bool UseSystemHosts { get; set; }
|
public bool UseSystemHosts { get; set; }
|
||||||
public string? NormalDNS { get; set; }
|
public string? NormalDNS { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using SQLite;
|
||||||
namespace ServiceLib.Models;
|
namespace ServiceLib.Models;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class CustomConfigItem
|
public class FullConfigTemplateItem
|
||||||
{
|
{
|
||||||
[PrimaryKey]
|
[PrimaryKey]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
@ -36,6 +36,7 @@ public class Dns4Sbox
|
||||||
|
|
||||||
public class Route4Sbox
|
public class Route4Sbox
|
||||||
{
|
{
|
||||||
|
public Rule4Sbox? default_domain_resolver { get; set; } // or string
|
||||||
public bool? auto_detect_interface { get; set; }
|
public bool? auto_detect_interface { get; set; }
|
||||||
public List<Rule4Sbox> rules { get; set; }
|
public List<Rule4Sbox> rules { get; set; }
|
||||||
public List<Ruleset4Sbox>? rule_set { get; set; }
|
public List<Ruleset4Sbox>? rule_set { get; set; }
|
||||||
|
|
@ -75,7 +76,7 @@ public class Rule4Sbox
|
||||||
public string? strategy { get; set; }
|
public string? strategy { get; set; }
|
||||||
public List<string>? sniffer { get; set; }
|
public List<string>? sniffer { get; set; }
|
||||||
public string? rcode { get; set; }
|
public string? rcode { get; set; }
|
||||||
public List<object>? query_type { get; set; }
|
public List<int>? query_type { get; set; }
|
||||||
public List<string>? answer { get; set; }
|
public List<string>? answer { get; set; }
|
||||||
public List<string>? ns { get; set; }
|
public List<string>? ns { get; set; }
|
||||||
public List<string>? extra { get; set; }
|
public List<string>? extra { get; set; }
|
||||||
|
|
@ -178,6 +179,9 @@ public class Tls4Sbox
|
||||||
public List<string>? alpn { get; set; }
|
public List<string>? alpn { get; set; }
|
||||||
public Utls4Sbox? utls { get; set; }
|
public Utls4Sbox? utls { get; set; }
|
||||||
public Reality4Sbox? reality { get; set; }
|
public Reality4Sbox? reality { get; set; }
|
||||||
|
public bool? fragment { get; set; }
|
||||||
|
public string? fragment_fallback_delay { get; set; }
|
||||||
|
public bool? record_fragment { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Multiplex4Sbox
|
public class Multiplex4Sbox
|
||||||
|
|
@ -236,10 +240,13 @@ public class Server4Sbox : BaseServer4Sbox
|
||||||
public int? server_port { get; set; }
|
public int? server_port { get; set; }
|
||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
public Headers4Sbox? headers { get; set; }
|
public Headers4Sbox? headers { get; set; }
|
||||||
|
|
||||||
// public List<string>? path { get; set; } // hosts
|
// public List<string>? path { get; set; } // hosts
|
||||||
public Dictionary<string, object>? predefined { get; set; }
|
public Dictionary<string, List<string>>? predefined { get; set; }
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
public string? address { get; set; }
|
public string? address { get; set; }
|
||||||
|
|
||||||
public string? address_resolver { get; set; }
|
public string? address_resolver { get; set; }
|
||||||
public string? address_strategy { get; set; }
|
public string? address_strategy { get; set; }
|
||||||
public string? strategy { get; set; }
|
public string? strategy { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace ServiceLib.Models;
|
||||||
public class V2rayConfig
|
public class V2rayConfig
|
||||||
{
|
{
|
||||||
public Log4Ray log { get; set; }
|
public Log4Ray log { get; set; }
|
||||||
public object dns { get; set; }
|
public Dns4Ray dns { get; set; }
|
||||||
public List<Inbounds4Ray> inbounds { get; set; }
|
public List<Inbounds4Ray> inbounds { get; set; }
|
||||||
public List<Outbounds4Ray> outbounds { get; set; }
|
public List<Outbounds4Ray> outbounds { get; set; }
|
||||||
public Routing4Ray routing { get; set; }
|
public Routing4Ray routing { get; set; }
|
||||||
|
|
@ -203,7 +203,8 @@ public class Response4Ray
|
||||||
|
|
||||||
public class Dns4Ray
|
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
|
public class DnsServer4Ray
|
||||||
|
|
@ -211,6 +212,8 @@ public class DnsServer4Ray
|
||||||
public string? address { get; set; }
|
public string? address { get; set; }
|
||||||
public List<string>? domains { get; set; }
|
public List<string>? domains { get; set; }
|
||||||
public bool? skipFallback { get; set; }
|
public bool? skipFallback { get; set; }
|
||||||
|
public List<string>? expectedIPs { get; set; }
|
||||||
|
public List<string>? unexpectedIPs { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Routing4Ray
|
public class Routing4Ray
|
||||||
|
|
|
||||||
220
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
220
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
|
@ -1,4 +1,4 @@
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// 此代码由工具生成。
|
// 此代码由工具生成。
|
||||||
// 运行时版本:4.0.30319.42000
|
// 运行时版本:4.0.30319.42000
|
||||||
|
|
@ -187,11 +187,11 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Please fill in the correct custom config 的本地化字符串。
|
/// 查找类似 Please fill in the correct config template 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string FillCorrectConfigText {
|
public static string FillCorrectConfigTemplateText {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("FillCorrectConfigText", resourceCulture);
|
return ResourceManager.GetString("FillCorrectConfigTemplateText", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -861,15 +861,6 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Custom Config 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string menuCustomConfig {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("menuCustomConfig", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 DNS Settings 的本地化字符串。
|
/// 查找类似 DNS Settings 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -951,6 +942,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Full Config Template Setting 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuFullConfigTemplate {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuFullConfigTemplate", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Global Hotkey Setting 的本地化字符串。
|
/// 查找类似 Global Hotkey Setting 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2238,6 +2238,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Add Common DNS Hosts 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbAddCommonDNSHosts {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbAddCommonDNSHosts", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Do Not Add Non-Proxy Protocol Outbound 的本地化字符串。
|
/// 查找类似 Do Not Add Non-Proxy Protocol Outbound 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2283,6 +2292,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Apply to Proxy Domains Only 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbApplyProxyDomainsOnly {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbApplyProxyDomainsOnly", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Auto refresh 的本地化字符串。
|
/// 查找类似 Auto refresh 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2310,6 +2328,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Block SVCB and HTTPS Queries 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbBlockSVCBHTTPSQueries {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbBlockSVCBHTTPSQueries", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Browse 的本地化字符串。
|
/// 查找类似 Browse 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2364,24 +2391,6 @@ 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>
|
/// <summary>
|
||||||
/// 查找类似 Enable Custom DNS 的本地化字符串。
|
/// 查找类似 Enable Custom DNS 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2418,6 +2427,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 DNS Hosts: ("domain1 ip1 ip2" per line) 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbDNSHostsConfig {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbDNSHostsConfig", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Supports DNS Object; Click to view documentation 的本地化字符串。
|
/// 查找类似 Supports DNS Object; Click to view documentation 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2463,6 +2481,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Domestic DNS 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbDomesticDNS {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbDomesticDNS", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Edit 的本地化字符串。
|
/// 查找类似 Edit 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2481,6 +2508,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 FakeIP 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbFakeIP {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbFakeIP", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Fingerprint 的本地化字符串。
|
/// 查找类似 Fingerprint 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2499,6 +2535,24 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core's basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbFullConfigTemplateDesc {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbFullConfigTemplateDesc", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Enable Full Config Template 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbFullConfigTemplateEnable {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbFullConfigTemplateEnable", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Global Hotkey Settings 的本地化字符串。
|
/// 查找类似 Global Hotkey Settings 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2679,6 +2733,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Prevent DNS Leaks 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbPreventDNSLeaks {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbPreventDNSLeaks", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Private Key 的本地化字符串。
|
/// 查找类似 Private Key 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2707,20 +2770,20 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 v2ray Custom Config 的本地化字符串。
|
/// 查找类似 v2ray Full Config Template 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbRayCustomConfig {
|
public static string TbRayFullConfigTemplate {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("TbRayCustomConfig", resourceCulture);
|
return ResourceManager.GetString("TbRayFullConfigTemplate", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Add Outbound Config Only, routing.balancers and routing.rules.outboundTag 的本地化字符串。
|
/// 查找类似 Add Outbound Config Only, routing.balancers and routing.rules.outboundTag, Click to view the document 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbRayCustomConfigDesc {
|
public static string TbRayFullConfigTemplateDesc {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("TbRayCustomConfigDesc", resourceCulture);
|
return ResourceManager.GetString("TbRayFullConfigTemplateDesc", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2733,6 +2796,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Remote DNS 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbRemoteDNS {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbRemoteDNS", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Camouflage domain(host) 的本地化字符串。
|
/// 查找类似 Camouflage domain(host) 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2841,15 +2913,6 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Add Outbound and Endpoint Config Only 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string TbSBCustomConfigDesc {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("TbSBCustomConfigDesc", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 sing-box Direct Resolution Strategy 的本地化字符串。
|
/// 查找类似 sing-box Direct Resolution Strategy 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2886,6 +2949,24 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 sing-box Full Config Template 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSBFullConfigTemplate {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSBFullConfigTemplate", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Add Outbound and Endpoint Config Only, Click to view the document 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSBFullConfigTemplateDesc {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSBFullConfigTemplateDesc", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Resolve Outbound Domains 的本地化字符串。
|
/// 查找类似 Resolve Outbound Domains 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -3238,7 +3319,7 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Use Xray and enable non-Tun mode, which conflicts with the group previous proxy 的本地化字符串。
|
/// 查找类似 which conflicts with the group previous proxy 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbSettingsEnableFragmentTips {
|
public static string TbSettingsEnableFragmentTips {
|
||||||
get {
|
get {
|
||||||
|
|
@ -3867,6 +3948,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>
|
/// <summary>
|
||||||
/// 查找类似 The delay: {0} ms, {1} 的本地化字符串。
|
/// 查找类似 The delay: {0} ms, {1} 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -3876,6 +3984,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>
|
/// <summary>
|
||||||
/// 查找类似 Active 的本地化字符串。
|
/// 查找类似 Active 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1105,7 +1105,7 @@
|
||||||
<value>افزودن سرور [HTTP]</value>
|
<value>افزودن سرور [HTTP]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
<value>از Xray استفاده کنید و حالت non-Tun را فعال کنید، که با پراکسی قبلی گروه در تضاد است</value>
|
<value>which conflicts with the group previous proxy</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>فعال کردن فرگمنت</value>
|
<value>فعال کردن فرگمنت</value>
|
||||||
|
|
@ -1404,23 +1404,86 @@
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>Add [Anytls] Configuration</value>
|
<value>Add [Anytls] Configuration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuCustomConfig" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>Custom Config</value>
|
<value>Remote DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigEnable" xml:space="preserve">
|
<data name="TbDomesticDNS" xml:space="preserve">
|
||||||
<value>Enable Custom Config</value>
|
<value>Domestic DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfig" xml:space="preserve">
|
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||||
<value>v2ray Custom Config</value>
|
<value>Outbound DNS Resolution (sing-box)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigSingbox" xml:space="preserve">
|
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||||
<value>sing-box Custom Config</value>
|
<value>Resolve Outbound Domains</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||||
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value>
|
<value>sing-box DoH Resolver Server</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSBCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||||
<value>Add Outbound and Endpoint Config Only</value>
|
<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="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
|
<value>Please fill in the correct config template</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>Full Config Template Setting</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateEnable" xml:space="preserve">
|
||||||
|
<value>Enable Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>v2ray Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag, Click to view the document</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||||
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
||||||
|
|
@ -1428,4 +1491,13 @@
|
||||||
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
||||||
<value>Set Upstream Proxy Tag</value>
|
<value>Set Upstream Proxy Tag</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>sing-box Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound and Endpoint Config Only, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core's basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1105,7 +1105,7 @@
|
||||||
<value>HTTP konfiguráció hozzáadása</value>
|
<value>HTTP konfiguráció hozzáadása</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
<value>Használja az Xray-t és engedélyezze a nem Tun módot, ami ütközik a csoport előző proxyjával</value>
|
<value>which conflicts with the group previous proxy</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>Fragment engedélyezése</value>
|
<value>Fragment engedélyezése</value>
|
||||||
|
|
@ -1404,23 +1404,86 @@
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>[Anytls] konfiguráció hozzáadása</value>
|
<value>[Anytls] konfiguráció hozzáadása</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuCustomConfig" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>Custom Config</value>
|
<value>Remote DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigEnable" xml:space="preserve">
|
<data name="TbDomesticDNS" xml:space="preserve">
|
||||||
<value>Enable Custom Config</value>
|
<value>Domestic DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfig" xml:space="preserve">
|
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||||
<value>v2ray Custom Config</value>
|
<value>Outbound DNS Resolution (sing-box)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigSingbox" xml:space="preserve">
|
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||||
<value>sing-box Custom Config</value>
|
<value>Resolve Outbound Domains</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||||
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value>
|
<value>sing-box DoH Resolver Server</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSBCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||||
<value>Add Outbound and Endpoint Config Only</value>
|
<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="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
|
<value>Please fill in the correct config template</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>Full Config Template Setting</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateEnable" xml:space="preserve">
|
||||||
|
<value>Enable Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>v2ray Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag, Click to view the document</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||||
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
||||||
|
|
@ -1428,4 +1491,13 @@
|
||||||
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
||||||
<value>Set Upstream Proxy Tag</value>
|
<value>Set Upstream Proxy Tag</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>sing-box Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound and Endpoint Config Only, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core's basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1105,7 +1105,7 @@
|
||||||
<value>Add [HTTP] Configuration</value>
|
<value>Add [HTTP] Configuration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
<value>Use Xray and enable non-Tun mode, which conflicts with the group previous proxy</value>
|
<value>which conflicts with the group previous proxy</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>Enable fragment</value>
|
<value>Enable fragment</value>
|
||||||
|
|
@ -1404,23 +1404,86 @@
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>Add [Anytls] Configuration</value>
|
<value>Add [Anytls] Configuration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuCustomConfig" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>Custom Config</value>
|
<value>Remote DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigEnable" xml:space="preserve">
|
<data name="TbDomesticDNS" xml:space="preserve">
|
||||||
<value>Enable Custom Config</value>
|
<value>Domestic DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfig" xml:space="preserve">
|
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||||
<value>v2ray Custom Config</value>
|
<value>Outbound DNS Resolution (sing-box)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigSingbox" xml:space="preserve">
|
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||||
<value>sing-box Custom Config</value>
|
<value>Resolve Outbound Domains</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||||
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value>
|
<value>sing-box DoH Resolver Server</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSBCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||||
<value>Add Outbound and Endpoint Config Only</value>
|
<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="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
|
<value>Please fill in the correct config template</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>Full Config Template Setting</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateEnable" xml:space="preserve">
|
||||||
|
<value>Enable Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>v2ray Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag, Click to view the document</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||||
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
||||||
|
|
@ -1428,4 +1491,13 @@
|
||||||
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
||||||
<value>Set Upstream Proxy Tag</value>
|
<value>Set Upstream Proxy Tag</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>sing-box Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound and Endpoint Config Only, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core's basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -807,9 +807,6 @@
|
||||||
<data name="menuMoveUp" xml:space="preserve">
|
<data name="menuMoveUp" xml:space="preserve">
|
||||||
<value>Вверх (U)</value>
|
<value>Вверх (U)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuMoveTo" xml:space="preserve">
|
|
||||||
<value>Переместить вверх/вниз</value>
|
|
||||||
</data>
|
|
||||||
<data name="MsgFilterTitle" xml:space="preserve">
|
<data name="MsgFilterTitle" xml:space="preserve">
|
||||||
<value>Фильтр, поддерживает regex</value>
|
<value>Фильтр, поддерживает regex</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -969,6 +966,9 @@
|
||||||
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
|
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
|
||||||
<value>URL для тестирования скорости</value>
|
<value>URL для тестирования скорости</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuMoveTo" xml:space="preserve">
|
||||||
|
<value>Переместить вверх/вниз</value>
|
||||||
|
</data>
|
||||||
<data name="TbPublicKey" xml:space="preserve">
|
<data name="TbPublicKey" xml:space="preserve">
|
||||||
<value>PublicKey</value>
|
<value>PublicKey</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -1105,7 +1105,7 @@
|
||||||
<value>Добавить сервер [HTTP]</value>
|
<value>Добавить сервер [HTTP]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
<value>Используйте Xray и отключите режим TUN, так как он конфликтует с предыдущим прокси-сервером группы</value>
|
<value>which conflicts with the group previous proxy</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>Включить фрагментацию (Fragment)</value>
|
<value>Включить фрагментацию (Fragment)</value>
|
||||||
|
|
@ -1404,23 +1404,86 @@
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>Добавить сервер [Anytls]</value>
|
<value>Добавить сервер [Anytls]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuCustomConfig" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>Custom Config</value>
|
<value>Remote DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigEnable" xml:space="preserve">
|
<data name="TbDomesticDNS" xml:space="preserve">
|
||||||
<value>Enable Custom Config</value>
|
<value>Domestic DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfig" xml:space="preserve">
|
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||||
<value>v2ray Custom Config</value>
|
<value>Outbound DNS Resolution (sing-box)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigSingbox" xml:space="preserve">
|
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||||
<value>sing-box Custom Config</value>
|
<value>Resolve Outbound Domains</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||||
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value>
|
<value>sing-box DoH Resolver Server</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSBCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||||
<value>Add Outbound and Endpoint Config Only</value>
|
<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="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
|
<value>Please fill in the correct config template</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>Full Config Template Setting</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateEnable" xml:space="preserve">
|
||||||
|
<value>Enable Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>v2ray Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag, Click to view the document</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||||
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
||||||
|
|
@ -1428,4 +1491,13 @@
|
||||||
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
||||||
<value>Set Upstream Proxy Tag</value>
|
<value>Set Upstream Proxy Tag</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>sing-box Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound and Endpoint Config Only, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core's basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1102,7 +1102,7 @@
|
||||||
<value>添加 [HTTP] 配置文件</value>
|
<value>添加 [HTTP] 配置文件</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
<value>使用 Xray 且非 Tun 模式启用,和分组前置代理冲突</value>
|
<value>和分组前置代理冲突</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>启用分片 (Fragment)</value>
|
<value>启用分片 (Fragment)</value>
|
||||||
|
|
@ -1401,23 +1401,86 @@
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>添加 [Anytls] 配置文件</value>
|
<value>添加 [Anytls] 配置文件</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuCustomConfig" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>自定义配置</value>
|
<value>远程 DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigEnable" xml:space="preserve">
|
<data name="TbDomesticDNS" xml:space="preserve">
|
||||||
<value>启用自定义配置</value>
|
<value>直连 DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfig" xml:space="preserve">
|
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||||
<value>v2ray 自定义配置</value>
|
<value>出站 DNS 解析(sing-box)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigSingbox" xml:space="preserve">
|
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||||
<value>sing-box 自定义配置</value>
|
<value>解析出站域名</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||||
<value>仅添加出站配置,routing.balancers 和 routing.rules.outboundTag</value>
|
<value>sing-box DoH 解析服务器</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSBCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||||
<value>仅添加出站和端点配置</value>
|
<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="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
|
<value>请填写正确的配置模板</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>完整配置模板设置</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateEnable" xml:space="preserve">
|
||||||
|
<value>启用完整配置模板</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>v2ray 完整配置模板</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>仅添加出站配置,routing.balancers 和 routing.rules.outboundTag,点击查看文档</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||||
<value>不添加非代理协议出站</value>
|
<value>不添加非代理协议出站</value>
|
||||||
|
|
@ -1425,4 +1488,13 @@
|
||||||
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
||||||
<value>设置上游代理 tag</value>
|
<value>设置上游代理 tag</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>sing-box 完整配置模板</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>仅添加出站和端点配置,点击查看文档</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>此功能供高级用户和有特殊需求的用户使用。 启用此功能后,将忽略 Core 的基础设置,DNS 设置 ,路由设置。你需要保证系统代理的端口和流量统计等功能的配置正确,一切都由你来设置。</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1102,7 +1102,7 @@
|
||||||
<value>新增 [HTTP] 設定檔</value>
|
<value>新增 [HTTP] 設定檔</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
<value>使用 Xray 且非 Tun 模式啟用,和分組前置代理衝突</value>
|
<value>和分組前置代理衝突</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>啟用分片(Fragment)</value>
|
<value>啟用分片(Fragment)</value>
|
||||||
|
|
@ -1401,23 +1401,86 @@
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>新增 [Anytls] 設定檔</value>
|
<value>新增 [Anytls] 設定檔</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuCustomConfig" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>Custom Config</value>
|
<value>Remote DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigEnable" xml:space="preserve">
|
<data name="TbDomesticDNS" xml:space="preserve">
|
||||||
<value>Enable Custom Config</value>
|
<value>Domestic DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfig" xml:space="preserve">
|
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||||
<value>v2ray Custom Config</value>
|
<value>Outbound DNS Resolution (sing-box)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCustomConfigSingbox" xml:space="preserve">
|
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||||
<value>sing-box Custom Config</value>
|
<value>Resolve Outbound Domains</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRayCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||||
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag</value>
|
<value>sing-box DoH Resolver Server</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSBCustomConfigDesc" xml:space="preserve">
|
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||||
<value>Add Outbound and Endpoint Config Only</value>
|
<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="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
|
<value>Please fill in the correct config template</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>Full Config Template Setting</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateEnable" xml:space="preserve">
|
||||||
|
<value>Enable Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>v2ray Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound Config Only, routing.balancers and routing.rules.outboundTag, Click to view the document</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||||
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
<value>Do Not Add Non-Proxy Protocol Outbound</value>
|
||||||
|
|
@ -1425,4 +1488,13 @@
|
||||||
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
<data name="TbSetUpstreamProxyDetour" xml:space="preserve">
|
||||||
<value>Set Upstream Proxy Tag</value>
|
<value>Set Upstream Proxy Tag</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplate" xml:space="preserve">
|
||||||
|
<value>sing-box Full Config Template</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSBFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>Add Outbound and Endpoint Config Only, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbFullConfigTemplateDesc" xml:space="preserve">
|
||||||
|
<value>This feature is intended for advanced users and those with special requirements. Once enabled, it will ignore the Core's basic settings, DNS settings, and routing settings. You must ensure that the system proxy port, traffic statistics, and other related configurations are set correctly — everything will be configured by you.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Reactive;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using DynamicData;
|
|
||||||
using ServiceLib.Models;
|
|
||||||
|
|
||||||
namespace ServiceLib.Services.CoreConfig;
|
namespace ServiceLib.Services.CoreConfig;
|
||||||
|
|
||||||
|
|
@ -75,7 +71,7 @@ public class CoreConfigSingboxService
|
||||||
|
|
||||||
await GenRouting(singboxConfig);
|
await GenRouting(singboxConfig);
|
||||||
|
|
||||||
await GenDns(node, singboxConfig);
|
await GenDns(singboxConfig);
|
||||||
|
|
||||||
await GenExperimental(singboxConfig);
|
await GenExperimental(singboxConfig);
|
||||||
|
|
||||||
|
|
@ -84,8 +80,8 @@ public class CoreConfigSingboxService
|
||||||
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
|
|
||||||
var customConfig = await AppHandler.Instance.GetCustomConfigItem(ECoreType.sing_box);
|
var fullConfigTemplate = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||||
ret.Data = await ApplyCustomConfig(customConfig, singboxConfig);
|
ret.Data = await ApplyFullConfigTemplate(fullConfigTemplate, singboxConfig);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -247,20 +243,20 @@ public class CoreConfigSingboxService
|
||||||
singboxConfig.route.rules.Add(rule);
|
singboxConfig.route.rules.Add(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenDnsDomains(null, singboxConfig, null);
|
var rawDNSItem = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
//var dnsServer = singboxConfig.dns?.servers.FirstOrDefault();
|
if (rawDNSItem != null && rawDNSItem.Enabled == true)
|
||||||
//if (dnsServer != null)
|
{
|
||||||
//{
|
await GenDnsDomainsCompatible(singboxConfig, rawDNSItem);
|
||||||
// dnsServer.detour = singboxConfig.route.rules.LastOrDefault()?.outbound;
|
}
|
||||||
//}
|
else
|
||||||
//var dnsRule = singboxConfig.dns?.rules.Where(t => t.outbound != null).FirstOrDefault();
|
{
|
||||||
//if (dnsRule != null)
|
await GenDnsDomains(singboxConfig, _config.SimpleDNSItem);
|
||||||
//{
|
}
|
||||||
// singboxConfig.dns.rules = [];
|
singboxConfig.route.default_domain_resolver = new()
|
||||||
// singboxConfig.dns.rules.Add(dnsRule);
|
{
|
||||||
//}
|
server = Global.SingboxFinalResolverTag
|
||||||
|
};
|
||||||
|
|
||||||
//ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
|
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
ret.Data = JsonUtils.Serialize(singboxConfig);
|
ret.Data = JsonUtils.Serialize(singboxConfig);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -319,7 +315,19 @@ public class CoreConfigSingboxService
|
||||||
await GenOutbound(node, singboxConfig.outbounds.First());
|
await GenOutbound(node, singboxConfig.outbounds.First());
|
||||||
}
|
}
|
||||||
await GenMoreOutbounds(node, singboxConfig);
|
await GenMoreOutbounds(node, singboxConfig);
|
||||||
await GenDnsDomains(null, singboxConfig, null);
|
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
|
if (item != null && item.Enabled == true)
|
||||||
|
{
|
||||||
|
await GenDnsDomainsCompatible(singboxConfig, item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await GenDnsDomains(singboxConfig, _config.SimpleDNSItem);
|
||||||
|
}
|
||||||
|
singboxConfig.route.default_domain_resolver = new()
|
||||||
|
{
|
||||||
|
server = Global.SingboxFinalResolverTag
|
||||||
|
};
|
||||||
|
|
||||||
singboxConfig.route.rules.Clear();
|
singboxConfig.route.rules.Clear();
|
||||||
singboxConfig.inbounds.Clear();
|
singboxConfig.inbounds.Clear();
|
||||||
|
|
@ -421,13 +429,13 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
await GenOutboundsList(proxyProfiles, singboxConfig);
|
await GenOutboundsList(proxyProfiles, singboxConfig);
|
||||||
|
|
||||||
await GenDns(null, singboxConfig);
|
await GenDns(singboxConfig);
|
||||||
await ConvertGeo2Ruleset(singboxConfig);
|
await ConvertGeo2Ruleset(singboxConfig);
|
||||||
|
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
|
|
||||||
var customConfig = await AppHandler.Instance.GetCustomConfigItem(ECoreType.sing_box);
|
var fullConfigTemplate = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||||
ret.Data = await ApplyCustomConfig(customConfig, singboxConfig);
|
ret.Data = await ApplyFullConfigTemplate(fullConfigTemplate, singboxConfig);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -654,17 +662,6 @@ public class CoreConfigSingboxService
|
||||||
outbound.server_port = node.Port;
|
outbound.server_port = node.Port;
|
||||||
outbound.type = Global.ProtocolTypes[node.ConfigType];
|
outbound.type = Global.ProtocolTypes[node.ConfigType];
|
||||||
|
|
||||||
if (Utils.IsDomain(node.Address))
|
|
||||||
{
|
|
||||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
|
||||||
var localDnsAddress = string.IsNullOrEmpty(item?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : item?.DomainDNSAddress;
|
|
||||||
outbound.domain_resolver = new()
|
|
||||||
{
|
|
||||||
server = localDnsAddress.StartsWith("tag://") ? localDnsAddress.Substring(6) : "local_resolver",
|
|
||||||
strategy = string.IsNullOrEmpty(item?.DomainStrategy4Freedom) ? null : item?.DomainStrategy4Freedom
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node.ConfigType)
|
switch (node.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.VMess:
|
case EConfigType.VMess:
|
||||||
|
|
@ -799,17 +796,6 @@ public class CoreConfigSingboxService
|
||||||
endpoint.address = Utils.String2List(node.RequestHost);
|
endpoint.address = Utils.String2List(node.RequestHost);
|
||||||
endpoint.type = Global.ProtocolTypes[node.ConfigType];
|
endpoint.type = Global.ProtocolTypes[node.ConfigType];
|
||||||
|
|
||||||
if (Utils.IsDomain(node.Address))
|
|
||||||
{
|
|
||||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
|
||||||
var localDnsAddress = string.IsNullOrEmpty(item?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : item?.DomainDNSAddress;
|
|
||||||
endpoint.domain_resolver = new()
|
|
||||||
{
|
|
||||||
server = localDnsAddress.StartsWith("tag://") ? localDnsAddress.Substring(6) : "local_resolver",
|
|
||||||
strategy = string.IsNullOrEmpty(item?.DomainStrategy4Freedom) ? null : item?.DomainStrategy4Freedom
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node.ConfigType)
|
switch (node.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.WireGuard:
|
case EConfigType.WireGuard:
|
||||||
|
|
@ -904,6 +890,7 @@ public class CoreConfigSingboxService
|
||||||
var tls = new Tls4Sbox()
|
var tls = new Tls4Sbox()
|
||||||
{
|
{
|
||||||
enabled = true,
|
enabled = true,
|
||||||
|
record_fragment = _config.CoreBasicItem.EnableFragment,
|
||||||
server_name = server_name,
|
server_name = server_name,
|
||||||
insecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
|
insecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
|
||||||
alpn = node.GetAlpn(),
|
alpn = node.GetAlpn(),
|
||||||
|
|
@ -1028,7 +1015,8 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
//current proxy
|
//current proxy
|
||||||
BaseServer4Sbox? outbound = singboxConfig.endpoints?.FirstOrDefault(t => t.tag == Global.ProxyTag) == null ? singboxConfig.outbounds.First() : null;
|
BaseServer4Sbox? outbound = singboxConfig.endpoints?.FirstOrDefault(t => t.tag == Global.ProxyTag, null);
|
||||||
|
outbound ??= singboxConfig.outbounds.First();
|
||||||
|
|
||||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||||
|
|
||||||
|
|
@ -1256,6 +1244,22 @@ public class CoreConfigSingboxService
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
singboxConfig.route.final = Global.ProxyTag;
|
singboxConfig.route.final = Global.ProxyTag;
|
||||||
|
var item = _config.SimpleDNSItem;
|
||||||
|
|
||||||
|
var defaultDomainResolverTag = Global.SingboxOutboundResolverTag;
|
||||||
|
var directDNSStrategy = item.SingboxStrategy4Direct.IsNullOrEmpty() ? Global.SingboxDomainStrategy4Out.FirstOrDefault() : item.SingboxStrategy4Direct;
|
||||||
|
|
||||||
|
var rawDNSItem = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
|
if (rawDNSItem != null && rawDNSItem.Enabled == true)
|
||||||
|
{
|
||||||
|
defaultDomainResolverTag = Global.SingboxFinalResolverTag;
|
||||||
|
directDNSStrategy = rawDNSItem.DomainStrategy4Freedom.IsNullOrEmpty() ? Global.SingboxDomainStrategy4Out.FirstOrDefault() : rawDNSItem.DomainStrategy4Freedom;
|
||||||
|
}
|
||||||
|
singboxConfig.route.default_domain_resolver = new()
|
||||||
|
{
|
||||||
|
server = defaultDomainResolverTag,
|
||||||
|
strategy = directDNSStrategy
|
||||||
|
};
|
||||||
|
|
||||||
if (_config.TunModeItem.EnableTun)
|
if (_config.TunModeItem.EnableTun)
|
||||||
{
|
{
|
||||||
|
|
@ -1336,14 +1340,14 @@ public class CoreConfigSingboxService
|
||||||
if (routing != null)
|
if (routing != null)
|
||||||
{
|
{
|
||||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
||||||
foreach (var item in rules ?? [])
|
foreach (var item1 in rules ?? [])
|
||||||
{
|
{
|
||||||
if (item.Enabled)
|
if (item1.Enabled)
|
||||||
{
|
{
|
||||||
await GenRoutingUserRule(item, singboxConfig);
|
await GenRoutingUserRule(item1, singboxConfig);
|
||||||
if (item.Ip != null && item.Ip.Count > 0)
|
if (item1.Ip != null && item1.Ip.Count > 0)
|
||||||
{
|
{
|
||||||
ipRules.Add(item);
|
ipRules.Add(item1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1351,9 +1355,9 @@ public class CoreConfigSingboxService
|
||||||
if (_config.RoutingBasicItem.DomainStrategy == "IPIfNonMatch")
|
if (_config.RoutingBasicItem.DomainStrategy == "IPIfNonMatch")
|
||||||
{
|
{
|
||||||
singboxConfig.route.rules.Add(resolveRule);
|
singboxConfig.route.rules.Add(resolveRule);
|
||||||
foreach (var item in ipRules)
|
foreach (var item2 in ipRules)
|
||||||
{
|
{
|
||||||
await GenRoutingUserRule(item, singboxConfig);
|
await GenRoutingUserRule(item2, singboxConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1596,7 +1600,278 @@ public class CoreConfigSingboxService
|
||||||
return server.tag;
|
return server.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
private async Task<int> GenDns(SingboxConfig singboxConfig)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
|
if (item != null && item.Enabled == true)
|
||||||
|
{
|
||||||
|
return await GenDnsCompatible(singboxConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
var simpleDNSItem = _config.SimpleDNSItem;
|
||||||
|
await GenDnsServers(singboxConfig, simpleDNSItem);
|
||||||
|
await GenDnsRules(singboxConfig, simpleDNSItem);
|
||||||
|
|
||||||
|
singboxConfig.dns ??= new Dns4Sbox();
|
||||||
|
singboxConfig.dns.independent_cache = true;
|
||||||
|
|
||||||
|
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
||||||
|
var useDirectDns = false;
|
||||||
|
if (routing != null)
|
||||||
|
{
|
||||||
|
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
singboxConfig.dns.final = useDirectDns ? Global.SingboxDirectDNSTag : Global.SingboxRemoteDNSTag;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<int> GenDnsServers(SingboxConfig singboxConfig, SimpleDNSItem simpleDNSItem)
|
||||||
|
{
|
||||||
|
var finalDns = await GenDnsDomains(singboxConfig, simpleDNSItem);
|
||||||
|
|
||||||
|
var directDns = ParseDnsAddress(simpleDNSItem.DirectDNS);
|
||||||
|
directDns.tag = Global.SingboxDirectDNSTag;
|
||||||
|
directDns.domain_resolver = Global.SingboxFinalResolverTag;
|
||||||
|
|
||||||
|
var remoteDns = ParseDnsAddress(simpleDNSItem.RemoteDNS);
|
||||||
|
remoteDns.tag = Global.SingboxRemoteDNSTag;
|
||||||
|
remoteDns.detour = Global.ProxyTag;
|
||||||
|
remoteDns.domain_resolver = Global.SingboxFinalResolverTag;
|
||||||
|
|
||||||
|
var resolverDns = ParseDnsAddress(simpleDNSItem.SingboxOutboundsResolveDNS);
|
||||||
|
resolverDns.tag = Global.SingboxOutboundResolverTag;
|
||||||
|
resolverDns.domain_resolver = Global.SingboxFinalResolverTag;
|
||||||
|
|
||||||
|
var hostsDns = new Server4Sbox
|
||||||
|
{
|
||||||
|
tag = Global.SingboxHostsDNSTag,
|
||||||
|
type = "hosts",
|
||||||
|
};
|
||||||
|
if (simpleDNSItem.AddCommonHosts == true)
|
||||||
|
{
|
||||||
|
hostsDns.predefined = Global.PredefinedHosts;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
hostsDns.predefined[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var host in hostsDns.predefined)
|
||||||
|
{
|
||||||
|
if (finalDns.server == host.Key)
|
||||||
|
{
|
||||||
|
finalDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||||
|
}
|
||||||
|
if (remoteDns.server == host.Key)
|
||||||
|
{
|
||||||
|
remoteDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||||
|
}
|
||||||
|
if (resolverDns.server == host.Key)
|
||||||
|
{
|
||||||
|
resolverDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||||
|
}
|
||||||
|
if (directDns.server == host.Key)
|
||||||
|
{
|
||||||
|
directDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
singboxConfig.dns ??= new Dns4Sbox();
|
||||||
|
singboxConfig.dns.servers ??= new List<Server4Sbox>();
|
||||||
|
singboxConfig.dns.servers.Add(remoteDns);
|
||||||
|
singboxConfig.dns.servers.Add(directDns);
|
||||||
|
singboxConfig.dns.servers.Add(resolverDns);
|
||||||
|
singboxConfig.dns.servers.Add(hostsDns);
|
||||||
|
|
||||||
|
// fake ip
|
||||||
|
if (simpleDNSItem.FakeIP == true)
|
||||||
|
{
|
||||||
|
var fakeip = new Server4Sbox
|
||||||
|
{
|
||||||
|
tag = Global.SingboxFakeDNSTag,
|
||||||
|
type = "fakeip",
|
||||||
|
inet4_range = "198.18.0.0/15",
|
||||||
|
inet6_range = "fc00::/18",
|
||||||
|
};
|
||||||
|
singboxConfig.dns.servers.Add(fakeip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Server4Sbox> GenDnsDomains(SingboxConfig singboxConfig, SimpleDNSItem? simpleDNSItem)
|
||||||
|
{
|
||||||
|
var finalDns = ParseDnsAddress(simpleDNSItem.SingboxFinalResolveDNS);
|
||||||
|
finalDns.tag = Global.SingboxFinalResolverTag;
|
||||||
|
singboxConfig.dns ??= new Dns4Sbox();
|
||||||
|
singboxConfig.dns.servers ??= new List<Server4Sbox>();
|
||||||
|
singboxConfig.dns.servers.Add(finalDns);
|
||||||
|
return await Task.FromResult(finalDns);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<int> GenDnsRules(SingboxConfig singboxConfig, SimpleDNSItem simpleDNSItem)
|
||||||
|
{
|
||||||
|
singboxConfig.dns ??= new Dns4Sbox();
|
||||||
|
singboxConfig.dns.rules ??= new List<Rule4Sbox>();
|
||||||
|
|
||||||
|
singboxConfig.dns.rules.AddRange(new[]
|
||||||
|
{
|
||||||
|
new Rule4Sbox { ip_accept_any = true, server = Global.SingboxHostsDNSTag },
|
||||||
|
new Rule4Sbox
|
||||||
|
{
|
||||||
|
server = Global.SingboxRemoteDNSTag,
|
||||||
|
strategy = simpleDNSItem.SingboxStrategy4Proxy.IsNullOrEmpty() ? null : simpleDNSItem.SingboxStrategy4Proxy,
|
||||||
|
clash_mode = ERuleMode.Global.ToString()
|
||||||
|
},
|
||||||
|
new Rule4Sbox
|
||||||
|
{
|
||||||
|
server = Global.SingboxDirectDNSTag,
|
||||||
|
strategy = simpleDNSItem.SingboxStrategy4Direct.IsNullOrEmpty() ? null : simpleDNSItem.SingboxStrategy4Direct,
|
||||||
|
clash_mode = ERuleMode.Direct.ToString()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (simpleDNSItem.BlockBindingQuery == true)
|
||||||
|
{
|
||||||
|
singboxConfig.dns.rules.Add(new()
|
||||||
|
{
|
||||||
|
query_type = new List<int> { 64, 65 },
|
||||||
|
action = "predefined",
|
||||||
|
rcode = "NOTIMP"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
||||||
|
if (routing == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||||
|
var expectedIPCidr = new List<string>();
|
||||||
|
var expectedIPsRegions = new List<string>();
|
||||||
|
var regionNames = new HashSet<string>();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(simpleDNSItem?.DirectExpectedIPs))
|
||||||
|
{
|
||||||
|
var ipItems = simpleDNSItem.DirectExpectedIPs
|
||||||
|
.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(s => s.Trim())
|
||||||
|
.Where(s => !string.IsNullOrEmpty(s))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var ip in ipItems)
|
||||||
|
{
|
||||||
|
if (ip.StartsWith("geoip:", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var region = ip["geoip:".Length..];
|
||||||
|
if (!string.IsNullOrEmpty(region))
|
||||||
|
{
|
||||||
|
expectedIPsRegions.Add(region);
|
||||||
|
regionNames.Add(region);
|
||||||
|
regionNames.Add($"geolocation-{region}");
|
||||||
|
regionNames.Add($"tld-{region}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expectedIPCidr.Add(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in rules)
|
||||||
|
{
|
||||||
|
if (!item.Enabled || item.Domain is null || item.Domain.Count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rule = new Rule4Sbox();
|
||||||
|
var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule));
|
||||||
|
if (validDomains <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.OutboundTag == Global.DirectTag)
|
||||||
|
{
|
||||||
|
rule.server = Global.SingboxDirectDNSTag;
|
||||||
|
rule.strategy = string.IsNullOrEmpty(simpleDNSItem.SingboxStrategy4Direct) ? null : simpleDNSItem.SingboxStrategy4Direct;
|
||||||
|
|
||||||
|
if (expectedIPsRegions.Count > 0 && rule.geosite?.Count > 0)
|
||||||
|
{
|
||||||
|
var geositeSet = new HashSet<string>(rule.geosite);
|
||||||
|
if (regionNames.Intersect(geositeSet).Any())
|
||||||
|
{
|
||||||
|
if (expectedIPsRegions.Count > 0)
|
||||||
|
{
|
||||||
|
rule.geoip = expectedIPsRegions;
|
||||||
|
}
|
||||||
|
if (expectedIPCidr.Count > 0)
|
||||||
|
{
|
||||||
|
rule.ip_cidr = expectedIPCidr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (item.OutboundTag == Global.ProxyTag)
|
||||||
|
{
|
||||||
|
if (simpleDNSItem.FakeIP == true)
|
||||||
|
{
|
||||||
|
var rule4Fake = JsonUtils.DeepCopy(rule);
|
||||||
|
rule4Fake.server = Global.SingboxFakeDNSTag;
|
||||||
|
singboxConfig.dns.rules.Add(rule4Fake);
|
||||||
|
}
|
||||||
|
rule.server = Global.SingboxRemoteDNSTag;
|
||||||
|
rule.strategy = string.IsNullOrEmpty(simpleDNSItem.SingboxStrategy4Proxy) ? null : simpleDNSItem.SingboxStrategy4Proxy;
|
||||||
|
}
|
||||||
|
else if (item.OutboundTag == Global.BlockTag)
|
||||||
|
{
|
||||||
|
rule.action = "predefined";
|
||||||
|
rule.rcode = "NOERROR";
|
||||||
|
rule.answer = new List<string> { "A" };
|
||||||
|
}
|
||||||
|
|
||||||
|
singboxConfig.dns.rules.Add(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<int> GenDnsCompatible(SingboxConfig singboxConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -1620,11 +1895,11 @@ public class CoreConfigSingboxService
|
||||||
|
|
||||||
if (dns4Sbox.servers != null && dns4Sbox.servers.Count > 0 && dns4Sbox.servers.First().address.IsNullOrEmpty())
|
if (dns4Sbox.servers != null && dns4Sbox.servers.Count > 0 && dns4Sbox.servers.First().address.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
await GenDnsDomains(node, singboxConfig, item);
|
await GenDnsDomainsCompatible(singboxConfig, item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await GenDnsDomainsLegacy(node, singboxConfig, item);
|
await GenDnsDomainsLegacyCompatible(singboxConfig, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -1634,86 +1909,35 @@ public class CoreConfigSingboxService
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem)
|
private async Task<int> GenDnsDomainsCompatible(SingboxConfig singboxConfig, DNSItem? dNSItem)
|
||||||
{
|
{
|
||||||
var dns4Sbox = singboxConfig.dns ?? new();
|
var dns4Sbox = singboxConfig.dns ?? new();
|
||||||
dns4Sbox.servers ??= [];
|
dns4Sbox.servers ??= [];
|
||||||
dns4Sbox.rules ??= [];
|
dns4Sbox.rules ??= [];
|
||||||
|
|
||||||
var tag = "local_resolver";
|
var tag = Global.SingboxFinalResolverTag;
|
||||||
var localDnsAddress = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress;
|
var localDnsAddress = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress;
|
||||||
|
|
||||||
if (localDnsAddress.StartsWith("tag://"))
|
var localDnsServer = ParseDnsAddress(localDnsAddress);
|
||||||
{
|
localDnsServer.tag = tag;
|
||||||
tag = localDnsAddress.Substring(6);
|
|
||||||
|
|
||||||
var localDnsTag = "local_local";
|
dns4Sbox.servers.Add(localDnsServer);
|
||||||
|
|
||||||
dns4Sbox.servers.Add(new()
|
|
||||||
{
|
|
||||||
tag = localDnsTag,
|
|
||||||
type = "local"
|
|
||||||
});
|
|
||||||
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = localDnsTag,
|
|
||||||
clash_mode = ERuleMode.Direct.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var (dnsType, dnsHost, dnsPort, dnsPath) = ParseDnsAddress(localDnsAddress);
|
|
||||||
|
|
||||||
dns4Sbox.servers.Add(new()
|
|
||||||
{
|
|
||||||
tag = tag,
|
|
||||||
type = dnsType,
|
|
||||||
server = dnsHost,
|
|
||||||
Interface = dnsType == "dhcp" ? dnsHost : null,
|
|
||||||
server_port = dnsPort,
|
|
||||||
path = dnsPath
|
|
||||||
});
|
|
||||||
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = tag,
|
|
||||||
clash_mode = ERuleMode.Direct.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = dns4Sbox.servers.Where(t => t.detour == Global.ProxyTag).Select(t => t.tag).FirstOrDefault() ?? "remote",
|
|
||||||
clash_mode = ERuleMode.Global.ToString()
|
|
||||||
});
|
|
||||||
|
|
||||||
//Tun2SocksAddress
|
|
||||||
if (_config.TunModeItem.EnableTun && node?.ConfigType == EConfigType.SOCKS && Utils.IsDomain(node?.Sni))
|
|
||||||
{
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = tag,
|
|
||||||
domain = [node?.Sni],
|
|
||||||
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
singboxConfig.dns = dns4Sbox;
|
singboxConfig.dns = dns4Sbox;
|
||||||
return await Task.FromResult(0);
|
return await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenDnsDomainsLegacy(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem)
|
private async Task<int> GenDnsDomainsLegacyCompatible(SingboxConfig singboxConfig, DNSItem? dNSItem)
|
||||||
{
|
{
|
||||||
var dns4Sbox = singboxConfig.dns ?? new();
|
var dns4Sbox = singboxConfig.dns ?? new();
|
||||||
dns4Sbox.servers ??= [];
|
dns4Sbox.servers ??= [];
|
||||||
dns4Sbox.rules ??= [];
|
dns4Sbox.rules ??= [];
|
||||||
|
|
||||||
var tag = "local_local";
|
var tag = Global.SingboxFinalResolverTag;
|
||||||
dns4Sbox.servers.Add(new()
|
dns4Sbox.servers.Add(new()
|
||||||
{
|
{
|
||||||
tag = tag,
|
tag = tag,
|
||||||
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
|
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
|
||||||
detour = Global.DirectTag,
|
detour = Global.DirectTag,
|
||||||
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom,
|
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom,
|
||||||
});
|
});
|
||||||
|
|
@ -1742,103 +1966,100 @@ public class CoreConfigSingboxService
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Tun2SocksAddress
|
|
||||||
if (_config.TunModeItem.EnableTun && node?.ConfigType == EConfigType.SOCKS && Utils.IsDomain(node?.Sni))
|
|
||||||
{
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = tag,
|
|
||||||
domain = [node?.Sni]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
singboxConfig.dns = dns4Sbox;
|
singboxConfig.dns = dns4Sbox;
|
||||||
return await Task.FromResult(0);
|
return await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private (string type, string? host, int? port, string? path) ParseDnsAddress(string address)
|
private static Server4Sbox? ParseDnsAddress(string address)
|
||||||
{
|
{
|
||||||
string type = "udp";
|
var addressFirst = address?.Split(address.Contains(',') ? ',' : ';').FirstOrDefault()?.Trim();
|
||||||
string? host = null;
|
if (string.IsNullOrEmpty(addressFirst))
|
||||||
int? port = null;
|
|
||||||
string? path = null;
|
|
||||||
|
|
||||||
if (address is "local" or "localhost")
|
|
||||||
{
|
{
|
||||||
return ("local", null, null, null);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address.StartsWith("dhcp://", StringComparison.OrdinalIgnoreCase))
|
var server = new Server4Sbox();
|
||||||
|
|
||||||
|
if (addressFirst is "local" or "localhost")
|
||||||
{
|
{
|
||||||
string interface_name = address.Substring(7);
|
server.type = "local";
|
||||||
return ("dhcp", interface_name == "auto" ? null : interface_name, null, null);
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!address.Contains("://"))
|
if (addressFirst.StartsWith("dhcp://", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var interface_name = addressFirst.Substring(7);
|
||||||
|
server.type = "dhcp";
|
||||||
|
server.Interface = interface_name == "auto" ? null : interface_name;
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!addressFirst.Contains("://"))
|
||||||
{
|
{
|
||||||
// udp dns
|
// udp dns
|
||||||
host = address;
|
server.type = "udp";
|
||||||
return (type, host, port, path);
|
server.server = addressFirst;
|
||||||
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int protocolEndIndex = address.IndexOf("://", StringComparison.Ordinal);
|
var protocolEndIndex = addressFirst.IndexOf("://", StringComparison.Ordinal);
|
||||||
type = address.Substring(0, protocolEndIndex).ToLower();
|
server.type = addressFirst.Substring(0, protocolEndIndex).ToLower();
|
||||||
|
|
||||||
var uri = new Uri(address);
|
var uri = new Uri(addressFirst);
|
||||||
host = uri.Host;
|
server.server = uri.Host;
|
||||||
|
|
||||||
if (!uri.IsDefaultPort)
|
if (!uri.IsDefaultPort)
|
||||||
{
|
{
|
||||||
port = uri.Port;
|
server.server_port = uri.Port;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type == "https" || type == "h3") && !string.IsNullOrEmpty(uri.AbsolutePath) && uri.AbsolutePath != "/")
|
if ((server.type == "https" || server.type == "h3") && !string.IsNullOrEmpty(uri.AbsolutePath) && uri.AbsolutePath != "/")
|
||||||
{
|
{
|
||||||
path = uri.AbsolutePath;
|
server.path = uri.AbsolutePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (UriFormatException)
|
catch (UriFormatException)
|
||||||
{
|
{
|
||||||
int protocolEndIndex = address.IndexOf("://", StringComparison.Ordinal);
|
var protocolEndIndex = addressFirst.IndexOf("://", StringComparison.Ordinal);
|
||||||
if (protocolEndIndex > 0)
|
if (protocolEndIndex > 0)
|
||||||
{
|
{
|
||||||
type = address.Substring(0, protocolEndIndex).ToLower();
|
server.type = addressFirst.Substring(0, protocolEndIndex).ToLower();
|
||||||
string remaining = address.Substring(protocolEndIndex + 3);
|
var remaining = addressFirst.Substring(protocolEndIndex + 3);
|
||||||
|
|
||||||
int portIndex = remaining.IndexOf(':');
|
var portIndex = remaining.IndexOf(':');
|
||||||
int pathIndex = remaining.IndexOf('/');
|
var pathIndex = remaining.IndexOf('/');
|
||||||
|
|
||||||
if (portIndex > 0)
|
if (portIndex > 0)
|
||||||
{
|
{
|
||||||
host = remaining.Substring(0, portIndex);
|
server.server = remaining.Substring(0, portIndex);
|
||||||
string portPart = pathIndex > portIndex
|
var portPart = pathIndex > portIndex
|
||||||
? remaining.Substring(portIndex + 1, pathIndex - portIndex - 1)
|
? remaining.Substring(portIndex + 1, pathIndex - portIndex - 1)
|
||||||
: remaining.Substring(portIndex + 1);
|
: remaining.Substring(portIndex + 1);
|
||||||
|
|
||||||
if (int.TryParse(portPart, out int parsedPort))
|
if (int.TryParse(portPart, out var parsedPort))
|
||||||
{
|
{
|
||||||
port = parsedPort;
|
server.server_port = parsedPort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pathIndex > 0)
|
else if (pathIndex > 0)
|
||||||
{
|
{
|
||||||
host = remaining.Substring(0, pathIndex);
|
server.server = remaining.Substring(0, pathIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
host = remaining;
|
server.server = remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathIndex > 0 && (type == "https" || type == "h3"))
|
if (pathIndex > 0 && (server.type == "https" || server.type == "h3"))
|
||||||
{
|
{
|
||||||
path = remaining.Substring(pathIndex);
|
server.path = remaining.Substring(pathIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (type, host, port, path);
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenExperimental(SingboxConfig singboxConfig)
|
private async Task<int> GenExperimental(SingboxConfig singboxConfig)
|
||||||
|
|
@ -1858,7 +2079,8 @@ public class CoreConfigSingboxService
|
||||||
singboxConfig.experimental.cache_file = new CacheFile4Sbox()
|
singboxConfig.experimental.cache_file = new CacheFile4Sbox()
|
||||||
{
|
{
|
||||||
enabled = true,
|
enabled = true,
|
||||||
path = Utils.GetBinPath("cache.db")
|
path = Utils.GetBinPath("cache.db"),
|
||||||
|
store_fakeip = _config.SimpleDNSItem.FakeIP == true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1879,13 +2101,15 @@ public class CoreConfigSingboxService
|
||||||
//convert route geosite & geoip to ruleset
|
//convert route geosite & geoip to ruleset
|
||||||
foreach (var rule in singboxConfig.route.rules.Where(t => t.geosite?.Count > 0).ToList() ?? [])
|
foreach (var rule in singboxConfig.route.rules.Where(t => t.geosite?.Count > 0).ToList() ?? [])
|
||||||
{
|
{
|
||||||
rule.rule_set = rule?.geosite?.Select(t => $"{geosite}-{t}").ToList();
|
rule.rule_set ??= new List<string>();
|
||||||
|
rule.rule_set.AddRange(rule?.geosite?.Select(t => $"{geosite}-{t}").ToList());
|
||||||
rule.geosite = null;
|
rule.geosite = null;
|
||||||
AddRuleSets(ruleSets, rule.rule_set);
|
AddRuleSets(ruleSets, rule.rule_set);
|
||||||
}
|
}
|
||||||
foreach (var rule in singboxConfig.route.rules.Where(t => t.geoip?.Count > 0).ToList() ?? [])
|
foreach (var rule in singboxConfig.route.rules.Where(t => t.geoip?.Count > 0).ToList() ?? [])
|
||||||
{
|
{
|
||||||
rule.rule_set = rule?.geoip?.Select(t => $"{geoip}-{t}").ToList();
|
rule.rule_set ??= new List<string>();
|
||||||
|
rule.rule_set.AddRange(rule?.geoip?.Select(t => $"{geoip}-{t}").ToList());
|
||||||
rule.geoip = null;
|
rule.geoip = null;
|
||||||
AddRuleSets(ruleSets, rule.rule_set);
|
AddRuleSets(ruleSets, rule.rule_set);
|
||||||
}
|
}
|
||||||
|
|
@ -1893,12 +2117,14 @@ public class CoreConfigSingboxService
|
||||||
//convert dns geosite & geoip to ruleset
|
//convert dns geosite & geoip to ruleset
|
||||||
foreach (var rule in singboxConfig.dns?.rules.Where(t => t.geosite?.Count > 0).ToList() ?? [])
|
foreach (var rule in singboxConfig.dns?.rules.Where(t => t.geosite?.Count > 0).ToList() ?? [])
|
||||||
{
|
{
|
||||||
rule.rule_set = rule?.geosite?.Select(t => $"{geosite}-{t}").ToList();
|
rule.rule_set ??= new List<string>();
|
||||||
|
rule.rule_set.AddRange(rule?.geosite?.Select(t => $"{geosite}-{t}").ToList());
|
||||||
rule.geosite = null;
|
rule.geosite = null;
|
||||||
}
|
}
|
||||||
foreach (var rule in singboxConfig.dns?.rules.Where(t => t.geoip?.Count > 0).ToList() ?? [])
|
foreach (var rule in singboxConfig.dns?.rules.Where(t => t.geoip?.Count > 0).ToList() ?? [])
|
||||||
{
|
{
|
||||||
rule.rule_set = rule?.geoip?.Select(t => $"{geoip}-{t}").ToList();
|
rule.rule_set ??= new List<string>();
|
||||||
|
rule.rule_set.AddRange(rule?.geoip?.Select(t => $"{geoip}-{t}").ToList());
|
||||||
rule.geoip = null;
|
rule.geoip = null;
|
||||||
}
|
}
|
||||||
foreach (var dnsRule in singboxConfig.dns?.rules.Where(t => t.rule_set?.Count > 0).ToList() ?? [])
|
foreach (var dnsRule in singboxConfig.dns?.rules.Where(t => t.rule_set?.Count > 0).ToList() ?? [])
|
||||||
|
|
@ -1976,60 +2202,60 @@ public class CoreConfigSingboxService
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ApplyCustomConfig(CustomConfigItem customConfig, SingboxConfig singboxConfig)
|
private async Task<string> ApplyFullConfigTemplate(FullConfigTemplateItem fullConfigTemplate, SingboxConfig singboxConfig)
|
||||||
{
|
{
|
||||||
var customConfigItem = customConfig.Config;
|
var fullConfigTemplateItem = fullConfigTemplate.Config;
|
||||||
if (_config.TunModeItem.EnableTun)
|
if (_config.TunModeItem.EnableTun)
|
||||||
{
|
{
|
||||||
customConfigItem = customConfig.TunConfig;
|
fullConfigTemplateItem = fullConfigTemplate.TunConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!customConfig.Enabled || customConfigItem.IsNullOrEmpty())
|
if (!fullConfigTemplate.Enabled || fullConfigTemplateItem.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return JsonUtils.Serialize(singboxConfig);
|
return JsonUtils.Serialize(singboxConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
var customConfigNode = JsonNode.Parse(customConfigItem);
|
var fullConfigTemplateNode = JsonNode.Parse(fullConfigTemplateItem);
|
||||||
if (customConfigNode == null)
|
if (fullConfigTemplateNode == null)
|
||||||
{
|
{
|
||||||
return JsonUtils.Serialize(singboxConfig);
|
return JsonUtils.Serialize(singboxConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process outbounds
|
// Process outbounds
|
||||||
var customOutboundsNode = customConfigNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray();
|
var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray();
|
||||||
foreach (var outbound in singboxConfig.outbounds)
|
foreach (var outbound in singboxConfig.outbounds)
|
||||||
{
|
{
|
||||||
if (outbound.type.ToLower() is "direct" or "block")
|
if (outbound.type.ToLower() is "direct" or "block")
|
||||||
{
|
{
|
||||||
if (customConfig.AddProxyOnly == true)
|
if (fullConfigTemplate.AddProxyOnly == true)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (outbound.detour.IsNullOrEmpty() && (!customConfig.ProxyDetour.IsNullOrEmpty()) && !Utils.IsPrivateNetwork(outbound.server ?? string.Empty))
|
else if (outbound.detour.IsNullOrEmpty() && (!fullConfigTemplate.ProxyDetour.IsNullOrEmpty()) && !Utils.IsPrivateNetwork(outbound.server ?? string.Empty))
|
||||||
{
|
{
|
||||||
outbound.detour = customConfig.ProxyDetour;
|
outbound.detour = fullConfigTemplate.ProxyDetour;
|
||||||
}
|
}
|
||||||
customOutboundsNode.Add(JsonUtils.DeepCopy(outbound));
|
customOutboundsNode.Add(JsonUtils.DeepCopy(outbound));
|
||||||
}
|
}
|
||||||
customConfigNode["outbounds"] = customOutboundsNode;
|
fullConfigTemplateNode["outbounds"] = customOutboundsNode;
|
||||||
|
|
||||||
// Process endpoints
|
// Process endpoints
|
||||||
if (singboxConfig.endpoints != null && singboxConfig.endpoints.Count > 0)
|
if (singboxConfig.endpoints != null && singboxConfig.endpoints.Count > 0)
|
||||||
{
|
{
|
||||||
var customEndpointsNode = customConfigNode["endpoints"] is JsonArray endpoints ? endpoints : new JsonArray();
|
var customEndpointsNode = fullConfigTemplateNode["endpoints"] is JsonArray endpoints ? endpoints : new JsonArray();
|
||||||
foreach (var endpoint in singboxConfig.endpoints)
|
foreach (var endpoint in singboxConfig.endpoints)
|
||||||
{
|
{
|
||||||
if (endpoint.detour.IsNullOrEmpty() && (!customConfig.ProxyDetour.IsNullOrEmpty()))
|
if (endpoint.detour.IsNullOrEmpty() && (!fullConfigTemplate.ProxyDetour.IsNullOrEmpty()))
|
||||||
{
|
{
|
||||||
endpoint.detour = customConfig.ProxyDetour;
|
endpoint.detour = fullConfigTemplate.ProxyDetour;
|
||||||
}
|
}
|
||||||
customEndpointsNode.Add(JsonUtils.DeepCopy(endpoint));
|
customEndpointsNode.Add(JsonUtils.DeepCopy(endpoint));
|
||||||
}
|
}
|
||||||
customConfigNode["endpoints"] = customEndpointsNode;
|
fullConfigTemplateNode["endpoints"] = customEndpointsNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Task.FromResult(JsonUtils.Serialize(customConfigNode));
|
return await Task.FromResult(JsonUtils.Serialize(fullConfigTemplateNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion private gen function
|
#endregion private gen function
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using ServiceLib.Models;
|
using ServiceLib.Models;
|
||||||
|
|
@ -69,8 +70,8 @@ public class CoreConfigV2rayService
|
||||||
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
|
|
||||||
var customConfig = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray);
|
var fullConfigTemplate = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||||
ret.Data = await ApplyCustomConfig(customConfig, v2rayConfig);
|
ret.Data = await ApplyFullConfigTemplate(fullConfigTemplate, v2rayConfig);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -200,8 +201,8 @@ public class CoreConfigV2rayService
|
||||||
|
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
|
|
||||||
var customConfig = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray);
|
var fullConfigTemplate = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||||
ret.Data = await ApplyCustomConfig(customConfig, v2rayConfig, true);
|
ret.Data = await ApplyFullConfigTemplate(fullConfigTemplate, v2rayConfig, true);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -1140,6 +1141,264 @@ public class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
|
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
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -1182,22 +1441,33 @@ public class CoreConfigV2rayService
|
||||||
var systemHosts = Utils.GetSystemHosts();
|
var systemHosts = Utils.GetSystemHosts();
|
||||||
if (systemHosts.Count > 0)
|
if (systemHosts.Count > 0)
|
||||||
{
|
{
|
||||||
var normalHost = obj["hosts"];
|
var normalHost1 = obj["hosts"];
|
||||||
if (normalHost != null)
|
if (normalHost1 != null)
|
||||||
{
|
{
|
||||||
foreach (var host in systemHosts)
|
foreach (var host in systemHosts)
|
||||||
{
|
{
|
||||||
if (normalHost[host.Key] != null)
|
if (normalHost1[host.Key] != null)
|
||||||
continue;
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -1206,7 +1476,7 @@ public class CoreConfigV2rayService
|
||||||
return 0;
|
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)
|
if (node == null)
|
||||||
{
|
{
|
||||||
|
|
@ -1229,7 +1499,6 @@ public class CoreConfigV2rayService
|
||||||
&& prevNode.ConfigType != EConfigType.Custom
|
&& prevNode.ConfigType != EConfigType.Custom
|
||||||
&& prevNode.ConfigType != EConfigType.Hysteria2
|
&& prevNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& prevNode.ConfigType != EConfigType.TUIC
|
&& prevNode.ConfigType != EConfigType.TUIC
|
||||||
&& prevNode.ConfigType != EConfigType.Anytls
|
|
||||||
&& Utils.IsDomain(prevNode.Address))
|
&& Utils.IsDomain(prevNode.Address))
|
||||||
{
|
{
|
||||||
domainList.Add(prevNode.Address);
|
domainList.Add(prevNode.Address);
|
||||||
|
|
@ -1241,7 +1510,6 @@ public class CoreConfigV2rayService
|
||||||
&& nextNode.ConfigType != EConfigType.Custom
|
&& nextNode.ConfigType != EConfigType.Custom
|
||||||
&& nextNode.ConfigType != EConfigType.Hysteria2
|
&& nextNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& nextNode.ConfigType != EConfigType.TUIC
|
&& nextNode.ConfigType != EConfigType.TUIC
|
||||||
&& nextNode.ConfigType != EConfigType.Anytls
|
|
||||||
&& Utils.IsDomain(nextNode.Address))
|
&& Utils.IsDomain(nextNode.Address))
|
||||||
{
|
{
|
||||||
domainList.Add(nextNode.Address);
|
domainList.Add(nextNode.Address);
|
||||||
|
|
@ -1251,7 +1519,7 @@ public class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
var dnsServer = new DnsServer4Ray()
|
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,
|
skipFallback = true,
|
||||||
domains = domainList
|
domains = domainList
|
||||||
};
|
};
|
||||||
|
|
@ -1576,15 +1844,15 @@ public class CoreConfigV2rayService
|
||||||
return await Task.FromResult(0);
|
return await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ApplyCustomConfig(CustomConfigItem customConfig, V2rayConfig v2rayConfig, bool handleBalancerAndRules = false)
|
private async Task<string> ApplyFullConfigTemplate(FullConfigTemplateItem fullConfigTemplate, V2rayConfig v2rayConfig, bool handleBalancerAndRules = false)
|
||||||
{
|
{
|
||||||
if (!customConfig.Enabled || customConfig.Config.IsNullOrEmpty())
|
if (!fullConfigTemplate.Enabled || fullConfigTemplate.Config.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return JsonUtils.Serialize(v2rayConfig);
|
return JsonUtils.Serialize(v2rayConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
var customConfigNode = JsonNode.Parse(customConfig.Config);
|
var fullConfigTemplateNode = JsonNode.Parse(fullConfigTemplate.Config);
|
||||||
if (customConfigNode == null)
|
if (fullConfigTemplateNode == null)
|
||||||
{
|
{
|
||||||
return JsonUtils.Serialize(v2rayConfig);
|
return JsonUtils.Serialize(v2rayConfig);
|
||||||
}
|
}
|
||||||
|
|
@ -1595,7 +1863,7 @@ public class CoreConfigV2rayService
|
||||||
var balancer = v2rayConfig.routing.balancers.First();
|
var balancer = v2rayConfig.routing.balancers.First();
|
||||||
|
|
||||||
// Modify existing rules in custom config
|
// Modify existing rules in custom config
|
||||||
var rulesNode = customConfigNode["routing"]?["rules"];
|
var rulesNode = fullConfigTemplateNode["routing"]?["rules"];
|
||||||
if (rulesNode != null)
|
if (rulesNode != null)
|
||||||
{
|
{
|
||||||
foreach (var rule in rulesNode.AsArray())
|
foreach (var rule in rulesNode.AsArray())
|
||||||
|
|
@ -1609,13 +1877,13 @@ public class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure routing node exists
|
// Ensure routing node exists
|
||||||
if (customConfigNode["routing"] == null)
|
if (fullConfigTemplateNode["routing"] == null)
|
||||||
{
|
{
|
||||||
customConfigNode["routing"] = new JsonObject();
|
fullConfigTemplateNode["routing"] = new JsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle balancers - append instead of override
|
// Handle balancers - append instead of override
|
||||||
if (customConfigNode["routing"]["balancers"] is JsonArray customBalancersNode)
|
if (fullConfigTemplateNode["routing"]["balancers"] is JsonArray customBalancersNode)
|
||||||
{
|
{
|
||||||
if (JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.routing.balancers)) is JsonArray newBalancers)
|
if (JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.routing.balancers)) is JsonArray newBalancers)
|
||||||
{
|
{
|
||||||
|
|
@ -1627,31 +1895,31 @@ public class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
customConfigNode["routing"]["balancers"] = JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.routing.balancers));
|
fullConfigTemplateNode["routing"]["balancers"] = JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.routing.balancers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle outbounds - append instead of override
|
// Handle outbounds - append instead of override
|
||||||
var customOutboundsNode = customConfigNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray();
|
var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray();
|
||||||
foreach (var outbound in v2rayConfig.outbounds)
|
foreach (var outbound in v2rayConfig.outbounds)
|
||||||
{
|
{
|
||||||
if (outbound.protocol.ToLower() is "blackhole" or "dns" or "freedom")
|
if (outbound.protocol.ToLower() is "blackhole" or "dns" or "freedom")
|
||||||
{
|
{
|
||||||
if (customConfig.AddProxyOnly == true)
|
if (fullConfigTemplate.AddProxyOnly == true)
|
||||||
{
|
{
|
||||||
continue;
|
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)))
|
else if ((outbound.streamSettings?.sockopt?.dialerProxy.IsNullOrEmpty() == true) && (!fullConfigTemplate.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 ??= new StreamSettings4Ray();
|
||||||
outbound.streamSettings.sockopt ??= new Sockopt4Ray();
|
outbound.streamSettings.sockopt ??= new Sockopt4Ray();
|
||||||
outbound.streamSettings.sockopt.dialerProxy = customConfig.ProxyDetour;
|
outbound.streamSettings.sockopt.dialerProxy = fullConfigTemplate.ProxyDetour;
|
||||||
}
|
}
|
||||||
customOutboundsNode.Add(JsonUtils.DeepCopy(outbound));
|
customOutboundsNode.Add(JsonUtils.DeepCopy(outbound));
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Task.FromResult(JsonUtils.Serialize(customConfigNode));
|
return await Task.FromResult(JsonUtils.Serialize(fullConfigTemplateNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion private gen function
|
#endregion private gen function
|
||||||
|
|
|
||||||
|
|
@ -6,39 +6,52 @@ namespace ServiceLib.ViewModels;
|
||||||
|
|
||||||
public class DNSSettingViewModel : MyReactiveObject
|
public class DNSSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
[Reactive] public bool UseSystemHosts { get; set; }
|
[Reactive] public bool? UseSystemHosts { get; set; }
|
||||||
[Reactive] public string DomainStrategy4Freedom { get; set; }
|
[Reactive] public bool? AddCommonHosts { get; set; }
|
||||||
[Reactive] public string DomainDNSAddress { get; set; }
|
[Reactive] public bool? FakeIP { get; set; }
|
||||||
[Reactive] public string NormalDNS { 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 bool UseSystemHostsCompatible { get; set; }
|
||||||
[Reactive] public string DomainDNSAddress2 { get; set; }
|
[Reactive] public string DomainStrategy4FreedomCompatible { get; set; }
|
||||||
[Reactive] public string NormalDNS2 { get; set; }
|
[Reactive] public string DomainDNSAddressCompatible { get; set; }
|
||||||
[Reactive] public string TunDNS2 { 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> SaveCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
|
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCompatibleCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }
|
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCompatibleCmd { get; }
|
||||||
|
|
||||||
public DNSSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
public DNSSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||||
{
|
{
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
_updateView = updateView;
|
_updateView = updateView;
|
||||||
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
|
SaveCmd = ReactiveCommand.CreateFromTask(SaveSettingAsync);
|
||||||
{
|
|
||||||
await SaveSettingAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
|
ImportDefConfig4V2rayCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
NormalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
|
NormalDNSCompatible = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
|
|
||||||
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
|
ImportDefConfig4SingboxCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
NormalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
NormalDNS2Compatible = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
||||||
TunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
|
TunDNS2Compatible = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -47,48 +60,80 @@ public class DNSSettingViewModel : MyReactiveObject
|
||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
_config = AppHandler.Instance.Config;
|
||||||
|
var item = _config.SimpleDNSItem;
|
||||||
UseSystemHosts = item.UseSystemHosts;
|
UseSystemHosts = item.UseSystemHosts;
|
||||||
DomainStrategy4Freedom = item?.DomainStrategy4Freedom ?? string.Empty;
|
AddCommonHosts = item.AddCommonHosts;
|
||||||
DomainDNSAddress = item?.DomainDNSAddress ?? string.Empty;
|
FakeIP = item.FakeIP;
|
||||||
NormalDNS = item?.NormalDNS ?? string.Empty;
|
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);
|
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
DomainStrategy4Freedom2 = item2?.DomainStrategy4Freedom ?? string.Empty;
|
SBCustomDNSEnableCompatible = item2.Enabled;
|
||||||
DomainDNSAddress2 = item2?.DomainDNSAddress ?? string.Empty;
|
DomainStrategy4Freedom2Compatible = item2?.DomainStrategy4Freedom ?? string.Empty;
|
||||||
NormalDNS2 = item2?.NormalDNS ?? string.Empty;
|
DomainDNSAddress2Compatible = item2?.DomainDNSAddress ?? string.Empty;
|
||||||
TunDNS2 = item2?.TunDNS ?? string.Empty;
|
NormalDNS2Compatible = item2?.NormalDNS ?? string.Empty;
|
||||||
|
TunDNS2Compatible = item2?.TunDNS ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveSettingAsync()
|
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)
|
if (obj != null && obj["servers"] != null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (NormalDNS.Contains('{') || NormalDNS.Contains('}'))
|
if (NormalDNSCompatible.Contains('{') || NormalDNSCompatible.Contains('}'))
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NormalDNS2.IsNotEmpty())
|
if (NormalDNS2Compatible.IsNotEmpty())
|
||||||
{
|
{
|
||||||
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2);
|
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2Compatible);
|
||||||
if (obj2 == null)
|
if (obj2 == null)
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TunDNS2.IsNotEmpty())
|
if (TunDNS2Compatible.IsNotEmpty())
|
||||||
{
|
{
|
||||||
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(TunDNS2);
|
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(TunDNS2Compatible);
|
||||||
if (obj2 == null)
|
if (obj2 == null)
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
||||||
|
|
@ -96,21 +141,26 @@ public class DNSSettingViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
var item1 = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||||
item.DomainStrategy4Freedom = DomainStrategy4Freedom;
|
item1.Enabled = RayCustomDNSEnableCompatible;
|
||||||
item.DomainDNSAddress = DomainDNSAddress;
|
item1.DomainStrategy4Freedom = DomainStrategy4FreedomCompatible;
|
||||||
item.UseSystemHosts = UseSystemHosts;
|
item1.DomainDNSAddress = DomainDNSAddressCompatible;
|
||||||
item.NormalDNS = NormalDNS;
|
item1.UseSystemHosts = UseSystemHostsCompatible;
|
||||||
await ConfigHandler.SaveDNSItems(_config, item);
|
item1.NormalDNS = NormalDNSCompatible;
|
||||||
|
await ConfigHandler.SaveDNSItems(_config, item1);
|
||||||
|
|
||||||
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2;
|
item2.Enabled = RayCustomDNSEnableCompatible;
|
||||||
item2.DomainDNSAddress = DomainDNSAddress2;
|
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2Compatible;
|
||||||
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2));
|
item2.DomainDNSAddress = DomainDNSAddress2Compatible;
|
||||||
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2));
|
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2Compatible));
|
||||||
|
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2Compatible));
|
||||||
await ConfigHandler.SaveDNSItems(_config, item2);
|
await ConfigHandler.SaveDNSItems(_config, item2);
|
||||||
|
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
_ = _updateView?.Invoke(EViewAction.CloseWindow, null);
|
if (_updateView != null)
|
||||||
|
{
|
||||||
|
await _updateView(EViewAction.CloseWindow, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,23 @@ using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels;
|
namespace ServiceLib.ViewModels;
|
||||||
public class CustomConfigViewModel : MyReactiveObject
|
public class FullConfigTemplateViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
#region Reactive
|
#region Reactive
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool EnableCustomConfig4Ray { get; set; }
|
public bool EnableFullConfigTemplate4Ray { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool EnableCustomConfig4Singbox { get; set; }
|
public bool EnableFullConfigTemplate4Singbox { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string CustomConfig4Ray { get; set; }
|
public string FullConfigTemplate4Ray { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string CustomConfig4Singbox { get; set; }
|
public string FullConfigTemplate4Singbox { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string CustomTunConfig4Singbox { get; set; }
|
public string FullTunConfigTemplate4Singbox { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool AddProxyOnly4Ray { get; set; }
|
public bool AddProxyOnly4Ray { get; set; }
|
||||||
|
|
@ -37,7 +37,7 @@ public class CustomConfigViewModel : MyReactiveObject
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
#endregion Reactive
|
#endregion Reactive
|
||||||
|
|
||||||
public CustomConfigViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
public FullConfigTemplateViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||||
{
|
{
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
_updateView = updateView;
|
_updateView = updateView;
|
||||||
|
|
@ -50,16 +50,16 @@ public class CustomConfigViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
var item = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray);
|
var item = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||||
EnableCustomConfig4Ray = item?.Enabled ?? false;
|
EnableFullConfigTemplate4Ray = item?.Enabled ?? false;
|
||||||
CustomConfig4Ray = item?.Config ?? string.Empty;
|
FullConfigTemplate4Ray = item?.Config ?? string.Empty;
|
||||||
AddProxyOnly4Ray = item?.AddProxyOnly ?? false;
|
AddProxyOnly4Ray = item?.AddProxyOnly ?? false;
|
||||||
ProxyDetour4Ray = item?.ProxyDetour ?? string.Empty;
|
ProxyDetour4Ray = item?.ProxyDetour ?? string.Empty;
|
||||||
|
|
||||||
var item2 = await AppHandler.Instance.GetCustomConfigItem(ECoreType.sing_box);
|
var item2 = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||||
EnableCustomConfig4Singbox = item2?.Enabled ?? false;
|
EnableFullConfigTemplate4Singbox = item2?.Enabled ?? false;
|
||||||
CustomConfig4Singbox = item2?.Config ?? string.Empty;
|
FullConfigTemplate4Singbox = item2?.Config ?? string.Empty;
|
||||||
CustomTunConfig4Singbox = item2?.TunConfig ?? string.Empty;
|
FullTunConfigTemplate4Singbox = item2?.TunConfig ?? string.Empty;
|
||||||
AddProxyOnly4Singbox = item2?.AddProxyOnly ?? false;
|
AddProxyOnly4Singbox = item2?.AddProxyOnly ?? false;
|
||||||
ProxyDetour4Singbox = item2?.ProxyDetour ?? string.Empty;
|
ProxyDetour4Singbox = item2?.ProxyDetour ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
@ -78,33 +78,33 @@ public class CustomConfigViewModel : MyReactiveObject
|
||||||
|
|
||||||
private async Task<bool> SaveXrayConfigAsync()
|
private async Task<bool> SaveXrayConfigAsync()
|
||||||
{
|
{
|
||||||
var item = await AppHandler.Instance.GetCustomConfigItem(ECoreType.Xray);
|
var item = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||||
item.Enabled = EnableCustomConfig4Ray;
|
item.Enabled = EnableFullConfigTemplate4Ray;
|
||||||
item.Config = null;
|
item.Config = null;
|
||||||
|
|
||||||
item.Config = CustomConfig4Ray;
|
item.Config = FullConfigTemplate4Ray;
|
||||||
|
|
||||||
item.AddProxyOnly = AddProxyOnly4Ray;
|
item.AddProxyOnly = AddProxyOnly4Ray;
|
||||||
item.ProxyDetour = ProxyDetour4Ray;
|
item.ProxyDetour = ProxyDetour4Ray;
|
||||||
|
|
||||||
await ConfigHandler.SaveCustomConfigItem(_config, item);
|
await ConfigHandler.SaveFullConfigTemplate(_config, item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> SaveSingboxConfigAsync()
|
private async Task<bool> SaveSingboxConfigAsync()
|
||||||
{
|
{
|
||||||
var item = await AppHandler.Instance.GetCustomConfigItem(ECoreType.sing_box);
|
var item = await AppHandler.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||||
item.Enabled = EnableCustomConfig4Singbox;
|
item.Enabled = EnableFullConfigTemplate4Singbox;
|
||||||
item.Config = null;
|
item.Config = null;
|
||||||
item.TunConfig = null;
|
item.TunConfig = null;
|
||||||
|
|
||||||
item.Config = CustomConfig4Singbox;
|
item.Config = FullConfigTemplate4Singbox;
|
||||||
item.TunConfig = CustomTunConfig4Singbox;
|
item.TunConfig = FullTunConfigTemplate4Singbox;
|
||||||
|
|
||||||
item.AddProxyOnly = AddProxyOnly4Singbox;
|
item.AddProxyOnly = AddProxyOnly4Singbox;
|
||||||
item.ProxyDetour = ProxyDetour4Singbox;
|
item.ProxyDetour = ProxyDetour4Singbox;
|
||||||
|
|
||||||
await ConfigHandler.SaveCustomConfigItem(_config, item);
|
await ConfigHandler.SaveFullConfigTemplate(_config, item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> RoutingSettingCmd { get; }
|
public ReactiveCommand<Unit, Unit> RoutingSettingCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> DNSSettingCmd { get; }
|
public ReactiveCommand<Unit, Unit> DNSSettingCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> CustomConfigCmd { get; }
|
public ReactiveCommand<Unit, Unit> FullConfigTemplateCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> GlobalHotkeySettingCmd { get; }
|
public ReactiveCommand<Unit, Unit> GlobalHotkeySettingCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> RebootAsAdminCmd { get; }
|
public ReactiveCommand<Unit, Unit> RebootAsAdminCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; }
|
public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; }
|
||||||
|
|
@ -170,9 +170,9 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
await DNSSettingAsync();
|
await DNSSettingAsync();
|
||||||
});
|
});
|
||||||
CustomConfigCmd = ReactiveCommand.CreateFromTask(async () =>
|
FullConfigTemplateCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await CustomConfigAsync();
|
await FullConfigTemplateAsync();
|
||||||
});
|
});
|
||||||
GlobalHotkeySettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
GlobalHotkeySettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
|
|
@ -225,7 +225,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
|
|
||||||
await ConfigHandler.InitBuiltinRouting(_config);
|
await ConfigHandler.InitBuiltinRouting(_config);
|
||||||
await ConfigHandler.InitBuiltinDNS(_config);
|
await ConfigHandler.InitBuiltinDNS(_config);
|
||||||
await ConfigHandler.InitBuiltinCustomConfig(_config);
|
await ConfigHandler.InitBuiltinFullConfigTemplate(_config);
|
||||||
await ProfileExHandler.Instance.Init();
|
await ProfileExHandler.Instance.Init();
|
||||||
await CoreHandler.Instance.Init(_config, UpdateHandler);
|
await CoreHandler.Instance.Init(_config, UpdateHandler);
|
||||||
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
||||||
|
|
@ -514,9 +514,9 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CustomConfigAsync()
|
private async Task FullConfigTemplateAsync()
|
||||||
{
|
{
|
||||||
var ret = await _updateView?.Invoke(EViewAction.CustomConfigWindow, null);
|
var ret = await _updateView?.Invoke(EViewAction.FullConfigTemplateWindow, null);
|
||||||
if (ret == true)
|
if (ret == true)
|
||||||
{
|
{
|
||||||
await Reload();
|
await Reload();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
x:Class="v2rayN.Desktop.Views.DNSSettingWindow"
|
x:Class="v2rayN.Desktop.Views.DNSSettingWindow"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
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:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
|
|
@ -35,9 +36,282 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TabControl HorizontalContentAlignment="Stretch">
|
<TabControl HorizontalContentAlignment="Stretch">
|
||||||
|
<TabItem Header="{x:Static resx:ResUI.ThBasicDNSSettings}">
|
||||||
|
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||||
|
<Grid
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
ColumnDefinitions="Auto,Auto,*"
|
||||||
|
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
x:Name="txtBasicDNSSettingsInvalid"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbDomesticDNS}" />
|
||||||
|
<ctrls:AutoCompleteBox
|
||||||
|
x:Name="cmbDirectDNS"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Text="{Binding DirectDNS, Mode=TwoWay}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbRemoteDNS}" />
|
||||||
|
<ctrls:AutoCompleteBox
|
||||||
|
x:Name="cmbRemoteDNS"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Text="{Binding RemoteDNS, Mode=TwoWay}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBOutboundsResolverDNS}" />
|
||||||
|
<ctrls:AutoCompleteBox
|
||||||
|
x:Name="cmbSBResolverDNS"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Text="{Binding SingboxOutboundsResolveDNS, Mode=TwoWay}" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBOutboundDomainResolve}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBDoHResolverServer}" />
|
||||||
|
<ctrls:AutoCompleteBox
|
||||||
|
x:Name="cmbSBFinalResolverDNS"
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Text="{Binding SingboxFinalResolveDNS, Mode=TwoWay}" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBFallbackDNSResolve}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="5"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbXrayFreedomResolveStrategy}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbRayFreedomDNSStrategy"
|
||||||
|
Grid.Row="5"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
PlaceholderText="Default" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="6"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbSBDirectDNSStrategy"
|
||||||
|
Grid.Row="6"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
PlaceholderText="Default" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="7"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbSBRemoteDNSStrategy"
|
||||||
|
Grid.Row="7"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
PlaceholderText="Default" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togAddCommonHosts"
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbSBDoHOverride}" />
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem Header="{x:Static resx:ResUI.ThAdvancedDNSSettings}">
|
||||||
|
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||||
|
<Grid
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
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"
|
||||||
|
BorderThickness="1"
|
||||||
|
Classes="TextArea"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Watermark="{x:Static resx:ResUI.TbDNSHostsConfig}" />
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
|
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
<Grid DockPanel.Dock="Top">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togRayCustomDNSEnableCompatible"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
|
@ -49,11 +323,12 @@
|
||||||
</HyperlinkButton>
|
</HyperlinkButton>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnImportDefConfig4V2ray"
|
x:Name="btnImportDefConfig4V2rayCompatible"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||||
Cursor="Hand" />
|
Cursor="Hand" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|
@ -62,7 +337,7 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
x:Name="togUseSystemHosts"
|
x:Name="togUseSystemHostsCompatible"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -73,7 +348,7 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbdomainStrategy4Freedom"
|
x:Name="cmbdomainStrategy4FreedomCompatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -83,10 +358,11 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||||
<ComboBox
|
<ctrls:AutoCompleteBox
|
||||||
x:Name="cmbdomainDNSAddress"
|
x:Name="cmbdomainDNSAddressCompatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}"
|
||||||
|
Text="{Binding DomainDNSAddressCompatible, Mode=TwoWay}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
|
|
@ -96,7 +372,7 @@
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="HTTP/SOCKS">
|
Header="HTTP/SOCKS">
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="txtnormalDNS"
|
Name="txtnormalDNSCompatible"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
MinLines="10"
|
MinLines="10"
|
||||||
|
|
@ -107,18 +383,36 @@
|
||||||
|
|
||||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
<Grid DockPanel.Dock="Top">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togSBCustomDNSEnableCompatible"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||||
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
|
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
|
||||||
<HyperlinkButton Classes="WithIcon" Click="linkDnsSingboxObjectDoc_Click">
|
<HyperlinkButton Classes="WithIcon" Click="linkDnsSingboxObjectDoc_Click">
|
||||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
||||||
</HyperlinkButton>
|
</HyperlinkButton>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnImportDefConfig4Singbox"
|
x:Name="btnImportDefConfig4SingboxCompatible"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||||
Cursor="Hand" />
|
Cursor="Hand" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|
@ -127,7 +421,7 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbdomainStrategy4Out"
|
x:Name="cmbdomainStrategy4OutCompatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -137,10 +431,11 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||||
<ComboBox
|
<ctrls:AutoCompleteBox
|
||||||
x:Name="cmbdomainDNSAddress2"
|
x:Name="cmbdomainDNSAddress2Compatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}"
|
||||||
|
Text="{Binding DomainDNSAddress2Compatible, Mode=TwoWay}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
|
|
@ -152,7 +447,7 @@
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="HTTP/SOCKS">
|
Header="HTTP/SOCKS">
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="txtnormalDNS2"
|
Name="txtnormalDNS2Compatible"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
MinLines="10"
|
MinLines="10"
|
||||||
|
|
@ -167,7 +462,7 @@
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
|
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="txttunDNS2"
|
Name="txttunDNS2Compatible"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
MinLines="10"
|
MinLines="10"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using v2rayN.Desktop.Base;
|
using v2rayN.Desktop.Base;
|
||||||
|
|
@ -17,26 +18,64 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
|
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||||
cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
|
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||||
cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
|
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||||
cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
|
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.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(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.AddCommonHosts, v => v.togAddCommonHosts.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FakeIP, v => v.togFakeIP.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).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.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.SelectedValue).DisposeWith(disposables);
|
//this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.SelectedValue).DisposeWith(disposables);
|
//this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
//this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.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.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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
<Window
|
<Window
|
||||||
x:Class="v2rayN.Desktop.Views.CustomConfigWindow"
|
x:Class="v2rayN.Desktop.Views.FullConfigTemplateWindow"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuCustomConfig}"
|
Title="{x:Static resx:ResUI.menuFullConfigTemplate}"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="600"
|
Height="600"
|
||||||
x:DataType="vms:CustomConfigViewModel"
|
x:DataType="vms:FullConfigTemplateViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
@ -35,25 +35,33 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TabControl HorizontalContentAlignment="Stretch">
|
<TabControl HorizontalContentAlignment="Stretch">
|
||||||
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRayCustomConfig}">
|
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRayFullConfigTemplate}">
|
||||||
<DockPanel Margin="{StaticResource Margin4}">
|
<DockPanel Margin="{StaticResource Margin4}">
|
||||||
<Grid DockPanel.Dock="Top" RowDefinitions="Auto,Auto">
|
<Grid DockPanel.Dock="Top" RowDefinitions="Auto,Auto,Auto">
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbRayCustomConfigDesc}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateDesc}"
|
||||||
</StackPanel>
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<HyperlinkButton Classes="WithIcon" Click="linkFullConfigTemplateDoc_Click">
|
||||||
|
<TextBlock Text="{x:Static resx:ResUI.TbRayFullConfigTemplateDesc}" />
|
||||||
|
</HyperlinkButton>
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbCustomConfigEnable}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateEnable}" />
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
x:Name="rayCustomConfigEnable"
|
x:Name="rayFullConfigTemplateEnable"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -87,9 +95,9 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="xray json config">
|
Header="xray config template json">
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="rayCustomConfig"
|
x:Name="rayFullConfigTemplate"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
MinLines="10"
|
MinLines="10"
|
||||||
|
|
@ -97,25 +105,33 @@
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbCustomConfigSingbox}">
|
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbSBFullConfigTemplate}">
|
||||||
<DockPanel Margin="{StaticResource Margin4}">
|
<DockPanel Margin="{StaticResource Margin4}">
|
||||||
<Grid DockPanel.Dock="Top" RowDefinitions="Auto,Auto">
|
<Grid DockPanel.Dock="Top" RowDefinitions="Auto,Auto,Auto">
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbSBCustomConfigDesc}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateDesc}"
|
||||||
</StackPanel>
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<HyperlinkButton Classes="WithIcon" Click="linkFullConfigTemplateDoc_Click">
|
||||||
|
<TextBlock Text="{x:Static resx:ResUI.TbSBFullConfigTemplateDesc}" />
|
||||||
|
</HyperlinkButton>
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbCustomConfigEnable}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateEnable}" />
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
x:Name="sbCustomConfigEnable"
|
x:Name="sbFullConfigTemplateEnable"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -151,9 +167,9 @@
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="sing-box json config">
|
Header="sing-box config template json">
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="sbCustomConfig"
|
x:Name="sbFullConfigTemplate"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
MinLines="10"
|
MinLines="10"
|
||||||
|
|
@ -166,9 +182,9 @@
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="sing-box json tun config">
|
Header="sing-box tun config template json">
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="sbCustomTunConfig"
|
x:Name="sbFullTunConfigTemplate"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
MinLines="10"
|
MinLines="10"
|
||||||
|
|
@ -5,27 +5,27 @@ using v2rayN.Desktop.Base;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views;
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
||||||
public partial class CustomConfigWindow : WindowBase<CustomConfigViewModel>
|
public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateViewModel>
|
||||||
{
|
{
|
||||||
private static Config _config;
|
private static Config _config;
|
||||||
|
|
||||||
public CustomConfigWindow()
|
public FullConfigTemplateWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
ViewModel = new CustomConfigViewModel(UpdateViewHandler);
|
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm => vm.EnableCustomConfig4Ray, v => v.rayCustomConfigEnable.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Ray, v => v.rayFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CustomConfig4Ray, v => v.rayCustomConfig.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FullConfigTemplate4Ray, v => v.rayFullConfigTemplate.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AddProxyOnly4Ray, v => v.togAddProxyProtocolOutboundOnly4Ray.IsChecked).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.ProxyDetour4Ray, v => v.txtProxyDetour4Ray.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableCustomConfig4Singbox, v => v.sbCustomConfigEnable.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Singbox, v => v.sbFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CustomConfig4Singbox, v => v.sbCustomConfig.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FullConfigTemplate4Singbox, v => v.sbFullConfigTemplate.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CustomTunConfig4Singbox, v => v.sbCustomTunConfig.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FullTunConfigTemplate4Singbox, v => v.sbFullTunConfigTemplate.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AddProxyOnly4Singbox, v => v.togAddProxyProtocolOutboundOnly4Singbox.IsChecked).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.Bind(ViewModel, vm => vm.ProxyDetour4Singbox, v => v.txtProxyDetour4Singbox.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
|
|
@ -43,4 +43,9 @@ public partial class CustomConfigWindow : WindowBase<CustomConfigViewModel>
|
||||||
}
|
}
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void linkFullConfigTemplateDoc_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ProcUtils.ProcessStart("https://github.com/2dust/v2rayN/wiki/Description-of-some-ui#%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF%E8%AE%BE%E7%BD%AE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
<MenuItem x:Name="menuOptionSetting" Header="{x:Static resx:ResUI.menuOptionSetting}" />
|
<MenuItem x:Name="menuOptionSetting" Header="{x:Static resx:ResUI.menuOptionSetting}" />
|
||||||
<MenuItem x:Name="menuRoutingSetting" Header="{x:Static resx:ResUI.menuRoutingSetting}" />
|
<MenuItem x:Name="menuRoutingSetting" Header="{x:Static resx:ResUI.menuRoutingSetting}" />
|
||||||
<MenuItem x:Name="menuDNSSetting" Header="{x:Static resx:ResUI.menuDNSSetting}" />
|
<MenuItem x:Name="menuDNSSetting" Header="{x:Static resx:ResUI.menuDNSSetting}" />
|
||||||
<MenuItem x:Name="menuCustomConfig" Header="{x:Static resx:ResUI.menuCustomConfig}" />
|
<MenuItem x:Name="menuFullConfigTemplate" Header="{x:Static resx:ResUI.menuFullConfigTemplate}" />
|
||||||
<MenuItem x:Name="menuGlobalHotkeySetting" Header="{x:Static resx:ResUI.menuGlobalHotkeySetting}" />
|
<MenuItem x:Name="menuGlobalHotkeySetting" Header="{x:Static resx:ResUI.menuGlobalHotkeySetting}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem x:Name="menuRebootAsAdmin" Header="{x:Static resx:ResUI.menuRebootAsAdmin}" />
|
<MenuItem x:Name="menuRebootAsAdmin" Header="{x:Static resx:ResUI.menuRebootAsAdmin}" />
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
this.BindCommand(ViewModel, vm => vm.OptionSettingCmd, v => v.menuOptionSetting).DisposeWith(disposables);
|
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.RoutingSettingCmd, v => v.menuRoutingSetting).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.DNSSettingCmd, v => v.menuDNSSetting).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.FullConfigTemplateCmd, v => v.menuFullConfigTemplate).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.GlobalHotkeySettingCmd, v => v.menuGlobalHotkeySetting).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.RebootAsAdminCmd, v => v.menuRebootAsAdmin).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables);
|
||||||
|
|
@ -191,8 +191,8 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
case EViewAction.DNSSettingWindow:
|
case EViewAction.DNSSettingWindow:
|
||||||
return await new DNSSettingWindow().ShowDialog<bool>(this);
|
return await new DNSSettingWindow().ShowDialog<bool>(this);
|
||||||
|
|
||||||
case EViewAction.CustomConfigWindow:
|
case EViewAction.FullConfigTemplateWindow:
|
||||||
return await new CustomConfigWindow().ShowDialog<bool>(this);
|
return await new FullConfigTemplateWindow().ShowDialog<bool>(this);
|
||||||
|
|
||||||
case EViewAction.RoutingSettingWindow:
|
case EViewAction.RoutingSettingWindow:
|
||||||
return await new RoutingSettingWindow().ShowDialog<bool>(this);
|
return await new RoutingSettingWindow().ShowDialog<bool>(this);
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@
|
||||||
<EmbeddedResource Include="Assets\v2rayN.ico">
|
<EmbeddedResource Include="Assets\v2rayN.ico">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<Compile Update="Views\FullConfigTemplateWindow.axaml.cs">
|
||||||
|
<DependentUpon>FullConfigTemplateWindow.axaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<None Update="v2rayN.png">
|
<None Update="v2rayN.png">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ClashConnectionsView"
|
x:Class="v2rayN.Views.ClashConnectionsView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ClashProxiesView"
|
x:Class="v2rayN.Views.ClashProxiesView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:converters="clr-namespace:v2rayN.Converters"
|
||||||
|
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
xmlns:converters="clr-namespace:v2rayN.Converters"
|
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
x:TypeArguments="vms:ClashProxiesViewModel"
|
x:TypeArguments="vms:ClashProxiesViewModel"
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,338 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TabControl HorizontalContentAlignment="Left">
|
<TabControl HorizontalContentAlignment="Left">
|
||||||
|
<TabItem Header="{x:Static resx:ResUI.ThBasicDNSSettings}">
|
||||||
|
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||||
|
<Grid Margin="{StaticResource Margin8}">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
x:Name="txtBasicDNSSettingsInvalid"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="3"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbDomesticDNS}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbDirectDNS"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
IsEditable="True"
|
||||||
|
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"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
IsEditable="True"
|
||||||
|
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"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
IsEditable="True"
|
||||||
|
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"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
IsEditable="True"
|
||||||
|
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"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
IsEditable="True"
|
||||||
|
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}">
|
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
<Grid DockPanel.Dock="Top">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togRayCustomDNSEnableCompatible"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
|
@ -60,12 +388,13 @@
|
||||||
</Hyperlink>
|
</Hyperlink>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnImportDefConfig4V2ray"
|
x:Name="btnImportDefConfig4V2rayCompatible"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
Style="{StaticResource DefButton}" />
|
Style="{StaticResource DefButton}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|
@ -75,7 +404,7 @@
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="togUseSystemHosts"
|
x:Name="togUseSystemHostsCompatible"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -87,7 +416,7 @@
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbdomainStrategy4Freedom"
|
x:Name="cmbdomainStrategy4FreedomCompatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
@ -100,7 +429,7 @@
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbdomainDNSAddress"
|
x:Name="cmbdomainDNSAddressCompatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
IsEditable="True"
|
IsEditable="True"
|
||||||
|
|
@ -109,7 +438,7 @@
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtnormalDNS"
|
x:Name="txtnormalDNSCompatible"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
||||||
|
|
@ -123,7 +452,25 @@
|
||||||
|
|
||||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
<Grid DockPanel.Dock="Top">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togSBCustomDNSEnableCompatible"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
|
@ -134,12 +481,13 @@
|
||||||
</Hyperlink>
|
</Hyperlink>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnImportDefConfig4Singbox"
|
x:Name="btnImportDefConfig4SingboxCompatible"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
Style="{StaticResource DefButton}" />
|
Style="{StaticResource DefButton}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|
@ -149,7 +497,7 @@
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbdomainStrategy4Out"
|
x:Name="cmbdomainStrategy4OutCompatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
@ -162,7 +510,7 @@
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbdomainDNSAddress2"
|
x:Name="cmbdomainDNSAddress2Compatible"
|
||||||
Width="150"
|
Width="150"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
IsEditable="True"
|
IsEditable="True"
|
||||||
|
|
@ -178,7 +526,7 @@
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtnormalDNS2"
|
x:Name="txtnormalDNS2Compatible"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
||||||
|
|
@ -191,7 +539,7 @@
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txttunDNS2"
|
x:Name="txttunDNS2Compatible"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsTunMode}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsTunMode}"
|
||||||
|
|
|
||||||
|
|
@ -17,26 +17,66 @@ public partial class DNSSettingWindow
|
||||||
|
|
||||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
cmbdomainStrategy4Freedom.ItemsSource = Global.DomainStrategy4Freedoms;
|
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||||
cmbdomainStrategy4Out.ItemsSource = Global.SingboxDomainStrategy4Out;
|
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||||
cmbdomainDNSAddress.ItemsSource = Global.DomainDNSAddress;
|
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||||
cmbdomainDNSAddress2.ItemsSource = Global.SingboxDomainDNSAddress;
|
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.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(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.AddCommonHosts, v => v.togAddCommonHosts.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FakeIP, v => v.togFakeIP.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).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.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.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.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);
|
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<base:WindowBase
|
<base:WindowBase
|
||||||
x:Class="v2rayN.Views.CustomConfigWindow"
|
x:Class="v2rayN.Views.FullConfigTemplateWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:base="clr-namespace:v2rayN.Base"
|
xmlns:base="clr-namespace:v2rayN.Base"
|
||||||
|
|
@ -9,10 +9,10 @@
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuCustomConfig}"
|
Title="{x:Static resx:ResUI.menuFullConfigTemplate}"
|
||||||
Width="1000"
|
Width="1000"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:CustomConfigViewModel"
|
x:TypeArguments="vms:FullConfigTemplateViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|
@ -41,31 +41,42 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TabControl HorizontalContentAlignment="Left">
|
<TabControl HorizontalContentAlignment="Left">
|
||||||
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRayCustomConfig}">
|
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRayFullConfigTemplate}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<Grid DockPanel.Dock="Top">
|
<Grid DockPanel.Dock="Top">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbRayCustomConfigDesc}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateDesc}"
|
||||||
</StackPanel>
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}">
|
||||||
|
<Hyperlink Click="linkFullConfigTemplateDoc_Click">
|
||||||
|
<TextBlock Text="{x:Static resx:ResUI.TbRayFullConfigTemplateDesc}" />
|
||||||
|
<materialDesign:PackIcon Kind="Link" />
|
||||||
|
</Hyperlink>
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbCustomConfigEnable}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateEnable}" />
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="rayCustomConfigEnable"
|
x:Name="rayFullConfigTemplateEnable"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -99,10 +110,10 @@
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="rayCustomConfig"
|
x:Name="rayFullConfigTemplate"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
materialDesign:HintAssist.Hint="xray json config"
|
materialDesign:HintAssist.Hint="xray config template json"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
||||||
|
|
@ -110,31 +121,42 @@
|
||||||
VerticalScrollBarVisibility="Auto" />
|
VerticalScrollBarVisibility="Auto" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbCustomConfigSingbox}">
|
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbSBFullConfigTemplate}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<Grid DockPanel.Dock="Top">
|
<Grid DockPanel.Dock="Top">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSBCustomConfigDesc}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateDesc}"
|
||||||
</StackPanel>
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}">
|
||||||
|
<Hyperlink Click="linkFullConfigTemplateDoc_Click">
|
||||||
|
<TextBlock Text="{x:Static resx:ResUI.TbSBFullConfigTemplateDesc}" />
|
||||||
|
<materialDesign:PackIcon Kind="Link" />
|
||||||
|
</Hyperlink>
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbCustomConfigEnable}" />
|
Text="{x:Static resx:ResUI.TbFullConfigTemplateEnable}" />
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="sbCustomConfigEnable"
|
x:Name="sbFullConfigTemplateEnable"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
@ -175,10 +197,10 @@
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="sbCustomConfig"
|
x:Name="sbFullConfigTemplate"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
materialDesign:HintAssist.Hint="sing-box json config"
|
materialDesign:HintAssist.Hint="sing-box config template json"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
||||||
|
|
@ -188,10 +210,10 @@
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="sbCustomTunConfig"
|
x:Name="sbFullTunConfigTemplate"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
materialDesign:HintAssist.Hint="sing-box json tun config"
|
materialDesign:HintAssist.Hint="sing-box tun config template json"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
||||||
|
|
@ -4,28 +4,28 @@ using ReactiveUI;
|
||||||
|
|
||||||
namespace v2rayN.Views;
|
namespace v2rayN.Views;
|
||||||
|
|
||||||
public partial class CustomConfigWindow
|
public partial class FullConfigTemplateWindow
|
||||||
{
|
{
|
||||||
private static Config _config;
|
private static Config _config;
|
||||||
|
|
||||||
public CustomConfigWindow()
|
public FullConfigTemplateWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
|
|
||||||
ViewModel = new CustomConfigViewModel(UpdateViewHandler);
|
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm => vm.EnableCustomConfig4Ray, v => v.rayCustomConfigEnable.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Ray, v => v.rayFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CustomConfig4Ray, v => v.rayCustomConfig.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FullConfigTemplate4Ray, v => v.rayFullConfigTemplate.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AddProxyOnly4Ray, v => v.togAddProxyProtocolOutboundOnly4Ray.IsChecked).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.ProxyDetour4Ray, v => v.txtProxyDetour4Ray.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableCustomConfig4Singbox, v => v.sbCustomConfigEnable.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Singbox, v => v.sbFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CustomConfig4Singbox, v => v.sbCustomConfig.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FullConfigTemplate4Singbox, v => v.sbFullConfigTemplate.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CustomTunConfig4Singbox, v => v.sbCustomTunConfig.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.FullTunConfigTemplate4Singbox, v => v.sbFullTunConfigTemplate.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AddProxyOnly4Singbox, v => v.togAddProxyProtocolOutboundOnly4Singbox.IsChecked).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.Bind(ViewModel, vm => vm.ProxyDetour4Singbox, v => v.txtProxyDetour4Singbox.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
|
|
@ -44,4 +44,9 @@ public partial class CustomConfigWindow
|
||||||
}
|
}
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void linkFullConfigTemplateDoc_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ProcUtils.ProcessStart("https://github.com/2dust/v2rayN/wiki/Description-of-some-ui#%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF%E8%AE%BE%E7%BD%AE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,9 +174,9 @@
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuDNSSetting}" />
|
Header="{x:Static resx:ResUI.menuDNSSetting}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuCustomConfig"
|
x:Name="menuFullConfigTemplate"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuCustomConfig}" />
|
Header="{x:Static resx:ResUI.menuFullConfigTemplate}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuGlobalHotkeySetting"
|
x:Name="menuGlobalHotkeySetting"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ public partial class MainWindow
|
||||||
this.BindCommand(ViewModel, vm => vm.OptionSettingCmd, v => v.menuOptionSetting).DisposeWith(disposables);
|
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.RoutingSettingCmd, v => v.menuRoutingSetting).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.DNSSettingCmd, v => v.menuDNSSetting).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.FullConfigTemplateCmd, v => v.menuFullConfigTemplate).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.GlobalHotkeySettingCmd, v => v.menuGlobalHotkeySetting).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.RebootAsAdminCmd, v => v.menuRebootAsAdmin).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables);
|
||||||
|
|
@ -187,8 +187,8 @@ public partial class MainWindow
|
||||||
case EViewAction.OptionSettingWindow:
|
case EViewAction.OptionSettingWindow:
|
||||||
return (new OptionSettingWindow().ShowDialog() ?? false);
|
return (new OptionSettingWindow().ShowDialog() ?? false);
|
||||||
|
|
||||||
case EViewAction.CustomConfigWindow:
|
case EViewAction.FullConfigTemplateWindow:
|
||||||
return (new CustomConfigWindow().ShowDialog() ?? false);
|
return (new FullConfigTemplateWindow().ShowDialog() ?? false);
|
||||||
|
|
||||||
case EViewAction.GlobalHotkeySettingWindow:
|
case EViewAction.GlobalHotkeySettingWindow:
|
||||||
return (new GlobalHotkeySettingWindow().ShowDialog() ?? false);
|
return (new GlobalHotkeySettingWindow().ShowDialog() ?? false);
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,7 @@
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
||||||
DisplayMemberPath="Remarks"
|
DisplayMemberPath="Remarks"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
|
Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
|
||||||
</ComboBox>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
|
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
|
||||||
|
|
@ -185,8 +184,7 @@
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
||||||
DisplayMemberPath="Remarks"
|
DisplayMemberPath="Remarks"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFilledComboBox}">
|
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||||
</ComboBox>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
@ -200,8 +198,7 @@
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
|
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
|
||||||
DisplayMemberPath="Text"
|
DisplayMemberPath="Text"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFilledComboBox}">
|
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||||
</ComboBox>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue