Compare commits

...

22 Commits
1.6.1 ... 1.6.2

Author SHA1 Message Date
ChsBuffer
c3eb07005e bump version to 1.6.2 2020-10-11 19:57:54 +08:00
ChsBuffer
12b2989755 feat: Resolve Server hostname option 2020-10-11 02:08:43 +08:00
ChsBuffer
0222792361 refactor: IServerController client config 2020-10-11 01:58:14 +08:00
ChsBuffer
3e5e3a7275 clean: remove SS DLL's No ACL support remark
refactor: Enable SS DLL by default
2020-10-11 00:56:55 +08:00
ChsBuffer
a49e280e03 refactor: NetTraffic record pid
fix: #399
2020-10-11 00:51:41 +08:00
ChsBuffer
45b6352553 feat: -console argument 2020-10-10 22:37:23 +08:00
Bruce Wayne
406fbd8b7e Merge pull request #398 from NetchX/fixCI 2020-10-10 22:35:16 +08:00
Bruce Wayne
454b03a69f Fix build scripts 2020-10-10 22:22:41 +08:00
ChsBuffer
98ab8864eb fix: SS DLL config 2020-10-10 21:43:53 +08:00
Bruce Wayne
f3358f3da2 Drop Nuget cache 2020-10-10 21:12:14 +08:00
Bruce Wayne
fa1593de49 Fix CI 2020-10-10 20:27:04 +08:00
Bruce Wayne
f26d09bf9f Update GetSHA256.ps1 2020-10-10 20:08:38 +08:00
ChsBuffer
35859a19f7 fix: #396 2020-10-10 13:13:44 +08:00
ChsBuffer
e3e595d469 cut: edit process mode endwith ".exe" check 2020-10-10 00:05:31 +08:00
ChsBuffer
36718e774c feat: mode reference( #include <RelativePathWithoutExtesion.h> ) 2020-10-10 00:02:44 +08:00
ChsBuffer
bf6d3aae95 fix: Process Form high dpi scale 2020-10-09 22:15:36 +08:00
ChsBuffer
477509b12f refactor: VMess.ParseUri
- break: version 1 support
- break: mux config in uri
2020-10-09 20:23:46 +08:00
ChsBuffer
910f6818b0 Revert "mode 2 remove outbound 0.0.0.0/0"
This reverts commit d369858273.
2020-10-09 20:02:59 +08:00
ChsBuffer
ed3f4d1763 refactor: ShareLink.ParseText Non-Nullable
refactor: UpdateServersFromSubscribe
2020-10-09 19:56:47 +08:00
ChsBuffer
be53432a2e refactor: try catch ICSHelper exception #393 2020-10-09 19:21:00 +08:00
ChsBuffer
9d78de0f6c refactor: SubscribeForm Save
- remove: duplicate link check
- fix: check remark duplicate not work
2020-10-08 20:31:50 +08:00
ChsBuffer
75bf753a65 reafactor: ICS Check State 2020-10-08 20:30:42 +08:00
33 changed files with 405 additions and 340 deletions

View File

@@ -5,43 +5,29 @@ jobs:
name: Build
runs-on: windows-latest
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@v1
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1.0.1
uses: microsoft/setup-msbuild@v1.0.2
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Restore NuGet Packages Cache
uses: actions/cache@v2
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('Netch/Netch.csproj') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore NuGet Package
run: nuget restore Netch.sln
- name: Build Solution
shell: pwsh
run: |
.\BUILD.ps1
New-Item -ItemType Directory -Path C:\builtfiles -Force > $null
7z a -mx9 C:\builtfiles\Netch.7z .\Netch\bin\x64\Release\win-x64\
7z rn C:\builtfiles\Netch.7z win-x64 Netch
echo "::set-env name=Netch_SHA256::$(.\GetSHA256.ps1 C:\builtfiles\Netch.7z)"
echo "::set-env name=Netch_EXE_SHA256::$(.\GetSHA256.ps1 Netch\bin\x64\Release\win-x64\Netch.exe)"
7z a -mx9 C:\builtfiles\Netch.7z .\Netch\bin\x64\Release\
7z rn C:\builtfiles\Netch.7z Release Netch
echo "Netch_SHA256=$(.\GetSHA256.ps1 C:\builtfiles\Netch.7z)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "Netch_EXE_SHA256=$(.\GetSHA256.ps1 Netch\bin\x64\Release\Netch.exe)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: Netch
path: Netch\bin\x64\Release\win-x64
path: Netch\bin\x64\Release
- name: Release
uses: softprops/action-gh-release@v1

View File

@@ -1,33 +1,12 @@
param([string]$buildtfm = 'all')
Write-Host 'Building'
Write-Host 'DotNet SDK Version'
dotnet --version
msbuild -v:n -m:1 /p:Configuration="Release" `
/p:Platform="x64" `
/p:TargetFramework=net48 `
/p:SolutionDir="..\" `
/restore `
Netch\Netch.csproj
$exe = 'Netch.exe'
$mainDir = (Get-Item -Path ".\").FullName
$net_baseoutput = "$mainDir\Netch\bin\$configuration"
if ($LASTEXITCODE) { exit $LASTEXITCODE }
Write-Host $mainDir
Write-Host $net_baseoutput
function Build-NetFrameworkx64
{
Write-Host 'Building .NET Framework x64'
$outdir = "$net_baseoutput\x64"
msbuild -v:n -m:1 /p:Configuration="Release" `
/p:Platform="x64" `
/p:TargetFramework=net48 `
/p:Runtimeidentifier=win-x64 `
/restore
if ($LASTEXITCODE) { cd $mainDir ; exit $LASTEXITCODE }
Write-Host 'Build done'
}
cd $mainDir
Build-NetFrameworkx64
cd $mainDir
exit 0
Write-Host 'Build done'

View File

@@ -1,5 +1,6 @@
param([string]$file)
$hash = [Security.Cryptography.HashAlgorithm]::Create( "SHA256" )
$stream = ([IO.StreamReader]$file).BaseStream
-join ($hash.ComputeHash($stream) | ForEach { "{0:x2}" -f $_ })
$stream.Close()
$path = (Resolve-Path -Path $file).Path
$stream = ([IO.StreamReader]$path).BaseStream
-join ($hash.ComputeHash($stream) | ForEach-Object { "{0:x2}" -f $_ })
$stream.Close()

View File

@@ -16,4 +16,17 @@ namespace Netch.Controllers
/// <returns>是否启动成功</returns>
public abstract bool Start(Server server, Mode mode);
}
public static class ServerControllerExtension
{
public static int Socks5LocalPort(this IServerController controller)
{
return controller.Socks5LocalPort ?? Global.Settings.Socks5LocalPort;
}
public static string LocalAddress(this IServerController controller)
{
return controller.LocalAddress ?? Global.Settings.LocalAddress;
}
}
}

View File

@@ -45,7 +45,7 @@ namespace Netch.Controllers
return false;
}
if (DNS.Lookup(server.Hostname) == null)
if (Global.Settings.ResolveServerHostname && DNS.Lookup(server.Hostname) == null)
{
MessageBoxX.Show("Lookup Server hostname failed");
return false;
@@ -184,6 +184,8 @@ namespace Netch.Controllers
Task.Run(() => ModeController?.Stop()),
};
await Task.WhenAll(tasks);
ModeController = null;
ServerController = null;
}

View File

@@ -62,7 +62,7 @@ namespace Netch.Controllers
}
aio_dial((int) NameList.TYPE_CLRNAME, "");
foreach (var rule in mode.Rule)
foreach (var rule in mode.FullRule)
{
aio_dial((int) NameList.TYPE_ADDNAME, rule);
}

View File

@@ -142,7 +142,7 @@ namespace Netch.Controllers
case 1:
// 代理规则
Logging.Info("代理 → 规则 IP");
_proxyIPs.AddRange(_savedMode.Rule.Select(IPNetwork.Parse));
_proxyIPs.AddRange(_savedMode.FullRule.Select(IPNetwork.Parse));
//处理 NAT 类型检测,由于协议的原因,无法仅通过域名确定需要代理的 IP自己记录解析了返回的 IP仅支持默认检测服务器
if (Global.Settings.STUN_Server == "stun.stunprotocol.org")
@@ -189,13 +189,15 @@ namespace Netch.Controllers
);
Logging.Info("绕行 → 规则 IP");
_directIPs.AddRange(_savedMode.Rule.Select(IPNetwork.Parse));
_directIPs.AddRange(_savedMode.FullRule.Select(IPNetwork.Parse));
Logging.Info("代理 → 全局");
RouteAction(Action.Create, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP);
Logging.Info("移除 → 出口网卡路由");
RouteAction(Action.Delete, IPNetwork.Parse("0.0.0.0", 0), RouteType.Outbound);
if (!RouteAction(Action.Create, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP))
{
State = State.Stopped;
return;
}
break;
}
@@ -216,8 +218,7 @@ namespace Netch.Controllers
case 1:
break;
case 2:
RouteAction(Action.Delete, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP);
RouteAction(Action.Create, IPNetwork.Parse("0.0.0.0", 0), RouteType.Outbound);
RouteAction(Action.Delete, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP, 10);
break;
}

View File

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

View File

@@ -26,19 +26,8 @@ namespace Netch.Forms
var texts = Clipboard.GetText();
if (!string.IsNullOrWhiteSpace(texts))
{
var result = ShareLink.ParseText(texts);
if (result != null)
{
foreach (var server in result)
{
Global.Settings.Server.Add(server);
}
}
else
{
MessageBoxX.Show(i18N.Translate("Import servers error!"), LogLevel.ERROR);
}
Global.Settings.Server.AddRange(ShareLink.ParseText(texts));
NotifyTip(i18N.TranslateFormat("Import {0} server(s) form Clipboard", ShareLink.ParseText(texts).Count));
InitServer();
Configuration.Save();
@@ -108,6 +97,9 @@ namespace Netch.Forms
await UpdateServersFromSubscribe();
}
private readonly object _serverLock = new object();
public async Task UpdateServersFromSubscribe()
{
void DisableItems(bool v)
@@ -144,8 +136,6 @@ namespace Netch.Forms
await MainController.Start(ServerComboBox.SelectedItem as Server, mode);
}
var serverLock = new object();
await Task.WhenAll(Global.Settings.SubscribeLink.Select(async item => await Task.Run(async () =>
{
try
@@ -156,31 +146,25 @@ namespace Netch.Forms
if (Global.Settings.UseProxyToUpdateSubscription)
request.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
var str = await WebUtil.DownloadStringAsync(request);
var servers = ShareLink.ParseText(await WebUtil.DownloadStringAsync(request));
lock (serverLock)
foreach (var server in servers)
{
Global.Settings.Server.RemoveAll(server => server.Group == item.Remark);
var result = ShareLink.ParseText(str);
if (result != null)
{
foreach (var server in result)
{
server.Group = item.Remark;
Global.Settings.Server.Add(server);
}
}
NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, result?.Count ?? 0));
server.Group = item.Remark;
}
}
catch (WebException e)
{
NotifyTip($"{i18N.TranslateFormat("Update servers error from {0}", item.Remark)}\n{e.Message}", info: false);
lock (_serverLock)
{
Global.Settings.Server.RemoveAll(server => server.Group.Equals(item.Remark));
Global.Settings.Server.AddRange(servers);
}
NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, servers.Count));
}
catch (Exception e)
{
NotifyTip($"{i18N.TranslateFormat("Update servers error from {0}", item.Remark)}\n{e.Message}", info: false);
Logging.Error(e.ToString());
}
})).ToArray());

View File

@@ -47,19 +47,21 @@ namespace Netch.Forms.Mode
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.ControlButton = new System.Windows.Forms.Button();
this.DeleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.containerControl1 = new System.Windows.Forms.ContainerControl();
this.ConfigurationGroupBox.SuspendLayout();
this.ProcessGroupBox.SuspendLayout();
this.contextMenuStrip.SuspendLayout();
this.containerControl1.SuspendLayout();
this.SuspendLayout();
//
// ConfigurationGroupBox
//
this.ConfigurationGroupBox.Controls.Add(this.containerControl1);
this.ConfigurationGroupBox.Controls.Add(this.UseCustomFilenameBox);
this.ConfigurationGroupBox.Controls.Add(this.FilenameLabel);
this.ConfigurationGroupBox.Controls.Add(this.FilenameTextBox);
this.ConfigurationGroupBox.Controls.Add(this.ScanButton);
this.ConfigurationGroupBox.Controls.Add(this.ProcessGroupBox);
this.ConfigurationGroupBox.Controls.Add(this.RuleListBox);
this.ConfigurationGroupBox.Controls.Add(this.RemarkTextBox);
this.ConfigurationGroupBox.Controls.Add(this.RemarkLabel);
this.ConfigurationGroupBox.Location = new System.Drawing.Point(12, 12);
@@ -136,8 +138,9 @@ namespace Netch.Forms.Mode
// RuleListBox
//
this.RuleListBox.FormattingEnabled = true;
this.RuleListBox.Dock = DockStyle.Fill;
this.RuleListBox.ItemHeight = 17;
this.RuleListBox.Location = new System.Drawing.Point(6, 100);
this.RuleListBox.Location = new System.Drawing.Point(0, 0);
this.RuleListBox.Name = "RuleListBox";
this.RuleListBox.Size = new System.Drawing.Size(328, 157);
this.RuleListBox.TabIndex = 2;
@@ -183,6 +186,16 @@ namespace Netch.Forms.Mode
this.DeleteToolStripMenuItem.Text = "Delete";
this.DeleteToolStripMenuItem.Click += new System.EventHandler(this.deleteRule_Click);
//
// containerControl1
//
this.containerControl1.Controls.Add(this.RuleListBox);
this.containerControl1.Location = new System.Drawing.Point(6, 100);
this.containerControl1.Name = "containerControl1";
this.containerControl1.Size = new System.Drawing.Size(328, 157);
this.containerControl1.TabIndex = 10;
this.containerControl1.Padding = new Padding(0);
this.containerControl1.Text = "containerControl1";
//
// Process
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@@ -204,11 +217,13 @@ namespace Netch.Forms.Mode
this.ProcessGroupBox.ResumeLayout(false);
this.ProcessGroupBox.PerformLayout();
this.contextMenuStrip.ResumeLayout(false);
this.containerControl1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ContainerControl containerControl1;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip;
private System.Windows.Forms.ToolStripMenuItem DeleteToolStripMenuItem;
public System.Windows.Forms.GroupBox ConfigurationGroupBox;

View File

@@ -142,10 +142,6 @@ namespace Netch.Forms.Mode
if (!string.IsNullOrWhiteSpace(ProcessNameTextBox.Text))
{
var process = ProcessNameTextBox.Text;
if (!process.EndsWith(".exe"))
{
process += ".exe";
}
if (!RuleListBox.Items.Contains(process))
{

View File

@@ -53,8 +53,10 @@
this.ControlButton = new System.Windows.Forms.Button();
this.GlobalBypassIPsButton = new System.Windows.Forms.Button();
this.BehaviorGroupBox = new System.Windows.Forms.GroupBox();
this.UpdateSubscribeatWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
this.LanguageLabel = new System.Windows.Forms.Label();
this.LanguageComboBox = new System.Windows.Forms.ComboBox();
this.ResolveServerHostnameCheckBox = new System.Windows.Forms.CheckBox();
this.ModifySystemDNSCheckBox = new System.Windows.Forms.CheckBox();
this.BootShadowsocksFromDLLCheckBox = new System.Windows.Forms.CheckBox();
this.AclAddrTextBox = new System.Windows.Forms.TextBox();
@@ -73,7 +75,6 @@
this.StartWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
this.StopWhenExitedCheckBox = new System.Windows.Forms.CheckBox();
this.ExitWhenClosedCheckBox = new System.Windows.Forms.CheckBox();
this.UpdateSubscribeatWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
this.PortGroupBox.SuspendLayout();
this.TUNTAPGroupBox.SuspendLayout();
this.BehaviorGroupBox.SuspendLayout();
@@ -186,8 +187,8 @@
this.UseFakeDNSCheckBox.Size = new System.Drawing.Size(110, 21);
this.UseFakeDNSCheckBox.TabIndex = 11;
this.UseFakeDNSCheckBox.Text = "Use Fake DNS";
this.UseFakeDNSCheckBox.Visible = false;
this.UseFakeDNSCheckBox.UseVisualStyleBackColor = true;
this.UseFakeDNSCheckBox.Visible = false;
//
// ProxyDNSCheckBox
//
@@ -202,12 +203,12 @@
// ICSCheckBox
//
this.ICSCheckBox.AutoSize = true;
this.ICSCheckBox.Enabled = false;
this.ICSCheckBox.Location = new System.Drawing.Point(261, 160);
this.ICSCheckBox.Name = "ICSCheckBox";
this.ICSCheckBox.Size = new System.Drawing.Size(46, 21);
this.ICSCheckBox.Size = new System.Drawing.Size(151, 21);
this.ICSCheckBox.TabIndex = 5;
this.ICSCheckBox.Text = "Tap Network Sharing";
this.ICSCheckBox.Enabled = false;
this.ICSCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.ICSCheckBox.UseVisualStyleBackColor = true;
this.ICSCheckBox.CheckedChanged += new System.EventHandler(this.ICSCheckBox_CheckedChanged);
@@ -293,7 +294,7 @@
//
// ControlButton
//
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.ControlButton.Location = new System.Drawing.Point(804, 356);
this.ControlButton.Name = "ControlButton";
this.ControlButton.Size = new System.Drawing.Size(75, 23);
@@ -304,7 +305,7 @@
//
// GlobalBypassIPsButton
//
this.GlobalBypassIPsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.GlobalBypassIPsButton.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.GlobalBypassIPsButton.Location = new System.Drawing.Point(12, 356);
this.GlobalBypassIPsButton.Name = "GlobalBypassIPsButton";
this.GlobalBypassIPsButton.Size = new System.Drawing.Size(128, 23);
@@ -318,6 +319,7 @@
this.BehaviorGroupBox.Controls.Add(this.UpdateSubscribeatWhenOpenedCheckBox);
this.BehaviorGroupBox.Controls.Add(this.LanguageLabel);
this.BehaviorGroupBox.Controls.Add(this.LanguageComboBox);
this.BehaviorGroupBox.Controls.Add(this.ResolveServerHostnameCheckBox);
this.BehaviorGroupBox.Controls.Add(this.ModifySystemDNSCheckBox);
this.BehaviorGroupBox.Controls.Add(this.BootShadowsocksFromDLLCheckBox);
this.BehaviorGroupBox.Controls.Add(this.AclAddrTextBox);
@@ -343,6 +345,17 @@
this.BehaviorGroupBox.TabStop = false;
this.BehaviorGroupBox.Text = "Behavior";
//
// UpdateSubscribeatWhenOpenedCheckBox
//
this.UpdateSubscribeatWhenOpenedCheckBox.AutoSize = true;
this.UpdateSubscribeatWhenOpenedCheckBox.Location = new System.Drawing.Point(206, 129);
this.UpdateSubscribeatWhenOpenedCheckBox.Name = "UpdateSubscribeatWhenOpenedCheckBox";
this.UpdateSubscribeatWhenOpenedCheckBox.Size = new System.Drawing.Size(224, 21);
this.UpdateSubscribeatWhenOpenedCheckBox.TabIndex = 24;
this.UpdateSubscribeatWhenOpenedCheckBox.Text = "Update subscribeat when opened";
this.UpdateSubscribeatWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.UpdateSubscribeatWhenOpenedCheckBox.UseVisualStyleBackColor = true;
//
// LanguageLabel
//
this.LanguageLabel.AutoSize = true;
@@ -361,6 +374,16 @@
this.LanguageComboBox.Size = new System.Drawing.Size(121, 25);
this.LanguageComboBox.TabIndex = 22;
//
// ResolveServerHostnameCheckBox
//
this.ResolveServerHostnameCheckBox.AutoSize = true;
this.ResolveServerHostnameCheckBox.Location = new System.Drawing.Point(12, 156);
this.ResolveServerHostnameCheckBox.Name = "ResolveServerHostnameCheckBox";
this.ResolveServerHostnameCheckBox.Size = new System.Drawing.Size(176, 21);
this.ResolveServerHostnameCheckBox.TabIndex = 21;
this.ResolveServerHostnameCheckBox.Text = "Resolve Server Hostname";
this.ResolveServerHostnameCheckBox.UseVisualStyleBackColor = true;
//
// ModifySystemDNSCheckBox
//
this.ModifySystemDNSCheckBox.AutoSize = true;
@@ -376,9 +399,9 @@
this.BootShadowsocksFromDLLCheckBox.AutoSize = true;
this.BootShadowsocksFromDLLCheckBox.Location = new System.Drawing.Point(12, 102);
this.BootShadowsocksFromDLLCheckBox.Name = "BootShadowsocksFromDLLCheckBox";
this.BootShadowsocksFromDLLCheckBox.Size = new System.Drawing.Size(168, 21);
this.BootShadowsocksFromDLLCheckBox.Size = new System.Drawing.Size(66, 21);
this.BootShadowsocksFromDLLCheckBox.TabIndex = 21;
this.BootShadowsocksFromDLLCheckBox.Text = "SS DLL(No ACL support)";
this.BootShadowsocksFromDLLCheckBox.Text = "SS DLL";
this.BootShadowsocksFromDLLCheckBox.UseVisualStyleBackColor = true;
//
// AclAddrTextBox
@@ -535,17 +558,6 @@
this.ExitWhenClosedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.ExitWhenClosedCheckBox.UseVisualStyleBackColor = true;
//
// UpdateSubscribeatWhenOpenedCheckBox
//
this.UpdateSubscribeatWhenOpenedCheckBox.AutoSize = true;
this.UpdateSubscribeatWhenOpenedCheckBox.Location = new System.Drawing.Point(206, 129);
this.UpdateSubscribeatWhenOpenedCheckBox.Name = "UpdateSubscribeatWhenOpenedCheckBox";
this.UpdateSubscribeatWhenOpenedCheckBox.Size = new System.Drawing.Size(224, 21);
this.UpdateSubscribeatWhenOpenedCheckBox.TabIndex = 24;
this.UpdateSubscribeatWhenOpenedCheckBox.Text = "Update subscribeat when opened";
this.UpdateSubscribeatWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.UpdateSubscribeatWhenOpenedCheckBox.UseVisualStyleBackColor = true;
//
// SettingForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@@ -556,9 +568,9 @@
this.Controls.Add(this.GlobalBypassIPsButton);
this.Controls.Add(this.ControlButton);
this.Controls.Add(this.TUNTAPGroupBox);
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (134)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.MaximizeBox = false;
this.Name = "SettingForm";
@@ -574,6 +586,8 @@
this.ResumeLayout(false);
}
private System.Windows.Forms.CheckBox ResolveServerHostnameCheckBox;
private System.Windows.Forms.CheckBox ICSCheckBox;
#endregion

View File

@@ -15,6 +15,7 @@ namespace Netch.Forms
public SettingForm()
{
InitializeComponent();
InitText();
}
private void InitValue()
@@ -39,10 +40,18 @@ namespace Netch.Forms
ProxyDNSCheckBox.Checked = Global.Settings.TUNTAP.ProxyDNS;
UseFakeDNSCheckBox.Checked = Global.Settings.TUNTAP.UseFakeDNS;
if (TUNTAPController.SearchTapAdapter())
try
{
ICSCheckBox.Enabled = true;
ICSCheckBox.Checked = ICSHelper.Enabled;
var icsHelperEnabled = ICSHelper.Enabled;
if (icsHelperEnabled != null)
{
ICSCheckBox.Enabled = true;
ICSCheckBox.Checked = (bool) icsHelperEnabled;
}
}
catch
{
// ignored
}
// Behavior
@@ -56,6 +65,7 @@ namespace Netch.Forms
CheckBetaUpdateCheckBox.Checked = Global.Settings.CheckBetaUpdate;
ModifySystemDNSCheckBox.Checked = Global.Settings.ModifySystemDNS;
UpdateSubscribeatWhenOpenedCheckBox.Checked = Global.Settings.UpdateSubscribeatWhenOpened;
ResolveServerHostnameCheckBox.Checked = Global.Settings.ResolveServerHostname;
ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString();
TcpingAtStartedCheckBox.Checked = Global.Settings.StartedTcping;
@@ -104,9 +114,9 @@ namespace Netch.Forms
private void SettingForm_Load(object sender, EventArgs e)
{
UseFakeDNSCheckBox.Visible = Global.Flags.SupportFakeDns;
InitText();
InitValue();
Task.Run(() => BeginInvoke(new Action(() => UseFakeDNSCheckBox.Visible = Global.Flags.SupportFakeDns)));
}
private void GlobalBypassIPsButton_Click(object sender, EventArgs e)
@@ -320,6 +330,7 @@ namespace Netch.Forms
Global.Settings.CheckBetaUpdate = CheckBetaUpdateCheckBox.Checked;
Global.Settings.ModifySystemDNS = ModifySystemDNSCheckBox.Checked;
Global.Settings.UpdateSubscribeatWhenOpened = UpdateSubscribeatWhenOpenedCheckBox.Checked;
Global.Settings.ResolveServerHostname = ResolveServerHostnameCheckBox.Checked;
Global.Settings.ProfileCount = profileCount;
Global.Settings.StartedTcping = TcpingAtStartedCheckBox.Checked;
@@ -387,20 +398,31 @@ namespace Netch.Forms
private async void ICSCheckBox_CheckedChanged(object sender, EventArgs e)
{
ICSCheckBox.Enabled = false;
await Task.Run(() =>
try
{
if (ICSCheckBox.Checked)
ICSCheckBox.Enabled = false;
await Task.Run(() =>
{
if (!ICSHelper.Enabled)
ICSCheckBox.Checked = ICSHelper.Enable();
}
else
{
ICSHelper.Disable();
}
});
ICSCheckBox.Enabled = true;
if (ICSCheckBox.Checked)
{
if (!(ICSHelper.Enabled ?? true))
ICSCheckBox.Checked = ICSHelper.Enable();
}
else
{
ICSHelper.Disable();
}
});
}
catch (Exception exception)
{
ICSCheckBox.Checked = false;
Logging.Error(exception.ToString());
}
finally
{
ICSCheckBox.Enabled = true;
}
}
}
}

View File

@@ -81,11 +81,11 @@
//
// ClearButton
//
this.ClearButton.Location = new System.Drawing.Point(477, 103);
this.ClearButton.Location = new System.Drawing.Point(448, 103);
this.ClearButton.Name = "ClearButton";
this.ClearButton.Size = new System.Drawing.Size(58, 26);
this.ClearButton.Size = new System.Drawing.Size(87, 26);
this.ClearButton.TabIndex = 7;
this.ClearButton.Text = "Clear";
this.ClearButton.Text = "Unselect";
this.ClearButton.UseVisualStyleBackColor = true;
this.ClearButton.Click += new System.EventHandler(this.ClearButton_Click);
//
@@ -114,7 +114,6 @@
this.LinkTextBox.Name = "LinkTextBox";
this.LinkTextBox.Size = new System.Drawing.Size(545, 23);
this.LinkTextBox.TabIndex = 4;
this.LinkTextBox.TextChanged += new System.EventHandler(this.ListTextBox_TextChanged);
//
// LinkLabel
//

View File

@@ -109,39 +109,23 @@ namespace Netch.Forms
return;
}
// 备注重复的订阅项
var duplicateRemarkItems = Global.Settings.SubscribeLink.Where(link => link.Remark.Equals(RemarkLabel.Text));
// 链接重复的订阅项
SubscribeLink duplicateLinkItem = null;
try
{
duplicateLinkItem = Global.Settings.SubscribeLink.First(link => link.Link.Equals(LinkTextBox.Text));
}
catch
{
// ignored
}
if (duplicateRemarkItems.Any())
if (Global.Settings.SubscribeLink.Any(link => link.Remark.Equals(RemarkTextBox.Text)))
{
MessageBoxX.Show("Remark Name Duplicate!");
return;
}
if (duplicateLinkItem != null)
if (_editingIndex == -1)
{
if (duplicateLinkItem.Remark != RemarkTextBox.Text)
Global.Settings.SubscribeLink.Add(new SubscribeLink
{
RenameServersGroup(duplicateLinkItem.Remark, RemarkTextBox.Text);
}
duplicateLinkItem.Remark = RemarkTextBox.Text;
duplicateLinkItem.UserAgent = UserAgentTextBox.Text;
Remark = RemarkTextBox.Text,
Link = LinkTextBox.Text,
UserAgent = UserAgentTextBox.Text
});
}
else if (_editingIndex != -1)
else
{
// 只修改备注/未修改被上面处理
var target = Global.Settings.SubscribeLink[_editingIndex];
if (MessageBox.Show(i18N.Translate("Delete the corresponding group of items in the server list?"), i18N.Translate("Confirm"), MessageBoxButtons.YesNo) == DialogResult.Yes)
{
@@ -156,15 +140,6 @@ namespace Netch.Forms
target.Remark = RemarkTextBox.Text;
target.UserAgent = UserAgentTextBox.Text;
}
else
{
Global.Settings.SubscribeLink.Add(new SubscribeLink
{
Remark = RemarkTextBox.Text,
Link = LinkTextBox.Text,
UserAgent = UserAgentTextBox.Text
});
}
Configuration.Save();
Global.Settings.UseProxyToUpdateSubscription = UseSelectedServerCheckBox.Checked;
@@ -260,17 +235,5 @@ namespace Netch.Forms
{
ResetEditingGroup();
}
private void ListTextBox_TextChanged(object sender, EventArgs e)
{
for (var i = 0; i < SubscribeLinkListView.Items.Count; i++)
{
if (((TextBox) sender).Text == SubscribeLinkListView.Items[i].SubItems[1].Text)
{
_editingIndex = i;
AddSubscriptionBox.Text = SubscribeLinkListView.Items[i].SubItems[0].Text;
}
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Netch.Utils;
namespace Netch.Models
@@ -42,6 +43,61 @@ namespace Netch.Models
/// </summary>
public readonly List<string> Rule = new List<string>();
public List<string> FullRule
{
get
{
var result = new List<string>();
foreach (var s in Rule)
{
if (string.IsNullOrWhiteSpace(s))
continue;
if (s.StartsWith("//"))
continue;
if (s.StartsWith("#include"))
{
var relativePath = new StringBuilder(s.Substring(8).Trim());
relativePath.Replace("<", "");
relativePath.Replace(">", "");
relativePath.Replace(".h", ".txt");
var mode = Global.Modes.FirstOrDefault(m => m.RelativePath.Equals(relativePath.ToString()));
if (mode == null)
{
Logging.Warning($"{relativePath} file included in {Remark} not found");
}
else
{
if (mode.Type != Type)
{
Logging.Warning($"{mode.Remark}'s mode is not as same as {Remark}'s mode");
}
else
{
if (mode.Rule.Any(rule => rule.StartsWith("#include")))
{
Logging.Warning("Cannot reference mode that reference other mode");
}
else
{
result.AddRange(mode.FullRule);
}
}
}
}
else
{
result.Add(s);
}
}
return result;
}
}
/// <summary>
/// 获取备注
/// </summary>

View File

@@ -101,4 +101,12 @@ namespace Netch.Models
}
}
}
public static class ServerExtension
{
public static string AutoResolveHostname(this Server server)
{
return Global.Settings.ResolveServerHostname ? DNS.Lookup(server.Hostname).ToString() : server.Hostname;
}
}
}

View File

@@ -103,6 +103,11 @@ namespace Netch.Models
/// </summary>
public bool ModifySystemDNS = false;
/// <summary>
/// 解析服务器主机名
/// </summary>
public bool ResolveServerHostname = true;
/// <summary>
/// 网页请求超时 毫秒
/// </summary>
@@ -196,7 +201,7 @@ namespace Netch.Models
/// <summary>
/// 是否使用DLL启动Shadowsocks
/// </summary>
public bool BootShadowsocksFromDLL = false;
public bool BootShadowsocksFromDLL = true;
/// <summary>
/// 语言设置

View File

@@ -66,5 +66,11 @@ namespace Netch
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
public static extern uint FlushDNSResolverCache();
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
[DllImport("kernel32.dll")]
public static extern bool AttachConsole(int dwProcessId);
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -17,6 +18,12 @@ namespace Netch
[STAThread]
public static void Main(string[] args)
{
if (args.Contains("-console"))
{
NativeMethods.AllocConsole();
NativeMethods.AttachConsole(-1);
}
// 创建互斥体防止多次运行
using (var mutex = new Mutex(false, "Global\\Netch"))
{

View File

@@ -153,7 +153,7 @@
"Check update when opened": "打开软件时检查更新",
"Check Beta update": "检查 Beta 更新",
"Update subscribeat when opened": "自动更新订阅",
"SS DLL(No ACL support)": "SS DLL(不支持 ACL",
"SS DLL": "SS DLL",
"Modify System DNS": "修改系统 DNS",
"ProfileCount": "快捷配置数量",
"ProfileCount value illegal. Try again.": "快捷配置数值非法。请重试。",
@@ -169,6 +169,7 @@
"Custom ACL": "自定义 ACL 规则",
"Language": "语言",
"Tap Network Sharing": "Tap 网络共享",
"Resolve Server Hostname": "解析服务器主机名",
"Profile": "配置名",
"Profiles": "配置",

View File

@@ -14,20 +14,20 @@ namespace Netch.Servers.Shadowsocks
public int? Socks5LocalPort { get; set; }
public string LocalAddress { get; set; }
private Mode _savedMode;
public bool DllFlag => Global.Settings.BootShadowsocksFromDLL && (_savedMode.Type == 0 || _savedMode.Type == 1 || _savedMode.Type == 2);
public bool Start(Server s, Mode mode)
{
bool DllFlag()
{
return Global.Settings.BootShadowsocksFromDLL && (mode.Type == 0 || mode.Type == 1 || mode.Type == 2);
}
_savedMode = mode;
var server = (Shadowsocks) s;
//从DLL启动Shaowsocks
if (DllFlag())
if (DllFlag)
{
State = State.Starting;
var client = Encoding.UTF8.GetBytes($"{LocalAddress}:{Socks5LocalPort}");
var remote = Encoding.UTF8.GetBytes($"{DNS.Lookup(server.Hostname)}:{server.Port}");
var client = Encoding.UTF8.GetBytes($"{this.LocalAddress()}:{this.Socks5LocalPort()}");
var remote = Encoding.UTF8.GetBytes($"{server.AutoResolveHostname()}:{server.Port}");
var passwd = Encoding.UTF8.GetBytes($"{server.Password}");
var method = Encoding.UTF8.GetBytes($"{server.EncryptMethod}");
if (!ShadowsocksDLL.Info(client, remote, passwd, method))
@@ -55,10 +55,10 @@ namespace Netch.Servers.Shadowsocks
var argument = new StringBuilder();
argument.Append(
$"-s {DNS.Lookup(server.Hostname)} " +
$"-s {server.AutoResolveHostname()} " +
$"-p {server.Port} " +
$"-b {LocalAddress ?? Global.Settings.LocalAddress} " +
$"-l {Socks5LocalPort ?? Global.Settings.Socks5LocalPort} " +
$"-b {this.LocalAddress()} " +
$"-l {this.Socks5LocalPort()} " +
$"-m {server.EncryptMethod} " +
$"-k \"{server.Password}\" " +
"-u ");
@@ -79,6 +79,7 @@ namespace Netch.Servers.Shadowsocks
ShadowsocksDLL.Stop();
else
StopInstance();
_savedMode = null;
}

View File

@@ -21,7 +21,7 @@ namespace Netch.Servers.ShadowsocksR
#region Argument
var argument = new StringBuilder();
argument.Append($"-s {DNS.Lookup(server.Hostname)} -p {server.Port} -k \"{server.Password}\" -m {server.EncryptMethod} -t 120");
argument.Append($"-s {server.AutoResolveHostname()} -p {server.Port} -k \"{server.Password}\" -m {server.EncryptMethod} -t 120");
if (!string.IsNullOrEmpty(server.Protocol))
{
argument.Append($" -O {server.Protocol}");
@@ -34,7 +34,7 @@ namespace Netch.Servers.ShadowsocksR
if (!string.IsNullOrEmpty(server.OBFSParam)) argument.Append($" -g \"{server.OBFSParam}\"");
}
argument.Append($" -b {LocalAddress ?? Global.Settings.LocalAddress} -l {Socks5LocalPort ?? Global.Settings.Socks5LocalPort} -u");
argument.Append($" -b {this.LocalAddress()} -l {this.Socks5LocalPort()} -u");
if (mode.BypassChina) argument.Append(" --acl default.acl");
#endregion

View File

@@ -27,9 +27,9 @@ namespace Netch.Servers.Trojan
var server = (Trojan) s;
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new TrojanConfig
{
local_addr = LocalAddress ?? Global.Settings.LocalAddress,
local_port = Socks5LocalPort ?? Global.Settings.Socks5LocalPort,
remote_addr = DNS.Lookup(server.Hostname).ToString(),
local_addr = this.LocalAddress(),
local_port = this.Socks5LocalPort(),
remote_addr = server.AutoResolveHostname(),
remote_port = server.Port,
password = new List<string>
{

View File

@@ -5,72 +5,59 @@
/// </summary>
public class VMessJObject
{
/// <summary>
/// Mux Class
/// </summary>
public class Mux
{
public object enabled;
}
/// <summary>
/// 链接版本
/// </summary>
public string v;
public string v = string.Empty;
/// <summary>
/// 备注
/// </summary>
public string ps;
public string ps = string.Empty;
/// <summary>
/// 地址
/// </summary>
public string add;
public string add = string.Empty;
/// <summary>
/// 端口
/// </summary>
public int port;
public string port = string.Empty;
/// <summary>
/// 用户 ID
/// </summary>
public string id;
public string id = string.Empty;
/// <summary>
/// 额外 ID
/// </summary>
public int aid = 0;
public string aid = string.Empty;
/// <summary>
/// 传输协议
/// </summary>
public string net;
public string net = string.Empty;
/// <summary>
/// 伪装类型
/// </summary>
public string type;
public string type = string.Empty;
/// <summary>
/// 伪装域名HTTPWS
/// </summary>
public string host;
public string host = string.Empty;
/// <summary>
/// 伪装路径
/// </summary>
public string path;
public string path = string.Empty;
/// <summary>
/// 是否使用 TLS
/// </summary>
public string tls;
/// <summary>
/// Mux 多路复用
/// </summary>
public Mux mux;
public string tls = string.Empty;
}
}

View File

@@ -33,8 +33,8 @@ namespace Netch.Servers.VMess
new VMessConfig.Inbounds
{
settings = new VMessConfig.InboundSettings(),
port = Socks5LocalPort ?? Global.Settings.Socks5LocalPort,
listen = LocalAddress ?? Global.Settings.LocalAddress
port = this.Socks5LocalPort(),
listen = this.LocalAddress()
}
},
outbounds = new List<VMessConfig.Outbounds>
@@ -47,7 +47,7 @@ namespace Netch.Servers.VMess
{
new VMessConfig.VNext
{
address = DNS.Lookup(server.Hostname).ToString(),
address = server.AutoResolveHostname(),
port = server.Port,
users = new List<VMessConfig.User>
{

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Netch.Controllers;
using Netch.Models;
@@ -63,26 +64,25 @@ namespace Netch.Servers.VMess
var data = new VMess();
text = text.Substring(8);
var vmess = JsonConvert.DeserializeObject<VMessJObject>(ShareLink.URLSafeBase64Decode(text));
VMessJObject vmess;
try
{
vmess = JsonConvert.DeserializeObject<VMessJObject>(ShareLink.URLSafeBase64Decode(text));
}
catch (Exception e)
{
Logging.Warning(e.ToString());
return null;
}
data.Remark = vmess.ps;
data.Hostname = vmess.add;
data.Port = vmess.port;
data.Port = ushort.Parse(vmess.port);
data.UserID = vmess.id;
data.AlterID = vmess.aid;
data.AlterID = int.Parse(vmess.aid);
data.TransferProtocol = vmess.net;
data.FakeType = vmess.type;
if (vmess.v == null || vmess.v == "1")
{
var info = vmess.host.Split(';');
if (info.Length == 2)
{
vmess.host = info[0];
vmess.path = info[1];
}
}
if (data.TransferProtocol == "quic")
{
if (VMessGlobal.QUIC.Contains(vmess.host))
@@ -98,28 +98,8 @@ namespace Netch.Servers.VMess
}
data.TLSSecure = vmess.tls == "tls";
if (vmess.mux == null)
{
data.UseMux = false;
}
else
{
if (vmess.mux.enabled is bool enabled)
{
data.UseMux = enabled;
}
else if (vmess.mux.enabled is string muxEnabled)
{
data.UseMux = muxEnabled == "true"; // 针对使用字符串当作布尔值的情况
}
else
{
data.UseMux = false;
}
}
data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个
return CheckServer(data) ? new[] {data} : null;
}

View File

@@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Tracing.Parsers;
using Microsoft.Diagnostics.Tracing.Session;
using Netch.Controllers;
using Netch.Models;
using Netch.Servers.Shadowsocks;
namespace Netch.Utils
{
@@ -66,20 +67,29 @@ namespace Netch.Utils
{
instances.Add(((HTTPController) MainController.ModeController).pPrivoxyController.Instance);
}
else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL &&
(mode.Type == 0 || mode.Type == 1 || mode.Type == 2))
{
instances.Add(Process.GetCurrentProcess());
}
else if (MainController.ServerController != null)
{
if (MainController.ServerController is Guard instanceController)
instances.Add(instanceController.Instance);
switch (MainController.ServerController)
{
case SSController ssController when ssController.DllFlag:
instances.Add(Process.GetCurrentProcess());
break;
case Guard instanceController:
instances.Add(instanceController.Instance);
break;
}
}
else if (MainController.ModeController != null)
{
if (MainController.ModeController is Guard instanceController)
instances.Add(instanceController.Instance);
switch (MainController.ModeController)
{
case NFController _:
instances.Add(Process.GetCurrentProcess());
break;
case Guard instanceController:
instances.Add(instanceController.Instance);
break;
}
}
var processList = instances.Select(instance => instance.Id).ToList();

View File

@@ -49,6 +49,8 @@ namespace Netch.Utils
private static RegistryKey AdapterRegistry(bool write = false)
{
if (Global.Outbound.Adapter == null)
Utils.SearchOutboundAdapter();
return Registry.LocalMachine.OpenSubKey(
$@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{Global.Outbound.Adapter.Id}", write);
}

View File

@@ -9,23 +9,44 @@ namespace Netch.Utils
{
public static class ICSHelper
{
public static bool Enabled
public static bool? Enabled
{
get
{
TUNTAPController.SearchTapAdapter();
return (
from NetworkConnection connection in new NetworkConnectionCollection()
where connection.DeviceName == Global.TUNTAP.Adapter.Description
select connection.SharingEnabled
).FirstOrDefault();
AutoSearchTapAdapter();
if (Global.TUNTAP.Adapter == null)
return null;
foreach (NetworkConnection connection in new NetworkConnectionCollection())
{
try
{
if (connection.DeviceName == Global.TUNTAP.Adapter?.Description)
{
return connection.SharingEnabled;
}
}
catch (Exception e)
{
Logging.Warning(e.ToString());
}
}
return null;
}
}
private static void AutoSearchTapAdapter()
{
if (Global.TUNTAP.Adapter == null)
TUNTAPController.SearchTapAdapter();
}
public static bool Enable()
{
Utils.SearchOutboundAdapter(false);
TUNTAPController.SearchTapAdapter();
AutoSearchTapAdapter();
if (Global.TUNTAP.Adapter == null || Global.Outbound.Adapter == null)
{
@@ -133,9 +154,19 @@ namespace Netch.Utils
public static void Disable()
{
foreach (var connection in new NetworkConnectionCollection().Cast<NetworkConnection>().Where(connection => connection.SharingEnabled))
foreach (NetworkConnection connection in new NetworkConnectionCollection())
{
connection.DisableSharing();
try
{
if (connection.SharingEnabled)
{
connection.DisableSharing();
}
}
catch (Exception e)
{
Logging.Warning(e.ToString());
}
}
CleanupWMISharingEntries();

View File

@@ -60,7 +60,7 @@ namespace Netch.Utils
for (var i = 0; i < content.Length; i++)
{
var text = content[i];
var text = content[i].Trim();
if (i == 0)
{
@@ -83,8 +83,7 @@ namespace Netch.Utils
}
else
{
if (!text.StartsWith("#") && !string.IsNullOrWhiteSpace(text))
mode.Rule.Add(text.Trim());
mode.Rule.Add(text);
}
}

View File

@@ -120,42 +120,30 @@ namespace Netch.Utils
}
var list = new List<Server>();
try
{
try
list.AddRange(JsonConvert.DeserializeObject<List<ShadowsocksConfig>>(text).Select(server => new Shadowsocks
{
list.AddRange(JsonConvert.DeserializeObject<List<ShadowsocksConfig>>(text).Select(server => new Shadowsocks
{
Hostname = server.server,
Port = server.server_port,
EncryptMethod = server.method,
Password = server.password,
Remark = server.remarks,
Plugin = server.plugin,
PluginOption = server.plugin_opts
}));
}
catch (JsonReaderException)
Hostname = server.server,
Port = server.server_port,
EncryptMethod = server.method,
Password = server.password,
Remark = server.remarks,
Plugin = server.plugin,
PluginOption = server.plugin_opts
}));
}
catch (JsonReaderException)
{
foreach (var line in text.GetLines())
{
foreach (var line in text.GetLines())
{
var servers = ParseUri(line);
if (servers != null)
{
list.AddRange(servers);
}
}
}
if (list.Count == 0)
{
return null;
list.AddRange(ParseUri(line));
}
}
catch (Exception e)
{
Logging.Error(e.ToString());
return null;
}
return list;
@@ -179,19 +167,19 @@ namespace Netch.Utils
{
var scheme = GetUriScheme(text);
var util = ServerHelper.GetUtilByUriScheme(scheme);
if (util == null)
if (util != null)
{
list.AddRange(util.ParseUri(text));
}
else
{
Logging.Warning($"无法处理 {scheme} 协议订阅链接");
return null;
}
list.AddRange(util.ParseUri(text));
}
}
catch (Exception e)
{
Logging.Error(e.ToString());
return null;
}
foreach (var node in list)
@@ -212,26 +200,35 @@ namespace Netch.Utils
private static Server ParseNetchUri(string text)
{
text = text.Substring(8);
var NetchLink = (JObject) JsonConvert.DeserializeObject(URLSafeBase64Decode(text));
if (NetchLink == null)
try
{
text = text.Substring(8);
var NetchLink = (JObject) JsonConvert.DeserializeObject(URLSafeBase64Decode(text));
if (NetchLink == null)
{
return null;
}
if (string.IsNullOrEmpty((string) NetchLink["Hostname"]))
{
return null;
}
if (!ushort.TryParse((string) NetchLink["Port"], out _))
{
return null;
}
var type = (string) NetchLink["Type"];
var s = ServerHelper.GetUtilByTypeName(type).ParseJObject(NetchLink);
return ServerHelper.GetUtilByTypeName(s.Type).CheckServer(s) ? s : null;
}
catch (Exception e)
{
Logging.Warning(e.ToString());
return null;
}
if (string.IsNullOrEmpty((string) NetchLink["Hostname"]))
{
return null;
}
if (!ushort.TryParse((string) NetchLink["Port"], out _))
{
return null;
}
var type = (string) NetchLink["Type"];
var s = ServerHelper.GetUtilByTypeName(type).ParseJObject(NetchLink);
return ServerHelper.GetUtilByTypeName(s.Type).CheckServer(s) ? s : null;
}
public static string GetNetchLink(Server s)