mirror of
https://github.com/2dust/v2rayN.git
synced 2025-05-03 13:48:52 +00:00
Merge branch '2dust:master' into hotkey
This commit is contained in:
commit
48880328b0
39 changed files with 797 additions and 1140 deletions
|
@ -11,7 +11,7 @@
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<materialDesign:BundledTheme
|
<materialDesign:BundledTheme
|
||||||
BaseTheme="Light"
|
BaseTheme="Light"
|
||||||
PrimaryColor="DeepPurple"
|
PrimaryColor="Blue"
|
||||||
SecondaryColor="Lime" />
|
SecondaryColor="Lime" />
|
||||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
public const string v2raySampleInbound = "v2rayN.Sample.SampleInbound";
|
public const string v2raySampleInbound = "v2rayN.Sample.SampleInbound";
|
||||||
public const string CustomRoutingFileName = "v2rayN.Sample.custom_routing_";
|
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 TunSingboxDNSFileName = "v2rayN.Sample.tun_singbox_dns";
|
||||||
public const string TunSingboxInboundFileName = "v2rayN.Sample.tun_singbox_inbound";
|
public const string TunSingboxInboundFileName = "v2rayN.Sample.tun_singbox_inbound";
|
||||||
public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules";
|
public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules";
|
||||||
|
@ -158,6 +157,7 @@
|
||||||
public static readonly List<string> TunMtus = new() { "9000", "1500" };
|
public static readonly List<string> TunMtus = new() { "9000", "1500" };
|
||||||
public static readonly List<string> TunStacks = new() { "gvisor", "system" };
|
public static readonly List<string> TunStacks = new() { "gvisor", "system" };
|
||||||
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
|
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
|
||||||
|
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
||||||
|
|
||||||
#endregion const
|
#endregion const
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,6 @@ namespace v2rayN.Handler
|
||||||
config.tunModeItem = new TunModeItem
|
config.tunModeItem = new TunModeItem
|
||||||
{
|
{
|
||||||
enableTun = false,
|
enableTun = false,
|
||||||
showWindow = true,
|
|
||||||
mtu = 9000,
|
mtu = 9000,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -191,6 +190,18 @@ namespace v2rayN.Handler
|
||||||
config.guiItem.statisticsFreshRate = 1;
|
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);
|
LazyConfig.Instance.SetConfig(config);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,15 +19,16 @@ namespace v2rayN.Handler
|
||||||
msg = ResUI.CheckServerSettings;
|
msg = ResUI.CheckServerSettings;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
var config = LazyConfig.Instance.GetConfig();
|
||||||
|
|
||||||
msg = ResUI.InitialConfiguration;
|
msg = ResUI.InitialConfiguration;
|
||||||
if (node.configType == EConfigType.Custom)
|
if (node.configType == EConfigType.Custom)
|
||||||
{
|
{
|
||||||
return GenerateClientCustomConfig(node, fileName, out msg);
|
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)
|
if (configGenSingbox.GenerateClientConfigContent(node, out SingboxConfig? singboxConfig, out msg) != 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -43,7 +44,7 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var coreConfigV2ray = new CoreConfigV2ray(LazyConfig.Instance.GetConfig());
|
var coreConfigV2ray = new CoreConfigV2ray(config);
|
||||||
if (coreConfigV2ray.GenerateClientConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0)
|
if (coreConfigV2ray.GenerateClientConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
dns(node, singboxConfig);
|
dns(node, singboxConfig);
|
||||||
|
|
||||||
//statistic(singboxConfig);
|
statistic(singboxConfig);
|
||||||
|
|
||||||
msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,11 @@ namespace v2rayN.Handler
|
||||||
outbound.flow = node.flow;
|
outbound.flow = node.flow;
|
||||||
|
|
||||||
outbound.packet_encoding = "xudp";
|
outbound.packet_encoding = "xudp";
|
||||||
|
|
||||||
|
if (Utils.IsNullOrEmpty(node.flow))
|
||||||
|
{
|
||||||
|
outboundMux(node, outbound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.Trojan)
|
else if (node.configType == EConfigType.Trojan)
|
||||||
{
|
{
|
||||||
|
@ -288,10 +293,11 @@ namespace v2rayN.Handler
|
||||||
var mux = new Multiplex4Sbox()
|
var mux = new Multiplex4Sbox()
|
||||||
{
|
{
|
||||||
enabled = true,
|
enabled = true,
|
||||||
protocol = "smux",
|
protocol = _config.mux4Sbox.protocol,
|
||||||
max_connections = 4,
|
max_connections = _config.mux4Sbox.max_connections,
|
||||||
min_streams = 4,
|
min_streams = _config.mux4Sbox.min_streams,
|
||||||
max_streams = 0,
|
max_streams = _config.mux4Sbox.max_streams,
|
||||||
|
padding = _config.mux4Sbox.padding
|
||||||
};
|
};
|
||||||
outbound.multiplex = mux;
|
outbound.multiplex = mux;
|
||||||
}
|
}
|
||||||
|
@ -361,6 +367,13 @@ namespace v2rayN.Handler
|
||||||
case "ws":
|
case "ws":
|
||||||
transport.type = "ws";
|
transport.type = "ws";
|
||||||
transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path;
|
transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path;
|
||||||
|
if (!Utils.IsNullOrEmpty(node.requestHost))
|
||||||
|
{
|
||||||
|
transport.headers = new()
|
||||||
|
{
|
||||||
|
Host = node.requestHost
|
||||||
|
};
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "quic":
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -546,6 +527,7 @@ namespace v2rayN.Handler
|
||||||
rule.inbound = item.inboundTag;
|
rule.inbound = item.inboundTag;
|
||||||
}
|
}
|
||||||
var rule2 = Utils.DeepCopy(rule);
|
var rule2 = Utils.DeepCopy(rule);
|
||||||
|
var rule3 = Utils.DeepCopy(rule);
|
||||||
|
|
||||||
var hasDomainIp = false;
|
var hasDomainIp = false;
|
||||||
if (item.domain?.Count > 0)
|
if (item.domain?.Count > 0)
|
||||||
|
@ -568,6 +550,13 @@ namespace v2rayN.Handler
|
||||||
hasDomainIp = true;
|
hasDomainIp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_config.tunModeItem.enableTun && item.process?.Count > 0)
|
||||||
|
{
|
||||||
|
rule3.process_name = item.process;
|
||||||
|
rules.Add(rule3);
|
||||||
|
hasDomainIp = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hasDomainIp)
|
if (!hasDomainIp)
|
||||||
{
|
{
|
||||||
rules.Add(rule);
|
rules.Add(rule);
|
||||||
|
@ -653,16 +642,9 @@ namespace v2rayN.Handler
|
||||||
Dns4Sbox? dns4Sbox;
|
Dns4Sbox? dns4Sbox;
|
||||||
if (_config.tunModeItem.enableTun)
|
if (_config.tunModeItem.enableTun)
|
||||||
{
|
{
|
||||||
string tunDNS = String.Empty;
|
var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
if (_config.tunModeItem.bypassMode)
|
var tunDNS = item?.tunDNS;
|
||||||
{
|
if (string.IsNullOrWhiteSpace(tunDNS))
|
||||||
tunDNS = _config.tunModeItem.directDNS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tunDNS = _config.tunModeItem.proxyDNS;
|
|
||||||
}
|
|
||||||
if (tunDNS.IsNullOrEmpty() || Utils.FromJson<Dns4Sbox>(tunDNS) is null)
|
|
||||||
{
|
{
|
||||||
tunDNS = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
|
tunDNS = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||||
}
|
}
|
||||||
|
@ -720,13 +702,18 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
singboxConfig.experimental = new Experimental4Sbox()
|
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}",
|
external_controller = $"{Global.Loopback}:{Global.statePort}",
|
||||||
stats = new Stats4Sbox()
|
store_selected = true
|
||||||
{
|
|
||||||
enabled = true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,24 +96,24 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
v2rayConfig.inbounds = new List<Inbounds>();
|
v2rayConfig.inbounds = new List<Inbounds4Ray>();
|
||||||
|
|
||||||
Inbounds? inbound = GetInbound(_config.inbound[0], Global.InboundSocks, 0, true);
|
Inbounds4Ray? inbound = GetInbound(_config.inbound[0], Global.InboundSocks, 0, true);
|
||||||
v2rayConfig.inbounds.Add(inbound);
|
v2rayConfig.inbounds.Add(inbound);
|
||||||
|
|
||||||
//http
|
//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);
|
v2rayConfig.inbounds.Add(inbound2);
|
||||||
|
|
||||||
if (_config.inbound[0].allowLANConn)
|
if (_config.inbound[0].allowLANConn)
|
||||||
{
|
{
|
||||||
if (_config.inbound[0].newPort4LAN)
|
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";
|
inbound3.listen = "0.0.0.0";
|
||||||
v2rayConfig.inbounds.Add(inbound3);
|
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";
|
inbound4.listen = "0.0.0.0";
|
||||||
v2rayConfig.inbounds.Add(inbound4);
|
v2rayConfig.inbounds.Add(inbound4);
|
||||||
|
|
||||||
|
@ -121,10 +121,10 @@ namespace v2rayN.Handler
|
||||||
if (!Utils.IsNullOrEmpty(_config.inbound[0].user) && !Utils.IsNullOrEmpty(_config.inbound[0].pass))
|
if (!Utils.IsNullOrEmpty(_config.inbound[0].user) && !Utils.IsNullOrEmpty(_config.inbound[0].pass))
|
||||||
{
|
{
|
||||||
inbound3.settings.auth = "password";
|
inbound3.settings.auth = "password";
|
||||||
inbound3.settings.accounts = new List<AccountsItem> { new AccountsItem() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } };
|
inbound3.settings.accounts = new List<AccountsItem4Ray> { new AccountsItem4Ray() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } };
|
||||||
|
|
||||||
inbound4.settings.auth = "password";
|
inbound4.settings.auth = "password";
|
||||||
inbound4.settings.accounts = new List<AccountsItem> { new AccountsItem() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } };
|
inbound4.settings.accounts = new List<AccountsItem4Ray> { new AccountsItem4Ray() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -141,7 +141,7 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
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);
|
string result = Utils.GetEmbedText(Global.v2raySampleInbound);
|
||||||
if (Utils.IsNullOrEmpty(result))
|
if (Utils.IsNullOrEmpty(result))
|
||||||
|
@ -149,7 +149,7 @@ namespace v2rayN.Handler
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inbound = Utils.FromJson<Inbounds>(result);
|
var inbound = Utils.FromJson<Inbounds4Ray>(result);
|
||||||
if (inbound == null)
|
if (inbound == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -187,7 +187,8 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
if (item.enabled)
|
if (item.enabled)
|
||||||
{
|
{
|
||||||
routingUserRule(item, v2rayConfig);
|
var item2 = Utils.FromJson<RulesItem4Ray>(Utils.ToJson(item));
|
||||||
|
routingUserRule(item2, v2rayConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +201,8 @@ namespace v2rayN.Handler
|
||||||
var rules = Utils.FromJson<List<RulesItem>>(lockedItem.ruleSet);
|
var rules = Utils.FromJson<List<RulesItem>>(lockedItem.ruleSet);
|
||||||
foreach (var item in rules)
|
foreach (var item in rules)
|
||||||
{
|
{
|
||||||
routingUserRule(item, v2rayConfig);
|
var item2 = Utils.FromJson<RulesItem4Ray>(Utils.ToJson(item));
|
||||||
|
routingUserRule(item2, v2rayConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +215,7 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int routingUserRule(RulesItem rules, V2rayConfig v2rayConfig)
|
private int routingUserRule(RulesItem4Ray rules, V2rayConfig v2rayConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -291,13 +293,13 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Outbounds outbound = v2rayConfig.outbounds[0];
|
Outbounds4Ray outbound = v2rayConfig.outbounds[0];
|
||||||
if (node.configType == EConfigType.VMess)
|
if (node.configType == EConfigType.VMess)
|
||||||
{
|
{
|
||||||
VnextItem vnextItem;
|
VnextItem4Ray vnextItem;
|
||||||
if (outbound.settings.vnext.Count <= 0)
|
if (outbound.settings.vnext.Count <= 0)
|
||||||
{
|
{
|
||||||
vnextItem = new VnextItem();
|
vnextItem = new VnextItem4Ray();
|
||||||
outbound.settings.vnext.Add(vnextItem);
|
outbound.settings.vnext.Add(vnextItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -307,10 +309,10 @@ namespace v2rayN.Handler
|
||||||
vnextItem.address = node.address;
|
vnextItem.address = node.address;
|
||||||
vnextItem.port = node.port;
|
vnextItem.port = node.port;
|
||||||
|
|
||||||
UsersItem usersItem;
|
UsersItem4Ray usersItem;
|
||||||
if (vnextItem.users.Count <= 0)
|
if (vnextItem.users.Count <= 0)
|
||||||
{
|
{
|
||||||
usersItem = new UsersItem();
|
usersItem = new UsersItem4Ray();
|
||||||
vnextItem.users.Add(usersItem);
|
vnextItem.users.Add(usersItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -330,19 +332,17 @@ namespace v2rayN.Handler
|
||||||
usersItem.security = Global.DefaultSecurity;
|
usersItem.security = Global.DefaultSecurity;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mux
|
outboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
||||||
outbound.mux.enabled = _config.coreBasicItem.muxEnabled;
|
|
||||||
outbound.mux.concurrency = _config.coreBasicItem.muxEnabled ? 8 : -1;
|
|
||||||
|
|
||||||
outbound.protocol = Global.vmessProtocolLite;
|
outbound.protocol = Global.vmessProtocolLite;
|
||||||
outbound.settings.servers = null;
|
outbound.settings.servers = null;
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.Shadowsocks)
|
else if (node.configType == EConfigType.Shadowsocks)
|
||||||
{
|
{
|
||||||
ServersItem serversItem;
|
ServersItem4Ray serversItem;
|
||||||
if (outbound.settings.servers.Count <= 0)
|
if (outbound.settings.servers.Count <= 0)
|
||||||
{
|
{
|
||||||
serversItem = new ServersItem();
|
serversItem = new ServersItem4Ray();
|
||||||
outbound.settings.servers.Add(serversItem);
|
outbound.settings.servers.Add(serversItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -357,18 +357,17 @@ namespace v2rayN.Handler
|
||||||
serversItem.ota = false;
|
serversItem.ota = false;
|
||||||
serversItem.level = 1;
|
serversItem.level = 1;
|
||||||
|
|
||||||
outbound.mux.enabled = false;
|
outboundMux(node, outbound, false);
|
||||||
outbound.mux.concurrency = -1;
|
|
||||||
|
|
||||||
outbound.protocol = Global.ssProtocolLite;
|
outbound.protocol = Global.ssProtocolLite;
|
||||||
outbound.settings.vnext = null;
|
outbound.settings.vnext = null;
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.Socks)
|
else if (node.configType == EConfigType.Socks)
|
||||||
{
|
{
|
||||||
ServersItem serversItem;
|
ServersItem4Ray serversItem;
|
||||||
if (outbound.settings.servers.Count <= 0)
|
if (outbound.settings.servers.Count <= 0)
|
||||||
{
|
{
|
||||||
serversItem = new ServersItem();
|
serversItem = new ServersItem4Ray();
|
||||||
outbound.settings.servers.Add(serversItem);
|
outbound.settings.servers.Add(serversItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -383,28 +382,27 @@ namespace v2rayN.Handler
|
||||||
if (!Utils.IsNullOrEmpty(node.security)
|
if (!Utils.IsNullOrEmpty(node.security)
|
||||||
&& !Utils.IsNullOrEmpty(node.id))
|
&& !Utils.IsNullOrEmpty(node.id))
|
||||||
{
|
{
|
||||||
SocksUsersItem socksUsersItem = new()
|
SocksUsersItem4Ray socksUsersItem = new()
|
||||||
{
|
{
|
||||||
user = node.security,
|
user = node.security,
|
||||||
pass = node.id,
|
pass = node.id,
|
||||||
level = 1
|
level = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
serversItem.users = new List<SocksUsersItem>() { socksUsersItem };
|
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
|
||||||
}
|
}
|
||||||
|
|
||||||
outbound.mux.enabled = false;
|
outboundMux(node, outbound, false);
|
||||||
outbound.mux.concurrency = -1;
|
|
||||||
|
|
||||||
outbound.protocol = Global.socksProtocolLite;
|
outbound.protocol = Global.socksProtocolLite;
|
||||||
outbound.settings.vnext = null;
|
outbound.settings.vnext = null;
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.VLESS)
|
else if (node.configType == EConfigType.VLESS)
|
||||||
{
|
{
|
||||||
VnextItem vnextItem;
|
VnextItem4Ray vnextItem;
|
||||||
if (outbound.settings.vnext.Count <= 0)
|
if (outbound.settings.vnext.Count <= 0)
|
||||||
{
|
{
|
||||||
vnextItem = new VnextItem();
|
vnextItem = new VnextItem4Ray();
|
||||||
outbound.settings.vnext.Add(vnextItem);
|
outbound.settings.vnext.Add(vnextItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -414,10 +412,10 @@ namespace v2rayN.Handler
|
||||||
vnextItem.address = node.address;
|
vnextItem.address = node.address;
|
||||||
vnextItem.port = node.port;
|
vnextItem.port = node.port;
|
||||||
|
|
||||||
UsersItem usersItem;
|
UsersItem4Ray usersItem;
|
||||||
if (vnextItem.users.Count <= 0)
|
if (vnextItem.users.Count <= 0)
|
||||||
{
|
{
|
||||||
usersItem = new UsersItem();
|
usersItem = new UsersItem4Ray();
|
||||||
vnextItem.users.Add(usersItem);
|
vnextItem.users.Add(usersItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -429,9 +427,7 @@ namespace v2rayN.Handler
|
||||||
usersItem.email = Global.userEMail;
|
usersItem.email = Global.userEMail;
|
||||||
usersItem.encryption = node.security;
|
usersItem.encryption = node.security;
|
||||||
|
|
||||||
//Mux
|
outboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
||||||
outbound.mux.enabled = _config.coreBasicItem.muxEnabled;
|
|
||||||
outbound.mux.concurrency = _config.coreBasicItem.muxEnabled ? 8 : -1;
|
|
||||||
|
|
||||||
if (node.streamSecurity == Global.StreamSecurityReality
|
if (node.streamSecurity == Global.StreamSecurityReality
|
||||||
|| node.streamSecurity == Global.StreamSecurity)
|
|| node.streamSecurity == Global.StreamSecurity)
|
||||||
|
@ -440,20 +436,23 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
usersItem.flow = node.flow;
|
usersItem.flow = node.flow;
|
||||||
|
|
||||||
outbound.mux.enabled = false;
|
outboundMux(node, outbound, false);
|
||||||
outbound.mux.concurrency = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow))
|
||||||
|
{
|
||||||
|
outboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
outbound.protocol = Global.vlessProtocolLite;
|
outbound.protocol = Global.vlessProtocolLite;
|
||||||
outbound.settings.servers = null;
|
outbound.settings.servers = null;
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.Trojan)
|
else if (node.configType == EConfigType.Trojan)
|
||||||
{
|
{
|
||||||
ServersItem serversItem;
|
ServersItem4Ray serversItem;
|
||||||
if (outbound.settings.servers.Count <= 0)
|
if (outbound.settings.servers.Count <= 0)
|
||||||
{
|
{
|
||||||
serversItem = new ServersItem();
|
serversItem = new ServersItem4Ray();
|
||||||
outbound.settings.servers.Add(serversItem);
|
outbound.settings.servers.Add(serversItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -468,8 +467,7 @@ namespace v2rayN.Handler
|
||||||
serversItem.ota = false;
|
serversItem.ota = false;
|
||||||
serversItem.level = 1;
|
serversItem.level = 1;
|
||||||
|
|
||||||
outbound.mux.enabled = false;
|
outboundMux(node, outbound, false);
|
||||||
outbound.mux.concurrency = -1;
|
|
||||||
|
|
||||||
outbound.protocol = Global.trojanProtocolLite;
|
outbound.protocol = Global.trojanProtocolLite;
|
||||||
outbound.settings.vnext = null;
|
outbound.settings.vnext = null;
|
||||||
|
@ -483,7 +481,29 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
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
|
try
|
||||||
{
|
{
|
||||||
|
@ -508,7 +528,7 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
streamSettings.security = node.streamSecurity;
|
streamSettings.security = node.streamSecurity;
|
||||||
|
|
||||||
TlsSettings tlsSettings = new()
|
TlsSettings4Ray tlsSettings = new()
|
||||||
{
|
{
|
||||||
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
|
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
|
||||||
alpn = node.GetAlpn(),
|
alpn = node.GetAlpn(),
|
||||||
|
@ -530,7 +550,7 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
streamSettings.security = node.streamSecurity;
|
streamSettings.security = node.streamSecurity;
|
||||||
|
|
||||||
TlsSettings realitySettings = new()
|
TlsSettings4Ray realitySettings = new()
|
||||||
{
|
{
|
||||||
fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint,
|
fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint,
|
||||||
serverName = sni,
|
serverName = sni,
|
||||||
|
@ -546,7 +566,7 @@ namespace v2rayN.Handler
|
||||||
switch (node.GetNetwork())
|
switch (node.GetNetwork())
|
||||||
{
|
{
|
||||||
case "kcp":
|
case "kcp":
|
||||||
KcpSettings kcpSettings = new()
|
KcpSettings4Ray kcpSettings = new()
|
||||||
{
|
{
|
||||||
mtu = _config.kcpItem.mtu,
|
mtu = _config.kcpItem.mtu,
|
||||||
tti = _config.kcpItem.tti
|
tti = _config.kcpItem.tti
|
||||||
|
@ -558,7 +578,7 @@ namespace v2rayN.Handler
|
||||||
kcpSettings.congestion = _config.kcpItem.congestion;
|
kcpSettings.congestion = _config.kcpItem.congestion;
|
||||||
kcpSettings.readBufferSize = _config.kcpItem.readBufferSize;
|
kcpSettings.readBufferSize = _config.kcpItem.readBufferSize;
|
||||||
kcpSettings.writeBufferSize = _config.kcpItem.writeBufferSize;
|
kcpSettings.writeBufferSize = _config.kcpItem.writeBufferSize;
|
||||||
kcpSettings.header = new Header
|
kcpSettings.header = new Header4Ray
|
||||||
{
|
{
|
||||||
type = node.headerType
|
type = node.headerType
|
||||||
};
|
};
|
||||||
|
@ -570,8 +590,8 @@ namespace v2rayN.Handler
|
||||||
break;
|
break;
|
||||||
//ws
|
//ws
|
||||||
case "ws":
|
case "ws":
|
||||||
WsSettings wsSettings = new();
|
WsSettings4Ray wsSettings = new();
|
||||||
wsSettings.headers = new Headers();
|
wsSettings.headers = new Headers4Ray();
|
||||||
string path = node.path;
|
string path = node.path;
|
||||||
if (!string.IsNullOrWhiteSpace(host))
|
if (!string.IsNullOrWhiteSpace(host))
|
||||||
{
|
{
|
||||||
|
@ -590,7 +610,7 @@ namespace v2rayN.Handler
|
||||||
break;
|
break;
|
||||||
//h2
|
//h2
|
||||||
case "h2":
|
case "h2":
|
||||||
HttpSettings httpSettings = new();
|
HttpSettings4Ray httpSettings = new();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(host))
|
if (!string.IsNullOrWhiteSpace(host))
|
||||||
{
|
{
|
||||||
|
@ -603,11 +623,11 @@ namespace v2rayN.Handler
|
||||||
break;
|
break;
|
||||||
//quic
|
//quic
|
||||||
case "quic":
|
case "quic":
|
||||||
QuicSettings quicsettings = new()
|
QuicSettings4Ray quicsettings = new()
|
||||||
{
|
{
|
||||||
security = host,
|
security = host,
|
||||||
key = node.path,
|
key = node.path,
|
||||||
header = new Header
|
header = new Header4Ray
|
||||||
{
|
{
|
||||||
type = node.headerType
|
type = node.headerType
|
||||||
}
|
}
|
||||||
|
@ -627,7 +647,7 @@ namespace v2rayN.Handler
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "grpc":
|
case "grpc":
|
||||||
GrpcSettings grpcSettings = new()
|
GrpcSettings4Ray grpcSettings = new()
|
||||||
{
|
{
|
||||||
serviceName = node.path,
|
serviceName = node.path,
|
||||||
multiMode = (node.headerType == Global.GrpcmultiMode),
|
multiMode = (node.headerType == Global.GrpcmultiMode),
|
||||||
|
@ -643,9 +663,9 @@ namespace v2rayN.Handler
|
||||||
//tcp
|
//tcp
|
||||||
if (node.headerType == Global.TcpHeaderHttp)
|
if (node.headerType == Global.TcpHeaderHttp)
|
||||||
{
|
{
|
||||||
TcpSettings tcpSettings = new()
|
TcpSettings4Ray tcpSettings = new()
|
||||||
{
|
{
|
||||||
header = new Header
|
header = new Header4Ray
|
||||||
{
|
{
|
||||||
type = node.headerType
|
type = node.headerType
|
||||||
}
|
}
|
||||||
|
@ -718,7 +738,7 @@ namespace v2rayN.Handler
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
//servers.Add("localhost");
|
//servers.Add("localhost");
|
||||||
v2rayConfig.dns = new Mode.Dns
|
v2rayConfig.dns = new Mode.Dns4Ray
|
||||||
{
|
{
|
||||||
servers = servers
|
servers = servers
|
||||||
};
|
};
|
||||||
|
@ -736,13 +756,13 @@ namespace v2rayN.Handler
|
||||||
if (_config.guiItem.enableStatistics)
|
if (_config.guiItem.enableStatistics)
|
||||||
{
|
{
|
||||||
string tag = Global.InboundAPITagName;
|
string tag = Global.InboundAPITagName;
|
||||||
API apiObj = new();
|
API4Ray apiObj = new();
|
||||||
Policy policyObj = new();
|
Policy4Ray policyObj = new();
|
||||||
SystemPolicy policySystemSetting = new();
|
SystemPolicy4Ray policySystemSetting = new();
|
||||||
|
|
||||||
string[] services = { "StatsService" };
|
string[] services = { "StatsService" };
|
||||||
|
|
||||||
v2rayConfig.stats = new Stats();
|
v2rayConfig.stats = new Stats4Ray();
|
||||||
|
|
||||||
apiObj.tag = tag;
|
apiObj.tag = tag;
|
||||||
apiObj.services = services.ToList();
|
apiObj.services = services.ToList();
|
||||||
|
@ -755,8 +775,8 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
if (!v2rayConfig.inbounds.Exists(item => item.tag == tag))
|
if (!v2rayConfig.inbounds.Exists(item => item.tag == tag))
|
||||||
{
|
{
|
||||||
Inbounds apiInbound = new();
|
Inbounds4Ray apiInbound = new();
|
||||||
Inboundsettings apiInboundSettings = new();
|
Inboundsettings4Ray apiInboundSettings = new();
|
||||||
apiInbound.tag = tag;
|
apiInbound.tag = tag;
|
||||||
apiInbound.listen = Global.Loopback;
|
apiInbound.listen = Global.Loopback;
|
||||||
apiInbound.port = Global.statePort;
|
apiInbound.port = Global.statePort;
|
||||||
|
@ -768,12 +788,13 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
if (!v2rayConfig.routing.rules.Exists(item => item.outboundTag == tag))
|
if (!v2rayConfig.routing.rules.Exists(item => item.outboundTag == tag))
|
||||||
{
|
{
|
||||||
RulesItem apiRoutingRule = new()
|
RulesItem4Ray apiRoutingRule = new()
|
||||||
{
|
{
|
||||||
inboundTag = new List<string> { tag },
|
inboundTag = new List<string> { tag },
|
||||||
outboundTag = tag,
|
outboundTag = tag,
|
||||||
type = "field"
|
type = "field"
|
||||||
};
|
};
|
||||||
|
|
||||||
v2rayConfig.routing.rules.Add(apiRoutingRule);
|
v2rayConfig.routing.rules.Add(apiRoutingRule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -873,7 +894,7 @@ namespace v2rayN.Handler
|
||||||
it.allowTest = true;
|
it.allowTest = true;
|
||||||
|
|
||||||
//inbound
|
//inbound
|
||||||
Inbounds inbound = new()
|
Inbounds4Ray inbound = new()
|
||||||
{
|
{
|
||||||
listen = Global.Loopback,
|
listen = Global.Loopback,
|
||||||
port = port,
|
port = port,
|
||||||
|
@ -905,7 +926,7 @@ namespace v2rayN.Handler
|
||||||
v2rayConfig.outbounds.Add(v2rayConfigCopy.outbounds[0]);
|
v2rayConfig.outbounds.Add(v2rayConfigCopy.outbounds[0]);
|
||||||
|
|
||||||
//rule
|
//rule
|
||||||
RulesItem rule = new()
|
RulesItem4Ray rule = new()
|
||||||
{
|
{
|
||||||
inboundTag = new List<string> { inbound.tag },
|
inboundTag = new List<string> { inbound.tag },
|
||||||
outboundTag = v2rayConfigCopy.outbounds[0].tag,
|
outboundTag = v2rayConfigCopy.outbounds[0].tag,
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace v2rayN.Handler
|
||||||
internal class CoreHandler
|
internal class CoreHandler
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
private CoreInfo? _coreInfo;
|
|
||||||
private Process? _process;
|
private Process? _process;
|
||||||
private Process? _processPre;
|
private Process? _processPre;
|
||||||
private Action<bool, string> _updateFunc;
|
private Action<bool, string> _updateFunc;
|
||||||
|
@ -35,11 +34,6 @@ namespace v2rayN.Handler
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SetCore(node) != 0)
|
|
||||||
{
|
|
||||||
ShowMsg(false, ResUI.CheckServerSettings);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string fileName = Utils.GetConfigPath(Global.coreConfigFileName);
|
string fileName = Utils.GetConfigPath(Global.coreConfigFileName);
|
||||||
if (CoreConfigHandler.GenerateClientConfig(node, fileName, out string msg, out string content) != 0)
|
if (CoreConfigHandler.GenerateClientConfig(node, fileName, out string msg, out string content) != 0)
|
||||||
{
|
{
|
||||||
|
@ -74,30 +68,13 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
bool hasProc = false;
|
||||||
if (_process != null)
|
if (_process != null)
|
||||||
{
|
{
|
||||||
KillProcess(_process);
|
KillProcess(_process);
|
||||||
_process.Dispose();
|
_process.Dispose();
|
||||||
_process = null;
|
_process = null;
|
||||||
}
|
hasProc = true;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_processPre != null)
|
if (_processPre != null)
|
||||||
|
@ -105,6 +82,31 @@ namespace v2rayN.Handler
|
||||||
KillProcess(_processPre);
|
KillProcess(_processPre);
|
||||||
_processPre.Dispose();
|
_processPre.Dispose();
|
||||||
_processPre = null;
|
_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)
|
catch (Exception ex)
|
||||||
|
@ -152,7 +154,19 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString()));
|
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)
|
if (proc is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -162,21 +176,20 @@ namespace v2rayN.Handler
|
||||||
//start a socks service
|
//start a socks service
|
||||||
if (_process != null && !_process.HasExited)
|
if (_process != null && !_process.HasExited)
|
||||||
{
|
{
|
||||||
if ((node.configType == EConfigType.Custom && node.preSocksPort > 0)
|
if ((node.configType == EConfigType.Custom && node.preSocksPort > 0))
|
||||||
|| (node.configType != EConfigType.Custom && _coreInfo.coreType != ECoreType.sing_box && _config.tunModeItem.enableTun))
|
|
||||||
{
|
{
|
||||||
var itemSocks = new ProfileItem()
|
var itemSocks = new ProfileItem()
|
||||||
{
|
{
|
||||||
coreType = ECoreType.sing_box,
|
coreType = ECoreType.sing_box,
|
||||||
configType = EConfigType.Socks,
|
configType = EConfigType.Socks,
|
||||||
address = Global.Loopback,
|
address = Global.Loopback,
|
||||||
port = node.preSocksPort > 0 ? node.preSocksPort : LazyConfig.Instance.GetLocalPort(Global.InboundSocks)
|
port = node.preSocksPort
|
||||||
};
|
};
|
||||||
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 coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box);
|
var coreInfo2 = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box);
|
||||||
var proc2 = RunProcess(node, coreInfo, $" -c {Global.corePreConfigFileName}", ShowMsg);
|
var proc2 = RunProcess(node, coreInfo2, $" -c {Global.corePreConfigFileName}", true, ShowMsg);
|
||||||
if (proc2 is not null)
|
if (proc2 is not null)
|
||||||
{
|
{
|
||||||
_processPre = proc2;
|
_processPre = proc2;
|
||||||
|
@ -257,26 +270,9 @@ namespace v2rayN.Handler
|
||||||
_updateFunc(updateToTrayTooltip, msg);
|
_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
|
#region Process
|
||||||
|
|
||||||
private Process? RunProcess(ProfileItem node, CoreInfo coreInfo, string configPath, Action<bool, string> update)
|
private Process? RunProcess(ProfileItem node, CoreInfo coreInfo, string configPath, bool displayLog, Action<bool, string> update)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -285,7 +281,6 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var displayLog = node.configType != EConfigType.Custom || node.displayLog;
|
|
||||||
Process proc = new()
|
Process proc = new()
|
||||||
{
|
{
|
||||||
StartInfo = new ProcessStartInfo
|
StartInfo = new ProcessStartInfo
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using Grpc.Core;
|
using System.Net;
|
||||||
using Grpc.Net.Client;
|
|
||||||
using ProtosLib.Statistics;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using v2rayN.Base;
|
using v2rayN.Base;
|
||||||
using v2rayN.Mode;
|
using v2rayN.Mode;
|
||||||
|
@ -10,51 +7,40 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
internal class StatisticsHandler
|
internal class StatisticsHandler
|
||||||
{
|
{
|
||||||
private Mode.Config config_;
|
private Config _config;
|
||||||
private GrpcChannel _channel;
|
|
||||||
private StatsService.StatsServiceClient _client;
|
|
||||||
private bool _exitFlag;
|
|
||||||
private ServerStatItem? _serverStatItem;
|
private ServerStatItem? _serverStatItem;
|
||||||
private List<ServerStatItem> _lstServerStat;
|
private List<ServerStatItem> _lstServerStat;
|
||||||
public List<ServerStatItem> ServerStat => _lstServerStat;
|
|
||||||
|
|
||||||
private Action<ServerSpeedItem> _updateFunc;
|
private Action<ServerSpeedItem> _updateFunc;
|
||||||
|
private StatisticsV2ray? _statisticsV2Ray;
|
||||||
|
private StatisticsSingbox? _statisticsSingbox;
|
||||||
|
|
||||||
public bool Enable
|
public List<ServerStatItem> ServerStat => _lstServerStat;
|
||||||
{
|
public bool Enable { get; set; }
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StatisticsHandler(Mode.Config config, Action<ServerSpeedItem> update)
|
public StatisticsHandler(Config config, Action<ServerSpeedItem> update)
|
||||||
{
|
{
|
||||||
config_ = config;
|
_config = config;
|
||||||
Enable = config.guiItem.enableStatistics;
|
Enable = config.guiItem.enableStatistics;
|
||||||
|
if (!Enable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_updateFunc = update;
|
_updateFunc = update;
|
||||||
_exitFlag = false;
|
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
GrpcInit();
|
Global.statePort = GetFreePort();
|
||||||
|
|
||||||
Task.Run(Run);
|
_statisticsV2Ray = new StatisticsV2ray(config, UpdateServerStat);
|
||||||
}
|
_statisticsSingbox = new StatisticsSingbox(config, UpdateServerStat);
|
||||||
|
|
||||||
private void GrpcInit()
|
|
||||||
{
|
|
||||||
if (_channel == null)
|
|
||||||
{
|
|
||||||
Global.statePort = GetFreePort();
|
|
||||||
|
|
||||||
_channel = GrpcChannel.ForAddress($"{Global.httpProtocol}{Global.Loopback}:{Global.statePort}");
|
|
||||||
_client = new StatsService.StatsServiceClient(_channel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_exitFlag = true;
|
_statisticsV2Ray?.Close();
|
||||||
//channel_.ShutdownAsync();
|
_statisticsSingbox?.Close();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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()
|
public void ClearAllServerStatistics()
|
||||||
{
|
{
|
||||||
SqliteHelper.Instance.Execute($"delete from ServerStatItem ");
|
SqliteHelper.Instance.Execute($"delete from ServerStatItem ");
|
||||||
|
@ -142,6 +77,28 @@ namespace v2rayN.Handler
|
||||||
_lstServerStat = SqliteHelper.Instance.Table<ServerStatItem>().ToList();
|
_lstServerStat = SqliteHelper.Instance.Table<ServerStatItem>().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)
|
private void GetServerStatItem(string indexId)
|
||||||
{
|
{
|
||||||
long ticks = DateTime.Now.Date.Ticks;
|
long ticks = DateTime.Now.Date.Ticks;
|
||||||
|
@ -177,71 +134,28 @@ namespace v2rayN.Handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ParseOutput(Google.Protobuf.Collections.RepeatedField<Stat> 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()
|
private int GetFreePort()
|
||||||
{
|
{
|
||||||
int defaultPort = 28123;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TCP stack please do me a favor
|
int defaultPort = 9090;
|
||||||
TcpListener l = new(IPAddress.Loopback, 0);
|
if (!Utils.PortInUse(defaultPort))
|
||||||
l.Start();
|
{
|
||||||
int port = ((IPEndPoint)l.LocalEndpoint).Port;
|
return defaultPort;
|
||||||
l.Stop();
|
}
|
||||||
return port;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
127
v2rayN/v2rayN/Handler/StatisticsSingbox.cs
Normal file
127
v2rayN/v2rayN/Handler/StatisticsSingbox.cs
Normal file
|
@ -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<ServerSpeedItem> _updateFunc;
|
||||||
|
|
||||||
|
public StatisticsSingbox(Config config, Action<ServerSpeedItem> 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<byte>(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<byte>(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<TrafficItem>(source);
|
||||||
|
if (trafficItem != null)
|
||||||
|
{
|
||||||
|
up = trafficItem.up;
|
||||||
|
down = trafficItem.down;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
v2rayN/v2rayN/Handler/StatisticsV2ray.cs
Normal file
120
v2rayN/v2rayN/Handler/StatisticsV2ray.cs
Normal file
|
@ -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<ServerSpeedItem> _updateFunc;
|
||||||
|
|
||||||
|
public StatisticsV2ray(Mode.Config config, Action<ServerSpeedItem> 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<Stat> 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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<TunHandler> _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<string> lstDnsExe, out List<string> 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<string> lstDnsExe, out List<string> 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,6 +27,7 @@
|
||||||
public UIItem uiItem { get; set; }
|
public UIItem uiItem { get; set; }
|
||||||
public ConstItem constItem { get; set; }
|
public ConstItem constItem { get; set; }
|
||||||
public SpeedTestItem speedTestItem { get; set; }
|
public SpeedTestItem speedTestItem { get; set; }
|
||||||
|
public Mux4Sbox mux4Sbox { get; set; }
|
||||||
public List<InItem> inbound { get; set; }
|
public List<InItem> inbound { get; set; }
|
||||||
public List<KeyEventItem> globalHotkeys { get; set; }
|
public List<KeyEventItem> globalHotkeys { get; set; }
|
||||||
public List<CoreTypeItem> coreTypeItem { get; set; }
|
public List<CoreTypeItem> coreTypeItem { get; set; }
|
||||||
|
|
|
@ -161,19 +161,9 @@ namespace v2rayN.Mode
|
||||||
public class TunModeItem
|
public class TunModeItem
|
||||||
{
|
{
|
||||||
public bool enableTun { get; set; }
|
public bool enableTun { get; set; }
|
||||||
public bool showWindow { get; set; }
|
|
||||||
public bool enabledLog { get; set; }
|
|
||||||
public bool strictRoute { get; set; }
|
public bool strictRoute { get; set; }
|
||||||
public string stack { get; set; }
|
public string stack { get; set; }
|
||||||
public int mtu { get; set; }
|
public int mtu { get; set; }
|
||||||
public string customTemplate { get; set; }
|
|
||||||
public bool bypassMode { get; set; } = true;
|
|
||||||
public List<string> directIP { get; set; }
|
|
||||||
public List<string> directProcess { get; set; }
|
|
||||||
public string directDNS { get; set; }
|
|
||||||
public List<string> proxyIP { get; set; }
|
|
||||||
public List<string> proxyProcess { get; set; }
|
|
||||||
public string proxyDNS { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
@ -191,6 +181,7 @@ namespace v2rayN.Mode
|
||||||
/// 域名解析策略
|
/// 域名解析策略
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string domainStrategy { get; set; }
|
public string domainStrategy { get; set; }
|
||||||
|
|
||||||
public string domainStrategy4Singbox { get; set; }
|
public string domainStrategy4Singbox { get; set; }
|
||||||
|
|
||||||
public string domainMatcher { get; set; }
|
public string domainMatcher { get; set; }
|
||||||
|
@ -205,4 +196,14 @@ namespace v2rayN.Mode
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
public int Index { 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; }
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -12,8 +12,7 @@ namespace v2rayN.Mode
|
||||||
public bool enabled { get; set; } = true;
|
public bool enabled { get; set; } = true;
|
||||||
public ECoreType coreType { get; set; }
|
public ECoreType coreType { get; set; }
|
||||||
public string? normalDNS { get; set; }
|
public string? normalDNS { get; set; }
|
||||||
public string? directDNS { get; set; }
|
public string? tunDNS { get; set; }
|
||||||
public string? proxyDNS { get; set; }
|
|
||||||
public string? domainStrategy4Freedom { get; set; }
|
public string? domainStrategy4Freedom { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
public List<string> protocol { get; set; }
|
public List<string> protocol { get; set; }
|
||||||
|
|
||||||
|
public List<string> process { get; set; }
|
||||||
|
|
||||||
public bool enabled { get; set; } = true;
|
public bool enabled { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,4 +23,18 @@
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class TrafficItem
|
||||||
|
{
|
||||||
|
public ulong up
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong down
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -127,6 +127,7 @@
|
||||||
public int max_connections { get; set; }
|
public int max_connections { get; set; }
|
||||||
public int min_streams { get; set; }
|
public int min_streams { get; set; }
|
||||||
public int max_streams { get; set; }
|
public int max_streams { get; set; }
|
||||||
|
public bool padding { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Utls4Sbox
|
public class Utls4Sbox
|
||||||
|
@ -147,12 +148,19 @@
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
public List<string>? host { get; set; }
|
public List<string>? host { get; set; }
|
||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
|
public Headers4Sbox? headers { get; set; }
|
||||||
|
|
||||||
public string service_name { get; set; }
|
public string service_name { get; set; }
|
||||||
public string idle_timeout { get; set; }
|
public string idle_timeout { get; set; }
|
||||||
public string ping_timeout { get; set; }
|
public string ping_timeout { get; set; }
|
||||||
public bool? permit_without_stream { get; set; }
|
public bool? permit_without_stream { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Headers4Sbox
|
||||||
|
{
|
||||||
|
public string? Host { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class Server4Sbox
|
public class Server4Sbox
|
||||||
{
|
{
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
|
@ -165,6 +173,7 @@
|
||||||
public class Experimental4Sbox
|
public class Experimental4Sbox
|
||||||
{
|
{
|
||||||
public V2ray_Api4Sbox v2ray_api { get; set; }
|
public V2ray_Api4Sbox v2ray_api { get; set; }
|
||||||
|
public Clash_Api4Sbox clash_api { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class V2ray_Api4Sbox
|
public class V2ray_Api4Sbox
|
||||||
|
@ -173,6 +182,12 @@
|
||||||
public Stats4Sbox stats { get; set; }
|
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 class Stats4Sbox
|
||||||
{
|
{
|
||||||
public bool enabled { get; set; }
|
public bool enabled { get; set; }
|
||||||
|
|
|
@ -11,28 +11,28 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日志配置
|
/// 日志配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Log log { get; set; }
|
public Log4Ray log { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 传入连接配置
|
/// 传入连接配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<Inbounds> inbounds { get; set; }
|
public List<Inbounds4Ray> inbounds { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 传出连接配置
|
/// 传出连接配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<Outbounds> outbounds { get; set; }
|
public List<Outbounds4Ray> outbounds { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 统计需要, 空对象
|
/// 统计需要, 空对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Stats stats { get; set; }
|
public Stats4Ray stats { get; set; }
|
||||||
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public API api { get; set; }
|
public API4Ray api { get; set; }
|
||||||
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Policy policy;
|
public Policy4Ray policy;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DNS 配置
|
/// DNS 配置
|
||||||
|
@ -42,30 +42,30 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 路由配置
|
/// 路由配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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 string tag { get; set; }
|
||||||
public List<string> services { get; set; }
|
public List<string> 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 statsOutboundUplink;
|
||||||
public bool statsOutboundDownlink;
|
public bool statsOutboundDownlink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Log
|
public class Log4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -83,7 +83,7 @@ namespace v2rayN.Mode
|
||||||
public string loglevel { get; set; }
|
public string loglevel { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Inbounds
|
public class Inbounds4Ray
|
||||||
{
|
{
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
|
|
||||||
|
@ -105,20 +105,20 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Sniffing sniffing { get; set; }
|
public Sniffing4Ray sniffing { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Inboundsettings settings { get; set; }
|
public Inboundsettings4Ray settings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StreamSettings streamSettings { get; set; }
|
public StreamSettings4Ray streamSettings { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Inboundsettings
|
public class Inboundsettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -143,7 +143,7 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<UsersItem> clients { get; set; }
|
public List<UsersItem4Ray> clients { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VLESS
|
/// VLESS
|
||||||
|
@ -152,10 +152,10 @@ namespace v2rayN.Mode
|
||||||
|
|
||||||
public bool allowTransparent { get; set; }
|
public bool allowTransparent { get; set; }
|
||||||
|
|
||||||
public List<AccountsItem> accounts { get; set; }
|
public List<AccountsItem4Ray> accounts { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UsersItem
|
public class UsersItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -188,14 +188,14 @@ namespace v2rayN.Mode
|
||||||
public string flow { get; set; }
|
public string flow { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Sniffing
|
public class Sniffing4Ray
|
||||||
{
|
{
|
||||||
public bool enabled { get; set; }
|
public bool enabled { get; set; }
|
||||||
public List<string> destOverride { get; set; }
|
public List<string> destOverride { get; set; }
|
||||||
public bool routeOnly { get; set; }
|
public bool routeOnly { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Outbounds
|
public class Outbounds4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认值agentout
|
/// 默认值agentout
|
||||||
|
@ -210,35 +210,35 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Outboundsettings settings { get; set; }
|
public Outboundsettings4Ray settings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StreamSettings streamSettings { get; set; }
|
public StreamSettings4Ray streamSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Mux mux { get; set; }
|
public Mux4Ray mux { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Outboundsettings
|
public class Outboundsettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<VnextItem> vnext { get; set; }
|
public List<VnextItem4Ray> vnext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ServersItem> servers { get; set; }
|
public List<ServersItem4Ray> servers { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Response response { get; set; }
|
public Response4Ray response { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -251,7 +251,7 @@ namespace v2rayN.Mode
|
||||||
public int? userLevel { get; set; }
|
public int? userLevel { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VnextItem
|
public class VnextItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -266,10 +266,10 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<UsersItem> users { get; set; }
|
public List<UsersItem4Ray> users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServersItem
|
public class ServersItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -314,10 +314,10 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<SocksUsersItem> users { get; set; }
|
public List<SocksUsersItem4Ray> users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SocksUsersItem
|
public class SocksUsersItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -335,7 +335,7 @@ namespace v2rayN.Mode
|
||||||
public int level { get; set; }
|
public int level { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Mux
|
public class Mux4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -348,7 +348,7 @@ namespace v2rayN.Mode
|
||||||
public int concurrency { get; set; }
|
public int concurrency { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Response
|
public class Response4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -356,7 +356,7 @@ namespace v2rayN.Mode
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Dns
|
public class Dns4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -364,7 +364,7 @@ namespace v2rayN.Mode
|
||||||
public List<string> servers { get; set; }
|
public List<string> servers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Routing
|
public class Routing4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -379,10 +379,28 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<RulesItem> rules { get; set; }
|
public List<RulesItem4Ray> rules { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StreamSettings
|
[Serializable]
|
||||||
|
public class RulesItem4Ray
|
||||||
|
{
|
||||||
|
public string type { get; set; }
|
||||||
|
|
||||||
|
public string port { get; set; }
|
||||||
|
|
||||||
|
public List<string> inboundTag { get; set; }
|
||||||
|
|
||||||
|
public string outboundTag { get; set; }
|
||||||
|
|
||||||
|
public List<string> ip { get; set; }
|
||||||
|
|
||||||
|
public List<string> domain { get; set; }
|
||||||
|
|
||||||
|
public List<string> protocol { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StreamSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -397,45 +415,45 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TlsSettings tlsSettings { get; set; }
|
public TlsSettings4Ray tlsSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tcp传输额外设置
|
/// Tcp传输额外设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TcpSettings tcpSettings { get; set; }
|
public TcpSettings4Ray tcpSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Kcp传输额外设置
|
/// Kcp传输额外设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KcpSettings kcpSettings { get; set; }
|
public KcpSettings4Ray kcpSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ws传输额外设置
|
/// ws传输额外设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WsSettings wsSettings { get; set; }
|
public WsSettings4Ray wsSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// h2传输额外设置
|
/// h2传输额外设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HttpSettings httpSettings { get; set; }
|
public HttpSettings4Ray httpSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// QUIC
|
/// QUIC
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public QuicSettings quicSettings { get; set; }
|
public QuicSettings4Ray quicSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VLESS only
|
/// VLESS only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TlsSettings realitySettings { get; set; }
|
public TlsSettings4Ray realitySettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// grpc
|
/// grpc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GrpcSettings grpcSettings { get; set; }
|
public GrpcSettings4Ray grpcSettings { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TlsSettings
|
public class TlsSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否允许不安全连接(用于客户端)
|
/// 是否允许不安全连接(用于客户端)
|
||||||
|
@ -460,15 +478,15 @@ namespace v2rayN.Mode
|
||||||
public string? spiderX { get; set; }
|
public string? spiderX { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TcpSettings
|
public class TcpSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据包头部伪装设置
|
/// 数据包头部伪装设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Header header { get; set; }
|
public Header4Ray header { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Header
|
public class Header4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 伪装
|
/// 伪装
|
||||||
|
@ -486,7 +504,7 @@ namespace v2rayN.Mode
|
||||||
public object response { get; set; }
|
public object response { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KcpSettings
|
public class KcpSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -526,7 +544,7 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Header header { get; set; }
|
public Header4Ray header { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -534,7 +552,7 @@ namespace v2rayN.Mode
|
||||||
public string seed { get; set; }
|
public string seed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WsSettings
|
public class WsSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -544,10 +562,10 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Headers headers { get; set; }
|
public Headers4Ray headers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Headers
|
public class Headers4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -561,7 +579,7 @@ namespace v2rayN.Mode
|
||||||
public string UserAgent { get; set; }
|
public string UserAgent { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HttpSettings
|
public class HttpSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -574,7 +592,7 @@ namespace v2rayN.Mode
|
||||||
public List<string> host { get; set; }
|
public List<string> host { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QuicSettings
|
public class QuicSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -589,10 +607,10 @@ namespace v2rayN.Mode
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Header header { get; set; }
|
public Header4Ray header { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GrpcSettings
|
public class GrpcSettings4Ray
|
||||||
{
|
{
|
||||||
public string serviceName { get; set; }
|
public string serviceName { get; set; }
|
||||||
public bool multiMode { get; set; }
|
public bool multiMode { get; set; }
|
||||||
|
@ -602,7 +620,7 @@ namespace v2rayN.Mode
|
||||||
public int initial_windows_size { get; set; }
|
public int initial_windows_size { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AccountsItem
|
public class AccountsItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|
53
v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
53
v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
|
@ -1853,7 +1853,7 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Domain and ip are auto sorted when saving 的本地化字符串。
|
/// 查找类似 Domain, ip, process are auto sorted when saving 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbAutoSort {
|
public static string TbAutoSort {
|
||||||
get {
|
get {
|
||||||
|
@ -1961,7 +1961,7 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Sing-box domain strategy 的本地化字符串。
|
/// 查找类似 sing-box domain strategy 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbdomainStrategy4Singbox {
|
public static string TbdomainStrategy4Singbox {
|
||||||
get {
|
get {
|
||||||
|
@ -2167,6 +2167,33 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Domain 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbRoutingRuleDomain {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbRoutingRuleDomain", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 IP or IP CIDR 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbRoutingRuleIP {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbRoutingRuleIP", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Full process name (Tun mode) 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbRoutingRuleProcess {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbRoutingRuleProcess", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 3.Block Domain or IP 的本地化字符串。
|
/// 查找类似 3.Block Domain or IP 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2348,7 +2375,7 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Sing-box DNS settings 的本地化字符串。
|
/// 查找类似 sing-box DNS settings 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbSettingsCoreDnsSingbox {
|
public static string TbSettingsCoreDnsSingbox {
|
||||||
get {
|
get {
|
||||||
|
@ -2572,6 +2599,15 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 sing-box Mux Protocol 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSettingsMux4SboxProtocol {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSettingsMux4SboxProtocol", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Turn on Mux Multiplexing 的本地化字符串。
|
/// 查找类似 Turn on Mux Multiplexing 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2770,15 +2806,6 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Enable: If no route matches, the final proxy 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string TbSettingsTunModeBypassModeTip {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("TbSettingsTunModeBypassModeTip", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Custom Template 的本地化字符串。
|
/// 查找类似 Custom Template 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2951,7 +2978,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 sing-box to provide functions such as speed display 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TipPreSocksPort {
|
public static string TipPreSocksPort {
|
||||||
get {
|
get {
|
||||||
|
|
|
@ -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 sing-box 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>
|
||||||
|
|
|
@ -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 sing-box 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>
|
||||||
|
@ -941,7 +941,7 @@
|
||||||
<value>RoutingRuleDetailsSetting</value>
|
<value>RoutingRuleDetailsSetting</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAutoSort" xml:space="preserve">
|
<data name="TbAutoSort" xml:space="preserve">
|
||||||
<value>Domain and ip are auto sorted when saving</value>
|
<value>Domain, ip, process are auto sorted when saving</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRuleobjectDoc" xml:space="preserve">
|
<data name="TbRuleobjectDoc" xml:space="preserve">
|
||||||
<value>Ruleobject Doc</value>
|
<value>Ruleobject Doc</value>
|
||||||
|
@ -1057,9 +1057,6 @@
|
||||||
<data name="TbSettingsTunModeBypassMode" xml:space="preserve">
|
<data name="TbSettingsTunModeBypassMode" xml:space="preserve">
|
||||||
<value>Bypass Mode</value>
|
<value>Bypass Mode</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsTunModeBypassModeTip" xml:space="preserve">
|
|
||||||
<value>Enable: If no route matches, the final proxy</value>
|
|
||||||
</data>
|
|
||||||
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
|
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
|
||||||
<value>SpeedTest Single Timeout Value</value>
|
<value>SpeedTest Single Timeout Value</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -1118,7 +1115,7 @@
|
||||||
<value>DNS Settings</value>
|
<value>DNS Settings</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
|
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
|
||||||
<value>Sing-box DNS settings</value>
|
<value>sing-box DNS settings</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
||||||
<value>Please fill in DNS Structure, Click to view the document</value>
|
<value>Please fill in DNS Structure, Click to view the document</value>
|
||||||
|
@ -1127,6 +1124,18 @@
|
||||||
<value>Click to import default DNS config</value>
|
<value>Click to import default DNS config</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
||||||
<value>Sing-box domain strategy</value>
|
<value>sing-box domain strategy</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
|
||||||
|
<value>sing-box Mux Protocol</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
||||||
|
<value>Full process name (Tun mode)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleIP" xml:space="preserve">
|
||||||
|
<value>IP or IP CIDR</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleDomain" xml:space="preserve">
|
||||||
|
<value>Domain</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -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 будет запущена с использованием sing-box для обеспечения таких функций, как отображение скорости</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbBrowse" xml:space="preserve">
|
<data name="TbBrowse" xml:space="preserve">
|
||||||
<value>Просмотр</value>
|
<value>Просмотр</value>
|
||||||
|
|
|
@ -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端口值,可不设置;当设置此值后,将使用sing-box额外启动一个前置Socks服务,提供分流和速度显示等功能</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbBrowse" xml:space="preserve">
|
<data name="TbBrowse" xml:space="preserve">
|
||||||
<value>浏览</value>
|
<value>浏览</value>
|
||||||
|
@ -941,7 +941,7 @@
|
||||||
<value>路由规则详情设置</value>
|
<value>路由规则详情设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAutoSort" xml:space="preserve">
|
<data name="TbAutoSort" xml:space="preserve">
|
||||||
<value>保存时Domain和IP自动排序</value>
|
<value>保存时Domain, IP, 进程名 自动排序</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRuleobjectDoc" xml:space="preserve">
|
<data name="TbRuleobjectDoc" xml:space="preserve">
|
||||||
<value>规则详细说明文档</value>
|
<value>规则详细说明文档</value>
|
||||||
|
@ -1057,9 +1057,6 @@
|
||||||
<data name="TbSettingsTunModeBypassMode" xml:space="preserve">
|
<data name="TbSettingsTunModeBypassMode" xml:space="preserve">
|
||||||
<value>绕行模式</value>
|
<value>绕行模式</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsTunModeBypassModeTip" xml:space="preserve">
|
|
||||||
<value>启用:路由无匹配则最终代理</value>
|
|
||||||
</data>
|
|
||||||
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
|
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
|
||||||
<value>测速单个超时值</value>
|
<value>测速单个超时值</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -1115,7 +1112,7 @@
|
||||||
<value>DNS设置</value>
|
<value>DNS设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
|
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
|
||||||
<value>Sing-box DNS设置</value>
|
<value>sing-box DNS设置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
||||||
<value>请填写 DNS JSON 结构,点击查看文档</value>
|
<value>请填写 DNS JSON 结构,点击查看文档</value>
|
||||||
|
@ -1124,6 +1121,18 @@
|
||||||
<value>点击导入默认DNS配置</value>
|
<value>点击导入默认DNS配置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
||||||
<value>Sing-box域名解析策略</value>
|
<value>sing-box域名解析策略</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
|
||||||
|
<value>sing-box Mux 多路复用协议</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
||||||
|
<value>进程名全称 (Tun模式)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleDomain" xml:space="preserve">
|
||||||
|
<value>Domain</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleIP" xml:space="preserve">
|
||||||
|
<value>IP 或 IP CIDR</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -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$
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,6 +18,7 @@ namespace v2rayN.ViewModels
|
||||||
[Reactive] public string domainStrategy4Freedom { get; set; }
|
[Reactive] public string domainStrategy4Freedom { get; set; }
|
||||||
[Reactive] public string normalDNS { get; set; }
|
[Reactive] public string normalDNS { get; set; }
|
||||||
[Reactive] public string normalDNS2 { get; set; }
|
[Reactive] public string normalDNS2 { get; set; }
|
||||||
|
[Reactive] public string tunDNS2 { get; set; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
|
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
|
||||||
|
@ -35,6 +36,7 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
normalDNS2 = item2?.normalDNS!;
|
normalDNS2 = item2?.normalDNS!;
|
||||||
|
tunDNS2 = item2?.tunDNS!;
|
||||||
|
|
||||||
SaveCmd = ReactiveCommand.Create(() =>
|
SaveCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
|
@ -49,6 +51,7 @@ namespace v2rayN.ViewModels
|
||||||
ImportDefConfig4SingboxCmd = ReactiveCommand.Create(() =>
|
ImportDefConfig4SingboxCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
||||||
|
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);
|
Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);
|
||||||
|
@ -80,6 +83,15 @@ namespace v2rayN.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!Utils.IsNullOrEmpty(tunDNS2))
|
||||||
|
{
|
||||||
|
var obj2 = Utils.FromJson<Dns4Sbox>(tunDNS2);
|
||||||
|
if (obj2 == null)
|
||||||
|
{
|
||||||
|
UI.Show(ResUI.FillCorrectDNSText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
|
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
|
||||||
item.domainStrategy4Freedom = domainStrategy4Freedom;
|
item.domainStrategy4Freedom = domainStrategy4Freedom;
|
||||||
|
@ -88,6 +100,7 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
item2.normalDNS = Utils.ToJson(Utils.ParseJson(normalDNS2));
|
item2.normalDNS = Utils.ToJson(Utils.ParseJson(normalDNS2));
|
||||||
|
item2.tunDNS = Utils.ToJson(Utils.ParseJson(tunDNS2));
|
||||||
ConfigHandler.SaveDNSItems(_config, item2);
|
ConfigHandler.SaveDNSItems(_config, item2);
|
||||||
|
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
|
|
|
@ -1617,18 +1617,6 @@ namespace v2rayN.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TunModeSwitch()
|
|
||||||
{
|
|
||||||
if (EnableTun)
|
|
||||||
{
|
|
||||||
TunHandler.Instance.Start();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TunHandler.Instance.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion System proxy and Routings
|
#endregion System proxy and Routings
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace v2rayN.ViewModels
|
||||||
[Reactive] public bool defAllowInsecure { get; set; }
|
[Reactive] public bool defAllowInsecure { get; set; }
|
||||||
[Reactive] public string defFingerprint { get; set; }
|
[Reactive] public string defFingerprint { get; set; }
|
||||||
[Reactive] public string defUserAgent { get; set; }
|
[Reactive] public string defUserAgent { get; set; }
|
||||||
|
[Reactive] public string mux4SboxProtocol { get; set; }
|
||||||
|
|
||||||
#endregion Core
|
#endregion Core
|
||||||
|
|
||||||
|
@ -78,20 +79,9 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
#region Tun mode
|
#region Tun mode
|
||||||
|
|
||||||
[Reactive] public bool TunShowWindow { get; set; }
|
|
||||||
[Reactive] public bool TunEnabledLog { get; set; }
|
|
||||||
[Reactive] public bool TunStrictRoute { get; set; }
|
[Reactive] public bool TunStrictRoute { get; set; }
|
||||||
[Reactive] public string TunStack { get; set; }
|
[Reactive] public string TunStack { get; set; }
|
||||||
[Reactive] public int TunMtu { 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
|
#endregion Tun mode
|
||||||
|
|
||||||
|
@ -131,6 +121,7 @@ namespace v2rayN.ViewModels
|
||||||
defAllowInsecure = _config.coreBasicItem.defAllowInsecure;
|
defAllowInsecure = _config.coreBasicItem.defAllowInsecure;
|
||||||
defFingerprint = _config.coreBasicItem.defFingerprint;
|
defFingerprint = _config.coreBasicItem.defFingerprint;
|
||||||
defUserAgent = _config.coreBasicItem.defUserAgent;
|
defUserAgent = _config.coreBasicItem.defUserAgent;
|
||||||
|
mux4SboxProtocol = _config.mux4Sbox.protocol;
|
||||||
|
|
||||||
#endregion Core
|
#endregion Core
|
||||||
|
|
||||||
|
@ -178,22 +169,9 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
#region Tun mode
|
#region Tun mode
|
||||||
|
|
||||||
TunShowWindow = _config.tunModeItem.showWindow;
|
|
||||||
TunEnabledLog = _config.tunModeItem.enabledLog;
|
|
||||||
TunStrictRoute = _config.tunModeItem.strictRoute;
|
TunStrictRoute = _config.tunModeItem.strictRoute;
|
||||||
TunStack = _config.tunModeItem.stack;
|
TunStack = _config.tunModeItem.stack;
|
||||||
TunMtu = _config.tunModeItem.mtu;
|
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
|
#endregion Tun mode
|
||||||
|
|
||||||
|
@ -298,6 +276,7 @@ namespace v2rayN.ViewModels
|
||||||
_config.coreBasicItem.defAllowInsecure = defAllowInsecure;
|
_config.coreBasicItem.defAllowInsecure = defAllowInsecure;
|
||||||
_config.coreBasicItem.defFingerprint = defFingerprint;
|
_config.coreBasicItem.defFingerprint = defFingerprint;
|
||||||
_config.coreBasicItem.defUserAgent = defUserAgent;
|
_config.coreBasicItem.defUserAgent = defUserAgent;
|
||||||
|
_config.mux4Sbox.protocol = mux4SboxProtocol;
|
||||||
|
|
||||||
//Kcp
|
//Kcp
|
||||||
//_config.kcpItem.mtu = Kcpmtu;
|
//_config.kcpItem.mtu = Kcpmtu;
|
||||||
|
@ -338,19 +317,9 @@ namespace v2rayN.ViewModels
|
||||||
_config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
|
_config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
|
||||||
|
|
||||||
//tun mode
|
//tun mode
|
||||||
_config.tunModeItem.showWindow = TunShowWindow;
|
|
||||||
_config.tunModeItem.enabledLog = TunEnabledLog;
|
|
||||||
_config.tunModeItem.strictRoute = TunStrictRoute;
|
_config.tunModeItem.strictRoute = TunStrictRoute;
|
||||||
_config.tunModeItem.stack = TunStack;
|
_config.tunModeItem.stack = TunStack;
|
||||||
_config.tunModeItem.mtu = TunMtu;
|
_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
|
//coreType
|
||||||
SaveCoreType();
|
SaveCoreType();
|
||||||
|
|
|
@ -28,6 +28,9 @@ namespace v2rayN.ViewModels
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string IP { get; set; }
|
public string IP { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string Process { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool AutoSort { get; set; }
|
public bool AutoSort { get; set; }
|
||||||
|
|
||||||
|
@ -53,6 +56,7 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
Domain = Utils.List2String(SelectedSource.domain, true);
|
Domain = Utils.List2String(SelectedSource.domain, true);
|
||||||
IP = Utils.List2String(SelectedSource.ip, true);
|
IP = Utils.List2String(SelectedSource.ip, true);
|
||||||
|
Process = Utils.List2String(SelectedSource.process, true);
|
||||||
|
|
||||||
SaveCmd = ReactiveCommand.Create(() =>
|
SaveCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
|
@ -66,16 +70,19 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
Domain = Utils.Convert2Comma(Domain);
|
Domain = Utils.Convert2Comma(Domain);
|
||||||
IP = Utils.Convert2Comma(IP);
|
IP = Utils.Convert2Comma(IP);
|
||||||
|
Process = Utils.Convert2Comma(Process);
|
||||||
|
|
||||||
if (AutoSort)
|
if (AutoSort)
|
||||||
{
|
{
|
||||||
SelectedSource.domain = Utils.String2ListSorted(Domain);
|
SelectedSource.domain = Utils.String2ListSorted(Domain);
|
||||||
SelectedSource.ip = Utils.String2ListSorted(IP);
|
SelectedSource.ip = Utils.String2ListSorted(IP);
|
||||||
|
SelectedSource.process = Utils.String2ListSorted(Process);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SelectedSource.domain = Utils.String2List(Domain);
|
SelectedSource.domain = Utils.String2List(Domain);
|
||||||
SelectedSource.ip = Utils.String2List(IP);
|
SelectedSource.ip = Utils.String2List(IP);
|
||||||
|
SelectedSource.process = Utils.String2List(Process);
|
||||||
}
|
}
|
||||||
SelectedSource.protocol = ProtocolItems?.ToList();
|
SelectedSource.protocol = ProtocolItems?.ToList();
|
||||||
SelectedSource.inboundTag = InboundTagItems?.ToList();
|
SelectedSource.inboundTag = InboundTagItems?.ToList();
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:v2rayN.Resx"
|
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||||
|
@ -115,18 +114,46 @@
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
Style="{StaticResource DefButton}" />
|
Style="{StaticResource DefButton}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBox
|
|
||||||
x:Name="txtnormalDNS2"
|
<Grid Margin="{StaticResource SettingItemMargin}">
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
<Grid.ColumnDefinitions>
|
||||||
VerticalAlignment="Stretch"
|
<ColumnDefinition Width="1*" />
|
||||||
AcceptsReturn="True"
|
<ColumnDefinition Width="10" />
|
||||||
BorderThickness="1"
|
<ColumnDefinition Width="1*" />
|
||||||
Style="{StaticResource DefTextBox}"
|
</Grid.ColumnDefinitions>
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
<GroupBox
|
||||||
|
Grid.Column="0"
|
||||||
|
Header=""
|
||||||
|
Style="{StaticResource MyGroupBox}">
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtnormalDNS2"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
BorderThickness="1"
|
||||||
|
Style="{StaticResource DefTextBox}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
VerticalScrollBarVisibility="Auto" />
|
||||||
|
</GroupBox>
|
||||||
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||||
|
<GroupBox
|
||||||
|
Grid.Column="2"
|
||||||
|
Header="{x:Static resx:ResUI.TbSettingsTunMode}"
|
||||||
|
Style="{StaticResource MyGroupBox}">
|
||||||
|
<TextBox
|
||||||
|
x:Name="txttunDNS2"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
BorderThickness="1"
|
||||||
|
Style="{StaticResource DefTextBox}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
VerticalScrollBarVisibility="Auto" />
|
||||||
|
</GroupBox>
|
||||||
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
</TabControl>
|
</TabControl>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</reactiveui:ReactiveWindow>
|
</reactiveui:ReactiveWindow>
|
|
@ -29,6 +29,7 @@ namespace v2rayN.Views
|
||||||
this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.tunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
|
||||||
|
|
|
@ -235,7 +235,7 @@
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuCheckUpdateSingBoxCore"
|
x:Name="menuCheckUpdateSingBoxCore"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="Sing-box Core" />
|
Header="sing-box Core" />
|
||||||
<Separator Margin="-40,5" />
|
<Separator Margin="-40,5" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuCheckUpdateGeo"
|
x:Name="menuCheckUpdateGeo"
|
||||||
|
|
|
@ -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" />
|
||||||
|
@ -291,6 +292,21 @@
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsDefUserAgentTips}" />
|
Text="{x:Static resx:ResUI.TbSettingsDefUserAgentTips}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="14"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbSettingsMux4SboxProtocol}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbmux4SboxProtocol"
|
||||||
|
Grid.Row="14"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
Style="{StaticResource DefComboBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
@ -776,13 +792,6 @@
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<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" />
|
||||||
|
@ -790,34 +799,6 @@
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="0"
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsTunModeShowWindow}" />
|
|
||||||
<ToggleButton
|
|
||||||
x:Name="togShowWindow"
|
|
||||||
Grid.Row="0"
|
|
||||||
Grid.Column="1"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="1"
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsLogEnabled}" />
|
|
||||||
<ToggleButton
|
|
||||||
x:Name="togEnabledLog"
|
|
||||||
Grid.Row="1"
|
|
||||||
Grid.Column="1"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
@ -863,152 +844,6 @@
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="5"
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsTunModeCustomTemplate}" />
|
|
||||||
<TextBox
|
|
||||||
x:Name="txtCustomTemplate"
|
|
||||||
Grid.Row="5"
|
|
||||||
Grid.Column="1"
|
|
||||||
Width="400"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
VerticalAlignment="Top"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
<Button
|
|
||||||
x:Name="btnBrowse"
|
|
||||||
Grid.Row="5"
|
|
||||||
Grid.Column="2"
|
|
||||||
Width="100"
|
|
||||||
Margin="2,0,8,0"
|
|
||||||
Click="btnBrowse_Click"
|
|
||||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
|
||||||
Style="{StaticResource DefButton}" />
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="6"
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsTunModeBypassMode}" />
|
|
||||||
<ToggleButton
|
|
||||||
x:Name="togBypassMode"
|
|
||||||
Grid.Row="6"
|
|
||||||
Grid.Column="1"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="6"
|
|
||||||
Grid.Column="2"
|
|
||||||
Margin="{StaticResource ServerItemMargin}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsTunModeBypassModeTip}" />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid
|
|
||||||
x:Name="gridTunModeDirect"
|
|
||||||
Width="800"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
HorizontalAlignment="Left">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="2*" />
|
|
||||||
<ColumnDefinition Width="5" />
|
|
||||||
<ColumnDefinition Width="2*" />
|
|
||||||
<ColumnDefinition Width="5" />
|
|
||||||
<ColumnDefinition Width="3*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<GroupBox
|
|
||||||
Grid.Column="0"
|
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunModeDirectIP}"
|
|
||||||
Style="{StaticResource MyGroupBox}">
|
|
||||||
<TextBox
|
|
||||||
Name="txtDirectIP"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
</GroupBox>
|
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
|
||||||
<GroupBox
|
|
||||||
Grid.Column="2"
|
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunModeDirectProcess}"
|
|
||||||
Style="{StaticResource MyGroupBox}">
|
|
||||||
<TextBox
|
|
||||||
Name="txtDirectProcess"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
</GroupBox>
|
|
||||||
<GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" />
|
|
||||||
<GroupBox
|
|
||||||
Grid.Column="4"
|
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunModeDNS}"
|
|
||||||
Style="{StaticResource MyGroupBox}">
|
|
||||||
<TextBox
|
|
||||||
Name="txtDirectDNS"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
</GroupBox>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid
|
|
||||||
x:Name="gridTunModeProxy"
|
|
||||||
Width="800"
|
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
|
||||||
HorizontalAlignment="Left">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="2*" />
|
|
||||||
<ColumnDefinition Width="5" />
|
|
||||||
<ColumnDefinition Width="2*" />
|
|
||||||
<ColumnDefinition Width="5" />
|
|
||||||
<ColumnDefinition Width="3*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<GroupBox
|
|
||||||
Grid.Column="0"
|
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunModeProxyIP}"
|
|
||||||
Style="{StaticResource MyGroupBox}">
|
|
||||||
<TextBox
|
|
||||||
Name="txtProxyIP"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
</GroupBox>
|
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
|
||||||
<GroupBox
|
|
||||||
Grid.Column="2"
|
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunModeProxyProcess}"
|
|
||||||
Style="{StaticResource MyGroupBox}">
|
|
||||||
<TextBox
|
|
||||||
Name="txtProxyProcess"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
</GroupBox>
|
|
||||||
<GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" />
|
|
||||||
<GroupBox
|
|
||||||
Grid.Column="4"
|
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunModeDNS}"
|
|
||||||
Style="{StaticResource MyGroupBox}">
|
|
||||||
<TextBox
|
|
||||||
Name="txtProxyDNS"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
</GroupBox>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
|
@ -39,6 +39,10 @@ namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
cmbdefUserAgent.Items.Add(it);
|
cmbdefUserAgent.Items.Add(it);
|
||||||
});
|
});
|
||||||
|
Global.SingboxMuxs.ForEach(it =>
|
||||||
|
{
|
||||||
|
cmbmux4SboxProtocol.Items.Add(it);
|
||||||
|
});
|
||||||
|
|
||||||
for (int i = 1; i <= 10; i++)
|
for (int i = 1; i <= 10; i++)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +138,7 @@ namespace v2rayN.Views
|
||||||
this.Bind(ViewModel, vm => vm.defAllowInsecure, v => v.togdefAllowInsecure.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.defAllowInsecure, v => v.togdefAllowInsecure.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.defFingerprint, v => v.cmbdefFingerprint.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.defFingerprint, v => v.cmbdefFingerprint.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.defUserAgent, v => v.cmbdefUserAgent.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.defUserAgent, v => v.cmbdefUserAgent.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.mux4SboxProtocol, v => v.cmbmux4SboxProtocol.Text).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);
|
||||||
|
@ -165,21 +170,9 @@ namespace v2rayN.Views
|
||||||
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.systemProxyExceptions, v => v.txtsystemProxyExceptions.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.systemProxyExceptions, v => v.txtsystemProxyExceptions.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.TunShowWindow, v => v.togShowWindow.IsChecked).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunEnabledLog, v => v.togEnabledLog.IsChecked).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunCustomTemplate, v => v.txtCustomTemplate.Text).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunBypassMode, v => v.togBypassMode.IsChecked).DisposeWith(disposables);
|
|
||||||
this.OneWayBind(ViewModel, vm => vm.TunBypassMode, v => v.gridTunModeDirect.Visibility, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
|
||||||
this.OneWayBind(ViewModel, vm => vm.TunBypassMode2, v => v.gridTunModeProxy.Visibility, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunDirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunDirectProcess, v => v.txtDirectProcess.Text).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunDirectDNS, v => v.txtDirectDNS.Text).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunProxyIP, v => v.txtProxyIP.Text).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunProxyProcess, v => v.txtProxyProcess.Text).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.TunProxyDNS, v => v.txtProxyDNS.Text).DisposeWith(disposables);
|
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);
|
||||||
|
@ -203,7 +196,7 @@ namespace v2rayN.Views
|
||||||
openFileDialog1.Filter = "tunConfig|*.json|All|*.*";
|
openFileDialog1.Filter = "tunConfig|*.json|All|*.*";
|
||||||
openFileDialog1.ShowDialog();
|
openFileDialog1.ShowDialog();
|
||||||
|
|
||||||
txtCustomTemplate.Text = openFileDialog1.FileName;
|
// txtCustomTemplate.Text = openFileDialog1.FileName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -172,10 +172,12 @@
|
||||||
<ColumnDefinition Width="1*" />
|
<ColumnDefinition Width="1*" />
|
||||||
<ColumnDefinition Width="10" />
|
<ColumnDefinition Width="10" />
|
||||||
<ColumnDefinition Width="1*" />
|
<ColumnDefinition Width="1*" />
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
<ColumnDefinition Width="1*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Header="Domain"
|
Header="{x:Static resx:ResUI.TbRoutingRuleDomain}"
|
||||||
Style="{StaticResource MyGroupBox}">
|
Style="{StaticResource MyGroupBox}">
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="txtDomain"
|
Name="txtDomain"
|
||||||
|
@ -187,7 +189,7 @@
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Header="IP"
|
Header="{x:Static resx:ResUI.TbRoutingRuleIP}"
|
||||||
Style="{StaticResource MyGroupBox}">
|
Style="{StaticResource MyGroupBox}">
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="txtIP"
|
Name="txtIP"
|
||||||
|
@ -196,6 +198,18 @@
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
VerticalScrollBarVisibility="Auto" />
|
VerticalScrollBarVisibility="Auto" />
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
<GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" />
|
||||||
|
<GroupBox
|
||||||
|
Grid.Column="4"
|
||||||
|
Header="{x:Static resx:ResUI.TbRoutingRuleProcess}"
|
||||||
|
Style="{StaticResource MyGroupBox}">
|
||||||
|
<TextBox
|
||||||
|
Name="txtProcess"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
Style="{StaticResource DefTextBox}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
VerticalScrollBarVisibility="Auto" />
|
||||||
|
</GroupBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</reactiveui:ReactiveWindow>
|
</reactiveui:ReactiveWindow>
|
|
@ -49,6 +49,7 @@ namespace v2rayN.Views
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||||
|
|
|
@ -196,7 +196,6 @@
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}" />
|
Style="{StaticResource MyOutlinedTextBox}" />
|
||||||
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="7"
|
Grid.Row="7"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
@ -214,7 +213,6 @@
|
||||||
MaxDropDownHeight="1000"
|
MaxDropDownHeight="1000"
|
||||||
Style="{StaticResource MaterialDesignOutlinedComboBox}" />
|
Style="{StaticResource MaterialDesignOutlinedComboBox}" />
|
||||||
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="8"
|
Grid.Row="8"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
|
|
@ -34,9 +34,6 @@
|
||||||
<EmbeddedResource Include="Sample\SingboxSampleClientConfig">
|
<EmbeddedResource Include="Sample\SingboxSampleClientConfig">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Sample\tun_singbox">
|
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<EmbeddedResource Include="Sample\tun_singbox_dns">
|
<EmbeddedResource Include="Sample\tun_singbox_dns">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
Loading…
Reference in a new issue