mirror of https://github.com/2dust/v2rayN
Added outbound HTTP support (support group prefix proxy)
https://github.com/2dust/v2rayN/discussions/4550pull/4991/head
parent
b5cb9ce67e
commit
5683df2fc0
|
@ -142,7 +142,8 @@ namespace v2rayN
|
||||||
{
|
{
|
||||||
{EConfigType.VMess,"vmess"},
|
{EConfigType.VMess,"vmess"},
|
||||||
{EConfigType.Shadowsocks,"shadowsocks"},
|
{EConfigType.Shadowsocks,"shadowsocks"},
|
||||||
{EConfigType.Socks,"socks"},
|
{EConfigType.Socks,"socks"},
|
||||||
|
{EConfigType.Http,"http"},
|
||||||
{EConfigType.VLESS,"vless"},
|
{EConfigType.VLESS,"vless"},
|
||||||
{EConfigType.Trojan,"trojan"},
|
{EConfigType.Trojan,"trojan"},
|
||||||
{EConfigType.Hysteria2,"hysteria2"},
|
{EConfigType.Hysteria2,"hysteria2"},
|
||||||
|
|
|
@ -664,6 +664,23 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add or edit server
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <param name="profileItem"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int AddHttpServer(Config config, ProfileItem profileItem, bool toFile = true)
|
||||||
|
{
|
||||||
|
profileItem.configType = EConfigType.Http;
|
||||||
|
|
||||||
|
profileItem.address = profileItem.address.TrimEx();
|
||||||
|
|
||||||
|
AddServerCommon(config, profileItem, toFile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add or edit server
|
/// Add or edit server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -213,105 +213,111 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
outbound.server = node.address;
|
outbound.server = node.address;
|
||||||
outbound.server_port = node.port;
|
outbound.server_port = node.port;
|
||||||
|
outbound.type = Global.ProtocolTypes[node.configType];
|
||||||
|
|
||||||
if (node.configType == EConfigType.VMess)
|
switch (node.configType)
|
||||||
{
|
{
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.VMess];
|
case EConfigType.VMess:
|
||||||
|
|
||||||
outbound.uuid = node.id;
|
|
||||||
outbound.alter_id = node.alterId;
|
|
||||||
if (Global.VmessSecurities.Contains(node.security))
|
|
||||||
{
|
|
||||||
outbound.security = node.security;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outbound.security = Global.DefaultSecurity;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound);
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.Shadowsocks)
|
|
||||||
{
|
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.Shadowsocks];
|
|
||||||
|
|
||||||
outbound.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
|
|
||||||
outbound.password = node.id;
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound);
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.Socks)
|
|
||||||
{
|
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.Socks];
|
|
||||||
|
|
||||||
outbound.version = "5";
|
|
||||||
if (!Utils.IsNullOrEmpty(node.security)
|
|
||||||
&& !Utils.IsNullOrEmpty(node.id))
|
|
||||||
{
|
|
||||||
outbound.username = node.security;
|
|
||||||
outbound.password = node.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.VLESS)
|
|
||||||
{
|
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.VLESS];
|
|
||||||
|
|
||||||
outbound.uuid = node.id;
|
|
||||||
|
|
||||||
outbound.packet_encoding = "xudp";
|
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(node.flow))
|
|
||||||
{
|
|
||||||
GenOutboundMux(node, outbound);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outbound.flow = node.flow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.Trojan)
|
|
||||||
{
|
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.Trojan];
|
|
||||||
|
|
||||||
outbound.password = node.id;
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound);
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.Hysteria2)
|
|
||||||
{
|
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.Hysteria2];
|
|
||||||
|
|
||||||
outbound.password = node.id;
|
|
||||||
|
|
||||||
if (!Utils.IsNullOrEmpty(node.path))
|
|
||||||
{
|
|
||||||
outbound.obfs = new()
|
|
||||||
{
|
{
|
||||||
type = "salamander",
|
outbound.uuid = node.id;
|
||||||
password = node.path.TrimEx(),
|
outbound.alter_id = node.alterId;
|
||||||
};
|
if (Global.VmessSecurities.Contains(node.security))
|
||||||
}
|
{
|
||||||
|
outbound.security = node.security;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outbound.security = Global.DefaultSecurity;
|
||||||
|
}
|
||||||
|
|
||||||
outbound.up_mbps = _config.hysteriaItem.up_mbps > 0 ? _config.hysteriaItem.up_mbps : null;
|
GenOutboundMux(node, outbound);
|
||||||
outbound.down_mbps = _config.hysteriaItem.down_mbps > 0 ? _config.hysteriaItem.down_mbps : null;
|
break;
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.Tuic)
|
case EConfigType.Shadowsocks:
|
||||||
{
|
{
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.Tuic];
|
outbound.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
|
||||||
|
outbound.password = node.id;
|
||||||
|
|
||||||
outbound.uuid = node.id;
|
GenOutboundMux(node, outbound);
|
||||||
outbound.password = node.security;
|
break;
|
||||||
outbound.congestion_control = node.headerType;
|
}
|
||||||
}
|
case EConfigType.Socks:
|
||||||
else if (node.configType == EConfigType.Wireguard)
|
{
|
||||||
{
|
outbound.version = "5";
|
||||||
outbound.type = Global.ProtocolTypes[EConfigType.Wireguard];
|
if (!Utils.IsNullOrEmpty(node.security)
|
||||||
|
&& !Utils.IsNullOrEmpty(node.id))
|
||||||
|
{
|
||||||
|
outbound.username = node.security;
|
||||||
|
outbound.password = node.id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.Http:
|
||||||
|
{
|
||||||
|
if (!Utils.IsNullOrEmpty(node.security)
|
||||||
|
&& !Utils.IsNullOrEmpty(node.id))
|
||||||
|
{
|
||||||
|
outbound.username = node.security;
|
||||||
|
outbound.password = node.id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.VLESS:
|
||||||
|
{
|
||||||
|
outbound.uuid = node.id;
|
||||||
|
|
||||||
outbound.private_key = node.id;
|
outbound.packet_encoding = "xudp";
|
||||||
outbound.peer_public_key = node.publicKey;
|
|
||||||
outbound.reserved = Utils.String2List(node.path).Select(int.Parse).ToArray();
|
if (Utils.IsNullOrEmpty(node.flow))
|
||||||
outbound.local_address = [.. Utils.String2List(node.requestHost)];
|
{
|
||||||
outbound.mtu = Utils.ToInt(node.shortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.shortId);
|
GenOutboundMux(node, outbound);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outbound.flow = node.flow;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.Trojan:
|
||||||
|
{
|
||||||
|
outbound.password = node.id;
|
||||||
|
|
||||||
|
GenOutboundMux(node, outbound);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.Hysteria2:
|
||||||
|
{
|
||||||
|
outbound.password = node.id;
|
||||||
|
|
||||||
|
if (!Utils.IsNullOrEmpty(node.path))
|
||||||
|
{
|
||||||
|
outbound.obfs = new()
|
||||||
|
{
|
||||||
|
type = "salamander",
|
||||||
|
password = node.path.TrimEx(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
outbound.up_mbps = _config.hysteriaItem.up_mbps > 0 ? _config.hysteriaItem.up_mbps : null;
|
||||||
|
outbound.down_mbps = _config.hysteriaItem.down_mbps > 0 ? _config.hysteriaItem.down_mbps : null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.Tuic:
|
||||||
|
{
|
||||||
|
outbound.uuid = node.id;
|
||||||
|
outbound.password = node.security;
|
||||||
|
outbound.congestion_control = node.headerType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.Wireguard:
|
||||||
|
{
|
||||||
|
outbound.private_key = node.id;
|
||||||
|
outbound.peer_public_key = node.publicKey;
|
||||||
|
outbound.reserved = Utils.String2List(node.path).Select(int.Parse).ToArray();
|
||||||
|
outbound.local_address = [.. Utils.String2List(node.requestHost)];
|
||||||
|
outbound.mtu = Utils.ToInt(node.shortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.shortId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GenOutboundTls(node, outbound);
|
GenOutboundTls(node, outbound);
|
||||||
|
|
|
@ -295,182 +295,188 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (node.configType == EConfigType.VMess)
|
switch (node.configType)
|
||||||
{
|
{
|
||||||
VnextItem4Ray vnextItem;
|
case EConfigType.VMess:
|
||||||
if (outbound.settings.vnext.Count <= 0)
|
|
||||||
{
|
|
||||||
vnextItem = new VnextItem4Ray();
|
|
||||||
outbound.settings.vnext.Add(vnextItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vnextItem = outbound.settings.vnext[0];
|
|
||||||
}
|
|
||||||
vnextItem.address = node.address;
|
|
||||||
vnextItem.port = node.port;
|
|
||||||
|
|
||||||
UsersItem4Ray usersItem;
|
|
||||||
if (vnextItem.users.Count <= 0)
|
|
||||||
{
|
|
||||||
usersItem = new UsersItem4Ray();
|
|
||||||
vnextItem.users.Add(usersItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
usersItem = vnextItem.users[0];
|
|
||||||
}
|
|
||||||
//远程服务器用户ID
|
|
||||||
usersItem.id = node.id;
|
|
||||||
usersItem.alterId = node.alterId;
|
|
||||||
usersItem.email = Global.UserEMail;
|
|
||||||
if (Global.VmessSecurities.Contains(node.security))
|
|
||||||
{
|
|
||||||
usersItem.security = node.security;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
usersItem.security = Global.DefaultSecurity;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
|
||||||
|
|
||||||
outbound.protocol = Global.ProtocolTypes[EConfigType.VMess];
|
|
||||||
outbound.settings.servers = null;
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.Shadowsocks)
|
|
||||||
{
|
|
||||||
ServersItem4Ray serversItem;
|
|
||||||
if (outbound.settings.servers.Count <= 0)
|
|
||||||
{
|
|
||||||
serversItem = new ServersItem4Ray();
|
|
||||||
outbound.settings.servers.Add(serversItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serversItem = outbound.settings.servers[0];
|
|
||||||
}
|
|
||||||
serversItem.address = node.address;
|
|
||||||
serversItem.port = node.port;
|
|
||||||
serversItem.password = node.id;
|
|
||||||
serversItem.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : "none";
|
|
||||||
|
|
||||||
serversItem.ota = false;
|
|
||||||
serversItem.level = 1;
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound, false);
|
|
||||||
|
|
||||||
outbound.protocol = Global.ProtocolTypes[EConfigType.Shadowsocks];
|
|
||||||
outbound.settings.vnext = null;
|
|
||||||
}
|
|
||||||
else if (node.configType == EConfigType.Socks)
|
|
||||||
{
|
|
||||||
ServersItem4Ray serversItem;
|
|
||||||
if (outbound.settings.servers.Count <= 0)
|
|
||||||
{
|
|
||||||
serversItem = new ServersItem4Ray();
|
|
||||||
outbound.settings.servers.Add(serversItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serversItem = outbound.settings.servers[0];
|
|
||||||
}
|
|
||||||
serversItem.address = node.address;
|
|
||||||
serversItem.port = node.port;
|
|
||||||
serversItem.method = null;
|
|
||||||
serversItem.password = null;
|
|
||||||
|
|
||||||
if (!Utils.IsNullOrEmpty(node.security)
|
|
||||||
&& !Utils.IsNullOrEmpty(node.id))
|
|
||||||
{
|
|
||||||
SocksUsersItem4Ray socksUsersItem = new()
|
|
||||||
{
|
{
|
||||||
user = node.security,
|
VnextItem4Ray vnextItem;
|
||||||
pass = node.id,
|
if (outbound.settings.vnext.Count <= 0)
|
||||||
level = 1
|
{
|
||||||
};
|
vnextItem = new VnextItem4Ray();
|
||||||
|
outbound.settings.vnext.Add(vnextItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vnextItem = outbound.settings.vnext[0];
|
||||||
|
}
|
||||||
|
vnextItem.address = node.address;
|
||||||
|
vnextItem.port = node.port;
|
||||||
|
|
||||||
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
|
UsersItem4Ray usersItem;
|
||||||
}
|
if (vnextItem.users.Count <= 0)
|
||||||
|
{
|
||||||
|
usersItem = new UsersItem4Ray();
|
||||||
|
vnextItem.users.Add(usersItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usersItem = vnextItem.users[0];
|
||||||
|
}
|
||||||
|
//远程服务器用户ID
|
||||||
|
usersItem.id = node.id;
|
||||||
|
usersItem.alterId = node.alterId;
|
||||||
|
usersItem.email = Global.UserEMail;
|
||||||
|
if (Global.VmessSecurities.Contains(node.security))
|
||||||
|
{
|
||||||
|
usersItem.security = node.security;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usersItem.security = Global.DefaultSecurity;
|
||||||
|
}
|
||||||
|
|
||||||
GenOutboundMux(node, outbound, false);
|
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
||||||
|
|
||||||
outbound.protocol = Global.ProtocolTypes[EConfigType.Socks];
|
outbound.settings.servers = null;
|
||||||
outbound.settings.vnext = null;
|
break;
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.VLESS)
|
case EConfigType.Shadowsocks:
|
||||||
{
|
|
||||||
VnextItem4Ray vnextItem;
|
|
||||||
if (outbound.settings.vnext.Count <= 0)
|
|
||||||
{
|
|
||||||
vnextItem = new VnextItem4Ray();
|
|
||||||
outbound.settings.vnext.Add(vnextItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vnextItem = outbound.settings.vnext[0];
|
|
||||||
}
|
|
||||||
vnextItem.address = node.address;
|
|
||||||
vnextItem.port = node.port;
|
|
||||||
|
|
||||||
UsersItem4Ray usersItem;
|
|
||||||
if (vnextItem.users.Count <= 0)
|
|
||||||
{
|
|
||||||
usersItem = new UsersItem4Ray();
|
|
||||||
vnextItem.users.Add(usersItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
usersItem = vnextItem.users[0];
|
|
||||||
}
|
|
||||||
usersItem.id = node.id;
|
|
||||||
usersItem.email = Global.UserEMail;
|
|
||||||
usersItem.encryption = node.security;
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
|
||||||
|
|
||||||
if (node.streamSecurity == Global.StreamSecurityReality
|
|
||||||
|| node.streamSecurity == Global.StreamSecurity)
|
|
||||||
{
|
|
||||||
if (!Utils.IsNullOrEmpty(node.flow))
|
|
||||||
{
|
{
|
||||||
usersItem.flow = node.flow;
|
ServersItem4Ray serversItem;
|
||||||
|
if (outbound.settings.servers.Count <= 0)
|
||||||
|
{
|
||||||
|
serversItem = new ServersItem4Ray();
|
||||||
|
outbound.settings.servers.Add(serversItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serversItem = outbound.settings.servers[0];
|
||||||
|
}
|
||||||
|
serversItem.address = node.address;
|
||||||
|
serversItem.port = node.port;
|
||||||
|
serversItem.password = node.id;
|
||||||
|
serversItem.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : "none";
|
||||||
|
|
||||||
|
serversItem.ota = false;
|
||||||
|
serversItem.level = 1;
|
||||||
|
|
||||||
GenOutboundMux(node, outbound, false);
|
GenOutboundMux(node, outbound, false);
|
||||||
|
|
||||||
|
outbound.settings.vnext = null;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case EConfigType.Socks:
|
||||||
if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow))
|
case EConfigType.Http:
|
||||||
{
|
{
|
||||||
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
ServersItem4Ray serversItem;
|
||||||
}
|
if (outbound.settings.servers.Count <= 0)
|
||||||
|
{
|
||||||
|
serversItem = new ServersItem4Ray();
|
||||||
|
outbound.settings.servers.Add(serversItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serversItem = outbound.settings.servers[0];
|
||||||
|
}
|
||||||
|
serversItem.address = node.address;
|
||||||
|
serversItem.port = node.port;
|
||||||
|
serversItem.method = null;
|
||||||
|
serversItem.password = null;
|
||||||
|
|
||||||
outbound.protocol = Global.ProtocolTypes[EConfigType.VLESS];
|
if (!Utils.IsNullOrEmpty(node.security)
|
||||||
outbound.settings.servers = null;
|
&& !Utils.IsNullOrEmpty(node.id))
|
||||||
|
{
|
||||||
|
SocksUsersItem4Ray socksUsersItem = new()
|
||||||
|
{
|
||||||
|
user = node.security,
|
||||||
|
pass = node.id,
|
||||||
|
level = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
|
||||||
|
}
|
||||||
|
|
||||||
|
GenOutboundMux(node, outbound, false);
|
||||||
|
|
||||||
|
outbound.settings.vnext = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.VLESS:
|
||||||
|
{
|
||||||
|
VnextItem4Ray vnextItem;
|
||||||
|
if (outbound.settings.vnext?.Count <= 0)
|
||||||
|
{
|
||||||
|
vnextItem = new VnextItem4Ray();
|
||||||
|
outbound.settings.vnext.Add(vnextItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vnextItem = outbound.settings.vnext[0];
|
||||||
|
}
|
||||||
|
vnextItem.address = node.address;
|
||||||
|
vnextItem.port = node.port;
|
||||||
|
|
||||||
|
UsersItem4Ray usersItem;
|
||||||
|
if (vnextItem.users.Count <= 0)
|
||||||
|
{
|
||||||
|
usersItem = new UsersItem4Ray();
|
||||||
|
vnextItem.users.Add(usersItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usersItem = vnextItem.users[0];
|
||||||
|
}
|
||||||
|
usersItem.id = node.id;
|
||||||
|
usersItem.email = Global.UserEMail;
|
||||||
|
usersItem.encryption = node.security;
|
||||||
|
|
||||||
|
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
||||||
|
|
||||||
|
if (node.streamSecurity == Global.StreamSecurityReality
|
||||||
|
|| node.streamSecurity == Global.StreamSecurity)
|
||||||
|
{
|
||||||
|
if (!Utils.IsNullOrEmpty(node.flow))
|
||||||
|
{
|
||||||
|
usersItem.flow = node.flow;
|
||||||
|
|
||||||
|
GenOutboundMux(node, outbound, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow))
|
||||||
|
{
|
||||||
|
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
outbound.settings.servers = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EConfigType.Trojan:
|
||||||
|
{
|
||||||
|
ServersItem4Ray serversItem;
|
||||||
|
if (outbound.settings.servers.Count <= 0)
|
||||||
|
{
|
||||||
|
serversItem = new ServersItem4Ray();
|
||||||
|
outbound.settings.servers.Add(serversItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serversItem = outbound.settings.servers[0];
|
||||||
|
}
|
||||||
|
serversItem.address = node.address;
|
||||||
|
serversItem.port = node.port;
|
||||||
|
serversItem.password = node.id;
|
||||||
|
|
||||||
|
serversItem.ota = false;
|
||||||
|
serversItem.level = 1;
|
||||||
|
|
||||||
|
GenOutboundMux(node, outbound, false);
|
||||||
|
|
||||||
|
outbound.settings.vnext = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (node.configType == EConfigType.Trojan)
|
|
||||||
{
|
|
||||||
ServersItem4Ray serversItem;
|
|
||||||
if (outbound.settings.servers.Count <= 0)
|
|
||||||
{
|
|
||||||
serversItem = new ServersItem4Ray();
|
|
||||||
outbound.settings.servers.Add(serversItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serversItem = outbound.settings.servers[0];
|
|
||||||
}
|
|
||||||
serversItem.address = node.address;
|
|
||||||
serversItem.port = node.port;
|
|
||||||
serversItem.password = node.id;
|
|
||||||
|
|
||||||
serversItem.ota = false;
|
outbound.protocol = Global.ProtocolTypes[node.configType];
|
||||||
serversItem.level = 1;
|
|
||||||
|
|
||||||
GenOutboundMux(node, outbound, false);
|
|
||||||
|
|
||||||
outbound.protocol = Global.ProtocolTypes[EConfigType.Trojan];
|
|
||||||
outbound.settings.vnext = null;
|
|
||||||
}
|
|
||||||
GenBoundStreamSettings(node, outbound.streamSettings);
|
GenBoundStreamSettings(node, outbound.streamSettings);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
Trojan = 6,
|
Trojan = 6,
|
||||||
Hysteria2 = 7,
|
Hysteria2 = 7,
|
||||||
Tuic = 8,
|
Tuic = 8,
|
||||||
Wireguard = 9
|
Wireguard = 9,
|
||||||
|
Http = 10
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -232,7 +232,7 @@ namespace v2rayN.Models
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<VnextItem4Ray> vnext { get; set; }
|
public List<VnextItem4Ray>? vnext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -288,17 +288,17 @@ namespace v2rayN.Models
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string method { get; set; }
|
public string? method { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ota { get; set; }
|
public bool? ota { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string password { get; set; }
|
public string? password { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -308,7 +308,7 @@ namespace v2rayN.Models
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int level { get; set; }
|
public int? level { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// trojan
|
/// trojan
|
||||||
|
@ -336,7 +336,7 @@ namespace v2rayN.Models
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int level { get; set; }
|
public int? level { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Mux4Ray
|
public class Mux4Ray
|
||||||
|
|
|
@ -618,6 +618,15 @@ namespace v2rayN.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Add [Http] server 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuAddHttpServer {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuAddHttpServer", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Add [Hysteria2] server 的本地化字符串。
|
/// 查找类似 Add [Hysteria2] server 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1198,4 +1198,7 @@
|
||||||
<data name="TransportRequestHostTip5" xml:space="preserve">
|
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||||
<value>*grpc Authority</value>
|
<value>*grpc Authority</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddHttpServer" xml:space="preserve">
|
||||||
|
<value>Add [Http] server</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -1195,4 +1195,7 @@
|
||||||
<data name="TransportRequestHostTip5" xml:space="preserve">
|
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||||
<value>*grpc Authority</value>
|
<value>*grpc Authority</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddHttpServer" xml:space="preserve">
|
||||||
|
<value>添加[Http]服务器</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -1168,4 +1168,7 @@
|
||||||
<data name="TransportRequestHostTip5" xml:space="preserve">
|
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||||
<value>*grpc Authority</value>
|
<value>*grpc Authority</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddHttpServer" xml:space="preserve">
|
||||||
|
<value>新增[Http]伺服器</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -80,7 +80,8 @@ namespace v2rayN.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SelectedSource.configType != EConfigType.Socks)
|
if (SelectedSource.configType != EConfigType.Socks
|
||||||
|
&& SelectedSource.configType != EConfigType.Http)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(SelectedSource.id))
|
if (Utils.IsNullOrEmpty(SelectedSource.id))
|
||||||
{
|
{
|
||||||
|
@ -127,6 +128,7 @@ namespace v2rayN.ViewModels
|
||||||
EConfigType.VMess => ConfigHandler.AddServer(_config, item),
|
EConfigType.VMess => ConfigHandler.AddServer(_config, item),
|
||||||
EConfigType.Shadowsocks => ConfigHandler.AddShadowsocksServer(_config, item),
|
EConfigType.Shadowsocks => ConfigHandler.AddShadowsocksServer(_config, item),
|
||||||
EConfigType.Socks => ConfigHandler.AddSocksServer(_config, item),
|
EConfigType.Socks => ConfigHandler.AddSocksServer(_config, item),
|
||||||
|
EConfigType.Http => ConfigHandler.AddHttpServer(_config, item),
|
||||||
EConfigType.Trojan => ConfigHandler.AddTrojanServer(_config, item),
|
EConfigType.Trojan => ConfigHandler.AddTrojanServer(_config, item),
|
||||||
EConfigType.VLESS => ConfigHandler.AddVlessServer(_config, item),
|
EConfigType.VLESS => ConfigHandler.AddVlessServer(_config, item),
|
||||||
EConfigType.Hysteria2 => ConfigHandler.AddHysteria2Server(_config, item),
|
EConfigType.Hysteria2 => ConfigHandler.AddHysteria2Server(_config, item),
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace v2rayN.ViewModels
|
||||||
public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AddHttpServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
||||||
|
@ -333,6 +334,10 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
EditServer(true, EConfigType.Socks);
|
EditServer(true, EConfigType.Socks);
|
||||||
});
|
});
|
||||||
|
AddHttpServerCmd = ReactiveCommand.Create(() =>
|
||||||
|
{
|
||||||
|
EditServer(true, EConfigType.Http);
|
||||||
|
});
|
||||||
AddTrojanServerCmd = ReactiveCommand.Create(() =>
|
AddTrojanServerCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
EditServer(true, EConfigType.Trojan);
|
EditServer(true, EConfigType.Trojan);
|
||||||
|
|
|
@ -92,6 +92,7 @@ namespace v2rayN.Views
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Socks:
|
case EConfigType.Socks:
|
||||||
|
case EConfigType.Http:
|
||||||
gridSocks.Visibility = Visibility.Visible;
|
gridSocks.Visibility = Visibility.Visible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -174,6 +175,7 @@ namespace v2rayN.Views
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Socks:
|
case EConfigType.Socks:
|
||||||
|
case EConfigType.Http:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.MainWindow"
|
x:Class="v2rayN.Views.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
|
|
||||||
xmlns:base="clr-namespace:v2rayN.Base"
|
xmlns:base="clr-namespace:v2rayN.Base"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
xmlns:resx="clr-namespace:v2rayN.Resx"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
|
||||||
xmlns:local="clr-namespace:v2rayN.Views"
|
xmlns:local="clr-namespace:v2rayN.Views"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
|
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||||
|
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
|
||||||
|
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||||
Title="v2rayN"
|
Title="v2rayN"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="700"
|
||||||
|
@ -79,6 +79,10 @@
|
||||||
x:Name="menuAddSocksServer"
|
x:Name="menuAddSocksServer"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuAddSocksServer}" />
|
Header="{x:Static resx:ResUI.menuAddSocksServer}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuAddHttpServer"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuAddHttpServer}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuAddTrojanServer"
|
x:Name="menuAddTrojanServer"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace v2rayN.Views
|
||||||
this.BindCommand(ViewModel, vm => vm.AddVlessServerCmd, v => v.menuAddVlessServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddVlessServerCmd, v => v.menuAddVlessServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddShadowsocksServerCmd, v => v.menuAddShadowsocksServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddShadowsocksServerCmd, v => v.menuAddShadowsocksServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.AddHttpServerCmd, v => v.menuAddHttpServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||||
|
|
Loading…
Reference in New Issue