mirror of
https://github.com/2dust/v2rayN.git
synced 2025-08-29 14:26:20 +00:00
feat: allow user to choose any outbound for routing rules
This commit is contained in:
parent
5e2e45c673
commit
f0c03d6103
3 changed files with 112 additions and 5 deletions
|
@ -179,8 +179,9 @@ namespace v2rayN.Handler
|
||||||
return inbound;
|
return inbound;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int routing(Config config, ref V2rayConfig v2rayConfig)
|
private static int routing(Config config, ref V2rayConfig v2rayConfig, out HashSet<string> usedOutboundTags)
|
||||||
{
|
{
|
||||||
|
usedOutboundTags = new HashSet<string>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (v2rayConfig.routing != null
|
if (v2rayConfig.routing != null
|
||||||
|
@ -204,6 +205,7 @@ namespace v2rayN.Handler
|
||||||
if (item.enabled)
|
if (item.enabled)
|
||||||
{
|
{
|
||||||
routingUserRule(item, ref v2rayConfig);
|
routingUserRule(item, ref v2rayConfig);
|
||||||
|
usedOutboundTags.Add(item.outboundTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,12 +304,32 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int outbound(ProfileItem node, ref V2rayConfig v2rayConfig)
|
private static Outbounds createOutbound(ProfileItem node)
|
||||||
{
|
{
|
||||||
|
var outbound = new Outbounds
|
||||||
|
{
|
||||||
|
tag = node.remarks,
|
||||||
|
protocol = node.configType switch
|
||||||
|
{
|
||||||
|
EConfigType.VMess => Global.vmessProtocolLite,
|
||||||
|
EConfigType.Shadowsocks => Global.ssProtocolLite,
|
||||||
|
EConfigType.VLESS => Global.vlessProtocolLite,
|
||||||
|
EConfigType.Trojan => Global.trojanProtocolLite,
|
||||||
|
EConfigType.Socks => Global.socksProtocolLite,
|
||||||
|
_ => "unknown"
|
||||||
|
},
|
||||||
|
settings = new Outboundsettings
|
||||||
|
{
|
||||||
|
vnext = new List<VnextItem> { new VnextItem { users = new List<UsersItem>() } },
|
||||||
|
servers = new List<ServersItem>(),
|
||||||
|
response = new Response()
|
||||||
|
},
|
||||||
|
streamSettings = new StreamSettings(),
|
||||||
|
mux = new Mux()
|
||||||
|
};
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var config = LazyConfig.Instance.GetConfig();
|
var config = LazyConfig.Instance.GetConfig();
|
||||||
Outbounds outbound = v2rayConfig.outbounds[0];
|
|
||||||
if (node.configType == EConfigType.VMess)
|
if (node.configType == EConfigType.VMess)
|
||||||
{
|
{
|
||||||
VnextItem vnextItem;
|
VnextItem vnextItem;
|
||||||
|
@ -534,6 +556,26 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
Utils.SaveLog(ex.Message, ex);
|
Utils.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
return outbound;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int outbound(ProfileItem node, ref V2rayConfig v2rayConfig)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (v2rayConfig.outbounds.Count <= 0)
|
||||||
|
{
|
||||||
|
v2rayConfig.outbounds.Add(createOutbound(node));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v2rayConfig.outbounds[0] = createOutbound(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Utils.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,7 +998,7 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GenerateClientConfigContent(ProfileItem node, bool blExport, ref V2rayConfig v2rayConfig, out string msg)
|
private static int GenerateClientConfigContent(ProfileItem node, bool blExport, ref V2rayConfig v2rayConfig, out string msg)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -988,10 +1030,20 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
inbound(config, ref v2rayConfig);
|
inbound(config, ref v2rayConfig);
|
||||||
|
|
||||||
routing(config, ref v2rayConfig);
|
routing(config, ref v2rayConfig, out HashSet<string> usedTags);
|
||||||
|
|
||||||
|
v2rayConfig.outbounds.Clear();
|
||||||
//outbound
|
//outbound
|
||||||
outbound(node, ref v2rayConfig);
|
outbound(node, ref v2rayConfig);
|
||||||
|
// first outbound is current active node, of which name is always "proxy"
|
||||||
|
v2rayConfig.outbounds[0].tag = Global.agentTag;
|
||||||
|
|
||||||
|
// append all outbound used by custom routing rules
|
||||||
|
var allOutbounds = SqliteHelper.Instance.Table<ProfileItem>().Where(i => usedTags.Contains(i.remarks));
|
||||||
|
foreach (var item in allOutbounds)
|
||||||
|
{
|
||||||
|
v2rayConfig.outbounds.Add(createOutbound(item));
|
||||||
|
}
|
||||||
|
|
||||||
//dns
|
//dns
|
||||||
dns(config, ref v2rayConfig);
|
dns(config, ref v2rayConfig);
|
||||||
|
|
|
@ -247,5 +247,56 @@ namespace v2rayN.Mode
|
||||||
public string fingerprint { get; set; }
|
public string fingerprint { get; set; }
|
||||||
|
|
||||||
public bool displayLog { get; set; } = true;
|
public bool displayLog { get; set; } = true;
|
||||||
|
|
||||||
|
// TODO: change ProfileItem and other models to C# records
|
||||||
|
public override bool Equals(object? obj) {
|
||||||
|
if (ReferenceEquals(null, obj)) return false;
|
||||||
|
if (ReferenceEquals(this, obj)) return true;
|
||||||
|
if (obj.GetType() != GetType()) return false;
|
||||||
|
return Equals((ProfileItem)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool Equals(ProfileItem other) {
|
||||||
|
return indexId == other.indexId && configType == other.configType && configVersion == other.configVersion &&
|
||||||
|
sort == other.sort && address == other.address && port == other.port && id == other.id &&
|
||||||
|
alterId == other.alterId && security == other.security && network == other.network &&
|
||||||
|
remarks == other.remarks && headerType == other.headerType && requestHost == other.requestHost &&
|
||||||
|
path == other.path && streamSecurity == other.streamSecurity && allowInsecure == other.allowInsecure &&
|
||||||
|
delay == other.delay && speed == other.speed && subid == other.subid && isSub == other.isSub &&
|
||||||
|
flow == other.flow && sni == other.sni && alpn == other.alpn && coreType == other.coreType &&
|
||||||
|
preSocksPort == other.preSocksPort && fingerprint == other.fingerprint && displayLog == other.displayLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
var hashCode = new HashCode();
|
||||||
|
hashCode.Add(indexId);
|
||||||
|
hashCode.Add((int)configType);
|
||||||
|
hashCode.Add(configVersion);
|
||||||
|
hashCode.Add(sort);
|
||||||
|
hashCode.Add(address);
|
||||||
|
hashCode.Add(port);
|
||||||
|
hashCode.Add(id);
|
||||||
|
hashCode.Add(alterId);
|
||||||
|
hashCode.Add(security);
|
||||||
|
hashCode.Add(network);
|
||||||
|
hashCode.Add(remarks);
|
||||||
|
hashCode.Add(headerType);
|
||||||
|
hashCode.Add(requestHost);
|
||||||
|
hashCode.Add(path);
|
||||||
|
hashCode.Add(streamSecurity);
|
||||||
|
hashCode.Add(allowInsecure);
|
||||||
|
hashCode.Add(delay);
|
||||||
|
hashCode.Add(speed);
|
||||||
|
hashCode.Add(subid);
|
||||||
|
hashCode.Add(isSub);
|
||||||
|
hashCode.Add(flow);
|
||||||
|
hashCode.Add(sni);
|
||||||
|
hashCode.Add(alpn);
|
||||||
|
hashCode.Add(coreType);
|
||||||
|
hashCode.Add(preSocksPort);
|
||||||
|
hashCode.Add(fingerprint);
|
||||||
|
hashCode.Add(displayLog);
|
||||||
|
return hashCode.ToHashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@ namespace v2rayN.Views
|
||||||
cmbOutboundTag.Items.Add(Global.agentTag);
|
cmbOutboundTag.Items.Add(Global.agentTag);
|
||||||
cmbOutboundTag.Items.Add(Global.directTag);
|
cmbOutboundTag.Items.Add(Global.directTag);
|
||||||
cmbOutboundTag.Items.Add(Global.blockTag);
|
cmbOutboundTag.Items.Add(Global.blockTag);
|
||||||
|
foreach (var profileItem in SqliteHelper.Instance.Table<ProfileItem>())
|
||||||
|
{
|
||||||
|
cmbOutboundTag.Items.Add(profileItem.remarks);
|
||||||
|
}
|
||||||
Global.Protocols.ForEach(it =>
|
Global.Protocols.ForEach(it =>
|
||||||
{
|
{
|
||||||
clbProtocol.Items.Add(it);
|
clbProtocol.Items.Add(it);
|
||||||
|
|
Loading…
Reference in a new issue