Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dffc6d9a9b | ||
|
|
c9989108bd | ||
|
|
386c86bfa6 | ||
|
|
925cf16c50 | ||
|
|
c561916b67 | ||
|
|
d41a73b44b | ||
|
|
7995bdd4df | ||
|
|
df95cc6af7 | ||
|
|
c669e72189 | ||
|
|
46db5efef3 | ||
|
|
610418b42b | ||
|
|
508eb24fc3 | ||
|
|
6973272dd0 | ||
|
|
d820c4367e | ||
|
|
96e1f85d6f | ||
|
|
6fa5ca5aa9 | ||
|
|
1d1f5641eb | ||
|
|
3f79df21d9 | ||
|
|
ac1231ad54 | ||
|
|
8662d94ab6 | ||
|
|
3d23f3e3a2 | ||
|
|
6715d7dce6 | ||
|
|
dad35f57d0 | ||
|
|
f779e311ed | ||
|
|
ce7c41e3ff | ||
|
|
74bb01d044 | ||
|
|
82f9698c0d | ||
|
|
6911883995 | ||
|
|
47c509faf6 | ||
|
|
8704942209 | ||
|
|
e8cdc29bb5 | ||
|
|
191a7a6574 | ||
|
|
ad5d21db5a | ||
|
|
569e939492 | ||
|
|
6a17c539d1 | ||
|
|
f8a4f946e4 | ||
|
|
0715fa85ce | ||
|
|
1360051f0c | ||
|
|
42c4f9a6c6 | ||
|
|
11691d0128 | ||
|
|
26fe9c63a3 |
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>7.13.0</Version>
|
||||
<Version>7.13.7</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.2" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.2" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.2" />
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.2" />
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.3" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.3" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.3" />
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.3" />
|
||||
<PackageVersion Include="CliWrap" Version="3.9.0" />
|
||||
<PackageVersion Include="Downloader" Version="3.3.4" />
|
||||
<PackageVersion Include="Downloader" Version="4.0.2" />
|
||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
|
||||
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
|
||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||
@@ -27,4 +27,4 @@
|
||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -26,7 +26,7 @@ public class DownloaderHelper
|
||||
var downloadOpt = new DownloadConfiguration()
|
||||
{
|
||||
Timeout = timeout * 1000,
|
||||
MaxTryAgainOnFailover = 2,
|
||||
MaxTryAgainOnFailure = 2,
|
||||
RequestConfiguration =
|
||||
{
|
||||
Headers = headers,
|
||||
@@ -64,7 +64,7 @@ public class DownloaderHelper
|
||||
var downloadOpt = new DownloadConfiguration()
|
||||
{
|
||||
Timeout = timeout * 1000,
|
||||
MaxTryAgainOnFailover = 2,
|
||||
MaxTryAgainOnFailure = 2,
|
||||
RequestConfiguration =
|
||||
{
|
||||
Timeout= timeout * 1000,
|
||||
@@ -135,7 +135,7 @@ public class DownloaderHelper
|
||||
var downloadOpt = new DownloadConfiguration()
|
||||
{
|
||||
Timeout = timeout * 1000,
|
||||
MaxTryAgainOnFailover = 2,
|
||||
MaxTryAgainOnFailure = 2,
|
||||
RequestConfiguration =
|
||||
{
|
||||
Timeout= timeout * 1000,
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ServiceLib.Common;
|
||||
|
||||
public static class StringEx
|
||||
public static class Extension
|
||||
{
|
||||
public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value)
|
||||
{
|
||||
@@ -79,4 +79,9 @@ public static class StringEx
|
||||
{
|
||||
return int.TryParse(value, out var result) ? result : defaultValue;
|
||||
}
|
||||
|
||||
public static List<string> AppendEmpty(this IEnumerable<string> source)
|
||||
{
|
||||
return source.Concat(new[] { string.Empty }).ToList();
|
||||
}
|
||||
}
|
||||
@@ -223,4 +223,28 @@ public static class FileManager
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Linux shell file with the specified contents.
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="contents"></param>
|
||||
/// <param name="overwrite"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> CreateLinuxShellFile(string fileName, string contents, bool overwrite)
|
||||
{
|
||||
var shFilePath = Utils.GetBinConfigPath(fileName);
|
||||
|
||||
// Check if the file already exists and if we should overwrite it
|
||||
if (!overwrite && File.Exists(shFilePath))
|
||||
{
|
||||
return shFilePath;
|
||||
}
|
||||
|
||||
File.Delete(shFilePath);
|
||||
await File.WriteAllTextAsync(shFilePath, contents);
|
||||
await Utils.SetLinuxChmod(shFilePath);
|
||||
|
||||
return shFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,5 +128,8 @@ public class JsonUtils
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static JsonNode? SerializeToNode(object? obj) => JsonSerializer.SerializeToNode(obj);
|
||||
public static JsonNode? SerializeToNode(object? obj, JsonSerializerOptions? options = null)
|
||||
{
|
||||
return JsonSerializer.SerializeToNode(obj, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +323,14 @@ public class Utils
|
||||
return text.Replace(",", ",").Replace(Environment.NewLine, ",");
|
||||
}
|
||||
|
||||
public static List<string> GetEnumNames<TEnum>() where TEnum : Enum
|
||||
{
|
||||
return Enum.GetValues(typeof(TEnum))
|
||||
.Cast<TEnum>()
|
||||
.Select(e => e.ToString())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
#endregion 转换函数
|
||||
|
||||
#region 数据检查
|
||||
@@ -382,13 +390,44 @@ public class Utils
|
||||
{
|
||||
if (IPAddress.TryParse(ip, out var address))
|
||||
{
|
||||
// Loopback address check (127.0.0.1 for IPv4, ::1 for IPv6)
|
||||
if (IPAddress.IsLoopback(address))
|
||||
return true;
|
||||
|
||||
var ipBytes = address.GetAddressBytes();
|
||||
if (ipBytes[0] == 10)
|
||||
return true;
|
||||
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
|
||||
return true;
|
||||
if (ipBytes[0] == 192 && ipBytes[1] == 168)
|
||||
return true;
|
||||
if (address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
// IPv4 private address check
|
||||
if (ipBytes[0] == 10)
|
||||
return true;
|
||||
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
|
||||
return true;
|
||||
if (ipBytes[0] == 192 && ipBytes[1] == 168)
|
||||
return true;
|
||||
}
|
||||
else if (address.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
// IPv6 private address check
|
||||
// Link-local address fe80::/10
|
||||
if (ipBytes[0] == 0xfe && (ipBytes[1] & 0xc0) == 0x80)
|
||||
return true;
|
||||
|
||||
// Unique local address fc00::/7 (typically fd00::/8)
|
||||
if ((ipBytes[0] & 0xfe) == 0xfc)
|
||||
return true;
|
||||
|
||||
// Private portion in IPv4-mapped addresses ::ffff:0:0/96
|
||||
if (address.IsIPv4MappedToIPv6)
|
||||
{
|
||||
var ipv4Bytes = ipBytes.Skip(12).ToArray();
|
||||
if (ipv4Bytes[0] == 10)
|
||||
return true;
|
||||
if (ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31)
|
||||
return true;
|
||||
if (ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -427,11 +466,11 @@ public class Utils
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int GetFreePort(int defaultPort = 9090)
|
||||
public static int GetFreePort(int defaultPort = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Utils.PortInUse(defaultPort))
|
||||
if (!(defaultPort == 0 || Utils.PortInUse(defaultPort)))
|
||||
{
|
||||
return defaultPort;
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ public enum EConfigType
|
||||
Hysteria2 = 7,
|
||||
TUIC = 8,
|
||||
WireGuard = 9,
|
||||
HTTP = 10
|
||||
HTTP = 10,
|
||||
Anytls = 11
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ public class Global
|
||||
public const string PacFileName = NamespaceSample + "pac";
|
||||
public const string ProxySetOSXShellFileName = NamespaceSample + "proxy_set_osx_sh";
|
||||
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 DefaultSecurity = "auto";
|
||||
public const string DefaultNetwork = "tcp";
|
||||
@@ -74,6 +76,13 @@ public class Global
|
||||
public const int SpeedTestPageSize = 1000;
|
||||
public const string LinuxBash = "/bin/bash";
|
||||
|
||||
public const string SingboxDirectDNSTag = "direct_dns";
|
||||
public const string SingboxRemoteDNSTag = "remote_dns";
|
||||
public const string SingboxOutboundResolverTag = "outbound_resolver";
|
||||
public const string SingboxFinalResolverTag = "final_resolver";
|
||||
public const string SingboxHostsDNSTag = "hosts_dns";
|
||||
public const string SingboxFakeDNSTag = "fake_dns";
|
||||
|
||||
public static readonly List<string> IEProxyProtocols =
|
||||
[
|
||||
"{ip}:{http_port}",
|
||||
@@ -127,24 +136,24 @@ public class Global
|
||||
];
|
||||
|
||||
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://cdn.jsdelivr.net/gh/chocolate4u/Iran-sing-box-rules@rule-set/{1}.srs"
|
||||
];
|
||||
[
|
||||
"",
|
||||
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/release/sing-box/rule-set-{0}/{1}.srs",
|
||||
@"https://raw.githubusercontent.com/chocolate4u/Iran-sing-box-rules/rule-set/{1}.srs"
|
||||
];
|
||||
|
||||
public static readonly List<string> RoutingRulesSources =
|
||||
[
|
||||
"",
|
||||
@"https://cdn.jsdelivr.net/gh/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/runetfreedom/russia-v2ray-custom-routing-list/main/v2rayN/template.json",
|
||||
@"https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/main/v2rayN/template.json"
|
||||
];
|
||||
|
||||
public static readonly List<string> DNSTemplateSources =
|
||||
[
|
||||
"",
|
||||
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/",
|
||||
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/"
|
||||
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-custom-routing-list/main/v2rayN/",
|
||||
@"https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/main/v2rayN/"
|
||||
];
|
||||
|
||||
public static readonly Dictionary<string, string> UserAgentTexts = new()
|
||||
@@ -167,7 +176,8 @@ public class Global
|
||||
{ EConfigType.Trojan, "trojan://" },
|
||||
{ EConfigType.Hysteria2, "hysteria2://" },
|
||||
{ EConfigType.TUIC, "tuic://" },
|
||||
{ EConfigType.WireGuard, "wireguard://" }
|
||||
{ EConfigType.WireGuard, "wireguard://" },
|
||||
{ EConfigType.Anytls, "anytls://" }
|
||||
};
|
||||
|
||||
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
|
||||
@@ -180,7 +190,8 @@ public class Global
|
||||
{ EConfigType.Trojan, "trojan" },
|
||||
{ EConfigType.Hysteria2, "hysteria2" },
|
||||
{ EConfigType.TUIC, "tuic" },
|
||||
{ EConfigType.WireGuard, "wireguard" }
|
||||
{ EConfigType.WireGuard, "wireguard" },
|
||||
{ EConfigType.Anytls, "anytls" }
|
||||
};
|
||||
|
||||
public static readonly List<string> VmessSecurities =
|
||||
@@ -347,25 +358,42 @@ public class Global
|
||||
|
||||
public static readonly List<string> SingboxDomainStrategy4Out =
|
||||
[
|
||||
"ipv4_only",
|
||||
"",
|
||||
"ipv4_only",
|
||||
"prefer_ipv4",
|
||||
"prefer_ipv6",
|
||||
"ipv6_only",
|
||||
""
|
||||
"ipv6_only"
|
||||
];
|
||||
|
||||
public static readonly List<string> DomainDNSAddress =
|
||||
public static readonly List<string> DomainDirectDNSAddress =
|
||||
[
|
||||
"223.5.5.5",
|
||||
"223.6.6.6",
|
||||
"https://dns.alidns.com/dns-query",
|
||||
"https://doh.pub/dns-query",
|
||||
"223.5.5.5",
|
||||
"119.29.29.29",
|
||||
"localhost"
|
||||
];
|
||||
|
||||
public static readonly List<string> SingboxDomainDNSAddress =
|
||||
public static readonly List<string> DomainRemoteDNSAddress =
|
||||
[
|
||||
"https://cloudflare-dns.com/dns-query",
|
||||
"https://dns.cloudflare.com/dns-query",
|
||||
"https://dns.google/dns-query",
|
||||
"https://doh.dns.sb/dns-query",
|
||||
"https://doh.opendns.com/dns-query",
|
||||
"https://common.dot.dns.yandex.net",
|
||||
"8.8.8.8",
|
||||
"1.1.1.1",
|
||||
"185.222.222.222",
|
||||
"208.67.222.222",
|
||||
"77.88.8.8"
|
||||
];
|
||||
|
||||
public static readonly List<string> DomainPureIPDNSAddress =
|
||||
[
|
||||
"223.5.5.5",
|
||||
"223.6.6.6",
|
||||
"dhcp://auto"
|
||||
"119.29.29.29",
|
||||
"localhost"
|
||||
];
|
||||
|
||||
public static readonly List<string> Languages =
|
||||
@@ -528,5 +556,37 @@ public class Global
|
||||
@""
|
||||
];
|
||||
|
||||
public static readonly List<string> OutboundTags =
|
||||
[
|
||||
ProxyTag,
|
||||
DirectTag,
|
||||
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
|
||||
}
|
||||
|
||||
@@ -112,6 +112,8 @@ public class ConfigHandler
|
||||
|
||||
config.ConstItem ??= new ConstItem();
|
||||
|
||||
config.SimpleDNSItem ??= InitBuiltinSimpleDNS();
|
||||
|
||||
config.SpeedTestItem ??= new();
|
||||
if (config.SpeedTestItem.SpeedTestTimeout < 10)
|
||||
{
|
||||
@@ -246,6 +248,7 @@ public class ConfigHandler
|
||||
item.PublicKey = profileItem.PublicKey;
|
||||
item.ShortId = profileItem.ShortId;
|
||||
item.SpiderX = profileItem.SpiderX;
|
||||
item.Mldsa65Verify = profileItem.Mldsa65Verify;
|
||||
item.Extra = profileItem.Extra;
|
||||
item.MuxEnabled = profileItem.MuxEnabled;
|
||||
}
|
||||
@@ -261,6 +264,7 @@ public class ConfigHandler
|
||||
EConfigType.Hysteria2 => await AddHysteria2Server(config, item),
|
||||
EConfigType.TUIC => await AddTuicServer(config, item),
|
||||
EConfigType.WireGuard => await AddWireguardServer(config, item),
|
||||
EConfigType.Anytls => await AddAnytlsServer(config, item),
|
||||
_ => -1,
|
||||
};
|
||||
return ret;
|
||||
@@ -785,6 +789,35 @@ public class ConfigHandler
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add or edit a Anytls server
|
||||
/// Validates and processes Anytls-specific settings
|
||||
/// </summary>
|
||||
/// <param name="config">Current configuration</param>
|
||||
/// <param name="profileItem">Anytls profile to add</param>
|
||||
/// <param name="toFile">Whether to save to file</param>
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> AddAnytlsServer(Config config, ProfileItem profileItem, bool toFile = true)
|
||||
{
|
||||
profileItem.ConfigType = EConfigType.Anytls;
|
||||
profileItem.CoreType = ECoreType.sing_box;
|
||||
|
||||
profileItem.Address = profileItem.Address.TrimEx();
|
||||
profileItem.Id = profileItem.Id.TrimEx();
|
||||
profileItem.Security = profileItem.Security.TrimEx();
|
||||
profileItem.Network = string.Empty;
|
||||
if (profileItem.StreamSecurity.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.StreamSecurity = Global.StreamSecurity;
|
||||
}
|
||||
if (profileItem.Id.IsNullOrEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
await AddServerCommon(config, profileItem, toFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort the server list by the specified column
|
||||
/// Updates the sort order in the profile extension data
|
||||
@@ -1294,6 +1327,7 @@ public class ConfigHandler
|
||||
EConfigType.Hysteria2 => await AddHysteria2Server(config, profileItem, false),
|
||||
EConfigType.TUIC => await AddTuicServer(config, profileItem, false),
|
||||
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
|
||||
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
|
||||
_ => -1,
|
||||
};
|
||||
|
||||
@@ -1996,7 +2030,7 @@ public class ConfigHandler
|
||||
|
||||
if (!blImportAdvancedRules && items.Count > 0)
|
||||
{
|
||||
//migrate
|
||||
//migrate
|
||||
//TODO Temporary code to be removed later
|
||||
if (config.RoutingBasicItem.RoutingIndexId.IsNotEmpty())
|
||||
{
|
||||
@@ -2062,18 +2096,38 @@ public class ConfigHandler
|
||||
/// <summary>
|
||||
/// Initialize built-in DNS configurations
|
||||
/// Creates default DNS items for V2Ray and sing-box
|
||||
/// Also checks existing DNS items and disables those with empty NormalDNS
|
||||
/// </summary>
|
||||
/// <param name="config">Current configuration</param>
|
||||
/// <returns>0 if successful</returns>
|
||||
public static async Task<int> InitBuiltinDNS(Config config)
|
||||
{
|
||||
var items = await AppHandler.Instance.DNSItems();
|
||||
|
||||
// Check existing DNS items and disable those with empty NormalDNS
|
||||
var needsUpdate = false;
|
||||
foreach (var existingItem in items)
|
||||
{
|
||||
if (existingItem.NormalDNS.IsNullOrEmpty() && existingItem.Enabled)
|
||||
{
|
||||
existingItem.Enabled = false;
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update items if any changes were made
|
||||
if (needsUpdate)
|
||||
{
|
||||
await SQLiteHelper.Instance.UpdateAllAsync(items);
|
||||
}
|
||||
|
||||
if (items.Count <= 0)
|
||||
{
|
||||
var item = new DNSItem()
|
||||
{
|
||||
Remarks = "V2ray",
|
||||
CoreType = ECoreType.Xray,
|
||||
Enabled = false,
|
||||
};
|
||||
await SaveDNSItems(config, item);
|
||||
|
||||
@@ -2081,6 +2135,7 @@ public class ConfigHandler
|
||||
{
|
||||
Remarks = "sing-box",
|
||||
CoreType = ECoreType.sing_box,
|
||||
Enabled = false,
|
||||
};
|
||||
await SaveDNSItems(config, item2);
|
||||
}
|
||||
@@ -2152,6 +2207,37 @@ public class ConfigHandler
|
||||
|
||||
#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 Regional Presets
|
||||
|
||||
/// <summary>
|
||||
@@ -2173,7 +2259,8 @@ public class ConfigHandler
|
||||
await SQLiteHelper.Instance.DeleteAllAsync<DNSItem>();
|
||||
await InitBuiltinDNS(config);
|
||||
|
||||
return true;
|
||||
config.SimpleDNSItem = InitBuiltinSimpleDNS();
|
||||
break;
|
||||
|
||||
case EPresetType.Russia:
|
||||
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[1];
|
||||
@@ -2183,7 +2270,8 @@ public class ConfigHandler
|
||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json"));
|
||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
|
||||
|
||||
return true;
|
||||
config.SimpleDNSItem = await GetExternalSimpleDNSItem(Global.DNSTemplateSources[1] + "simple_dns.json") ?? InitBuiltinSimpleDNS();
|
||||
break;
|
||||
|
||||
case EPresetType.Iran:
|
||||
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[2];
|
||||
@@ -2193,10 +2281,11 @@ public class ConfigHandler
|
||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[2] + "v2ray.json"));
|
||||
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[2] + "sing_box.json"));
|
||||
|
||||
return true;
|
||||
config.SimpleDNSItem = await GetExternalSimpleDNSItem(Global.DNSTemplateSources[2] + "simple_dns.json") ?? InitBuiltinSimpleDNS();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion Regional Presets
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using CliWrap;
|
||||
using CliWrap.Buffered;
|
||||
|
||||
namespace ServiceLib.Handler;
|
||||
|
||||
@@ -11,6 +12,7 @@ public class CoreAdminHandler
|
||||
private Config _config;
|
||||
private Action<bool, string>? _updateFunc;
|
||||
private int _linuxSudoPid = -1;
|
||||
private const string _tag = "CoreAdminHandler";
|
||||
|
||||
public async Task Init(Config config, Action<bool, string> updateFunc)
|
||||
{
|
||||
@@ -20,6 +22,8 @@ public class CoreAdminHandler
|
||||
}
|
||||
_config = config;
|
||||
_updateFunc = updateFunc;
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void UpdateFunc(bool notify, string msg)
|
||||
@@ -29,8 +33,11 @@ public class CoreAdminHandler
|
||||
|
||||
public async Task<Process?> RunProcessAsLinuxSudo(string fileName, CoreInfo coreInfo, string configPath)
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine("#!/bin/bash");
|
||||
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
|
||||
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
|
||||
sb.AppendLine($"sudo -S {cmdLine}");
|
||||
var shFilePath = await FileManager.CreateLinuxShellFile("run_as_sudo.sh", sb.ToString(), true);
|
||||
|
||||
Process proc = new()
|
||||
{
|
||||
@@ -44,33 +51,26 @@ public class CoreAdminHandler
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
StandardInputEncoding = Encoding.UTF8,
|
||||
StandardOutputEncoding = Encoding.UTF8,
|
||||
StandardErrorEncoding = Encoding.UTF8,
|
||||
}
|
||||
};
|
||||
|
||||
proc.OutputDataReceived += (sender, e) =>
|
||||
void dataHandler(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e.Data.IsNotEmpty())
|
||||
{
|
||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||
}
|
||||
};
|
||||
proc.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data.IsNotEmpty())
|
||||
{
|
||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
proc.OutputDataReceived += dataHandler;
|
||||
proc.ErrorDataReceived += dataHandler;
|
||||
|
||||
proc.Start();
|
||||
proc.BeginOutputReadLine();
|
||||
proc.BeginErrorReadLine();
|
||||
|
||||
await Task.Delay(10);
|
||||
await proc.StandardInput.WriteLineAsync();
|
||||
await Task.Delay(10);
|
||||
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
|
||||
|
||||
@@ -92,35 +92,27 @@ public class CoreAdminHandler
|
||||
return;
|
||||
}
|
||||
|
||||
var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
|
||||
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
|
||||
try
|
||||
{
|
||||
var shellFileName = Utils.IsOSX() ? Global.KillAsSudoOSXShellFileName : Global.KillAsSudoLinuxShellFileName;
|
||||
var shFilePath = await FileManager.CreateLinuxShellFile("kill_as_sudo.sh", EmbedUtils.GetEmbedText(shellFileName), true);
|
||||
if (shFilePath.Contains(' '))
|
||||
{
|
||||
shFilePath = shFilePath.AppendQuotes();
|
||||
}
|
||||
var arg = new List<string>() { "-c", $"sudo -S {shFilePath} {_linuxSudoPid}" };
|
||||
var result = await Cli.Wrap(Global.LinuxBash)
|
||||
.WithArguments(arg)
|
||||
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
|
||||
.ExecuteBufferedAsync();
|
||||
|
||||
await Cli.Wrap(shFilePath)
|
||||
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
|
||||
.ExecuteAsync();
|
||||
UpdateFunc(false, result.StandardOutput.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
}
|
||||
|
||||
_linuxSudoPid = -1;
|
||||
}
|
||||
|
||||
private async Task<string> CreateLinuxShellFile(string cmdLine, string fileName)
|
||||
{
|
||||
var shFilePath = Utils.GetBinConfigPath(fileName);
|
||||
File.Delete(shFilePath);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#!/bin/sh");
|
||||
if (Utils.IsAdministrator())
|
||||
{
|
||||
sb.AppendLine($"{cmdLine}");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($"sudo -S {cmdLine}");
|
||||
}
|
||||
|
||||
await File.WriteAllTextAsync(shFilePath, sb.ToString());
|
||||
await Utils.SetLinuxChmod(shFilePath);
|
||||
|
||||
return shFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public class CoreHandler
|
||||
|
||||
public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
|
||||
{
|
||||
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC) ? ECoreType.sing_box : ECoreType.Xray;
|
||||
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls) ? ECoreType.sing_box : ECoreType.Xray;
|
||||
var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
|
||||
var configPath = Utils.GetBinConfigPath(fileName);
|
||||
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
|
||||
@@ -280,20 +280,15 @@ public class CoreHandler
|
||||
|
||||
if (displayLog)
|
||||
{
|
||||
proc.OutputDataReceived += (sender, e) =>
|
||||
void dataHandler(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e.Data.IsNotEmpty())
|
||||
{
|
||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||
}
|
||||
};
|
||||
proc.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data.IsNotEmpty())
|
||||
{
|
||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||
}
|
||||
};
|
||||
}
|
||||
proc.OutputDataReceived += dataHandler;
|
||||
proc.ErrorDataReceived += dataHandler;
|
||||
}
|
||||
proc.Start();
|
||||
|
||||
|
||||
48
v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs
Normal file
48
v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace ServiceLib.Handler.Fmt;
|
||||
|
||||
public class AnytlsFmt : BaseFmt
|
||||
{
|
||||
public static ProfileItem? Resolve(string str, out string msg)
|
||||
{
|
||||
msg = ResUI.ConfigurationFormatIncorrect;
|
||||
|
||||
var parsedUrl = Utils.TryUri(str);
|
||||
if (parsedUrl == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ProfileItem item = new()
|
||||
{
|
||||
ConfigType = EConfigType.Anytls,
|
||||
Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
|
||||
Address = parsedUrl.IdnHost,
|
||||
Port = parsedUrl.Port,
|
||||
};
|
||||
var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo);
|
||||
item.Id = rawUserInfo;
|
||||
|
||||
var query = Utils.ParseQueryString(parsedUrl.Query);
|
||||
_ = ResolveStdTransport(query, ref item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static string? ToUri(ProfileItem? item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var remark = string.Empty;
|
||||
if (item.Remarks.IsNotEmpty())
|
||||
{
|
||||
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||
}
|
||||
var pw = item.Id;
|
||||
var dicQuery = new Dictionary<string, string>();
|
||||
_ = GetStdTransport(item, Global.None, ref dicQuery);
|
||||
|
||||
return ToUri(EConfigType.Anytls, item.Address, item.Port, pw, dicQuery, remark);
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,10 @@ public class BaseFmt
|
||||
{
|
||||
dicQuery.Add("spx", Utils.UrlEncode(item.SpiderX));
|
||||
}
|
||||
if (item.Mldsa65Verify.IsNotEmpty())
|
||||
{
|
||||
dicQuery.Add("pqv", Utils.UrlEncode(item.Mldsa65Verify));
|
||||
}
|
||||
if (item.AllowInsecure.Equals("true"))
|
||||
{
|
||||
dicQuery.Add("allowInsecure", "1");
|
||||
@@ -159,6 +163,7 @@ public class BaseFmt
|
||||
item.PublicKey = Utils.UrlDecode(query["pbk"] ?? "");
|
||||
item.ShortId = Utils.UrlDecode(query["sid"] ?? "");
|
||||
item.SpiderX = Utils.UrlDecode(query["spx"] ?? "");
|
||||
item.Mldsa65Verify = Utils.UrlDecode(query["pqv"] ?? "");
|
||||
item.AllowInsecure = (query["allowInsecure"] ?? "") == "1" ? "true" : "";
|
||||
|
||||
item.Network = query["type"] ?? nameof(ETransport.tcp);
|
||||
|
||||
@@ -18,6 +18,7 @@ public class FmtHandler
|
||||
EConfigType.Hysteria2 => Hysteria2Fmt.ToUri(item),
|
||||
EConfigType.TUIC => TuicFmt.ToUri(item),
|
||||
EConfigType.WireGuard => WireguardFmt.ToUri(item),
|
||||
EConfigType.Anytls => AnytlsFmt.ToUri(item),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
@@ -75,6 +76,10 @@ public class FmtHandler
|
||||
{
|
||||
return WireguardFmt.Resolve(str, out msg);
|
||||
}
|
||||
else if (str.StartsWith(Global.ProtocolShares[EConfigType.Anytls]))
|
||||
{
|
||||
return AnytlsFmt.Resolve(str, out msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = ResUI.NonvmessOrssProtocol;
|
||||
|
||||
@@ -24,7 +24,7 @@ public class Hysteria2Fmt : BaseFmt
|
||||
item.Path = Utils.UrlDecode(query["obfs-password"] ?? "");
|
||||
item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false";
|
||||
|
||||
item.Ports = Utils.UrlDecode(query["mport"] ?? "").Replace('-', ':');
|
||||
item.Ports = Utils.UrlDecode(query["mport"] ?? "");
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,7 @@ public class ProxySettingLinux
|
||||
|
||||
private static async Task ExecCmd(List<string> args)
|
||||
{
|
||||
var fileName = Utils.GetBinConfigPath(_proxySetFileName);
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
var contents = EmbedUtils.GetEmbedText(Global.ProxySetLinuxShellFileName);
|
||||
await File.AppendAllTextAsync(fileName, contents);
|
||||
|
||||
await Utils.SetLinuxChmod(fileName);
|
||||
}
|
||||
var fileName = await FileManager.CreateLinuxShellFile(_proxySetFileName, EmbedUtils.GetEmbedText(Global.ProxySetLinuxShellFileName), false);
|
||||
|
||||
await Utils.GetCliWrapOutput(fileName, args);
|
||||
}
|
||||
|
||||
@@ -23,14 +23,7 @@ public class ProxySettingOSX
|
||||
|
||||
private static async Task ExecCmd(List<string> args)
|
||||
{
|
||||
var fileName = Utils.GetBinConfigPath(_proxySetFileName);
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
var contents = EmbedUtils.GetEmbedText(Global.ProxySetOSXShellFileName);
|
||||
await File.AppendAllTextAsync(fileName, contents);
|
||||
|
||||
await Utils.SetLinuxChmod(fileName);
|
||||
}
|
||||
var fileName = await FileManager.CreateLinuxShellFile(_proxySetFileName, EmbedUtils.GetEmbedText(Global.ProxySetOSXShellFileName), false);
|
||||
|
||||
await Utils.GetCliWrapOutput(fileName, args);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public class Config
|
||||
public List<InItem> Inbound { get; set; }
|
||||
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
||||
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
||||
public SimpleDNSItem SimpleDNSItem { get; set; }
|
||||
|
||||
#endregion other entities
|
||||
}
|
||||
|
||||
@@ -253,3 +253,21 @@ public class WindowSizeItem
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SimpleDNSItem
|
||||
{
|
||||
public bool? UseSystemHosts { get; set; }
|
||||
public bool? AddCommonHosts { get; set; }
|
||||
public bool? FakeIP { get; set; }
|
||||
public bool? BlockBindingQuery { get; set; }
|
||||
public string? DirectDNS { get; set; }
|
||||
public string? RemoteDNS { get; set; }
|
||||
public string? SingboxOutboundsResolveDNS { get; set; }
|
||||
public string? SingboxFinalResolveDNS { get; set; }
|
||||
public string? RayStrategy4Freedom { get; set; }
|
||||
public string? SingboxStrategy4Direct { get; set; }
|
||||
public string? SingboxStrategy4Proxy { get; set; }
|
||||
public string? Hosts { get; set; }
|
||||
public string? DirectExpectedIPs { get; set; }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ public class DNSItem
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Remarks { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
public bool Enabled { get; set; } = false;
|
||||
public ECoreType CoreType { get; set; }
|
||||
public bool UseSystemHosts { get; set; }
|
||||
public string? NormalDNS { get; set; }
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ProfileItem : ReactiveObject
|
||||
public string GetSummary()
|
||||
{
|
||||
var summary = $"[{(ConfigType).ToString()}] ";
|
||||
var arrAddr = Address.Split('.');
|
||||
var arrAddr = Address.Contains(':') ? Address.Split(':') : Address.Split('.');
|
||||
var addr = arrAddr.Length switch
|
||||
{
|
||||
> 2 => $"{arrAddr.First()}***{arrAddr.Last()}",
|
||||
@@ -93,6 +93,7 @@ public class ProfileItem : ReactiveObject
|
||||
public string PublicKey { get; set; }
|
||||
public string ShortId { get; set; }
|
||||
public string SpiderX { get; set; }
|
||||
public string Mldsa65Verify { get; set; }
|
||||
public string Extra { get; set; }
|
||||
public bool? MuxEnabled { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ServiceLib.Models;
|
||||
|
||||
public class SingboxConfig
|
||||
@@ -6,6 +8,7 @@ public class SingboxConfig
|
||||
public Dns4Sbox? dns { get; set; }
|
||||
public List<Inbound4Sbox> inbounds { get; set; }
|
||||
public List<Outbound4Sbox> outbounds { get; set; }
|
||||
public List<Endpoints4Sbox>? endpoints { get; set; }
|
||||
public Route4Sbox route { get; set; }
|
||||
public Experimental4Sbox? experimental { get; set; }
|
||||
}
|
||||
@@ -29,14 +32,15 @@ public class Dns4Sbox
|
||||
public bool? independent_cache { get; set; }
|
||||
public bool? reverse_mapping { get; set; }
|
||||
public string? client_subnet { get; set; }
|
||||
public Fakeip4Sbox? fakeip { get; set; }
|
||||
}
|
||||
|
||||
public class Route4Sbox
|
||||
{
|
||||
public Rule4Sbox? default_domain_resolver { get; set; } // or string
|
||||
public bool? auto_detect_interface { get; set; }
|
||||
public List<Rule4Sbox> rules { get; set; }
|
||||
public List<Ruleset4Sbox>? rule_set { get; set; }
|
||||
public string? final { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -49,6 +53,7 @@ public class Rule4Sbox
|
||||
public string? mode { get; set; }
|
||||
public bool? ip_is_private { get; set; }
|
||||
public string? client_subnet { get; set; }
|
||||
public int? rewrite_ttl { get; set; }
|
||||
public bool? invert { get; set; }
|
||||
public string? clash_mode { get; set; }
|
||||
public List<string>? inbound { get; set; }
|
||||
@@ -67,6 +72,27 @@ public class Rule4Sbox
|
||||
public List<string>? process_name { get; set; }
|
||||
public List<string>? rule_set { get; set; }
|
||||
public List<Rule4Sbox>? rules { get; set; }
|
||||
public string? action { get; set; }
|
||||
public string? strategy { get; set; }
|
||||
public List<string>? sniffer { get; set; }
|
||||
public string? rcode { get; set; }
|
||||
public List<int>? query_type { get; set; }
|
||||
public List<string>? answer { get; set; }
|
||||
public List<string>? ns { get; set; }
|
||||
public List<string>? extra { get; set; }
|
||||
public string? method { get; set; }
|
||||
public bool? no_drop { get; set; }
|
||||
public bool? source_ip_is_private { get; set; }
|
||||
public bool? ip_accept_any { get; set; }
|
||||
public int? source_port { get; set; }
|
||||
public List<string>? source_port_range { get; set; }
|
||||
public List<string>? network_type { get; set; }
|
||||
public bool? network_is_expensive { get; set; }
|
||||
public bool? network_is_constrained { get; set; }
|
||||
public List<string>? wifi_ssid { get; set; }
|
||||
public List<string>? wifi_bssid { get; set; }
|
||||
public bool? rule_set_ip_cidr_match_source { get; set; }
|
||||
public bool? rule_set_ip_cidr_accept_empty { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -76,7 +102,6 @@ public class Inbound4Sbox
|
||||
public string tag { get; set; }
|
||||
public string listen { get; set; }
|
||||
public int? listen_port { get; set; }
|
||||
public string? domain_strategy { get; set; }
|
||||
public string interface_name { get; set; }
|
||||
public List<string>? address { get; set; }
|
||||
public int? mtu { get; set; }
|
||||
@@ -84,8 +109,6 @@ public class Inbound4Sbox
|
||||
public bool? strict_route { get; set; }
|
||||
public bool? endpoint_independent_nat { get; set; }
|
||||
public string? stack { get; set; }
|
||||
public bool? sniff { get; set; }
|
||||
public bool? sniff_override_destination { get; set; }
|
||||
public List<User4Sbox> users { get; set; }
|
||||
}
|
||||
|
||||
@@ -95,10 +118,8 @@ public class User4Sbox
|
||||
public string password { get; set; }
|
||||
}
|
||||
|
||||
public class Outbound4Sbox
|
||||
public class Outbound4Sbox : BaseServer4Sbox
|
||||
{
|
||||
public string type { get; set; }
|
||||
public string tag { get; set; }
|
||||
public string? server { get; set; }
|
||||
public int? server_port { get; set; }
|
||||
public List<string>? server_ports { get; set; }
|
||||
@@ -113,7 +134,6 @@ public class Outbound4Sbox
|
||||
public int? recv_window_conn { get; set; }
|
||||
public int? recv_window { get; set; }
|
||||
public bool? disable_mtu_discovery { get; set; }
|
||||
public string? detour { get; set; }
|
||||
public string? method { get; set; }
|
||||
public string? username { get; set; }
|
||||
public string? password { get; set; }
|
||||
@@ -121,21 +141,36 @@ public class Outbound4Sbox
|
||||
public string? version { get; set; }
|
||||
public string? network { get; set; }
|
||||
public string? packet_encoding { get; set; }
|
||||
public List<string>? local_address { get; set; }
|
||||
public string? private_key { get; set; }
|
||||
public string? peer_public_key { get; set; }
|
||||
public List<int>? reserved { get; set; }
|
||||
public int? mtu { get; set; }
|
||||
public string? plugin { get; set; }
|
||||
public string? plugin_opts { get; set; }
|
||||
public Tls4Sbox? tls { get; set; }
|
||||
public Multiplex4Sbox? multiplex { get; set; }
|
||||
public Transport4Sbox? transport { get; set; }
|
||||
public HyObfs4Sbox? obfs { get; set; }
|
||||
public List<string>? outbounds { get; set; }
|
||||
public bool? interrupt_exist_connections { get; set; }
|
||||
}
|
||||
|
||||
public class Endpoints4Sbox : BaseServer4Sbox
|
||||
{
|
||||
public bool? system { get; set; }
|
||||
public string? name { get; set; }
|
||||
public int? mtu { get; set; }
|
||||
public List<string> address { get; set; }
|
||||
public string private_key { get; set; }
|
||||
public int? listen_port { get; set; }
|
||||
public string? udp_timeout { get; set; }
|
||||
public int? workers { get; set; }
|
||||
public List<Peer4Sbox> peers { get; set; }
|
||||
}
|
||||
|
||||
public class Peer4Sbox
|
||||
{
|
||||
public string address { get; set; }
|
||||
public int port { get; set; }
|
||||
public string public_key { get; set; }
|
||||
public string? pre_shared_key { get; set; }
|
||||
public List<string> allowed_ips { get; set; }
|
||||
public int? persistent_keepalive_interval { get; set; }
|
||||
public List<int> reserved { get; set; }
|
||||
}
|
||||
|
||||
public class Tls4Sbox
|
||||
{
|
||||
public bool enabled { get; set; }
|
||||
@@ -144,6 +179,9 @@ public class Tls4Sbox
|
||||
public List<string>? alpn { get; set; }
|
||||
public Utls4Sbox? utls { 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
|
||||
@@ -191,15 +229,28 @@ public class HyObfs4Sbox
|
||||
public string? password { get; set; }
|
||||
}
|
||||
|
||||
public class Server4Sbox
|
||||
public class Server4Sbox : BaseServer4Sbox
|
||||
{
|
||||
public string? tag { get; set; }
|
||||
public string? inet4_range { get; set; }
|
||||
public string? inet6_range { get; set; }
|
||||
public string? client_subnet { get; set; }
|
||||
public string? server { get; set; }
|
||||
public new string? domain_resolver { get; set; }
|
||||
[JsonPropertyName("interface")] public string? Interface { get; set; }
|
||||
public int? server_port { get; set; }
|
||||
public string? path { get; set; }
|
||||
public Headers4Sbox? headers { get; set; }
|
||||
|
||||
// public List<string>? path { get; set; } // hosts
|
||||
public Dictionary<string, List<string>>? predefined { get; set; }
|
||||
|
||||
// Deprecated
|
||||
public string? address { get; set; }
|
||||
|
||||
public string? address_resolver { get; set; }
|
||||
public string? address_strategy { get; set; }
|
||||
public string? strategy { get; set; }
|
||||
public string? detour { get; set; }
|
||||
public string? client_subnet { get; set; }
|
||||
// Deprecated End
|
||||
}
|
||||
|
||||
public class Experimental4Sbox
|
||||
@@ -229,13 +280,6 @@ public class Stats4Sbox
|
||||
public List<string>? users { get; set; }
|
||||
}
|
||||
|
||||
public class Fakeip4Sbox
|
||||
{
|
||||
public bool enabled { get; set; }
|
||||
public string inet4_range { get; set; }
|
||||
public string inet6_range { get; set; }
|
||||
}
|
||||
|
||||
public class CacheFile4Sbox
|
||||
{
|
||||
public bool enabled { get; set; }
|
||||
@@ -254,3 +298,33 @@ public class Ruleset4Sbox
|
||||
public string? download_detour { get; set; }
|
||||
public string? update_interval { get; set; }
|
||||
}
|
||||
|
||||
public abstract class DialFields4Sbox
|
||||
{
|
||||
public string? detour { get; set; }
|
||||
public string? bind_interface { get; set; }
|
||||
public string? inet4_bind_address { get; set; }
|
||||
public string? inet6_bind_address { get; set; }
|
||||
public int? routing_mark { get; set; }
|
||||
public bool? reuse_addr { get; set; }
|
||||
public string? netns { get; set; }
|
||||
public string? connect_timeout { get; set; }
|
||||
public bool? tcp_fast_open { get; set; }
|
||||
public bool? tcp_multi_path { get; set; }
|
||||
public bool? udp_fragment { get; set; }
|
||||
public Rule4Sbox? domain_resolver { get; set; } // or string
|
||||
public string? network_strategy { get; set; }
|
||||
public List<string>? network_type { get; set; }
|
||||
public List<string>? fallback_network_type { get; set; }
|
||||
public string? fallback_delay { get; set; }
|
||||
public Tls4Sbox? tls { get; set; }
|
||||
public Multiplex4Sbox? multiplex { get; set; }
|
||||
public Transport4Sbox? transport { get; set; }
|
||||
public HyObfs4Sbox? obfs { get; set; }
|
||||
}
|
||||
|
||||
public abstract class BaseServer4Sbox : DialFields4Sbox
|
||||
{
|
||||
public string type { get; set; }
|
||||
public string tag { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ServiceLib.Models;
|
||||
public class V2rayConfig
|
||||
{
|
||||
public Log4Ray log { get; set; }
|
||||
public object dns { get; set; }
|
||||
public Dns4Ray dns { get; set; }
|
||||
public List<Inbounds4Ray> inbounds { get; set; }
|
||||
public List<Outbounds4Ray> outbounds { get; set; }
|
||||
public Routing4Ray routing { get; set; }
|
||||
@@ -203,7 +203,8 @@ public class Response4Ray
|
||||
|
||||
public class Dns4Ray
|
||||
{
|
||||
public List<string> servers { get; set; }
|
||||
public Dictionary<string, List<string>>? hosts { get; set; }
|
||||
public List<object> servers { get; set; }
|
||||
}
|
||||
|
||||
public class DnsServer4Ray
|
||||
@@ -211,6 +212,8 @@ public class DnsServer4Ray
|
||||
public string? address { get; set; }
|
||||
public List<string>? domains { get; set; }
|
||||
public bool? skipFallback { get; set; }
|
||||
public List<string>? expectedIPs { get; set; }
|
||||
public List<string>? unexpectedIPs { get; set; }
|
||||
}
|
||||
|
||||
public class Routing4Ray
|
||||
@@ -340,6 +343,7 @@ public class TlsSettings4Ray
|
||||
public string? publicKey { get; set; }
|
||||
public string? shortId { get; set; }
|
||||
public string? spiderX { get; set; }
|
||||
public string? mldsa65Verify { get; set; }
|
||||
}
|
||||
|
||||
public class TcpSettings4Ray
|
||||
|
||||
229
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
229
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -654,6 +654,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [Anytls] Configuration 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddAnytlsServer {
|
||||
get {
|
||||
return ResourceManager.GetString("menuAddAnytlsServer", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add a custom configuration Configuration 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2202,6 +2211,24 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Incorrect password, please try again. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SudoIncorrectPasswordTip {
|
||||
get {
|
||||
return ResourceManager.GetString("SudoIncorrectPasswordTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add Common DNS Hosts 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbAddCommonDNSHosts {
|
||||
get {
|
||||
return ResourceManager.GetString("TbAddCommonDNSHosts", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Address 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2238,6 +2265,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Apply to Proxy Domains Only 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbApplyProxyDomainsOnly {
|
||||
get {
|
||||
return ResourceManager.GetString("TbApplyProxyDomainsOnly", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Auto refresh 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2265,6 +2301,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Block SVCB and HTTPS Queries 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbBlockSVCBHTTPSQueries {
|
||||
get {
|
||||
return ResourceManager.GetString("TbBlockSVCBHTTPSQueries", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Browse 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2319,6 +2364,24 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Enable Custom DNS 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbCustomDNSEnable {
|
||||
get {
|
||||
return ResourceManager.GetString("TbCustomDNSEnable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Custom DNS Enabled, This Page's Settings Invalid 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbCustomDNSEnabledPageInvalid {
|
||||
get {
|
||||
return ResourceManager.GetString("TbCustomDNSEnabledPageInvalid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Display GUI 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2337,6 +2400,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 DNS Hosts: ("domain1 ip1 ip2" per line) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbDNSHostsConfig {
|
||||
get {
|
||||
return ResourceManager.GetString("TbDNSHostsConfig", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Supports DNS Object; Click to view documentation 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2382,6 +2454,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Domestic DNS 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbDomesticDNS {
|
||||
get {
|
||||
return ResourceManager.GetString("TbDomesticDNS", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Edit 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2400,6 +2481,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 FakeIP 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbFakeIP {
|
||||
get {
|
||||
return ResourceManager.GetString("TbFakeIP", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fingerprint 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2508,6 +2598,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Mldsa65Verify 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbMldsa65Verify {
|
||||
get {
|
||||
return ResourceManager.GetString("TbMldsa65Verify", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Transport protocol(network) 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2589,6 +2688,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Prevent DNS Leaks 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbPreventDNSLeaks {
|
||||
get {
|
||||
return ResourceManager.GetString("TbPreventDNSLeaks", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Private Key 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2625,6 +2733,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Remote DNS 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbRemoteDNS {
|
||||
get {
|
||||
return ResourceManager.GetString("TbRemoteDNS", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Camouflage domain(host) 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2733,6 +2850,69 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 sing-box Direct Resolution Strategy 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBDirectResolveStrategy {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBDirectResolveStrategy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The sing-box DoH resolution server can be overwritten 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBDoHOverride {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBDoHOverride", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 sing-box DoH Resolver Server 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBDoHResolverServer {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBDoHResolverServer", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fallback DNS Resolution, Suggest IP 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBFallbackDNSResolve {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBFallbackDNSResolve", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Resolve Outbound Domains 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBOutboundDomainResolve {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBOutboundDomainResolve", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Outbound DNS Resolution (sing-box) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBOutboundsResolverDNS {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBOutboundsResolverDNS", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 sing-box Remote Resolution Strategy 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSBRemoteResolveStrategy {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSBRemoteResolveStrategy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Encryption method (security) 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -3058,7 +3238,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Use Xray and enable non-Tun mode, which conflicts with the group previous proxy 的本地化字符串。
|
||||
/// 查找类似 which conflicts with the group previous proxy 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsEnableFragmentTips {
|
||||
get {
|
||||
@@ -3193,7 +3373,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart. 的本地化字符串。
|
||||
/// 查找类似 The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsLinuxSudoPasswordTip {
|
||||
get {
|
||||
@@ -3678,6 +3858,33 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Validate Regional Domain IPs 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbValidateDirectExpectedIPs {
|
||||
get {
|
||||
return ResourceManager.GetString("TbValidateDirectExpectedIPs", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbValidateDirectExpectedIPsDesc {
|
||||
get {
|
||||
return ResourceManager.GetString("TbValidateDirectExpectedIPsDesc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 xray Freedom Resolution Strategy 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbXrayFreedomResolveStrategy {
|
||||
get {
|
||||
return ResourceManager.GetString("TbXrayFreedomResolveStrategy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 The delay: {0} ms, {1} 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -3687,6 +3894,24 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Advanced DNS Settings 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ThAdvancedDNSSettings {
|
||||
get {
|
||||
return ResourceManager.GetString("ThAdvancedDNSSettings", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Basic DNS Settings 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ThBasicDNSSettings {
|
||||
get {
|
||||
return ResourceManager.GetString("ThBasicDNSSettings", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Active 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1105,7 +1105,7 @@
|
||||
<value>افزودن سرور [HTTP]</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||
<value>از Xray استفاده کنید و حالت non-Tun را فعال کنید، که با پراکسی قبلی گروه در تضاد است</value>
|
||||
<value>which conflicts with the group previous proxy</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||
<value>فعال کردن فرگمنت</value>
|
||||
@@ -1318,7 +1318,7 @@
|
||||
<value>رمز عبور sudo سیستم</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>رمز عبوری که وارد کرده اید تایید نمی شود، بنابراین مطمئن شوید که آن را به درستی وارد کرده اید. اگر برنامه به دلیل ورودی نادرست به درستی کار نمی کند، لطفاً برنامه را مجدداً راه اندازی کنید. رمز عبور ذخیره نمی شود و پس از هر بار راه اندازی مجدد باید آن را دوباره وارد کنید.</value>
|
||||
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
|
||||
</data>
|
||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||
<value>*حالت xhttp</value>
|
||||
@@ -1395,4 +1395,79 @@
|
||||
<data name="TbRuleOutboundTagTip" xml:space="preserve">
|
||||
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
|
||||
</data>
|
||||
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
|
||||
<value>Incorrect password, please try again.</value>
|
||||
</data>
|
||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||
<value>Mldsa65Verify</value>
|
||||
</data>
|
||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||
<value>Add [Anytls] Configuration</value>
|
||||
</data>
|
||||
<data name="TbRemoteDNS" xml:space="preserve">
|
||||
<value>Remote DNS</value>
|
||||
</data>
|
||||
<data name="TbDomesticDNS" xml:space="preserve">
|
||||
<value>Domestic DNS</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||
<value>Outbound DNS Resolution (sing-box)</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||
<value>Resolve Outbound Domains</value>
|
||||
</data>
|
||||
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||
<value>sing-box DoH Resolver Server</value>
|
||||
</data>
|
||||
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||
<value>Fallback DNS Resolution, Suggest IP</value>
|
||||
</data>
|
||||
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
|
||||
<value>xray Freedom Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Direct Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Remote Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
||||
<value>Add Common DNS Hosts</value>
|
||||
</data>
|
||||
<data name="TbSBDoHOverride" xml:space="preserve">
|
||||
<value>The sing-box DoH resolution server can be overwritten</value>
|
||||
</data>
|
||||
<data name="TbFakeIP" xml:space="preserve">
|
||||
<value>FakeIP</value>
|
||||
</data>
|
||||
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
|
||||
<value>Block SVCB and HTTPS Queries</value>
|
||||
</data>
|
||||
<data name="TbPreventDNSLeaks" xml:space="preserve">
|
||||
<value>Prevent DNS Leaks</value>
|
||||
</data>
|
||||
<data name="TbDNSHostsConfig" xml:space="preserve">
|
||||
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
|
||||
</data>
|
||||
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
|
||||
<value>Apply to Proxy Domains Only</value>
|
||||
</data>
|
||||
<data name="ThBasicDNSSettings" xml:space="preserve">
|
||||
<value>Basic DNS Settings</value>
|
||||
</data>
|
||||
<data name="ThAdvancedDNSSettings" xml:space="preserve">
|
||||
<value>Advanced DNS Settings</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
|
||||
<value>Validate Regional Domain IPs</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
|
||||
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnable" xml:space="preserve">
|
||||
<value>Enable Custom DNS</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
|
||||
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
|
||||
</data>
|
||||
</root>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1105,7 +1105,7 @@
|
||||
<value>Add [HTTP] Configuration</value>
|
||||
</data>
|
||||
<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 name="TbSettingsEnableFragment" xml:space="preserve">
|
||||
<value>Enable fragment</value>
|
||||
@@ -1318,7 +1318,7 @@
|
||||
<value>System sudo password</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.</value>
|
||||
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
|
||||
</data>
|
||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||
<value>*xhttp mode</value>
|
||||
@@ -1395,4 +1395,79 @@
|
||||
<data name="TbRuleOutboundTagTip" xml:space="preserve">
|
||||
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
|
||||
</data>
|
||||
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
|
||||
<value>Incorrect password, please try again.</value>
|
||||
</data>
|
||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||
<value>Mldsa65Verify</value>
|
||||
</data>
|
||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||
<value>Add [Anytls] Configuration</value>
|
||||
</data>
|
||||
<data name="TbRemoteDNS" xml:space="preserve">
|
||||
<value>Remote DNS</value>
|
||||
</data>
|
||||
<data name="TbDomesticDNS" xml:space="preserve">
|
||||
<value>Domestic DNS</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||
<value>Outbound DNS Resolution (sing-box)</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||
<value>Resolve Outbound Domains</value>
|
||||
</data>
|
||||
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||
<value>sing-box DoH Resolver Server</value>
|
||||
</data>
|
||||
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||
<value>Fallback DNS Resolution, Suggest IP</value>
|
||||
</data>
|
||||
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
|
||||
<value>xray Freedom Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Direct Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Remote Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
||||
<value>Add Common DNS Hosts</value>
|
||||
</data>
|
||||
<data name="TbSBDoHOverride" xml:space="preserve">
|
||||
<value>The sing-box DoH resolution server can be overwritten</value>
|
||||
</data>
|
||||
<data name="TbFakeIP" xml:space="preserve">
|
||||
<value>FakeIP</value>
|
||||
</data>
|
||||
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
|
||||
<value>Block SVCB and HTTPS Queries</value>
|
||||
</data>
|
||||
<data name="TbPreventDNSLeaks" xml:space="preserve">
|
||||
<value>Prevent DNS Leaks</value>
|
||||
</data>
|
||||
<data name="TbDNSHostsConfig" xml:space="preserve">
|
||||
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
|
||||
</data>
|
||||
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
|
||||
<value>Apply to Proxy Domains Only</value>
|
||||
</data>
|
||||
<data name="ThBasicDNSSettings" xml:space="preserve">
|
||||
<value>Basic DNS Settings</value>
|
||||
</data>
|
||||
<data name="ThAdvancedDNSSettings" xml:space="preserve">
|
||||
<value>Advanced DNS Settings</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
|
||||
<value>Validate Regional Domain IPs</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
|
||||
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnable" xml:space="preserve">
|
||||
<value>Enable Custom DNS</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
|
||||
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,36 +26,36 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
@@ -807,9 +807,6 @@
|
||||
<data name="menuMoveUp" xml:space="preserve">
|
||||
<value>Вверх (U)</value>
|
||||
</data>
|
||||
<data name="menuMoveTo" xml:space="preserve">
|
||||
<value>Переместить вверх/вниз</value>
|
||||
</data>
|
||||
<data name="MsgFilterTitle" xml:space="preserve">
|
||||
<value>Фильтр, поддерживает regex</value>
|
||||
</data>
|
||||
@@ -969,6 +966,9 @@
|
||||
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
|
||||
<value>URL для тестирования скорости</value>
|
||||
</data>
|
||||
<data name="menuMoveTo" xml:space="preserve">
|
||||
<value>Переместить вверх/вниз</value>
|
||||
</data>
|
||||
<data name="TbPublicKey" xml:space="preserve">
|
||||
<value>PublicKey</value>
|
||||
</data>
|
||||
@@ -1105,7 +1105,7 @@
|
||||
<value>Добавить сервер [HTTP]</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||
<value>Используйте Xray и отключите режим TUN, так как он конфликтует с предыдущим прокси-сервером группы</value>
|
||||
<value>which conflicts with the group previous proxy</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||
<value>Включить фрагментацию (Fragment)</value>
|
||||
@@ -1318,7 +1318,7 @@
|
||||
<value>Пароль sudo системы</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>Введенный вами пароль не может быть подтвержден, поэтому убедитесь, что вы ввели его правильно. Если приложение не работает должным образом из-за неправильного ввода, то перезапустите его. Пароль не будет сохранен, и вам придется вводить его заново после каждого перезапуска</value>
|
||||
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
|
||||
</data>
|
||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||
<value>*XHTTP-режим</value>
|
||||
@@ -1395,4 +1395,79 @@
|
||||
<data name="TbRuleOutboundTagTip" xml:space="preserve">
|
||||
<value>Can fill in the configuration remarks, please make sure it exist and are unique</value>
|
||||
</data>
|
||||
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
|
||||
<value>Incorrect password, please try again.</value>
|
||||
</data>
|
||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||
<value>Mldsa65Verify</value>
|
||||
</data>
|
||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||
<value>Добавить сервер [Anytls]</value>
|
||||
</data>
|
||||
<data name="TbRemoteDNS" xml:space="preserve">
|
||||
<value>Remote DNS</value>
|
||||
</data>
|
||||
<data name="TbDomesticDNS" xml:space="preserve">
|
||||
<value>Domestic DNS</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||
<value>Outbound DNS Resolution (sing-box)</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||
<value>Resolve Outbound Domains</value>
|
||||
</data>
|
||||
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||
<value>sing-box DoH Resolver Server</value>
|
||||
</data>
|
||||
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||
<value>Fallback DNS Resolution, Suggest IP</value>
|
||||
</data>
|
||||
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
|
||||
<value>xray Freedom Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Direct Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Remote Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
||||
<value>Add Common DNS Hosts</value>
|
||||
</data>
|
||||
<data name="TbSBDoHOverride" xml:space="preserve">
|
||||
<value>The sing-box DoH resolution server can be overwritten</value>
|
||||
</data>
|
||||
<data name="TbFakeIP" xml:space="preserve">
|
||||
<value>FakeIP</value>
|
||||
</data>
|
||||
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
|
||||
<value>Block SVCB and HTTPS Queries</value>
|
||||
</data>
|
||||
<data name="TbPreventDNSLeaks" xml:space="preserve">
|
||||
<value>Prevent DNS Leaks</value>
|
||||
</data>
|
||||
<data name="TbDNSHostsConfig" xml:space="preserve">
|
||||
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
|
||||
</data>
|
||||
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
|
||||
<value>Apply to Proxy Domains Only</value>
|
||||
</data>
|
||||
<data name="ThBasicDNSSettings" xml:space="preserve">
|
||||
<value>Basic DNS Settings</value>
|
||||
</data>
|
||||
<data name="ThAdvancedDNSSettings" xml:space="preserve">
|
||||
<value>Advanced DNS Settings</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
|
||||
<value>Validate Regional Domain IPs</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
|
||||
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnable" xml:space="preserve">
|
||||
<value>Enable Custom DNS</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
|
||||
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -703,7 +703,7 @@
|
||||
<value>例外:对于下列字符开头的地址,不使用代理配置文件。使用分号 (;) 分隔。</value>
|
||||
</data>
|
||||
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
|
||||
<value>显示实时速度(需重启)</value>
|
||||
<value>显示实时速度 (需重启)</value>
|
||||
</data>
|
||||
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
|
||||
<value>去重时保留序号较小的项</value>
|
||||
@@ -739,7 +739,7 @@
|
||||
<value>开机启动 (可能会不成功)</value>
|
||||
</data>
|
||||
<data name="TbSettingsStatistics" xml:space="preserve">
|
||||
<value>启用流量统计(需重启)</value>
|
||||
<value>启用流量统计 (需重启)</value>
|
||||
</data>
|
||||
<data name="TbSettingsSubConvert" xml:space="preserve">
|
||||
<value>订阅转换网址 (可选)</value>
|
||||
@@ -886,7 +886,7 @@
|
||||
<value>仅限路由 (routeOnly)</value>
|
||||
</data>
|
||||
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
|
||||
<value>请勿将代理服务器用于本地(Intranet)地址</value>
|
||||
<value>请勿将代理服务器用于本地 (Intranet) 地址</value>
|
||||
</data>
|
||||
<data name="menuMixedTestServer" xml:space="preserve">
|
||||
<value>一键多线程测试延迟和速度 (Ctrl+E)</value>
|
||||
@@ -919,7 +919,7 @@
|
||||
<value>移至订阅分组</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
|
||||
<value>启用配置文件拖放排序(需重启)</value>
|
||||
<value>启用配置文件拖放排序 (需重启)</value>
|
||||
</data>
|
||||
<data name="TbAutoRefresh" xml:space="preserve">
|
||||
<value>自动刷新</value>
|
||||
@@ -946,10 +946,10 @@
|
||||
<value>仅对 tcp/http、ws 协议生效</value>
|
||||
</data>
|
||||
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
|
||||
<value>当前字体(需重启)</value>
|
||||
<value>当前字体 (需重启)</value>
|
||||
</data>
|
||||
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
|
||||
<value>拷贝字体 TTF/TTC 文件到目录 guiFonts,重启设置</value>
|
||||
<value>拷贝字体 TTF/TTC 文件到目录 guiFonts,重启生效</value>
|
||||
</data>
|
||||
<data name="TbSettingsSocksPortTip" xml:space="preserve">
|
||||
<value>Pac 端口 = +3;Xray API 端口 = +4;mihomo API 端口 = +5;</value>
|
||||
@@ -979,10 +979,10 @@
|
||||
<value>SpiderX</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableHWA" xml:space="preserve">
|
||||
<value>启用硬件加速(需重启)</value>
|
||||
<value>启用硬件加速 (需重启)</value>
|
||||
</data>
|
||||
<data name="SpeedtestingWait" xml:space="preserve">
|
||||
<value>等待测试中(按 ESC 终止)...</value>
|
||||
<value>等待测试中 (按 ESC 终止)...</value>
|
||||
</data>
|
||||
<data name="TipDisplayLog" xml:space="preserve">
|
||||
<value>当有异常断流时请关闭</value>
|
||||
@@ -1075,7 +1075,7 @@
|
||||
<value>Reserved (2,3,4)</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Address (Ipv4,Ipv6)</value>
|
||||
<value>Address (IPv4,IPv6)</value>
|
||||
</data>
|
||||
<data name="TbPath7" xml:space="preserve">
|
||||
<value>混淆密码 (obfs password)</value>
|
||||
@@ -1102,13 +1102,13 @@
|
||||
<value>添加 [HTTP] 配置文件</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||
<value>使用 Xray 且非 Tun 模式启用,和分组前置代理冲突</value>
|
||||
<value>和分组前置代理冲突</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||
<value>启用分片(Fragment)</value>
|
||||
<value>启用分片 (Fragment)</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
|
||||
<value>启用 sing-box(规则集文件)的缓存文件</value>
|
||||
<value>启用 sing-box (规则集文件) 的缓存文件</value>
|
||||
</data>
|
||||
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||
<value>自定义 sing-box rule-set</value>
|
||||
@@ -1201,7 +1201,7 @@
|
||||
<value>Outbound 默认解析策略</value>
|
||||
</data>
|
||||
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
|
||||
<value>主界面布局方向(需重启)</value>
|
||||
<value>主界面布局方向 (需重启)</value>
|
||||
</data>
|
||||
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
|
||||
<value>Outbound 域名解析地址</value>
|
||||
@@ -1303,7 +1303,7 @@
|
||||
<value>请不要使用不安全的 HTTP 协议订阅地址</value>
|
||||
</data>
|
||||
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||
<value>安装字体到系统中,选择或填入字体名称,重启设置</value>
|
||||
<value>安装字体到系统中,选择或填入字体名称,重启生效</value>
|
||||
</data>
|
||||
<data name="menuExitTips" xml:space="preserve">
|
||||
<value>是否确定退出?</value>
|
||||
@@ -1315,10 +1315,10 @@
|
||||
<value>系统的 sudo 密码</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>输入的密码无法校验,所以请确保输入正确。如果因为输入错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
|
||||
<value>密码将调用命令行校验,如果因为校验错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
|
||||
</data>
|
||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||
<value>*xhttp 模式</value>
|
||||
<value>*XHTTP 模式</value>
|
||||
</data>
|
||||
<data name="TransportExtraTip" xml:space="preserve">
|
||||
<value>XHTTP Extra 原始 JSON,格式: { XHTTPObject }</value>
|
||||
@@ -1339,7 +1339,7 @@
|
||||
<value>开启第二个本地监听端口</value>
|
||||
</data>
|
||||
<data name="TbRoutingInboundTagTips" xml:space="preserve">
|
||||
<value>socks:本地端口,socks2:第二个本地端口,socks3:局域网端口</value>
|
||||
<value>Socks:本地端口,Socks2:第二个本地端口,Socks3:局域网端口</value>
|
||||
</data>
|
||||
<data name="TbSettingsTheme" xml:space="preserve">
|
||||
<value>主题</value>
|
||||
@@ -1372,13 +1372,13 @@
|
||||
<value>多配置文件随机 Xray</value>
|
||||
</data>
|
||||
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
|
||||
<value>多配置文件负载均衡 Xray</value>
|
||||
<value>多配置文件负载均衡 Xray</value>
|
||||
</data>
|
||||
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
|
||||
<value>多配置文件最低延迟 Xray</value>
|
||||
<value>多配置文件最低延迟 Xray</value>
|
||||
</data>
|
||||
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
|
||||
<value>多配置文件最稳定 Xray</value>
|
||||
<value>多配置文件最稳定 Xray</value>
|
||||
</data>
|
||||
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
|
||||
<value>多配置文件最低延迟 sing-box</value>
|
||||
@@ -1392,4 +1392,79 @@
|
||||
<data name="TbRuleOutboundTagTip" xml:space="preserve">
|
||||
<value>可以填写配置文件别名,请确保存在并唯一</value>
|
||||
</data>
|
||||
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
|
||||
<value>密码错误,请重试。</value>
|
||||
</data>
|
||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||
<value>Mldsa65Verify</value>
|
||||
</data>
|
||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||
<value>添加 [Anytls] 配置文件</value>
|
||||
</data>
|
||||
<data name="TbRemoteDNS" xml:space="preserve">
|
||||
<value>远程 DNS</value>
|
||||
</data>
|
||||
<data name="TbDomesticDNS" xml:space="preserve">
|
||||
<value>直连 DNS</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||
<value>出站 DNS 解析(sing-box)</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||
<value>解析出站域名</value>
|
||||
</data>
|
||||
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||
<value>sing-box DoH 解析服务器</value>
|
||||
</data>
|
||||
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||
<value>兜底解析其他 DNS 域名,建议设为 ip</value>
|
||||
</data>
|
||||
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
|
||||
<value>xray freedom 解析策略</value>
|
||||
</data>
|
||||
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box 直连解析策略</value>
|
||||
</data>
|
||||
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box 远程解析策略</value>
|
||||
</data>
|
||||
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
||||
<value>添加常用 DNS Hosts</value>
|
||||
</data>
|
||||
<data name="TbSBDoHOverride" xml:space="preserve">
|
||||
<value>开启后可覆盖 sing-box DoH 解析服务器</value>
|
||||
</data>
|
||||
<data name="TbFakeIP" xml:space="preserve">
|
||||
<value>FakeIP</value>
|
||||
</data>
|
||||
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
|
||||
<value>阻止 SVCB 和 HTTPS 查询</value>
|
||||
</data>
|
||||
<data name="TbPreventDNSLeaks" xml:space="preserve">
|
||||
<value>避免 DNS 泄漏</value>
|
||||
</data>
|
||||
<data name="TbDNSHostsConfig" xml:space="preserve">
|
||||
<value>DNS Hosts:(“域名1 ip1 ip2” 一行一个)</value>
|
||||
</data>
|
||||
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
|
||||
<value>仅对代理域名生效</value>
|
||||
</data>
|
||||
<data name="ThBasicDNSSettings" xml:space="preserve">
|
||||
<value>DNS 基础设置</value>
|
||||
</data>
|
||||
<data name="ThAdvancedDNSSettings" xml:space="preserve">
|
||||
<value>DNS 进阶设置</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
|
||||
<value>校验相应地区域名 IP</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
|
||||
<value>配置后,会对相应地区域名(如 geosite:cn)的返回 IP 进行校验,仅返回期望 IP</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnable" xml:space="preserve">
|
||||
<value>启用自定义 DNS</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
|
||||
<value>自定义 DNS 已启用,此页面配置将无效</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1102,7 +1102,7 @@
|
||||
<value>新增 [HTTP] 設定檔</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||
<value>使用 Xray 且非 Tun 模式啟用,和分組前置代理衝突</value>
|
||||
<value>和分組前置代理衝突</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||
<value>啟用分片(Fragment)</value>
|
||||
@@ -1315,7 +1315,7 @@
|
||||
<value>系統的 sudo 密碼</value>
|
||||
</data>
|
||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||
<value>輸入的密碼無法校驗,所以請確保輸入正確。如果因為輸入錯誤導致無法正常運作時,請重新啟動本應用。 密碼不會儲存,每次重啟後都需要再次輸入。</value>
|
||||
<value>密碼將調用命令行校驗,如果因為校驗錯誤導致無法正常運行時,請重啟本應用。密碼不會存儲,每次重啟後都需要再次輸入。</value>
|
||||
</data>
|
||||
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||
<value>*xhttp 模式</value>
|
||||
@@ -1392,4 +1392,79 @@
|
||||
<data name="TbRuleOutboundTagTip" xml:space="preserve">
|
||||
<value>可以填寫設定檔別名,請確保存在並唯一</value>
|
||||
</data>
|
||||
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
|
||||
<value>密碼錯誤,請重試。</value>
|
||||
</data>
|
||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||
<value>Mldsa65Verify</value>
|
||||
</data>
|
||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||
<value>新增 [Anytls] 設定檔</value>
|
||||
</data>
|
||||
<data name="TbRemoteDNS" xml:space="preserve">
|
||||
<value>Remote DNS</value>
|
||||
</data>
|
||||
<data name="TbDomesticDNS" xml:space="preserve">
|
||||
<value>Domestic DNS</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundsResolverDNS" xml:space="preserve">
|
||||
<value>Outbound DNS Resolution (sing-box)</value>
|
||||
</data>
|
||||
<data name="TbSBOutboundDomainResolve" xml:space="preserve">
|
||||
<value>Resolve Outbound Domains</value>
|
||||
</data>
|
||||
<data name="TbSBDoHResolverServer" xml:space="preserve">
|
||||
<value>sing-box DoH Resolver Server</value>
|
||||
</data>
|
||||
<data name="TbSBFallbackDNSResolve" xml:space="preserve">
|
||||
<value>Fallback DNS Resolution, Suggest IP</value>
|
||||
</data>
|
||||
<data name="TbXrayFreedomResolveStrategy" xml:space="preserve">
|
||||
<value>xray Freedom Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBDirectResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Direct Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbSBRemoteResolveStrategy" xml:space="preserve">
|
||||
<value>sing-box Remote Resolution Strategy</value>
|
||||
</data>
|
||||
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
||||
<value>Add Common DNS Hosts</value>
|
||||
</data>
|
||||
<data name="TbSBDoHOverride" xml:space="preserve">
|
||||
<value>The sing-box DoH resolution server can be overwritten</value>
|
||||
</data>
|
||||
<data name="TbFakeIP" xml:space="preserve">
|
||||
<value>FakeIP</value>
|
||||
</data>
|
||||
<data name="TbBlockSVCBHTTPSQueries" xml:space="preserve">
|
||||
<value>Block SVCB and HTTPS Queries</value>
|
||||
</data>
|
||||
<data name="TbPreventDNSLeaks" xml:space="preserve">
|
||||
<value>Prevent DNS Leaks</value>
|
||||
</data>
|
||||
<data name="TbDNSHostsConfig" xml:space="preserve">
|
||||
<value>DNS Hosts: ("domain1 ip1 ip2" per line)</value>
|
||||
</data>
|
||||
<data name="TbApplyProxyDomainsOnly" xml:space="preserve">
|
||||
<value>Apply to Proxy Domains Only</value>
|
||||
</data>
|
||||
<data name="ThBasicDNSSettings" xml:space="preserve">
|
||||
<value>Basic DNS Settings</value>
|
||||
</data>
|
||||
<data name="ThAdvancedDNSSettings" xml:space="preserve">
|
||||
<value>Advanced DNS Settings</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPs" xml:space="preserve">
|
||||
<value>Validate Regional Domain IPs</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
|
||||
<value>When configured, validates IPs returned for regional domains (e.g., geosite:cn), returning only expected IPs</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnable" xml:space="preserve">
|
||||
<value>Enable Custom DNS</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnabledPageInvalid" xml:space="preserve">
|
||||
<value>Custom DNS Enabled, This Page's Settings Invalid</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"timestamp": true
|
||||
@@ -14,22 +14,10 @@
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "block",
|
||||
"tag": "block"
|
||||
},
|
||||
{
|
||||
"tag": "dns_out",
|
||||
"type": "dns"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"protocol": [ "dns" ],
|
||||
"outbound": "dns_out"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -2,28 +2,33 @@
|
||||
"servers": [
|
||||
{
|
||||
"tag": "remote",
|
||||
"address": "tcp://8.8.8.8",
|
||||
"strategy": "prefer_ipv4",
|
||||
"type": "tcp",
|
||||
"server": "8.8.8.8",
|
||||
"detour": "proxy"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"address": "223.5.5.5",
|
||||
"strategy": "prefer_ipv4",
|
||||
"detour": "direct"
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"address": "rcode://success"
|
||||
"type": "udp",
|
||||
"server": "223.5.5.5"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": [
|
||||
"googleapis.cn",
|
||||
"gstatic.com"
|
||||
],
|
||||
"server": "remote",
|
||||
"strategy": "prefer_ipv4"
|
||||
},
|
||||
{
|
||||
"rule_set": [
|
||||
"geosite-cn"
|
||||
],
|
||||
"server": "local"
|
||||
"server": "local",
|
||||
"strategy": "prefer_ipv4"
|
||||
}
|
||||
],
|
||||
"final": "remote"
|
||||
"final": "remote",
|
||||
"strategy": "prefer_ipv4"
|
||||
}
|
||||
|
||||
61
v2rayN/ServiceLib/Sample/kill_as_sudo_linux_sh
Normal file
61
v2rayN/ServiceLib/Sample/kill_as_sudo_linux_sh
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Process Terminator Script for Linux
|
||||
# This script forcibly terminates a process and all its child processes
|
||||
#
|
||||
|
||||
# Check if PID argument is provided
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <PID>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PID=$1
|
||||
|
||||
# Validate that input is a valid PID (numeric)
|
||||
if ! [[ "$PID" =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: The PID must be a numeric value"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the process exists
|
||||
if ! ps -p $PID > /dev/null; then
|
||||
echo "Warning: No process found with PID $PID"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Recursive function to find and kill all child processes
|
||||
kill_children() {
|
||||
local parent=$1
|
||||
local children=$(ps -o pid --no-headers --ppid "$parent")
|
||||
|
||||
# Output information about processes being terminated
|
||||
echo "Processing children of PID: $parent..."
|
||||
|
||||
# Process each child
|
||||
for child in $children; do
|
||||
# Recursively find and kill child's children first
|
||||
kill_children "$child"
|
||||
|
||||
# Force kill the child process
|
||||
echo "Terminating child process: $child"
|
||||
kill -9 "$child" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
echo "============================================"
|
||||
echo "Starting termination of process $PID and all its children"
|
||||
echo "============================================"
|
||||
|
||||
# Find and kill all child processes
|
||||
kill_children "$PID"
|
||||
|
||||
# Finally kill the main process
|
||||
echo "Terminating main process: $PID"
|
||||
kill -9 "$PID" 2>/dev/null || true
|
||||
|
||||
echo "============================================"
|
||||
echo "Process $PID and all its children have been terminated"
|
||||
echo "============================================"
|
||||
|
||||
exit 0
|
||||
56
v2rayN/ServiceLib/Sample/kill_as_sudo_osx_sh
Normal file
56
v2rayN/ServiceLib/Sample/kill_as_sudo_osx_sh
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Process Terminator Script for macOS
|
||||
# This script forcibly terminates a process and all its descendant processes
|
||||
#
|
||||
|
||||
# Check if PID argument is provided
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <PID>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PID=$1
|
||||
|
||||
# Validate that input is a valid PID (numeric)
|
||||
if ! [[ "$PID" =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: The PID must be a numeric value"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the process exists - using kill -0 which is more reliable on macOS
|
||||
if ! kill -0 $PID 2>/dev/null; then
|
||||
echo "Warning: No process found with PID $PID"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Recursive function to find and kill all descendant processes
|
||||
kill_descendants() {
|
||||
local parent=$1
|
||||
# Use ps -axo for macOS to ensure all processes are included
|
||||
local children=$(ps -axo pid=,ppid= | awk -v ppid=$parent '$2==ppid {print $1}')
|
||||
|
||||
echo "Processing children of PID: $parent..."
|
||||
for child in $children; do
|
||||
kill_descendants "$child"
|
||||
echo "Terminating child process: $child"
|
||||
kill -9 "$child" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
echo "============================================"
|
||||
echo "Starting termination of process $PID and all its descendants"
|
||||
echo "============================================"
|
||||
|
||||
# Find and kill all descendant processes
|
||||
kill_descendants "$PID"
|
||||
|
||||
# Finally kill the main process
|
||||
echo "Terminating main process: $PID"
|
||||
kill -9 "$PID" 2>/dev/null || true
|
||||
|
||||
echo "============================================"
|
||||
echo "Process $PID and all its descendants have been terminated"
|
||||
echo "============================================"
|
||||
|
||||
exit 0
|
||||
@@ -2,29 +2,33 @@
|
||||
"servers": [
|
||||
{
|
||||
"tag": "remote",
|
||||
"address": "tcp://8.8.8.8",
|
||||
"strategy": "prefer_ipv4",
|
||||
"type": "tcp",
|
||||
"server": "8.8.8.8",
|
||||
"detour": "proxy"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"address": "223.5.5.5",
|
||||
"strategy": "prefer_ipv4",
|
||||
"detour": "direct"
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"address": "rcode://success"
|
||||
"type": "udp",
|
||||
"server": "223.5.5.5"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"rule_set": [
|
||||
"geosite-cn",
|
||||
"geosite-geolocation-cn"
|
||||
"domain_suffix": [
|
||||
"googleapis.cn",
|
||||
"gstatic.com"
|
||||
],
|
||||
"server": "local"
|
||||
"server": "remote",
|
||||
"strategy": "prefer_ipv4"
|
||||
},
|
||||
{
|
||||
"rule_set": [
|
||||
"geosite-cn"
|
||||
],
|
||||
"server": "local",
|
||||
"strategy": "prefer_ipv4"
|
||||
}
|
||||
],
|
||||
"final": "remote"
|
||||
}
|
||||
"final": "remote",
|
||||
"strategy": "prefer_ipv4"
|
||||
}
|
||||
@@ -8,13 +8,13 @@
|
||||
139,
|
||||
5353
|
||||
],
|
||||
"outbound": "block"
|
||||
"action": "reject"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"224.0.0.0/3",
|
||||
"ff00::/8"
|
||||
],
|
||||
"outbound": "block"
|
||||
"action": "reject"
|
||||
}
|
||||
]
|
||||
@@ -28,6 +28,8 @@
|
||||
<EmbeddedResource Include="Sample\custom_routing_white" />
|
||||
<EmbeddedResource Include="Sample\dns_singbox_normal" />
|
||||
<EmbeddedResource Include="Sample\dns_v2ray_normal" />
|
||||
<EmbeddedResource Include="Sample\kill_as_sudo_linux_sh" />
|
||||
<EmbeddedResource Include="Sample\kill_as_sudo_osx_sh" />
|
||||
<EmbeddedResource Include="Sample\pac" />
|
||||
<EmbeddedResource Include="Sample\proxy_set_linux_sh" />
|
||||
<EmbeddedResource Include="Sample\proxy_set_osx_sh" />
|
||||
|
||||
@@ -12,7 +12,7 @@ public class CoreConfigClashService
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
|
||||
public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
|
||||
{
|
||||
var ret = new RetResult();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ServiceLib.Services.CoreConfig;
|
||||
|
||||
@@ -120,7 +122,7 @@ public class CoreConfigV2rayService
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC)
|
||||
if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -631,7 +633,7 @@ public class CoreConfigV2rayService
|
||||
|
||||
private async Task<string?> GenRoutingUserRuleOutbound(string outboundTag, V2rayConfig v2rayConfig)
|
||||
{
|
||||
if (outboundTag is Global.ProxyTag or Global.ProxyTag or Global.BlockTag)
|
||||
if (Global.OutboundTags.Contains(outboundTag))
|
||||
{
|
||||
return outboundTag;
|
||||
}
|
||||
@@ -640,7 +642,8 @@ public class CoreConfigV2rayService
|
||||
if (node == null
|
||||
|| node.ConfigType == EConfigType.Custom
|
||||
|| node.ConfigType == EConfigType.Hysteria2
|
||||
|| node.ConfigType == EConfigType.TUIC)
|
||||
|| node.ConfigType == EConfigType.TUIC
|
||||
|| node.ConfigType == EConfigType.Anytls)
|
||||
{
|
||||
return Global.ProxyTag;
|
||||
}
|
||||
@@ -944,6 +947,7 @@ public class CoreConfigV2rayService
|
||||
publicKey = node.PublicKey,
|
||||
shortId = node.ShortId,
|
||||
spiderX = node.SpiderX,
|
||||
mldsa65Verify = node.Mldsa65Verify,
|
||||
show = false,
|
||||
};
|
||||
|
||||
@@ -1132,6 +1136,264 @@ public class CoreConfigV2rayService
|
||||
}
|
||||
|
||||
private async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||
if (item != null && item.Enabled == true)
|
||||
{
|
||||
return await GenDnsCompatible(node, v2rayConfig);
|
||||
}
|
||||
var simpleDNSItem = _config.SimpleDNSItem;
|
||||
var domainStrategy4Freedom = simpleDNSItem?.RayStrategy4Freedom;
|
||||
|
||||
//Outbound Freedom domainStrategy
|
||||
if (domainStrategy4Freedom.IsNotEmpty())
|
||||
{
|
||||
var outbound = v2rayConfig.outbounds.FirstOrDefault(t => t is { protocol: "freedom", tag: Global.DirectTag });
|
||||
if (outbound != null)
|
||||
{
|
||||
outbound.settings = new()
|
||||
{
|
||||
domainStrategy = domainStrategy4Freedom,
|
||||
userLevel = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
await GenDnsServers(node, v2rayConfig, simpleDNSItem);
|
||||
await GenDnsHosts(v2rayConfig, simpleDNSItem);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async Task<int> GenDnsServers(ProfileItem? node, V2rayConfig v2rayConfig, SimpleDNSItem simpleDNSItem)
|
||||
{
|
||||
static List<string> ParseDnsAddresses(string? dnsInput, string defaultAddress)
|
||||
{
|
||||
var addresses = dnsInput?.Split(dnsInput.Contains(',') ? ',' : ';')
|
||||
.Select(addr => addr.Trim())
|
||||
.Where(addr => !string.IsNullOrEmpty(addr))
|
||||
.Select(addr => addr.StartsWith("dhcp", StringComparison.OrdinalIgnoreCase) ? "localhost" : addr)
|
||||
.Distinct()
|
||||
.ToList() ?? new List<string> { defaultAddress };
|
||||
return addresses.Count > 0 ? addresses : new List<string> { defaultAddress };
|
||||
}
|
||||
|
||||
static object CreateDnsServer(string dnsAddress, List<string> domains, List<string>? expectedIPs = null)
|
||||
{
|
||||
var dnsServer = new DnsServer4Ray
|
||||
{
|
||||
address = dnsAddress,
|
||||
skipFallback = true,
|
||||
domains = domains.Count > 0 ? domains : null,
|
||||
expectedIPs = expectedIPs?.Count > 0 ? expectedIPs : null
|
||||
};
|
||||
return JsonUtils.SerializeToNode(dnsServer, new JsonSerializerOptions
|
||||
{
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
||||
});
|
||||
}
|
||||
|
||||
var directDNSAddress = ParseDnsAddresses(simpleDNSItem?.DirectDNS, Global.DomainDirectDNSAddress.FirstOrDefault());
|
||||
var remoteDNSAddress = ParseDnsAddresses(simpleDNSItem?.RemoteDNS, Global.DomainRemoteDNSAddress.FirstOrDefault());
|
||||
|
||||
var directDomainList = new List<string>();
|
||||
var directGeositeList = new List<string>();
|
||||
var proxyDomainList = new List<string>();
|
||||
var proxyGeositeList = new List<string>();
|
||||
var expectedDomainList = new List<string>();
|
||||
var expectedIPs = new List<string>();
|
||||
var regionNames = new HashSet<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(simpleDNSItem?.DirectExpectedIPs))
|
||||
{
|
||||
expectedIPs = simpleDNSItem.DirectExpectedIPs
|
||||
.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(s => s.Trim())
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToList();
|
||||
|
||||
foreach (var ip in expectedIPs)
|
||||
{
|
||||
if (ip.StartsWith("geoip:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var region = ip["geoip:".Length..];
|
||||
if (!string.IsNullOrEmpty(region))
|
||||
{
|
||||
regionNames.Add($"geosite:{region}");
|
||||
regionNames.Add($"geosite:geolocation-{region}");
|
||||
regionNames.Add($"geosite:tld-{region}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
||||
List<RulesItem>? rules = null;
|
||||
if (routing != null)
|
||||
{
|
||||
rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||
foreach (var item in rules)
|
||||
{
|
||||
if (!item.Enabled || item.Domain is null || item.Domain.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var domain in item.Domain)
|
||||
{
|
||||
if (domain.StartsWith('#'))
|
||||
continue;
|
||||
var normalizedDomain = domain.Replace(Global.RoutingRuleComma, ",");
|
||||
|
||||
if (item.OutboundTag == Global.DirectTag)
|
||||
{
|
||||
if (normalizedDomain.StartsWith("geosite:"))
|
||||
{
|
||||
(regionNames.Contains(normalizedDomain) ? expectedDomainList : directGeositeList).Add(normalizedDomain);
|
||||
}
|
||||
else
|
||||
{
|
||||
directDomainList.Add(normalizedDomain);
|
||||
}
|
||||
}
|
||||
else if (item.OutboundTag == Global.ProxyTag)
|
||||
{
|
||||
if (normalizedDomain.StartsWith("geosite:"))
|
||||
{
|
||||
proxyGeositeList.Add(normalizedDomain);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyDomainList.Add(normalizedDomain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils.IsDomain(node?.Address))
|
||||
{
|
||||
directDomainList.Add(node.Address);
|
||||
}
|
||||
|
||||
if (node?.Subid is not null)
|
||||
{
|
||||
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
|
||||
if (subItem is not null)
|
||||
{
|
||||
foreach (var profile in new[] { subItem.PrevProfile, subItem.NextProfile })
|
||||
{
|
||||
var profileNode = await AppHandler.Instance.GetProfileItemViaRemarks(profile);
|
||||
if (profileNode is not null &&
|
||||
profileNode.ConfigType is not (EConfigType.Custom or EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls) &&
|
||||
Utils.IsDomain(profileNode.Address))
|
||||
{
|
||||
directDomainList.Add(profileNode.Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v2rayConfig.dns ??= new Dns4Ray();
|
||||
v2rayConfig.dns.servers ??= new List<object>();
|
||||
|
||||
void AddDnsServers(List<string> dnsAddresses, List<string> domains, List<string>? expectedIPs = null)
|
||||
{
|
||||
if (domains.Count > 0)
|
||||
{
|
||||
foreach (var dnsAddress in dnsAddresses)
|
||||
{
|
||||
v2rayConfig.dns.servers.Add(CreateDnsServer(dnsAddress, domains, expectedIPs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddDnsServers(remoteDNSAddress, proxyDomainList);
|
||||
AddDnsServers(directDNSAddress, directDomainList);
|
||||
AddDnsServers(remoteDNSAddress, proxyGeositeList);
|
||||
AddDnsServers(directDNSAddress, directGeositeList);
|
||||
AddDnsServers(directDNSAddress, expectedDomainList, expectedIPs);
|
||||
|
||||
var useDirectDns = rules?.LastOrDefault() is { } lastRule &&
|
||||
lastRule.OutboundTag == Global.DirectTag &&
|
||||
(lastRule.Port == "0-65535" ||
|
||||
lastRule.Network == "tcp,udp" ||
|
||||
lastRule.Ip?.Contains("0.0.0.0/0") == true);
|
||||
|
||||
var defaultDnsServers = useDirectDns ? directDNSAddress : remoteDNSAddress;
|
||||
v2rayConfig.dns.servers.AddRange(defaultDnsServers);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async Task<int> GenDnsHosts(V2rayConfig v2rayConfig, SimpleDNSItem simpleDNSItem)
|
||||
{
|
||||
if (simpleDNSItem.AddCommonHosts == false && simpleDNSItem.UseSystemHosts == false && simpleDNSItem.Hosts.IsNullOrEmpty())
|
||||
{
|
||||
return await Task.FromResult(0);
|
||||
}
|
||||
v2rayConfig.dns ??= new Dns4Ray();
|
||||
v2rayConfig.dns.hosts ??= new Dictionary<string, List<string>>();
|
||||
if (simpleDNSItem.AddCommonHosts == true)
|
||||
{
|
||||
v2rayConfig.dns.hosts = Global.PredefinedHosts;
|
||||
}
|
||||
|
||||
if (simpleDNSItem.UseSystemHosts == true)
|
||||
{
|
||||
var systemHosts = Utils.GetSystemHosts();
|
||||
if (systemHosts.Count > 0)
|
||||
{
|
||||
var normalHost = v2rayConfig.dns.hosts;
|
||||
if (normalHost != null)
|
||||
{
|
||||
foreach (var host in systemHosts)
|
||||
{
|
||||
if (normalHost[host.Key] != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
normalHost[host.Key] = new List<string> { host.Value };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var userHostsMap = simpleDNSItem.Hosts?
|
||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line))
|
||||
.Where(line => line.Contains(' '))
|
||||
.ToDictionary(
|
||||
line =>
|
||||
{
|
||||
var parts = line.Trim().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
return parts[0];
|
||||
},
|
||||
line =>
|
||||
{
|
||||
var parts = line.Trim().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var values = parts.Skip(1).ToList();
|
||||
return values;
|
||||
}
|
||||
);
|
||||
|
||||
if (userHostsMap != null)
|
||||
{
|
||||
foreach (var kvp in userHostsMap)
|
||||
{
|
||||
v2rayConfig.dns.hosts[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
return await Task.FromResult(0);
|
||||
}
|
||||
|
||||
private async Task<int> GenDnsCompatible(ProfileItem? node, V2rayConfig v2rayConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1174,22 +1436,33 @@ public class CoreConfigV2rayService
|
||||
var systemHosts = Utils.GetSystemHosts();
|
||||
if (systemHosts.Count > 0)
|
||||
{
|
||||
var normalHost = obj["hosts"];
|
||||
if (normalHost != null)
|
||||
var normalHost1 = obj["hosts"];
|
||||
if (normalHost1 != null)
|
||||
{
|
||||
foreach (var host in systemHosts)
|
||||
{
|
||||
if (normalHost[host.Key] != null)
|
||||
if (normalHost1[host.Key] != null)
|
||||
continue;
|
||||
normalHost[host.Key] = host.Value;
|
||||
normalHost1[host.Key] = host.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var normalHost = obj["hosts"];
|
||||
if (normalHost != null)
|
||||
{
|
||||
foreach (var hostProp in normalHost.AsObject().ToList())
|
||||
{
|
||||
if (hostProp.Value is JsonValue value && value.TryGetValue<string>(out var ip))
|
||||
{
|
||||
normalHost[hostProp.Key] = new JsonArray(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await GenDnsDomains(node, obj, item);
|
||||
await GenDnsDomainsCompatible(node, obj, item);
|
||||
|
||||
v2rayConfig.dns = obj;
|
||||
v2rayConfig.dns = JsonUtils.Deserialize<Dns4Ray>(obj.ToJsonString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -1198,7 +1471,7 @@ public class CoreConfigV2rayService
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async Task<int> GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
|
||||
private async Task<int> GenDnsDomainsCompatible(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
@@ -1241,7 +1514,7 @@ public class CoreConfigV2rayService
|
||||
{
|
||||
var dnsServer = new DnsServer4Ray()
|
||||
{
|
||||
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
|
||||
address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
|
||||
skipFallback = true,
|
||||
domains = domainList
|
||||
};
|
||||
@@ -1349,7 +1622,8 @@ public class CoreConfigV2rayService
|
||||
if (prevNode is not null
|
||||
&& prevNode.ConfigType != EConfigType.Custom
|
||||
&& prevNode.ConfigType != EConfigType.Hysteria2
|
||||
&& prevNode.ConfigType != EConfigType.TUIC)
|
||||
&& prevNode.ConfigType != EConfigType.TUIC
|
||||
&& prevNode.ConfigType != EConfigType.Anytls)
|
||||
{
|
||||
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
||||
await GenOutbound(prevNode, prevOutbound);
|
||||
@@ -1424,7 +1698,8 @@ public class CoreConfigV2rayService
|
||||
if (prevNode is not null
|
||||
&& prevNode.ConfigType != EConfigType.Custom
|
||||
&& prevNode.ConfigType != EConfigType.Hysteria2
|
||||
&& prevNode.ConfigType != EConfigType.TUIC)
|
||||
&& prevNode.ConfigType != EConfigType.TUIC
|
||||
&& prevNode.ConfigType != EConfigType.Anytls)
|
||||
{
|
||||
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
||||
await GenOutbound(prevNode, prevOutbound);
|
||||
@@ -1493,7 +1768,8 @@ public class CoreConfigV2rayService
|
||||
if (nextNode is not null
|
||||
&& nextNode.ConfigType != EConfigType.Custom
|
||||
&& nextNode.ConfigType != EConfigType.Hysteria2
|
||||
&& nextNode.ConfigType != EConfigType.TUIC)
|
||||
&& nextNode.ConfigType != EConfigType.TUIC
|
||||
&& nextNode.ConfigType != EConfigType.Anytls)
|
||||
{
|
||||
if (nextOutbound == null)
|
||||
{
|
||||
|
||||
@@ -358,8 +358,8 @@ public class SpeedtestService
|
||||
private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
|
||||
{
|
||||
List<List<ServerTestItem>> lstTest = new();
|
||||
var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC)).ToList();
|
||||
var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC).ToList();
|
||||
var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls)).ToList();
|
||||
var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls).ToList();
|
||||
|
||||
for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++)
|
||||
{
|
||||
|
||||
@@ -536,6 +536,11 @@ public class UpdateService
|
||||
}
|
||||
}
|
||||
|
||||
//append dns items TODO
|
||||
geoSiteFiles.Add("cn");
|
||||
geoSiteFiles.Add("geolocation-cn");
|
||||
geoSiteFiles.Add("category-ads-all");
|
||||
|
||||
var path = Utils.GetBinPath("srss");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
|
||||
@@ -234,7 +234,7 @@ public class ClashProxiesViewModel : MyReactiveObject
|
||||
else
|
||||
{
|
||||
SelectedGroup = _proxyGroups.First();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -6,39 +6,52 @@ namespace ServiceLib.ViewModels;
|
||||
|
||||
public class DNSSettingViewModel : MyReactiveObject
|
||||
{
|
||||
[Reactive] public bool UseSystemHosts { get; set; }
|
||||
[Reactive] public string DomainStrategy4Freedom { get; set; }
|
||||
[Reactive] public string DomainDNSAddress { get; set; }
|
||||
[Reactive] public string NormalDNS { get; set; }
|
||||
[Reactive] public bool? UseSystemHosts { get; set; }
|
||||
[Reactive] public bool? AddCommonHosts { get; set; }
|
||||
[Reactive] public bool? FakeIP { get; set; }
|
||||
[Reactive] public bool? BlockBindingQuery { get; set; }
|
||||
[Reactive] public string? DirectDNS { get; set; }
|
||||
[Reactive] public string? RemoteDNS { get; set; }
|
||||
[Reactive] public string? SingboxOutboundsResolveDNS { get; set; }
|
||||
[Reactive] public string? SingboxFinalResolveDNS { get; set; }
|
||||
[Reactive] public string? RayStrategy4Freedom { get; set; }
|
||||
[Reactive] public string? SingboxStrategy4Direct { get; set; }
|
||||
[Reactive] public string? SingboxStrategy4Proxy { get; set; }
|
||||
[Reactive] public string? Hosts { get; set; }
|
||||
[Reactive] public string? DirectExpectedIPs { get; set; }
|
||||
|
||||
[Reactive] public string DomainStrategy4Freedom2 { get; set; }
|
||||
[Reactive] public string DomainDNSAddress2 { get; set; }
|
||||
[Reactive] public string NormalDNS2 { get; set; }
|
||||
[Reactive] public string TunDNS2 { get; set; }
|
||||
[Reactive] public bool UseSystemHostsCompatible { get; set; }
|
||||
[Reactive] public string DomainStrategy4FreedomCompatible { get; set; }
|
||||
[Reactive] public string DomainDNSAddressCompatible { get; set; }
|
||||
[Reactive] public string NormalDNSCompatible { get; set; }
|
||||
|
||||
[Reactive] public string DomainStrategy4Freedom2Compatible { get; set; }
|
||||
[Reactive] public string DomainDNSAddress2Compatible { get; set; }
|
||||
[Reactive] public string NormalDNS2Compatible { get; set; }
|
||||
[Reactive] public string TunDNS2Compatible { get; set; }
|
||||
[Reactive] public bool RayCustomDNSEnableCompatible { get; set; }
|
||||
[Reactive] public bool SBCustomDNSEnableCompatible { get; set; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCompatibleCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCompatibleCmd { get; }
|
||||
|
||||
public DNSSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SaveSettingAsync();
|
||||
});
|
||||
SaveCmd = ReactiveCommand.CreateFromTask(SaveSettingAsync);
|
||||
|
||||
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
ImportDefConfig4V2rayCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
NormalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
|
||||
NormalDNSCompatible = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
|
||||
await Task.CompletedTask;
|
||||
});
|
||||
|
||||
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
ImportDefConfig4SingboxCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
NormalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
||||
TunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||
NormalDNS2Compatible = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
||||
TunDNS2Compatible = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||
await Task.CompletedTask;
|
||||
});
|
||||
|
||||
@@ -47,48 +60,80 @@ public class DNSSettingViewModel : MyReactiveObject
|
||||
|
||||
private async Task Init()
|
||||
{
|
||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||
_config = AppHandler.Instance.Config;
|
||||
var item = _config.SimpleDNSItem;
|
||||
UseSystemHosts = item.UseSystemHosts;
|
||||
DomainStrategy4Freedom = item?.DomainStrategy4Freedom ?? string.Empty;
|
||||
DomainDNSAddress = item?.DomainDNSAddress ?? string.Empty;
|
||||
NormalDNS = item?.NormalDNS ?? string.Empty;
|
||||
AddCommonHosts = item.AddCommonHosts;
|
||||
FakeIP = item.FakeIP;
|
||||
BlockBindingQuery = item.BlockBindingQuery;
|
||||
DirectDNS = item.DirectDNS;
|
||||
RemoteDNS = item.RemoteDNS;
|
||||
RayStrategy4Freedom = item.RayStrategy4Freedom;
|
||||
SingboxOutboundsResolveDNS = item.SingboxOutboundsResolveDNS;
|
||||
SingboxFinalResolveDNS = item.SingboxFinalResolveDNS;
|
||||
SingboxStrategy4Direct = item.SingboxStrategy4Direct;
|
||||
SingboxStrategy4Proxy = item.SingboxStrategy4Proxy;
|
||||
Hosts = item.Hosts;
|
||||
DirectExpectedIPs = item.DirectExpectedIPs;
|
||||
|
||||
var item1 = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||
RayCustomDNSEnableCompatible = item1.Enabled;
|
||||
UseSystemHostsCompatible = item1.UseSystemHosts;
|
||||
DomainStrategy4FreedomCompatible = item1?.DomainStrategy4Freedom ?? string.Empty;
|
||||
DomainDNSAddressCompatible = item1?.DomainDNSAddress ?? string.Empty;
|
||||
NormalDNSCompatible = item1?.NormalDNS ?? string.Empty;
|
||||
|
||||
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
DomainStrategy4Freedom2 = item2?.DomainStrategy4Freedom ?? string.Empty;
|
||||
DomainDNSAddress2 = item2?.DomainDNSAddress ?? string.Empty;
|
||||
NormalDNS2 = item2?.NormalDNS ?? string.Empty;
|
||||
TunDNS2 = item2?.TunDNS ?? string.Empty;
|
||||
SBCustomDNSEnableCompatible = item2.Enabled;
|
||||
DomainStrategy4Freedom2Compatible = item2?.DomainStrategy4Freedom ?? string.Empty;
|
||||
DomainDNSAddress2Compatible = item2?.DomainDNSAddress ?? string.Empty;
|
||||
NormalDNS2Compatible = item2?.NormalDNS ?? string.Empty;
|
||||
TunDNS2Compatible = item2?.TunDNS ?? string.Empty;
|
||||
}
|
||||
|
||||
private async Task SaveSettingAsync()
|
||||
{
|
||||
if (NormalDNS.IsNotEmpty())
|
||||
_config.SimpleDNSItem.UseSystemHosts = UseSystemHosts;
|
||||
_config.SimpleDNSItem.AddCommonHosts = AddCommonHosts;
|
||||
_config.SimpleDNSItem.FakeIP = FakeIP;
|
||||
_config.SimpleDNSItem.BlockBindingQuery = BlockBindingQuery;
|
||||
_config.SimpleDNSItem.DirectDNS = DirectDNS;
|
||||
_config.SimpleDNSItem.RemoteDNS = RemoteDNS;
|
||||
_config.SimpleDNSItem.RayStrategy4Freedom = RayStrategy4Freedom;
|
||||
_config.SimpleDNSItem.SingboxOutboundsResolveDNS = SingboxOutboundsResolveDNS;
|
||||
_config.SimpleDNSItem.SingboxFinalResolveDNS = SingboxFinalResolveDNS;
|
||||
_config.SimpleDNSItem.SingboxStrategy4Direct = SingboxStrategy4Direct;
|
||||
_config.SimpleDNSItem.SingboxStrategy4Proxy = SingboxStrategy4Proxy;
|
||||
_config.SimpleDNSItem.Hosts = Hosts;
|
||||
_config.SimpleDNSItem.DirectExpectedIPs = DirectExpectedIPs;
|
||||
|
||||
if (NormalDNSCompatible.IsNotEmpty())
|
||||
{
|
||||
var obj = JsonUtils.ParseJson(NormalDNS);
|
||||
var obj = JsonUtils.ParseJson(NormalDNSCompatible);
|
||||
if (obj != null && obj["servers"] != null)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NormalDNS.Contains('{') || NormalDNS.Contains('}'))
|
||||
if (NormalDNSCompatible.Contains('{') || NormalDNSCompatible.Contains('}'))
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NormalDNS2.IsNotEmpty())
|
||||
if (NormalDNS2Compatible.IsNotEmpty())
|
||||
{
|
||||
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2);
|
||||
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2Compatible);
|
||||
if (obj2 == null)
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (TunDNS2.IsNotEmpty())
|
||||
if (TunDNS2Compatible.IsNotEmpty())
|
||||
{
|
||||
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(TunDNS2);
|
||||
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(TunDNS2Compatible);
|
||||
if (obj2 == null)
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText);
|
||||
@@ -96,21 +141,26 @@ public class DNSSettingViewModel : MyReactiveObject
|
||||
}
|
||||
}
|
||||
|
||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||
item.DomainStrategy4Freedom = DomainStrategy4Freedom;
|
||||
item.DomainDNSAddress = DomainDNSAddress;
|
||||
item.UseSystemHosts = UseSystemHosts;
|
||||
item.NormalDNS = NormalDNS;
|
||||
await ConfigHandler.SaveDNSItems(_config, item);
|
||||
var item1 = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||
item1.Enabled = RayCustomDNSEnableCompatible;
|
||||
item1.DomainStrategy4Freedom = DomainStrategy4FreedomCompatible;
|
||||
item1.DomainDNSAddress = DomainDNSAddressCompatible;
|
||||
item1.UseSystemHosts = UseSystemHostsCompatible;
|
||||
item1.NormalDNS = NormalDNSCompatible;
|
||||
await ConfigHandler.SaveDNSItems(_config, item1);
|
||||
|
||||
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2;
|
||||
item2.DomainDNSAddress = DomainDNSAddress2;
|
||||
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2));
|
||||
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2));
|
||||
item2.Enabled = RayCustomDNSEnableCompatible;
|
||||
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2Compatible;
|
||||
item2.DomainDNSAddress = DomainDNSAddress2Compatible;
|
||||
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2Compatible));
|
||||
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2Compatible));
|
||||
await ConfigHandler.SaveDNSItems(_config, item2);
|
||||
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||
_ = _updateView?.Invoke(EViewAction.CloseWindow, null);
|
||||
await ConfigHandler.SaveConfig(_config);
|
||||
if (_updateView != null)
|
||||
{
|
||||
await _updateView(EViewAction.CloseWindow, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddAnytlsServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
|
||||
@@ -111,6 +112,10 @@ public class MainWindowViewModel : MyReactiveObject
|
||||
{
|
||||
await AddServerAsync(true, EConfigType.WireGuard);
|
||||
});
|
||||
AddAnytlsServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerAsync(true, EConfigType.Anytls);
|
||||
});
|
||||
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerAsync(true, EConfigType.Custom);
|
||||
|
||||
@@ -436,30 +436,34 @@ public class StatusBarViewModel : MyReactiveObject
|
||||
|
||||
private async Task DoEnableTun(bool c)
|
||||
{
|
||||
if (_config.TunModeItem.EnableTun != EnableTun)
|
||||
if (_config.TunModeItem.EnableTun == EnableTun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_config.TunModeItem.EnableTun = EnableTun;
|
||||
|
||||
if (EnableTun && AllowEnableTun() == false)
|
||||
{
|
||||
_config.TunModeItem.EnableTun = EnableTun;
|
||||
// When running as a non-administrator, reboot to administrator mode
|
||||
if (EnableTun && AllowEnableTun() == false)
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
if (Utils.IsWindows())
|
||||
_config.TunModeItem.EnableTun = false;
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool? passwordResult = await _updateView?.Invoke(EViewAction.PasswordInput, null);
|
||||
if (passwordResult == false)
|
||||
{
|
||||
_config.TunModeItem.EnableTun = false;
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await _updateView?.Invoke(EViewAction.PasswordInput, null) == false)
|
||||
{
|
||||
_config.TunModeItem.EnableTun = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
await ConfigHandler.SaveConfig(_config);
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
||||
}
|
||||
await ConfigHandler.SaveConfig(_config);
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
||||
}
|
||||
|
||||
private bool AllowEnableTun()
|
||||
|
||||
@@ -61,11 +61,7 @@ internal class Program
|
||||
//.WithInterFont()
|
||||
.WithFontByDefault()
|
||||
.LogToTrace()
|
||||
#if OS_OSX
|
||||
.UseReactiveUI()
|
||||
.With(new MacOSPlatformOptions { ShowInDock = AppHandler.Instance.Config.UiItem.MacOSShowInDock });
|
||||
#else
|
||||
.UseReactiveUI();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ public class ThemeSettingViewModel : MyReactiveObject
|
||||
x.OfType<Button>(),
|
||||
x.OfType<TextBox>(),
|
||||
x.OfType<TextBlock>(),
|
||||
x.OfType<SelectableTextBlock>(),
|
||||
x.OfType<Menu>(),
|
||||
x.OfType<ContextMenu>(),
|
||||
x.OfType<DataGridRow>(),
|
||||
@@ -146,6 +147,7 @@ public class ThemeSettingViewModel : MyReactiveObject
|
||||
x.OfType<Button>(),
|
||||
x.OfType<TextBox>(),
|
||||
x.OfType<TextBlock>(),
|
||||
x.OfType<SelectableTextBlock>(),
|
||||
x.OfType<Menu>(),
|
||||
x.OfType<ContextMenu>(),
|
||||
x.OfType<DataGridRow>(),
|
||||
|
||||
@@ -21,13 +21,7 @@ public partial class AddServer2Window : WindowBase<AddServer2ViewModel>
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
|
||||
|
||||
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
|
||||
{
|
||||
if (it == ECoreType.v2rayN)
|
||||
continue;
|
||||
cmbCoreType.Items.Add(it.ToString());
|
||||
}
|
||||
cmbCoreType.Items.Add(string.Empty);
|
||||
cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -533,6 +533,26 @@
|
||||
HorizontalAlignment="Left"
|
||||
Watermark="1500" />
|
||||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridAnytls"
|
||||
Grid.Row="2"
|
||||
ColumnDefinitions="180,Auto"
|
||||
IsVisible="False"
|
||||
RowDefinitions="Auto,Auto,Auto">
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
<TextBox
|
||||
x:Name="txtId10"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
</Grid>
|
||||
|
||||
<Separator
|
||||
x:Name="sepa2"
|
||||
@@ -753,7 +773,7 @@
|
||||
Grid.Row="7"
|
||||
ColumnDefinitions="180,Auto"
|
||||
IsVisible="False"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto">
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
@@ -823,6 +843,20 @@
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbMldsa65Verify}" />
|
||||
<TextBox
|
||||
x:Name="txtMldsa65Verify"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</Grid>
|
||||
<Separator Grid.Row="8" Margin="{StaticResource MarginTb8}" />
|
||||
</Grid>
|
||||
|
||||
@@ -26,41 +26,22 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
|
||||
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
|
||||
|
||||
Global.CoreTypes.ForEach(it =>
|
||||
{
|
||||
cmbCoreType.Items.Add(it);
|
||||
});
|
||||
cmbCoreType.Items.Add(string.Empty);
|
||||
cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
|
||||
cmbNetwork.ItemsSource = Global.Networks;
|
||||
cmbFingerprint.ItemsSource = Global.Fingerprints;
|
||||
cmbFingerprint2.ItemsSource = Global.Fingerprints;
|
||||
cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
|
||||
cmbAlpn.ItemsSource = Global.Alpns;
|
||||
|
||||
cmbStreamSecurity.Items.Add(string.Empty);
|
||||
cmbStreamSecurity.Items.Add(Global.StreamSecurity);
|
||||
|
||||
Global.Networks.ForEach(it =>
|
||||
{
|
||||
cmbNetwork.Items.Add(it);
|
||||
});
|
||||
Global.Fingerprints.ForEach(it =>
|
||||
{
|
||||
cmbFingerprint.Items.Add(it);
|
||||
cmbFingerprint2.Items.Add(it);
|
||||
});
|
||||
Global.AllowInsecure.ForEach(it =>
|
||||
{
|
||||
cmbAllowInsecure.Items.Add(it);
|
||||
});
|
||||
Global.Alpns.ForEach(it =>
|
||||
{
|
||||
cmbAlpn.Items.Add(it);
|
||||
});
|
||||
var lstStreamSecurity = new List<string>();
|
||||
lstStreamSecurity.Add(string.Empty);
|
||||
lstStreamSecurity.Add(Global.StreamSecurity);
|
||||
|
||||
switch (profileItem.ConfigType)
|
||||
{
|
||||
case EConfigType.VMess:
|
||||
gridVMess.IsVisible = true;
|
||||
Global.VmessSecurities.ForEach(it =>
|
||||
{
|
||||
cmbSecurity.Items.Add(it);
|
||||
});
|
||||
cmbSecurity.ItemsSource = Global.VmessSecurities;
|
||||
if (profileItem.Security.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.Security = Global.DefaultSecurity;
|
||||
@@ -69,10 +50,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
|
||||
case EConfigType.Shadowsocks:
|
||||
gridSs.IsVisible = true;
|
||||
AppHandler.Instance.GetShadowsocksSecurities(profileItem).ForEach(it =>
|
||||
{
|
||||
cmbSecurity3.Items.Add(it);
|
||||
});
|
||||
cmbSecurity3.ItemsSource = AppHandler.Instance.GetShadowsocksSecurities(profileItem);
|
||||
break;
|
||||
|
||||
case EConfigType.SOCKS:
|
||||
@@ -82,11 +60,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
|
||||
case EConfigType.VLESS:
|
||||
gridVLESS.IsVisible = true;
|
||||
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
|
||||
Global.Flows.ForEach(it =>
|
||||
{
|
||||
cmbFlow5.Items.Add(it);
|
||||
});
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbFlow5.ItemsSource = Global.Flows;
|
||||
if (profileItem.Security.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.Security = Global.None;
|
||||
@@ -95,11 +70,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
|
||||
case EConfigType.Trojan:
|
||||
gridTrojan.IsVisible = true;
|
||||
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
|
||||
Global.Flows.ForEach(it =>
|
||||
{
|
||||
cmbFlow6.Items.Add(it);
|
||||
});
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbFlow6.ItemsSource = Global.Flows;
|
||||
break;
|
||||
|
||||
case EConfigType.Hysteria2:
|
||||
@@ -119,10 +91,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
cmbFingerprint.IsEnabled = false;
|
||||
cmbFingerprint.SelectedValue = string.Empty;
|
||||
|
||||
Global.TuicCongestionControls.ForEach(it =>
|
||||
{
|
||||
cmbHeaderType8.Items.Add(it);
|
||||
});
|
||||
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
@@ -133,7 +102,14 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
gridTls.IsVisible = false;
|
||||
|
||||
break;
|
||||
|
||||
case EConfigType.Anytls:
|
||||
gridAnytls.IsVisible = true;
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbCoreType.IsEnabled = false;
|
||||
break;
|
||||
}
|
||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||
|
||||
gridTlsMore.IsVisible = false;
|
||||
|
||||
@@ -197,6 +173,10 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EConfigType.Anytls:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId10.Text).DisposeWith(disposables);
|
||||
break;
|
||||
}
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);
|
||||
@@ -215,6 +195,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.PublicKey, v => v.txtPublicKey.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.SpiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Mldsa65Verify, v => v.txtMldsa65Verify.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
});
|
||||
@@ -272,44 +253,41 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
|
||||
private void SetHeaderType()
|
||||
{
|
||||
cmbHeaderType.Items.Clear();
|
||||
var lstHeaderType = new List<string>();
|
||||
|
||||
var network = cmbNetwork.SelectedItem.ToString();
|
||||
if (network.IsNullOrEmpty())
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
lstHeaderType.Add(Global.None);
|
||||
cmbHeaderType.ItemsSource = lstHeaderType;
|
||||
cmbHeaderType.SelectedIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (network == nameof(ETransport.tcp))
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
cmbHeaderType.Items.Add(Global.TcpHeaderHttp);
|
||||
lstHeaderType.Add(Global.None);
|
||||
lstHeaderType.Add(Global.TcpHeaderHttp);
|
||||
}
|
||||
else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic))
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
Global.KcpHeaderTypes.ForEach(it =>
|
||||
{
|
||||
cmbHeaderType.Items.Add(it);
|
||||
});
|
||||
lstHeaderType.Add(Global.None);
|
||||
lstHeaderType.AddRange(Global.KcpHeaderTypes);
|
||||
}
|
||||
else if (network is nameof(ETransport.xhttp))
|
||||
{
|
||||
Global.XhttpMode.ForEach(it =>
|
||||
{
|
||||
cmbHeaderType.Items.Add(it);
|
||||
});
|
||||
lstHeaderType.AddRange(Global.XhttpMode);
|
||||
}
|
||||
else if (network == nameof(ETransport.grpc))
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.GrpcGunMode);
|
||||
cmbHeaderType.Items.Add(Global.GrpcMultiMode);
|
||||
lstHeaderType.Add(Global.GrpcGunMode);
|
||||
lstHeaderType.Add(Global.GrpcMultiMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
lstHeaderType.Add(Global.None);
|
||||
}
|
||||
cmbHeaderType.ItemsSource = lstHeaderType;
|
||||
cmbHeaderType.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
x:Class="v2rayN.Desktop.Views.DNSSettingWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:ctrls="clr-namespace:v2rayN.Desktop.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
@@ -35,25 +36,299 @@
|
||||
</StackPanel>
|
||||
|
||||
<TabControl HorizontalContentAlignment="Stretch">
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TabItem Header="{x:Static resx:ResUI.ThBasicDNSSettings}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||
<Grid
|
||||
Margin="{StaticResource 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.TbSettingsRemoteDNS}" />
|
||||
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
|
||||
|
||||
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
|
||||
<HyperlinkButton Classes="WithIcon" Click="linkDnsObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" />
|
||||
</HyperlinkButton>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4V2ray"
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand" />
|
||||
</StackPanel>
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbDomesticDNS}" />
|
||||
<ctrls:AutoCompleteBox
|
||||
x:Name="cmbDirectDNS"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Text="{Binding DirectDNS, Mode=TwoWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbRemoteDNS}" />
|
||||
<ctrls:AutoCompleteBox
|
||||
x:Name="cmbRemoteDNS"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Text="{Binding RemoteDNS, Mode=TwoWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBOutboundsResolverDNS}" />
|
||||
<ctrls:AutoCompleteBox
|
||||
x:Name="cmbSBResolverDNS"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Text="{Binding SingboxOutboundsResolveDNS, Mode=TwoWay}" />
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBOutboundDomainResolve}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBDoHResolverServer}" />
|
||||
<ctrls:AutoCompleteBox
|
||||
x:Name="cmbSBFinalResolverDNS"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Text="{Binding SingboxFinalResolveDNS, Mode=TwoWay}" />
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBFallbackDNSResolve}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbXrayFreedomResolveStrategy}" />
|
||||
<ComboBox
|
||||
x:Name="cmbRayFreedomDNSStrategy"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
PlaceholderText="Default" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBDirectResolveStrategy}" />
|
||||
<ComboBox
|
||||
x:Name="cmbSBDirectDNSStrategy"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
PlaceholderText="Default" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBRemoteResolveStrategy}" />
|
||||
<ComboBox
|
||||
x:Name="cmbSBRemoteDNSStrategy"
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
PlaceholderText="Default" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="8"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbAddCommonDNSHosts}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togAddCommonHosts"
|
||||
Grid.Row="8"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
<TextBlock
|
||||
Grid.Row="8"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSBDoHOverride}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="{x:Static resx:ResUI.ThAdvancedDNSSettings}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||
<Grid
|
||||
Margin="{StaticResource 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}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<Grid DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togRayCustomDNSEnableCompatible"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsRemoteDNS}" />
|
||||
|
||||
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
|
||||
<HyperlinkButton Classes="WithIcon" Click="linkDnsObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" />
|
||||
</HyperlinkButton>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4V2rayCompatible"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@@ -62,7 +337,7 @@
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togUseSystemHosts"
|
||||
x:Name="togUseSystemHostsCompatible"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
@@ -73,7 +348,7 @@
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Freedom"
|
||||
x:Name="cmbdomainStrategy4FreedomCompatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
</StackPanel>
|
||||
@@ -83,10 +358,11 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainDNSAddress"
|
||||
<ctrls:AutoCompleteBox
|
||||
x:Name="cmbdomainDNSAddressCompatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
Margin="{StaticResource Margin4}"
|
||||
Text="{Binding DomainDNSAddressCompatible, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</WrapPanel>
|
||||
|
||||
@@ -96,7 +372,7 @@
|
||||
BorderThickness="1"
|
||||
Header="HTTP/SOCKS">
|
||||
<TextBox
|
||||
Name="txtnormalDNS"
|
||||
Name="txtnormalDNSCompatible"
|
||||
VerticalAlignment="Stretch"
|
||||
Classes="TextArea"
|
||||
MinLines="10"
|
||||
@@ -107,18 +383,36 @@
|
||||
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
|
||||
<HyperlinkButton Classes="WithIcon" Click="linkDnsSingboxObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
||||
</HyperlinkButton>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4Singbox"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand" />
|
||||
</StackPanel>
|
||||
<Grid DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togSBCustomDNSEnableCompatible"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock Margin="{StaticResource Margin4}" VerticalAlignment="Center">
|
||||
<HyperlinkButton Classes="WithIcon" Click="linkDnsSingboxObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
||||
</HyperlinkButton>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4SingboxCompatible"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@@ -127,7 +421,7 @@
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Out"
|
||||
x:Name="cmbdomainStrategy4OutCompatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
</StackPanel>
|
||||
@@ -137,10 +431,11 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainDNSAddress2"
|
||||
<ctrls:AutoCompleteBox
|
||||
x:Name="cmbdomainDNSAddress2Compatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
Margin="{StaticResource Margin4}"
|
||||
Text="{Binding DomainDNSAddress2Compatible, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</WrapPanel>
|
||||
|
||||
@@ -152,7 +447,7 @@
|
||||
BorderThickness="1"
|
||||
Header="HTTP/SOCKS">
|
||||
<TextBox
|
||||
Name="txtnormalDNS2"
|
||||
Name="txtnormalDNS2Compatible"
|
||||
VerticalAlignment="Stretch"
|
||||
Classes="TextArea"
|
||||
MinLines="10"
|
||||
@@ -167,7 +462,7 @@
|
||||
BorderThickness="1"
|
||||
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
|
||||
<TextBox
|
||||
Name="txttunDNS2"
|
||||
Name="txttunDNS2Compatible"
|
||||
VerticalAlignment="Stretch"
|
||||
Classes="TextArea"
|
||||
MinLines="10"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Reactive.Disposables;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using ReactiveUI;
|
||||
using v2rayN.Desktop.Base;
|
||||
@@ -17,38 +18,64 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||
|
||||
Global.DomainStrategy4Freedoms.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Freedom.Items.Add(it);
|
||||
});
|
||||
Global.SingboxDomainStrategy4Out.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Out.Items.Add(it);
|
||||
});
|
||||
Global.DomainDNSAddress.ForEach(it =>
|
||||
{
|
||||
cmbdomainDNSAddress.Items.Add(it);
|
||||
});
|
||||
Global.SingboxDomainDNSAddress.ForEach(it =>
|
||||
{
|
||||
cmbdomainDNSAddress2.Items.Add(it);
|
||||
});
|
||||
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||
cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress;
|
||||
cmbSBResolverDNS.ItemsSource = Global.DomainDirectDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
|
||||
cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress;
|
||||
cmbSBFinalResolverDNS.ItemsSource = Global.DomainPureIPDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
|
||||
cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs;
|
||||
|
||||
cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||
cmbdomainStrategy4OutCompatible.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||
cmbdomainDNSAddressCompatible.ItemsSource = Global.DomainPureIPDNSAddress;
|
||||
cmbdomainDNSAddress2Compatible.ItemsSource = Global.DomainPureIPDNSAddress;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.AddCommonHosts, v => v.togAddCommonHosts.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.FakeIP, v => v.togFakeIP.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.SelectedItem).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.SelectedItem).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.SelectedItem).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.Hosts, v => v.txtHosts.Text).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.DirectExpectedIPs, v => v.cmbDirectExpectedIPs.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.RayCustomDNSEnableCompatible, v => v.togRayCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SBCustomDNSEnableCompatible, v => v.togSBCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.UseSystemHostsCompatible, v => v.togUseSystemHostsCompatible.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4FreedomCompatible, v => v.cmbdomainStrategy4FreedomCompatible.SelectedItem).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.DomainDNSAddressCompatible, v => v.cmbdomainDNSAddressCompatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNSCompatible, v => v.txtnormalDNSCompatible.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2Compatible, v => v.cmbdomainStrategy4OutCompatible.SelectedItem).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.DomainDNSAddress2Compatible, v => v.cmbdomainDNSAddress2Compatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNS2Compatible, v => v.txtnormalDNS2Compatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDNS2Compatible, v => v.txttunDNS2Compatible.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables);
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.ViewModel.RayCustomDNSEnableCompatible,
|
||||
x => x.ViewModel.SBCustomDNSEnableCompatible,
|
||||
(ray, sb) => ray && sb
|
||||
).BindTo(this.FindControl<TextBlock>("txtBasicDNSSettingsInvalid"), t => t.IsVisible);
|
||||
this.WhenAnyValue(
|
||||
x => x.ViewModel.RayCustomDNSEnableCompatible,
|
||||
x => x.ViewModel.SBCustomDNSEnableCompatible,
|
||||
(ray, sb) => ray && sb
|
||||
).BindTo(this.FindControl<TextBlock>("txtAdvancedDNSSettingsInvalid"), t => t.IsVisible);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<Separator />
|
||||
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
||||
<MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
||||
<MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem Padding="8,0">
|
||||
|
||||
@@ -83,6 +83,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);
|
||||
@@ -134,7 +135,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
|
||||
@@ -69,34 +69,36 @@
|
||||
IsChecked="True"
|
||||
Theme="{DynamicResource SimpleToggleSwitch}" />
|
||||
</WrapPanel>
|
||||
<TextBox
|
||||
Name="txtMsg"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderThickness="0"
|
||||
Classes="TextArea"
|
||||
IsReadOnly="True"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap">
|
||||
<TextBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewSelectAll"
|
||||
Click="menuMsgViewSelectAll_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewSelectAll}" />
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewCopy"
|
||||
Click="menuMsgViewCopy_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewCopy}" />
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewCopyAll"
|
||||
Click="menuMsgViewCopyAll_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewCopyAll}" />
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewClear"
|
||||
Click="menuMsgViewClear_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewClear}" />
|
||||
</ContextMenu>
|
||||
</TextBox.ContextMenu>
|
||||
</TextBox>
|
||||
|
||||
<ScrollViewer x:Name="msgScrollViewer" VerticalScrollBarVisibility="Auto">
|
||||
<SelectableTextBlock
|
||||
Name="txtMsg"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Stretch"
|
||||
Classes="TextArea"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap">
|
||||
<SelectableTextBlock.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewSelectAll"
|
||||
Click="menuMsgViewSelectAll_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewSelectAll}" />
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewCopy"
|
||||
Click="menuMsgViewCopy_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewCopy}" />
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewCopyAll"
|
||||
Click="menuMsgViewCopyAll_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewCopyAll}" />
|
||||
<MenuItem
|
||||
x:Name="menuMsgViewClear"
|
||||
Click="menuMsgViewClear_Click"
|
||||
Header="{x:Static resx:ResUI.menuMsgViewClear}" />
|
||||
</ContextMenu>
|
||||
</SelectableTextBlock.ContextMenu>
|
||||
</SelectableTextBlock>
|
||||
</ScrollViewer>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Reactive.Disposables;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
@@ -9,9 +10,12 @@ namespace v2rayN.Desktop.Views;
|
||||
|
||||
public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
||||
{
|
||||
private readonly ScrollViewer _scrollViewer;
|
||||
|
||||
public MsgView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_scrollViewer = this.FindControl<ScrollViewer>("msgScrollViewer");
|
||||
|
||||
ViewModel = new MsgViewModel(UpdateViewHandler);
|
||||
|
||||
@@ -43,14 +47,14 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
||||
txtMsg.Text = msg.ToString();
|
||||
if (togScrollToEnd.IsChecked ?? true)
|
||||
{
|
||||
txtMsg.CaretIndex = int.MaxValue;
|
||||
_scrollViewer?.ScrollToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearMsg()
|
||||
{
|
||||
ViewModel?.ClearMsg();
|
||||
txtMsg.Clear();
|
||||
txtMsg.Text = "";
|
||||
}
|
||||
|
||||
private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e)
|
||||
|
||||
@@ -19,87 +19,39 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||
|
||||
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
|
||||
Global.destOverrideProtocols.ForEach(it =>
|
||||
{
|
||||
clbdestOverride.Items.Add(it);
|
||||
});
|
||||
clbdestOverride.ItemsSource = Global.destOverrideProtocols;
|
||||
_config.Inbound.First().DestOverride?.ForEach(it =>
|
||||
{
|
||||
clbdestOverride.SelectedItems.Add(it);
|
||||
});
|
||||
Global.IEProxyProtocols.ForEach(it =>
|
||||
{
|
||||
cmbsystemProxyAdvancedProtocol.Items.Add(it);
|
||||
});
|
||||
Global.LogLevels.ForEach(it =>
|
||||
{
|
||||
cmbloglevel.Items.Add(it);
|
||||
});
|
||||
Global.Fingerprints.ForEach(it =>
|
||||
{
|
||||
cmbdefFingerprint.Items.Add(it);
|
||||
});
|
||||
Global.UserAgent.ForEach(it =>
|
||||
{
|
||||
cmbdefUserAgent.Items.Add(it);
|
||||
});
|
||||
Global.SingboxMuxs.ForEach(it =>
|
||||
{
|
||||
cmbmux4SboxProtocol.Items.Add(it);
|
||||
});
|
||||
|
||||
Global.TunMtus.ForEach(it =>
|
||||
{
|
||||
cmbMtu.Items.Add(it);
|
||||
});
|
||||
Global.TunStacks.ForEach(it =>
|
||||
{
|
||||
cmbStack.Items.Add(it);
|
||||
});
|
||||
Global.CoreTypes.ForEach(it =>
|
||||
{
|
||||
cmbCoreType1.Items.Add(it);
|
||||
cmbCoreType2.Items.Add(it);
|
||||
cmbCoreType3.Items.Add(it);
|
||||
cmbCoreType4.Items.Add(it);
|
||||
cmbCoreType5.Items.Add(it);
|
||||
cmbCoreType6.Items.Add(it);
|
||||
cmbCoreType9.Items.Add(it);
|
||||
});
|
||||
cmbsystemProxyAdvancedProtocol.ItemsSource = Global.IEProxyProtocols;
|
||||
cmbloglevel.ItemsSource = Global.LogLevels;
|
||||
cmbdefFingerprint.ItemsSource = Global.Fingerprints;
|
||||
cmbdefUserAgent.ItemsSource = Global.UserAgent;
|
||||
cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
|
||||
cmbMtu.ItemsSource = Global.TunMtus;
|
||||
cmbStack.ItemsSource = Global.TunStacks;
|
||||
|
||||
for (var i = 2; i <= 8; i++)
|
||||
{
|
||||
cmbMixedConcurrencyCount.Items.Add(i);
|
||||
}
|
||||
for (var i = 2; i <= 6; i++)
|
||||
{
|
||||
cmbSpeedTestTimeout.Items.Add(i * 5);
|
||||
}
|
||||
cmbCoreType1.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType2.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType3.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType4.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType5.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType6.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType9.ItemsSource = Global.CoreTypes;
|
||||
|
||||
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList();
|
||||
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
|
||||
cmbSpeedTestUrl.ItemsSource = Global.SpeedTestUrls;
|
||||
cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls;
|
||||
cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls;
|
||||
cmbGetFilesSourceUrl.ItemsSource = Global.GeoFilesSources;
|
||||
cmbSrsFilesSourceUrl.ItemsSource = Global.SingboxRulesetSources;
|
||||
cmbRoutingRulesSourceUrl.ItemsSource = Global.RoutingRulesSources;
|
||||
cmbIPAPIUrl.ItemsSource = Global.IPAPIUrls;
|
||||
|
||||
Global.GeoFilesSources.ForEach(it =>
|
||||
{
|
||||
cmbGetFilesSourceUrl.Items.Add(it);
|
||||
});
|
||||
Global.SingboxRulesetSources.ForEach(it =>
|
||||
{
|
||||
cmbSrsFilesSourceUrl.Items.Add(it);
|
||||
});
|
||||
Global.RoutingRulesSources.ForEach(it =>
|
||||
{
|
||||
cmbRoutingRulesSourceUrl.Items.Add(it);
|
||||
});
|
||||
Global.IPAPIUrls.ForEach(it =>
|
||||
{
|
||||
cmbIPAPIUrl.Items.Add(it);
|
||||
});
|
||||
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
|
||||
{
|
||||
cmbMainGirdOrientation.Items.Add(it.ToString());
|
||||
}
|
||||
cmbMainGirdOrientation.ItemsSource = Utils.GetEnumNames<EGirdOrientation>();
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -23,19 +23,11 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
|
||||
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
|
||||
|
||||
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
|
||||
cmbOutboundTag.ItemsSource = new List<string> { Global.ProxyTag, Global.DirectTag, Global.BlockTag };
|
||||
Global.RuleProtocols.ForEach(it =>
|
||||
{
|
||||
clbProtocol.Items.Add(it);
|
||||
});
|
||||
Global.InboundTags.ForEach(it =>
|
||||
{
|
||||
clbInboundTag.Items.Add(it);
|
||||
});
|
||||
Global.RuleNetworks.ForEach(it =>
|
||||
{
|
||||
cmbNetwork.Items.Add(it);
|
||||
});
|
||||
|
||||
cmbOutboundTag.ItemsSource = Global.OutboundTags;
|
||||
clbProtocol.ItemsSource = Global.RuleProtocols;
|
||||
clbInboundTag.ItemsSource = Global.InboundTags;
|
||||
cmbNetwork.ItemsSource = Global.RuleNetworks;
|
||||
|
||||
if (!rulesItem.Id.IsNullOrEmpty())
|
||||
{
|
||||
|
||||
@@ -30,15 +30,9 @@ public partial class RoutingRuleSettingWindow : WindowBase<RoutingRuleSettingVie
|
||||
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync;
|
||||
|
||||
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
|
||||
Global.DomainStrategies.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy.Items.Add(it);
|
||||
});
|
||||
cmbdomainStrategy.Items.Add(string.Empty);
|
||||
Global.DomainStrategies4Singbox.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Singbox.Items.Add(it);
|
||||
});
|
||||
|
||||
cmbdomainStrategy.ItemsSource = Global.DomainStrategies.AppendEmpty();
|
||||
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -26,18 +26,9 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||
|
||||
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
|
||||
|
||||
Global.DomainStrategies.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy.Items.Add(it);
|
||||
});
|
||||
Global.DomainMatchers.ForEach(it =>
|
||||
{
|
||||
cmbdomainMatcher.Items.Add(it);
|
||||
});
|
||||
Global.DomainStrategies4Singbox.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Singbox.Items.Add(it);
|
||||
});
|
||||
cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
|
||||
cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
|
||||
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
@@ -126,7 +117,7 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||
|
||||
private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
||||
|
||||
@@ -104,13 +104,15 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
|
||||
{
|
||||
var dialog = new SudoPasswordInputView();
|
||||
var obj = await DialogHost.Show(dialog);
|
||||
if (obj == null)
|
||||
|
||||
var password = obj?.ToString();
|
||||
if (password.IsNullOrEmpty())
|
||||
{
|
||||
togEnableTun.IsChecked = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
AppHandler.Instance.LinuxSudoPwd = obj.ToString() ?? string.Empty;
|
||||
AppHandler.Instance.LinuxSudoPwd = password;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,7 @@ public partial class SubEditWindow : WindowBase<SubEditViewModel>
|
||||
|
||||
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
|
||||
|
||||
Global.SubConvertTargets.ForEach(it =>
|
||||
{
|
||||
cmbConvertTarget.Items.Add(it);
|
||||
});
|
||||
cmbConvertTarget.ItemsSource = Global.SubConvertTargets;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Threading;
|
||||
using CliWrap.Buffered;
|
||||
using DialogHostAvalonia;
|
||||
|
||||
namespace v2rayN.Desktop.Views;
|
||||
@@ -12,22 +13,70 @@ public partial class SudoPasswordInputView : UserControl
|
||||
|
||||
this.Loaded += (s, e) => txtPassword.Focus();
|
||||
|
||||
btnSave.Click += (_, _) =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(txtPassword.Text))
|
||||
{
|
||||
txtPassword.Focus();
|
||||
return;
|
||||
}
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
DialogHost.Close(null, txtPassword.Text);
|
||||
});
|
||||
};
|
||||
btnSave.Click += async (_, _) => await SavePasswordAsync();
|
||||
|
||||
btnCancel.Click += (_, _) =>
|
||||
{
|
||||
DialogHost.Close(null);
|
||||
};
|
||||
}
|
||||
|
||||
private async Task SavePasswordAsync()
|
||||
{
|
||||
if (txtPassword.Text.IsNullOrEmpty())
|
||||
{
|
||||
txtPassword.Focus();
|
||||
return;
|
||||
}
|
||||
|
||||
var password = txtPassword.Text;
|
||||
btnSave.IsEnabled = false;
|
||||
|
||||
try
|
||||
{
|
||||
// Verify if the password is correct
|
||||
if (await CheckSudoPasswordAsync(password))
|
||||
{
|
||||
// Password verification successful, return password and close dialog
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
DialogHost.Close(null, password);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Password verification failed, display error and let user try again
|
||||
NoticeHandler.Instance.Enqueue(ResUI.SudoIncorrectPasswordTip);
|
||||
txtPassword.Focus();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog("SudoPassword", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
btnSave.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CheckSudoPasswordAsync(string password)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use sudo echo command to verify password
|
||||
var arg = new List<string>() { "-c", "sudo -S echo SUDO_CHECK" };
|
||||
var result = await CliWrap.Cli.Wrap(Global.LinuxBash)
|
||||
.WithArguments(arg)
|
||||
.WithStandardInputPipe(CliWrap.PipeSource.FromString(password))
|
||||
.ExecuteBufferedAsync();
|
||||
|
||||
return result.ExitCode == 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog("CheckSudoPassword", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,20 +16,9 @@ public partial class ThemeSettingView : ReactiveUserControl<ThemeSettingViewMode
|
||||
InitializeComponent();
|
||||
ViewModel = new ThemeSettingViewModel();
|
||||
|
||||
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
|
||||
{
|
||||
cmbCurrentTheme.Items.Add(it.ToString());
|
||||
}
|
||||
|
||||
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
|
||||
{
|
||||
cmbCurrentFontSize.Items.Add(i);
|
||||
}
|
||||
|
||||
Global.Languages.ForEach(it =>
|
||||
{
|
||||
cmbCurrentLanguage.Items.Add(it);
|
||||
});
|
||||
cmbCurrentTheme.ItemsSource = Utils.GetEnumNames<ETheme>();
|
||||
cmbCurrentFontSize.ItemsSource = Enumerable.Range(Global.MinFontSize, 11).ToList();
|
||||
cmbCurrentLanguage.ItemsSource = Global.Languages;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -14,13 +14,7 @@ public partial class AddServer2Window
|
||||
this.Loaded += Window_Loaded;
|
||||
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
|
||||
|
||||
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
|
||||
{
|
||||
if (it == ECoreType.v2rayN)
|
||||
continue;
|
||||
cmbCoreType.Items.Add(it.ToString());
|
||||
}
|
||||
cmbCoreType.Items.Add(string.Empty);
|
||||
cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -707,6 +707,35 @@
|
||||
materialDesign:HintAssist.Hint="1500"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridAnytls"
|
||||
Grid.Row="2"
|
||||
Visibility="Hidden">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
<TextBox
|
||||
x:Name="txtId10"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
|
||||
<Separator
|
||||
x:Name="sepa2"
|
||||
@@ -979,6 +1008,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
@@ -1064,6 +1094,22 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbMldsa65Verify}" />
|
||||
<TextBox
|
||||
x:Name="txtMldsa65Verify"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Separator
|
||||
Grid.Row="8"
|
||||
|
||||
@@ -20,41 +20,22 @@ public partial class AddServerWindow
|
||||
|
||||
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
|
||||
|
||||
Global.CoreTypes.ForEach(it =>
|
||||
{
|
||||
cmbCoreType.Items.Add(it);
|
||||
});
|
||||
cmbCoreType.Items.Add(string.Empty);
|
||||
cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
|
||||
cmbNetwork.ItemsSource = Global.Networks;
|
||||
cmbFingerprint.ItemsSource = Global.Fingerprints;
|
||||
cmbFingerprint2.ItemsSource = Global.Fingerprints;
|
||||
cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
|
||||
cmbAlpn.ItemsSource = Global.Alpns;
|
||||
|
||||
cmbStreamSecurity.Items.Add(string.Empty);
|
||||
cmbStreamSecurity.Items.Add(Global.StreamSecurity);
|
||||
|
||||
Global.Networks.ForEach(it =>
|
||||
{
|
||||
cmbNetwork.Items.Add(it);
|
||||
});
|
||||
Global.Fingerprints.ForEach(it =>
|
||||
{
|
||||
cmbFingerprint.Items.Add(it);
|
||||
cmbFingerprint2.Items.Add(it);
|
||||
});
|
||||
Global.AllowInsecure.ForEach(it =>
|
||||
{
|
||||
cmbAllowInsecure.Items.Add(it);
|
||||
});
|
||||
Global.Alpns.ForEach(it =>
|
||||
{
|
||||
cmbAlpn.Items.Add(it);
|
||||
});
|
||||
var lstStreamSecurity = new List<string>();
|
||||
lstStreamSecurity.Add(string.Empty);
|
||||
lstStreamSecurity.Add(Global.StreamSecurity);
|
||||
|
||||
switch (profileItem.ConfigType)
|
||||
{
|
||||
case EConfigType.VMess:
|
||||
gridVMess.Visibility = Visibility.Visible;
|
||||
Global.VmessSecurities.ForEach(it =>
|
||||
{
|
||||
cmbSecurity.Items.Add(it);
|
||||
});
|
||||
cmbSecurity.ItemsSource = Global.VmessSecurities;
|
||||
if (profileItem.Security.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.Security = Global.DefaultSecurity;
|
||||
@@ -63,10 +44,7 @@ public partial class AddServerWindow
|
||||
|
||||
case EConfigType.Shadowsocks:
|
||||
gridSs.Visibility = Visibility.Visible;
|
||||
AppHandler.Instance.GetShadowsocksSecurities(profileItem).ForEach(it =>
|
||||
{
|
||||
cmbSecurity3.Items.Add(it);
|
||||
});
|
||||
cmbSecurity3.ItemsSource = AppHandler.Instance.GetShadowsocksSecurities(profileItem);
|
||||
break;
|
||||
|
||||
case EConfigType.SOCKS:
|
||||
@@ -76,11 +54,8 @@ public partial class AddServerWindow
|
||||
|
||||
case EConfigType.VLESS:
|
||||
gridVLESS.Visibility = Visibility.Visible;
|
||||
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
|
||||
Global.Flows.ForEach(it =>
|
||||
{
|
||||
cmbFlow5.Items.Add(it);
|
||||
});
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbFlow5.ItemsSource = Global.Flows;
|
||||
if (profileItem.Security.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.Security = Global.None;
|
||||
@@ -89,11 +64,8 @@ public partial class AddServerWindow
|
||||
|
||||
case EConfigType.Trojan:
|
||||
gridTrojan.Visibility = Visibility.Visible;
|
||||
cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);
|
||||
Global.Flows.ForEach(it =>
|
||||
{
|
||||
cmbFlow6.Items.Add(it);
|
||||
});
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbFlow6.ItemsSource = Global.Flows;
|
||||
break;
|
||||
|
||||
case EConfigType.Hysteria2:
|
||||
@@ -113,10 +85,7 @@ public partial class AddServerWindow
|
||||
cmbFingerprint.IsEnabled = false;
|
||||
cmbFingerprint.Text = string.Empty;
|
||||
|
||||
Global.TuicCongestionControls.ForEach(it =>
|
||||
{
|
||||
cmbHeaderType8.Items.Add(it);
|
||||
});
|
||||
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
@@ -127,7 +96,14 @@ public partial class AddServerWindow
|
||||
gridTls.Visibility = Visibility.Collapsed;
|
||||
|
||||
break;
|
||||
|
||||
case EConfigType.Anytls:
|
||||
gridAnytls.Visibility = Visibility.Visible;
|
||||
cmbCoreType.IsEnabled = false;
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
break;
|
||||
}
|
||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||
|
||||
gridTlsMore.Visibility = Visibility.Hidden;
|
||||
|
||||
@@ -191,6 +167,10 @@ public partial class AddServerWindow
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EConfigType.Anytls:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId10.Text).DisposeWith(disposables);
|
||||
break;
|
||||
}
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.Text).DisposeWith(disposables);
|
||||
@@ -209,6 +189,7 @@ public partial class AddServerWindow
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.PublicKey, v => v.txtPublicKey.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.SpiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Mldsa65Verify, v => v.txtMldsa65Verify.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
});
|
||||
@@ -267,44 +248,41 @@ public partial class AddServerWindow
|
||||
|
||||
private void SetHeaderType()
|
||||
{
|
||||
cmbHeaderType.Items.Clear();
|
||||
var lstHeaderType = new List<string>();
|
||||
|
||||
var network = cmbNetwork.SelectedItem.ToString();
|
||||
if (network.IsNullOrEmpty())
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
lstHeaderType.Add(Global.None);
|
||||
cmbHeaderType.ItemsSource = lstHeaderType;
|
||||
cmbHeaderType.SelectedIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (network == nameof(ETransport.tcp))
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
cmbHeaderType.Items.Add(Global.TcpHeaderHttp);
|
||||
lstHeaderType.Add(Global.None);
|
||||
lstHeaderType.Add(Global.TcpHeaderHttp);
|
||||
}
|
||||
else if (network is nameof(ETransport.kcp) or nameof(ETransport.quic))
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
Global.KcpHeaderTypes.ForEach(it =>
|
||||
{
|
||||
cmbHeaderType.Items.Add(it);
|
||||
});
|
||||
lstHeaderType.Add(Global.None);
|
||||
lstHeaderType.AddRange(Global.KcpHeaderTypes);
|
||||
}
|
||||
else if (network is nameof(ETransport.xhttp))
|
||||
{
|
||||
Global.XhttpMode.ForEach(it =>
|
||||
{
|
||||
cmbHeaderType.Items.Add(it);
|
||||
});
|
||||
lstHeaderType.AddRange(Global.XhttpMode);
|
||||
}
|
||||
else if (network == nameof(ETransport.grpc))
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.GrpcGunMode);
|
||||
cmbHeaderType.Items.Add(Global.GrpcMultiMode);
|
||||
lstHeaderType.Add(Global.GrpcGunMode);
|
||||
lstHeaderType.Add(Global.GrpcMultiMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmbHeaderType.Items.Add(Global.None);
|
||||
lstHeaderType.Add(Global.None);
|
||||
}
|
||||
cmbHeaderType.ItemsSource = lstHeaderType;
|
||||
cmbHeaderType.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<reactiveui:ReactiveUserControl
|
||||
x:Class="v2rayN.Views.ClashConnectionsView"
|
||||
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:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
d:DesignHeight="450"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<reactiveui:ReactiveUserControl
|
||||
x:Class="v2rayN.Views.ClashProxiesView"
|
||||
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: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:reactiveui="http://reactiveui.net"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
xmlns:converters="clr-namespace:v2rayN.Converters"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:TypeArguments="vms:ClashProxiesViewModel"
|
||||
|
||||
@@ -41,31 +41,360 @@
|
||||
</StackPanel>
|
||||
|
||||
<TabControl HorizontalContentAlignment="Left">
|
||||
<TabItem Header="{x:Static resx:ResUI.ThBasicDNSSettings}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||
<Grid Margin="{StaticResource Margin8}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
x:Name="txtBasicDNSSettingsInvalid"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsRemoteDNS}" />
|
||||
Text="{x:Static resx:ResUI.TbCustomDNSEnabledPageInvalid}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4V2ray"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbDomesticDNS}" />
|
||||
<ComboBox
|
||||
x:Name="cmbDirectDNS"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
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}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<Grid DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||
<ToggleButton
|
||||
x:Name="togRayCustomDNSEnableCompatible"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsRemoteDNS}" />
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4V2rayCompatible"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@@ -75,7 +404,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
||||
<ToggleButton
|
||||
x:Name="togUseSystemHosts"
|
||||
x:Name="togUseSystemHostsCompatible"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
@@ -87,7 +416,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Freedom"
|
||||
x:Name="cmbdomainStrategy4FreedomCompatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
@@ -100,7 +429,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainDNSAddress"
|
||||
x:Name="cmbdomainDNSAddressCompatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin8}"
|
||||
IsEditable="True"
|
||||
@@ -109,7 +438,7 @@
|
||||
</WrapPanel>
|
||||
|
||||
<TextBox
|
||||
x:Name="txtnormalDNS"
|
||||
x:Name="txtnormalDNSCompatible"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Stretch"
|
||||
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
||||
@@ -123,23 +452,42 @@
|
||||
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsSingboxObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4Singbox"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
<Grid DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbCustomDNSEnable}" />
|
||||
<ToggleButton
|
||||
x:Name="togSBCustomDNSEnableCompatible"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsSingboxObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4SingboxCompatible"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@@ -149,7 +497,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Out"
|
||||
x:Name="cmbdomainStrategy4OutCompatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
@@ -162,7 +510,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainDNSAddress2"
|
||||
x:Name="cmbdomainDNSAddress2Compatible"
|
||||
Width="150"
|
||||
Margin="{StaticResource Margin8}"
|
||||
IsEditable="True"
|
||||
@@ -178,7 +526,7 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox
|
||||
x:Name="txtnormalDNS2"
|
||||
x:Name="txtnormalDNS2Compatible"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Stretch"
|
||||
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
||||
@@ -191,7 +539,7 @@
|
||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||
|
||||
<TextBox
|
||||
x:Name="txttunDNS2"
|
||||
x:Name="txttunDNS2Compatible"
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Stretch"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsTunMode}"
|
||||
|
||||
@@ -17,38 +17,66 @@ public partial class DNSSettingWindow
|
||||
|
||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||
|
||||
Global.DomainStrategy4Freedoms.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Freedom.Items.Add(it);
|
||||
});
|
||||
Global.SingboxDomainStrategy4Out.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Out.Items.Add(it);
|
||||
});
|
||||
Global.DomainDNSAddress.ForEach(it =>
|
||||
{
|
||||
cmbdomainDNSAddress.Items.Add(it);
|
||||
});
|
||||
Global.SingboxDomainDNSAddress.ForEach(it =>
|
||||
{
|
||||
cmbdomainDNSAddress2.Items.Add(it);
|
||||
});
|
||||
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||
cmbSBDirectDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||
cmbSBRemoteDNSStrategy.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||
cmbDirectDNS.ItemsSource = Global.DomainDirectDNSAddress;
|
||||
cmbSBResolverDNS.ItemsSource = Global.DomainDirectDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
|
||||
cmbRemoteDNS.ItemsSource = Global.DomainRemoteDNSAddress;
|
||||
cmbSBFinalResolverDNS.ItemsSource = Global.DomainPureIPDNSAddress.Concat(new[] { "dhcp://auto,localhost" });
|
||||
cmbDirectExpectedIPs.ItemsSource = Global.ExpectedIPs;
|
||||
|
||||
cmbdomainStrategy4FreedomCompatible.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||
cmbdomainStrategy4OutCompatible.ItemsSource = Global.SingboxDomainStrategy4Out;
|
||||
cmbdomainDNSAddressCompatible.ItemsSource = Global.DomainPureIPDNSAddress;
|
||||
cmbdomainDNSAddress2Compatible.ItemsSource = Global.DomainPureIPDNSAddress;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.AddCommonHosts, v => v.togAddCommonHosts.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.FakeIP, v => v.togFakeIP.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.BlockBindingQuery, v => v.togBlockBindingQuery.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DirectDNS, v => v.cmbDirectDNS.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.RemoteDNS, v => v.cmbRemoteDNS.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SingboxOutboundsResolveDNS, v => v.cmbSBResolverDNS.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SingboxFinalResolveDNS, v => v.cmbSBFinalResolverDNS.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.RayStrategy4Freedom, v => v.cmbRayFreedomDNSStrategy.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SingboxStrategy4Direct, v => v.cmbSBDirectDNSStrategy.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SingboxStrategy4Proxy, v => v.cmbSBRemoteDNSStrategy.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.Hosts, v => v.txtHosts.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DirectExpectedIPs, v => v.cmbDirectExpectedIPs.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.RayCustomDNSEnableCompatible, v => v.togRayCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SBCustomDNSEnableCompatible, v => v.togSBCustomDNSEnableCompatible.IsChecked).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.UseSystemHostsCompatible, v => v.togUseSystemHostsCompatible.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4FreedomCompatible, v => v.cmbdomainStrategy4FreedomCompatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainDNSAddressCompatible, v => v.cmbdomainDNSAddressCompatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNSCompatible, v => v.txtnormalDNSCompatible.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2Compatible, v => v.cmbdomainStrategy4OutCompatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.DomainDNSAddress2Compatible, v => v.cmbdomainDNSAddress2Compatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NormalDNS2Compatible, v => v.txtnormalDNS2Compatible.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDNS2Compatible, v => v.txttunDNS2Compatible.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables);
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.ViewModel.RayCustomDNSEnableCompatible,
|
||||
x => x.ViewModel.SBCustomDNSEnableCompatible,
|
||||
(ray, sb) => ray && sb ? Visibility.Visible : Visibility.Collapsed)
|
||||
.BindTo(this, x => x.txtBasicDNSSettingsInvalid.Visibility)
|
||||
.DisposeWith(disposables);
|
||||
this.WhenAnyValue(
|
||||
x => x.ViewModel.RayCustomDNSEnableCompatible,
|
||||
x => x.ViewModel.SBCustomDNSEnableCompatible,
|
||||
(ray, sb) => ray && sb ? Visibility.Visible : Visibility.Collapsed)
|
||||
.BindTo(this, x => x.txtAdvancedDNSSettingsInvalid.Visibility)
|
||||
.DisposeWith(disposables);
|
||||
});
|
||||
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,10 @@
|
||||
x:Name="menuAddTuicServer"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
||||
<MenuItem
|
||||
x:Name="menuAddAnytlsServer"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Separator />
|
||||
|
||||
@@ -80,6 +80,7 @@ public partial class MainWindow
|
||||
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);
|
||||
|
||||
@@ -26,10 +26,7 @@ public partial class MsgView
|
||||
menuMsgViewCopyAll.Click += menuMsgViewCopyAll_Click;
|
||||
menuMsgViewClear.Click += menuMsgViewClear_Click;
|
||||
|
||||
Global.PresetMsgFilters.ForEach(it =>
|
||||
{
|
||||
cmbMsgFilter.Items.Add(it);
|
||||
});
|
||||
cmbMsgFilter.ItemsSource = Global.PresetMsgFilters;
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
|
||||
@@ -21,94 +21,39 @@ public partial class OptionSettingWindow
|
||||
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||
|
||||
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
|
||||
Global.destOverrideProtocols.ForEach(it =>
|
||||
{
|
||||
clbdestOverride.Items.Add(it);
|
||||
});
|
||||
clbdestOverride.ItemsSource = Global.destOverrideProtocols;
|
||||
_config.Inbound.First().DestOverride?.ForEach(it =>
|
||||
{
|
||||
clbdestOverride.SelectedItems.Add(it);
|
||||
});
|
||||
Global.IEProxyProtocols.ForEach(it =>
|
||||
{
|
||||
cmbsystemProxyAdvancedProtocol.Items.Add(it);
|
||||
});
|
||||
Global.LogLevels.ForEach(it =>
|
||||
{
|
||||
cmbloglevel.Items.Add(it);
|
||||
});
|
||||
Global.Fingerprints.ForEach(it =>
|
||||
{
|
||||
cmbdefFingerprint.Items.Add(it);
|
||||
});
|
||||
Global.UserAgent.ForEach(it =>
|
||||
{
|
||||
cmbdefUserAgent.Items.Add(it);
|
||||
});
|
||||
Global.SingboxMuxs.ForEach(it =>
|
||||
{
|
||||
cmbmux4SboxProtocol.Items.Add(it);
|
||||
});
|
||||
|
||||
Global.TunMtus.ForEach(it =>
|
||||
{
|
||||
cmbMtu.Items.Add(it);
|
||||
});
|
||||
Global.TunStacks.ForEach(it =>
|
||||
{
|
||||
cmbStack.Items.Add(it);
|
||||
});
|
||||
Global.CoreTypes.ForEach(it =>
|
||||
{
|
||||
cmbCoreType1.Items.Add(it);
|
||||
cmbCoreType2.Items.Add(it);
|
||||
cmbCoreType3.Items.Add(it);
|
||||
cmbCoreType4.Items.Add(it);
|
||||
cmbCoreType5.Items.Add(it);
|
||||
cmbCoreType6.Items.Add(it);
|
||||
cmbCoreType9.Items.Add(it);
|
||||
});
|
||||
cmbsystemProxyAdvancedProtocol.ItemsSource = Global.IEProxyProtocols;
|
||||
cmbloglevel.ItemsSource = Global.LogLevels;
|
||||
cmbdefFingerprint.ItemsSource = Global.Fingerprints;
|
||||
cmbdefUserAgent.ItemsSource = Global.UserAgent;
|
||||
cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
|
||||
cmbMtu.ItemsSource = Global.TunMtus;
|
||||
cmbStack.ItemsSource = Global.TunStacks;
|
||||
|
||||
for (var i = 2; i <= 8; i++)
|
||||
{
|
||||
cmbMixedConcurrencyCount.Items.Add(i);
|
||||
}
|
||||
for (var i = 2; i <= 6; i++)
|
||||
{
|
||||
cmbSpeedTestTimeout.Items.Add(i * 5);
|
||||
}
|
||||
Global.SpeedTestUrls.ForEach(it =>
|
||||
{
|
||||
cmbSpeedTestUrl.Items.Add(it);
|
||||
});
|
||||
Global.SpeedPingTestUrls.ForEach(it =>
|
||||
{
|
||||
cmbSpeedPingTestUrl.Items.Add(it);
|
||||
});
|
||||
Global.SubConvertUrls.ForEach(it =>
|
||||
{
|
||||
cmbSubConvertUrl.Items.Add(it);
|
||||
});
|
||||
Global.GeoFilesSources.ForEach(it =>
|
||||
{
|
||||
cmbGetFilesSourceUrl.Items.Add(it);
|
||||
});
|
||||
Global.SingboxRulesetSources.ForEach(it =>
|
||||
{
|
||||
cmbSrsFilesSourceUrl.Items.Add(it);
|
||||
});
|
||||
Global.RoutingRulesSources.ForEach(it =>
|
||||
{
|
||||
cmbRoutingRulesSourceUrl.Items.Add(it);
|
||||
});
|
||||
Global.IPAPIUrls.ForEach(it =>
|
||||
{
|
||||
cmbIPAPIUrl.Items.Add(it);
|
||||
});
|
||||
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
|
||||
{
|
||||
cmbMainGirdOrientation.Items.Add(it.ToString());
|
||||
}
|
||||
cmbCoreType1.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType2.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType3.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType4.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType5.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType6.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType9.ItemsSource = Global.CoreTypes;
|
||||
|
||||
cmbMixedConcurrencyCount.ItemsSource = Enumerable.Range(2, 7).ToList();
|
||||
cmbSpeedTestTimeout.ItemsSource = Enumerable.Range(2, 5).Select(i => i * 5).ToList();
|
||||
cmbSpeedTestUrl.ItemsSource = Global.SpeedTestUrls;
|
||||
cmbSpeedPingTestUrl.ItemsSource = Global.SpeedPingTestUrls;
|
||||
cmbSubConvertUrl.ItemsSource = Global.SubConvertUrls;
|
||||
cmbGetFilesSourceUrl.ItemsSource = Global.GeoFilesSources;
|
||||
cmbSrsFilesSourceUrl.ItemsSource = Global.SingboxRulesetSources;
|
||||
cmbRoutingRulesSourceUrl.ItemsSource = Global.RoutingRulesSources;
|
||||
cmbIPAPIUrl.ItemsSource = Global.IPAPIUrls;
|
||||
|
||||
cmbMainGirdOrientation.ItemsSource = Utils.GetEnumNames<EGirdOrientation>();
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
@@ -209,8 +154,7 @@ public partial class OptionSettingWindow
|
||||
private async Task InitSettingFont()
|
||||
{
|
||||
var lstFonts = await GetFonts(Utils.GetFontsPath());
|
||||
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
|
||||
cmbcurrentFontFamily.Items.Add(string.Empty);
|
||||
cmbcurrentFontFamily.ItemsSource = lstFonts.AppendEmpty();
|
||||
}
|
||||
|
||||
private async Task<List<string>> GetFonts(string path)
|
||||
|
||||
@@ -16,21 +16,11 @@ public partial class RoutingRuleDetailsWindow
|
||||
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
|
||||
|
||||
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
|
||||
cmbOutboundTag.Items.Add(Global.ProxyTag);
|
||||
cmbOutboundTag.Items.Add(Global.DirectTag);
|
||||
cmbOutboundTag.Items.Add(Global.BlockTag);
|
||||
Global.RuleProtocols.ForEach(it =>
|
||||
{
|
||||
clbProtocol.Items.Add(it);
|
||||
});
|
||||
Global.InboundTags.ForEach(it =>
|
||||
{
|
||||
clbInboundTag.Items.Add(it);
|
||||
});
|
||||
Global.RuleNetworks.ForEach(it =>
|
||||
{
|
||||
cmbNetwork.Items.Add(it);
|
||||
});
|
||||
|
||||
cmbOutboundTag.ItemsSource = Global.OutboundTags;
|
||||
clbProtocol.ItemsSource = Global.RuleProtocols;
|
||||
clbInboundTag.ItemsSource = Global.InboundTags;
|
||||
cmbNetwork.ItemsSource = Global.RuleNetworks;
|
||||
|
||||
if (!rulesItem.Id.IsNullOrEmpty())
|
||||
{
|
||||
|
||||
@@ -21,15 +21,9 @@ public partial class RoutingRuleSettingWindow
|
||||
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_Click;
|
||||
|
||||
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
|
||||
Global.DomainStrategies.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy.Items.Add(it);
|
||||
});
|
||||
cmbdomainStrategy.Items.Add(string.Empty);
|
||||
Global.DomainStrategies4Singbox.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Singbox.Items.Add(it);
|
||||
});
|
||||
|
||||
cmbdomainStrategy.ItemsSource = Global.DomainStrategies.AppendEmpty();
|
||||
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -21,18 +21,9 @@ public partial class RoutingSettingWindow
|
||||
|
||||
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
|
||||
|
||||
Global.DomainStrategies.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy.Items.Add(it);
|
||||
});
|
||||
Global.DomainMatchers.ForEach(it =>
|
||||
{
|
||||
cmbdomainMatcher.Items.Add(it);
|
||||
});
|
||||
Global.DomainStrategies4Singbox.ForEach(it =>
|
||||
{
|
||||
cmbdomainStrategy4Singbox.Items.Add(it);
|
||||
});
|
||||
cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
|
||||
cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
|
||||
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
@@ -131,7 +122,7 @@ public partial class RoutingSettingWindow
|
||||
|
||||
private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
|
||||
@@ -92,8 +92,7 @@
|
||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
||||
DisplayMemberPath="Remarks"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
|
||||
</ComboBox>
|
||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
|
||||
@@ -185,8 +184,7 @@
|
||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
||||
DisplayMemberPath="Remarks"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}">
|
||||
</ComboBox>
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
@@ -200,8 +198,7 @@
|
||||
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
|
||||
DisplayMemberPath="Text"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}">
|
||||
</ComboBox>
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
|
||||
@@ -15,10 +15,7 @@ public partial class SubEditWindow
|
||||
|
||||
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
|
||||
|
||||
Global.SubConvertTargets.ForEach(it =>
|
||||
{
|
||||
cmbConvertTarget.Items.Add(it);
|
||||
});
|
||||
cmbConvertTarget.ItemsSource = Global.SubConvertTargets;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -13,22 +13,10 @@ public partial class ThemeSettingView
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new ThemeSettingViewModel();
|
||||
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
|
||||
{
|
||||
if ((int)it > 2)
|
||||
continue;
|
||||
cmbCurrentTheme.Items.Add(it.ToString());
|
||||
}
|
||||
|
||||
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
|
||||
{
|
||||
cmbCurrentFontSize.Items.Add(i.ToString());
|
||||
}
|
||||
|
||||
Global.Languages.ForEach(it =>
|
||||
{
|
||||
cmbCurrentLanguage.Items.Add(it);
|
||||
});
|
||||
cmbCurrentTheme.ItemsSource = Utils.GetEnumNames<ETheme>().Take(3).ToList();
|
||||
cmbCurrentFontSize.ItemsSource = Enumerable.Range(Global.MinFontSize, 11).ToList();
|
||||
cmbCurrentLanguage.ItemsSource = Global.Languages;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user