From 5683df2fc09c9a57a11f0e845eccb912bf6518d1 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Mon, 8 Apr 2024 14:02:56 +0800
Subject: [PATCH] Added outbound HTTP support (support group prefix proxy)
https://github.com/2dust/v2rayN/discussions/4550
---
v2rayN/v2rayN/Global.cs | 3 +-
v2rayN/v2rayN/Handler/ConfigHandler.cs | 17 +
v2rayN/v2rayN/Handler/CoreConfigSingbox.cs | 192 +++++-----
v2rayN/v2rayN/Handler/CoreConfigV2ray.cs | 334 +++++++++---------
v2rayN/v2rayN/Models/EConfigType.cs | 3 +-
v2rayN/v2rayN/Models/V2rayConfig.cs | 12 +-
v2rayN/v2rayN/Resx/ResUI.Designer.cs | 9 +
v2rayN/v2rayN/Resx/ResUI.resx | 3 +
v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx | 3 +
v2rayN/v2rayN/Resx/ResUI.zh-Hant.resx | 3 +
.../v2rayN/ViewModels/AddServerViewModel.cs | 4 +-
.../v2rayN/ViewModels/MainWindowViewModel.cs | 5 +
v2rayN/v2rayN/Views/AddServerWindow.xaml.cs | 2 +
v2rayN/v2rayN/Views/MainWindow.xaml | 18 +-
v2rayN/v2rayN/Views/MainWindow.xaml.cs | 1 +
15 files changed, 336 insertions(+), 273 deletions(-)
diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs
index 9df96dc0..19b3cf35 100644
--- a/v2rayN/v2rayN/Global.cs
+++ b/v2rayN/v2rayN/Global.cs
@@ -142,7 +142,8 @@ namespace v2rayN
{
{EConfigType.VMess,"vmess"},
{EConfigType.Shadowsocks,"shadowsocks"},
- {EConfigType.Socks,"socks"},
+ {EConfigType.Socks,"socks"},
+ {EConfigType.Http,"http"},
{EConfigType.VLESS,"vless"},
{EConfigType.Trojan,"trojan"},
{EConfigType.Hysteria2,"hysteria2"},
diff --git a/v2rayN/v2rayN/Handler/ConfigHandler.cs b/v2rayN/v2rayN/Handler/ConfigHandler.cs
index aea543f1..bf99b053 100644
--- a/v2rayN/v2rayN/Handler/ConfigHandler.cs
+++ b/v2rayN/v2rayN/Handler/ConfigHandler.cs
@@ -664,6 +664,23 @@ namespace v2rayN.Handler
return 0;
}
+ ///
+ /// Add or edit server
+ ///
+ ///
+ ///
+ ///
+ 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;
+ }
+
///
/// Add or edit server
///
diff --git a/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs b/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs
index 3da7d3c6..635967c7 100644
--- a/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs
+++ b/v2rayN/v2rayN/Handler/CoreConfigSingbox.cs
@@ -213,105 +213,111 @@ namespace v2rayN.Handler
{
outbound.server = node.address;
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];
-
- 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()
+ case EConfigType.VMess:
{
- type = "salamander",
- password = node.path.TrimEx(),
- };
- }
+ outbound.uuid = node.id;
+ 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;
- outbound.down_mbps = _config.hysteriaItem.down_mbps > 0 ? _config.hysteriaItem.down_mbps : null;
- }
- else if (node.configType == EConfigType.Tuic)
- {
- outbound.type = Global.ProtocolTypes[EConfigType.Tuic];
+ GenOutboundMux(node, outbound);
+ break;
+ }
+ case EConfigType.Shadowsocks:
+ {
+ outbound.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
+ outbound.password = node.id;
- outbound.uuid = node.id;
- outbound.password = node.security;
- outbound.congestion_control = node.headerType;
- }
- else if (node.configType == EConfigType.Wireguard)
- {
- outbound.type = Global.ProtocolTypes[EConfigType.Wireguard];
+ GenOutboundMux(node, outbound);
+ break;
+ }
+ case EConfigType.Socks:
+ {
+ outbound.version = "5";
+ 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.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);
+ outbound.packet_encoding = "xudp";
+
+ if (Utils.IsNullOrEmpty(node.flow))
+ {
+ 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);
diff --git a/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs b/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs
index 202f1363..c29f3869 100644
--- a/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs
+++ b/v2rayN/v2rayN/Handler/CoreConfigV2ray.cs
@@ -295,182 +295,188 @@ namespace v2rayN.Handler
{
try
{
- if (node.configType == EConfigType.VMess)
+ switch (node.configType)
{
- 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];
- }
- //远程服务器用户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()
+ case EConfigType.VMess:
{
- user = node.security,
- pass = node.id,
- level = 1
- };
+ 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;
- serversItem.users = new List() { 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.vnext = null;
- }
- else if (node.configType == 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))
+ outbound.settings.servers = null;
+ break;
+ }
+ case EConfigType.Shadowsocks:
{
- 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);
+
+ outbound.settings.vnext = null;
+ break;
}
- }
- if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow))
- {
- GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
- }
+ case EConfigType.Socks:
+ case EConfigType.Http:
+ {
+ 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];
- outbound.settings.servers = null;
+ if (!Utils.IsNullOrEmpty(node.security)
+ && !Utils.IsNullOrEmpty(node.id))
+ {
+ SocksUsersItem4Ray socksUsersItem = new()
+ {
+ user = node.security,
+ pass = node.id,
+ level = 1
+ };
+
+ serversItem.users = new List() { 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;
- serversItem.level = 1;
-
- GenOutboundMux(node, outbound, false);
-
- outbound.protocol = Global.ProtocolTypes[EConfigType.Trojan];
- outbound.settings.vnext = null;
- }
+ outbound.protocol = Global.ProtocolTypes[node.configType];
GenBoundStreamSettings(node, outbound.streamSettings);
}
catch (Exception ex)
diff --git a/v2rayN/v2rayN/Models/EConfigType.cs b/v2rayN/v2rayN/Models/EConfigType.cs
index 60f43d74..81880eb4 100644
--- a/v2rayN/v2rayN/Models/EConfigType.cs
+++ b/v2rayN/v2rayN/Models/EConfigType.cs
@@ -10,6 +10,7 @@
Trojan = 6,
Hysteria2 = 7,
Tuic = 8,
- Wireguard = 9
+ Wireguard = 9,
+ Http = 10
}
}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Models/V2rayConfig.cs b/v2rayN/v2rayN/Models/V2rayConfig.cs
index e5b6750f..eba9def5 100644
--- a/v2rayN/v2rayN/Models/V2rayConfig.cs
+++ b/v2rayN/v2rayN/Models/V2rayConfig.cs
@@ -232,7 +232,7 @@ namespace v2rayN.Models
///
///
///
- public List vnext { get; set; }
+ public List? vnext { get; set; }
///
///
@@ -288,17 +288,17 @@ namespace v2rayN.Models
///
///
///
- public string method { get; set; }
+ public string? method { get; set; }
///
///
///
- public bool ota { get; set; }
+ public bool? ota { get; set; }
///
///
///
- public string password { get; set; }
+ public string? password { get; set; }
///
///
@@ -308,7 +308,7 @@ namespace v2rayN.Models
///
///
///
- public int level { get; set; }
+ public int? level { get; set; }
///
/// trojan
@@ -336,7 +336,7 @@ namespace v2rayN.Models
///
///
///
- public int level { get; set; }
+ public int? level { get; set; }
}
public class Mux4Ray
diff --git a/v2rayN/v2rayN/Resx/ResUI.Designer.cs b/v2rayN/v2rayN/Resx/ResUI.Designer.cs
index 97b872dd..f2f0f507 100644
--- a/v2rayN/v2rayN/Resx/ResUI.Designer.cs
+++ b/v2rayN/v2rayN/Resx/ResUI.Designer.cs
@@ -618,6 +618,15 @@ namespace v2rayN.Resx {
}
}
+ ///
+ /// 查找类似 Add [Http] server 的本地化字符串。
+ ///
+ public static string menuAddHttpServer {
+ get {
+ return ResourceManager.GetString("menuAddHttpServer", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Add [Hysteria2] server 的本地化字符串。
///
diff --git a/v2rayN/v2rayN/Resx/ResUI.resx b/v2rayN/v2rayN/Resx/ResUI.resx
index 9dbd1826..f474f069 100644
--- a/v2rayN/v2rayN/Resx/ResUI.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.resx
@@ -1198,4 +1198,7 @@
*grpc Authority
+
+ Add [Http] server
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
index fa0d4851..dca5948a 100644
--- a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
@@ -1195,4 +1195,7 @@
*grpc Authority
+
+ 添加[Http]服务器
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Resx/ResUI.zh-Hant.resx b/v2rayN/v2rayN/Resx/ResUI.zh-Hant.resx
index 42981ede..59538750 100644
--- a/v2rayN/v2rayN/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.zh-Hant.resx
@@ -1168,4 +1168,7 @@
*grpc Authority
+
+ 新增[Http]伺服器
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs b/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs
index 64c87c90..b3e54bd4 100644
--- a/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs
@@ -80,7 +80,8 @@ namespace v2rayN.ViewModels
return;
}
}
- if (SelectedSource.configType != EConfigType.Socks)
+ if (SelectedSource.configType != EConfigType.Socks
+ && SelectedSource.configType != EConfigType.Http)
{
if (Utils.IsNullOrEmpty(SelectedSource.id))
{
@@ -127,6 +128,7 @@ namespace v2rayN.ViewModels
EConfigType.VMess => ConfigHandler.AddServer(_config, item),
EConfigType.Shadowsocks => ConfigHandler.AddShadowsocksServer(_config, item),
EConfigType.Socks => ConfigHandler.AddSocksServer(_config, item),
+ EConfigType.Http => ConfigHandler.AddHttpServer(_config, item),
EConfigType.Trojan => ConfigHandler.AddTrojanServer(_config, item),
EConfigType.VLESS => ConfigHandler.AddVlessServer(_config, item),
EConfigType.Hysteria2 => ConfigHandler.AddHysteria2Server(_config, item),
diff --git a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
index df485a71..b39f0ebd 100644
--- a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
@@ -86,6 +86,7 @@ namespace v2rayN.ViewModels
public ReactiveCommand AddVlessServerCmd { get; }
public ReactiveCommand AddShadowsocksServerCmd { get; }
public ReactiveCommand AddSocksServerCmd { get; }
+ public ReactiveCommand AddHttpServerCmd { get; }
public ReactiveCommand AddTrojanServerCmd { get; }
public ReactiveCommand AddHysteria2ServerCmd { get; }
public ReactiveCommand AddTuicServerCmd { get; }
@@ -333,6 +334,10 @@ namespace v2rayN.ViewModels
{
EditServer(true, EConfigType.Socks);
});
+ AddHttpServerCmd = ReactiveCommand.Create(() =>
+ {
+ EditServer(true, EConfigType.Http);
+ });
AddTrojanServerCmd = ReactiveCommand.Create(() =>
{
EditServer(true, EConfigType.Trojan);
diff --git a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs
index 8668e6e5..0bbac569 100644
--- a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs
@@ -92,6 +92,7 @@ namespace v2rayN.Views
break;
case EConfigType.Socks:
+ case EConfigType.Http:
gridSocks.Visibility = Visibility.Visible;
break;
@@ -174,6 +175,7 @@ namespace v2rayN.Views
break;
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.security, v => v.txtSecurity4.Text).DisposeWith(disposables);
break;
diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml b/v2rayN/v2rayN/Views/MainWindow.xaml
index 1023c9ba..490c6cb5 100644
--- a/v2rayN/v2rayN/Views/MainWindow.xaml
+++ b/v2rayN/v2rayN/Views/MainWindow.xaml
@@ -1,17 +1,17 @@
+