diff --git a/v2rayN/v2rayN/App.xaml b/v2rayN/v2rayN/App.xaml index a5bafb0d..ddb2a4ba 100644 --- a/v2rayN/v2rayN/App.xaml +++ b/v2rayN/v2rayN/App.xaml @@ -11,7 +11,7 @@ diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs index c689e6d2..19ad0168 100644 --- a/v2rayN/v2rayN/Global.cs +++ b/v2rayN/v2rayN/Global.cs @@ -37,7 +37,6 @@ public const string v2raySampleInbound = "v2rayN.Sample.SampleInbound"; public const string CustomRoutingFileName = "v2rayN.Sample.custom_routing_"; - public const string TunSingboxFileName = "v2rayN.Sample.tun_singbox"; public const string TunSingboxDNSFileName = "v2rayN.Sample.tun_singbox_dns"; public const string TunSingboxInboundFileName = "v2rayN.Sample.tun_singbox_inbound"; public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules"; @@ -158,6 +157,7 @@ public static readonly List TunMtus = new() { "9000", "1500" }; public static readonly List TunStacks = new() { "gvisor", "system" }; public static readonly List PresetMsgFilters = new() { "proxy", "direct", "block", "" }; + public static readonly List SingboxMuxs = new() { "h2mux", "smux", "yamux", "" }; #endregion const diff --git a/v2rayN/v2rayN/Handler/ConfigHandler.cs b/v2rayN/v2rayN/Handler/ConfigHandler.cs index 1f7e6598..9584d799 100644 --- a/v2rayN/v2rayN/Handler/ConfigHandler.cs +++ b/v2rayN/v2rayN/Handler/ConfigHandler.cs @@ -132,7 +132,6 @@ namespace v2rayN.Handler config.tunModeItem = new TunModeItem { enableTun = false, - showWindow = true, mtu = 9000, }; } @@ -191,6 +190,18 @@ namespace v2rayN.Handler config.guiItem.statisticsFreshRate = 1; } + if (config.mux4Sbox == null) + { + config.mux4Sbox = new() + { + protocol = Global.SingboxMuxs[0], + max_connections = 4, + min_streams = 4, + max_streams = 0, + padding = true + }; + } + LazyConfig.Instance.SetConfig(config); return 0; } diff --git a/v2rayN/v2rayN/Handler/CoreConfigHandler.cs b/v2rayN/v2rayN/Handler/CoreConfigHandler.cs index 7e3aca47..c0dc712e 100644 --- a/v2rayN/v2rayN/Handler/CoreConfigHandler.cs +++ b/v2rayN/v2rayN/Handler/CoreConfigHandler.cs @@ -19,15 +19,16 @@ namespace v2rayN.Handler msg = ResUI.CheckServerSettings; return -1; } + var config = LazyConfig.Instance.GetConfig(); msg = ResUI.InitialConfiguration; if (node.configType == EConfigType.Custom) { return GenerateClientCustomConfig(node, fileName, out msg); } - else if (LazyConfig.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box) + else if (config.tunModeItem.enableTun || LazyConfig.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box) { - var configGenSingbox = new CoreConfigSingbox(LazyConfig.Instance.GetConfig()); + var configGenSingbox = new CoreConfigSingbox(config); if (configGenSingbox.GenerateClientConfigContent(node, out SingboxConfig? singboxConfig, out msg) != 0) { return -1; @@ -43,7 +44,7 @@ namespace v2rayN.Handler } else { - var coreConfigV2ray = new CoreConfigV2ray(LazyConfig.Instance.GetConfig()); + var coreConfigV2ray = new CoreConfigV2ray(config); if (coreConfigV2ray.GenerateClientConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0) { return -1; diff --git a/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs b/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs index 0916cd7b..9c5d2ede 100644 --- a/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs +++ b/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs @@ -52,7 +52,7 @@ namespace v2rayN.Handler dns(node, singboxConfig); - //statistic(singboxConfig); + statistic(singboxConfig); msg = string.Format(ResUI.SuccessfulConfiguration, ""); } @@ -258,6 +258,11 @@ namespace v2rayN.Handler outbound.flow = node.flow; outbound.packet_encoding = "xudp"; + + if (Utils.IsNullOrEmpty(node.flow)) + { + outboundMux(node, outbound); + } } else if (node.configType == EConfigType.Trojan) { @@ -288,10 +293,11 @@ namespace v2rayN.Handler var mux = new Multiplex4Sbox() { enabled = true, - protocol = "smux", - max_connections = 4, - min_streams = 4, - max_streams = 0, + protocol = _config.mux4Sbox.protocol, + max_connections = _config.mux4Sbox.max_connections, + min_streams = _config.mux4Sbox.min_streams, + max_streams = _config.mux4Sbox.max_streams, + padding = _config.mux4Sbox.padding }; outbound.multiplex = mux; } @@ -361,6 +367,13 @@ namespace v2rayN.Handler case "ws": transport.type = "ws"; transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path; + if (!Utils.IsNullOrEmpty(node.requestHost)) + { + transport.headers = new() + { + Host = node.requestHost + }; + } break; case "quic": @@ -446,38 +459,6 @@ namespace v2rayN.Handler } } } - - if (_config.tunModeItem.enableTun) - { - if (_config.tunModeItem.bypassMode) - { - //direct ips - if (_config.tunModeItem.directIP != null && _config.tunModeItem.directIP.Count > 0) - { - singboxConfig.route.rules.Add(new() { outbound = "direct", ip_cidr = _config.tunModeItem.directIP }); - } - //direct process - if (_config.tunModeItem.directProcess != null && _config.tunModeItem.directProcess.Count > 0) - { - singboxConfig.route.rules.Add(new() { outbound = "direct", process_name = _config.tunModeItem.directProcess }); - } - } - else - { - //proxy ips - if (_config.tunModeItem.proxyIP != null && _config.tunModeItem.proxyIP.Count > 0) - { - singboxConfig.route.rules.Add(new() { outbound = "proxy", ip_cidr = _config.tunModeItem.proxyIP }); - } - //proxy process - if (_config.tunModeItem.proxyProcess != null && _config.tunModeItem.proxyProcess.Count > 0) - { - singboxConfig.route.rules.Add(new() { outbound = "proxy", process_name = _config.tunModeItem.proxyProcess }); - } - - singboxConfig.route.rules.Add(new() { outbound = "direct", inbound = new() { "tun-in" } }); - } - } } catch (Exception ex) { @@ -546,6 +527,7 @@ namespace v2rayN.Handler rule.inbound = item.inboundTag; } var rule2 = Utils.DeepCopy(rule); + var rule3 = Utils.DeepCopy(rule); var hasDomainIp = false; if (item.domain?.Count > 0) @@ -568,6 +550,13 @@ namespace v2rayN.Handler hasDomainIp = true; } + if (_config.tunModeItem.enableTun && item.process?.Count > 0) + { + rule3.process_name = item.process; + rules.Add(rule3); + hasDomainIp = true; + } + if (!hasDomainIp) { rules.Add(rule); @@ -653,16 +642,9 @@ namespace v2rayN.Handler Dns4Sbox? dns4Sbox; if (_config.tunModeItem.enableTun) { - string tunDNS = String.Empty; - if (_config.tunModeItem.bypassMode) - { - tunDNS = _config.tunModeItem.directDNS; - } - else - { - tunDNS = _config.tunModeItem.proxyDNS; - } - if (tunDNS.IsNullOrEmpty() || Utils.FromJson(tunDNS) is null) + var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); + var tunDNS = item?.tunDNS; + if (string.IsNullOrWhiteSpace(tunDNS)) { tunDNS = Utils.GetEmbedText(Global.TunSingboxDNSFileName); } @@ -720,13 +702,18 @@ namespace v2rayN.Handler { singboxConfig.experimental = new Experimental4Sbox() { - v2ray_api = new V2ray_Api4Sbox() + //v2ray_api = new V2ray_Api4Sbox() + //{ + // listen = $"{Global.Loopback}:{Global.statePort}", + // stats = new Stats4Sbox() + // { + // enabled = true, + // } + //} + clash_api = new Clash_Api4Sbox() { - listen = $"{Global.Loopback}:{Global.statePort}", - stats = new Stats4Sbox() - { - enabled = true, - } + external_controller = $"{Global.Loopback}:{Global.statePort}", + store_selected = true } }; } diff --git a/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs b/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs index ea836079..b4ef45f8 100644 --- a/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs +++ b/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs @@ -96,24 +96,24 @@ namespace v2rayN.Handler { try { - v2rayConfig.inbounds = new List(); + v2rayConfig.inbounds = new List(); - Inbounds? inbound = GetInbound(_config.inbound[0], Global.InboundSocks, 0, true); + Inbounds4Ray? inbound = GetInbound(_config.inbound[0], Global.InboundSocks, 0, true); v2rayConfig.inbounds.Add(inbound); //http - Inbounds? inbound2 = GetInbound(_config.inbound[0], Global.InboundHttp, 1, false); + Inbounds4Ray? inbound2 = GetInbound(_config.inbound[0], Global.InboundHttp, 1, false); v2rayConfig.inbounds.Add(inbound2); if (_config.inbound[0].allowLANConn) { if (_config.inbound[0].newPort4LAN) { - Inbounds inbound3 = GetInbound(_config.inbound[0], Global.InboundSocks2, 2, true); + Inbounds4Ray inbound3 = GetInbound(_config.inbound[0], Global.InboundSocks2, 2, true); inbound3.listen = "0.0.0.0"; v2rayConfig.inbounds.Add(inbound3); - Inbounds inbound4 = GetInbound(_config.inbound[0], Global.InboundHttp2, 3, false); + Inbounds4Ray inbound4 = GetInbound(_config.inbound[0], Global.InboundHttp2, 3, false); inbound4.listen = "0.0.0.0"; v2rayConfig.inbounds.Add(inbound4); @@ -121,10 +121,10 @@ namespace v2rayN.Handler if (!Utils.IsNullOrEmpty(_config.inbound[0].user) && !Utils.IsNullOrEmpty(_config.inbound[0].pass)) { inbound3.settings.auth = "password"; - inbound3.settings.accounts = new List { new AccountsItem() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } }; + inbound3.settings.accounts = new List { new AccountsItem4Ray() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } }; inbound4.settings.auth = "password"; - inbound4.settings.accounts = new List { new AccountsItem() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } }; + inbound4.settings.accounts = new List { new AccountsItem4Ray() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } }; } } else @@ -141,7 +141,7 @@ namespace v2rayN.Handler return 0; } - private Inbounds? GetInbound(InItem inItem, string tag, int offset, bool bSocks) + private Inbounds4Ray? GetInbound(InItem inItem, string tag, int offset, bool bSocks) { string result = Utils.GetEmbedText(Global.v2raySampleInbound); if (Utils.IsNullOrEmpty(result)) @@ -149,7 +149,7 @@ namespace v2rayN.Handler return null; } - var inbound = Utils.FromJson(result); + var inbound = Utils.FromJson(result); if (inbound == null) { return null; @@ -187,7 +187,8 @@ namespace v2rayN.Handler { if (item.enabled) { - routingUserRule(item, v2rayConfig); + var item2 = Utils.FromJson(Utils.ToJson(item)); + routingUserRule(item2, v2rayConfig); } } } @@ -200,7 +201,8 @@ namespace v2rayN.Handler var rules = Utils.FromJson>(lockedItem.ruleSet); foreach (var item in rules) { - routingUserRule(item, v2rayConfig); + var item2 = Utils.FromJson(Utils.ToJson(item)); + routingUserRule(item2, v2rayConfig); } } } @@ -213,7 +215,7 @@ namespace v2rayN.Handler return 0; } - private int routingUserRule(RulesItem rules, V2rayConfig v2rayConfig) + private int routingUserRule(RulesItem4Ray rules, V2rayConfig v2rayConfig) { try { @@ -291,13 +293,13 @@ namespace v2rayN.Handler { try { - Outbounds outbound = v2rayConfig.outbounds[0]; + Outbounds4Ray outbound = v2rayConfig.outbounds[0]; if (node.configType == EConfigType.VMess) { - VnextItem vnextItem; + VnextItem4Ray vnextItem; if (outbound.settings.vnext.Count <= 0) { - vnextItem = new VnextItem(); + vnextItem = new VnextItem4Ray(); outbound.settings.vnext.Add(vnextItem); } else @@ -307,10 +309,10 @@ namespace v2rayN.Handler vnextItem.address = node.address; vnextItem.port = node.port; - UsersItem usersItem; + UsersItem4Ray usersItem; if (vnextItem.users.Count <= 0) { - usersItem = new UsersItem(); + usersItem = new UsersItem4Ray(); vnextItem.users.Add(usersItem); } else @@ -330,19 +332,17 @@ namespace v2rayN.Handler usersItem.security = Global.DefaultSecurity; } - //Mux - outbound.mux.enabled = _config.coreBasicItem.muxEnabled; - outbound.mux.concurrency = _config.coreBasicItem.muxEnabled ? 8 : -1; + outboundMux(node, outbound, _config.coreBasicItem.muxEnabled); outbound.protocol = Global.vmessProtocolLite; outbound.settings.servers = null; } else if (node.configType == EConfigType.Shadowsocks) { - ServersItem serversItem; + ServersItem4Ray serversItem; if (outbound.settings.servers.Count <= 0) { - serversItem = new ServersItem(); + serversItem = new ServersItem4Ray(); outbound.settings.servers.Add(serversItem); } else @@ -357,18 +357,17 @@ namespace v2rayN.Handler serversItem.ota = false; serversItem.level = 1; - outbound.mux.enabled = false; - outbound.mux.concurrency = -1; + outboundMux(node, outbound, false); outbound.protocol = Global.ssProtocolLite; outbound.settings.vnext = null; } else if (node.configType == EConfigType.Socks) { - ServersItem serversItem; + ServersItem4Ray serversItem; if (outbound.settings.servers.Count <= 0) { - serversItem = new ServersItem(); + serversItem = new ServersItem4Ray(); outbound.settings.servers.Add(serversItem); } else @@ -383,28 +382,27 @@ namespace v2rayN.Handler if (!Utils.IsNullOrEmpty(node.security) && !Utils.IsNullOrEmpty(node.id)) { - SocksUsersItem socksUsersItem = new() + SocksUsersItem4Ray socksUsersItem = new() { user = node.security, pass = node.id, level = 1 }; - serversItem.users = new List() { socksUsersItem }; + serversItem.users = new List() { socksUsersItem }; } - outbound.mux.enabled = false; - outbound.mux.concurrency = -1; + outboundMux(node, outbound, false); outbound.protocol = Global.socksProtocolLite; outbound.settings.vnext = null; } else if (node.configType == EConfigType.VLESS) { - VnextItem vnextItem; + VnextItem4Ray vnextItem; if (outbound.settings.vnext.Count <= 0) { - vnextItem = new VnextItem(); + vnextItem = new VnextItem4Ray(); outbound.settings.vnext.Add(vnextItem); } else @@ -414,10 +412,10 @@ namespace v2rayN.Handler vnextItem.address = node.address; vnextItem.port = node.port; - UsersItem usersItem; + UsersItem4Ray usersItem; if (vnextItem.users.Count <= 0) { - usersItem = new UsersItem(); + usersItem = new UsersItem4Ray(); vnextItem.users.Add(usersItem); } else @@ -429,9 +427,7 @@ namespace v2rayN.Handler usersItem.email = Global.userEMail; usersItem.encryption = node.security; - //Mux - outbound.mux.enabled = _config.coreBasicItem.muxEnabled; - outbound.mux.concurrency = _config.coreBasicItem.muxEnabled ? 8 : -1; + outboundMux(node, outbound, _config.coreBasicItem.muxEnabled); if (node.streamSecurity == Global.StreamSecurityReality || node.streamSecurity == Global.StreamSecurity) @@ -440,20 +436,23 @@ namespace v2rayN.Handler { usersItem.flow = node.flow; - outbound.mux.enabled = false; - outbound.mux.concurrency = -1; + outboundMux(node, outbound, false); } } + if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow)) + { + outboundMux(node, outbound, _config.coreBasicItem.muxEnabled); + } outbound.protocol = Global.vlessProtocolLite; outbound.settings.servers = null; } else if (node.configType == EConfigType.Trojan) { - ServersItem serversItem; + ServersItem4Ray serversItem; if (outbound.settings.servers.Count <= 0) { - serversItem = new ServersItem(); + serversItem = new ServersItem4Ray(); outbound.settings.servers.Add(serversItem); } else @@ -468,8 +467,7 @@ namespace v2rayN.Handler serversItem.ota = false; serversItem.level = 1; - outbound.mux.enabled = false; - outbound.mux.concurrency = -1; + outboundMux(node, outbound, false); outbound.protocol = Global.trojanProtocolLite; outbound.settings.vnext = null; @@ -483,7 +481,29 @@ namespace v2rayN.Handler return 0; } - private int boundStreamSettings(ProfileItem node, StreamSettings streamSettings) + private int outboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled) + { + try + { + if (enabled) + { + outbound.mux.enabled = true; + outbound.mux.concurrency = 8; + } + else + { + outbound.mux.enabled = false; + outbound.mux.concurrency = -1; + } + } + catch (Exception ex) + { + Utils.SaveLog(ex.Message, ex); + } + return 0; + } + + private int boundStreamSettings(ProfileItem node, StreamSettings4Ray streamSettings) { try { @@ -508,7 +528,7 @@ namespace v2rayN.Handler { streamSettings.security = node.streamSecurity; - TlsSettings tlsSettings = new() + TlsSettings4Ray tlsSettings = new() { allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure), alpn = node.GetAlpn(), @@ -530,7 +550,7 @@ namespace v2rayN.Handler { streamSettings.security = node.streamSecurity; - TlsSettings realitySettings = new() + TlsSettings4Ray realitySettings = new() { fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint, serverName = sni, @@ -546,7 +566,7 @@ namespace v2rayN.Handler switch (node.GetNetwork()) { case "kcp": - KcpSettings kcpSettings = new() + KcpSettings4Ray kcpSettings = new() { mtu = _config.kcpItem.mtu, tti = _config.kcpItem.tti @@ -558,7 +578,7 @@ namespace v2rayN.Handler kcpSettings.congestion = _config.kcpItem.congestion; kcpSettings.readBufferSize = _config.kcpItem.readBufferSize; kcpSettings.writeBufferSize = _config.kcpItem.writeBufferSize; - kcpSettings.header = new Header + kcpSettings.header = new Header4Ray { type = node.headerType }; @@ -570,8 +590,8 @@ namespace v2rayN.Handler break; //ws case "ws": - WsSettings wsSettings = new(); - wsSettings.headers = new Headers(); + WsSettings4Ray wsSettings = new(); + wsSettings.headers = new Headers4Ray(); string path = node.path; if (!string.IsNullOrWhiteSpace(host)) { @@ -590,7 +610,7 @@ namespace v2rayN.Handler break; //h2 case "h2": - HttpSettings httpSettings = new(); + HttpSettings4Ray httpSettings = new(); if (!string.IsNullOrWhiteSpace(host)) { @@ -603,11 +623,11 @@ namespace v2rayN.Handler break; //quic case "quic": - QuicSettings quicsettings = new() + QuicSettings4Ray quicsettings = new() { security = host, key = node.path, - header = new Header + header = new Header4Ray { type = node.headerType } @@ -627,7 +647,7 @@ namespace v2rayN.Handler break; case "grpc": - GrpcSettings grpcSettings = new() + GrpcSettings4Ray grpcSettings = new() { serviceName = node.path, multiMode = (node.headerType == Global.GrpcmultiMode), @@ -643,9 +663,9 @@ namespace v2rayN.Handler //tcp if (node.headerType == Global.TcpHeaderHttp) { - TcpSettings tcpSettings = new() + TcpSettings4Ray tcpSettings = new() { - header = new Header + header = new Header4Ray { type = node.headerType } @@ -718,7 +738,7 @@ namespace v2rayN.Handler //} } //servers.Add("localhost"); - v2rayConfig.dns = new Mode.Dns + v2rayConfig.dns = new Mode.Dns4Ray { servers = servers }; @@ -736,13 +756,13 @@ namespace v2rayN.Handler if (_config.guiItem.enableStatistics) { string tag = Global.InboundAPITagName; - API apiObj = new(); - Policy policyObj = new(); - SystemPolicy policySystemSetting = new(); + API4Ray apiObj = new(); + Policy4Ray policyObj = new(); + SystemPolicy4Ray policySystemSetting = new(); string[] services = { "StatsService" }; - v2rayConfig.stats = new Stats(); + v2rayConfig.stats = new Stats4Ray(); apiObj.tag = tag; apiObj.services = services.ToList(); @@ -755,8 +775,8 @@ namespace v2rayN.Handler if (!v2rayConfig.inbounds.Exists(item => item.tag == tag)) { - Inbounds apiInbound = new(); - Inboundsettings apiInboundSettings = new(); + Inbounds4Ray apiInbound = new(); + Inboundsettings4Ray apiInboundSettings = new(); apiInbound.tag = tag; apiInbound.listen = Global.Loopback; apiInbound.port = Global.statePort; @@ -768,12 +788,13 @@ namespace v2rayN.Handler if (!v2rayConfig.routing.rules.Exists(item => item.outboundTag == tag)) { - RulesItem apiRoutingRule = new() + RulesItem4Ray apiRoutingRule = new() { inboundTag = new List { tag }, outboundTag = tag, type = "field" }; + v2rayConfig.routing.rules.Add(apiRoutingRule); } } @@ -873,7 +894,7 @@ namespace v2rayN.Handler it.allowTest = true; //inbound - Inbounds inbound = new() + Inbounds4Ray inbound = new() { listen = Global.Loopback, port = port, @@ -905,7 +926,7 @@ namespace v2rayN.Handler v2rayConfig.outbounds.Add(v2rayConfigCopy.outbounds[0]); //rule - RulesItem rule = new() + RulesItem4Ray rule = new() { inboundTag = new List { inbound.tag }, outboundTag = v2rayConfigCopy.outbounds[0].tag, diff --git a/v2rayN/v2rayN/Handler/CoreHandler.cs b/v2rayN/v2rayN/Handler/CoreHandler.cs index 24cf5255..5960980e 100644 --- a/v2rayN/v2rayN/Handler/CoreHandler.cs +++ b/v2rayN/v2rayN/Handler/CoreHandler.cs @@ -12,7 +12,6 @@ namespace v2rayN.Handler internal class CoreHandler { private Config _config; - private CoreInfo? _coreInfo; private Process? _process; private Process? _processPre; private Action _updateFunc; @@ -35,11 +34,6 @@ namespace v2rayN.Handler return; } - if (SetCore(node) != 0) - { - ShowMsg(false, ResUI.CheckServerSettings); - return; - } string fileName = Utils.GetConfigPath(Global.coreConfigFileName); if (CoreConfigHandler.GenerateClientConfig(node, fileName, out string msg, out string content) != 0) { @@ -74,30 +68,13 @@ namespace v2rayN.Handler { try { + bool hasProc = false; if (_process != null) { KillProcess(_process); _process.Dispose(); _process = null; - } - else - { - if (_coreInfo == null || _coreInfo.coreExes == null) - { - return; - } - foreach (string vName in _coreInfo.coreExes) - { - Process[] existing = Process.GetProcessesByName(vName); - foreach (Process p in existing) - { - string? path = p.MainModule?.FileName; - if (path == $"{Utils.GetBinPath(vName, _coreInfo.coreType)}.exe") - { - KillProcess(p); - } - } - } + hasProc = true; } if (_processPre != null) @@ -105,6 +82,31 @@ namespace v2rayN.Handler KillProcess(_processPre); _processPre.Dispose(); _processPre = null; + hasProc = true; + } + + if (!hasProc) + { + var coreInfos = LazyConfig.Instance.GetCoreInfos(); + foreach (var it in coreInfos) + { + if (it.coreType == ECoreType.v2rayN) + { + continue; + } + foreach (string vName in it.coreExes) + { + Process[] existing = Process.GetProcessesByName(vName); + foreach (Process p in existing) + { + string? path = p.MainModule?.FileName; + if (path == $"{Utils.GetBinPath(vName, it.coreType)}.exe") + { + KillProcess(p); + } + } + } + } } } catch (Exception ex) @@ -152,7 +154,19 @@ namespace v2rayN.Handler { ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString())); - var proc = RunProcess(node, _coreInfo, "", ShowMsg); + ECoreType coreType; + if (node.configType != EConfigType.Custom && _config.tunModeItem.enableTun) + { + coreType = ECoreType.sing_box; + } + else + { + coreType = LazyConfig.Instance.GetCoreType(node, node.configType); + } + var coreInfo = LazyConfig.Instance.GetCoreInfo(coreType); + + var displayLog = node.configType != EConfigType.Custom || node.displayLog; + var proc = RunProcess(node, coreInfo, "", displayLog, ShowMsg); if (proc is null) { return; @@ -162,21 +176,20 @@ namespace v2rayN.Handler //start a socks service if (_process != null && !_process.HasExited) { - if ((node.configType == EConfigType.Custom && node.preSocksPort > 0) - || (node.configType != EConfigType.Custom && _coreInfo.coreType != ECoreType.sing_box && _config.tunModeItem.enableTun)) + if ((node.configType == EConfigType.Custom && node.preSocksPort > 0)) { var itemSocks = new ProfileItem() { coreType = ECoreType.sing_box, configType = EConfigType.Socks, address = Global.Loopback, - port = node.preSocksPort > 0 ? node.preSocksPort : LazyConfig.Instance.GetLocalPort(Global.InboundSocks) + port = node.preSocksPort }; string fileName2 = Utils.GetConfigPath(Global.corePreConfigFileName); if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0) { - var coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box); - var proc2 = RunProcess(node, coreInfo, $" -c {Global.corePreConfigFileName}", ShowMsg); + var coreInfo2 = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box); + var proc2 = RunProcess(node, coreInfo2, $" -c {Global.corePreConfigFileName}", true, ShowMsg); if (proc2 is not null) { _processPre = proc2; @@ -257,26 +270,9 @@ namespace v2rayN.Handler _updateFunc(updateToTrayTooltip, msg); } - private int SetCore(ProfileItem node) - { - if (node == null) - { - return -1; - } - var coreType = LazyConfig.Instance.GetCoreType(node, node.configType); - - _coreInfo = LazyConfig.Instance.GetCoreInfo(coreType); - - if (_coreInfo == null) - { - return -1; - } - return 0; - } - #region Process - private Process? RunProcess(ProfileItem node, CoreInfo coreInfo, string configPath, Action update) + private Process? RunProcess(ProfileItem node, CoreInfo coreInfo, string configPath, bool displayLog, Action update) { try { @@ -285,7 +281,6 @@ namespace v2rayN.Handler { return null; } - var displayLog = node.configType != EConfigType.Custom || node.displayLog; Process proc = new() { StartInfo = new ProcessStartInfo diff --git a/v2rayN/v2rayN/Handler/MainFormHandler.cs b/v2rayN/v2rayN/Handler/MainFormHandler.cs index bae28515..4390a6a9 100644 --- a/v2rayN/v2rayN/Handler/MainFormHandler.cs +++ b/v2rayN/v2rayN/Handler/MainFormHandler.cs @@ -208,8 +208,8 @@ namespace v2rayN.Handler { updateHandle.UpdateGeoFileAll(config, (bool success, string msg) => { - update(false, msg); - }); + update(false, msg); + }); autoUpdateGeoTime = dtNow; } } diff --git a/v2rayN/v2rayN/Handler/StatisticsHandler.cs b/v2rayN/v2rayN/Handler/StatisticsHandler.cs index 23f18ba1..4ca0ae02 100644 --- a/v2rayN/v2rayN/Handler/StatisticsHandler.cs +++ b/v2rayN/v2rayN/Handler/StatisticsHandler.cs @@ -1,7 +1,4 @@ -using Grpc.Core; -using Grpc.Net.Client; -using ProtosLib.Statistics; -using System.Net; +using System.Net; using System.Net.Sockets; using v2rayN.Base; using v2rayN.Mode; @@ -10,51 +7,40 @@ namespace v2rayN.Handler { internal class StatisticsHandler { - private Mode.Config config_; - private GrpcChannel _channel; - private StatsService.StatsServiceClient _client; - private bool _exitFlag; + private Config _config; private ServerStatItem? _serverStatItem; private List _lstServerStat; - public List ServerStat => _lstServerStat; - private Action _updateFunc; + private StatisticsV2ray? _statisticsV2Ray; + private StatisticsSingbox? _statisticsSingbox; - public bool Enable - { - get; set; - } + public List ServerStat => _lstServerStat; + public bool Enable { get; set; } - public StatisticsHandler(Mode.Config config, Action update) + public StatisticsHandler(Config config, Action update) { - config_ = config; + _config = config; Enable = config.guiItem.enableStatistics; + if (!Enable) + { + return; + } + _updateFunc = update; - _exitFlag = false; Init(); - GrpcInit(); + Global.statePort = GetFreePort(); - Task.Run(Run); - } - - private void GrpcInit() - { - if (_channel == null) - { - Global.statePort = GetFreePort(); - - _channel = GrpcChannel.ForAddress($"{Global.httpProtocol}{Global.Loopback}:{Global.statePort}"); - _client = new StatsService.StatsServiceClient(_channel); - } + _statisticsV2Ray = new StatisticsV2ray(config, UpdateServerStat); + _statisticsSingbox = new StatisticsSingbox(config, UpdateServerStat); } public void Close() { try { - _exitFlag = true; - //channel_.ShutdownAsync(); + _statisticsV2Ray?.Close(); + _statisticsSingbox?.Close(); } catch (Exception ex) { @@ -62,57 +48,6 @@ namespace v2rayN.Handler } } - public async void Run() - { - while (!_exitFlag) - { - try - { - if (Enable && _channel.State == ConnectivityState.Ready) - { - QueryStatsResponse? res = null; - try - { - res = await _client.QueryStatsAsync(new QueryStatsRequest() { Pattern = "", Reset = true }); - } - catch (Exception ex) - { - //Utils.SaveLog(ex.Message, ex); - } - - if (res != null) - { - GetServerStatItem(config_.indexId); - ParseOutput(res.Stat, out ServerSpeedItem server); - - if (server.proxyUp != 0 || server.proxyDown != 0) - { - _serverStatItem.todayUp += server.proxyUp; - _serverStatItem.todayDown += server.proxyDown; - _serverStatItem.totalUp += server.proxyUp; - _serverStatItem.totalDown += server.proxyDown; - } - if (Global.ShowInTaskbar) - { - server.indexId = config_.indexId; - server.todayUp = _serverStatItem.todayUp; - server.todayDown = _serverStatItem.todayDown; - server.totalUp = _serverStatItem.totalUp; - server.totalDown = _serverStatItem.totalDown; - _updateFunc(server); - } - } - } - var sleep = config_.guiItem.statisticsFreshRate < 1 ? 1 : config_.guiItem.statisticsFreshRate; - Thread.Sleep(1000 * sleep); - await _channel.ConnectAsync(); - } - catch - { - } - } - } - public void ClearAllServerStatistics() { SqliteHelper.Instance.Execute($"delete from ServerStatItem "); @@ -142,6 +77,28 @@ namespace v2rayN.Handler _lstServerStat = SqliteHelper.Instance.Table().ToList(); } + private void UpdateServerStat(ServerSpeedItem server) + { + GetServerStatItem(_config.indexId); + + if (server.proxyUp != 0 || server.proxyDown != 0) + { + _serverStatItem.todayUp += server.proxyUp; + _serverStatItem.todayDown += server.proxyDown; + _serverStatItem.totalUp += server.proxyUp; + _serverStatItem.totalDown += server.proxyDown; + } + if (Global.ShowInTaskbar) + { + server.indexId = _config.indexId; + server.todayUp = _serverStatItem.todayUp; + server.todayDown = _serverStatItem.todayDown; + server.totalUp = _serverStatItem.totalUp; + server.totalDown = _serverStatItem.totalDown; + _updateFunc(server); + } + } + private void GetServerStatItem(string indexId) { long ticks = DateTime.Now.Date.Ticks; @@ -177,71 +134,28 @@ namespace v2rayN.Handler } } - private void ParseOutput(Google.Protobuf.Collections.RepeatedField source, out ServerSpeedItem server) - { - server = new(); - try - { - foreach (Stat stat in source) - { - string name = stat.Name; - long value = stat.Value / 1024; //KByte - string[] nStr = name.Split(">>>".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - string type = ""; - - name = name.Trim(); - - name = nStr[1]; - type = nStr[3]; - - if (name == Global.agentTag) - { - if (type == "uplink") - { - server.proxyUp = value; - } - else if (type == "downlink") - { - server.proxyDown = value; - } - } - else if (name == Global.directTag) - { - if (type == "uplink") - { - server.directUp = value; - } - else if (type == "downlink") - { - server.directDown = value; - } - } - } - } - catch (Exception ex) - { - //Utils.SaveLog(ex.Message, ex); - } - } - private int GetFreePort() { - int defaultPort = 28123; try { - // TCP stack please do me a favor - TcpListener l = new(IPAddress.Loopback, 0); - l.Start(); - int port = ((IPEndPoint)l.LocalEndpoint).Port; - l.Stop(); - return port; + int defaultPort = 9090; + if (!Utils.PortInUse(defaultPort)) + { + return defaultPort; + } + for (int i = 0; i < 3; i++) + { + TcpListener l = new(IPAddress.Loopback, 0); + l.Start(); + int port = ((IPEndPoint)l.LocalEndpoint).Port; + l.Stop(); + return port; + } } - catch (Exception ex) + catch { - // in case access denied - Utils.SaveLog(ex.Message, ex); - return defaultPort; } + return 69090; } } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Handler/StatisticsSingbox.cs b/v2rayN/v2rayN/Handler/StatisticsSingbox.cs new file mode 100644 index 00000000..15fea2d9 --- /dev/null +++ b/v2rayN/v2rayN/Handler/StatisticsSingbox.cs @@ -0,0 +1,127 @@ +using System.Net.WebSockets; +using System.Text; +using v2rayN.Mode; + +namespace v2rayN.Handler +{ + internal class StatisticsSingbox + { + private Config _config; + private bool _exitFlag; + private ClientWebSocket? webSocket; + private string url = string.Empty; + private Action _updateFunc; + + public StatisticsSingbox(Config config, Action update) + { + _config = config; + _updateFunc = update; + _exitFlag = false; + + Task.Run(() => Run()); + } + + private async void Init() + { + Thread.Sleep(5000); + + try + { + url = $"ws://{Global.Loopback}:{Global.statePort}/traffic"; + + if (webSocket == null) + { + webSocket = new ClientWebSocket(); + await webSocket.ConnectAsync(new Uri(url), CancellationToken.None); + } + } + catch { } + } + + public void Close() + { + try + { + _exitFlag = true; + if (webSocket != null) + { + webSocket.Abort(); + webSocket = null; + } + } + catch (Exception ex) + { + Utils.SaveLog(ex.Message, ex); + } + } + + private async void Run() + { + Init(); + + while (!_exitFlag) + { + try + { + if (webSocket != null) + { + if (webSocket.State == WebSocketState.Aborted + || webSocket.State == WebSocketState.Closed) + { + webSocket.Abort(); + webSocket = null; + Init(); + } + + if (webSocket.State != WebSocketState.Open) + { + continue; + } + + var buffer = new byte[1024]; + var res = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); + while (!res.CloseStatus.HasValue) + { + var result = Encoding.UTF8.GetString(buffer, 0, res.Count); + if (!string.IsNullOrEmpty(result)) + { + ParseOutput(result, out ulong up, out ulong down); + + _updateFunc(new ServerSpeedItem() + { + proxyUp = (long)(up / 1000), + proxyDown = (long)(down / 1000) + }); + } + res = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); + } + } + } + catch + { + } + finally + { + Thread.Sleep(1000); + } + } + } + + private void ParseOutput(string source, out ulong up, out ulong down) + { + up = 0; down = 0; + try + { + var trafficItem = Utils.FromJson(source); + if (trafficItem != null) + { + up = trafficItem.up; + down = trafficItem.down; + } + } + catch + { + } + } + } +} \ No newline at end of file diff --git a/v2rayN/v2rayN/Handler/StatisticsV2ray.cs b/v2rayN/v2rayN/Handler/StatisticsV2ray.cs new file mode 100644 index 00000000..cc4a065b --- /dev/null +++ b/v2rayN/v2rayN/Handler/StatisticsV2ray.cs @@ -0,0 +1,120 @@ +using Grpc.Core; +using Grpc.Net.Client; +using ProtosLib.Statistics; +using v2rayN.Mode; + +namespace v2rayN.Handler +{ + internal class StatisticsV2ray + { + private Mode.Config _config; + private GrpcChannel _channel; + private StatsService.StatsServiceClient _client; + private bool _exitFlag; + private Action _updateFunc; + + public StatisticsV2ray(Mode.Config config, Action update) + { + _config = config; + _updateFunc = update; + _exitFlag = false; + + GrpcInit(); + + Task.Run(Run); + } + + private void GrpcInit() + { + if (_channel == null) + { + _channel = GrpcChannel.ForAddress($"{Global.httpProtocol}{Global.Loopback}:{Global.statePort}"); + _client = new StatsService.StatsServiceClient(_channel); + } + } + + public void Close() + { + _exitFlag = true; + } + + private async void Run() + { + while (!_exitFlag) + { + try + { + if (_channel.State == ConnectivityState.Ready) + { + QueryStatsResponse? res = null; + try + { + res = await _client.QueryStatsAsync(new QueryStatsRequest() { Pattern = "", Reset = true }); + } + catch + { + } + + if (res != null) + { + ParseOutput(res.Stat, out ServerSpeedItem server); + _updateFunc(server); + } + } + var sleep = _config.guiItem.statisticsFreshRate < 1 ? 1 : _config.guiItem.statisticsFreshRate; + Thread.Sleep(1000 * sleep); + await _channel.ConnectAsync(); + } + catch + { + } + } + } + + private void ParseOutput(Google.Protobuf.Collections.RepeatedField source, out ServerSpeedItem server) + { + server = new(); + try + { + foreach (Stat stat in source) + { + string name = stat.Name; + long value = stat.Value / 1024; //KByte + string[] nStr = name.Split(">>>".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + string type = ""; + + name = name.Trim(); + + name = nStr[1]; + type = nStr[3]; + + if (name == Global.agentTag) + { + if (type == "uplink") + { + server.proxyUp = value; + } + else if (type == "downlink") + { + server.proxyDown = value; + } + } + else if (name == Global.directTag) + { + if (type == "uplink") + { + server.directUp = value; + } + else if (type == "downlink") + { + server.directDown = value; + } + } + } + } + catch + { + } + } + } +} \ No newline at end of file diff --git a/v2rayN/v2rayN/Handler/TunHandler.cs b/v2rayN/v2rayN/Handler/TunHandler.cs deleted file mode 100644 index d446bb82..00000000 --- a/v2rayN/v2rayN/Handler/TunHandler.cs +++ /dev/null @@ -1,361 +0,0 @@ -using System.Diagnostics; -using System.IO; -using System.Reactive.Linq; -using v2rayN.Handler; -using v2rayN.Mode; -using v2rayN.Resx; - -namespace v2rayN.Base -{ - public sealed class TunHandler - { - private static readonly Lazy _instance = new(() => new()); - public static TunHandler Instance => _instance.Value; - private string _tunConfigName = "tunConfig.json"; - private static Config _config; - private CoreInfo coreInfo; - private Process? _process; - private static int _socksPort; - private static bool _needRestart = true; - private static bool _isRunning = false; - - public TunHandler() - { - _config = LazyConfig.Instance.GetConfig(); - - Observable.Interval(TimeSpan.FromSeconds(10)) - .Subscribe(x => - { - if (_isRunning && _config.tunModeItem.enableTun) - { - if (_process == null || _process.HasExited) - { - if (Init() == false) - { - return; - } - CoreStart(); - Utils.SaveLog("Tun mode monitors restart"); - } - } - }); - } - - public void Start() - { - var socksPort = LazyConfig.Instance.GetLocalPort(Global.InboundSocks); - - if (socksPort == _socksPort - && _process != null - && !_process.HasExited) - { - _needRestart = false; - } - - _socksPort = socksPort; - - if (_needRestart) - { - CoreStop(); - if (Init() == false) - { - return; - } - CoreStartTest(); - CoreStart(); - } - } - - public void Stop() - { - CoreStop(); - } - - private bool Init() - { - coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box); - //Template - string configStr = Utils.GetEmbedText(Global.TunSingboxFileName); - if (!Utils.IsNullOrEmpty(_config.tunModeItem.customTemplate) && File.Exists(_config.tunModeItem.customTemplate)) - { - var customTemplate = File.ReadAllText(_config.tunModeItem.customTemplate); - if (!Utils.IsNullOrEmpty(customTemplate)) - { - configStr = customTemplate; - } - } - if (Utils.IsNullOrEmpty(configStr)) - { - return false; - } - - //settings - if (_config.tunModeItem.mtu <= 0) - { - _config.tunModeItem.mtu = Convert.ToInt32(Global.TunMtus[0]); - } - if (Utils.IsNullOrEmpty(_config.tunModeItem.stack)) - { - _config.tunModeItem.stack = Global.TunStacks[0]; - } - configStr = configStr.Replace("$mtu$", $"{_config.tunModeItem.mtu}"); - configStr = configStr.Replace("$strict_route$", $"{_config.tunModeItem.strictRoute.ToString().ToLower()}"); - configStr = configStr.Replace("$stack$", $"{_config.tunModeItem.stack}"); - - //logs - configStr = configStr.Replace("$log_disabled$", $"{(!_config.tunModeItem.enabledLog).ToString().ToLower()}"); - if (_config.tunModeItem.showWindow) - { - configStr = configStr.Replace("$log_output$", $""); - } - else - { - var dtNow = DateTime.Now; - var log_output = $"\"output\": \"{Utils.GetLogPath($"singbox_{dtNow:yyyy-MM-dd}.txt")}\", "; - configStr = configStr.Replace("$log_output$", $"{log_output.Replace(@"\", @"\\")}"); - } - - //port - configStr = configStr.Replace("$socksPort$", $"{_socksPort}"); - - //dns - string dnsObject = String.Empty; - if (_config.tunModeItem.bypassMode) - { - dnsObject = _config.tunModeItem.directDNS; - } - else - { - dnsObject = _config.tunModeItem.proxyDNS; - } - if (dnsObject.IsNullOrEmpty() || Utils.ParseJson(dnsObject)?.ContainsKey("servers") == false) - { - dnsObject = Utils.GetEmbedText(Global.TunSingboxDNSFileName); - } - configStr = configStr.Replace("$dns_object$", dnsObject); - - //exe - routingDirectExe(out List lstDnsExe, out List lstDirectExe); - string strDns = string.Join("\",\"", lstDnsExe.ToArray()); - configStr = configStr.Replace("$dnsProcessName$", $"\"{strDns}\""); - - string strDirect = string.Join("\",\"", lstDirectExe.ToArray()); - configStr = configStr.Replace("$directProcessName$", $"\"{strDirect}\""); - - if (_config.tunModeItem.bypassMode) - { - //direct ips - if (_config.tunModeItem.directIP != null && _config.tunModeItem.directIP.Count > 0) - { - var ips = new { outbound = "direct", ip_cidr = _config.tunModeItem.directIP }; - configStr = configStr.Replace("$ruleDirectIPs$", "," + Utils.ToJson(ips)); - } - //direct process - if (_config.tunModeItem.directProcess != null && _config.tunModeItem.directProcess.Count > 0) - { - var process = new { outbound = "direct", process_name = _config.tunModeItem.directProcess }; - configStr = configStr.Replace("$ruleDirectProcess$", "," + Utils.ToJson(process)); - } - } - else - { - //proxy ips - if (_config.tunModeItem.proxyIP != null && _config.tunModeItem.proxyIP.Count > 0) - { - var ips = new { outbound = "proxy", ip_cidr = _config.tunModeItem.proxyIP }; - configStr = configStr.Replace("$ruleProxyIPs$", "," + Utils.ToJson(ips)); - } - //proxy process - if (_config.tunModeItem.proxyProcess != null && _config.tunModeItem.proxyProcess.Count > 0) - { - var process = new { outbound = "proxy", process_name = _config.tunModeItem.proxyProcess }; - configStr = configStr.Replace("$ruleProxyProcess$", "," + Utils.ToJson(process)); - } - - var final = new { outbound = "direct", inbound = "tun-in" }; - configStr = configStr.Replace("$ruleFinally$", "," + Utils.ToJson(final)); - } - configStr = configStr.Replace("$ruleDirectIPs$", ""); - configStr = configStr.Replace("$ruleDirectProcess$", ""); - configStr = configStr.Replace("$ruleProxyIPs$", ""); - configStr = configStr.Replace("$ruleProxyProcess$", ""); - configStr = configStr.Replace("$ruleFinally$", ""); - - File.WriteAllText(Utils.GetConfigPath(_tunConfigName), configStr); - - return true; - } - - private void routingDirectExe(out List lstDnsExe, out List lstDirectExe) - { - lstDnsExe = new(); - lstDirectExe = new(); - var coreInfos = LazyConfig.Instance.GetCoreInfos(); - foreach (var it in coreInfos) - { - if (it.coreType == ECoreType.v2rayN) - { - continue; - } - foreach (var it2 in it.coreExes) - { - if (!lstDnsExe.Contains(it2) && it.coreType != ECoreType.sing_box) - { - lstDnsExe.Add($"{it2}.exe"); - } - - if (!lstDirectExe.Contains(it2)) - { - lstDirectExe.Add($"{it2}.exe"); - } - } - } - } - - private void CoreStop() - { - try - { - _isRunning = false; - if (_process != null) - { - KillProcess(_process); - _process.Dispose(); - _process = null; - _needRestart = true; - } - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - } - - private string CoreFindexe() - { - string fileName = string.Empty; - foreach (string name in coreInfo.coreExes) - { - string vName = $"{name}.exe"; - vName = Utils.GetBinPath(vName, coreInfo.coreType); - if (File.Exists(vName)) - { - fileName = vName; - break; - } - } - if (Utils.IsNullOrEmpty(fileName)) - { - string msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.coreType), string.Join(", ", coreInfo.coreExes.ToArray()), coreInfo.coreUrl); - Utils.SaveLog(msg); - } - return fileName; - } - - private void CoreStart() - { - try - { - string fileName = CoreFindexe(); - if (Utils.IsNullOrEmpty(fileName)) - { - return; - } - var showWindow = _config.tunModeItem.showWindow; - Process p = new() - { - StartInfo = new ProcessStartInfo - { - FileName = fileName, - Arguments = $"run -c \"{Utils.GetConfigPath(_tunConfigName)}\"", - WorkingDirectory = Utils.GetConfigPath(), - UseShellExecute = showWindow, - CreateNoWindow = !showWindow, - //RedirectStandardError = !showWindow, - Verb = "runas", - } - }; - p.Start(); - _process = p; - _isRunning = true; - if (p.WaitForExit(1000)) - { - //if (showWindow) - //{ - throw new Exception("start tun mode fail"); - //} - //else - //{ - // throw new Exception(p.StandardError.ReadToEnd()); - //} - } - - Global.processJob.AddProcess(p.Handle); - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - } - - private void KillProcess(Process p) - { - try - { - p.CloseMainWindow(); - p.WaitForExit(100); - if (!p.HasExited) - { - p.Kill(); - p.WaitForExit(100); - } - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - } - - private int CoreStartTest() - { - Utils.SaveLog("Tun mode configuration file test start"); - try - { - string fileName = CoreFindexe(); - if (fileName == "") - { - return -1; - } - Process p = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = fileName, - Arguments = $"run -c \"{Utils.GetConfigPath(_tunConfigName)}\"", - WorkingDirectory = Utils.GetConfigPath(), - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardError = true, - Verb = "runas", - } - }; - p.Start(); - if (p.WaitForExit(2000)) - { - throw new Exception(p.StandardError.ReadToEnd()); - } - KillProcess(p); - return 0; - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - return -1; - } - finally - { - Utils.SaveLog("Tun mode configuration file test end"); - } - } - } -} \ No newline at end of file diff --git a/v2rayN/v2rayN/Mode/Config.cs b/v2rayN/v2rayN/Mode/Config.cs index 978508e8..f6639b93 100644 --- a/v2rayN/v2rayN/Mode/Config.cs +++ b/v2rayN/v2rayN/Mode/Config.cs @@ -27,6 +27,7 @@ public UIItem uiItem { get; set; } public ConstItem constItem { get; set; } public SpeedTestItem speedTestItem { get; set; } + public Mux4Sbox mux4Sbox { get; set; } public List inbound { get; set; } public List globalHotkeys { get; set; } public List coreTypeItem { get; set; } diff --git a/v2rayN/v2rayN/Mode/ConfigItems.cs b/v2rayN/v2rayN/Mode/ConfigItems.cs index 4ab9d3ce..22817422 100644 --- a/v2rayN/v2rayN/Mode/ConfigItems.cs +++ b/v2rayN/v2rayN/Mode/ConfigItems.cs @@ -161,19 +161,9 @@ namespace v2rayN.Mode public class TunModeItem { public bool enableTun { get; set; } - public bool showWindow { get; set; } - public bool enabledLog { get; set; } public bool strictRoute { get; set; } public string stack { get; set; } public int mtu { get; set; } - public string customTemplate { get; set; } - public bool bypassMode { get; set; } = true; - public List directIP { get; set; } - public List directProcess { get; set; } - public string directDNS { get; set; } - public List proxyIP { get; set; } - public List proxyProcess { get; set; } - public string proxyDNS { get; set; } } [Serializable] @@ -191,6 +181,7 @@ namespace v2rayN.Mode /// 域名解析策略 /// public string domainStrategy { get; set; } + public string domainStrategy4Singbox { get; set; } public string domainMatcher { get; set; } @@ -205,4 +196,14 @@ namespace v2rayN.Mode public int Width { get; set; } public int Index { get; set; } } + + [Serializable] + public class Mux4Sbox + { + public string protocol { get; set; } + public int max_connections { get; set; } + public int min_streams { get; set; } + public int max_streams { get; set; } + public bool padding { get; set; } + } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Mode/DNSItem.cs b/v2rayN/v2rayN/Mode/DNSItem.cs index bf21822b..fef779ec 100644 --- a/v2rayN/v2rayN/Mode/DNSItem.cs +++ b/v2rayN/v2rayN/Mode/DNSItem.cs @@ -12,8 +12,7 @@ namespace v2rayN.Mode public bool enabled { get; set; } = true; public ECoreType coreType { get; set; } public string? normalDNS { get; set; } - public string? directDNS { get; set; } - public string? proxyDNS { get; set; } + public string? tunDNS { get; set; } public string? domainStrategy4Freedom { get; set; } } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Mode/RulesItem.cs b/v2rayN/v2rayN/Mode/RulesItem.cs index e9a5395c..1985c258 100644 --- a/v2rayN/v2rayN/Mode/RulesItem.cs +++ b/v2rayN/v2rayN/Mode/RulesItem.cs @@ -18,6 +18,8 @@ public List protocol { get; set; } + public List process { get; set; } + public bool enabled { get; set; } = true; } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Mode/ServerSpeedItem.cs b/v2rayN/v2rayN/Mode/ServerSpeedItem.cs index 8f953159..c51f6d11 100644 --- a/v2rayN/v2rayN/Mode/ServerSpeedItem.cs +++ b/v2rayN/v2rayN/Mode/ServerSpeedItem.cs @@ -23,4 +23,18 @@ get; set; } } + + [Serializable] + public class TrafficItem + { + public ulong up + { + get; set; + } + + public ulong down + { + get; set; + } + } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Mode/SingboxConfig.cs b/v2rayN/v2rayN/Mode/SingboxConfig.cs index fc8a09df..ed5ada0e 100644 --- a/v2rayN/v2rayN/Mode/SingboxConfig.cs +++ b/v2rayN/v2rayN/Mode/SingboxConfig.cs @@ -127,6 +127,7 @@ public int max_connections { get; set; } public int min_streams { get; set; } public int max_streams { get; set; } + public bool padding { get; set; } } public class Utls4Sbox @@ -147,12 +148,19 @@ public string type { get; set; } public List? host { get; set; } public string? path { get; set; } + public Headers4Sbox? headers { get; set; } + public string service_name { get; set; } public string idle_timeout { get; set; } public string ping_timeout { get; set; } public bool? permit_without_stream { get; set; } } + public class Headers4Sbox + { + public string? Host { get; set; } + } + public class Server4Sbox { public string tag { get; set; } @@ -165,6 +173,7 @@ public class Experimental4Sbox { public V2ray_Api4Sbox v2ray_api { get; set; } + public Clash_Api4Sbox clash_api { get; set; } } public class V2ray_Api4Sbox @@ -173,6 +182,12 @@ public Stats4Sbox stats { get; set; } } + public class Clash_Api4Sbox + { + public string external_controller { get; set; } + public bool store_selected { get; set; } + } + public class Stats4Sbox { public bool enabled { get; set; } diff --git a/v2rayN/v2rayN/Mode/V2rayConfig.cs b/v2rayN/v2rayN/Mode/V2rayConfig.cs index a9888312..b20f526d 100644 --- a/v2rayN/v2rayN/Mode/V2rayConfig.cs +++ b/v2rayN/v2rayN/Mode/V2rayConfig.cs @@ -11,28 +11,28 @@ namespace v2rayN.Mode /// /// 日志配置 /// - public Log log { get; set; } + public Log4Ray log { get; set; } /// /// 传入连接配置 /// - public List inbounds { get; set; } + public List inbounds { get; set; } /// /// 传出连接配置 /// - public List outbounds { get; set; } + public List outbounds { get; set; } /// /// 统计需要, 空对象 /// - public Stats stats { get; set; } + public Stats4Ray stats { get; set; } /// - public API api { get; set; } + public API4Ray api { get; set; } /// - public Policy policy; + public Policy4Ray policy; /// /// DNS 配置 @@ -42,30 +42,30 @@ namespace v2rayN.Mode /// /// 路由配置 /// - public Routing routing { get; set; } + public Routing4Ray routing { get; set; } } - public class Stats + public class Stats4Ray { }; - public class API + public class API4Ray { public string tag { get; set; } public List services { get; set; } } - public class Policy + public class Policy4Ray { - public SystemPolicy system; + public SystemPolicy4Ray system; } - public class SystemPolicy + public class SystemPolicy4Ray { public bool statsOutboundUplink; public bool statsOutboundDownlink; } - public class Log + public class Log4Ray { /// /// @@ -83,7 +83,7 @@ namespace v2rayN.Mode public string loglevel { get; set; } } - public class Inbounds + public class Inbounds4Ray { public string tag { get; set; } @@ -105,20 +105,20 @@ namespace v2rayN.Mode /// /// /// - public Sniffing sniffing { get; set; } + public Sniffing4Ray sniffing { get; set; } /// /// /// - public Inboundsettings settings { get; set; } + public Inboundsettings4Ray settings { get; set; } /// /// /// - public StreamSettings streamSettings { get; set; } + public StreamSettings4Ray streamSettings { get; set; } } - public class Inboundsettings + public class Inboundsettings4Ray { /// /// @@ -143,7 +143,7 @@ namespace v2rayN.Mode /// /// /// - public List clients { get; set; } + public List clients { get; set; } /// /// VLESS @@ -152,10 +152,10 @@ namespace v2rayN.Mode public bool allowTransparent { get; set; } - public List accounts { get; set; } + public List accounts { get; set; } } - public class UsersItem + public class UsersItem4Ray { /// /// @@ -188,14 +188,14 @@ namespace v2rayN.Mode public string flow { get; set; } } - public class Sniffing + public class Sniffing4Ray { public bool enabled { get; set; } public List destOverride { get; set; } public bool routeOnly { get; set; } } - public class Outbounds + public class Outbounds4Ray { /// /// 默认值agentout @@ -210,35 +210,35 @@ namespace v2rayN.Mode /// /// /// - public Outboundsettings settings { get; set; } + public Outboundsettings4Ray settings { get; set; } /// /// /// - public StreamSettings streamSettings { get; set; } + public StreamSettings4Ray streamSettings { get; set; } /// /// /// - public Mux mux { get; set; } + public Mux4Ray mux { get; set; } } - public class Outboundsettings + public class Outboundsettings4Ray { /// /// /// - public List vnext { get; set; } + public List vnext { get; set; } /// /// /// - public List servers { get; set; } + public List servers { get; set; } /// /// /// - public Response response { get; set; } + public Response4Ray response { get; set; } /// /// @@ -251,7 +251,7 @@ namespace v2rayN.Mode public int? userLevel { get; set; } } - public class VnextItem + public class VnextItem4Ray { /// /// @@ -266,10 +266,10 @@ namespace v2rayN.Mode /// /// /// - public List users { get; set; } + public List users { get; set; } } - public class ServersItem + public class ServersItem4Ray { /// /// @@ -314,10 +314,10 @@ namespace v2rayN.Mode /// /// /// - public List users { get; set; } + public List users { get; set; } } - public class SocksUsersItem + public class SocksUsersItem4Ray { /// /// @@ -335,7 +335,7 @@ namespace v2rayN.Mode public int level { get; set; } } - public class Mux + public class Mux4Ray { /// /// @@ -348,7 +348,7 @@ namespace v2rayN.Mode public int concurrency { get; set; } } - public class Response + public class Response4Ray { /// /// @@ -356,7 +356,7 @@ namespace v2rayN.Mode public string type { get; set; } } - public class Dns + public class Dns4Ray { /// /// @@ -364,7 +364,7 @@ namespace v2rayN.Mode public List servers { get; set; } } - public class Routing + public class Routing4Ray { /// /// @@ -379,10 +379,28 @@ namespace v2rayN.Mode /// /// /// - public List rules { get; set; } + public List rules { get; set; } } - public class StreamSettings + [Serializable] + public class RulesItem4Ray + { + public string type { get; set; } + + public string port { get; set; } + + public List inboundTag { get; set; } + + public string outboundTag { get; set; } + + public List ip { get; set; } + + public List domain { get; set; } + + public List protocol { get; set; } + } + + public class StreamSettings4Ray { /// /// @@ -397,45 +415,45 @@ namespace v2rayN.Mode /// /// /// - public TlsSettings tlsSettings { get; set; } + public TlsSettings4Ray tlsSettings { get; set; } /// /// Tcp传输额外设置 /// - public TcpSettings tcpSettings { get; set; } + public TcpSettings4Ray tcpSettings { get; set; } /// /// Kcp传输额外设置 /// - public KcpSettings kcpSettings { get; set; } + public KcpSettings4Ray kcpSettings { get; set; } /// /// ws传输额外设置 /// - public WsSettings wsSettings { get; set; } + public WsSettings4Ray wsSettings { get; set; } /// /// h2传输额外设置 /// - public HttpSettings httpSettings { get; set; } + public HttpSettings4Ray httpSettings { get; set; } /// /// QUIC /// - public QuicSettings quicSettings { get; set; } + public QuicSettings4Ray quicSettings { get; set; } /// /// VLESS only /// - public TlsSettings realitySettings { get; set; } + public TlsSettings4Ray realitySettings { get; set; } /// /// grpc /// - public GrpcSettings grpcSettings { get; set; } + public GrpcSettings4Ray grpcSettings { get; set; } } - public class TlsSettings + public class TlsSettings4Ray { /// /// 是否允许不安全连接(用于客户端) @@ -460,15 +478,15 @@ namespace v2rayN.Mode public string? spiderX { get; set; } } - public class TcpSettings + public class TcpSettings4Ray { /// /// 数据包头部伪装设置 /// - public Header header { get; set; } + public Header4Ray header { get; set; } } - public class Header + public class Header4Ray { /// /// 伪装 @@ -486,7 +504,7 @@ namespace v2rayN.Mode public object response { get; set; } } - public class KcpSettings + public class KcpSettings4Ray { /// /// @@ -526,7 +544,7 @@ namespace v2rayN.Mode /// /// /// - public Header header { get; set; } + public Header4Ray header { get; set; } /// /// @@ -534,7 +552,7 @@ namespace v2rayN.Mode public string seed { get; set; } } - public class WsSettings + public class WsSettings4Ray { /// /// @@ -544,10 +562,10 @@ namespace v2rayN.Mode /// /// /// - public Headers headers { get; set; } + public Headers4Ray headers { get; set; } } - public class Headers + public class Headers4Ray { /// /// @@ -561,7 +579,7 @@ namespace v2rayN.Mode public string UserAgent { get; set; } } - public class HttpSettings + public class HttpSettings4Ray { /// /// @@ -574,7 +592,7 @@ namespace v2rayN.Mode public List host { get; set; } } - public class QuicSettings + public class QuicSettings4Ray { /// /// @@ -589,10 +607,10 @@ namespace v2rayN.Mode /// /// /// - public Header header { get; set; } + public Header4Ray header { get; set; } } - public class GrpcSettings + public class GrpcSettings4Ray { public string serviceName { get; set; } public bool multiMode { get; set; } @@ -602,7 +620,7 @@ namespace v2rayN.Mode public int initial_windows_size { get; set; } } - public class AccountsItem + public class AccountsItem4Ray { /// /// diff --git a/v2rayN/v2rayN/Resx/ResUI.Designer.cs b/v2rayN/v2rayN/Resx/ResUI.Designer.cs index c09993d2..6c208a7c 100644 --- a/v2rayN/v2rayN/Resx/ResUI.Designer.cs +++ b/v2rayN/v2rayN/Resx/ResUI.Designer.cs @@ -1853,7 +1853,7 @@ namespace v2rayN.Resx { } /// - /// 查找类似 Domain and ip are auto sorted when saving 的本地化字符串。 + /// 查找类似 Domain, ip, process are auto sorted when saving 的本地化字符串。 /// public static string TbAutoSort { get { @@ -1961,7 +1961,7 @@ namespace v2rayN.Resx { } /// - /// 查找类似 Sing-box domain strategy 的本地化字符串。 + /// 查找类似 sing-box domain strategy 的本地化字符串。 /// public static string TbdomainStrategy4Singbox { get { @@ -2167,6 +2167,33 @@ namespace v2rayN.Resx { } } + /// + /// 查找类似 Domain 的本地化字符串。 + /// + public static string TbRoutingRuleDomain { + get { + return ResourceManager.GetString("TbRoutingRuleDomain", resourceCulture); + } + } + + /// + /// 查找类似 IP or IP CIDR 的本地化字符串。 + /// + public static string TbRoutingRuleIP { + get { + return ResourceManager.GetString("TbRoutingRuleIP", resourceCulture); + } + } + + /// + /// 查找类似 Full process name (Tun mode) 的本地化字符串。 + /// + public static string TbRoutingRuleProcess { + get { + return ResourceManager.GetString("TbRoutingRuleProcess", resourceCulture); + } + } + /// /// 查找类似 3.Block Domain or IP 的本地化字符串。 /// @@ -2348,7 +2375,7 @@ namespace v2rayN.Resx { } /// - /// 查找类似 Sing-box DNS settings 的本地化字符串。 + /// 查找类似 sing-box DNS settings 的本地化字符串。 /// public static string TbSettingsCoreDnsSingbox { get { @@ -2572,6 +2599,15 @@ namespace v2rayN.Resx { } } + /// + /// 查找类似 sing-box Mux Protocol 的本地化字符串。 + /// + public static string TbSettingsMux4SboxProtocol { + get { + return ResourceManager.GetString("TbSettingsMux4SboxProtocol", resourceCulture); + } + } + /// /// 查找类似 Turn on Mux Multiplexing 的本地化字符串。 /// @@ -2770,15 +2806,6 @@ namespace v2rayN.Resx { } } - /// - /// 查找类似 Enable: If no route matches, the final proxy 的本地化字符串。 - /// - public static string TbSettingsTunModeBypassModeTip { - get { - return ResourceManager.GetString("TbSettingsTunModeBypassModeTip", resourceCulture); - } - } - /// /// 查找类似 Custom Template 的本地化字符串。 /// @@ -2951,7 +2978,7 @@ namespace v2rayN.Resx { } /// - /// 查找类似 * After setting this value, an socks service will be started using Sing-box to provide functions such as speed display 的本地化字符串。 + /// 查找类似 * After setting this value, an socks service will be started using sing-box to provide functions such as speed display 的本地化字符串。 /// public static string TipPreSocksPort { get { diff --git a/v2rayN/v2rayN/Resx/ResUI.fa-Ir.resx b/v2rayN/v2rayN/Resx/ResUI.fa-Ir.resx index 6bd3a9ec..39f211d2 100644 --- a/v2rayN/v2rayN/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/v2rayN/Resx/ResUI.fa-Ir.resx @@ -701,7 +701,7 @@ txtPreSocksPort - * After setting this value, an socks service will be started using Sing-box to provide functions such as speed display + * After setting this value, an socks service will be started using sing-box to provide functions such as speed display Browse diff --git a/v2rayN/v2rayN/Resx/ResUI.resx b/v2rayN/v2rayN/Resx/ResUI.resx index d4c2f302..1625e449 100644 --- a/v2rayN/v2rayN/Resx/ResUI.resx +++ b/v2rayN/v2rayN/Resx/ResUI.resx @@ -701,7 +701,7 @@ txtPreSocksPort - * After setting this value, an socks service will be started using Sing-box to provide functions such as speed display + * After setting this value, an socks service will be started using sing-box to provide functions such as speed display Browse @@ -941,7 +941,7 @@ RoutingRuleDetailsSetting - Domain and ip are auto sorted when saving + Domain, ip, process are auto sorted when saving Ruleobject Doc @@ -1057,9 +1057,6 @@ Bypass Mode - - Enable: If no route matches, the final proxy - SpeedTest Single Timeout Value @@ -1118,7 +1115,7 @@ DNS Settings - Sing-box DNS settings + sing-box DNS settings Please fill in DNS Structure, Click to view the document @@ -1127,6 +1124,18 @@ Click to import default DNS config - Sing-box domain strategy + sing-box domain strategy + + + sing-box Mux Protocol + + + Full process name (Tun mode) + + + IP or IP CIDR + + + Domain \ No newline at end of file diff --git a/v2rayN/v2rayN/Resx/ResUI.ru.resx b/v2rayN/v2rayN/Resx/ResUI.ru.resx index 9e2309d8..99be3632 100644 --- a/v2rayN/v2rayN/Resx/ResUI.ru.resx +++ b/v2rayN/v2rayN/Resx/ResUI.ru.resx @@ -701,7 +701,7 @@ txtPreSocksPort - * После установки этого значения служба socks будет запущена с использованием Sing-box для обеспечения таких функций, как отображение скорости + * После установки этого значения служба socks будет запущена с использованием sing-box для обеспечения таких функций, как отображение скорости Просмотр diff --git a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx index da34e169..0363c124 100644 --- a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx @@ -701,7 +701,7 @@ Socks端口 - * 自定义配置的Socks端口值,可不设置;当设置此值后,将使用Sing-box额外启动一个前置Socks服务,提供分流和速度显示等功能 + * 自定义配置的Socks端口值,可不设置;当设置此值后,将使用sing-box额外启动一个前置Socks服务,提供分流和速度显示等功能 浏览 @@ -941,7 +941,7 @@ 路由规则详情设置 - 保存时Domain和IP自动排序 + 保存时Domain, IP, 进程名 自动排序 规则详细说明文档 @@ -1057,9 +1057,6 @@ 绕行模式 - - 启用:路由无匹配则最终代理 - 测速单个超时值 @@ -1115,7 +1112,7 @@ DNS设置 - Sing-box DNS设置 + sing-box DNS设置 请填写 DNS JSON 结构,点击查看文档 @@ -1124,6 +1121,18 @@ 点击导入默认DNS配置 - Sing-box域名解析策略 + sing-box域名解析策略 + + + sing-box Mux 多路复用协议 + + + 进程名全称 (Tun模式) + + + Domain + + + IP 或 IP CIDR \ No newline at end of file diff --git a/v2rayN/v2rayN/Sample/tun_singbox b/v2rayN/v2rayN/Sample/tun_singbox deleted file mode 100644 index 1710b0e3..00000000 --- a/v2rayN/v2rayN/Sample/tun_singbox +++ /dev/null @@ -1,96 +0,0 @@ -{ - "log": { - "disabled": $log_disabled$, - "level": "debug", - $log_output$ - "timestamp": true - }, - "dns": $dns_object$ , - "inbounds": [ - { - "type": "tun", - "tag": "tun-in", - "interface_name": "singbox_tun", - "inet4_address": "172.19.0.1/30", - - "mtu": $mtu$, - "auto_route": true, - "strict_route": $strict_route$, - "stack": "$stack$", - "sniff": true - } - ], - "outbounds": [ - { - "type": "socks", - "tag": "proxy", - "udp_fragment": true, - "server": "127.0.0.1", - "server_port": $socksPort$ - }, - { - "type": "block", - "tag": "block" - }, - { - "type": "direct", - "tag": "direct" - }, - { - "type": "dns", - "tag": "dns_out" - } - ], - "route": { - "auto_detect_interface": true, - "rules": [ - { - "inbound": "dns_in", - "outbound": "dns_out" - }, - { - "protocol": "dns", - "outbound": "dns_out" - }, - { - "network": "udp", - "port": [ - 135, - 137, - 138, - 139, - 5353 - ], - "outbound": "block" - }, - { - "ip_cidr": [ - "224.0.0.0/3", - "ff00::/8" - ], - "outbound": "block" - }, - { - "source_ip_cidr": [ - "224.0.0.0/3", - "ff00::/8" - ], - "outbound": "block" - }, - { - "port": 53, - "process_name": [ $dnsProcessName$], - "outbound": "dns_out" - }, - { - "process_name": [ $directProcessName$], - "outbound": "direct" - } - $ruleDirectIPs$ - $ruleDirectProcess$ - $ruleProxyIPs$ - $ruleProxyProcess$ - $ruleFinally$ - ] - } -} \ No newline at end of file diff --git a/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs index c1e1ee6c..3ead0dcf 100644 --- a/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs @@ -18,6 +18,7 @@ namespace v2rayN.ViewModels [Reactive] public string domainStrategy4Freedom { get; set; } [Reactive] public string normalDNS { get; set; } [Reactive] public string normalDNS2 { get; set; } + [Reactive] public string tunDNS2 { get; set; } public ReactiveCommand SaveCmd { get; } public ReactiveCommand ImportDefConfig4V2rayCmd { get; } @@ -35,6 +36,7 @@ namespace v2rayN.ViewModels var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); normalDNS2 = item2?.normalDNS!; + tunDNS2 = item2?.tunDNS!; SaveCmd = ReactiveCommand.Create(() => { @@ -49,6 +51,7 @@ namespace v2rayN.ViewModels ImportDefConfig4SingboxCmd = ReactiveCommand.Create(() => { normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); + tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName); }); Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); @@ -80,6 +83,15 @@ namespace v2rayN.ViewModels return; } } + if (!Utils.IsNullOrEmpty(tunDNS2)) + { + var obj2 = Utils.FromJson(tunDNS2); + if (obj2 == null) + { + UI.Show(ResUI.FillCorrectDNSText); + return; + } + } var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray); item.domainStrategy4Freedom = domainStrategy4Freedom; @@ -88,6 +100,7 @@ namespace v2rayN.ViewModels var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); item2.normalDNS = Utils.ToJson(Utils.ParseJson(normalDNS2)); + item2.tunDNS = Utils.ToJson(Utils.ParseJson(tunDNS2)); ConfigHandler.SaveDNSItems(_config, item2); _noticeHandler?.Enqueue(ResUI.OperationSuccess); diff --git a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs index 1e90d7aa..7a250e96 100644 --- a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs @@ -1617,18 +1617,6 @@ namespace v2rayN.ViewModels } } - private void TunModeSwitch() - { - if (EnableTun) - { - TunHandler.Instance.Start(); - } - else - { - TunHandler.Instance.Stop(); - } - } - #endregion System proxy and Routings #region UI diff --git a/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs index 3f74de06..b1d9e803 100644 --- a/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs @@ -31,6 +31,7 @@ namespace v2rayN.ViewModels [Reactive] public bool defAllowInsecure { get; set; } [Reactive] public string defFingerprint { get; set; } [Reactive] public string defUserAgent { get; set; } + [Reactive] public string mux4SboxProtocol { get; set; } #endregion Core @@ -78,20 +79,9 @@ namespace v2rayN.ViewModels #region Tun mode - [Reactive] public bool TunShowWindow { get; set; } - [Reactive] public bool TunEnabledLog { get; set; } [Reactive] public bool TunStrictRoute { get; set; } [Reactive] public string TunStack { get; set; } [Reactive] public int TunMtu { get; set; } - [Reactive] public string TunCustomTemplate { get; set; } - [Reactive] public bool TunBypassMode { get; set; } - [Reactive] public bool TunBypassMode2 { get; set; } - [Reactive] public string TunDirectIP { get; set; } - [Reactive] public string TunDirectProcess { get; set; } - [Reactive] public string TunDirectDNS { get; set; } - [Reactive] public string TunProxyIP { get; set; } - [Reactive] public string TunProxyProcess { get; set; } - [Reactive] public string TunProxyDNS { get; set; } #endregion Tun mode @@ -131,6 +121,7 @@ namespace v2rayN.ViewModels defAllowInsecure = _config.coreBasicItem.defAllowInsecure; defFingerprint = _config.coreBasicItem.defFingerprint; defUserAgent = _config.coreBasicItem.defUserAgent; + mux4SboxProtocol = _config.mux4Sbox.protocol; #endregion Core @@ -178,22 +169,9 @@ namespace v2rayN.ViewModels #region Tun mode - TunShowWindow = _config.tunModeItem.showWindow; - TunEnabledLog = _config.tunModeItem.enabledLog; TunStrictRoute = _config.tunModeItem.strictRoute; TunStack = _config.tunModeItem.stack; TunMtu = _config.tunModeItem.mtu; - TunCustomTemplate = _config.tunModeItem.customTemplate; - TunBypassMode = _config.tunModeItem.bypassMode; - TunDirectIP = Utils.List2String(_config.tunModeItem.directIP, true); - TunDirectProcess = Utils.List2String(_config.tunModeItem.directProcess, true); - TunDirectDNS = _config.tunModeItem.directDNS; - TunProxyIP = Utils.List2String(_config.tunModeItem.proxyIP, true); - TunProxyProcess = Utils.List2String(_config.tunModeItem.proxyProcess, true); - TunProxyDNS = _config.tunModeItem.proxyDNS; - this.WhenAnyValue( - x => x.TunBypassMode) - .Subscribe(c => TunBypassMode2 = !TunBypassMode); #endregion Tun mode @@ -298,6 +276,7 @@ namespace v2rayN.ViewModels _config.coreBasicItem.defAllowInsecure = defAllowInsecure; _config.coreBasicItem.defFingerprint = defFingerprint; _config.coreBasicItem.defUserAgent = defUserAgent; + _config.mux4Sbox.protocol = mux4SboxProtocol; //Kcp //_config.kcpItem.mtu = Kcpmtu; @@ -338,19 +317,9 @@ namespace v2rayN.ViewModels _config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol; //tun mode - _config.tunModeItem.showWindow = TunShowWindow; - _config.tunModeItem.enabledLog = TunEnabledLog; _config.tunModeItem.strictRoute = TunStrictRoute; _config.tunModeItem.stack = TunStack; _config.tunModeItem.mtu = TunMtu; - _config.tunModeItem.customTemplate = TunCustomTemplate; - _config.tunModeItem.bypassMode = TunBypassMode; - _config.tunModeItem.directIP = Utils.String2List(Utils.Convert2Comma(TunDirectIP)); - _config.tunModeItem.directProcess = Utils.String2List(Utils.Convert2Comma(TunDirectProcess)); - _config.tunModeItem.directDNS = Utils.ToJson(Utils.ParseJson(TunDirectDNS)); - _config.tunModeItem.proxyIP = Utils.String2List(Utils.Convert2Comma(TunProxyIP)); - _config.tunModeItem.proxyProcess = Utils.String2List(Utils.Convert2Comma(TunProxyProcess)); - _config.tunModeItem.proxyDNS = Utils.ToJson(Utils.ParseJson(TunProxyDNS)); //coreType SaveCoreType(); diff --git a/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs b/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs index 6ba2cfe2..a21486aa 100644 --- a/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs @@ -28,6 +28,9 @@ namespace v2rayN.ViewModels [Reactive] public string IP { get; set; } + [Reactive] + public string Process { get; set; } + [Reactive] public bool AutoSort { get; set; } @@ -53,6 +56,7 @@ namespace v2rayN.ViewModels Domain = Utils.List2String(SelectedSource.domain, true); IP = Utils.List2String(SelectedSource.ip, true); + Process = Utils.List2String(SelectedSource.process, true); SaveCmd = ReactiveCommand.Create(() => { @@ -66,16 +70,19 @@ namespace v2rayN.ViewModels { Domain = Utils.Convert2Comma(Domain); IP = Utils.Convert2Comma(IP); + Process = Utils.Convert2Comma(Process); if (AutoSort) { SelectedSource.domain = Utils.String2ListSorted(Domain); SelectedSource.ip = Utils.String2ListSorted(IP); + SelectedSource.process = Utils.String2ListSorted(Process); } else { SelectedSource.domain = Utils.String2List(Domain); SelectedSource.ip = Utils.String2List(IP); + SelectedSource.process = Utils.String2List(Process); } SelectedSource.protocol = ProtocolItems?.ToList(); SelectedSource.inboundTag = InboundTagItems?.ToList(); diff --git a/v2rayN/v2rayN/Views/DNSSettingWindow.xaml b/v2rayN/v2rayN/Views/DNSSettingWindow.xaml index c19509ef..4fe14cbb 100644 --- a/v2rayN/v2rayN/Views/DNSSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/DNSSettingWindow.xaml @@ -4,7 +4,6 @@ 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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:reactiveui="http://reactiveui.net" xmlns:resx="clr-namespace:v2rayN.Resx" @@ -115,18 +114,46 @@ Cursor="Hand" Style="{StaticResource DefButton}" /> - + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs index c20943fe..f35c3b18 100644 --- a/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs @@ -29,6 +29,7 @@ namespace v2rayN.Views 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.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.tunDNS2, v => v.txttunDNS2.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); diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml b/v2rayN/v2rayN/Views/MainWindow.xaml index 0f2ed7f0..b994f28f 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml +++ b/v2rayN/v2rayN/Views/MainWindow.xaml @@ -235,7 +235,7 @@ + Header="sing-box Core" /> + @@ -291,6 +292,21 @@ Margin="{StaticResource SettingItemMargin}" Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.TbSettingsDefUserAgentTips}" /> + + + @@ -776,13 +792,6 @@ - - - - - - - @@ -790,34 +799,6 @@ - - - - - - - - - -