mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-26 18:24:43 +00:00
Compare commits
7 commits
cb486f69b7
...
330044e5df
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
330044e5df | ||
|
|
a87a015c03 | ||
|
|
c559914ff7 | ||
|
|
436d95576e | ||
|
|
c20d5b3208 | ||
|
|
54e83391d0 | ||
|
|
3e0578f775 |
26 changed files with 315 additions and 67 deletions
|
|
@ -9,6 +9,31 @@ public class JsonUtils
|
|||
{
|
||||
private static readonly string _tag = "JsonUtils";
|
||||
|
||||
private static readonly JsonSerializerOptions _defaultDeserializeOptions = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _defaultSerializeOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _nullValueSerializeOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
|
||||
private static readonly JsonDocumentOptions _defaultDocumentOptions = new()
|
||||
{
|
||||
CommentHandling = JsonCommentHandling.Skip
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// DeepCopy
|
||||
/// </summary>
|
||||
|
|
@ -34,11 +59,7 @@ public class JsonUtils
|
|||
{
|
||||
return default;
|
||||
}
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
return JsonSerializer.Deserialize<T>(strJson, options);
|
||||
return JsonSerializer.Deserialize<T>(strJson, _defaultDeserializeOptions);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -59,7 +80,7 @@ public class JsonUtils
|
|||
{
|
||||
return null;
|
||||
}
|
||||
return JsonNode.Parse(strJson);
|
||||
return JsonNode.Parse(strJson, nodeOptions: null, _defaultDocumentOptions);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -84,12 +105,7 @@ public class JsonUtils
|
|||
{
|
||||
return result;
|
||||
}
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = indented,
|
||||
DefaultIgnoreCondition = nullValue ? JsonIgnoreCondition.Never : JsonIgnoreCondition.WhenWritingNull,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
var options = nullValue ? _nullValueSerializeOptions : _defaultSerializeOptions;
|
||||
result = JsonSerializer.Serialize(obj, options);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -331,6 +331,32 @@ public class Utils
|
|||
.ToList();
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<string>> ParseHostsToDictionary(string hostsContent)
|
||||
{
|
||||
var userHostsMap = hostsContent
|
||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(line => line.Trim())
|
||||
// skip full-line comments
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))
|
||||
// strip inline comments (truncate at '#')
|
||||
.Select(line =>
|
||||
{
|
||||
var index = line.IndexOf('#');
|
||||
return index >= 0 ? line.Substring(0, index).Trim() : line;
|
||||
})
|
||||
// ensure line still contains valid parts
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
||||
.Select(line => line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Where(parts => parts.Length >= 2)
|
||||
.GroupBy(parts => parts[0])
|
||||
.ToDictionary(
|
||||
group => group.Key,
|
||||
group => group.SelectMany(parts => parts.Skip(1)).ToList()
|
||||
);
|
||||
|
||||
return userHostsMap;
|
||||
}
|
||||
|
||||
#endregion 转换函数
|
||||
|
||||
#region 数据检查
|
||||
|
|
@ -857,6 +883,55 @@ public class Utils
|
|||
return false;
|
||||
}
|
||||
|
||||
public static bool IsPackagedInstall()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsWindows() || IsOSX())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPIMAGE")))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var exePath = GetExePath();
|
||||
var baseDir = string.IsNullOrEmpty(exePath) ? StartupPath() : Path.GetDirectoryName(exePath) ?? "";
|
||||
var p = baseDir.Replace('\\', '/');
|
||||
|
||||
if (string.IsNullOrEmpty(p))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p.Contains("/.mount_", StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (p.StartsWith("/opt/v2rayN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (p.StartsWith("/usr/lib/v2rayN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (p.StartsWith("/usr/share/v2rayN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static async Task<string?> GetLinuxUserId()
|
||||
{
|
||||
var arg = new List<string>() { "-c", "id -u" };
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public class Global
|
|||
public const string ProxySetLinuxShellFileName = NamespaceSample + "proxy_set_linux_sh";
|
||||
public const string KillAsSudoOSXShellFileName = NamespaceSample + "kill_as_sudo_osx_sh";
|
||||
public const string KillAsSudoLinuxShellFileName = NamespaceSample + "kill_as_sudo_linux_sh";
|
||||
public const string SingboxFakeIPFilterFileName = NamespaceSample + "singbox_fakeip_filter";
|
||||
|
||||
public const string DefaultSecurity = "auto";
|
||||
public const string DefaultNetwork = "tcp";
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ public static class ConfigHandler
|
|||
config.ConstItem ??= new ConstItem();
|
||||
|
||||
config.SimpleDNSItem ??= InitBuiltinSimpleDNS();
|
||||
if (config.SimpleDNSItem.GlobalFakeIp is null)
|
||||
{
|
||||
config.SimpleDNSItem.GlobalFakeIp = true;
|
||||
}
|
||||
|
||||
config.SpeedTestItem ??= new();
|
||||
if (config.SpeedTestItem.SpeedTestTimeout < 10)
|
||||
|
|
@ -2221,6 +2225,7 @@ public static class ConfigHandler
|
|||
UseSystemHosts = false,
|
||||
AddCommonHosts = true,
|
||||
FakeIP = false,
|
||||
GlobalFakeIp = true,
|
||||
BlockBindingQuery = true,
|
||||
DirectDNS = Global.DomainDirectDNSAddress.FirstOrDefault(),
|
||||
RemoteDNS = Global.DomainRemoteDNSAddress.FirstOrDefault(),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ public class ClashFmt : BaseFmt
|
|||
{
|
||||
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
||||
{
|
||||
if (Contains(strData, "port", "socks-port", "proxies"))
|
||||
if (Contains(strData, "external-controller", "-port", "proxies"))
|
||||
{
|
||||
var fileName = WriteAllText(strData, "yaml");
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ public class SimpleDNSItem
|
|||
public bool? UseSystemHosts { get; set; }
|
||||
public bool? AddCommonHosts { get; set; }
|
||||
public bool? FakeIP { get; set; }
|
||||
public bool? GlobalFakeIp { get; set; }
|
||||
public bool? BlockBindingQuery { get; set; }
|
||||
public string? DirectDNS { get; set; }
|
||||
public string? RemoteDNS { get; set; }
|
||||
|
|
|
|||
18
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
18
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
|
@ -2301,15 +2301,6 @@ namespace ServiceLib.Resx {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Apply to Proxy Domains Only 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbApplyProxyDomainsOnly {
|
||||
get {
|
||||
return ResourceManager.GetString("TbApplyProxyDomainsOnly", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Auto refresh 的本地化字符串。
|
||||
/// </summary>
|
||||
|
|
@ -2526,6 +2517,15 @@ namespace ServiceLib.Resx {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Applies globally by default, with built-in FakeIP filtering (sing-box only). 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbFakeIPTips {
|
||||
get {
|
||||
return ResourceManager.GetString("TbFakeIPTips", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fingerprint 的本地化字符串。
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1455,9 +1455,6 @@
|
|||
<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>
|
||||
|
|
@ -1515,4 +1512,7 @@
|
|||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>Select Profile</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>Applies globally by default, with built-in FakeIP filtering (sing-box only).</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1455,9 +1455,6 @@
|
|||
<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>
|
||||
|
|
@ -1515,4 +1512,7 @@
|
|||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>Select Profile</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>Applies globally by default, with built-in FakeIP filtering (sing-box only).</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1455,9 +1455,6 @@
|
|||
<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>
|
||||
|
|
@ -1515,4 +1512,7 @@
|
|||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>Select Profile</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>Applies globally by default, with built-in FakeIP filtering (sing-box only).</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1455,9 +1455,6 @@
|
|||
<data name="TbDNSHostsConfig" xml:space="preserve">
|
||||
<value>DNS hosts: (каждая строка в формате "domain1 ip1 ip2")</value>
|
||||
</data>
|
||||
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
|
||||
<value>Применять только к доменам через прокси</value>
|
||||
</data>
|
||||
<data name="ThBasicDNSSettings" xml:space="preserve">
|
||||
<value>Базовые настройки DNS</value>
|
||||
</data>
|
||||
|
|
@ -1515,4 +1512,7 @@
|
|||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>Select Profile</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>Applies globally by default, with built-in FakeIP filtering (sing-box only).</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1452,9 +1452,6 @@
|
|||
<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>
|
||||
|
|
@ -1512,4 +1509,7 @@
|
|||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>选择配置文件</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>默认全局生效,内置 FakeIP 过滤,仅在 sing-box 中生效</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1452,9 +1452,6 @@
|
|||
<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>
|
||||
|
|
@ -1512,4 +1509,7 @@
|
|||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>Select Profile</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>Applies globally by default, with built-in FakeIP filtering (sing-box only).</value>
|
||||
</data>
|
||||
</root>
|
||||
92
v2rayN/ServiceLib/Sample/singbox_fakeip_filter
Normal file
92
v2rayN/ServiceLib/Sample/singbox_fakeip_filter
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"domain": [
|
||||
"amobile.music.tc.qq.com",
|
||||
"api-jooxtt.sanook.com",
|
||||
"api.joox.com",
|
||||
"aqqmusic.tc.qq.com",
|
||||
"dl.stream.qqmusic.qq.com",
|
||||
"ff.dorado.sdo.com",
|
||||
"heartbeat.belkin.com",
|
||||
"isure.stream.qqmusic.qq.com",
|
||||
"joox.com",
|
||||
"lens.l.google.com",
|
||||
"localhost.ptlogin2.qq.com",
|
||||
"localhost.sec.qq.com",
|
||||
"mesu.apple.com",
|
||||
"mobileoc.music.tc.qq.com",
|
||||
"music.taihe.com",
|
||||
"musicapi.taihe.com",
|
||||
"na.b.g-tun.com",
|
||||
"proxy.golang.org",
|
||||
"ps.res.netease.com",
|
||||
"shark007.net",
|
||||
"songsearch.kugou.com",
|
||||
"static.adtidy.org",
|
||||
"streamoc.music.tc.qq.com",
|
||||
"swcdn.apple.com",
|
||||
"swdist.apple.com",
|
||||
"swdownload.apple.com",
|
||||
"swquery.apple.com",
|
||||
"swscan.apple.com",
|
||||
"trackercdn.kugou.com",
|
||||
"xnotify.xboxlive.com"
|
||||
],
|
||||
"domain_keyword": [
|
||||
"ntp",
|
||||
"stun",
|
||||
"time"
|
||||
],
|
||||
"domain_regex": [
|
||||
"^[^.]+$",
|
||||
"^[^.]+\\.[^.]+\\.xboxlive\\.com$",
|
||||
"^localhost\\.[^.]+\\.weixin\\.qq\\.com$",
|
||||
"^mijia\\scloud$",
|
||||
"^xbox\\.[^.]+\\.microsoft\\.com$",
|
||||
"^xbox\\.[^.]+\\.[^.]+\\.microsoft\\.com$"
|
||||
],
|
||||
"domain_suffix": [
|
||||
"126.net",
|
||||
"3gppnetwork.org",
|
||||
"battle.net",
|
||||
"battlenet.com.cn",
|
||||
"cdn.nintendo.net",
|
||||
"cmbchina.com",
|
||||
"cmbimg.com",
|
||||
"ff14.sdo.com",
|
||||
"ffxiv.com",
|
||||
"finalfantasyxiv.com",
|
||||
"gcloudcs.com",
|
||||
"home.arpa",
|
||||
"invalid",
|
||||
"kuwo.cn",
|
||||
"lan",
|
||||
"linksys.com",
|
||||
"linksyssmartwifi.com",
|
||||
"local",
|
||||
"localdomain",
|
||||
"localhost",
|
||||
"market.xiaomi.com",
|
||||
"mcdn.bilivideo.cn",
|
||||
"media.dssott.com",
|
||||
"msftconnecttest.com",
|
||||
"msftncsi.com",
|
||||
"music.163.com",
|
||||
"music.migu.cn",
|
||||
"n0808.com",
|
||||
"nflxvideo.net",
|
||||
"oray.com",
|
||||
"orayimg.com",
|
||||
"router.asus.com",
|
||||
"sandai.net",
|
||||
"square-enix.com",
|
||||
"srv.nintendo.net",
|
||||
"steamcontent.com",
|
||||
"uu.163.com",
|
||||
"wargaming.net",
|
||||
"wggames.cn",
|
||||
"wotgame.cn",
|
||||
"wowsgame.cn",
|
||||
"xiami.com",
|
||||
"y.qq.com"
|
||||
]
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
<EmbeddedResource Include="Sample\tun_singbox_inbound" />
|
||||
<EmbeddedResource Include="Sample\tun_singbox_rules" />
|
||||
<EmbeddedResource Include="Sample\linux_autostart_config" />
|
||||
<EmbeddedResource Include="Sample\singbox_fakeip_filter" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,15 @@ public partial class CoreConfigSingboxService
|
|||
lastRule.Ip?.Contains("0.0.0.0/0") == true);
|
||||
}
|
||||
singboxConfig.dns.final = useDirectDns ? Global.SingboxDirectDNSTag : Global.SingboxRemoteDNSTag;
|
||||
if ((!useDirectDns) && simpleDNSItem.FakeIP == true && simpleDNSItem.GlobalFakeIp == false)
|
||||
{
|
||||
singboxConfig.dns.rules.Add(new()
|
||||
{
|
||||
server = Global.SingboxFakeDNSTag,
|
||||
query_type = new List<int> { 1, 28 }, // A and AAAA
|
||||
rewrite_ttl = 1,
|
||||
});
|
||||
}
|
||||
|
||||
// Tun2SocksAddress
|
||||
if (node != null && Utils.IsDomain(node.Address))
|
||||
|
|
@ -94,17 +103,7 @@ public partial class CoreConfigSingboxService
|
|||
|
||||
if (!simpleDNSItem.Hosts.IsNullOrEmpty())
|
||||
{
|
||||
var userHostsMap = simpleDNSItem.Hosts
|
||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(line => line.Trim())
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
||||
.Select(line => line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Where(parts => parts.Length >= 2)
|
||||
.GroupBy(parts => parts[0])
|
||||
.ToDictionary(
|
||||
group => group.Key,
|
||||
group => group.SelectMany(parts => parts.Skip(1)).ToList()
|
||||
);
|
||||
var userHostsMap = Utils.ParseHostsToDictionary(simpleDNSItem.Hosts);
|
||||
|
||||
foreach (var kvp in userHostsMap)
|
||||
{
|
||||
|
|
@ -197,6 +196,28 @@ public partial class CoreConfigSingboxService
|
|||
});
|
||||
}
|
||||
|
||||
if (simpleDNSItem.FakeIP == true && simpleDNSItem.GlobalFakeIp == true)
|
||||
{
|
||||
var fakeipFilterRule = JsonUtils.Deserialize<Rule4Sbox>(EmbedUtils.GetEmbedText(Global.SingboxFakeIPFilterFileName));
|
||||
fakeipFilterRule.invert = true;
|
||||
var rule4Fake = new Rule4Sbox
|
||||
{
|
||||
server = Global.SingboxFakeDNSTag,
|
||||
type = "logical",
|
||||
mode = "and",
|
||||
rewrite_ttl = 1,
|
||||
rules = new List<Rule4Sbox>
|
||||
{
|
||||
new() {
|
||||
query_type = new List<int> { 1, 28 }, // A and AAAA
|
||||
},
|
||||
fakeipFilterRule,
|
||||
}
|
||||
};
|
||||
|
||||
singboxConfig.dns.rules.Add(rule4Fake);
|
||||
}
|
||||
|
||||
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
||||
if (routing == null)
|
||||
return 0;
|
||||
|
|
@ -276,10 +297,12 @@ public partial class CoreConfigSingboxService
|
|||
}
|
||||
else
|
||||
{
|
||||
if (simpleDNSItem.FakeIP == true)
|
||||
if (simpleDNSItem.FakeIP == true && simpleDNSItem.GlobalFakeIp == false)
|
||||
{
|
||||
var rule4Fake = JsonUtils.DeepCopy(rule);
|
||||
rule4Fake.server = Global.SingboxFakeDNSTag;
|
||||
rule4Fake.query_type = new List<int> { 1, 28 }; // A and AAAA
|
||||
rule4Fake.rewrite_ttl = 1;
|
||||
singboxConfig.dns.rules.Add(rule4Fake);
|
||||
}
|
||||
rule.server = Global.SingboxRemoteDNSTag;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,31 @@ public partial class CoreConfigSingboxService
|
|||
});
|
||||
}
|
||||
|
||||
var hostsDomains = new List<string>();
|
||||
var systemHostsMap = Utils.GetSystemHosts();
|
||||
foreach (var kvp in systemHostsMap)
|
||||
{
|
||||
hostsDomains.Add(kvp.Key);
|
||||
}
|
||||
var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
if (dnsItem == null || dnsItem.Enabled == false)
|
||||
{
|
||||
var simpleDNSItem = _config.SimpleDNSItem;
|
||||
if (!simpleDNSItem.Hosts.IsNullOrEmpty())
|
||||
{
|
||||
var userHostsMap = Utils.ParseHostsToDictionary(simpleDNSItem.Hosts);
|
||||
foreach (var kvp in userHostsMap)
|
||||
{
|
||||
hostsDomains.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
singboxConfig.route.rules.Add(new()
|
||||
{
|
||||
action = "resolve",
|
||||
domain = hostsDomains,
|
||||
});
|
||||
|
||||
singboxConfig.route.rules.Add(new()
|
||||
{
|
||||
outbound = Global.DirectTag,
|
||||
|
|
|
|||
|
|
@ -261,17 +261,7 @@ public partial class CoreConfigV2rayService
|
|||
|
||||
if (!simpleDNSItem.Hosts.IsNullOrEmpty())
|
||||
{
|
||||
var userHostsMap = simpleDNSItem.Hosts
|
||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(line => line.Trim())
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
||||
.Select(line => line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Where(parts => parts.Length >= 2)
|
||||
.GroupBy(parts => parts[0])
|
||||
.ToDictionary(
|
||||
group => group.Key,
|
||||
group => group.SelectMany(parts => parts.Skip(1)).ToList()
|
||||
);
|
||||
var userHostsMap = Utils.ParseHostsToDictionary(simpleDNSItem.Hosts);
|
||||
|
||||
foreach (var kvp in userHostsMap)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ public class CheckUpdateViewModel : MyReactiveObject
|
|||
|
||||
private CheckUpdateModel GetCheckUpdateModel(string coreType)
|
||||
{
|
||||
if (coreType == _v2rayN && Utils.IsPackagedInstall())
|
||||
{
|
||||
return new()
|
||||
{
|
||||
IsSelected = false,
|
||||
CoreType = coreType,
|
||||
Remarks = ResUI.menuCheckUpdate + " (Not Support)",
|
||||
};
|
||||
}
|
||||
|
||||
return new()
|
||||
{
|
||||
IsSelected = _config.CheckUpdateItem.SelectedCoreTypes?.Contains(coreType) ?? true,
|
||||
|
|
@ -104,6 +114,11 @@ public class CheckUpdateViewModel : MyReactiveObject
|
|||
}
|
||||
else if (item.CoreType == _v2rayN)
|
||||
{
|
||||
if (Utils.IsPackagedInstall())
|
||||
{
|
||||
await UpdateView(_v2rayN, "Not Support");
|
||||
continue;
|
||||
}
|
||||
await CheckUpdateN(EnableCheckPreReleaseUpdate);
|
||||
}
|
||||
else if (item.CoreType == ECoreType.Xray.ToString())
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@
|
|||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Watermark="1000:2000,3000:4000" />
|
||||
Watermark="1000-2000,3000,4000" />
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@
|
|||
Grid.Column="2"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbApplyProxyDomainsOnly}"
|
||||
Text="{x:Static resx:ResUI.TbFakeIPTips}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@
|
|||
<DataGrid
|
||||
x:Name="lstRules"
|
||||
AutoGenerateColumns="False"
|
||||
Background="Transparent"
|
||||
BorderThickness="1"
|
||||
CanUserResizeColumns="True"
|
||||
GridLinesVisibility="All"
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@
|
|||
<DataGrid
|
||||
x:Name="lstRoutings"
|
||||
AutoGenerateColumns="False"
|
||||
Background="Transparent"
|
||||
BorderThickness="1"
|
||||
CanUserResizeColumns="True"
|
||||
GridLinesVisibility="All"
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@
|
|||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
materialDesign:HintAssist.Hint="1000:2000,3000:4000"
|
||||
materialDesign:HintAssist.Hint="1000-2000,3000,4000"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@
|
|||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbApplyProxyDomainsOnly}"
|
||||
Text="{x:Static resx:ResUI.TbFakeIPTips}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ public partial class RoutingRuleSettingWindow
|
|||
|
||||
private void RoutingRuleSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (!lstRules.IsKeyboardFocusWithin)
|
||||
return;
|
||||
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
||||
{
|
||||
if (e.Key == Key.A)
|
||||
|
|
|
|||
Loading…
Reference in a new issue