diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs
index f64cef38..6ba5b6e0 100644
--- a/v2rayN/v2rayN/Global.cs
+++ b/v2rayN/v2rayN/Global.cs
@@ -110,28 +110,32 @@ namespace v2rayN
///
- /// vmess
+ /// Vmess
///
public const string vmessProtocol = "vmess://";
///
- /// shadowsocks
+ /// Shadowsocks
///
public const string ssProtocol = "ss://";
///
- /// socks
+ /// ShadowsocksR
+ ///
+ public const string ssrProtocol = "ssr://";
+ ///
+ /// Socks proxy
///
public const string socksProtocol = "socks://";
///
- /// http
+ /// HTTP
///
public const string httpProtocol = "http://";
///
- /// https
+ /// HTTPS
///
public const string httpsProtocol = "https://";
///
- /// pac
+ /// PAC
///
public const string pacFILE = "pac.txt";
@@ -164,6 +168,7 @@ namespace v2rayN
public const string IEProxyExceptions = "localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*";
+ public const string ssProtocols_via_v2ray = "aes-256-cfb;aes-128-cfb;chacha20;chacha20-ietf;aes-256-gcm;aes-128-gcm;chacha20-poly1305;chacha20-ietf-poly1305";
#endregion
#region 全局变量
diff --git a/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs b/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs
index 8c3a81f3..80f73ee3 100644
--- a/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs
+++ b/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
+using System.Text.RegularExpressions;
using v2rayN.Base;
using v2rayN.Mode;
@@ -1215,7 +1216,7 @@ namespace v2rayN.Handler
msg = UIRes.I18N("ConfigurationFormatIncorrect");
vmessItem.configType = (int)EConfigType.Shadowsocks;
- result = result.Substring(Global.ssProtocol.Length);
+ result = result.Substring(Global.ssProtocol.Length); // strip
//remark
int indexRemark = result.IndexOf("#");
if (indexRemark > 0)
@@ -1255,6 +1256,61 @@ namespace v2rayN.Handler
vmessItem.security = arr21[0];
vmessItem.id = arr21[1];
}
+ else if (result.StartsWith(Global.ssrProtocol))
+ {
+ vmessItem.configType = (int)EConfigType.Shadowsocks;
+ if (result.Length <= Global.ssrProtocol.Length)
+ {
+ return null;
+ }
+ result = result.Substring(Global.ssrProtocol.Length);
+
+ //part decode
+ // thanks to https://html50.github.io/ssr2jsonBat/
+ result = result.Replace("-", "+").Replace("_", "/"); // TODO: review ss:// works.
+ string text = Utils.Base64Decode(result);
+ try
+ {
+ string[] arr = text.Split(':');
+
+ string ip = arr[0];
+ string port = arr[1];
+ string protocol = arr[2];
+ string method = arr[3];
+ string obfs = arr[4];
+ string[] base64two = arr[5].Split(new string[] { "/?"}, StringSplitOptions.RemoveEmptyEntries);
+ string password = Utils.Base64Decode(base64two[0]);
+ string remark = "";
+
+ string arr2 = base64two[1];
+ string _remark = Regex.Match(arr2, "remarks=([^&]*)").Groups[1].Value;
+ _remark = _remark.Replace("-", "+").Replace("_", "/"); // necessary
+ remark = Utils.Base64Decode(_remark);
+
+ if (method == "chacha20-ietf") { method = "chacha20-ietf-poly1305"; } // ssr alia
+ string[] v2ray_supported = Global.ssProtocols_via_v2ray.Split(';');
+ if (!v2ray_supported.Contains(method.ToLower()) ||
+ protocol != "origin" ||
+ obfs != "plain")
+ {
+ // TODO: Counters and then report to user
+ msg = UIRes.I18N("IncorrectconfigurationSSR");
+ return null; // skip
+ }
+
+ vmessItem.address = ip;
+ vmessItem.port = Convert.ToInt32(port);
+ vmessItem.security = method;
+ vmessItem.id = password;
+ vmessItem.remarks = remark;
+ }
+ catch
+ {
+ System.Diagnostics.Debug.Fail(text);
+ msg = UIRes.I18N("IncorrectconfigurationSSRError");
+ return null;
+ }
+ }
else if (result.StartsWith(Global.socksProtocol))
{
msg = UIRes.I18N("ConfigurationFormatIncorrect");
diff --git a/v2rayN/v2rayN/Resx/ResUI.Designer.cs b/v2rayN/v2rayN/Resx/ResUI.Designer.cs
index e80f0555..bc480b11 100644
--- a/v2rayN/v2rayN/Resx/ResUI.Designer.cs
+++ b/v2rayN/v2rayN/Resx/ResUI.Designer.cs
@@ -19,7 +19,7 @@ namespace v2rayN.Resx {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ResUI {
@@ -249,6 +249,24 @@ namespace v2rayN.Resx {
}
}
+ ///
+ /// 查找类似 is not supported. 的本地化字符串。
+ ///
+ internal static string IncorrectconfigurationSSR {
+ get {
+ return ResourceManager.GetString("IncorrectconfigurationSSR", resourceCulture);
+ }
+ }
+
+ ///
+ /// 查找类似 An error occurred. 的本地化字符串。
+ ///
+ internal static string IncorrectconfigurationSSRError {
+ get {
+ return ResourceManager.GetString("IncorrectconfigurationSSRError", resourceCulture);
+ }
+ }
+
///
/// 查找类似 is not the correct server configuration file, please check 的本地化字符串。
///
diff --git a/v2rayN/v2rayN/Resx/ResUI.resx b/v2rayN/v2rayN/Resx/ResUI.resx
index 74280a36..084e0701 100644
--- a/v2rayN/v2rayN/Resx/ResUI.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.resx
@@ -222,6 +222,12 @@
is not the correct configuration, please check
+
+ is not supported.
+
+
+ An error occurred.
+
is not the correct server configuration file, please check
diff --git a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
index cf7cab26..9eac4c3a 100644
--- a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
@@ -222,6 +222,12 @@
不是正确的配置,请检查
+
+ 不受支持或识别失败。
+
+
+ 发生内部错误。
+
不是正确的服务端配置文件,请检查