Compare commits

...

16 Commits
6.49 ... 6.51

Author SHA1 Message Date
2dust
cfe8fcd28d up 6.51 2024-07-12 14:23:29 +08:00
2dust
9f4718af70 Code clean
Add allowInsecure to Share
2024-07-11 14:42:01 +08:00
2dust
39faccfd0b Bug fix 2024-07-10 17:32:26 +08:00
2dust
7545763dae Default domain strategy for resolving the outbound domain names -- singbox 2024-07-08 18:45:29 +08:00
2dust
c2928be35d Log messages are not displayed when in the background 2024-07-08 17:16:49 +08:00
2dust
449bb40d48 sing-box prioritizes the use of local srs 2024-07-08 14:20:41 +08:00
2dust
4caf1a1e63 Improve and refactor the code 2024-07-08 09:52:11 +08:00
2dust
01b205e6f1 Adjust information DispatcherPriority 2024-07-07 21:11:04 +08:00
2dust
160d3843a6 Bug fix 2024-07-05 15:28:28 +08:00
2dust
5efb784115 up 6.50 2024-07-05 11:18:36 +08:00
2dust
acde5b8384 Bug fix 2024-07-05 11:18:14 +08:00
2dust
373ee6586a Optimize system proxy code 2024-07-04 17:07:05 +08:00
2dust
215308c329 Change srs source
https://github.com/2dust/sing-box-rules
2024-07-04 16:27:44 +08:00
2dust
478cadba5e Bug fix 2024-06-30 20:43:06 +08:00
2dust
f4af4da791 Adjust res 2024-06-30 10:00:28 +08:00
2dust
22d4f435de Add tun and mixin functions to clash 2024-06-28 20:29:44 +08:00
41 changed files with 348 additions and 316 deletions

View File

@@ -9,7 +9,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.27.1" /> <PackageReference Include="Google.Protobuf" Version="3.27.2" />
<PackageReference Include="Grpc.Net.Client" Version="2.63.0" /> <PackageReference Include="Grpc.Net.Client" Version="2.63.0" />
<PackageReference Include="Grpc.Tools" Version="2.64.0"> <PackageReference Include="Grpc.Tools" Version="2.64.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View File

@@ -43,6 +43,7 @@ namespace v2rayN
Init(); Init();
Logging.LoggingEnabled(_config.guiItem.enableLog); Logging.LoggingEnabled(_config.guiItem.enableLog);
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}"); Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
Logging.ClearLogs(); Logging.ClearLogs();
Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage); Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage);

View File

@@ -1,10 +1,38 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static v2rayN.Handler.ProxySetting.InternetConnectionOption; using static v2rayN.Common.ProxySetting.InternetConnectionOption;
namespace v2rayN.Handler namespace v2rayN.Common
{ {
internal class ProxySetting internal class ProxySetting
{ {
private const string _regPath = @"Software\Microsoft\Windows\CurrentVersion\Internet Settings";
private static bool SetProxyFallback(string? strProxy, string? exceptions, int type)
{
if (type == 1)
{
Utils.RegWriteValue(_regPath, "ProxyEnable", 0);
Utils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
Utils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
Utils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
}
if (type == 2)
{
Utils.RegWriteValue(_regPath, "ProxyEnable", 1);
Utils.RegWriteValue(_regPath, "ProxyServer", strProxy ?? string.Empty);
Utils.RegWriteValue(_regPath, "ProxyOverride", exceptions ?? string.Empty);
Utils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
}
else if (type == 4)
{
Utils.RegWriteValue(_regPath, "ProxyEnable", 0);
Utils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
Utils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
Utils.RegWriteValue(_regPath, "AutoConfigURL", strProxy ?? string.Empty);
}
return true;
}
/// <summary> /// <summary>
// set to use no proxy // set to use no proxy
/// </summary> /// </summary>
@@ -29,15 +57,24 @@ namespace v2rayN.Handler
/// <returns>true: one of connection is successfully updated proxy settings</returns> /// <returns>true: one of connection is successfully updated proxy settings</returns>
public static bool SetProxy(string? strProxy, string? exceptions, int type) public static bool SetProxy(string? strProxy, string? exceptions, int type)
{ {
// set proxy for LAN try
bool result = SetConnectionProxy(null, strProxy, exceptions, type);
// set proxy for dial up connections
var connections = EnumerateRasEntries();
foreach (var connection in connections)
{ {
result |= SetConnectionProxy(connection, strProxy, exceptions, type); // set proxy for LAN
bool result = SetConnectionProxy(null, strProxy, exceptions, type);
// set proxy for dial up connections
var connections = EnumerateRasEntries();
foreach (var connection in connections)
{
result |= SetConnectionProxy(connection, strProxy, exceptions, type);
}
return result;
}
catch (Exception ex)
{
SetProxyFallback(strProxy, exceptions, type);
Logging.SaveLog(ex.Message, ex);
return false;
} }
return result;
} }
private static bool SetConnectionProxy(string? connectionName, string? strProxy, string? exceptions, int type) private static bool SetConnectionProxy(string? connectionName, string? strProxy, string? exceptions, int type)
@@ -94,25 +131,25 @@ namespace v2rayN.Handler
} }
else else
{ {
list.szConnection = IntPtr.Zero; list.szConnection = nint.Zero;
} }
list.dwOptionCount = options.Length; list.dwOptionCount = options.Length;
list.dwOptionError = 0; list.dwOptionError = 0;
int optSize = Marshal.SizeOf(typeof(InternetConnectionOption)); int optSize = Marshal.SizeOf(typeof(InternetConnectionOption));
// make a pointer out of all that ... // make a pointer out of all that ...
IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length); // !! remember to deallocate memory 4 nint optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length); // !! remember to deallocate memory 4
// copy the array over into that spot in memory ... // copy the array over into that spot in memory ...
for (int i = 0; i < options.Length; ++i) for (int i = 0; i < options.Length; ++i)
{ {
if (Environment.Is64BitOperatingSystem) if (Environment.Is64BitOperatingSystem)
{ {
IntPtr opt = new(optionsPtr.ToInt64() + (i * optSize)); nint opt = new(optionsPtr.ToInt64() + i * optSize);
Marshal.StructureToPtr(options[i], opt, false); Marshal.StructureToPtr(options[i], opt, false);
} }
else else
{ {
IntPtr opt = new(optionsPtr.ToInt32() + (i * optSize)); nint opt = new(optionsPtr.ToInt32() + i * optSize);
Marshal.StructureToPtr(options[i], opt, false); Marshal.StructureToPtr(options[i], opt, false);
} }
} }
@@ -120,11 +157,11 @@ namespace v2rayN.Handler
list.options = optionsPtr; list.options = optionsPtr;
// and then make a pointer out of the whole list // and then make a pointer out of the whole list
IntPtr ipcoListPtr = Marshal.AllocCoTaskMem(list.dwSize); // !! remember to deallocate memory 5 nint ipcoListPtr = Marshal.AllocCoTaskMem(list.dwSize); // !! remember to deallocate memory 5
Marshal.StructureToPtr(list, ipcoListPtr, false); Marshal.StructureToPtr(list, ipcoListPtr, false);
// and finally, call the API method! // and finally, call the API method!
bool isSuccess = NativeMethods.InternetSetOption(IntPtr.Zero, bool isSuccess = NativeMethods.InternetSetOption(nint.Zero,
InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,
ipcoListPtr, list.dwSize); ipcoListPtr, list.dwSize);
int returnvalue = 0; // ERROR_SUCCESS int returnvalue = 0; // ERROR_SUCCESS
@@ -135,12 +172,12 @@ namespace v2rayN.Handler
else else
{ {
// Notify the system that the registry settings have been changed and cause them to be refreshed // Notify the system that the registry settings have been changed and cause them to be refreshed
NativeMethods.InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0); NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_SETTINGS_CHANGED, nint.Zero, 0);
NativeMethods.InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_REFRESH, nint.Zero, 0);
} }
// FREE the data ASAP // FREE the data ASAP
if (list.szConnection != IntPtr.Zero) Marshal.FreeHGlobal(list.szConnection); // release mem 3 if (list.szConnection != nint.Zero) Marshal.FreeHGlobal(list.szConnection); // release mem 3
if (optionCount > 1) if (optionCount > 1)
{ {
Marshal.FreeHGlobal(options[1].m_Value.m_StringPtr); // release mem 1 Marshal.FreeHGlobal(options[1].m_Value.m_StringPtr); // release mem 1
@@ -204,12 +241,12 @@ namespace v2rayN.Handler
public struct InternetPerConnOptionList public struct InternetPerConnOptionList
{ {
public int dwSize; // size of the INTERNET_PER_CONN_OPTION_LIST struct public int dwSize; // size of the INTERNET_PER_CONN_OPTION_LIST struct
public IntPtr szConnection; // connection name to set/query options public nint szConnection; // connection name to set/query options
public int dwOptionCount; // number of options to set/query public int dwOptionCount; // number of options to set/query
public int dwOptionError; // on error, which option failed public int dwOptionError; // on error, which option failed
//[MarshalAs(UnmanagedType.)] //[MarshalAs(UnmanagedType.)]
public IntPtr options; public nint options;
}; };
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
@@ -236,7 +273,7 @@ namespace v2rayN.Handler
public int m_Int; public int m_Int;
[FieldOffset(0)] [FieldOffset(0)]
public IntPtr m_StringPtr; public nint m_StringPtr;
} }
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
@@ -308,7 +345,7 @@ namespace v2rayN.Handler
{ {
[DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength); public static extern bool InternetSetOption(nint hInternet, InternetOption dwOption, nint lpBuffer, int dwBufferLength);
[DllImport("Rasapi32.dll", CharSet = CharSet.Auto)] [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
public static extern uint RasEnumEntries( public static extern uint RasEnumEntries(

View File

@@ -1,9 +1,4 @@
using System; using YamlDotNet.Serialization;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;
namespace v2rayN.Common namespace v2rayN.Common

View File

@@ -11,7 +11,7 @@ namespace v2rayN.Converters
if (delay <= 0) if (delay <= 0)
return new SolidColorBrush(Colors.Red); return new SolidColorBrush(Colors.Red);
if (delay <= 200) if (delay <= 500)
return new SolidColorBrush(Colors.Green); return new SolidColorBrush(Colors.Green);
else else
return new SolidColorBrush(Colors.IndianRed); return new SolidColorBrush(Colors.IndianRed);

View File

@@ -23,14 +23,14 @@ namespace v2rayN
public const string SpeedPingTestUrl = @"https://www.google.com/generate_204"; public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
public const string JuicityCoreUrl = "https://github.com/juicity/juicity/releases"; public const string JuicityCoreUrl = "https://github.com/juicity/juicity/releases";
public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/"; public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
public const string SingboxRulesetUrlGeosite = @"https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/{0}.srs"; public const string SingboxRulesetUrl = @"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-{0}/{1}.srs";
public const string SingboxRulesetUrlGeoip = @"https://raw.githubusercontent.com/Loyalsoldier/geoip/release/srs/{0}.srs";
public const string PromotionUrl = @"aHR0cHM6Ly85LjIzNDQ1Ni54eXovYWJjLmh0bWw="; public const string PromotionUrl = @"aHR0cHM6Ly85LjIzNDQ1Ni54eXovYWJjLmh0bWw=";
public const string ConfigFileName = "guiNConfig.json"; public const string ConfigFileName = "guiNConfig.json";
public const string CoreConfigFileName = "config.json"; public const string CoreConfigFileName = "config.json";
public const string CorePreConfigFileName = "configPre.json"; public const string CorePreConfigFileName = "configPre.json";
public const string CoreSpeedtestConfigFileName = "configSpeedtest.json"; public const string CoreSpeedtestConfigFileName = "configSpeedtest.json";
public const string ClashMixinConfigFileName = "Mixin.yaml";
public const string V2raySampleClient = "v2rayN.Sample.SampleClientConfig"; public const string V2raySampleClient = "v2rayN.Sample.SampleClientConfig";
public const string SingboxSampleClient = "v2rayN.Sample.SingboxSampleClientConfig"; public const string SingboxSampleClient = "v2rayN.Sample.SingboxSampleClientConfig";
public const string V2raySampleHttpRequestFileName = "v2rayN.Sample.SampleHttpRequest"; public const string V2raySampleHttpRequestFileName = "v2rayN.Sample.SampleHttpRequest";
@@ -44,6 +44,8 @@ namespace v2rayN
public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules"; public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules";
public const string DNSV2rayNormalFileName = "v2rayN.Sample.dns_v2ray_normal"; public const string DNSV2rayNormalFileName = "v2rayN.Sample.dns_v2ray_normal";
public const string DNSSingboxNormalFileName = "v2rayN.Sample.dns_singbox_normal"; public const string DNSSingboxNormalFileName = "v2rayN.Sample.dns_singbox_normal";
public const string ClashMixinYaml = "v2rayN.Sample.clash_mixin_yaml";
public const string ClashTunYaml = "v2rayN.Sample.clash_tun_yaml";
public const string DefaultSecurity = "auto"; public const string DefaultSecurity = "auto";
public const string DefaultNetwork = "tcp"; public const string DefaultNetwork = "tcp";
@@ -170,6 +172,7 @@ namespace v2rayN
public static readonly List<string> AllowInsecure = new() { "true", "false", "" }; public static readonly List<string> AllowInsecure = new() { "true", "false", "" };
public static readonly List<string> DomainStrategy4Freedoms = new() { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" }; public static readonly List<string> DomainStrategy4Freedoms = new() { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" };
public static readonly List<string> SingboxDomainStrategy4Out = new() { "ipv4_only", "prefer_ipv4", "prefer_ipv6", "ipv6_only", "" };
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" }; public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" };
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2,http/1.1", "h3,h2", "h2,http/1.1", "" }; public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2,http/1.1", "h3,h2", "h2,http/1.1", "" };
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" }; public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };

View File

@@ -82,7 +82,8 @@ namespace v2rayN.Handler.CoreConfig
//socks-port //socks-port
fileContent["socks-port"] = LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks); fileContent["socks-port"] = LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks);
//log-level //log-level
fileContent["log-level"] = _config.coreBasicItem.loglevel; fileContent["log-level"] = GetLogLevel(_config.coreBasicItem.loglevel);
//external-controller //external-controller
fileContent["external-controller"] = $"{Global.Loopback}:{LazyConfig.Instance.StatePort2}"; fileContent["external-controller"] = $"{Global.Loopback}:{LazyConfig.Instance.StatePort2}";
//allow-lan //allow-lan
@@ -97,7 +98,7 @@ namespace v2rayN.Handler.CoreConfig
} }
//ipv6 //ipv6
//fileContent["ipv6"] = _config.EnableIpv6; fileContent["ipv6"] = _config.clashUIItem.enableIPv6;
//mode //mode
if (!fileContent.ContainsKey("mode")) if (!fileContent.ContainsKey("mode"))
@@ -112,27 +113,27 @@ namespace v2rayN.Handler.CoreConfig
} }
} }
////enable tun mode //enable tun mode
//if (config.EnableTun) if (_config.tunModeItem.enableTun)
//{ {
// string tun = Utils.GetEmbedText(Global.SampleTun); string tun = Utils.GetEmbedText(Global.ClashTunYaml);
// if (!string.IsNullOrEmpty(tun)) if (!string.IsNullOrEmpty(tun))
// { {
// var tunContent = Utils.FromYaml<Dictionary<string, object>>(tun); var tunContent = YamlUtils.FromYaml<Dictionary<string, object>>(tun);
// if (tunContent != null) if (tunContent != null)
// fileContent["tun"] = tunContent["tun"]; fileContent["tun"] = tunContent["tun"];
// } }
//} }
//Mixin //Mixin
//try try
//{ {
// MixinContent(fileContent, config, node); MixinContent(fileContent, node);
//} }
//catch (Exception ex) catch (Exception ex)
//{ {
// Logging.SaveLog("GenerateClientConfigClash-Mixin", ex); Logging.SaveLog("GenerateClientConfigClash-Mixin", ex);
//} }
var txtFileNew = YamlUtils.ToYaml(fileContent).Replace(tagYamlStr2, tagYamlStr3); var txtFileNew = YamlUtils.ToYaml(fileContent).Replace(tagYamlStr2, tagYamlStr3);
File.WriteAllText(fileName, txtFileNew); File.WriteAllText(fileName, txtFileNew);
@@ -156,49 +157,48 @@ namespace v2rayN.Handler.CoreConfig
return 0; return 0;
} }
//private static void MixinContent(Dictionary<string, object> fileContent, Config config, ProfileItem node) private void MixinContent(Dictionary<string, object> fileContent, ProfileItem node)
//{ {
// if (!config.EnableMixinContent) //if (!_config.clashUIItem.enableMixinContent)
// { //{
// return; // return;
// } //}
// var path = Utils.GetConfigPath(Global.mixinConfigFileName); var path = Utils.GetConfigPath(Global.ClashMixinConfigFileName);
// if (!File.Exists(path)) if (!File.Exists(path))
// { {
// return; return;
// } }
// var txtFile = File.ReadAllText(Utils.GetConfigPath(Global.mixinConfigFileName)); var txtFile = File.ReadAllText(Utils.GetConfigPath(Global.ClashMixinConfigFileName));
// //txtFile = txtFile.Replace("!<str>", "");
// var mixinContent = YamlUtils.FromYaml<Dictionary<string, object>>(txtFile); var mixinContent = YamlUtils.FromYaml<Dictionary<string, object>>(txtFile);
// if (mixinContent == null) if (mixinContent == null)
// { {
// return; return;
// } }
// foreach (var item in mixinContent) foreach (var item in mixinContent)
// { {
// if (!config.EnableTun && item.Key == "tun") if (!_config.tunModeItem.enableTun && item.Key == "tun")
// { {
// continue; continue;
// } }
// if (item.Key.StartsWith("prepend-") if (item.Key.StartsWith("prepend-")
// || item.Key.StartsWith("append-") || item.Key.StartsWith("append-")
// || item.Key.StartsWith("removed-")) || item.Key.StartsWith("removed-"))
// { {
// ModifyContentMerge(fileContent, item.Key, item.Value); ModifyContentMerge(fileContent, item.Key, item.Value);
// } }
// else else
// { {
// fileContent[item.Key] = item.Value; fileContent[item.Key] = item.Value;
// } }
// } }
// return; return;
//} }
private static void ModifyContentMerge(Dictionary<string, object> fileContent, string key, object value) private void ModifyContentMerge(Dictionary<string, object> fileContent, string key, object value)
{ {
bool blPrepend = false; bool blPrepend = false;
bool blRemoved = false; bool blRemoved = false;
@@ -255,5 +255,17 @@ namespace v2rayN.Handler.CoreConfig
} }
} }
} }
private string GetLogLevel(string level)
{
if (level == "none")
{
return "silent";
}
else
{
return level;
}
}
} }
} }

View File

@@ -1,4 +1,5 @@
using System.Data; using System.Data;
using System.IO;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using v2rayN.Enums; using v2rayN.Enums;
@@ -825,7 +826,7 @@ namespace v2rayN.Handler.CoreConfig
} }
singboxConfig.dns = dns4Sbox; singboxConfig.dns = dns4Sbox;
GenDnsDomains(node, singboxConfig); GenDnsDomains(node, singboxConfig, item?.domainStrategy4Freedom);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -834,7 +835,7 @@ namespace v2rayN.Handler.CoreConfig
return 0; return 0;
} }
private int GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig) private int GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig, string? strategy)
{ {
var dns4Sbox = singboxConfig.dns ?? new(); var dns4Sbox = singboxConfig.dns ?? new();
dns4Sbox.servers ??= []; dns4Sbox.servers ??= [];
@@ -846,7 +847,7 @@ namespace v2rayN.Handler.CoreConfig
tag = tag, tag = tag,
address = "223.5.5.5", address = "223.5.5.5",
detour = Global.DirectTag, detour = Global.DirectTag,
//strategy = strategy strategy = Utils.IsNullOrEmpty(strategy) ? null : strategy,
}); });
var lstDomain = singboxConfig.outbounds var lstDomain = singboxConfig.outbounds
@@ -966,29 +967,41 @@ namespace v2rayN.Handler.CoreConfig
} }
} }
//Local srs files address
var localSrss = Utils.GetBinPath("srss");
//Add ruleset srs //Add ruleset srs
singboxConfig.route.rule_set = []; singboxConfig.route.rule_set = [];
foreach (var item in new HashSet<string>(ruleSets)) foreach (var item in new HashSet<string>(ruleSets))
{ {
if (Utils.IsNullOrEmpty(item)) { continue; } if (Utils.IsNullOrEmpty(item)) { continue; }
var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item)); var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item));
if (customRuleset != null) if (customRuleset is null)
{ {
singboxConfig.route.rule_set.Add(customRuleset); var pathSrs = Path.Combine(localSrss, $"{item}.srs");
} if (File.Exists(pathSrs))
else
{
singboxConfig.route.rule_set.Add(new()
{ {
type = "remote", customRuleset = new()
format = "binary", {
tag = item, type = "local",
url = item.StartsWith(geosite) ? format = "binary",
string.Format(Global.SingboxRulesetUrlGeosite, item) : tag = item,
string.Format(Global.SingboxRulesetUrlGeoip, item.Replace($"{geoip}-", "")), path = pathSrs
download_detour = Global.ProxyTag };
}); }
else
{
customRuleset = new()
{
type = "remote",
format = "binary",
tag = item,
url = string.Format(Global.SingboxRulesetUrl, item.StartsWith(geosite) ? geosite : geoip, item),
download_detour = Global.ProxyTag
};
}
} }
singboxConfig.route.rule_set.Add(customRuleset);
} }
return 0; return 0;
@@ -1131,7 +1144,7 @@ namespace v2rayN.Handler.CoreConfig
singboxConfig.route.rules.Add(rule); singboxConfig.route.rules.Add(rule);
} }
GenDnsDomains(null, singboxConfig); GenDnsDomains(null, singboxConfig, null);
//var dnsServer = singboxConfig.dns?.servers.FirstOrDefault(); //var dnsServer = singboxConfig.dns?.servers.FirstOrDefault();
//if (dnsServer != null) //if (dnsServer != null)
//{ //{

View File

@@ -286,8 +286,6 @@ namespace v2rayN.Handler
int responseTime = -1; int responseTime = -1;
try try
{ {
Stopwatch timer = Stopwatch.StartNew();
using var cts = new CancellationTokenSource(); using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(downloadTimeout)); cts.CancelAfter(TimeSpan.FromSeconds(downloadTimeout));
using var client = new HttpClient(new SocketsHttpHandler() using var client = new HttpClient(new SocketsHttpHandler()
@@ -295,9 +293,13 @@ namespace v2rayN.Handler
Proxy = webProxy, Proxy = webProxy,
UseProxy = webProxy != null UseProxy = webProxy != null
}); });
var timer = Stopwatch.StartNew();
await client.GetAsync(url, cts.Token); await client.GetAsync(url, cts.Token);
responseTime = timer.Elapsed.Milliseconds; timer.Stop();
responseTime = (int)timer.Elapsed.TotalMilliseconds;
} }
catch //(Exception ex) catch //(Exception ex)
{ {

View File

@@ -59,6 +59,10 @@ namespace v2rayN.Handler.Fmt
{ {
dicQuery.Add("spx", Utils.UrlEncode(item.spiderX)); dicQuery.Add("spx", Utils.UrlEncode(item.spiderX));
} }
if (item.allowInsecure.Equals("true"))
{
dicQuery.Add("allowInsecure", "1");
}
dicQuery.Add("type", !Utils.IsNullOrEmpty(item.network) ? item.network : nameof(ETransport.tcp)); dicQuery.Add("type", !Utils.IsNullOrEmpty(item.network) ? item.network : nameof(ETransport.tcp));
@@ -137,6 +141,7 @@ namespace v2rayN.Handler.Fmt
item.publicKey = Utils.UrlDecode(query["pbk"] ?? ""); item.publicKey = Utils.UrlDecode(query["pbk"] ?? "");
item.shortId = Utils.UrlDecode(query["sid"] ?? ""); item.shortId = Utils.UrlDecode(query["sid"] ?? "");
item.spiderX = Utils.UrlDecode(query["spx"] ?? ""); item.spiderX = Utils.UrlDecode(query["spx"] ?? "");
item.allowInsecure = (query["allowInsecure"] ?? "") == "1" ? "true" : "";
item.network = query["type"] ?? nameof(ETransport.tcp); item.network = query["type"] ?? nameof(ETransport.tcp);
switch (item.network) switch (item.network)

View File

@@ -1,5 +1,4 @@
using System.Text.RegularExpressions; using v2rayN.Enums;
using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
@@ -7,17 +6,13 @@ namespace v2rayN.Handler.Fmt
{ {
internal class VmessFmt : BaseFmt internal class VmessFmt : BaseFmt
{ {
private static readonly Regex StdVmessUserInfo = new(
@"^(?<network>[a-z]+)(\+(?<streamSecurity>[a-z]+))?:(?<id>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$", RegexOptions.Compiled);
public static ProfileItem? Resolve(string str, out string msg) public static ProfileItem? Resolve(string str, out string msg)
{ {
msg = ResUI.ConfigurationFormatIncorrect; msg = ResUI.ConfigurationFormatIncorrect;
ProfileItem? item; ProfileItem? item;
int indexSplit = str.IndexOf("?"); if (str.IndexOf('?') > 0 && str.IndexOf('&') > 0)
if (indexSplit > 0)
{ {
item = ResolveStdVmess(str) ?? ResolveVmess4Kitsunebi(str); item = ResolveStdVmess(str);
} }
else else
{ {
@@ -107,7 +102,7 @@ namespace v2rayN.Handler.Fmt
return item; return item;
} }
private static ProfileItem? ResolveStdVmess(string result) public static ProfileItem? ResolveStdVmess(string str)
{ {
ProfileItem item = new() ProfileItem item = new()
{ {
@@ -115,113 +110,15 @@ namespace v2rayN.Handler.Fmt
security = "auto" security = "auto"
}; };
Uri u = new(result); Uri url = new(str);
item.address = u.IdnHost; item.address = url.IdnHost;
item.port = u.Port; item.port = url.Port;
item.remarks = u.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
var query = Utils.ParseQueryString(u.Query); item.id = Utils.UrlDecode(url.UserInfo);
var m = StdVmessUserInfo.Match(u.UserInfo); var query = Utils.ParseQueryString(url.Query);
if (!m.Success) return null; ResolveStdTransport(query, ref item);
item.id = m.Groups["id"].Value;
if (m.Groups["streamSecurity"].Success)
{
item.streamSecurity = m.Groups["streamSecurity"].Value;
}
switch (item.streamSecurity)
{
case Global.StreamSecurity:
break;
default:
if (!Utils.IsNullOrEmpty(item.streamSecurity))
return null;
break;
}
item.network = m.Groups["network"].Value;
switch (item.network)
{
case nameof(ETransport.tcp):
string t1 = query["type"] ?? Global.None;
item.headerType = t1;
break;
case nameof(ETransport.kcp):
item.headerType = query["type"] ?? Global.None;
break;
case nameof(ETransport.ws):
case nameof(ETransport.httpupgrade):
case nameof(ETransport.splithttp):
string p1 = query["path"] ?? "/";
string h1 = query["host"] ?? "";
item.requestHost = Utils.UrlDecode(h1);
item.path = p1;
break;
case nameof(ETransport.http):
case nameof(ETransport.h2):
item.network = nameof(ETransport.h2);
string p2 = query["path"] ?? "/";
string h2 = query["host"] ?? "";
item.requestHost = Utils.UrlDecode(h2);
item.path = p2;
break;
case nameof(ETransport.quic):
string s = query["security"] ?? Global.None;
string k = query["key"] ?? "";
string t3 = query["type"] ?? Global.None;
item.headerType = t3;
item.requestHost = Utils.UrlDecode(s);
item.path = k;
break;
default:
return null;
}
return item;
}
private static ProfileItem? ResolveVmess4Kitsunebi(string result)
{
ProfileItem item = new()
{
configType = EConfigType.VMess
};
result = result[Global.ProtocolShares[EConfigType.VMess].Length..];
int indexSplit = result.IndexOf("?");
if (indexSplit > 0)
{
result = result[..indexSplit];
}
result = Utils.Base64Decode(result);
string[] arr1 = result.Split('@');
if (arr1.Length != 2)
{
return null;
}
string[] arr21 = arr1[0].Split(':');
string[] arr22 = arr1[1].Split(':');
if (arr21.Length != 2 || arr22.Length != 2)
{
return null;
}
item.address = arr22[0];
item.port = Utils.ToInt(arr22[1]);
item.security = arr21[0];
item.id = arr21[1];
item.network = Global.DefaultNetwork;
item.headerType = Global.None;
item.remarks = "Alien";
return item; return item;
} }

View File

@@ -377,19 +377,18 @@ namespace v2rayN.Handler
ipAddress = ipHostInfo.AddressList[0]; ipAddress = ipHostInfo.AddressList[0];
} }
Stopwatch timer = new(); var timer = Stopwatch.StartNew();
timer.Start();
IPEndPoint endPoint = new(ipAddress, port); IPEndPoint endPoint = new(ipAddress, port);
using Socket clientSocket = new(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); using Socket clientSocket = new(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult result = clientSocket.BeginConnect(endPoint, null, null); var result = clientSocket.BeginConnect(endPoint, null, null);
if (!result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5))) if (!result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)))
throw new TimeoutException("connect timeout (5s): " + url); throw new TimeoutException("connect timeout (5s): " + url);
clientSocket.EndConnect(result); clientSocket.EndConnect(result);
timer.Stop(); timer.Stop();
responseTime = timer.Elapsed.Milliseconds; responseTime = (int)timer.Elapsed.TotalMilliseconds;
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -1,6 +1,6 @@
using v2rayN.Models; using v2rayN.Models;
namespace v2rayN.Handler namespace v2rayN.Handler.Statistics
{ {
internal class StatisticsHandler internal class StatisticsHandler
{ {

View File

@@ -3,7 +3,7 @@ using System.Text;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
namespace v2rayN.Handler namespace v2rayN.Handler.Statistics
{ {
internal class StatisticsSingbox internal class StatisticsSingbox
{ {

View File

@@ -4,7 +4,7 @@ using ProtosLib.Statistics;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
namespace v2rayN.Handler namespace v2rayN.Handler.Statistics
{ {
internal class StatisticsV2ray internal class StatisticsV2ray
{ {

View File

@@ -1,4 +1,5 @@
using PacLib; using PacLib;
using v2rayN.Common;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
@@ -6,30 +7,7 @@ namespace v2rayN.Handler
{ {
public static class SysProxyHandle public static class SysProxyHandle
{ {
//private const string _userWininetConfigFile = "user-wininet.json"; private const string _regPath = @"Software\Microsoft\Windows\CurrentVersion\Internet Settings";
//private static string _queryStr;
// In general, this won't change
// format:
// <flags><CR-LF>
// <proxy-server><CR-LF>
// <bypass-list><CR-LF>
// <pac-url>
private enum RET_ERRORS : int
{
RET_NO_ERROR = 0,
INVALID_FORMAT = 1,
NO_PERMISSION = 2,
SYSCALL_FAILED = 3,
NO_MEMORY = 4,
INVAILD_OPTION_COUNT = 5,
};
static SysProxyHandle()
{
}
public static bool UpdateSysProxy(Config config, bool forceDisable) public static bool UpdateSysProxy(Config config, bool forceDisable)
{ {
@@ -65,11 +43,11 @@ namespace v2rayN.Handler
.Replace("{http_port}", port.ToString()) .Replace("{http_port}", port.ToString())
.Replace("{socks_port}", portSocks.ToString()); .Replace("{socks_port}", portSocks.ToString());
} }
ProxySetting.SetProxy(strProxy, strExceptions, 2); // set a named proxy ProxySetting.SetProxy(strProxy, strExceptions, 2);
} }
else if (type == ESysProxyType.ForcedClear) else if (type == ESysProxyType.ForcedClear)
{ {
ProxySetting.UnsetProxy(); // set to no proxy ProxySetting.UnsetProxy();
} }
else if (type == ESysProxyType.Unchanged) else if (type == ESysProxyType.Unchanged)
{ {
@@ -78,7 +56,7 @@ namespace v2rayN.Handler
{ {
PacHandler.Start(Utils.GetConfigPath(), port, portPac); PacHandler.Start(Utils.GetConfigPath(), port, portPac);
var strProxy = $"{Global.HttpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}"; var strProxy = $"{Global.HttpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}";
ProxySetting.SetProxy(strProxy, "", 4); // use pac script url for auto-config proxy ProxySetting.SetProxy(strProxy, "", 4);
} }
if (type != ESysProxyType.Pac) if (type != ESysProxyType.Pac)
@@ -95,14 +73,7 @@ namespace v2rayN.Handler
public static void ResetIEProxy4WindowsShutDown() public static void ResetIEProxy4WindowsShutDown()
{ {
try ProxySetting.UnsetProxy();
{
//TODO To be verified
Utils.RegWriteValue(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable", 0);
}
catch
{
}
} }
} }
} }

View File

@@ -1,6 +1,4 @@
 using static v2rayN.Models.ClashProxies;
using static v2rayN.Models.ClashProxies;
namespace v2rayN.Models namespace v2rayN.Models
{ {

View File

@@ -169,7 +169,7 @@ namespace v2rayN.Models
public string stack { get; set; } public string stack { get; set; }
public int mtu { get; set; } public int mtu { get; set; }
public bool enableExInbound { get; set; } public bool enableExInbound { get; set; }
public bool enableIPv6Address { get; set; } = true; public bool enableIPv6Address { get; set; }
} }
[Serializable] [Serializable]
@@ -217,6 +217,8 @@ namespace v2rayN.Models
{ {
public ERuleMode ruleMode { get; set; } public ERuleMode ruleMode { get; set; }
public bool showInTaskbar { get; set; } public bool showInTaskbar { get; set; }
public bool enableIPv6 { get; set; }
public bool enableMixinContent { get; set; }
public int proxiesSorting { get; set; } public int proxiesSorting { get; set; }
public bool proxiesAutoRefresh { get; set; } public bool proxiesAutoRefresh { get; set; }
public int proxiesAutoDelayTestInterval { get; set; } = 10; public int proxiesAutoDelayTestInterval { get; set; } = 10;

View File

@@ -2734,6 +2734,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Default domain strategy for outbound 的本地化字符串。
/// </summary>
public static string TbSettingsDomainStrategy4Out {
get {
return ResourceManager.GetString("TbSettingsDomainStrategy4Out", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Double-click server make active 的本地化字符串。 /// 查找类似 Double-click server make active 的本地化字符串。
/// </summary> /// </summary>
@@ -3032,7 +3041,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 HTTP port=SOCKS port+1;Pac port=SOCKS port+4;API port=SOCKS port+5; 的本地化字符串。 /// 查找类似 http port = +1; Pac port = +4; *ray API port = +5; mihomo API port = +6; 的本地化字符串。
/// </summary> /// </summary>
public static string TbSettingsSocksPortTip { public static string TbSettingsSocksPortTip {
get { get {

View File

@@ -1037,7 +1037,7 @@
<value>Copy the font TTF/TTC file to the directory guiFonts, restart the settings</value> <value>Copy the font TTF/TTC file to the directory guiFonts, restart the settings</value>
</data> </data>
<data name="TbSettingsSocksPortTip" xml:space="preserve"> <data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>HTTP port=SOCKS port+1;Pac port=SOCKS port+4;API port=SOCKS port+5;</value> <value>http port = +1; Pac port = +4; *ray API port = +5; mihomo API port = +6;</value>
</data> </data>
<data name="TbSettingsStartBootTip" xml:space="preserve"> <data name="TbSettingsStartBootTip" xml:space="preserve">
<value>Set this with admin privileges, get admin privileges after startup</value> <value>Set this with admin privileges, get admin privileges after startup</value>
@@ -1297,4 +1297,7 @@
<data name="menuProxiesSelectActivity" xml:space="preserve"> <data name="menuProxiesSelectActivity" xml:space="preserve">
<value>Select active node (Enter)</value> <value>Select active node (Enter)</value>
</data> </data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Default domain strategy for outbound</value>
</data>
</root> </root>

View File

@@ -1042,9 +1042,6 @@
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve"> <data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>Скопируйте файл шрифта TTF/TTC в каталог guiFonts, перезапустите настройки</value> <value>Скопируйте файл шрифта TTF/TTC в каталог guiFonts, перезапустите настройки</value>
</data> </data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>HTTP port=socks port+1</value>
</data>
<data name="TbSettingsStartBootTip" xml:space="preserve"> <data name="TbSettingsStartBootTip" xml:space="preserve">
<value>Установите это с правами администратора</value> <value>Установите это с правами администратора</value>
</data> </data>

View File

@@ -1037,7 +1037,7 @@
<value>拷贝字体TTF/TTC文件到目录guiFonts重启设置</value> <value>拷贝字体TTF/TTC文件到目录guiFonts重启设置</value>
</data> </data>
<data name="TbSettingsSocksPortTip" xml:space="preserve"> <data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>http端口=socks端口+1Pac端口=socks端口+4API端口=socks端口+5</value> <value>http端口= +1Pac端口= +4*ray API端口= +5mihomo API端口= +6</value>
</data> </data>
<data name="TbSettingsStartBootTip" xml:space="preserve"> <data name="TbSettingsStartBootTip" xml:space="preserve">
<value>以管理员权限设置此项,在启动后获得管理员权限</value> <value>以管理员权限设置此项,在启动后获得管理员权限</value>
@@ -1294,4 +1294,7 @@
<data name="menuProxiesSelectActivity" xml:space="preserve"> <data name="menuProxiesSelectActivity" xml:space="preserve">
<value>设为活动节点 (Enter)</value> <value>设为活动节点 (Enter)</value>
</data> </data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Outbound默认解析策略</value>
</data>
</root> </root>

View File

@@ -1037,7 +1037,7 @@
<value>複製字型TTF/TTC文件到目錄guiFonts重啟設定</value> <value>複製字型TTF/TTC文件到目錄guiFonts重啟設定</value>
</data> </data>
<data name="TbSettingsSocksPortTip" xml:space="preserve"> <data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>HTTP埠=SOCKS埠+1</value> <value>http端口= +1Pac端口= +4*ray API端口= +5mihomo API端口= +6</value>
</data> </data>
<data name="TbSettingsStartBootTip" xml:space="preserve"> <data name="TbSettingsStartBootTip" xml:space="preserve">
<value>以管理員權限設定此項,在啟動後獲得管理員權限</value> <value>以管理員權限設定此項,在啟動後獲得管理員權限</value>

View File

@@ -0,0 +1,39 @@
#
# 配置文件内容不会被修改,混合行为只会发生在内存中
#
# 注意下面缩进请用支持yaml显示的编辑器打开
#
# 使用clash配置文件关键字则覆盖原配置
#
# removed-rules 循环匹配rules数组每行,符合则移除当前行 (此规则请放最前面)
#
# append-rules 数组合并至原配置rules数组后
# prepend-rules 数组合并至原配置rules数组前
# append-proxies 数组合并至原配置proxies数组后
# prepend-proxies 数组合并至原配置proxies数组前
# append-proxy-groups 数组合并至原配置proxy-groups数组后
# prepend-proxy-groups 数组合并至原配置proxy-groups数组前
# append-rule-providers 数组合并至原配置rule-providers数组后
# prepend-rule-providers 数组合并至原配置rule-providers数组前
#
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- 114.114.114.114
- 223.5.5.5
- 8.8.8.8
fallback: []
fake-ip-filter:
- +.stun.*.*
- +.stun.*.*.*
- +.stun.*.*.*.*
- +.stun.*.*.*.*.*
- "*.n.n.srv.nintendo.net"
- +.stun.playstation.net
- xbox.*.*.microsoft.com
- "*.*.xboxlive.com"
- "*.msftncsi.com"
- "*.msftconnecttest.com"
- WORKGROUP

View File

@@ -0,0 +1,7 @@
tun:
enable: true
stack: gvisor
dns-hijack:
- 0.0.0.0:53
auto-route: true
auto-detect-interface: true

View File

@@ -5,6 +5,11 @@
"bittorrent" "bittorrent"
] ]
}, },
{
"outboundTag": "block",
"port": "443",
"network": "udp"
},
{ {
"outboundTag": "block", "outboundTag": "block",
"domain": [ "domain": [
@@ -15,7 +20,7 @@
"outboundTag": "proxy", "outboundTag": "proxy",
"domain": [ "domain": [
"geosite:geolocation-!cn", "geosite:gfw",
"geosite:greatfire" "geosite:greatfire"
] ]
}, },

View File

@@ -1,4 +1,9 @@
[ [
{
"outboundTag": "block",
"port": "443",
"network": "udp"
},
{ {
"port": "0-65535", "port": "0-65535",
"outboundTag": "proxy" "outboundTag": "proxy"

View File

@@ -6,6 +6,11 @@
"domain:example-example2.com" "domain:example-example2.com"
] ]
}, },
{
"outboundTag": "block",
"port": "443",
"network": "udp"
},
{ {
"outboundTag": "block", "outboundTag": "block",
"domain": [ "domain": [

View File

@@ -2,7 +2,6 @@ using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Windows; using System.Windows;
@@ -15,11 +14,6 @@ namespace v2rayN.ViewModels
{ {
private static Config _config; private static Config _config;
static ClashConnectionsViewModel()
{
_config = LazyConfig.Instance.GetConfig();
}
private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>(); private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>();
public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems; public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems;
@@ -38,6 +32,7 @@ namespace v2rayN.ViewModels
public ClashConnectionsViewModel() public ClashConnectionsViewModel()
{ {
_config = LazyConfig.Instance.GetConfig();
SortingSelected = _config.clashUIItem.connectionsSorting; SortingSelected = _config.clashUIItem.connectionsSorting;
AutoRefresh = _config.clashUIItem.connectionsAutoRefresh; AutoRefresh = _config.clashUIItem.connectionsAutoRefresh;

View File

@@ -147,6 +147,7 @@ namespace v2rayN.ViewModels
public void ProxiesReload() public void ProxiesReload()
{ {
GetClashProxies(true); GetClashProxies(true);
ProxiesDelayTest();
} }
public void ProxiesClear() public void ProxiesClear()
@@ -336,7 +337,7 @@ namespace v2rayN.ViewModels
private ProxiesItem? TryGetProxy(string name) private ProxiesItem? TryGetProxy(string name)
{ {
if(proxies is null) if (proxies is null)
return null; return null;
proxies.TryGetValue(name, out ProxiesItem proxy2); proxies.TryGetValue(name, out ProxiesItem proxy2);
if (proxy2 != null) if (proxy2 != null)

View File

@@ -21,6 +21,7 @@ namespace v2rayN.ViewModels
[Reactive] public string normalDNS { get; set; } [Reactive] public string normalDNS { get; set; }
[Reactive] public string normalDNS2 { get; set; } [Reactive] public string normalDNS2 { get; set; }
[Reactive] public string tunDNS2 { get; set; } [Reactive] public string tunDNS2 { get; set; }
[Reactive] public string domainStrategy4Freedom2 { get; set; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; } public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
@@ -34,12 +35,13 @@ namespace v2rayN.ViewModels
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray); var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
useSystemHosts = item.useSystemHosts; useSystemHosts = item.useSystemHosts;
domainStrategy4Freedom = item?.domainStrategy4Freedom!; domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty;
normalDNS = item?.normalDNS!; normalDNS = item?.normalDNS ?? string.Empty;
var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
normalDNS2 = item2?.normalDNS!; normalDNS2 = item2?.normalDNS ?? string.Empty;
tunDNS2 = item2?.tunDNS!; tunDNS2 = item2?.tunDNS ?? string.Empty;
domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty;
SaveCmd = ReactiveCommand.Create(() => SaveCmd = ReactiveCommand.Create(() =>
{ {
@@ -105,6 +107,7 @@ namespace v2rayN.ViewModels
var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2)); item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2));
item2.domainStrategy4Freedom = domainStrategy4Freedom2;
ConfigHandler.SaveDNSItems(_config, item2); ConfigHandler.SaveDNSItems(_config, item2);
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);

View File

@@ -17,6 +17,7 @@ using System.Windows.Media;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Handler.Fmt; using v2rayN.Handler.Fmt;
using v2rayN.Handler.Statistics;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
using v2rayN.Views; using v2rayN.Views;
@@ -150,6 +151,7 @@ namespace v2rayN.ViewModels
//CheckUpdate //CheckUpdate
public ReactiveCommand<Unit, Unit> CheckUpdateNCmd { get; } public ReactiveCommand<Unit, Unit> CheckUpdateNCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateXrayCoreCmd { get; } public ReactiveCommand<Unit, Unit> CheckUpdateXrayCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateClashMetaCoreCmd { get; } public ReactiveCommand<Unit, Unit> CheckUpdateClashMetaCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateSingBoxCoreCmd { get; } public ReactiveCommand<Unit, Unit> CheckUpdateSingBoxCoreCmd { get; }
@@ -612,6 +614,10 @@ namespace v2rayN.ViewModels
private void UpdateHandler(bool notify, string msg) private void UpdateHandler(bool notify, string msg)
{ {
if (!_showInTaskbar)
{
return;
}
_noticeHandler?.SendMessage(msg); _noticeHandler?.SendMessage(msg);
if (notify) if (notify)
{ {
@@ -1514,11 +1520,11 @@ namespace v2rayN.ViewModels
{ {
BlReloadEnabled = true; BlReloadEnabled = true;
ShowCalshUI = (_config.runningCoreType is ECoreType.clash or ECoreType.clash_meta or ECoreType.mihomo); ShowCalshUI = (_config.runningCoreType is ECoreType.clash or ECoreType.clash_meta or ECoreType.mihomo);
if (ShowCalshUI) { if (ShowCalshUI)
{
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload(); Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
} }
})); }));
}); });
} }

View File

@@ -1,6 +1,6 @@
using v2rayN.ViewModels;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View File

@@ -1,13 +1,12 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashProxiesView" x:Class="v2rayN.Views.ClashProxiesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:v2rayN.Views"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converters="clr-namespace:v2rayN.Converters"
xmlns:resx="clr-namespace:v2rayN.Resx" xmlns:resx="clr-namespace:v2rayN.Resx"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:vms="clr-namespace:v2rayN.ViewModels"
d:DesignHeight="450" d:DesignHeight="450"

View File

@@ -1,8 +1,8 @@
using v2rayN.ViewModels;
using ReactiveUI; using ReactiveUI;
using Splat; using Splat;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View File

@@ -132,6 +132,19 @@
Style="{StaticResource DefButton}" /> Style="{StaticResource DefButton}" />
</StackPanel> </StackPanel>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<TextBlock
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
<ComboBox
x:Name="cmbdomainStrategy4Out"
Width="200"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
</StackPanel>
<Grid Margin="{StaticResource SettingItemMargin}"> <Grid Margin="{StaticResource SettingItemMargin}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" />

View File

@@ -34,12 +34,17 @@ namespace v2rayN.Views
{ {
cmbdomainStrategy4Freedom.Items.Add(it); cmbdomainStrategy4Freedom.Items.Add(it);
}); });
Global.SingboxDomainStrategy4Out.ForEach(it =>
{
cmbdomainStrategy4Out.Items.Add(it);
});
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.useSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.useSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.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.normalDNS2, v => v.txtnormalDNS2.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.tunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables);

View File

@@ -31,7 +31,7 @@ namespace v2rayN.Views
private void DelegateAppendText(string msg) private void DelegateAppendText(string msg)
{ {
Dispatcher.BeginInvoke(AppendText, DispatcherPriority.Send, msg); Dispatcher.BeginInvoke(AppendText, DispatcherPriority.ApplicationIdle, msg);
} }
public void AppendText(string msg) public void AppendText(string msg)

View File

@@ -1,12 +1,12 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleDetailsWindow" x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:resx="clr-namespace:v2rayN.Resx" xmlns:resx="clr-namespace:v2rayN.Resx"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:vms="clr-namespace:v2rayN.ViewModels"
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}" Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"

View File

@@ -1,12 +1,12 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleSettingWindow" x:Class="v2rayN.Views.RoutingRuleSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:resx="clr-namespace:v2rayN.Resx" xmlns:resx="clr-namespace:v2rayN.Resx"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:vms="clr-namespace:v2rayN.ViewModels"
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}" Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"

View File

@@ -10,15 +10,15 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>v2rayN.ico</ApplicationIcon> <ApplicationIcon>v2rayN.ico</ApplicationIcon>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright> <Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
<FileVersion>6.49</FileVersion> <FileVersion>6.51</FileVersion>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Downloader" Version="3.0.6" /> <PackageReference Include="Downloader" Version="3.1.2" />
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" /> <PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.0.131" /> <PackageReference Include="H.NotifyIcon.Wpf" Version="2.1.0" />
<PackageReference Include="QRCoder.Xaml" Version="1.5.1" /> <PackageReference Include="QRCoder.Xaml" Version="1.6.0" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" /> <PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
<PackageReference Include="TaskScheduler" Version="2.11.0" /> <PackageReference Include="TaskScheduler" Version="2.11.0" />
<PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.12" /> <PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.12" />
@@ -31,6 +31,8 @@
<ItemGroup> <ItemGroup>
<AdditionalFiles Include="app.manifest" /> <AdditionalFiles Include="app.manifest" />
<EmbeddedResource Include="Sample\clash_mixin_yaml" />
<EmbeddedResource Include="Sample\clash_tun_yaml" />
<EmbeddedResource Include="Sample\SingboxSampleOutbound" /> <EmbeddedResource Include="Sample\SingboxSampleOutbound" />
<EmbeddedResource Include="Sample\SingboxSampleClientConfig"> <EmbeddedResource Include="Sample\SingboxSampleClientConfig">
<CopyToOutputDirectory>Never</CopyToOutputDirectory> <CopyToOutputDirectory>Never</CopyToOutputDirectory>