mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3eb07005e | ||
|
|
12b2989755 | ||
|
|
0222792361 | ||
|
|
3e5e3a7275 | ||
|
|
a49e280e03 | ||
|
|
45b6352553 | ||
|
|
406fbd8b7e | ||
|
|
454b03a69f | ||
|
|
98ab8864eb | ||
|
|
f3358f3da2 | ||
|
|
fa1593de49 | ||
|
|
f26d09bf9f | ||
|
|
35859a19f7 | ||
|
|
e3e595d469 | ||
|
|
36718e774c | ||
|
|
bf6d3aae95 | ||
|
|
477509b12f | ||
|
|
910f6818b0 | ||
|
|
ed3f4d1763 | ||
|
|
be53432a2e | ||
|
|
9d78de0f6c | ||
|
|
75bf753a65 |
26
.github/workflows/build.yml
vendored
26
.github/workflows/build.yml
vendored
@@ -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
|
||||
|
||||
39
BUILD.ps1
39
BUILD.ps1
@@ -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'
|
||||
|
||||
@@ -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()
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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}")}";
|
||||
|
||||
@@ -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());
|
||||
|
||||
19
Netch/Forms/Mode/Process.Designer.cs
generated
19
Netch/Forms/Mode/Process.Designer.cs
generated
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
56
Netch/Forms/SettingForm.Designer.cs
generated
56
Netch/Forms/SettingForm.Designer.cs
generated
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Netch/Forms/SubscribeForm.Designer.cs
generated
7
Netch/Forms/SubscribeForm.Designer.cs
generated
@@ -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
|
||||
//
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
/// 语言设置
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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"))
|
||||
{
|
||||
|
||||
@@ -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": "配置",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
/// 伪装域名(HTTP,WS)
|
||||
/// </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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Submodule translations updated: 9ee3747784...45e50093e3
Reference in New Issue
Block a user