Compare commits

...

13 Commits
6.41 ... 6.43

Author SHA1 Message Date
2dust
e0cea929ea Up 6.43 2024-04-10 13:52:38 +08:00
2dust
315f4c35f0 Code clean 2024-04-10 13:32:50 +08:00
2dust
d961ea22a6 Built-in routing rule set upgraded to V2 2024-04-10 10:50:52 +08:00
2dust
5c0c07c78f Migrate geosite & geoip to rule sets (sing-box) 2024-04-10 08:42:53 +08:00
2dust
bba93a0fb7 Added tls fragment support (Xray-core)
https://github.com/2dust/v2rayN/issues/4900
2024-04-08 17:06:48 +08:00
2dust
5683df2fc0 Added outbound HTTP support (support group prefix proxy)
https://github.com/2dust/v2rayN/discussions/4550
2024-04-08 14:02:56 +08:00
2dust
b5cb9ce67e Set autoHideStartup default value is false 2024-04-05 17:24:53 +08:00
2dust
06a32dc895 Adjust sing-box dns default example 2024-04-05 11:05:45 +08:00
2dust
dff12a8a3a fix
https://github.com/2dust/v2rayN/issues/4928
2024-04-05 11:04:35 +08:00
2dust
dc3f07ee84 Bug fix 2024-04-03 09:51:07 +08:00
2dust
1aef49ee11 Custom configuration file to use Xray prefix in non-Tun mode
https://github.com/2dust/v2rayN/issues/4855
2024-04-01 08:22:14 +08:00
2dust
ee3159b00e Update 6.42 2024-03-31 17:26:02 +08:00
2dust
86d2c307f1 Bug fix 2024-03-31 17:23:33 +08:00
34 changed files with 599 additions and 369 deletions

View File

@@ -23,6 +23,7 @@ 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 SingboxRulesetUrl = @"https://raw.githubusercontent.com/SagerNet/sing-{0}/rule-set/{1}.srs";
public const string PromotionUrl = @"aHR0cHM6Ly85LjIzNDQ1Ni54eXovYWJjLmh0bWw="; public const string PromotionUrl = @"aHR0cHM6Ly85LjIzNDQ1Ni54eXovYWJjLmh0bWw=";
public const string ConfigFileName = "guiNConfig.json"; public const string ConfigFileName = "guiNConfig.json";
@@ -143,6 +144,7 @@ namespace v2rayN
{EConfigType.VMess,"vmess"}, {EConfigType.VMess,"vmess"},
{EConfigType.Shadowsocks,"shadowsocks"}, {EConfigType.Shadowsocks,"shadowsocks"},
{EConfigType.Socks,"socks"}, {EConfigType.Socks,"socks"},
{EConfigType.Http,"http"},
{EConfigType.VLESS,"vless"}, {EConfigType.VLESS,"vless"},
{EConfigType.Trojan,"trojan"}, {EConfigType.Trojan,"trojan"},
{EConfigType.Hysteria2,"hysteria2"}, {EConfigType.Hysteria2,"hysteria2"},

View File

@@ -664,6 +664,23 @@ namespace v2rayN.Handler
return 0; return 0;
} }
/// <summary>
/// Add or edit server
/// </summary>
/// <param name="config"></param>
/// <param name="profileItem"></param>
/// <returns></returns>
public static int AddHttpServer(Config config, ProfileItem profileItem, bool toFile = true)
{
profileItem.configType = EConfigType.Http;
profileItem.address = profileItem.address.TrimEx();
AddServerCommon(config, profileItem, toFile);
return 0;
}
/// <summary> /// <summary>
/// Add or edit server /// Add or edit server
/// </summary> /// </summary>
@@ -1657,14 +1674,15 @@ namespace v2rayN.Handler
public static int InitBuiltinRouting(Config config, bool blImportAdvancedRules = false) public static int InitBuiltinRouting(Config config, bool blImportAdvancedRules = false)
{ {
var ver = "V2-";
var items = LazyConfig.Instance.RoutingItems(); var items = LazyConfig.Instance.RoutingItems();
if (blImportAdvancedRules || items.Count <= 0) if (blImportAdvancedRules || items.Where(t => t.remarks.StartsWith(ver)).ToList().Count <= 0)
{ {
var maxSort = items.Count; var maxSort = items.Count;
//Bypass the mainland //Bypass the mainland
var item2 = new RoutingItem() var item2 = new RoutingItem()
{ {
remarks = "绕过大陆(Whitelist)", remarks = $"{ver}绕过大陆(Whitelist)",
url = string.Empty, url = string.Empty,
sort = maxSort + 1, sort = maxSort + 1,
}; };
@@ -1673,7 +1691,7 @@ namespace v2rayN.Handler
//Blacklist //Blacklist
var item3 = new RoutingItem() var item3 = new RoutingItem()
{ {
remarks = "黑名单(Blacklist)", remarks = $"{ver}黑名单(Blacklist)",
url = string.Empty, url = string.Empty,
sort = maxSort + 2, sort = maxSort + 2,
}; };
@@ -1682,7 +1700,7 @@ namespace v2rayN.Handler
//Global //Global
var item1 = new RoutingItem() var item1 = new RoutingItem()
{ {
remarks = "全局(Global)", remarks = $"{ver}全局(Global)",
url = string.Empty, url = string.Empty,
sort = maxSort + 3, sort = maxSort + 3,
}; };

View File

@@ -56,6 +56,8 @@ namespace v2rayN.Handler
GenStatistic(singboxConfig); GenStatistic(singboxConfig);
ConvertGeo2Ruleset(singboxConfig);
msg = string.Format(ResUI.SuccessfulConfiguration, ""); msg = string.Format(ResUI.SuccessfulConfiguration, "");
} }
catch (Exception ex) catch (Exception ex)
@@ -213,11 +215,12 @@ namespace v2rayN.Handler
{ {
outbound.server = node.address; outbound.server = node.address;
outbound.server_port = node.port; outbound.server_port = node.port;
outbound.type = Global.ProtocolTypes[node.configType];
if (node.configType == EConfigType.VMess) switch (node.configType)
{
case EConfigType.VMess:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.VMess];
outbound.uuid = node.id; outbound.uuid = node.id;
outbound.alter_id = node.alterId; outbound.alter_id = node.alterId;
if (Global.VmessSecurities.Contains(node.security)) if (Global.VmessSecurities.Contains(node.security))
@@ -230,20 +233,18 @@ namespace v2rayN.Handler
} }
GenOutboundMux(node, outbound); GenOutboundMux(node, outbound);
break;
} }
else if (node.configType == EConfigType.Shadowsocks) case EConfigType.Shadowsocks:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.Shadowsocks];
outbound.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None; outbound.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
outbound.password = node.id; outbound.password = node.id;
GenOutboundMux(node, outbound); GenOutboundMux(node, outbound);
break;
} }
else if (node.configType == EConfigType.Socks) case EConfigType.Socks:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.Socks];
outbound.version = "5"; outbound.version = "5";
if (!Utils.IsNullOrEmpty(node.security) if (!Utils.IsNullOrEmpty(node.security)
&& !Utils.IsNullOrEmpty(node.id)) && !Utils.IsNullOrEmpty(node.id))
@@ -251,11 +252,20 @@ namespace v2rayN.Handler
outbound.username = node.security; outbound.username = node.security;
outbound.password = node.id; outbound.password = node.id;
} }
break;
} }
else if (node.configType == EConfigType.VLESS) case EConfigType.Http:
{
if (!Utils.IsNullOrEmpty(node.security)
&& !Utils.IsNullOrEmpty(node.id))
{
outbound.username = node.security;
outbound.password = node.id;
}
break;
}
case EConfigType.VLESS:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.VLESS];
outbound.uuid = node.id; outbound.uuid = node.id;
outbound.packet_encoding = "xudp"; outbound.packet_encoding = "xudp";
@@ -268,19 +278,17 @@ namespace v2rayN.Handler
{ {
outbound.flow = node.flow; outbound.flow = node.flow;
} }
break;
} }
else if (node.configType == EConfigType.Trojan) case EConfigType.Trojan:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.Trojan];
outbound.password = node.id; outbound.password = node.id;
GenOutboundMux(node, outbound); GenOutboundMux(node, outbound);
break;
} }
else if (node.configType == EConfigType.Hysteria2) case EConfigType.Hysteria2:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.Hysteria2];
outbound.password = node.id; outbound.password = node.id;
if (!Utils.IsNullOrEmpty(node.path)) if (!Utils.IsNullOrEmpty(node.path))
@@ -294,24 +302,24 @@ namespace v2rayN.Handler
outbound.up_mbps = _config.hysteriaItem.up_mbps > 0 ? _config.hysteriaItem.up_mbps : null; outbound.up_mbps = _config.hysteriaItem.up_mbps > 0 ? _config.hysteriaItem.up_mbps : null;
outbound.down_mbps = _config.hysteriaItem.down_mbps > 0 ? _config.hysteriaItem.down_mbps : null; outbound.down_mbps = _config.hysteriaItem.down_mbps > 0 ? _config.hysteriaItem.down_mbps : null;
break;
} }
else if (node.configType == EConfigType.Tuic) case EConfigType.Tuic:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.Tuic];
outbound.uuid = node.id; outbound.uuid = node.id;
outbound.password = node.security; outbound.password = node.security;
outbound.congestion_control = node.headerType; outbound.congestion_control = node.headerType;
break;
} }
else if (node.configType == EConfigType.Wireguard) case EConfigType.Wireguard:
{ {
outbound.type = Global.ProtocolTypes[EConfigType.Wireguard];
outbound.private_key = node.id; outbound.private_key = node.id;
outbound.peer_public_key = node.publicKey; outbound.peer_public_key = node.publicKey;
outbound.reserved = Utils.String2List(node.path).Select(int.Parse).ToArray(); outbound.reserved = Utils.String2List(node.path).Select(int.Parse).ToArray();
outbound.local_address = [.. Utils.String2List(node.requestHost)]; outbound.local_address = [.. Utils.String2List(node.requestHost)];
outbound.mtu = Utils.ToInt(node.shortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.shortId); outbound.mtu = Utils.ToInt(node.shortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.shortId);
break;
}
} }
GenOutboundTls(node, outbound); GenOutboundTls(node, outbound);
@@ -647,29 +655,38 @@ namespace v2rayN.Handler
{ {
rule.inbound = item.inboundTag; rule.inbound = item.inboundTag;
} }
var rule1 = JsonUtils.DeepCopy(rule);
var rule2 = JsonUtils.DeepCopy(rule); var rule2 = JsonUtils.DeepCopy(rule);
var rule3 = JsonUtils.DeepCopy(rule); var rule3 = JsonUtils.DeepCopy(rule);
var hasDomainIp = false; var hasDomainIp = false;
if (item.domain?.Count > 0) if (item.domain?.Count > 0)
{ {
var countDomain = 0;
foreach (var it in item.domain) foreach (var it in item.domain)
{ {
ParseV2Domain(it, rule); if (ParseV2Domain(it, rule1)) countDomain++;
} }
rules.Add(rule); if (countDomain > 0)
{
rules.Add(rule1);
hasDomainIp = true; hasDomainIp = true;
} }
}
if (item.ip?.Count > 0) if (item.ip?.Count > 0)
{ {
var countIp = 0;
foreach (var it in item.ip) foreach (var it in item.ip)
{ {
ParseV2Address(it, rule2); if (ParseV2Address(it, rule2)) countIp++;
} }
if (countIp > 0)
{
rules.Add(rule2); rules.Add(rule2);
hasDomainIp = true; hasDomainIp = true;
} }
}
if (_config.tunModeItem.enableTun && item.process?.Count > 0) if (_config.tunModeItem.enableTun && item.process?.Count > 0)
{ {
@@ -678,7 +695,8 @@ namespace v2rayN.Handler
hasDomainIp = true; hasDomainIp = true;
} }
if (!hasDomainIp) if (!hasDomainIp
&& (rule.port != null || rule.port_range != null || rule.protocol != null || rule.inbound != null))
{ {
rules.Add(rule); rules.Add(rule);
} }
@@ -690,11 +708,11 @@ namespace v2rayN.Handler
return 0; return 0;
} }
private void ParseV2Domain(string domain, Rule4Sbox rule) private bool ParseV2Domain(string domain, Rule4Sbox rule)
{ {
if (domain.StartsWith("#") || domain.StartsWith("ext:") || domain.StartsWith("ext-domain:")) if (domain.StartsWith("#") || domain.StartsWith("ext:") || domain.StartsWith("ext-domain:"))
{ {
return; return false;
} }
else if (domain.StartsWith("geosite:")) else if (domain.StartsWith("geosite:"))
{ {
@@ -728,17 +746,22 @@ namespace v2rayN.Handler
rule.domain_keyword ??= []; rule.domain_keyword ??= [];
rule.domain_keyword?.Add(domain); rule.domain_keyword?.Add(domain);
} }
return true;
} }
private void ParseV2Address(string address, Rule4Sbox rule) private bool ParseV2Address(string address, Rule4Sbox rule)
{ {
if (address.StartsWith("ext:") || address.StartsWith("ext-ip:")) if (address.StartsWith("ext:") || address.StartsWith("ext-ip:"))
{ {
return; return false;
} }
else if (address.StartsWith("geoip:!")) else if (address.StartsWith("geoip:!"))
{ {
return; return false;
}
else if (address.Equals("geoip:private"))
{
rule.ip_is_private = true;
} }
else if (address.StartsWith("geoip:")) else if (address.StartsWith("geoip:"))
{ {
@@ -750,34 +773,25 @@ namespace v2rayN.Handler
if (rule.ip_cidr is null) { rule.ip_cidr = new(); } if (rule.ip_cidr is null) { rule.ip_cidr = new(); }
rule.ip_cidr?.Add(address); rule.ip_cidr?.Add(address);
} }
return true;
} }
private int GenDns(ProfileItem node, SingboxConfig singboxConfig) private int GenDns(ProfileItem node, SingboxConfig singboxConfig)
{ {
try try
{ {
Dns4Sbox? dns4Sbox; var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
var strDNS = string.Empty;
if (_config.tunModeItem.enableTun) if (_config.tunModeItem.enableTun)
{ {
var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); strDNS = Utils.IsNullOrEmpty(item?.tunDNS) ? Utils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.tunDNS;
var tunDNS = item?.tunDNS;
if (Utils.IsNullOrEmpty(tunDNS))
{
tunDNS = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
}
dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(tunDNS);
} }
else else
{ {
var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); strDNS = Utils.IsNullOrEmpty(item?.normalDNS) ? Utils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.normalDNS;
var normalDNS = item?.normalDNS;
if (Utils.IsNullOrEmpty(normalDNS))
{
normalDNS = "{\"servers\":[{\"address\":\"tcp://8.8.8.8\"}]}";
} }
dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(normalDNS); var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS);
}
if (dns4Sbox is null) if (dns4Sbox is null)
{ {
return 0; return 0;
@@ -814,10 +828,10 @@ namespace v2rayN.Handler
{ {
singboxConfig.experimental = new Experimental4Sbox() singboxConfig.experimental = new Experimental4Sbox()
{ {
//cache_file = new CacheFile4Sbox() cache_file = new CacheFile4Sbox()
//{ {
// enabled = true enabled = true
//}, },
//v2ray_api = new V2ray_Api4Sbox() //v2ray_api = new V2ray_Api4Sbox()
//{ //{
// listen = $"{Global.Loopback}:{Global.StatePort}", // listen = $"{Global.Loopback}:{Global.StatePort}",
@@ -835,6 +849,59 @@ namespace v2rayN.Handler
return 0; return 0;
} }
private int ConvertGeo2Ruleset(SingboxConfig singboxConfig)
{
var geosite = "geosite";
var geoip = "geoip";
var ruleSets = new List<string>();
//convert route geosite & geoip to ruleset
foreach (var rule in singboxConfig.route.rules.Where(t => t.geosite?.Count > 0).ToList() ?? [])
{
rule.rule_set = rule?.geosite?.Select(t => $"{geosite}-{t}").ToList();
rule.geosite = null;
ruleSets.AddRange(rule.rule_set);
}
foreach (var rule in singboxConfig.route.rules.Where(t => t.geoip?.Count > 0).ToList() ?? [])
{
rule.rule_set = rule?.geoip?.Select(t => $"{geoip}-{t}").ToList();
rule.geoip = null;
ruleSets.AddRange(rule.rule_set);
}
//convert dns geosite & geoip to ruleset
foreach (var rule in singboxConfig.dns?.rules.Where(t => t.geosite?.Count > 0).ToList() ?? [])
{
rule.rule_set = rule?.geosite?.Select(t => $"{geosite}-{t}").ToList();
rule.geosite = null;
}
foreach (var rule in singboxConfig.dns?.rules.Where(t => t.geoip?.Count > 0).ToList() ?? [])
{
rule.rule_set = rule?.geoip?.Select(t => $"{geoip}-{t}").ToList();
rule.geoip = null;
}
foreach (var dnsRule in singboxConfig.dns?.rules.Where(t => t.rule_set?.Count > 0).ToList() ?? [])
{
ruleSets.AddRange(dnsRule.rule_set);
}
//Add ruleset srs
singboxConfig.route.rule_set = [];
foreach (var item in new HashSet<string>(ruleSets))
{
singboxConfig.route.rule_set.Add(new()
{
type = "remote",
format = "binary",
tag = item,
url = string.Format(Global.SingboxRulesetUrl, item.StartsWith(geosite) ? geosite : geoip, item),
download_detour = Global.ProxyTag
});
}
return 0;
}
#endregion private gen function #endregion private gen function
#region Gen speedtest config #region Gen speedtest config

View File

@@ -295,7 +295,9 @@ namespace v2rayN.Handler
{ {
try try
{ {
if (node.configType == EConfigType.VMess) switch (node.configType)
{
case EConfigType.VMess:
{ {
VnextItem4Ray vnextItem; VnextItem4Ray vnextItem;
if (outbound.settings.vnext.Count <= 0) if (outbound.settings.vnext.Count <= 0)
@@ -335,10 +337,10 @@ namespace v2rayN.Handler
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled); GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
outbound.protocol = Global.ProtocolTypes[EConfigType.VMess];
outbound.settings.servers = null; outbound.settings.servers = null;
break;
} }
else if (node.configType == EConfigType.Shadowsocks) case EConfigType.Shadowsocks:
{ {
ServersItem4Ray serversItem; ServersItem4Ray serversItem;
if (outbound.settings.servers.Count <= 0) if (outbound.settings.servers.Count <= 0)
@@ -360,10 +362,11 @@ namespace v2rayN.Handler
GenOutboundMux(node, outbound, false); GenOutboundMux(node, outbound, false);
outbound.protocol = Global.ProtocolTypes[EConfigType.Shadowsocks];
outbound.settings.vnext = null; outbound.settings.vnext = null;
break;
} }
else if (node.configType == EConfigType.Socks) case EConfigType.Socks:
case EConfigType.Http:
{ {
ServersItem4Ray serversItem; ServersItem4Ray serversItem;
if (outbound.settings.servers.Count <= 0) if (outbound.settings.servers.Count <= 0)
@@ -395,13 +398,13 @@ namespace v2rayN.Handler
GenOutboundMux(node, outbound, false); GenOutboundMux(node, outbound, false);
outbound.protocol = Global.ProtocolTypes[EConfigType.Socks];
outbound.settings.vnext = null; outbound.settings.vnext = null;
break;
} }
else if (node.configType == EConfigType.VLESS) case EConfigType.VLESS:
{ {
VnextItem4Ray vnextItem; VnextItem4Ray vnextItem;
if (outbound.settings.vnext.Count <= 0) if (outbound.settings.vnext?.Count <= 0)
{ {
vnextItem = new VnextItem4Ray(); vnextItem = new VnextItem4Ray();
outbound.settings.vnext.Add(vnextItem); outbound.settings.vnext.Add(vnextItem);
@@ -444,10 +447,10 @@ namespace v2rayN.Handler
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled); GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
} }
outbound.protocol = Global.ProtocolTypes[EConfigType.VLESS];
outbound.settings.servers = null; outbound.settings.servers = null;
break;
} }
else if (node.configType == EConfigType.Trojan) case EConfigType.Trojan:
{ {
ServersItem4Ray serversItem; ServersItem4Ray serversItem;
if (outbound.settings.servers.Count <= 0) if (outbound.settings.servers.Count <= 0)
@@ -468,9 +471,12 @@ namespace v2rayN.Handler
GenOutboundMux(node, outbound, false); GenOutboundMux(node, outbound, false);
outbound.protocol = Global.ProtocolTypes[EConfigType.Trojan];
outbound.settings.vnext = null; outbound.settings.vnext = null;
break;
} }
}
outbound.protocol = Global.ProtocolTypes[node.configType];
GenBoundStreamSettings(node, outbound.streamSettings); GenBoundStreamSettings(node, outbound.streamSettings);
} }
catch (Exception ex) catch (Exception ex)
@@ -724,7 +730,7 @@ namespace v2rayN.Handler
var domainStrategy4Freedom = item?.domainStrategy4Freedom; var domainStrategy4Freedom = item?.domainStrategy4Freedom;
if (Utils.IsNullOrEmpty(normalDNS)) if (Utils.IsNullOrEmpty(normalDNS))
{ {
normalDNS = "1.1.1.1,8.8.8.8"; normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
} }
//Outbound Freedom domainStrategy //Outbound Freedom domainStrategy
@@ -828,6 +834,33 @@ namespace v2rayN.Handler
private int GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig) private int GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig)
{ {
//fragment proxy
if (_config.coreBasicItem.enableFragment
&& !Utils.IsNullOrEmpty(v2rayConfig.outbounds[0].streamSettings?.security))
{
var fragmentOutbound = new Outbounds4Ray
{
protocol = "freedom",
tag = $"{Global.ProxyTag}3",
settings = new()
{
fragment = new()
{
packets = "tlshello",
length = "100-200",
interval = "10-20"
}
}
};
v2rayConfig.outbounds.Add(fragmentOutbound);
v2rayConfig.outbounds[0].streamSettings.sockopt = new()
{
dialerProxy = fragmentOutbound.tag
};
return 0;
}
if (node.subid.IsNullOrEmpty()) if (node.subid.IsNullOrEmpty())
{ {
return 0; return 0;

View File

@@ -208,18 +208,19 @@ namespace v2rayN.Handler
{ {
if ((node.configType == EConfigType.Custom && node.preSocksPort > 0)) if ((node.configType == EConfigType.Custom && node.preSocksPort > 0))
{ {
var preCoreType = _config.tunModeItem.enableTun ? ECoreType.sing_box : ECoreType.Xray;
var itemSocks = new ProfileItem() var itemSocks = new ProfileItem()
{ {
coreType = ECoreType.sing_box, coreType = preCoreType,
configType = EConfigType.Socks, configType = EConfigType.Socks,
address = Global.Loopback, address = Global.Loopback,
port = node.preSocksPort port = node.preSocksPort
}; };
_config.runningCoreType = ECoreType.sing_box; _config.runningCoreType = preCoreType;
string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName); string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0) if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0)
{ {
var coreInfo2 = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box); var coreInfo2 = LazyConfig.Instance.GetCoreInfo(preCoreType);
var proc2 = RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true); var proc2 = RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true);
if (proc2 is not null) if (proc2 is not null)
{ {

View File

@@ -61,6 +61,7 @@ namespace v2rayN.Handler
while (!_exitFlag) while (!_exitFlag)
{ {
await Task.Delay(1000);
try try
{ {
if (!(_config.runningCoreType is ECoreType.sing_box or ECoreType.clash or ECoreType.clash_meta or ECoreType.mihomo)) if (!(_config.runningCoreType is ECoreType.sing_box or ECoreType.clash or ECoreType.clash_meta or ECoreType.mihomo))
@@ -105,10 +106,6 @@ namespace v2rayN.Handler
catch catch
{ {
} }
finally
{
await Task.Delay(1000);
}
} }
} }

View File

@@ -49,6 +49,7 @@ namespace v2rayN.Handler
{ {
while (!_exitFlag) while (!_exitFlag)
{ {
await Task.Delay(1000);
try try
{ {
if (!(_config.runningCoreType is ECoreType.Xray or ECoreType.v2fly or ECoreType.v2fly_v5 or ECoreType.SagerNet)) if (!(_config.runningCoreType is ECoreType.Xray or ECoreType.v2fly or ECoreType.v2fly_v5 or ECoreType.SagerNet))
@@ -60,6 +61,7 @@ namespace v2rayN.Handler
QueryStatsResponse? res = null; QueryStatsResponse? res = null;
try try
{ {
if (_client != null)
res = await _client.QueryStatsAsync(new QueryStatsRequest() { Pattern = "", Reset = true }); res = await _client.QueryStatsAsync(new QueryStatsRequest() { Pattern = "", Reset = true });
} }
catch catch
@@ -72,8 +74,8 @@ namespace v2rayN.Handler
_updateFunc(server); _updateFunc(server);
} }
} }
await Task.Delay(1000); if (_channel != null)
if (_channel != null) await _channel.ConnectAsync(); await _channel.ConnectAsync();
} }
catch catch
{ {

View File

@@ -31,6 +31,8 @@ namespace v2rayN.Models
/// 默认用户代理 /// 默认用户代理
/// </summary> /// </summary>
public string defUserAgent { get; set; } public string defUserAgent { get; set; }
public bool enableFragment { get; set; }
} }
[Serializable] [Serializable]
@@ -122,7 +124,7 @@ namespace v2rayN.Models
public int currentFontSize { get; set; } public int currentFontSize { get; set; }
public bool enableDragDropSort { get; set; } public bool enableDragDropSort { get; set; }
public bool doubleClick2Activate { get; set; } public bool doubleClick2Activate { get; set; }
public bool autoHideStartup { get; set; } = true; public bool autoHideStartup { get; set; }
public string mainMsgFilter { get; set; } public string mainMsgFilter { get; set; }
public List<ColumnItem> mainColumnItem { get; set; } public List<ColumnItem> mainColumnItem { get; set; }
} }

View File

@@ -10,6 +10,7 @@
Trojan = 6, Trojan = 6,
Hysteria2 = 7, Hysteria2 = 7,
Tuic = 8, Tuic = 8,
Wireguard = 9 Wireguard = 9,
Http = 10
} }
} }

View File

@@ -35,6 +35,7 @@
{ {
public bool? auto_detect_interface { get; set; } public bool? auto_detect_interface { get; set; }
public List<Rule4Sbox> rules { get; set; } public List<Rule4Sbox> rules { get; set; }
public List<Ruleset4Sbox>? rule_set { get; set; }
} }
[Serializable] [Serializable]
@@ -48,6 +49,7 @@
public string type { get; set; } public string type { get; set; }
public string mode { get; set; } public string mode { get; set; }
public string network { get; set; } public string network { get; set; }
public bool? ip_is_private { get; set; }
public List<int>? port { get; set; } public List<int>? port { get; set; }
public List<string>? port_range { get; set; } public List<string>? port_range { get; set; }
public List<string>? geosite { get; set; } public List<string>? geosite { get; set; }
@@ -58,8 +60,8 @@
public List<string>? geoip { get; set; } public List<string>? geoip { get; set; }
public List<string>? ip_cidr { get; set; } public List<string>? ip_cidr { get; set; }
public List<string>? source_ip_cidr { get; set; } public List<string>? source_ip_cidr { get; set; }
public List<string>? process_name { get; set; } public List<string>? process_name { get; set; }
public List<string>? rule_set { get; set; }
} }
[Serializable] [Serializable]
@@ -230,4 +232,13 @@
public string? cache_id { get; set; } public string? cache_id { get; set; }
public bool? store_fakeip { get; set; } public bool? store_fakeip { get; set; }
} }
public class Ruleset4Sbox
{
public string? tag { get; set; }
public string? type { get; set; }
public string? format { get; set; }
public string? url { get; set; }
public string? download_detour { get; set; }
}
} }

View File

@@ -232,7 +232,7 @@ namespace v2rayN.Models
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public List<VnextItem4Ray> vnext { get; set; } public List<VnextItem4Ray>? vnext { get; set; }
/// <summary> /// <summary>
/// ///
@@ -253,6 +253,8 @@ namespace v2rayN.Models
/// ///
/// </summary> /// </summary>
public int? userLevel { get; set; } public int? userLevel { get; set; }
public FragmentItem4Ray? fragment { get; set; }
} }
public class VnextItem4Ray public class VnextItem4Ray
@@ -288,17 +290,17 @@ namespace v2rayN.Models
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string method { get; set; } public string? method { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public bool ota { get; set; } public bool? ota { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string password { get; set; } public string? password { get; set; }
/// <summary> /// <summary>
/// ///
@@ -308,7 +310,7 @@ namespace v2rayN.Models
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int level { get; set; } public int? level { get; set; }
/// <summary> /// <summary>
/// trojan /// trojan
@@ -336,7 +338,7 @@ namespace v2rayN.Models
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int level { get; set; } public int? level { get; set; }
} }
public class Mux4Ray public class Mux4Ray
@@ -389,19 +391,19 @@ namespace v2rayN.Models
[Serializable] [Serializable]
public class RulesItem4Ray public class RulesItem4Ray
{ {
public string type { get; set; } public string? type { get; set; }
public string port { get; set; } public string? port { get; set; }
public List<string> inboundTag { get; set; } public List<string>? inboundTag { get; set; }
public string outboundTag { get; set; } public string? outboundTag { get; set; }
public List<string> ip { get; set; } public List<string>? ip { get; set; }
public List<string> domain { get; set; } public List<string>? domain { get; set; }
public List<string> protocol { get; set; } public List<string>? protocol { get; set; }
} }
public class StreamSettings4Ray public class StreamSettings4Ray
@@ -665,4 +667,11 @@ namespace v2rayN.Models
{ {
public string? dialerProxy { get; set; } public string? dialerProxy { get; set; }
} }
public class FragmentItem4Ray
{
public string? packets { get; set; }
public string? length { get; set; }
public string? interval { get; set; }
}
} }

View File

@@ -618,6 +618,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Add [Http] server 的本地化字符串。
/// </summary>
public static string menuAddHttpServer {
get {
return ResourceManager.GetString("menuAddHttpServer", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Add [Hysteria2] server 的本地化字符串。 /// 查找类似 Add [Hysteria2] server 的本地化字符串。
/// </summary> /// </summary>
@@ -2626,6 +2635,24 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Enable fragment 的本地化字符串。
/// </summary>
public static string TbSettingsEnableFragment {
get {
return ResourceManager.GetString("TbSettingsEnableFragment", resourceCulture);
}
}
/// <summary>
/// 查找类似 Use Xray and enable non-Tun mode, which conflicts with the group previous proxy 的本地化字符串。
/// </summary>
public static string TbSettingsEnableFragmentTips {
get {
return ResourceManager.GetString("TbSettingsEnableFragmentTips", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Enable hardware acceleration(Require restart) 的本地化字符串。 /// 查找类似 Enable hardware acceleration(Require restart) 的本地化字符串。
/// </summary> /// </summary>
@@ -3149,7 +3176,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 * 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 Xray/sing-box(Tun) to provide functions such as speed display 的本地化字符串。
/// </summary> /// </summary>
public static string TipPreSocksPort { public static string TipPreSocksPort {
get { get {

View File

@@ -698,7 +698,7 @@
<value>txtPreSocksPort</value> <value>txtPreSocksPort</value>
</data> </data>
<data name="TipPreSocksPort" xml:space="preserve"> <data name="TipPreSocksPort" xml:space="preserve">
<value>* After setting this value, an socks service will be started using sing-box to provide functions such as speed display</value> <value>* After setting this value, an socks service will be started using Xray/sing-box(Tun) to provide functions such as speed display</value>
</data> </data>
<data name="TbBrowse" xml:space="preserve"> <data name="TbBrowse" xml:space="preserve">
<value>Browse</value> <value>Browse</value>

View File

@@ -701,7 +701,7 @@
<value>txtPreSocksPort</value> <value>txtPreSocksPort</value>
</data> </data>
<data name="TipPreSocksPort" xml:space="preserve"> <data name="TipPreSocksPort" xml:space="preserve">
<value>* After setting this value, an socks service will be started using sing-box to provide functions such as speed display</value> <value>* After setting this value, an socks service will be started using Xray/sing-box(Tun) to provide functions such as speed display</value>
</data> </data>
<data name="TbBrowse" xml:space="preserve"> <data name="TbBrowse" xml:space="preserve">
<value>Browse</value> <value>Browse</value>
@@ -1198,4 +1198,13 @@
<data name="TransportRequestHostTip5" xml:space="preserve"> <data name="TransportRequestHostTip5" xml:space="preserve">
<value>*grpc Authority</value> <value>*grpc Authority</value>
</data> </data>
<data name="menuAddHttpServer" xml:space="preserve">
<value>Add [Http] server</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>Use Xray and enable non-Tun mode, which conflicts with the group previous proxy</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>Enable fragment</value>
</data>
</root> </root>

View File

@@ -701,7 +701,7 @@
<value>txtPreSocksPort</value> <value>txtPreSocksPort</value>
</data> </data>
<data name="TipPreSocksPort" xml:space="preserve"> <data name="TipPreSocksPort" xml:space="preserve">
<value>* После установки этого значения служба socks будет запущена с использованием sing-box для обеспечения таких функций, как отображение скорости</value> <value>* После установки этого значения служба socks будет запущена с использованием Xray/sing-box(Tun) для обеспечения таких функций, как отображение скорости</value>
</data> </data>
<data name="TbBrowse" xml:space="preserve"> <data name="TbBrowse" xml:space="preserve">
<value>Просмотр</value> <value>Просмотр</value>

View File

@@ -701,7 +701,7 @@
<value>Socks端口</value> <value>Socks端口</value>
</data> </data>
<data name="TipPreSocksPort" xml:space="preserve"> <data name="TipPreSocksPort" xml:space="preserve">
<value>* 自定义配置的Socks端口值可不设置当设置此值后将使用sing-box额外启动一个前置Socks服务提供分流和速度显示等功能</value> <value>* 自定义配置的Socks端口值可不设置当设置此值后将使用Xray/sing-box(Tun)额外启动一个前置Socks服务提供分流和速度显示等功能</value>
</data> </data>
<data name="TbBrowse" xml:space="preserve"> <data name="TbBrowse" xml:space="preserve">
<value>浏览</value> <value>浏览</value>
@@ -1195,4 +1195,13 @@
<data name="TransportRequestHostTip5" xml:space="preserve"> <data name="TransportRequestHostTip5" xml:space="preserve">
<value>*grpc Authority</value> <value>*grpc Authority</value>
</data> </data>
<data name="menuAddHttpServer" xml:space="preserve">
<value>添加[Http]服务器</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>启用分片Fragment</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>使用Xray且非Tun模式启用和分组前置代理冲突</value>
</data>
</root> </root>

View File

@@ -700,7 +700,7 @@
<value>SOCKS埠</value> <value>SOCKS埠</value>
</data> </data>
<data name="TipPreSocksPort" xml:space="preserve"> <data name="TipPreSocksPort" xml:space="preserve">
<value>* 自訂配置的Socks埠值可不設定當設定此值後將使用sing-box額外啟動一個前置Socks服務提供分流和速度顯示等功能</value> <value>* 自訂配置的Socks埠值可不設定當設定此值後將使用Xray/sing-box(Tun)額外啟動一個前置Socks服務提供分流和速度顯示等功能</value>
</data> </data>
<!--********************************************--> <!--********************************************-->
<data name="TbBrowse" xml:space="preserve"> <data name="TbBrowse" xml:space="preserve">
@@ -1168,4 +1168,13 @@
<data name="TransportRequestHostTip5" xml:space="preserve"> <data name="TransportRequestHostTip5" xml:space="preserve">
<value>*grpc Authority</value> <value>*grpc Authority</value>
</data> </data>
<data name="menuAddHttpServer" xml:space="preserve">
<value>新增[Http]伺服器</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>啟用分片Fragment</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>使用Xray且非Tun模式啟用和分組前置代理衝突</value>
</data>
</root> </root>

View File

@@ -13,20 +13,10 @@
}, },
{ {
"outboundTag": "proxy", "outboundTag": "proxy",
"ip": [
"geoip:cloudflare",
"geoip:cloudfront",
"geoip:facebook",
"geoip:fastly",
"geoip:google",
"geoip:netflix",
"geoip:telegram",
"geoip:twitter"
],
"domain": [ "domain": [
"geosite:gfw", "geosite:geolocation-!cn",
"geosite:greatfire", "geosite:greatfire"
"geosite:tld-!cn"
] ]
}, },
{ {

View File

@@ -15,7 +15,8 @@
{ {
"outboundTag": "direct", "outboundTag": "direct",
"domain": [ "domain": [
"geosite:cn" "geosite:cn",
"geosite:geolocation-cn"
] ]
}, },
{ {

View File

@@ -3,11 +3,13 @@
{ {
"tag": "remote", "tag": "remote",
"address": "tcp://8.8.8.8", "address": "tcp://8.8.8.8",
"strategy": "ipv4_only",
"detour": "proxy" "detour": "proxy"
}, },
{ {
"tag": "local", "tag": "local",
"address": "223.5.5.5", "address": "223.5.5.5",
"strategy": "ipv4_only",
"detour": "direct" "detour": "direct"
}, },
{ {
@@ -17,14 +19,14 @@
], ],
"rules": [ "rules": [
{ {
"geosite": [ "rule_set": [
"cn" "geosite-geolocation-!cn"
], ],
"server": "local" "server": "remote"
}, },
{ {
"geosite": [ "rule_set": [
"category-ads-all" "geosite-category-ads-all"
], ],
"server": "block" "server": "block"
} }

View File

@@ -7,7 +7,8 @@
{ {
"address": "223.5.5.5", "address": "223.5.5.5",
"domains": [ "domains": [
"geosite:cn" "geosite:cn",
"geosite:geolocation-cn"
], ],
"expectIPs": [ "expectIPs": [
"geoip:cn" "geoip:cn"

View File

@@ -3,11 +3,13 @@
{ {
"tag": "remote", "tag": "remote",
"address": "tcp://8.8.8.8", "address": "tcp://8.8.8.8",
"strategy": "ipv4_only",
"detour": "proxy" "detour": "proxy"
}, },
{ {
"tag": "local", "tag": "local",
"address": "223.5.5.5", "address": "223.5.5.5",
"strategy": "ipv4_only",
"detour": "direct" "detour": "direct"
}, },
{ {
@@ -17,19 +19,16 @@
], ],
"rules": [ "rules": [
{ {
"geosite": [ "rule_set": [
"cn" "geosite-geolocation-!cn"
], ],
"server": "local", "server": "remote"
"disable_cache": true
}, },
{ {
"geosite": [ "rule_set": [
"category-ads-all" "geosite-category-ads-all"
], ],
"server": "block", "server": "block"
"disable_cache": true
} }
], ]
"strategy": "ipv4_only"
} }

View File

@@ -80,7 +80,8 @@ namespace v2rayN.ViewModels
return; return;
} }
} }
if (SelectedSource.configType != EConfigType.Socks) if (SelectedSource.configType != EConfigType.Socks
&& SelectedSource.configType != EConfigType.Http)
{ {
if (Utils.IsNullOrEmpty(SelectedSource.id)) if (Utils.IsNullOrEmpty(SelectedSource.id))
{ {
@@ -127,6 +128,7 @@ namespace v2rayN.ViewModels
EConfigType.VMess => ConfigHandler.AddServer(_config, item), EConfigType.VMess => ConfigHandler.AddServer(_config, item),
EConfigType.Shadowsocks => ConfigHandler.AddShadowsocksServer(_config, item), EConfigType.Shadowsocks => ConfigHandler.AddShadowsocksServer(_config, item),
EConfigType.Socks => ConfigHandler.AddSocksServer(_config, item), EConfigType.Socks => ConfigHandler.AddSocksServer(_config, item),
EConfigType.Http => ConfigHandler.AddHttpServer(_config, item),
EConfigType.Trojan => ConfigHandler.AddTrojanServer(_config, item), EConfigType.Trojan => ConfigHandler.AddTrojanServer(_config, item),
EConfigType.VLESS => ConfigHandler.AddVlessServer(_config, item), EConfigType.VLESS => ConfigHandler.AddVlessServer(_config, item),
EConfigType.Hysteria2 => ConfigHandler.AddHysteria2Server(_config, item), EConfigType.Hysteria2 => ConfigHandler.AddHysteria2Server(_config, item),

View File

@@ -86,6 +86,7 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; } public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; } public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; } public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddHttpServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; } public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; } public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; } public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
@@ -333,6 +334,10 @@ namespace v2rayN.ViewModels
{ {
EditServer(true, EConfigType.Socks); EditServer(true, EConfigType.Socks);
}); });
AddHttpServerCmd = ReactiveCommand.Create(() =>
{
EditServer(true, EConfigType.Http);
});
AddTrojanServerCmd = ReactiveCommand.Create(() => AddTrojanServerCmd = ReactiveCommand.Create(() =>
{ {
EditServer(true, EConfigType.Trojan); EditServer(true, EConfigType.Trojan);

View File

@@ -34,6 +34,7 @@ namespace v2rayN.ViewModels
[Reactive] public string mux4SboxProtocol { get; set; } [Reactive] public string mux4SboxProtocol { get; set; }
[Reactive] public int hyUpMbps { get; set; } [Reactive] public int hyUpMbps { get; set; }
[Reactive] public int hyDownMbps { get; set; } [Reactive] public int hyDownMbps { get; set; }
[Reactive] public bool enableFragment { get; set; }
#endregion Core #endregion Core
@@ -129,6 +130,7 @@ namespace v2rayN.ViewModels
mux4SboxProtocol = _config.mux4SboxItem.protocol; mux4SboxProtocol = _config.mux4SboxItem.protocol;
hyUpMbps = _config.hysteriaItem.up_mbps; hyUpMbps = _config.hysteriaItem.up_mbps;
hyDownMbps = _config.hysteriaItem.down_mbps; hyDownMbps = _config.hysteriaItem.down_mbps;
enableFragment = _config.coreBasicItem.enableFragment;
#endregion Core #endregion Core
@@ -289,6 +291,7 @@ namespace v2rayN.ViewModels
_config.mux4SboxItem.protocol = mux4SboxProtocol; _config.mux4SboxItem.protocol = mux4SboxProtocol;
_config.hysteriaItem.up_mbps = hyUpMbps; _config.hysteriaItem.up_mbps = hyUpMbps;
_config.hysteriaItem.down_mbps = hyDownMbps; _config.hysteriaItem.down_mbps = hyDownMbps;
_config.coreBasicItem.enableFragment = enableFragment;
//Kcp //Kcp
//_config.kcpItem.mtu = Kcpmtu; //_config.kcpItem.mtu = Kcpmtu;

View File

@@ -196,13 +196,14 @@ namespace v2rayN.ViewModels
return; return;
} }
var lst = new List<RulesItem>(); var lst = new List<RulesItem4Ray>();
foreach (var it in SelectedSources) foreach (var it in SelectedSources)
{ {
var item = _rules.FirstOrDefault(t => t.id == it?.id); var item = _rules.FirstOrDefault(t => t.id == it?.id);
if (item != null) if (item != null)
{ {
lst.Add(item); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
lst.Add(item2 ?? new());
} }
} }
if (lst.Count > 0) if (lst.Count > 0)

View File

@@ -92,6 +92,7 @@ namespace v2rayN.Views
break; break;
case EConfigType.Socks: case EConfigType.Socks:
case EConfigType.Http:
gridSocks.Visibility = Visibility.Visible; gridSocks.Visibility = Visibility.Visible;
break; break;
@@ -174,6 +175,7 @@ namespace v2rayN.Views
break; break;
case EConfigType.Socks: case EConfigType.Socks:
case EConfigType.Http:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables);
break; break;

View File

@@ -1,17 +1,17 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.MainWindow" x:Class="v2rayN.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
xmlns:base="clr-namespace:v2rayN.Base" xmlns:base="clr-namespace:v2rayN.Base"
xmlns:conv="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:resx="clr-namespace:v2rayN.Resx" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vms="clr-namespace:v2rayN.ViewModels"
xmlns:local="clr-namespace:v2rayN.Views" xmlns:local="clr-namespace:v2rayN.Views"
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"
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
xmlns:vms="clr-namespace:v2rayN.ViewModels"
Title="v2rayN" Title="v2rayN"
Width="900" Width="900"
Height="700" Height="700"
@@ -79,6 +79,10 @@
x:Name="menuAddSocksServer" x:Name="menuAddSocksServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddSocksServer}" /> Header="{x:Static resx:ResUI.menuAddSocksServer}" />
<MenuItem
x:Name="menuAddHttpServer"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuAddHttpServer}" />
<MenuItem <MenuItem
x:Name="menuAddTrojanServer" x:Name="menuAddTrojanServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"

View File

@@ -86,6 +86,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.AddVlessServerCmd, v => v.menuAddVlessServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddVlessServerCmd, v => v.menuAddVlessServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddShadowsocksServerCmd, v => v.menuAddShadowsocksServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddShadowsocksServerCmd, v => v.menuAddShadowsocksServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddHttpServerCmd, v => v.menuAddHttpServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);

View File

@@ -67,6 +67,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
@@ -333,6 +334,26 @@
materialDesign:HintAssist.Hint="Down" materialDesign:HintAssist.Hint="Down"
Style="{StaticResource DefTextBox}" /> Style="{StaticResource DefTextBox}" />
</StackPanel> </StackPanel>
<TextBlock
Grid.Row="16"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableFragment}" />
<ToggleButton
x:Name="togenableFragment"
Grid.Row="16"
Grid.Column="1"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="16"
Grid.Column="3"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableFragmentTips}" />
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>

View File

@@ -156,6 +156,7 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.mux4SboxProtocol, v => v.cmbmux4SboxProtocol.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.mux4SboxProtocol, v => v.cmbmux4SboxProtocol.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.hyUpMbps, v => v.txtUpMbps.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.hyUpMbps, v => v.txtUpMbps.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.hyDownMbps, v => v.txtDownMbps.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.hyDownMbps, v => v.txtDownMbps.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.enableFragment, v => v.togenableFragment.IsChecked).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.Kcpmtu, v => v.txtKcpmtu.Text).DisposeWith(disposables); //this.Bind(ViewModel, vm => vm.Kcpmtu, v => v.txtKcpmtu.Text).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.Kcptti, v => v.txtKcptti.Text).DisposeWith(disposables); //this.Bind(ViewModel, vm => vm.Kcptti, v => v.txtKcptti.Text).DisposeWith(disposables);

View File

@@ -10,7 +10,7 @@
<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.41</FileVersion> <FileVersion>6.43</FileVersion>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>