Compare commits

...

20 Commits
1.6.4 ... 1.6.5

Author SHA1 Message Date
ChsBuffer
2247a75269 bump version to 1.6.5 2020-10-24 16:06:13 +08:00
ChsBuffer
c1e9856e92 refactor: check and build dns string 2020-10-23 18:32:06 +08:00
ChsBuffer
41e74e0794 feat: Add setting ”Modified DNS“ for Process Mode 2020-10-23 17:46:31 +08:00
ChsBuffer
6f8214951a fix: update subscription async warning 2020-10-23 17:20:58 +08:00
ChsBuffer
0fc5b77004 refactor: Regenerate SettingForm designer code 2020-10-23 16:35:49 +08:00
ChsBuffer
34cbcbfb0f fix: SettingForm Control Order 2020-10-23 16:30:21 +08:00
ChsBuffer
1ad4a08a85 fix: Edit subscription link shows "Remark Name Duplicate!" 2020-10-23 14:46:16 +08:00
ChsBuffer
8e0bc8e260 feat: Notification update subscription exception status code 2020-10-23 14:45:30 +08:00
ChsBuffer
bae9ecfe88 fix: ImportServerFromClipboard parse twice 2020-10-23 14:36:43 +08:00
ChsBuffer
3ca3e45ce2 feat: Add AioDNS Setting 2020-10-23 13:48:33 +08:00
ChsBuffer
bcb220bc4b Revert "refactor: MainForm change Enabled to change State"
This reverts commit abfae4a9a0.
2020-10-23 12:36:46 +08:00
AmazingDM
c50eb32828 Update README.md 2020-10-23 10:19:53 +08:00
ChsBuffer
b96f171b47 fix: V2RayConfigUtils direct outbound config
refactor: rename VMessController Name V2Ray to VMess
2020-10-22 21:31:20 +08:00
ChsBuffer
4fbbd1dbd4 feat: update progress check hash 2020-10-22 15:17:26 +08:00
ChsBuffer
2ad394dfde refactor: builder dns string and Mode FileString 2020-10-22 15:17:26 +08:00
ChsBuffer
421b35a797 fix: SettingForm UseCustomDNSCheckBox click event is not bound 2020-10-22 15:17:26 +08:00
Connection Refused
25612df086 Update v2ray-core 4.31.2 2020-10-22 13:24:43 +08:00
ChsBuffer
4ac5065ce4 feat: add UseMux Setting 2020-10-21 22:18:11 +08:00
ChsBuffer
d4b97a99e0 feat: V2Ray AllowInsecure Setting 2020-10-21 22:09:53 +08:00
ChsBuffer
3d49fe0338 Revert "feat: V2Ray TLS AllowInsecure Setting"
This reverts commit 591f8e5a5c.
2020-10-21 22:07:58 +08:00
22 changed files with 760 additions and 544 deletions

View File

@@ -15,9 +15,9 @@ namespace Netch.Controllers
/// <returns></returns> /// <returns></returns>
public bool Start() public bool Start()
{ {
if (!aiodns_dial(Encoding.UTF8.GetBytes(Path.GetFullPath("bin\\china_site_list")), if (!aiodns_dial(Encoding.UTF8.GetBytes(Path.GetFullPath(Global.Settings.AioDNS.RulePath)),
Encoding.UTF8.GetBytes("223.5.5.5:53"), Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.ChinaDNS}:53"),
Encoding.UTF8.GetBytes("1.1.1.1:53")) Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.OtherDNS}:53"))
) )
return false; return false;
return return

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.ServiceProcess; using System.ServiceProcess;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -78,7 +80,9 @@ namespace Netch.Controllers
{ {
// 备份并替换系统 DNS // 备份并替换系统 DNS
_sysDns = DNS.OutboundDNS; _sysDns = DNS.OutboundDNS;
DNS.OutboundDNS = "1.1.1.1,8.8.8.8"; if (string.IsNullOrWhiteSpace(Global.Settings.ModifiedDNS))
Global.Settings.ModifiedDNS = "1.1.1.1,8.8.8.8";
DNS.OutboundDNS = Global.Settings.ModifiedDNS;
} }
return aio_init(); return aio_init();

View File

@@ -73,7 +73,7 @@ namespace Netch.Controllers
{ {
if (Global.Settings.TUNTAP.DNS.Any()) if (Global.Settings.TUNTAP.DNS.Any())
{ {
dns = Global.Settings.TUNTAP.DNS.Aggregate((current, ip) => $"{current},{ip}"); dns = DNS.Join(Global.Settings.TUNTAP.DNS);
} }
else else
{ {

View File

@@ -15,7 +15,7 @@ namespace Netch.Controllers
public const string Name = @"Netch"; public const string Name = @"Netch";
public const string Copyright = @"Copyright © 2019 - 2020"; public const string Copyright = @"Copyright © 2019 - 2020";
public const string AssemblyVersion = @"1.6.4"; public const string AssemblyVersion = @"1.6.5";
private const string Suffix = @""; private const string Suffix = @"";
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}"; public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
@@ -26,8 +27,9 @@ namespace Netch.Forms
var texts = Clipboard.GetText(); var texts = Clipboard.GetText();
if (!string.IsNullOrWhiteSpace(texts)) if (!string.IsNullOrWhiteSpace(texts))
{ {
Global.Settings.Server.AddRange(ShareLink.ParseText(texts)); var servers = ShareLink.ParseText(texts);
NotifyTip(i18N.TranslateFormat("Import {0} server(s) form Clipboard", ShareLink.ParseText(texts).Count)); Global.Settings.Server.AddRange(servers);
NotifyTip(i18N.TranslateFormat("Import {0} server(s) form Clipboard", servers.Count));
InitServer(); InitServer();
Configuration.Save(); Configuration.Save();
@@ -136,7 +138,7 @@ namespace Netch.Forms
await MainController.Start(ServerComboBox.SelectedItem as Server, mode); await MainController.Start(ServerComboBox.SelectedItem as Server, mode);
} }
await Task.WhenAll(Global.Settings.SubscribeLink.Select(async item => await Task.Run(async () => await Task.WhenAll(Global.Settings.SubscribeLink.Select(async item => await Task.Run(() =>
{ {
try try
{ {
@@ -146,7 +148,17 @@ namespace Netch.Forms
if (Global.Settings.UseProxyToUpdateSubscription) if (Global.Settings.UseProxyToUpdateSubscription)
request.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); request.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
var servers = ShareLink.ParseText(await WebUtil.DownloadStringAsync(request)); List<Server> servers;
var result = WebUtil.DownloadString(request, out var rep);
if (rep.StatusCode == HttpStatusCode.OK)
{
servers = ShareLink.ParseText(result);
}
else
{
throw new Exception($"{item.Remark} Response Status Code: {rep.StatusCode}");
}
foreach (var server in servers) foreach (var server in servers)
{ {
@@ -298,36 +310,32 @@ namespace Netch.Forms
private async void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e) private async void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
{ {
State = State.Starting; Enabled = false;
StatusText(i18N.TranslateFormat("Uninstalling {0}", "NF Service")); StatusText(i18N.TranslateFormat("Uninstalling {0}", "NF Service"));
var result = false;
try try
{ {
await Task.Run(() => await Task.Run(() =>
{ {
if (NFController.UninstallDriver()) if (NFController.UninstallDriver())
{ {
result = true; StatusText(i18N.TranslateFormat("{0} has been uninstalled", "NF Service"));
} }
}); });
} }
finally finally
{ {
State = State.Stopped; Enabled = true;
if (result)
StatusText(i18N.TranslateFormat("{0} has been uninstalled", "NF Service"));
} }
} }
private async void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e) private async void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
{ {
State = State.Starting;
StatusText(i18N.TranslateFormat("Uninstalling {0}", "TUN/TAP driver")); StatusText(i18N.TranslateFormat("Uninstalling {0}", "TUN/TAP driver"));
var result = false; Enabled = false;
try try
{ {
await Task.Run(TUNTAP.deltapall); await Task.Run(TUNTAP.deltapall);
result = true; StatusText(i18N.TranslateFormat("{0} has been uninstalled", "TUN/TAP driver"));
} }
catch (Exception exception) catch (Exception exception)
{ {
@@ -335,9 +343,8 @@ namespace Netch.Forms
} }
finally finally
{ {
State = State.Stopped; State = State.Waiting;
if (result) Enabled = true;
StatusText(i18N.TranslateFormat("{0} has been uninstalled", "TUN/TAP driver"));
} }
} }

View File

@@ -2,6 +2,7 @@
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using Netch.Controllers; using Netch.Controllers;
using Netch.Utils; using Netch.Utils;
@@ -44,15 +45,37 @@ namespace Netch.Forms
if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK) if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK)
return; return;
NotifyTip(i18N.Translate("Start downloading new version")); NotifyTip(i18N.Translate("Start downloading new version"));
var tagPage = await WebUtil.DownloadStringAsync(WebUtil.CreateRequest(_updater.LatestVersionUrl));
var match = Regex.Match(tagPage, @"<td .*>(?<sha256>.*)</td>", RegexOptions.Singleline);
// TODO Replace with regex get basename and sha256
var fileName = Path.GetFileName(new Uri(_updater.LatestVersionDownloadUrl).LocalPath); var fileName = Path.GetFileName(new Uri(_updater.LatestVersionDownloadUrl).LocalPath);
fileName = fileName.Insert(fileName.LastIndexOf('.'), _updater.LatestVersionNumber); fileName = fileName.Insert(fileName.LastIndexOf('.'), _updater.LatestVersionNumber);
var fileFullPath = Path.Combine(Global.NetchDir, "data", fileName); var fileFullPath = Path.Combine(Global.NetchDir, "data", fileName);
var sha256 = match.Groups["sha256"].Value;
try try
{ {
if (!File.Exists(fileFullPath)) if (File.Exists(fileFullPath))
{ {
await WebUtil.DownloadFileAsync(WebUtil.CreateRequest(_updater.LatestVersionDownloadUrl), fileFullPath); if (Utils.Utils.SHA256CheckSum(fileFullPath) == sha256)
{
RunUpdater();
return;
}
File.Delete(fileFullPath);
}
// TODO Replace "New Version Found" to Progress bar
await WebUtil.DownloadFileAsync(WebUtil.CreateRequest(_updater.LatestVersionDownloadUrl), fileFullPath);
if (Utils.Utils.SHA256CheckSum(fileFullPath) != sha256)
{
MessageBoxX.Show("The downloaded file has the wrong hash");
return;
} }
RunUpdater(); RunUpdater();

View File

@@ -334,7 +334,7 @@ namespace Netch.Forms
private async void SpeedPictureBox_Click(object sender, EventArgs e) private async void SpeedPictureBox_Click(object sender, EventArgs e)
{ {
State = State.Starting; Enabled = false;
StatusText(i18N.Translate("Testing")); StatusText(i18N.Translate("Testing"));
try try
{ {
@@ -342,7 +342,7 @@ namespace Netch.Forms
} }
finally finally
{ {
State = State.Stopped; Enabled = true;
StatusText(i18N.Translate("Test done")); StatusText(i18N.Translate("Test done"));
Refresh(); Refresh();
} }

File diff suppressed because it is too large Load Diff

View File

@@ -83,13 +83,17 @@ namespace Netch.Forms
#endregion #endregion
#region Process Mode #region Process Mode
BindCheckBox(ModifySystemDNSCheckBox, BindCheckBox(ModifySystemDNSCheckBox,
b => Global.Settings.ModifySystemDNS = b, b => Global.Settings.ModifySystemDNS = b,
Global.Settings.ModifySystemDNS); Global.Settings.ModifySystemDNS);
BindTextBox(ModifiedDNSTextBox,
s => DNS.TrySplit(s, out _, 2),
s => Global.Settings.ModifiedDNS = s,
Global.Settings.ModifiedDNS);
#endregion #endregion
#region TUN/TAP #region TUN/TAP
@@ -111,6 +115,11 @@ namespace Netch.Forms
Global.Settings.TUNTAP.UseCustomDNS); Global.Settings.TUNTAP.UseCustomDNS);
TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null); TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null);
BindTextBox(TUNTAPDNSTextBox,
s => !UseCustomDNSCheckBox.Checked || DNS.TrySplit(s, out _, 2),
s => Global.Settings.TUNTAP.DNS = DNS.Split(s).ToList(),
DNS.Join(Global.Settings.TUNTAP.DNS));
BindCheckBox(ProxyDNSCheckBox, BindCheckBox(ProxyDNSCheckBox,
b => Global.Settings.TUNTAP.ProxyDNS = b, b => Global.Settings.TUNTAP.ProxyDNS = b,
Global.Settings.TUNTAP.ProxyDNS); Global.Settings.TUNTAP.ProxyDNS);
@@ -139,6 +148,9 @@ namespace Netch.Forms
BindCheckBox(TLSAllowInsecureCheckBox, BindCheckBox(TLSAllowInsecureCheckBox,
b => Global.Settings.V2RayConfig.AllowInsecure = b, b => Global.Settings.V2RayConfig.AllowInsecure = b,
Global.Settings.V2RayConfig.AllowInsecure); Global.Settings.V2RayConfig.AllowInsecure);
BindCheckBox(UseMuxCheckBox,
b => Global.Settings.V2RayConfig.UseMux = b,
Global.Settings.V2RayConfig.UseMux);
BindTextBox<int>(mtuTextBox, BindTextBox<int>(mtuTextBox,
i => true, i => true,
@@ -205,6 +217,25 @@ namespace Netch.Forms
Global.Settings.UpdateSubscribeatWhenOpened); Global.Settings.UpdateSubscribeatWhenOpened);
#endregion #endregion
#region AioDNS
BindTextBox(AioDNSRulePathTextBox,
s => true,
s => Global.Settings.AioDNS.RulePath = s,
Global.Settings.AioDNS.RulePath);
BindTextBox(ChinaDNSTextBox,
s => IPAddress.TryParse(s, out _),
s => Global.Settings.AioDNS.ChinaDNS = s,
Global.Settings.AioDNS.ChinaDNS);
BindTextBox(OtherDNSTextBox,
s => IPAddress.TryParse(s, out _),
s => Global.Settings.AioDNS.OtherDNS = s,
Global.Settings.AioDNS.OtherDNS);
#endregion
} }
private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object sender, EventArgs e) private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object sender, EventArgs e)
@@ -214,12 +245,12 @@ namespace Netch.Forms
if (UseCustomDNSCheckBox.Checked) if (UseCustomDNSCheckBox.Checked)
{ {
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any() TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any()
? Global.Settings.TUNTAP.DNS.Aggregate((current, ip) => $"{current},{ip}") ? DNS.Join(Global.Settings.TUNTAP.DNS)
: "1.1.1.1"; : "1.1.1.1";
} }
else else
{ {
TUNTAPDNSTextBox.Text = "Local DNS"; TUNTAPDNSTextBox.Text = "AioDNS";
} }
} }
@@ -253,42 +284,6 @@ namespace Netch.Forms
#region Check #region Check
#region TUNTAP
var dns = new string[0];
try
{
if (UseCustomDNSCheckBox.Checked)
{
dns = TUNTAPDNSTextBox.Text.Split(',').Where(s => !string.IsNullOrEmpty(s)).Select(s => s.Trim())
.ToArray();
if (dns.Any())
{
foreach (var ip in dns)
IPAddress.Parse(ip);
}
else
{
MessageBoxX.Show("DNS can not be empty");
return;
}
}
}
catch (Exception exception)
{
if (exception is FormatException)
MessageBoxX.Show(i18N.Translate("IP address format illegal. Try again."));
if (UseCustomDNSCheckBox.Checked)
{
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Aggregate((current, ip) => $"{current},{ip}");
}
return;
}
#endregion
#region Behavior #region Behavior
// STUN // STUN
@@ -326,7 +321,6 @@ namespace Netch.Forms
pair.Value.Invoke(pair.Key); pair.Value.Invoke(pair.Key);
} }
Global.Settings.TUNTAP.DNS = dns.ToList();
Global.Settings.STUN_Server = stunServer; Global.Settings.STUN_Server = stunServer;
Global.Settings.STUN_Server_Port = stunServerPort; Global.Settings.STUN_Server_Port = stunServerPort;
@@ -454,5 +448,10 @@ namespace Netch.Forms
private readonly Dictionary<Control, Func<string, bool>> _checkActions = new Dictionary<Control, Func<string, bool>>(); private readonly Dictionary<Control, Func<string, bool>> _checkActions = new Dictionary<Control, Func<string, bool>>();
private readonly Dictionary<Control, Action<Control>> _saveActions = new Dictionary<Control, Action<Control>>(); private readonly Dictionary<Control, Action<Control>> _saveActions = new Dictionary<Control, Action<Control>>();
private void ModifySystemDNSCheckBox_CheckedChanged(object sender, EventArgs e)
{
ModifiedDNSTextBox.Enabled = ModifySystemDNSCheckBox.Checked;
}
} }
} }

View File

@@ -109,14 +109,14 @@ namespace Netch.Forms
return; return;
} }
if (Global.Settings.SubscribeLink.Any(link => link.Remark.Equals(RemarkTextBox.Text)))
{
MessageBoxX.Show("Remark Name Duplicate!");
return;
}
if (_editingIndex == -1) if (_editingIndex == -1)
{ {
if (Global.Settings.SubscribeLink.Any(link => link.Remark.Equals(RemarkTextBox.Text)))
{
MessageBoxX.Show("Remark Name Duplicate!");
return;
}
Global.Settings.SubscribeLink.Add(new SubscribeLink Global.Settings.SubscribeLink.Add(new SubscribeLink
{ {
Remark = RemarkTextBox.Text, Remark = RemarkTextBox.Text,

View File

@@ -131,30 +131,30 @@ namespace Netch.Models
/// <returns>模式文件字符串</returns> /// <returns>模式文件字符串</returns>
public string ToFileString() public string ToFileString()
{ {
string fileString; StringBuilder fileString = new StringBuilder();
switch (Type) switch (Type)
{ {
case 0: case 0:
// 进程模式 // 进程模式
fileString = $"# {Remark}"; fileString.Append($"# {Remark}");
break; break;
case 1: case 1:
// TUN/TAP 规则内 IP CIDR无 Bypass China 设置 // TUN/TAP 规则内 IP CIDR无 Bypass China 设置
fileString = $"# {Remark}, {Type}, 0"; fileString.Append($"# {Remark}, {Type}, 0");
break; break;
default: default:
fileString = $"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}"; fileString.Append($"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}");
break; break;
} }
fileString += Global.EOF; if (Rule.Any())
{
fileString.Append(Global.EOF);
fileString.Append(string.Join(Global.EOF, Rule));
}
fileString = Rule.Aggregate(fileString, (current, item) => $"{current}{item}{Global.EOF}"); return fileString.ToString();
// 去除最后的行尾符
fileString = fileString.Substring(0, fileString.Length - 2);
return fileString;
} }
public string TypeToString() public string TypeToString()

View File

@@ -1,4 +1,6 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq;
namespace Netch.Models namespace Netch.Models
{ {
@@ -65,6 +67,17 @@ namespace Netch.Models
public bool AllowInsecure = true; public bool AllowInsecure = true;
public KcpConfig KcpConfig = new KcpConfig(); public KcpConfig KcpConfig = new KcpConfig();
public bool UseMux = true;
}
public class AioDNSConfig
{
public string RulePath = "bin\\china_site_list";
public string ChinaDNS = "223.5.5.5";
public string OtherDNS = "1.1.1.1";
} }
/// <summary> /// <summary>
@@ -127,6 +140,11 @@ namespace Netch.Models
/// </summary> /// </summary>
public bool ModifySystemDNS = false; public bool ModifySystemDNS = false;
/// <summary>
/// 要修改为的系统 DNS
/// </summary>
public string ModifiedDNS = "1.1.1.1,8.8.8.8";
/// <summary> /// <summary>
/// 解析服务器主机名 /// 解析服务器主机名
/// </summary> /// </summary>
@@ -233,5 +251,7 @@ namespace Netch.Models
public string Language = "System"; public string Language = "System";
public V2rayConfig V2RayConfig = new V2rayConfig(); public V2rayConfig V2RayConfig = new V2rayConfig();
public AioDNSConfig AioDNS = new AioDNSConfig();
} }
} }

View File

@@ -39,22 +39,19 @@ namespace Netch.Servers.VLESS.VLESSForm
s => true, s => true,
s => server.Path = s, s => server.Path = s,
server.Path); server.Path);
CreateComboBox("TLSSecure", "TLS Secure", CreateComboBox("UseMux", "Use Mux",
new List<string> {"", "true", "false"}, new List<string> {"", "true", "false"},
s => s => server.UseMux = s switch
{ {
server.TLSSecure = s switch "" => null,
{ "true" => true,
"" => null, "false" => false,
"true" => true, _ => null
"false" => false,
_ => null
};
}, },
server.TLSSecure?.ToString() ?? string.Empty); server.UseMux?.ToString() ?? "");
CreateCheckBox("UseMux", "Use Mux", CreateCheckBox("TLSSecure", "TLS Secure",
b => server.UseMux = b, b => server.TLSSecure = b,
server.UseMux); server.TLSSecure);
} }
} }
} }

View File

@@ -48,22 +48,19 @@ namespace Netch.Servers.VMess.Form
s => true, s => true,
s => server.QUICSecret = s, s => server.QUICSecret = s,
server.QUICSecret); server.QUICSecret);
CreateComboBox("TLSSecure", "TLS Secure", CreateComboBox("UseMux", "Use Mux",
new List<string> {"", "true", "false"}, new List<string> {"", "true", "false"},
s => s => server.UseMux = s switch
{ {
server.TLSSecure = s switch "" => null,
{ "true" => true,
"" => null, "false" => false,
"true" => true, _ => null
"false" => false,
_ => null
};
}, },
server.TLSSecure?.ToString() ?? string.Empty); server.UseMux?.ToString() ?? "");
CreateCheckBox("UseMux", "Use Mux", CreateCheckBox("TLSSecure", "TLS Secure",
s => server.UseMux = s, s => server.TLSSecure = s,
server.UseMux); server.TLSSecure);
} }
} }
} }

View File

@@ -18,7 +18,7 @@ namespace Netch.Servers.VMess.Utils
routing(server, mode, ref v2rayConfig); routing(server, mode, ref v2rayConfig);
outbound(server, ref v2rayConfig); outbound(server, mode, ref v2rayConfig);
return JsonConvert.SerializeObject(v2rayConfig); return JsonConvert.SerializeObject(v2rayConfig);
} }
@@ -103,7 +103,7 @@ namespace Netch.Servers.VMess.Utils
} }
} }
private static void outbound(Server server, ref V2rayConfig v2rayConfig) private static void outbound(Server server, Mode mode, ref V2rayConfig v2rayConfig)
{ {
try try
{ {
@@ -174,8 +174,8 @@ namespace Netch.Servers.VMess.Utils
usersItem.flow = string.Empty; usersItem.flow = string.Empty;
usersItem.encryption = vless.EncryptMethod; usersItem.encryption = vless.EncryptMethod;
outbound.mux.enabled = vless.UseMux; outbound.mux.enabled = vless.UseMux ?? Global.Settings.V2RayConfig.UseMux;
outbound.mux.concurrency = vless.UseMux ? 8 : -1; outbound.mux.concurrency = vless.UseMux ?? Global.Settings.V2RayConfig.UseMux ? 8 : -1;
var streamSettings = outbound.streamSettings; var streamSettings = outbound.streamSettings;
boundStreamSettings(vless, ref streamSettings); boundStreamSettings(vless, ref streamSettings);
@@ -213,8 +213,8 @@ namespace Netch.Servers.VMess.Utils
usersItem.alterId = vmess.AlterID; usersItem.alterId = vmess.AlterID;
usersItem.security = vmess.EncryptMethod; usersItem.security = vmess.EncryptMethod;
outbound.mux.enabled = vmess.UseMux; outbound.mux.enabled = vmess.UseMux ?? Global.Settings.V2RayConfig.UseMux;
outbound.mux.concurrency = vmess.UseMux ? 8 : -1; outbound.mux.concurrency = vmess.UseMux ?? Global.Settings.V2RayConfig.UseMux ? 8 : -1;
var streamSettings = outbound.streamSettings; var streamSettings = outbound.streamSettings;
boundStreamSettings(vmess, ref streamSettings); boundStreamSettings(vmess, ref streamSettings);
@@ -224,7 +224,15 @@ namespace Netch.Servers.VMess.Utils
} }
} }
v2rayConfig.outbounds = new List<Outbounds> {outbound}; v2rayConfig.outbounds = new List<Outbounds>
{
outbound,
new Outbounds
{
tag = "direct",
protocol = "freedom"
}
};
} }
catch catch
{ {
@@ -238,13 +246,13 @@ namespace Netch.Servers.VMess.Utils
{ {
streamSettings.network = server.TransferProtocol; streamSettings.network = server.TransferProtocol;
var host = server.Host; var host = server.Host;
if (server.TLSSecure ?? Global.Settings.V2RayConfig.AllowInsecure) if (server.TLSSecure)
{ {
streamSettings.security = "tls"; streamSettings.security = "tls";
var tlsSettings = new TlsSettings var tlsSettings = new TlsSettings
{ {
allowInsecure = true allowInsecure = Global.Settings.V2RayConfig.AllowInsecure
}; };
if (!string.IsNullOrWhiteSpace(host)) if (!string.IsNullOrWhiteSpace(host))
{ {
@@ -318,7 +326,7 @@ namespace Netch.Servers.VMess.Utils
type = server.FakeType type = server.FakeType
} }
}; };
if (server.TLSSecure ?? Global.Settings.V2RayConfig.AllowInsecure) if (server.TLSSecure)
{ {
streamSettings.tlsSettings.serverName = server.Hostname; streamSettings.tlsSettings.serverName = server.Hostname;
} }
@@ -330,7 +338,7 @@ namespace Netch.Servers.VMess.Utils
var xtlsSettings = new TlsSettings var xtlsSettings = new TlsSettings
{ {
allowInsecure = true allowInsecure = Global.Settings.V2RayConfig.AllowInsecure
}; };
if (!string.IsNullOrWhiteSpace(host)) if (!string.IsNullOrWhiteSpace(host))
{ {

View File

@@ -64,12 +64,12 @@ namespace Netch.Servers.VMess
/// <summary> /// <summary>
/// TLS 底层传输安全 /// TLS 底层传输安全
/// </summary> /// </summary>
public bool? TLSSecure { get; set; } public bool TLSSecure { get; set; } = false;
/// <summary> /// <summary>
/// Mux 多路复用 /// Mux 多路复用
/// </summary> /// </summary>
public bool UseMux { get; set; } = true; public bool? UseMux { get; set; } = true;
} }
public class VMessGlobal public class VMessGlobal

View File

@@ -13,7 +13,7 @@ namespace Netch.Servers.VMess
StoppedKeywords.AddRange(new[] {"config file not readable", "failed to"}); StoppedKeywords.AddRange(new[] {"config file not readable", "failed to"});
} }
public override string Name { get; protected set; } = "V2Ray"; public override string Name { get; protected set; } = "VMess";
public override string MainFile { get; protected set; } = "v2ray.exe"; public override string MainFile { get; protected set; } = "v2ray.exe";
public Server Server { get; set; } public Server Server { get; set; }
public ushort? Socks5LocalPort { get; set; } public ushort? Socks5LocalPort { get; set; }

View File

@@ -49,7 +49,7 @@ namespace Netch.Servers.VMess
type = server.FakeType, type = server.FakeType,
host = server.Host, host = server.Host,
path = server.Path, path = server.Path,
tls = server.TLSSecure ?? Global.Settings.V2RayConfig.AllowInsecure ? "tls" : "" tls = server.TLSSecure ? "tls" : ""
}); });
return "vmess://" + ShareLink.URLSafeBase64Encode(vmessJson); return "vmess://" + ShareLink.URLSafeBase64Encode(vmessJson);
} }

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using Microsoft.Win32; using Microsoft.Win32;
@@ -75,5 +77,24 @@ namespace Netch.Utils
} }
set => AdapterRegistry(true).SetValue("NameServer", value, RegistryValueKind.String); set => AdapterRegistry(true).SetValue("NameServer", value, RegistryValueKind.String);
} }
public static IEnumerable<string> Split(string dns)
{
return dns.Split(',').Where(ip => !string.IsNullOrWhiteSpace(ip)).Select(ip => ip.Trim());
}
public static bool TrySplit(string value, out IEnumerable<string> result, ushort maxCount = 0)
{
result = Split(value).ToArray();
return maxCount == 0 || result.Count() <= maxCount
&&
result.All(ip => IPAddress.TryParse(ip, out _));
}
public static string Join(IEnumerable<string> dns)
{
return string.Join(",", dns);
}
} }
} }

View File

@@ -47,6 +47,22 @@ namespace Netch.Utils
return memoryStream.ToArray(); return memoryStream.ToArray();
} }
/// <summary>
/// 异步下载并编码为字符串
/// </summary>
/// <param name="req"></param>
/// <param name="rep"></param>
/// <param name="encoding">编码默认UTF-8</param>
/// <returns></returns>
public static string DownloadString(HttpWebRequest req, out HttpWebResponse rep, string encoding = "UTF-8")
{
rep = (HttpWebResponse) req.GetResponse();
using var responseStream = rep.GetResponseStream();
using var streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encoding));
return streamReader.ReadToEnd();
}
/// <summary> /// <summary>
/// 异步下载并编码为字符串 /// 异步下载并编码为字符串
/// </summary> /// </summary>

View File

@@ -70,3 +70,5 @@ As well, Netch avoid the restricted NAT problem caused by SSTap. You can use an
- [Privoxy](https://www.privoxy.org/) - [Privoxy](https://www.privoxy.org/)
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester) - [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
- [NetFilter SDK](https://netfiltersdk.com/) - [NetFilter SDK](https://netfiltersdk.com/)
[![Stargazers over time](https://starchart.cc/NetchX/Netch.svg)](https://starchart.cc/NetchX/Netch)