Compare commits

...

22 Commits
3.17 ... 3.20

Author SHA1 Message Date
2dust
2f3f52c5e0 Merge pull request #928 from rprx/patch-6
Update link
2020-08-01 09:32:41 +08:00
RPRX
1dcb72e9dc Update link 2020-07-31 14:06:30 +00:00
2dust
153c8a0a74 Merge pull request #921 from studentmain/stdurl
support new vmess url, fix ss url
2020-07-28 13:03:58 +08:00
Student Main
4e8ea374d8 regex vmess url 2020-07-25 21:09:33 +08:00
Student Main
e313e004eb vmess 2020-07-20 17:34:32 +08:00
Student Main
93b8dec63e ctrl cv sswindows 2020-07-19 20:05:16 +08:00
2dust
5c9c35c199 Merge pull request #866 from pzhlkj6612/ss_link_import
正确处理 存在空字段的 或 密码中包含冒号或 at 符号的 shadowsocks 分享 URL
2020-06-30 17:29:16 +08:00
2dust
4a6b8968d5 Merge pull request #860 from pzhlkj6612/master
在 v2rayN.exe 所在的文件夹运行 v2rayUpgrade.exe
2020-06-30 17:28:48 +08:00
2dust
088d2e6834 Update SpeedtestHandler.cs 2020-06-30 16:41:31 +08:00
Mozi
4f39f7a932 Properly parse shadowsocks URL
1. Parse the URL containing "colon" or "at sign" in the password.
2. Check the empty fields in the URL.
2020-06-08 15:33:22 +08:00
Mozi
2615b72cee Run v2rayUpgrade.exe in the same folder as v2rayN.exe 2020-06-06 12:09:04 +08:00
2dust
a799420d0f v2fly 2020-06-04 08:31:18 +08:00
2dust
70069a05e6 Update README.md 2020-06-04 08:08:30 +08:00
2dust
d385b44a48 Merge pull request #735 from rprx/patch-5
允许不安全连接 -> 跳过证书验证
2020-04-25 09:29:23 +08:00
rprx
56c1557f4a 允许不安全连接 -> 跳过证书验证
https://github.com/2dust/v2rayN/pull/733
2020-04-24 02:57:38 +00:00
2dust
737d563ebb up speedtest 2020-04-23 16:20:30 +08:00
2dust
81b70195cf Merge pull request #730 from rprx/patch-3
Update UI
2020-04-23 16:11:34 +08:00
2dust
e60851153b Merge pull request #728 from rprx/patch-2
Delete #routingobject
2020-04-23 16:11:23 +08:00
rprx
009a15f0d9 Update UI
Update UI
2020-04-23 07:27:13 +00:00
rprx
f234775bd5 Delete #routingobject
打开页面时露出上方“路由功能”的描述
2020-04-23 06:31:10 +00:00
2dust
9b8bd0fa8a Merge pull request #725 from rprx/patch-1
v2ray.com -> v2fly.org
2020-04-23 13:51:29 +08:00
rprx
f74191946c v2ray.com -> v2fly.org
v2ray.com -> v2fly.org
2020-04-23 05:48:34 +00:00
12 changed files with 245 additions and 87 deletions

View File

@@ -7,4 +7,4 @@
### Requirements
- Microsoft [.NET Framework 4.6](https://docs.microsoft.com/zh-cn/dotnet/framework/install/guide-for-developers) or higher
- Project V core [https://github.com/v2ray/v2ray-core/releases](https://github.com/v2ray/v2ray-core/releases)
- Project V core [https://github.com/v2fly/v2ray-core/releases](https://github.com/v2fly/v2ray-core/releases)

View File

@@ -149,7 +149,7 @@
<value>203, 12</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>是否允许不安全连接(allowInsecure)</value>
<value>跳过证书验证(allowInsecure)</value>
</data>
<data name="cmbAllowInsecure.Location" type="System.Drawing.Point, System.Drawing">
<value>223, 7</value>

View File

@@ -1298,7 +1298,16 @@ namespace v2rayN.Forms
try
{
string fileName = Utils.GetPath(downloadHandle.DownloadFileName);
Process process = Process.Start("v2rayUpgrade.exe", "\"" + fileName + "\"");
Process process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "v2rayUpgrade.exe",
Arguments = "\"" + fileName + "\"",
WorkingDirectory = Utils.StartupPath()
}
};
process.Start();
if (process.Id > 0)
{
menuExit_Click(null, null);

View File

@@ -444,7 +444,7 @@ namespace v2rayN.Forms
private void linkLabelRoutingDoc_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("https://www.v2ray.com/chapter_02/03_routing.html#routingobject");
System.Diagnostics.Process.Start("https://www.v2fly.org/config/routing.html");
}
}

View File

@@ -128,7 +128,7 @@
<value>222, 16</value>
</data>
<data name="chkdefAllowInsecure.Text" xml:space="preserve">
<value>是否允许不安全连接(allowInsecure)</value>
<value>底层传输安全选tls时默认跳过证书验证(allowInsecure)</value>
</data>
<data name="label16.Size" type="System.Drawing.Size, System.Drawing">
<value>53, 12</value>

View File

@@ -6,7 +6,7 @@ namespace v2rayN
#region
public const string v2rayWebsiteUrl = @"https://www.v2ray.com/";
public const string v2rayWebsiteUrl = @"https://www.v2fly.org/";
public const string AboutUrl = @"https://github.com/2dust/v2rayN";
public const string UpdateUrl = AboutUrl + @"/releases";

View File

@@ -54,8 +54,8 @@ namespace v2rayN.Handler
private readonly string nLatestUrl = "https://github.com/2dust/v2rayN/releases/latest";
private const string nUrl = "https://github.com/2dust/v2rayN/releases/download/{0}/v2rayN.zip";
private readonly string coreLatestUrl = "https://github.com/v2ray/v2ray-core/releases/latest";
private const string coreUrl = "https://github.com/v2ray/v2ray-core/releases/download/{0}/v2ray-windows-{1}.zip";
private readonly string coreLatestUrl = "https://github.com/v2fly/v2ray-core/releases/latest";
private const string coreUrl = "https://github.com/v2fly/v2ray-core/releases/download/{0}/v2ray-windows-{1}.zip";
public async void CheckUpdateAsync(string type)
{
@@ -101,7 +101,7 @@ namespace v2rayN.Handler
string filePath = Utils.GetPath("V2ray.exe");
if (!File.Exists(filePath))
{
string msg = string.Format(UIRes.I18N("NotFoundCore"), @"https://github.com/v2ray/v2ray-core/releases");
string msg = string.Format(UIRes.I18N("NotFoundCore"), @"https://github.com/v2fly/v2ray-core/releases");
//ShowMsg(true, msg);
return "";
}
@@ -136,13 +136,15 @@ namespace v2rayN.Handler
string curVersion;
string message;
string url;
if (type == "Core") {
if (type == "Core")
{
curVersion = "v" + getV2rayVersion();
message = string.Format(UIRes.I18N("IsLatestCore"), curVersion);
string osBit = Environment.Is64BitProcess ? "64" : "32";
url = string.Format(coreUrl, version, osBit);
}
else if (type == "v2rayN") {
else if (type == "v2rayN")
{
curVersion = FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString();
message = string.Format(UIRes.I18N("IsLatestN"), curVersion);
url = string.Format(nUrl, version);
@@ -172,8 +174,9 @@ namespace v2rayN.Handler
#region Download
public void DownloadFileAsync(string url, WebProxy webProxy, int downloadTimeout)
public WebClientEx DownloadFileAsync(string url, WebProxy webProxy, int downloadTimeout)
{
WebClientEx ws = new WebClientEx();
try
{
Utils.SetSecurityProtocol();
@@ -182,7 +185,7 @@ namespace v2rayN.Handler
progressPercentage = -1;
totalBytesToReceive = 0;
WebClientEx ws = new WebClientEx();
//WebClientEx ws = new WebClientEx();
DownloadTimeout = downloadTimeout;
if (webProxy != null)
{
@@ -199,6 +202,7 @@ namespace v2rayN.Handler
Error?.Invoke(this, new ErrorEventArgs(ex));
}
return ws;
}
void ws_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

View File

@@ -11,26 +11,17 @@ namespace v2rayN.Handler
{
class SpeedtestHandler
{
private DownloadHandle downloadHandle2;
private Config _config;
private V2rayHandler _v2rayHandler;
private List<int> _selecteds;
Action<int, string> _updateFunc;
private int testCounter = 0;
private int ItemIndex
{
get
{
return _selecteds[testCounter - 1];
}
}
public SpeedtestHandler(ref Config config, ref V2rayHandler v2rayHandler, List<int> selecteds, string actionType, Action<int, string> update)
{
_config = config;
_v2rayHandler = v2rayHandler;
_selecteds = selecteds;
_selecteds = Utils.DeepCopy(selecteds);
_updateFunc = update;
if (actionType == "ping")
@@ -178,6 +169,7 @@ namespace v2rayN.Handler
private void RunSpeedTest()
{
int testCounter = 0;
int pid = -1;
if (_config.vmess.Count <= 0)
@@ -188,39 +180,41 @@ namespace v2rayN.Handler
pid = _v2rayHandler.LoadV2rayConfigString(_config, _selecteds);
string url = _config.speedTestUrl;
testCounter = 0;
if (downloadHandle2 == null)
DownloadHandle downloadHandle2 = new DownloadHandle();
downloadHandle2.UpdateCompleted += (sender2, args) =>
{
downloadHandle2 = new DownloadHandle();
downloadHandle2.UpdateCompleted += (sender2, args) =>
{
_updateFunc(ItemIndex, args.Msg);
if (args.Success) StartNext();
};
downloadHandle2.Error += (sender2, args) =>
{
_updateFunc(ItemIndex, args.GetException().Message);
StartNext();
};
}
StartNext();
void StartNext()
_updateFunc(testCounter, args.Msg);
};
downloadHandle2.Error += (sender2, args) =>
{
if (testCounter >= _selecteds.Count)
_updateFunc(testCounter, args.GetException().Message);
};
var timeout = 10;
foreach (int itemIndex in _selecteds)
{
if (itemIndex >= _config.vmess.Count)
{
if (pid > 0) _v2rayHandler.V2rayStopPid(pid);
return;
break;
}
if (_config.vmess[itemIndex].configType == (int)EConfigType.Custom)
{
continue;
}
testCounter = itemIndex;
int httpPort = _config.GetLocalPort("speedtest");
int index = _selecteds[testCounter];
testCounter++;
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort + index);
downloadHandle2.DownloadFileAsync(url, webProxy, 10);
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort + itemIndex);
var ws = downloadHandle2.DownloadFileAsync(url, webProxy, timeout - 2);
Thread.Sleep(1000 * timeout);
ws.CancelAsync();
Thread.Sleep(1000 * 2);
}
if (pid > 0) _v2rayHandler.V2rayStopPid(pid);
}

View File

@@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using v2rayN.Base;
using v2rayN.Mode;
@@ -392,7 +396,7 @@ namespace v2rayN.Handler
outbound.mux.enabled = false;
outbound.mux.concurrency = -1;
outbound.protocol = "shadowsocks";
outbound.settings.vnext = null;
@@ -454,7 +458,7 @@ namespace v2rayN.Handler
{
//远程服务器底层传输配置
streamSettings.network = config.network();
string host = config.requestHost();
string host = config.requestHost();
//if tls
if (config.streamSecurity() == Global.StreamSecurity)
{
@@ -1195,7 +1199,7 @@ namespace v2rayN.Handler
int indexSplit = result.IndexOf("?");
if (indexSplit > 0)
{
vmessItem = ResolveVmess4Kitsunebi(result);
vmessItem = ResolveStdVmess(result) ?? ResolveVmess4Kitsunebi(result);
}
else
{
@@ -1242,46 +1246,21 @@ namespace v2rayN.Handler
{
msg = UIRes.I18N("ConfigurationFormatIncorrect");
vmessItem.configType = (int)EConfigType.Shadowsocks;
result = result.Substring(Global.ssProtocol.Length);
//remark
int indexRemark = result.IndexOf("#");
if (indexRemark > 0)
vmessItem = ResolveSSLegacy(result);
if (vmessItem == null)
{
try
{
vmessItem.remarks = WebUtility.UrlDecode(result.Substring(indexRemark + 1, result.Length - indexRemark - 1));
}
catch { }
result = result.Substring(0, indexRemark);
vmessItem = ResolveSip002(result);
}
//part decode
int indexS = result.IndexOf("@");
if (indexS > 0)
if (vmessItem == null)
{
result = Utils.Base64Decode(result.Substring(0, indexS)) + result.Substring(indexS, result.Length - indexS);
return null;
}
else
if (vmessItem.address.Length == 0 || vmessItem.port == 0 || vmessItem.security.Length == 0 || vmessItem.id.Length == 0)
{
result = Utils.Base64Decode(result);
return null;
}
string[] arr1 = result.Split('@');
if (arr1.Length != 2)
{
return null;
}
string[] arr21 = arr1[0].Split(':');
//string[] arr22 = arr1[1].Split(':');
int indexPort = arr1[1].LastIndexOf(":");
if (arr21.Length != 2 || indexPort < 0)
{
return null;
}
vmessItem.address = arr1[1].Substring(0, indexPort);
vmessItem.port = Utils.ToInt(arr1[1].Substring(indexPort + 1, arr1[1].Length - (indexPort + 1)));
vmessItem.security = arr21[0];
vmessItem.id = arr21[1];
vmessItem.configType = (int)EConfigType.Shadowsocks;
}
else if (result.StartsWith(Global.socksProtocol))
{
@@ -1406,6 +1385,177 @@ namespace v2rayN.Handler
return vmessItem;
}
private static VmessItem ResolveSip002(string result)
{
Uri parsedUrl;
try
{
parsedUrl = new Uri(result);
}
catch (UriFormatException)
{
return null;
}
VmessItem server = new VmessItem
{
remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
address = parsedUrl.IdnHost,
port = parsedUrl.Port,
};
// parse base64 UserInfo
string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped);
string base64 = rawUserInfo.Replace('-', '+').Replace('_', '/'); // Web-safe base64 to normal base64
string userInfo;
try
{
userInfo = Encoding.UTF8.GetString(Convert.FromBase64String(
base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=')));
}
catch (FormatException)
{
return null;
}
string[] userInfoParts = userInfo.Split(new char[] { ':' }, 2);
if (userInfoParts.Length != 2)
{
return null;
}
server.security = userInfoParts[0];
server.id = userInfoParts[1];
NameValueCollection queryParameters = HttpUtility.ParseQueryString(parsedUrl.Query);
if (queryParameters["plugin"] != null)
{
return null;
}
return server;
}
private static readonly Regex UrlFinder = new Regex(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase);
private static readonly Regex DetailsParser = new Regex(@"^((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$", RegexOptions.IgnoreCase);
private static VmessItem ResolveSSLegacy(string result)
{
var match = UrlFinder.Match(result);
if (!match.Success)
return null;
VmessItem server = new VmessItem();
var base64 = match.Groups["base64"].Value.TrimEnd('/');
var tag = match.Groups["tag"].Value;
if (!tag.IsNullOrEmpty())
{
server.remarks = HttpUtility.UrlDecode(tag, Encoding.UTF8);
}
Match details;
try
{
details = DetailsParser.Match(Encoding.UTF8.GetString(Convert.FromBase64String(
base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))));
}
catch (FormatException)
{
return null;
}
if (!details.Success)
return null;
server.security = details.Groups["method"].Value;
server.id = details.Groups["password"].Value;
server.address = details.Groups["hostname"].Value;
server.port = int.Parse(details.Groups["port"].Value);
return server;
}
private static readonly Regex StdVmessUserInfo = new Regex(
@"^(?<network>[a-z]+)(\+(?<streamSecurity>[a-z]+))?:(?<id>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})-(?<alterId>[0-9]+)$");
private static VmessItem ResolveStdVmess(string result)
{
VmessItem i = new VmessItem
{
configType = (int)EConfigType.Vmess,
security = "auto"
};
Uri u = new Uri(result);
i.address = u.IdnHost;
i.port = u.Port;
i.remarks = u.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
var q = HttpUtility.ParseQueryString(u.Query);
var m = StdVmessUserInfo.Match(u.UserInfo);
if (!m.Success) return null;
i.id = m.Groups["id"].Value;
if (!int.TryParse(m.Groups["alterId"].Value, out int aid))
{
return null;
}
i.alterId = aid;
if (m.Groups["streamSecurity"].Success)
{
i.streamSecurity = m.Groups["streamSecurity"].Value;
}
switch (i.streamSecurity)
{
case "tls":
// TODO tls config
break;
default:
if (!string.IsNullOrWhiteSpace(i.streamSecurity))
return null;
break;
}
i.network = m.Groups["network"].Value;
switch (i.network)
{
case "tcp":
string t1 = q["type"] ?? "none";
i.headerType = t1;
// TODO http option
break;
case "kcp":
i.headerType = q["type"] ?? "none";
// TODO kcp seed
break;
case "ws":
string p1 = q["path"] ?? "/";
string h1 = q["host"] ?? "";
i.requestHost = h1;
i.path = p1;
break;
case "http":
i.network = "h2";
string p2 = q["path"] ?? "/";
string h2 = q["host"] ?? "";
i.requestHost = h2;
i.path = p2;
break;
case "quic":
string s = q["security"] ?? "none";
string k = q["key"] ?? "";
string t3 = q["type"] ?? "none";
i.headerType = t3;
i.requestHost = s;
i.path = k;
break;
default:
return null;
}
return i;
}
#endregion
#region Gen speedtest config
@@ -1427,7 +1577,7 @@ namespace v2rayN.Handler
msg = UIRes.I18N("InitialConfiguration");
Config configCopy = Utils.DeepCopy(config);
Config configCopy = Utils.DeepCopy(config);
string result = Utils.GetEmbedText(SampleClient);
if (Utils.IsNullOrEmpty(result))

View File

@@ -174,7 +174,7 @@ namespace v2rayN.Handler
}
if (Utils.IsNullOrEmpty(fileName))
{
string msg = string.Format(UIRes.I18N("NotFoundCore"), @"https://github.com/v2ray/v2ray-core/releases");
string msg = string.Format(UIRes.I18N("NotFoundCore"), @"https://github.com/v2fly/v2ray-core/releases");
ShowMsg(false, msg);
}
return fileName;

View File

@@ -32,4 +32,4 @@ using System.Runtime.InteropServices;
// 方法是按如下所示使用“*”:
//[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyVersion("1.0.0")]
[assembly: AssemblyFileVersion("3.17")]
[assembly: AssemblyFileVersion("3.19")]

View File

@@ -93,6 +93,7 @@
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>