mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
Compare commits
127 Commits
1.8.3-Beta
...
1.8.3-Beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1099b2c6e6 | ||
|
|
295c5958fd | ||
|
|
9a3a85078e | ||
|
|
c14fa70a08 | ||
|
|
ebcde8cf55 | ||
|
|
5fca9c55fe | ||
|
|
9f105425ab | ||
|
|
4a3d6c49d0 | ||
|
|
fa23561827 | ||
|
|
96b8c42918 | ||
|
|
9b41ea99e5 | ||
|
|
6099891280 | ||
|
|
b8676df2ab | ||
|
|
5970e30974 | ||
|
|
37455bb89e | ||
|
|
9437ec7e5d | ||
|
|
93faf8a82e | ||
|
|
8a5c0dcd1d | ||
|
|
559f1dc8a9 | ||
|
|
d0c71698aa | ||
|
|
98bf6c3c9b | ||
|
|
8a6970cc26 | ||
|
|
c0b1ae193b | ||
|
|
f7d8af6592 | ||
|
|
7d7643ad77 | ||
|
|
15f9c6d4f5 | ||
|
|
732066ccf8 | ||
|
|
483dccc5d2 | ||
|
|
42b609b597 | ||
|
|
7ab89b67c5 | ||
|
|
a33c2c3757 | ||
|
|
268bdb7730 | ||
|
|
ed459ec8d6 | ||
|
|
ddd1ca5fac | ||
|
|
7c54c1f570 | ||
|
|
ed56d51c4d | ||
|
|
c669097aa5 | ||
|
|
5d74321771 | ||
|
|
093fe6404b | ||
|
|
2760b3c7bd | ||
|
|
ba17366094 | ||
|
|
6c668684e9 | ||
|
|
8d6e4bdd96 | ||
|
|
5522245ce0 | ||
|
|
f518fd6867 | ||
|
|
e0120e7de0 | ||
|
|
3565251b4d | ||
|
|
4a50ebd421 | ||
|
|
4e03793ceb | ||
|
|
23399b872d | ||
|
|
b553ddbb71 | ||
|
|
090e487733 | ||
|
|
cada4c997e | ||
|
|
8746125dda | ||
|
|
d09b5adc33 | ||
|
|
54c1fb5578 | ||
|
|
f07413c882 | ||
|
|
5b2b6c9f96 | ||
|
|
4c4ad72d1d | ||
|
|
830f3b3b60 | ||
|
|
777657e810 | ||
|
|
2413aabb15 | ||
|
|
6ccb99d1d8 | ||
|
|
ac0266a478 | ||
|
|
d701a8c950 | ||
|
|
934443556c | ||
|
|
a69252819c | ||
|
|
f90773aa84 | ||
|
|
246f52e54e | ||
|
|
a5f6b4a2c0 | ||
|
|
66d7cededd | ||
|
|
8254482799 | ||
|
|
b215b2caa8 | ||
|
|
5f9dbb0994 | ||
|
|
3cbd5af9a3 | ||
|
|
2ab693facf | ||
|
|
664b1a7e6c | ||
|
|
ad1575b3c7 | ||
|
|
62b78d1b1d | ||
|
|
dd3ce126e3 | ||
|
|
a295cf6250 | ||
|
|
a507df5f30 | ||
|
|
0a7b405f1b | ||
|
|
c61da9b918 | ||
|
|
9bf3490cf9 | ||
|
|
c505e2abbb | ||
|
|
5fc7c460aa | ||
|
|
c79f62334c | ||
|
|
2dc4308427 | ||
|
|
c3c534eb92 | ||
|
|
dbef41d8a4 | ||
|
|
e3d6a62e81 | ||
|
|
415c7705ac | ||
|
|
4ab844e31c | ||
|
|
f4759d2f94 | ||
|
|
a080de6ca4 | ||
|
|
f8148cb730 | ||
|
|
b092b6a4d4 | ||
|
|
e2bcdc8840 | ||
|
|
4202c8ac5a | ||
|
|
db765d60f0 | ||
|
|
28c248ea70 | ||
|
|
f818c444a4 | ||
|
|
d260afd49b | ||
|
|
66bfe39674 | ||
|
|
95d1b039cd | ||
|
|
b2a7d4fd59 | ||
|
|
ec6b9a2c18 | ||
|
|
dcb90ccdcd | ||
|
|
5da5daa112 | ||
|
|
5d5ee40cd6 | ||
|
|
32d3e97288 | ||
|
|
452c5ec67c | ||
|
|
9d2fd2cce3 | ||
|
|
5a3295d10c | ||
|
|
8269948288 | ||
|
|
8e545fc05f | ||
|
|
9a3a1e3664 | ||
|
|
3f4a31dac8 | ||
|
|
7c0088cc7f | ||
|
|
1a28d791b7 | ||
|
|
05df786ab6 | ||
|
|
1ffbae6135 | ||
|
|
8ca9d6d9be | ||
|
|
4f1ae20b9b | ||
|
|
15a1db3b21 | ||
|
|
54243a80e7 |
55
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
55
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
name: Bug report
|
||||
description: "Create a report to help us improve"
|
||||
title: ""
|
||||
labels: 需要核实
|
||||
issue_body: true
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "**Make sure you have read the readme, searched and read the issues related to yours. Otherwise it will be considered as a duplicate which will be closed immediately.**"
|
||||
- type: textarea
|
||||
id: error
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: To Reproduce
|
||||
placeholder: |
|
||||
Steps to reproduce the behavior:
|
||||
1. Open Netch
|
||||
2. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: captcha
|
||||
attributes:
|
||||
label: CAPTCHA
|
||||
description: Please confirm the options below.
|
||||
options:
|
||||
- label: I am human
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
render: shell
|
||||
label: Log
|
||||
description: Attaching any log files in the folder `Netch\logging` is strongly recommended.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
placeholder: |
|
||||
- OS: [e.g. Windows 10 Pro 64-bit 1903]
|
||||
- Netch Version: [e.g. 1.0.0-STABLE.x64]
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
In the text box below, you can attach any relevant screenshots and files.
|
||||
54
.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
vendored
Normal file
54
.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: 错误报告
|
||||
description: "创建错误报告以帮助我们改进"
|
||||
title: ""
|
||||
labels: 需要核实
|
||||
issue_body: true
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "**确保你已经看过 readme,也搜索并阅读过和你遇到的情况相关的问题。否则会被认为是重复的并被立刻关闭。**"
|
||||
- type: textarea
|
||||
id: error
|
||||
attributes:
|
||||
label: "错误描述"
|
||||
description: 对错误的清晰简洁描述
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: "复现步骤"
|
||||
placeholder: |
|
||||
1. 打开 Netch 软件
|
||||
2. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: captcha
|
||||
attributes:
|
||||
label: 验证
|
||||
description: 请确认下面选项
|
||||
options:
|
||||
- label: 我是人类
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
render: shell
|
||||
label: 日志
|
||||
description: 强烈建议附上任何在 `Netch\logging` 文件夹下面的日志
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: 操作环境
|
||||
placeholder: |
|
||||
操作系统:[Windows 10 专业版 64 位 1903]
|
||||
软件版本:[1.0.0-STABLE 64 位]
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
下面的文本框中你可以附上跟 issue 相关的截图、文件
|
||||
16
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
16
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: request
|
||||
description: "Suggest an idea for this project"
|
||||
title: ""
|
||||
labels: 需要核实
|
||||
issue_body: true
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "**Make sure you have read the readme, searched and read the issues related to yours. Otherwise it will be considered as a duplicate which will be closed immediately.**"
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: "Describe the feature you want"
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
16
.github/ISSUE_TEMPLATE/feature_request.zh-CN.yml
vendored
Normal file
16
.github/ISSUE_TEMPLATE/feature_request.zh-CN.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: 功能请求
|
||||
description: "建议这个项目的想法"
|
||||
title: ""
|
||||
labels: 需要核实
|
||||
issue_body: true
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "**确保你已经看过 readme,也搜索并阅读过和你遇到的情况相关的问题。否则会被认为是重复的并被立刻关闭。**"
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: "功能描述"
|
||||
description: 简明扼要地描述需要的功能
|
||||
validations:
|
||||
required: true
|
||||
27
.github/workflows/build.yml
vendored
Normal file
27
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: Netch CI
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Build
|
||||
shell: pwsh
|
||||
run: |
|
||||
.\build.ps1 -Configuration Release -OutputPath release
|
||||
|
||||
- name: Upload
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Netch
|
||||
path: release
|
||||
30
.github/workflows/ci.yml
vendored
30
.github/workflows/ci.yml
vendored
@@ -1,30 +0,0 @@
|
||||
name: Netch CI
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
dependabot/**
|
||||
pull_request:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Build Solution
|
||||
shell: pwsh
|
||||
run: .\BUILD.ps1
|
||||
|
||||
- name: Upload Artifact
|
||||
continue-on-error: true
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Netch
|
||||
path: Netch\bin\x64\Release
|
||||
34
.github/workflows/release.yml
vendored
34
.github/workflows/release.yml
vendored
@@ -1,44 +1,44 @@
|
||||
name: Netch Release
|
||||
name: Netch CI
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*.*'
|
||||
- '*.*.*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Setup MSBuild
|
||||
- name: MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Build Solution
|
||||
shell: pwsh
|
||||
run: .\BUILD.ps1
|
||||
|
||||
- name: Package
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
|
||||
- name: Build
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path C:\builtfiles -Force > $null
|
||||
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
|
||||
.\build.ps1 -Configuration Release -OutputPath release
|
||||
|
||||
- name: Package
|
||||
shell: pwsh
|
||||
run: |
|
||||
7z a -mx9 Netch.7z release
|
||||
7z rn Netch.7z release Netch
|
||||
|
||||
echo "NETCH_SHA256=$(.\sha256.ps1 Netch.7z)" | Out-File -Append -Encoding UTF8 -FilePath $Env:GITHUB_ENV
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
prerelease: ${{ contains(github.ref, '-') }}
|
||||
draft: false
|
||||
files: |
|
||||
C:\builtfiles\Netch.7z
|
||||
Netch.7z
|
||||
body: |
|
||||
[](https://t.me/Netch) [](https://t.me/Netch_Discuss_Group)
|
||||
|
||||
|
||||
9
.gitmodules
vendored
9
.gitmodules
vendored
@@ -1,9 +0,0 @@
|
||||
[submodule "binaries"]
|
||||
path = binaries
|
||||
url = https://github.com/NetchX/NetchBinaries
|
||||
[submodule "modes"]
|
||||
path = modes
|
||||
url = https://github.com/NetchX/NetchMode
|
||||
[submodule "translations"]
|
||||
path = translations
|
||||
url = https://github.com/NetchX/NetchTranslation
|
||||
12
BUILD.ps1
12
BUILD.ps1
@@ -1,12 +0,0 @@
|
||||
Write-Host 'Building'
|
||||
|
||||
msbuild -v:n /p:Configuration="Release" `
|
||||
/p:Platform="x64" `
|
||||
/p:TargetFramework=net48 `
|
||||
/p:SolutionDir="$pwd\" `
|
||||
/restore `
|
||||
Netch\Netch.csproj
|
||||
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
|
||||
Write-Host 'Build done'
|
||||
21
CLEAN.ps1
21
CLEAN.ps1
@@ -1,21 +0,0 @@
|
||||
if (Test-Path Netch\bin)
|
||||
{
|
||||
Remove-Item -Recurse -Force Netch\bin
|
||||
}
|
||||
|
||||
if (Test-Path Netch\obj)
|
||||
{
|
||||
Remove-Item -Recurse -Force Netch\obj
|
||||
}
|
||||
|
||||
if (Test-Path NetchLib\bin)
|
||||
{
|
||||
Remove-Item -Recurse -Force NetchLib\bin
|
||||
}
|
||||
|
||||
if (Test-Path NetchLib\obj)
|
||||
{
|
||||
Remove-Item -Recurse -Force NetchLib\obj
|
||||
}
|
||||
|
||||
exit 0
|
||||
53
GSF.md
53
GSF.md
@@ -1,53 +0,0 @@
|
||||
```json
|
||||
{
|
||||
"Type": "",
|
||||
"Rate": 1,
|
||||
"Remark": "",
|
||||
"Hostname": "",
|
||||
"Port": 0,
|
||||
"Username": "",
|
||||
"Password": "",
|
||||
"EncryptMethod": "",
|
||||
"Plugin": "",
|
||||
"PluginOption": "",
|
||||
"Protocol": "",
|
||||
"ProtocolParam": "",
|
||||
"OBFS": "",
|
||||
"OBFSParam": "",
|
||||
"UserID": "",
|
||||
"AlterID": 0,
|
||||
"TransferProtocol": "",
|
||||
"FakeType": "",
|
||||
"Host": "",
|
||||
"Path": "",
|
||||
"QUICSecure": "",
|
||||
"QUICSecret": "",
|
||||
"TLSSecure": false
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
| :- | :- |
|
||||
| Type | 代理类型(HTTP、HTTPS、Socks5、SS、SSR、VMess) |
|
||||
| Rate | 倍率 |
|
||||
| Remark | 备注 |
|
||||
| Hostname | 主机名 |
|
||||
| Port | 端口 |
|
||||
| Username | 账号(HTTP、HTTPS、Socks5) |
|
||||
| Password | 密码(HTTP、HTTPS、Socks5、SS、SSR) |
|
||||
| UserID | 用户 ID(VMess) |
|
||||
| AlterID | 额外 ID(VMess) |
|
||||
| EncryptMethod | 加密方式(SS、SSR、VMess) |
|
||||
| Plugin | 插件(SS) |
|
||||
| PluginOption | 插件参数(SS) |
|
||||
| Protocol | 协议(SSR) |
|
||||
| ProtocolParam | 协议参数(SSR) |
|
||||
| OBFS | 混淆(SSR) |
|
||||
| OBFSParam | 混淆参数(SSR) |
|
||||
| TransferProtcol | 传输协议(VMess) |
|
||||
| FakeType | 伪装类型(VMess) |
|
||||
| Host | 伪装域名(VMess) |
|
||||
| Path | 传输路径(VMess) |
|
||||
| QUICSecure | QUIC 加密方式(VMess) |
|
||||
| QUICSecret | QUIC 加密密钥(VMess) |
|
||||
| TLSSecure | TLS 底层传输安全(VMess) |
|
||||
11
Netch.sln
11
Netch.sln
@@ -5,10 +5,6 @@ VisualStudioVersion = 16.0.29009.5
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Netch", "Netch\Netch.csproj", "{4B041B91-5790-4571-8C58-C63FFE4BC9F8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SearchComboBox", "SearchComboBox\SearchComboBox.csproj", "{A8715AF4-ACC6-43F9-9381-4294C5360623}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{53397641-35CA-4336-8E22-2CE12EF476AC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -19,13 +15,6 @@ Global
|
||||
{4B041B91-5790-4571-8C58-C63FFE4BC9F8}.Debug|x64.Build.0 = Debug|x64
|
||||
{4B041B91-5790-4571-8C58-C63FFE4BC9F8}.Release|x64.ActiveCfg = Release|x64
|
||||
{4B041B91-5790-4571-8C58-C63FFE4BC9F8}.Release|x64.Build.0 = Release|x64
|
||||
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Release|x64.Build.0 = Release|Any CPU
|
||||
{53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.Build.0 = Debug|x64
|
||||
{53397641-35CA-4336-8E22-2CE12EF476AC}.Release|x64.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<System.Windows.Forms.ApplicationConfigurationSection>
|
||||
<add key="DpiAwareness" value="PerMonitorV2" />
|
||||
</System.Windows.Forms.ApplicationConfigurationSection>
|
||||
</configuration>
|
||||
14
Netch/Constants.cs
Normal file
14
Netch/Constants.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Netch
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const string EOF = "\r\n";
|
||||
|
||||
public static class Parameter
|
||||
{
|
||||
public const string Show = "-show";
|
||||
public const string ForceUpdate = "-forceUpdate";
|
||||
public const string Console = "-console";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using static Netch.Interops.AioDNSInterops;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
@@ -11,7 +10,7 @@ namespace Netch.Controllers
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
aiodns_free();
|
||||
Free();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -20,38 +19,14 @@ namespace Netch.Controllers
|
||||
/// <returns></returns>
|
||||
public void Start()
|
||||
{
|
||||
aiodns_dial((int) NameList.TYPE_REST, null);
|
||||
aiodns_dial((int) NameList.TYPE_ADDR, Encoding.UTF8.GetBytes($"{Global.Settings.LocalAddress}:53"));
|
||||
aiodns_dial((int) NameList.TYPE_LIST, Encoding.UTF8.GetBytes(Path.GetFullPath(Global.Settings.AioDNS.RulePath)));
|
||||
aiodns_dial((int) NameList.TYPE_CDNS, Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.ChinaDNS}:53"));
|
||||
aiodns_dial((int) NameList.TYPE_ODNS, Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.OtherDNS}:53"));
|
||||
aiodns_dial((int) NameList.TYPE_METH, Encoding.UTF8.GetBytes(Global.Settings.AioDNS.Protocol));
|
||||
Dial(NameList.TYPE_REST, "");
|
||||
Dial(NameList.TYPE_ADDR, $"{Global.Settings.LocalAddress}:{Global.Settings.AioDNS.ListenPort}");
|
||||
Dial(NameList.TYPE_LIST, Path.GetFullPath(Global.Settings.AioDNS.RulePath));
|
||||
Dial(NameList.TYPE_CDNS, $"{Global.Settings.AioDNS.ChinaDNS}");
|
||||
Dial(NameList.TYPE_ODNS, $"{Global.Settings.AioDNS.OtherDNS}");
|
||||
|
||||
if (!aiodns_init())
|
||||
if (!Init())
|
||||
throw new Exception("AioDNS start failed");
|
||||
}
|
||||
|
||||
#region NativeMethods
|
||||
|
||||
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool aiodns_dial(int name, byte[]? value);
|
||||
|
||||
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool aiodns_init();
|
||||
|
||||
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void aiodns_free();
|
||||
|
||||
private enum NameList
|
||||
{
|
||||
TYPE_REST,
|
||||
TYPE_ADDR,
|
||||
TYPE_LIST,
|
||||
TYPE_CDNS,
|
||||
TYPE_ODNS,
|
||||
TYPE_METH
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -30,12 +30,12 @@ namespace Netch.Controllers
|
||||
/// <summary>
|
||||
/// 成功启动关键词
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<string> StartedKeywords { get; } = new List<string>();
|
||||
protected virtual IEnumerable<string> StartedKeywords { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 启动失败关键词
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<string> StoppedKeywords { get; } = new List<string>();
|
||||
protected virtual IEnumerable<string> StoppedKeywords { get; set; } = new List<string>();
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
Logging.Error($"停止 {MainFile} 错误:\n" + e);
|
||||
Global.Logger.Error($"停止 {MainFile} 错误:\n" + e);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -268,7 +268,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logging.Warning($"写入 {Name} 日志错误:\n" + exception.Message);
|
||||
Global.Logger.Warning($"写入 {Name} 日志错误:\n" + exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using WindowsProxy;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Servers.Trojan;
|
||||
using Netch.Utils;
|
||||
using Netch.Utils.HttpProxyHandler;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class HTTPController : IModeController
|
||||
{
|
||||
public readonly PrivoxyController PrivoxyController = new();
|
||||
|
||||
private ProxyStatus? _oldState;
|
||||
|
||||
public string Name { get; } = "HTTP";
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
PrivoxyController.Start(MainController.Server!);
|
||||
string? pacUrl = null;
|
||||
|
||||
if (MainController.Server is Socks5 or Trojan && mode.BypassChina || (Global.Settings.AlwaysStartPACServer ?? false))
|
||||
{
|
||||
try
|
||||
{
|
||||
PortHelper.CheckPort(Global.Settings.Pac_Port);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Global.Settings.Pac_Port = PortHelper.GetAvailablePort();
|
||||
}
|
||||
|
||||
pacUrl = PACServerHandle.InitPACServer();
|
||||
}
|
||||
|
||||
if (mode.Type is 3)
|
||||
{
|
||||
using var service = new ProxyService();
|
||||
_oldState = service.Query();
|
||||
|
||||
if (pacUrl != null)
|
||||
{
|
||||
service.AutoConfigUrl = pacUrl;
|
||||
service.Pac();
|
||||
}
|
||||
else
|
||||
{
|
||||
service.Server = $"127.0.0.1:{Global.Settings.HTTPLocalPort}";
|
||||
service.Bypass = string.Join(";", ProxyService.LanIp);
|
||||
|
||||
service.Global();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
Task.Run(PrivoxyController.Stop),
|
||||
Task.Run(() =>
|
||||
{
|
||||
PACServerHandle.Stop();
|
||||
|
||||
if (_oldState != null)
|
||||
{
|
||||
using var service = new ProxyService();
|
||||
if (_oldState.IsProxy && _oldState.ProxyServer == service.Query().ProxyServer ||
|
||||
_oldState.IsAutoProxyUrl && _oldState.AutoConfigUrl!.StartsWith(PACServerHandle.PacPrefix))
|
||||
{
|
||||
service.Direct();
|
||||
return;
|
||||
}
|
||||
|
||||
service.Set(_oldState);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
@@ -55,13 +54,10 @@ namespace Netch.Controllers
|
||||
|
||||
public static void Start(Server server, Mode mode)
|
||||
{
|
||||
Logging.Info($"启动主控制器: {server.Type} [{mode.Type}]{mode.Remark}");
|
||||
Global.Logger.Info($"启动主控制器: {server.Type} [{mode.Type}]{mode.Remark}");
|
||||
Server = server;
|
||||
Mode = mode;
|
||||
|
||||
if (server is Socks5 && mode.Type == 4)
|
||||
throw new MessageException("Already Socks5 Server");
|
||||
|
||||
// 刷新DNS缓存
|
||||
NativeMethods.FlushDNSResolverCache();
|
||||
|
||||
@@ -93,8 +89,8 @@ namespace Netch.Controllers
|
||||
case MessageException:
|
||||
throw;
|
||||
default:
|
||||
Logging.Error(e.ToString());
|
||||
Utils.Utils.Open(Logging.LogFile);
|
||||
Global.Logger.Error(e.ToString());
|
||||
Global.Logger.ShowLog();
|
||||
throw new MessageException($"未处理异常\n{e.Message}");
|
||||
}
|
||||
}
|
||||
@@ -125,9 +121,6 @@ namespace Netch.Controllers
|
||||
{
|
||||
ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName);
|
||||
|
||||
if (ModeController == null)
|
||||
return;
|
||||
|
||||
if (port != null)
|
||||
TryReleaseTcpPort((ushort) port, portName);
|
||||
|
||||
@@ -165,8 +158,8 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.ToString());
|
||||
Utils.Utils.Open(Logging.LogFile);
|
||||
Global.Logger.Error(e.ToString());
|
||||
Global.Logger.ShowLog();
|
||||
}
|
||||
|
||||
ModeController = null;
|
||||
@@ -191,34 +184,31 @@ namespace Netch.Controllers
|
||||
|
||||
public static void TryReleaseTcpPort(ushort port, string portName)
|
||||
{
|
||||
Process? p;
|
||||
if ((p = PortHelper.GetProcessByUsedTcpPort(port)) != null)
|
||||
foreach (var p in PortHelper.GetProcessByUsedTcpPort(port))
|
||||
{
|
||||
if (p.MainModule!.FileName.StartsWith(Global.NetchDir))
|
||||
string fileName;
|
||||
try
|
||||
{
|
||||
fileName = p.MainModule?.FileName ?? throw new Exception(); // TODO what's this exception?
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Global.Logger.Warning(e.ToString());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileName.StartsWith(Global.NetchDir))
|
||||
{
|
||||
p.Kill();
|
||||
p.WaitForExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MessageException(i18N.TranslateFormat("The {0} port is used by {1}.",
|
||||
$"{portName} ({port})",
|
||||
$"({p.Id}){p.MainModule.FileName}"));
|
||||
throw new MessageException(i18N.TranslateFormat("The {0} port is used by {1}.", $"{portName} ({port})", $"({p.Id}){fileName}"));
|
||||
}
|
||||
}
|
||||
|
||||
PortCheck(port, portName, PortType.TCP);
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageException : Exception
|
||||
{
|
||||
public MessageException()
|
||||
{
|
||||
}
|
||||
|
||||
public MessageException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Interops;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Shadowsocks;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Utils;
|
||||
using nfapinet;
|
||||
using static Netch.Interops.RedirectorInterop;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
@@ -26,29 +25,30 @@ namespace Netch.Controllers
|
||||
{
|
||||
CheckDriver();
|
||||
|
||||
aio_dial((int) NameList.TYPE_FILTERLOOPBACK, "false");
|
||||
aio_dial((int) NameList.TYPE_TCPLISN, Global.Settings.RedirectorTCPPort.ToString());
|
||||
Dial(NameList.TYPE_FILTERLOOPBACK, "false");
|
||||
Dial(NameList.TYPE_FILTERICMP, "true");
|
||||
var p = PortHelper.GetAvailablePort();
|
||||
Dial(NameList.TYPE_TCPLISN, p.ToString());
|
||||
Dial(NameList.TYPE_UDPLISN, p.ToString());
|
||||
|
||||
// Server
|
||||
aio_dial((int) NameList.TYPE_FILTERUDP, (Global.Settings.ProcessProxyProtocol != PortType.TCP).ToString().ToLower());
|
||||
aio_dial((int) NameList.TYPE_FILTERTCP, (Global.Settings.ProcessProxyProtocol != PortType.UDP).ToString().ToLower());
|
||||
dial_Server(Global.Settings.ProcessProxyProtocol);
|
||||
Dial(NameList.TYPE_FILTERUDP, (Global.Settings.Redirector.ProxyProtocol != PortType.TCP).ToString().ToLower());
|
||||
Dial(NameList.TYPE_FILTERTCP, (Global.Settings.Redirector.ProxyProtocol != PortType.UDP).ToString().ToLower());
|
||||
dial_Server(Global.Settings.Redirector.ProxyProtocol);
|
||||
|
||||
// Mode Rule
|
||||
dial_Name(mode);
|
||||
|
||||
// Features
|
||||
aio_dial((int) NameList.TYPE_REDIRCTOR_DNS, Global.Settings.RedirectDNS ? Global.Settings.RedirectDNSAddr : "");
|
||||
aio_dial((int) NameList.TYPE_REDIRCTOR_ICMP, Global.Settings.RedirectICMP ? Global.Settings.RedirectICMPAddr : "");
|
||||
aio_dial((int) NameList.TYPE_FILTERCHILDPROC, Global.Settings.ChildProcessHandle.ToString().ToLower());
|
||||
Dial(NameList.TYPE_DNSHOST, Global.Settings.Redirector.DNSHijack ? Global.Settings.Redirector.DNSHijackHost : "");
|
||||
|
||||
if (!aio_init())
|
||||
if (!Init())
|
||||
throw new MessageException("Redirector Start failed, run Netch with \"-console\" argument");
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
aio_free();
|
||||
Free();
|
||||
}
|
||||
|
||||
#region CheckRule
|
||||
@@ -63,14 +63,14 @@ namespace Netch.Controllers
|
||||
try
|
||||
{
|
||||
if (r.StartsWith("!"))
|
||||
return aio_dial((int) NameList.TYPE_ADDNAME, r.Substring(1));
|
||||
return Dial(NameList.TYPE_ADDNAME, r.Substring(1));
|
||||
|
||||
return aio_dial((int) NameList.TYPE_ADDNAME, r);
|
||||
return Dial(NameList.TYPE_ADDNAME, r);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (clear)
|
||||
aio_dial((int) NameList.TYPE_CLRNAME, "");
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Netch.Controllers
|
||||
public static bool CheckRules(IEnumerable<string> rules, out IEnumerable<string> results)
|
||||
{
|
||||
results = rules.Where(r => !CheckCppRegex(r, false));
|
||||
aio_dial((int) NameList.TYPE_CLRNAME, "");
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
return !results.Any();
|
||||
}
|
||||
|
||||
@@ -121,52 +121,52 @@ namespace Netch.Controllers
|
||||
|
||||
if (server is Socks5 socks5)
|
||||
{
|
||||
aio_dial((int) NameList.TYPE_TCPTYPE + offset, "Socks5");
|
||||
aio_dial((int) NameList.TYPE_TCPHOST + offset, $"{socks5.AutoResolveHostname()}:{socks5.Port}");
|
||||
aio_dial((int) NameList.TYPE_TCPUSER + offset, socks5.Username ?? string.Empty);
|
||||
aio_dial((int) NameList.TYPE_TCPPASS + offset, socks5.Password ?? string.Empty);
|
||||
aio_dial((int) NameList.TYPE_TCPMETH + offset, string.Empty);
|
||||
Dial(NameList.TYPE_TCPTYPE + offset, "Socks5");
|
||||
Dial(NameList.TYPE_TCPHOST + offset, $"{socks5.AutoResolveHostname()}:{socks5.Port}");
|
||||
Dial(NameList.TYPE_TCPUSER + offset, socks5.Username ?? string.Empty);
|
||||
Dial(NameList.TYPE_TCPPASS + offset, socks5.Password ?? string.Empty);
|
||||
Dial(NameList.TYPE_TCPMETH + offset, string.Empty);
|
||||
}
|
||||
else if (server is Shadowsocks shadowsocks && !shadowsocks.HasPlugin() && Global.Settings.RedirectorSS)
|
||||
else if (server is Shadowsocks shadowsocks && !shadowsocks.HasPlugin() && Global.Settings.Redirector.RedirectorSS)
|
||||
{
|
||||
aio_dial((int) NameList.TYPE_TCPTYPE + offset, "Shadowsocks");
|
||||
aio_dial((int) NameList.TYPE_TCPHOST + offset, $"{shadowsocks.AutoResolveHostname()}:{shadowsocks.Port}");
|
||||
aio_dial((int) NameList.TYPE_TCPMETH + offset, shadowsocks.EncryptMethod);
|
||||
aio_dial((int) NameList.TYPE_TCPPASS + offset, shadowsocks.Password);
|
||||
Dial(NameList.TYPE_TCPTYPE + offset, "Shadowsocks");
|
||||
Dial(NameList.TYPE_TCPHOST + offset, $"{shadowsocks.AutoResolveHostname()}:{shadowsocks.Port}");
|
||||
Dial(NameList.TYPE_TCPMETH + offset, shadowsocks.EncryptMethod);
|
||||
Dial(NameList.TYPE_TCPPASS + offset, shadowsocks.Password);
|
||||
}
|
||||
else
|
||||
{
|
||||
aio_dial((int) NameList.TYPE_TCPTYPE + offset, "Socks5");
|
||||
aio_dial((int) NameList.TYPE_TCPHOST + offset, $"127.0.0.1:{controller.Socks5LocalPort()}");
|
||||
aio_dial((int) NameList.TYPE_TCPUSER + offset, string.Empty);
|
||||
aio_dial((int) NameList.TYPE_TCPPASS + offset, string.Empty);
|
||||
aio_dial((int) NameList.TYPE_TCPMETH + offset, string.Empty);
|
||||
Dial(NameList.TYPE_TCPTYPE + offset, "Socks5");
|
||||
Dial(NameList.TYPE_TCPHOST + offset, $"127.0.0.1:{controller.Socks5LocalPort()}");
|
||||
Dial(NameList.TYPE_TCPUSER + offset, string.Empty);
|
||||
Dial(NameList.TYPE_TCPPASS + offset, string.Empty);
|
||||
Dial(NameList.TYPE_TCPMETH + offset, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void dial_Name(Mode mode)
|
||||
{
|
||||
aio_dial((int) NameList.TYPE_CLRNAME, "");
|
||||
var list = new List<string>();
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
var invalidList = new List<string>();
|
||||
foreach (var s in mode.FullRule)
|
||||
{
|
||||
if (s.StartsWith("!"))
|
||||
{
|
||||
if (!aio_dial((int) NameList.TYPE_BYPNAME, s.Substring(1)))
|
||||
list.Add(s);
|
||||
if (!Dial(NameList.TYPE_BYPNAME, s.Substring(1)))
|
||||
invalidList.Add(s);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!aio_dial((int) NameList.TYPE_ADDNAME, s))
|
||||
list.Add(s);
|
||||
if (!Dial(NameList.TYPE_ADDNAME, s))
|
||||
invalidList.Add(s);
|
||||
}
|
||||
|
||||
if (list.Any())
|
||||
throw new MessageException(GenerateInvalidRulesMessage(list));
|
||||
if (invalidList.Any())
|
||||
throw new MessageException(GenerateInvalidRulesMessage(invalidList));
|
||||
|
||||
aio_dial((int) NameList.TYPE_ADDNAME, @"NTT\.exe");
|
||||
aio_dial((int) NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$");
|
||||
Dial(NameList.TYPE_ADDNAME, @"NTT\.exe");
|
||||
Dial(NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$");
|
||||
}
|
||||
|
||||
#region DriverUtil
|
||||
@@ -176,8 +176,8 @@ namespace Netch.Controllers
|
||||
var binFileVersion = Utils.Utils.GetFileVersion(BinDriver);
|
||||
var systemFileVersion = Utils.Utils.GetFileVersion(SystemDriver);
|
||||
|
||||
Logging.Info("内置驱动版本: " + binFileVersion);
|
||||
Logging.Info("系统驱动版本: " + systemFileVersion);
|
||||
Global.Logger.Info("内置驱动版本: " + binFileVersion);
|
||||
Global.Logger.Info("系统驱动版本: " + systemFileVersion);
|
||||
|
||||
if (!File.Exists(SystemDriver))
|
||||
{
|
||||
@@ -207,7 +207,7 @@ namespace Netch.Controllers
|
||||
if (!reinstall)
|
||||
return;
|
||||
|
||||
Logging.Info("更新驱动");
|
||||
Global.Logger.Info("更新驱动");
|
||||
UninstallDriver();
|
||||
InstallDriver();
|
||||
}
|
||||
@@ -216,9 +216,9 @@ namespace Netch.Controllers
|
||||
/// 安装 NF 驱动
|
||||
/// </summary>
|
||||
/// <returns>驱动是否安装成功</returns>
|
||||
public static void InstallDriver()
|
||||
private static void InstallDriver()
|
||||
{
|
||||
Logging.Info("安装 NF 驱动");
|
||||
Global.Logger.Info("安装 NF 驱动");
|
||||
|
||||
if (!File.Exists(BinDriver))
|
||||
throw new MessageException(i18N.Translate("builtin driver files missing, can't install NF driver"));
|
||||
@@ -229,7 +229,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("驱动复制失败\n" + e);
|
||||
Global.Logger.Error("驱动复制失败\n" + e);
|
||||
throw new MessageException($"Copy NF driver file failed\n{e.Message}");
|
||||
}
|
||||
|
||||
@@ -238,11 +238,11 @@ namespace Netch.Controllers
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result == NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Logging.Info("驱动安装成功");
|
||||
Global.Logger.Info("驱动安装成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error($"注册驱动失败,返回值:{result}");
|
||||
Global.Logger.Error($"注册驱动失败,返回值:{result}");
|
||||
throw new MessageException($"Register NF driver failed\n{result}");
|
||||
}
|
||||
}
|
||||
@@ -253,7 +253,7 @@ namespace Netch.Controllers
|
||||
/// <returns>是否成功卸载</returns>
|
||||
public static bool UninstallDriver()
|
||||
{
|
||||
Logging.Info("卸载 NF 驱动");
|
||||
Global.Logger.Info("卸载 NF 驱动");
|
||||
try
|
||||
{
|
||||
if (NFService.Status == ServiceControllerStatus.Running)
|
||||
@@ -277,61 +277,5 @@ namespace Netch.Controllers
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region NativeMethods
|
||||
|
||||
private const int UdpNameListOffset = (int) NameList.TYPE_UDPTYPE - (int) NameList.TYPE_TCPTYPE;
|
||||
|
||||
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_dial(int name, [MarshalAs(UnmanagedType.LPWStr)] string value);
|
||||
|
||||
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_init();
|
||||
|
||||
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_free();
|
||||
|
||||
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong aio_getUP();
|
||||
|
||||
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong aio_getDL();
|
||||
|
||||
public enum NameList
|
||||
{
|
||||
//bool
|
||||
TYPE_FILTERLOOPBACK,
|
||||
TYPE_FILTERTCP,
|
||||
TYPE_FILTERUDP,
|
||||
TYPE_FILTERIP,
|
||||
TYPE_FILTERCHILDPROC, //子进程捕获
|
||||
|
||||
TYPE_TCPLISN,
|
||||
TYPE_TCPTYPE,
|
||||
TYPE_TCPHOST,
|
||||
TYPE_TCPUSER,
|
||||
TYPE_TCPPASS,
|
||||
TYPE_TCPMETH,
|
||||
|
||||
TYPE_UDPTYPE,
|
||||
TYPE_UDPHOST,
|
||||
TYPE_UDPUSER,
|
||||
TYPE_UDPPASS,
|
||||
TYPE_UDPMETH,
|
||||
|
||||
TYPE_ADDNAME,
|
||||
TYPE_ADDFIP,
|
||||
|
||||
TYPE_BYPNAME,
|
||||
|
||||
TYPE_CLRNAME,
|
||||
TYPE_CLRFIP,
|
||||
|
||||
//str addr x.x.x.x only ipv4
|
||||
TYPE_REDIRCTOR_DNS,
|
||||
TYPE_REDIRCTOR_ICMP
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning($"写入 {Name} 日志错误:\n" + e.Message);
|
||||
Global.Logger.Warning($"写入 {Name} 日志错误:\n" + e.Message);
|
||||
}
|
||||
|
||||
if (output.IsNullOrWhiteSpace())
|
||||
@@ -86,7 +86,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($"{Name} 控制器出错:\n" + e);
|
||||
Global.Logger.Error($"{Name} 控制器出错:\n" + e);
|
||||
try
|
||||
{
|
||||
Stop();
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Netch.Controllers
|
||||
|
||||
public override string MainFile { get; protected set; } = "pcap2socks.exe";
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"└"};
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"└"};
|
||||
|
||||
private readonly OutboundAdapter _outbound = new();
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class PrivoxyController : Guard, IController
|
||||
{
|
||||
public PrivoxyController()
|
||||
{
|
||||
RedirectStd = false;
|
||||
}
|
||||
|
||||
public override string MainFile { get; protected set; } = "Privoxy.exe";
|
||||
|
||||
public override string Name { get; } = "Privoxy";
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
|
||||
public void Start(Server server)
|
||||
{
|
||||
var text = new StringBuilder(File.ReadAllText("bin\\default.conf"));
|
||||
|
||||
text.Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString());
|
||||
text.Replace("0.0.0.0", Global.Settings.LocalAddress); /* BIND_HOST */
|
||||
|
||||
if (server is Socks5 socks5 && !socks5.Auth())
|
||||
{
|
||||
text.Replace("/ 127.0.0.1", $"/ {server.AutoResolveHostname()}"); /* DEST_HOST */
|
||||
text.Replace("_DEST_PORT_", socks5.Port.ToString());
|
||||
}
|
||||
|
||||
text.Replace("_DEST_PORT_", Global.Settings.Socks5LocalPort.ToString());
|
||||
|
||||
|
||||
File.WriteAllText("data\\privoxy.conf", text.ToString());
|
||||
|
||||
StartInstanceAuto("..\\data\\privoxy.conf");
|
||||
}
|
||||
}
|
||||
}
|
||||
310
Netch/Controllers/TUNController.cs
Normal file
310
Netch/Controllers/TUNController.cs
Normal file
@@ -0,0 +1,310 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Utils;
|
||||
using Vanara.PInvoke;
|
||||
using static Netch.Interops.TUNInterop;
|
||||
using static Vanara.PInvoke.Ws2_32;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNController : IModeController
|
||||
{
|
||||
private readonly List<string> _directIPs = new();
|
||||
|
||||
private readonly List<string> _proxyIPs = new();
|
||||
|
||||
public readonly DNSController DNSController = new();
|
||||
|
||||
public string Name { get; } = "tun2socks";
|
||||
|
||||
private readonly OutboundAdapter _outboundAdapter = new();
|
||||
private IAdapter _tunAdapter = null!;
|
||||
private IPAddress _serverAddresses = null!;
|
||||
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
var server = MainController.Server!;
|
||||
_serverAddresses = DnsUtils.Lookup(server.Hostname)!; // server address have been cached when MainController.Start
|
||||
|
||||
CheckDriver();
|
||||
|
||||
Dial(NameList.TYPE_ADAPMTU, "1500");
|
||||
Dial(NameList.TYPE_BYPBIND, _outboundAdapter.Address.ToString());
|
||||
Dial(NameList.TYPE_BYPLIST, "disabled");
|
||||
|
||||
#region Server
|
||||
|
||||
Dial(NameList.TYPE_TCPREST, "");
|
||||
Dial(NameList.TYPE_TCPTYPE, "Socks5");
|
||||
|
||||
Dial(NameList.TYPE_UDPREST, "");
|
||||
Dial(NameList.TYPE_UDPTYPE, "Socks5");
|
||||
|
||||
if (server is Socks5 socks5)
|
||||
{
|
||||
Dial(NameList.TYPE_TCPHOST, $"{server.AutoResolveHostname()}:{server.Port}");
|
||||
|
||||
Dial(NameList.TYPE_UDPHOST, $"{server.AutoResolveHostname()}:{server.Port}");
|
||||
|
||||
if (socks5.Auth())
|
||||
{
|
||||
Dial(NameList.TYPE_TCPUSER, socks5.Username!);
|
||||
Dial(NameList.TYPE_TCPPASS, socks5.Password!);
|
||||
|
||||
Dial(NameList.TYPE_UDPUSER, socks5.Username!);
|
||||
Dial(NameList.TYPE_UDPPASS, socks5.Password!);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dial(NameList.TYPE_TCPHOST, $"127.0.0.1:{Global.Settings.Socks5LocalPort}");
|
||||
|
||||
Dial(NameList.TYPE_UDPHOST, $"127.0.0.1:{Global.Settings.Socks5LocalPort}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DNS
|
||||
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
{
|
||||
Dial(NameList.TYPE_DNSADDR, Global.Settings.TUNTAP.HijackDNS);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainController.PortCheck(Global.Settings.AioDNS.ListenPort, "DNS");
|
||||
DNSController.Start();
|
||||
Dial(NameList.TYPE_DNSADDR, $"127.0.0.1:{Global.Settings.AioDNS.ListenPort}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Global.Logger.Debug("tun2socks init");
|
||||
Init();
|
||||
|
||||
_tunAdapter = new TunAdapter();
|
||||
|
||||
NativeMethods.CreateUnicastIP((int) AddressFamily.InterNetwork,
|
||||
Global.Settings.TUNTAP.Address,
|
||||
Utils.Utils.SubnetToCidr(Global.Settings.TUNTAP.Netmask),
|
||||
_tunAdapter.InterfaceIndex);
|
||||
|
||||
SetupRouteTable(mode);
|
||||
}
|
||||
|
||||
private readonly string BinDriver = Path.Combine(Global.NetchDir, @"bin\wintun.dll");
|
||||
private readonly string SysDriver = $@"{Environment.SystemDirectory}\wintun.dll";
|
||||
|
||||
private void CheckDriver()
|
||||
{
|
||||
var binHash = Utils.Utils.SHA256CheckSum(BinDriver);
|
||||
var sysHash = Utils.Utils.SHA256CheckSum(SysDriver);
|
||||
Global.Logger.Info("自带 wintun.dll Hash: " + binHash);
|
||||
Global.Logger.Info("系统 wintun.dll Hash: " + sysHash);
|
||||
if (binHash == sysHash)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
File.Copy(BinDriver, SysDriver, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Global.Logger.Error(e.ToString());
|
||||
throw new MessageException($"Failed to copy wintun.dll to system directory: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
Task.Run(Free),
|
||||
Task.Run(ClearRouteTable),
|
||||
Task.Run(DNSController.Stop)
|
||||
};
|
||||
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置绕行规则
|
||||
/// </summary>
|
||||
/// <returns>是否设置成功</returns>
|
||||
private void SetupRouteTable(Mode mode)
|
||||
{
|
||||
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
|
||||
Global.Logger.Info("设置路由规则");
|
||||
|
||||
Global.Logger.Info("绕行 → 服务器 IP");
|
||||
if (!IPAddress.IsLoopback(_serverAddresses))
|
||||
RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound);
|
||||
|
||||
Global.Logger.Info("绕行 → 全局绕过 IP");
|
||||
RouteAction(Action.Create, Global.Settings.TUNTAP.BypassIPs, RouteType.Outbound);
|
||||
|
||||
#region Rule IPs
|
||||
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 1:
|
||||
// 代理规则 IP
|
||||
Global.Logger.Info("代理 → 规则 IP");
|
||||
RouteAction(Action.Create, mode.FullRule, RouteType.TUNTAP);
|
||||
|
||||
if (Global.Settings.TUNTAP.ProxyDNS)
|
||||
{
|
||||
Global.Logger.Info("代理 → 自定义 DNS");
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
RouteAction(Action.Create, Global.Settings.TUNTAP.HijackDNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP);
|
||||
else
|
||||
RouteAction(Action.Create, $"{Global.Settings.AioDNS.OtherDNS}/32", RouteType.TUNTAP);
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
// 绕过规则 IP
|
||||
|
||||
Global.Logger.Info("绕行 → 规则 IP");
|
||||
RouteAction(Action.Create, mode.FullRule, RouteType.Outbound);
|
||||
break;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if (mode.Type == 2)
|
||||
{
|
||||
Global.Logger.Info("代理 → 全局");
|
||||
SetInterface(RouteType.TUNTAP, 0);
|
||||
RouteAction(Action.Create, "0.0.0.0/0", RouteType.TUNTAP, record: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetInterface(RouteType routeType, int? metric = null)
|
||||
{
|
||||
var adapter = routeType == RouteType.Outbound ? _outboundAdapter : _tunAdapter;
|
||||
|
||||
var arguments = $"interface ip set interface {adapter.InterfaceIndex} ";
|
||||
if (metric != null)
|
||||
arguments += $"metric={metric} ";
|
||||
|
||||
Utils.Utils.ProcessRunHiddenAsync("netsh", arguments).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除绕行规则
|
||||
/// </summary>
|
||||
private bool ClearRouteTable()
|
||||
{
|
||||
var mode = MainController.Mode!;
|
||||
RouteAction(Action.Delete, _directIPs, RouteType.Outbound);
|
||||
RouteAction(Action.Delete, _proxyIPs, RouteType.TUNTAP);
|
||||
_directIPs.Clear();
|
||||
_proxyIPs.Clear();
|
||||
if (mode.Type == 2)
|
||||
{
|
||||
SetInterface(RouteType.Outbound);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Package
|
||||
|
||||
private void RouteAction(Action action, in IEnumerable<string> ipNetworks, RouteType routeType, int metric = 0, bool record = true)
|
||||
{
|
||||
foreach (var address in ipNetworks)
|
||||
RouteAction(action, address, routeType, metric);
|
||||
}
|
||||
|
||||
private bool RouteAction(Action action, in string ipNetwork, RouteType routeType, int metric = 0, bool record = true)
|
||||
{
|
||||
#region
|
||||
|
||||
if (!TryParseIPNetwork(ipNetwork, out var ip, out var cidr))
|
||||
return false;
|
||||
|
||||
IAdapter adapter = routeType switch
|
||||
{
|
||||
RouteType.Outbound => _outboundAdapter,
|
||||
RouteType.TUNTAP => _tunAdapter,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
|
||||
};
|
||||
|
||||
List<string> ipList = routeType switch
|
||||
{
|
||||
RouteType.Outbound => _directIPs,
|
||||
RouteType.TUNTAP => _proxyIPs,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
|
||||
};
|
||||
|
||||
string gateway = adapter.Gateway.ToString();
|
||||
var index = adapter.InterfaceIndex;
|
||||
|
||||
#endregion
|
||||
|
||||
bool result;
|
||||
switch (action)
|
||||
{
|
||||
case Action.Create:
|
||||
result = NativeMethods.CreateRoute((int) AddressFamily.InterNetwork, ip, cidr, gateway, index, metric);
|
||||
if (result && record)
|
||||
ipList.Add(ipNetwork);
|
||||
|
||||
break;
|
||||
case Action.Delete:
|
||||
result = NativeMethods.DeleteRoute((int) AddressFamily.InterNetwork, ip, cidr, gateway, index, metric);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(action), action, null);
|
||||
}
|
||||
|
||||
Global.Logger.Debug($"{action}Route(\"{ip}\", {cidr}, \"{gateway}\", {index}, {metric})");
|
||||
if (!result)
|
||||
Global.Logger.Warning($"Failed to invoke {action}Route(\"{ip}\", {cidr}, \"{gateway}\", {index}, {metric})");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TryParseIPNetwork(string ipNetwork, out string ip, out int cidr)
|
||||
{
|
||||
ip = null!;
|
||||
cidr = 0;
|
||||
|
||||
var s = ipNetwork.Split('/');
|
||||
if (s.Length != 2)
|
||||
{
|
||||
Global.Logger.Warning($"Failed to parse rule {ipNetwork}");
|
||||
return false;
|
||||
}
|
||||
|
||||
ip = s[0];
|
||||
cidr = int.Parse(s[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
private enum RouteType
|
||||
{
|
||||
Outbound,
|
||||
TUNTAP
|
||||
}
|
||||
|
||||
private enum Action
|
||||
{
|
||||
Create,
|
||||
Delete
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNTAPController : Guard, IModeController
|
||||
{
|
||||
private readonly List<string> _directIPs = new();
|
||||
|
||||
private readonly List<string> _proxyIPs = new();
|
||||
/// <summary>
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
private IPAddress _serverAddresses = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 本地 DNS 服务控制器
|
||||
/// </summary>
|
||||
public DNSController DNSController = new();
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"Running"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"failed", "invalid vconfig file"};
|
||||
|
||||
public override string MainFile { get; protected set; } = "tun2socks.exe";
|
||||
|
||||
protected override Encoding InstanceOutputEncoding { get; } = Encoding.UTF8;
|
||||
|
||||
public override string Name { get; } = "tun2socks";
|
||||
|
||||
private readonly OutboundAdapter _outbound = new();
|
||||
private TapAdapter _tap = null!;
|
||||
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
var server = MainController.Server!;
|
||||
_serverAddresses = DnsUtils.Lookup(server.Hostname)!; // server address have been cached when MainController.Start
|
||||
|
||||
if (TUNTAP.GetComponentID() == null)
|
||||
TUNTAP.AddTap();
|
||||
|
||||
_tap = new TapAdapter();
|
||||
|
||||
List<string> dns;
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
{
|
||||
dns = Global.Settings.TUNTAP.DNS.Any() ? Global.Settings.TUNTAP.DNS : Global.Settings.TUNTAP.DNS = new List<string> {"1.1.1.1"};
|
||||
}
|
||||
else
|
||||
{
|
||||
MainController.PortCheck(53, "DNS");
|
||||
DNSController.Start();
|
||||
dns = new List<string> {"127.0.0.1"};
|
||||
}
|
||||
|
||||
SetupRouteTable(mode);
|
||||
|
||||
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", Name));
|
||||
|
||||
var argument = new StringBuilder();
|
||||
if (server is Socks5 socks5 && !socks5.Auth())
|
||||
argument.Append($"-proxyServer {server.AutoResolveHostname()}:{server.Port} ");
|
||||
else
|
||||
argument.Append($"-proxyServer 127.0.0.1:{Global.Settings.Socks5LocalPort} ");
|
||||
|
||||
argument.Append(
|
||||
$"-tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {DnsUtils.Join(dns)} -tunName \"{TUNTAP.GetName(_tap.ComponentID)}\" ");
|
||||
|
||||
if (Global.Settings.TUNTAP.UseFakeDNS && Global.Flags.SupportFakeDns)
|
||||
argument.Append("-fakeDns ");
|
||||
|
||||
StartInstanceAuto(argument.ToString(), ProcessPriorityClass.RealTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
Task.Run(StopInstance),
|
||||
Task.Run(ClearRouteTable),
|
||||
Task.Run(DNSController.Stop)
|
||||
};
|
||||
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置绕行规则
|
||||
/// </summary>
|
||||
/// <returns>是否设置成功</returns>
|
||||
private void SetupRouteTable(Mode mode)
|
||||
{
|
||||
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
|
||||
Logging.Info("设置路由规则");
|
||||
|
||||
#region Rule IPs
|
||||
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 1:
|
||||
// 代理规则 IP
|
||||
Logging.Info("代理 → 规则 IP");
|
||||
RouteAction(Action.Create, mode.FullRule, RouteType.TUNTAP);
|
||||
|
||||
if (Global.Settings.TUNTAP.ProxyDNS)
|
||||
{
|
||||
Logging.Info("代理 → 自定义 DNS");
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
RouteAction(Action.Create, Global.Settings.TUNTAP.DNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP);
|
||||
else
|
||||
RouteAction(Action.Create, $"{Global.Settings.AioDNS.OtherDNS}/32", RouteType.TUNTAP);
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
// 绕过规则 IP
|
||||
|
||||
// 将 TUN/TAP 网卡权重放到最高
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "netsh",
|
||||
Arguments = $"interface ip set interface {_tap.Index} metric=0",
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = true,
|
||||
CreateNoWindow = true
|
||||
});
|
||||
|
||||
Logging.Info("绕行 → 规则 IP");
|
||||
RouteAction(Action.Create, mode.FullRule, RouteType.Outbound);
|
||||
break;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Logging.Info("绕行 → 服务器 IP");
|
||||
if (!IPAddress.IsLoopback(_serverAddresses))
|
||||
RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound);
|
||||
|
||||
Logging.Info("绕行 → 全局绕过 IP");
|
||||
RouteAction(Action.Create, Global.Settings.BypassIPs, RouteType.Outbound);
|
||||
|
||||
if (mode.Type == 2)
|
||||
{
|
||||
Logging.Info("代理 → 全局");
|
||||
RouteAction(Action.Create, "0.0.0.0/0", RouteType.TUNTAP);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除绕行规则
|
||||
/// </summary>
|
||||
private bool ClearRouteTable()
|
||||
{
|
||||
RouteAction(Action.Delete, _directIPs, RouteType.Outbound);
|
||||
RouteAction(Action.Delete, _proxyIPs, RouteType.TUNTAP);
|
||||
_directIPs.Clear();
|
||||
_proxyIPs.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TestFakeDNS()
|
||||
{
|
||||
try
|
||||
{
|
||||
InitInstance("-h");
|
||||
Instance!.Start();
|
||||
return Instance.StandardError.ReadToEnd().Contains("-fakeDns");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RouteAction(Action action, in IEnumerable<string> ipNetworks, RouteType routeType, int metric = 0)
|
||||
{
|
||||
foreach (var address in ipNetworks)
|
||||
RouteAction(action, address, routeType, metric);
|
||||
}
|
||||
|
||||
private bool RouteAction(Action action, in string ipNetwork, RouteType routeType, int metric = 0)
|
||||
{
|
||||
var s = ipNetwork.Split('/');
|
||||
if (s.Length != 2)
|
||||
{
|
||||
Logging.Warning($"Failed to parse rule {ipNetwork}");
|
||||
return false;
|
||||
}
|
||||
|
||||
IAdapter adapter;
|
||||
List<string> ipList;
|
||||
|
||||
switch (routeType)
|
||||
{
|
||||
case RouteType.TUNTAP:
|
||||
adapter = _tap;
|
||||
ipList = _proxyIPs;
|
||||
break;
|
||||
case RouteType.Outbound:
|
||||
adapter = _outbound;
|
||||
ipList = _directIPs;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null);
|
||||
}
|
||||
|
||||
string network = s[0];
|
||||
var cidr = ushort.Parse(s[1]);
|
||||
string gateway = adapter.Gateway.ToString();
|
||||
var index = adapter.Index;
|
||||
|
||||
bool result;
|
||||
switch (action)
|
||||
{
|
||||
case Action.Create:
|
||||
result = NativeMethods.CreateRoute(network, cidr, gateway, index, metric);
|
||||
ipList.Add(ipNetwork);
|
||||
break;
|
||||
case Action.Delete:
|
||||
result = NativeMethods.DeleteRoute(network, cidr, gateway, index, metric);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(action), action, null);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
Logging.Warning($"Failed to {action} Route on {routeType} Adapter: {ipNetwork} metric {metric}");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private enum RouteType
|
||||
{
|
||||
Outbound,
|
||||
TUNTAP
|
||||
}
|
||||
|
||||
private enum Action
|
||||
{
|
||||
Create,
|
||||
Delete
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -19,7 +20,7 @@ namespace Netch.Controllers
|
||||
public const string Copyright = @"Copyright © 2019 - 2021";
|
||||
|
||||
public const string AssemblyVersion = @"1.8.3";
|
||||
private const string Suffix = @"Beta1";
|
||||
private const string Suffix = @"Beta114514";
|
||||
|
||||
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";
|
||||
|
||||
@@ -46,24 +47,24 @@ namespace Netch.Controllers
|
||||
|
||||
var releases = JsonSerializer.Deserialize<List<Release>>(json)!;
|
||||
LatestRelease = VersionUtil.GetLatestRelease(releases, isPreRelease);
|
||||
Logging.Info($"Github 最新发布版本: {LatestRelease.tag_name}");
|
||||
Global.Logger.Info($"Github 最新发布版本: {LatestRelease.tag_name}");
|
||||
if (VersionUtil.CompareVersion(LatestRelease.tag_name, Version) > 0)
|
||||
{
|
||||
Logging.Info("发现新版本");
|
||||
Global.Logger.Info("发现新版本");
|
||||
NewVersionFound?.Invoke(null, new EventArgs());
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Info("目前是最新版本");
|
||||
Global.Logger.Info("目前是最新版本");
|
||||
NewVersionNotFound?.Invoke(null, new EventArgs());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is WebException)
|
||||
Logging.Warning($"获取新版本失败: {e.Message}");
|
||||
Global.Logger.Warning($"获取新版本失败: {e.Message}");
|
||||
else
|
||||
Logging.Warning(e.ToString());
|
||||
Global.Logger.Warning(e.ToString());
|
||||
|
||||
NewVersionFoundFailed?.Invoke(null, new EventArgs());
|
||||
}
|
||||
@@ -89,5 +90,19 @@ namespace Netch.Controllers
|
||||
fileName = match.Groups["filename"].Value;
|
||||
sha256 = match.Groups["sha256"].Value;
|
||||
}
|
||||
|
||||
public static string GetLatestReleaseContent()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (string l in LatestRelease.body.GetLines(false).SkipWhile(l => l.FirstOrDefault() != '#'))
|
||||
{
|
||||
if (l.Contains("校验和"))
|
||||
break;
|
||||
|
||||
sb.AppendLine(l);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
Netch/Flags.cs
Normal file
11
Netch/Flags.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Netch
|
||||
{
|
||||
public static class Flags
|
||||
{
|
||||
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
|
||||
|
||||
public static bool AlwaysShowNewVersionFound { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Properties;
|
||||
@@ -18,7 +19,7 @@ namespace Netch.Forms
|
||||
{
|
||||
i18N.TranslateForm(this);
|
||||
|
||||
IPListBox.Items.AddRange(Global.Settings.BypassIPs.ToArray());
|
||||
IPListBox.Items.AddRange(Global.Settings.TUNTAP.BypassIPs.Cast<object>().ToArray());
|
||||
|
||||
for (var i = 32; i >= 1; i--)
|
||||
PrefixComboBox.Items.Add(i);
|
||||
@@ -31,7 +32,7 @@ namespace Netch.Forms
|
||||
if (!string.IsNullOrEmpty(IPTextBox.Text))
|
||||
{
|
||||
if (IPAddress.TryParse(IPTextBox.Text, out var address))
|
||||
IPListBox.Items.Add(string.Format("{0}/{1}", address, PrefixComboBox.SelectedItem));
|
||||
IPListBox.Items.Add($"{address}/{PrefixComboBox.SelectedItem}");
|
||||
else
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a correct IP address"));
|
||||
}
|
||||
@@ -51,9 +52,9 @@ namespace Netch.Forms
|
||||
|
||||
private void ControlButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Global.Settings.BypassIPs.Clear();
|
||||
Global.Settings.TUNTAP.BypassIPs.Clear();
|
||||
foreach (var ip in IPListBox.Items)
|
||||
Global.Settings.BypassIPs.Add((string) ip);
|
||||
Global.Settings.TUNTAP.BypassIPs.Add((string) ip);
|
||||
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
|
||||
6
Netch/Forms/LogForm.Designer.cs
generated
6
Netch/Forms/LogForm.Designer.cs
generated
@@ -40,7 +40,7 @@ namespace Netch.Forms
|
||||
this.richTextBox1.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.richTextBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.richTextBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.richTextBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.richTextBox1.Name = "richTextBox1";
|
||||
this.richTextBox1.ReadOnly = true;
|
||||
@@ -54,14 +54,14 @@ namespace Netch.Forms
|
||||
this.checkBox1.AutoSize = true;
|
||||
this.checkBox1.Location = new System.Drawing.Point(12, 297);
|
||||
this.checkBox1.Name = "checkBox1";
|
||||
this.checkBox1.Size = new System.Drawing.Size(102, 16);
|
||||
this.checkBox1.Size = new System.Drawing.Size(101, 21);
|
||||
this.checkBox1.TabIndex = 1;
|
||||
this.checkBox1.Text = "Scroll to End";
|
||||
this.checkBox1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// LogForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(454, 318);
|
||||
this.ControlBox = false;
|
||||
|
||||
@@ -16,13 +16,13 @@ namespace Netch.Forms
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
protected override void OnLoad(EventArgs? e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
Parent_Move(null!, null!);
|
||||
}
|
||||
|
||||
private void Parent_Move(object sender, EventArgs e)
|
||||
private void Parent_Move(object? sender, EventArgs? e)
|
||||
{
|
||||
var cl = Location;
|
||||
var fl = _parent.Location;
|
||||
@@ -32,7 +32,7 @@ namespace Netch.Forms
|
||||
Location = cl;
|
||||
}
|
||||
|
||||
private void Parent_Activated(object sender, EventArgs e)
|
||||
private void Parent_Activated(object? sender, EventArgs? e)
|
||||
{
|
||||
SetWindowPos(Handle,
|
||||
HWND.HWND_TOPMOST,
|
||||
@@ -51,7 +51,7 @@ namespace Netch.Forms
|
||||
SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_SHOWWINDOW);
|
||||
}
|
||||
|
||||
private void richTextBox1_TextChanged(object sender, System.EventArgs e)
|
||||
private void richTextBox1_TextChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
if (!checkBox1.Checked)
|
||||
return;
|
||||
@@ -60,19 +60,19 @@ namespace Netch.Forms
|
||||
richTextBox1.ScrollToCaret();
|
||||
}
|
||||
|
||||
private void Notifycation_Load(object sender, EventArgs e)
|
||||
private void Notifycation_Load(object? sender, EventArgs? e)
|
||||
{
|
||||
_parent.LocationChanged += Parent_Move;
|
||||
_parent.SizeChanged += Parent_Move;
|
||||
_parent.Activated += Parent_Activated;
|
||||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
protected override void OnClosing(CancelEventArgs? e)
|
||||
{
|
||||
_parent.Activated -= Parent_Activated;
|
||||
_parent.LocationChanged -= Parent_Move;
|
||||
_parent.SizeChanged -= Parent_Move;
|
||||
base.OnClosing(e);
|
||||
base.OnClosing(e!);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Netch/Forms/LogForm.resx
Normal file
60
Netch/Forms/LogForm.resx
Normal file
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
162
Netch/Forms/MainForm.Designer.cs
generated
162
Netch/Forms/MainForm.Designer.cs
generated
@@ -29,26 +29,19 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
this.MenuStrip = new System.Windows.Forms.MenuStrip();
|
||||
this.ServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ImportServersFromClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CreateProcessModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CreateRouteTableRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ReloadModesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SubscribeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ManageSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.OptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.OpenDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CleanDNSCacheToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UpdateACLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.updateACLWithProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.updatePACToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallTapDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.removeNetchFirewallRulesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.HelpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CheckForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -63,7 +56,7 @@
|
||||
this.ModeLabel = new System.Windows.Forms.Label();
|
||||
this.ServerLabel = new System.Windows.Forms.Label();
|
||||
this.ProfileNameText = new System.Windows.Forms.TextBox();
|
||||
this.ModeComboBox = new System.Windows.Forms.SearchComboBox();
|
||||
this.ModeComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.ServerComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.EditServerPictureBox = new System.Windows.Forms.PictureBox();
|
||||
@@ -95,13 +88,13 @@
|
||||
this.ConfigurationGroupBox.SuspendLayout();
|
||||
this.configLayoutPanel.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize) (this.EditServerPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.CopyLinkPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.DeleteServerPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.SpeedPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditServerPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.CopyLinkPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeleteServerPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.SpeedPictureBox)).BeginInit();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize) (this.EditModePictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.DeleteModePictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditModePictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeleteModePictureBox)).BeginInit();
|
||||
this.StatusStrip.SuspendLayout();
|
||||
this.NotifyMenu.SuspendLayout();
|
||||
this.ProfileGroupBox.SuspendLayout();
|
||||
@@ -113,10 +106,16 @@
|
||||
//
|
||||
this.MenuStrip.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.MenuStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.ServerToolStripMenuItem, this.ModeToolStripMenuItem, this.SubscribeToolStripMenuItem, this.OptionsToolStripMenuItem, this.HelpToolStripMenuItem, this.exitToolStripMenuItem, this.AboutToolStripButton, this.NewVersionLabel, this.VersionLabel
|
||||
});
|
||||
this.MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ServerToolStripMenuItem,
|
||||
this.ModeToolStripMenuItem,
|
||||
this.SubscribeToolStripMenuItem,
|
||||
this.OptionsToolStripMenuItem,
|
||||
this.HelpToolStripMenuItem,
|
||||
this.exitToolStripMenuItem,
|
||||
this.AboutToolStripButton,
|
||||
this.NewVersionLabel,
|
||||
this.VersionLabel});
|
||||
this.MenuStrip.Location = new System.Drawing.Point(0, 0);
|
||||
this.MenuStrip.Name = "MenuStrip";
|
||||
this.MenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
|
||||
@@ -125,10 +124,8 @@
|
||||
//
|
||||
// ServerToolStripMenuItem
|
||||
//
|
||||
this.ServerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.ImportServersFromClipboardToolStripMenuItem
|
||||
});
|
||||
this.ServerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ImportServersFromClipboardToolStripMenuItem});
|
||||
this.ServerToolStripMenuItem.Margin = new System.Windows.Forms.Padding(3, 0, 0, 1);
|
||||
this.ServerToolStripMenuItem.Name = "ServerToolStripMenuItem";
|
||||
this.ServerToolStripMenuItem.Size = new System.Drawing.Size(57, 21);
|
||||
@@ -143,7 +140,9 @@
|
||||
//
|
||||
// ModeToolStripMenuItem
|
||||
//
|
||||
this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.CreateProcessModeToolStripMenuItem, this.CreateRouteTableRuleToolStripMenuItem, this.ReloadModesToolStripMenuItem});
|
||||
this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.CreateProcessModeToolStripMenuItem,
|
||||
this.CreateRouteTableRuleToolStripMenuItem});
|
||||
this.ModeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.ModeToolStripMenuItem.Name = "ModeToolStripMenuItem";
|
||||
this.ModeToolStripMenuItem.Size = new System.Drawing.Size(55, 21);
|
||||
@@ -163,19 +162,11 @@
|
||||
this.CreateRouteTableRuleToolStripMenuItem.Text = "Create Route Table Rule";
|
||||
this.CreateRouteTableRuleToolStripMenuItem.Click += new System.EventHandler(this.createRouteTableModeToolStripMenuItem_Click);
|
||||
//
|
||||
// ReloadModesToolStripMenuItem
|
||||
//
|
||||
this.ReloadModesToolStripMenuItem.Name = "ReloadModesToolStripMenuItem";
|
||||
this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
|
||||
this.ReloadModesToolStripMenuItem.Text = "Reload Modes";
|
||||
this.ReloadModesToolStripMenuItem.Click += new System.EventHandler(this.ReloadModesToolStripMenuItem_Click);
|
||||
//
|
||||
// SubscribeToolStripMenuItem
|
||||
//
|
||||
this.SubscribeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.ManageSubscribeLinksToolStripMenuItem, this.UpdateServersFromSubscribeLinksToolStripMenuItem, this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem
|
||||
});
|
||||
this.SubscribeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ManageSubscribeLinksToolStripMenuItem,
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem});
|
||||
this.SubscribeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.SubscribeToolStripMenuItem.Name = "SubscribeToolStripMenuItem";
|
||||
this.SubscribeToolStripMenuItem.Size = new System.Drawing.Size(77, 21);
|
||||
@@ -184,30 +175,24 @@
|
||||
// ManageSubscribeLinksToolStripMenuItem
|
||||
//
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Name = "ManageSubscribeLinksToolStripMenuItem";
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(360, 22);
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(294, 22);
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Text = "Manage Subscribe Links";
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Click += new System.EventHandler(this.ManageSubscribeLinksToolStripMenuItem_Click);
|
||||
//
|
||||
// UpdateServersFromSubscribeLinksToolStripMenuItem
|
||||
//
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Name = "UpdateServersFromSubscribeLinksToolStripMenuItem";
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(360, 22);
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(294, 22);
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Text = "Update Servers From Subscribe Links";
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Click += new System.EventHandler(this.UpdateServersFromSubscribeLinksToolStripMenuItem_Click);
|
||||
//
|
||||
// UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem
|
||||
//
|
||||
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Name = "UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem";
|
||||
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Size = new System.Drawing.Size(360, 22);
|
||||
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Text = "Update Servers From Subscribe Links With Proxy";
|
||||
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Click += new System.EventHandler(this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem_Click);
|
||||
//
|
||||
// OptionsToolStripMenuItem
|
||||
//
|
||||
this.OptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.OpenDirectoryToolStripMenuItem, this.CleanDNSCacheToolStripMenuItem, this.UpdateACLToolStripMenuItem, this.updateACLWithProxyToolStripMenuItem, this.updatePACToolStripMenuItem, this.UninstallServiceToolStripMenuItem, this.UninstallTapDriverToolStripMenuItem, this.removeNetchFirewallRulesToolStripMenuItem
|
||||
});
|
||||
this.OptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.OpenDirectoryToolStripMenuItem,
|
||||
this.CleanDNSCacheToolStripMenuItem,
|
||||
this.UninstallServiceToolStripMenuItem,
|
||||
this.removeNetchFirewallRulesToolStripMenuItem});
|
||||
this.OptionsToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.OptionsToolStripMenuItem.Name = "OptionsToolStripMenuItem";
|
||||
this.OptionsToolStripMenuItem.Size = new System.Drawing.Size(66, 21);
|
||||
@@ -227,27 +212,6 @@
|
||||
this.CleanDNSCacheToolStripMenuItem.Text = "Clean DNS Cache";
|
||||
this.CleanDNSCacheToolStripMenuItem.Click += new System.EventHandler(this.CleanDNSCacheToolStripMenuItem_Click);
|
||||
//
|
||||
// UpdateACLToolStripMenuItem
|
||||
//
|
||||
this.UpdateACLToolStripMenuItem.Name = "UpdateACLToolStripMenuItem";
|
||||
this.UpdateACLToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.UpdateACLToolStripMenuItem.Text = "Update ACL";
|
||||
this.UpdateACLToolStripMenuItem.Click += new System.EventHandler(this.updateACLToolStripMenuItem_Click);
|
||||
//
|
||||
// updateACLWithProxyToolStripMenuItem
|
||||
//
|
||||
this.updateACLWithProxyToolStripMenuItem.Name = "updateACLWithProxyToolStripMenuItem";
|
||||
this.updateACLWithProxyToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.updateACLWithProxyToolStripMenuItem.Text = "Update ACL with proxy";
|
||||
this.updateACLWithProxyToolStripMenuItem.Click += new System.EventHandler(this.updateACLWithProxyToolStripMenuItem_Click);
|
||||
//
|
||||
// updatePACToolStripMenuItem
|
||||
//
|
||||
this.updatePACToolStripMenuItem.Name = "updatePACToolStripMenuItem";
|
||||
this.updatePACToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.updatePACToolStripMenuItem.Text = "Update PAC";
|
||||
this.updatePACToolStripMenuItem.Click += new System.EventHandler(this.updatePACToolStripMenuItem_Click);
|
||||
//
|
||||
// UninstallServiceToolStripMenuItem
|
||||
//
|
||||
this.UninstallServiceToolStripMenuItem.Name = "UninstallServiceToolStripMenuItem";
|
||||
@@ -255,13 +219,6 @@
|
||||
this.UninstallServiceToolStripMenuItem.Text = "Uninstall NF Service";
|
||||
this.UninstallServiceToolStripMenuItem.Click += new System.EventHandler(this.UninstallServiceToolStripMenuItem_Click);
|
||||
//
|
||||
// UninstallTapDriverToolStripMenuItem
|
||||
//
|
||||
this.UninstallTapDriverToolStripMenuItem.Name = "UninstallTapDriverToolStripMenuItem";
|
||||
this.UninstallTapDriverToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.UninstallTapDriverToolStripMenuItem.Text = "Uninstall TUN/TAP driver";
|
||||
this.UninstallTapDriverToolStripMenuItem.Click += new System.EventHandler(this.UninstallTapDriverToolStripMenuItem_Click);
|
||||
//
|
||||
// removeNetchFirewallRulesToolStripMenuItem
|
||||
//
|
||||
this.removeNetchFirewallRulesToolStripMenuItem.Name = "removeNetchFirewallRulesToolStripMenuItem";
|
||||
@@ -271,10 +228,9 @@
|
||||
//
|
||||
// HelpToolStripMenuItem
|
||||
//
|
||||
this.HelpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.CheckForUpdatesToolStripMenuItem, this.fAQToolStripMenuItem
|
||||
});
|
||||
this.HelpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.CheckForUpdatesToolStripMenuItem,
|
||||
this.fAQToolStripMenuItem});
|
||||
this.HelpToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.HelpToolStripMenuItem.Name = "HelpToolStripMenuItem";
|
||||
this.HelpToolStripMenuItem.Size = new System.Drawing.Size(47, 21);
|
||||
@@ -413,9 +369,9 @@
|
||||
//
|
||||
// ModeComboBox
|
||||
//
|
||||
this.ModeComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
|
||||
this.ModeComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ModeComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
|
||||
this.ModeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.ModeComboBox.FormattingEnabled = true;
|
||||
this.ModeComboBox.IntegralHeight = false;
|
||||
this.ModeComboBox.Location = new System.Drawing.Point(54, 33);
|
||||
@@ -550,10 +506,14 @@
|
||||
// StatusStrip
|
||||
//
|
||||
this.StatusStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.StatusLabel, this.UsedBandwidthLabel, this.DownloadSpeedLabel, this.UploadSpeedLabel, this.blankToolStripStatusLabel, this.NatTypeStatusLabel, this.NatTypeStatusLightLabel
|
||||
});
|
||||
this.StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.StatusLabel,
|
||||
this.UsedBandwidthLabel,
|
||||
this.DownloadSpeedLabel,
|
||||
this.UploadSpeedLabel,
|
||||
this.blankToolStripStatusLabel,
|
||||
this.NatTypeStatusLabel,
|
||||
this.NatTypeStatusLightLabel});
|
||||
this.StatusStrip.Location = new System.Drawing.Point(0, 272);
|
||||
this.StatusStrip.Name = "StatusStrip";
|
||||
this.StatusStrip.Size = new System.Drawing.Size(740, 22);
|
||||
@@ -616,7 +576,7 @@
|
||||
//
|
||||
// ControlButton
|
||||
//
|
||||
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.ControlButton.Location = new System.Drawing.Point(631, 3);
|
||||
this.ControlButton.Name = "ControlButton";
|
||||
this.ControlButton.Size = new System.Drawing.Size(75, 27);
|
||||
@@ -635,10 +595,9 @@
|
||||
// NotifyMenu
|
||||
//
|
||||
this.NotifyMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.NotifyMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.ShowMainFormToolStripButton, this.ExitToolStripButton
|
||||
});
|
||||
this.NotifyMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ShowMainFormToolStripButton,
|
||||
this.ExitToolStripButton});
|
||||
this.NotifyMenu.Name = "NotifyMenu";
|
||||
this.NotifyMenu.ShowItemToolTips = false;
|
||||
this.NotifyMenu.Size = new System.Drawing.Size(108, 48);
|
||||
@@ -659,7 +618,7 @@
|
||||
//
|
||||
// SettingsButton
|
||||
//
|
||||
this.SettingsButton.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.SettingsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.SettingsButton.Location = new System.Drawing.Point(1, 3);
|
||||
this.SettingsButton.Name = "SettingsButton";
|
||||
this.SettingsButton.Size = new System.Drawing.Size(72, 27);
|
||||
@@ -728,7 +687,7 @@
|
||||
this.Controls.Add(this.MenuStrip);
|
||||
this.Controls.Add(this.StatusStrip);
|
||||
this.Controls.Add(this.flowLayoutPanel1);
|
||||
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);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.MaximizeBox = false;
|
||||
@@ -744,13 +703,13 @@
|
||||
this.configLayoutPanel.ResumeLayout(false);
|
||||
this.configLayoutPanel.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize) (this.EditServerPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.CopyLinkPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.DeleteServerPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.SpeedPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditServerPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.CopyLinkPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeleteServerPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.SpeedPictureBox)).EndInit();
|
||||
this.tableLayoutPanel3.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize) (this.EditModePictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.DeleteModePictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditModePictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeleteModePictureBox)).EndInit();
|
||||
this.StatusStrip.ResumeLayout(false);
|
||||
this.StatusStrip.PerformLayout();
|
||||
this.NotifyMenu.ResumeLayout(false);
|
||||
@@ -760,6 +719,7 @@
|
||||
this.ButtomControlContainerControl.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
private System.Windows.Forms.ToolStripMenuItem CreateRouteTableRuleToolStripMenuItem;
|
||||
@@ -783,7 +743,7 @@
|
||||
private System.Windows.Forms.ToolStripMenuItem ImportServersFromClipboardToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ManageSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.MenuStrip MenuStrip;
|
||||
private System.Windows.Forms.SearchComboBox ModeComboBox;
|
||||
private System.Windows.Forms.ComboBox ModeComboBox;
|
||||
private System.Windows.Forms.Label ModeLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem ModeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem HelpToolStripMenuItem;
|
||||
@@ -796,9 +756,7 @@
|
||||
private System.Windows.Forms.Label ProfileLabel;
|
||||
private System.Windows.Forms.TextBox ProfileNameText;
|
||||
private System.Windows.Forms.TableLayoutPanel ProfileTable;
|
||||
private System.Windows.Forms.ToolStripMenuItem UninstallTapDriverToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem CheckForUpdatesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ReloadModesToolStripMenuItem;
|
||||
private System.Windows.Forms.ComboBox ServerComboBox;
|
||||
private System.Windows.Forms.Label ServerLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem ServerToolStripMenuItem;
|
||||
@@ -811,10 +769,7 @@
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
|
||||
private System.Windows.Forms.ToolStripMenuItem UninstallServiceToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateACLToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem updateACLWithProxyToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UploadSpeedLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UsedBandwidthLabel;
|
||||
private System.Windows.Forms.ToolStripLabel NewVersionLabel;
|
||||
@@ -827,6 +782,5 @@
|
||||
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
||||
private System.Windows.Forms.ContainerControl ButtomControlContainerControl;
|
||||
private System.Windows.Forms.ToolStripMenuItem updatePACToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
@@ -42,25 +42,12 @@ namespace Netch.Forms
|
||||
#region i18N Translations
|
||||
|
||||
_mainFormText.Add(UninstallServiceToolStripMenuItem.Name, new[] {"Uninstall {0}", "NF Service"});
|
||||
_mainFormText.Add(UninstallTapDriverToolStripMenuItem.Name, new[] {"Uninstall {0}", "TUN/TAP driver"});
|
||||
|
||||
#endregion
|
||||
|
||||
// 监听电源事件
|
||||
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
||||
|
||||
ModeComboBox.KeyUp += (_, args) =>
|
||||
{
|
||||
switch (args.KeyData)
|
||||
{
|
||||
case Keys.Escape:
|
||||
{
|
||||
SelectLastMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CheckForIllegalCrossThreadCalls = false;
|
||||
}
|
||||
|
||||
@@ -84,8 +71,6 @@ namespace Netch.Forms
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Netch.TimePoint("MainForm ctor (Pre MainForm Load)");
|
||||
|
||||
// 计算 ComboBox绘制 目标宽度
|
||||
RecordSize();
|
||||
|
||||
@@ -115,14 +100,12 @@ namespace Netch.Forms
|
||||
{
|
||||
// 检查订阅更新
|
||||
if (Global.Settings.UpdateServersWhenOpened)
|
||||
UpdateServersFromSubscribe(Global.Settings.UseProxyToUpdateSubscription).Wait();
|
||||
UpdateServersFromSubscribe().Wait();
|
||||
|
||||
// 打开软件时启动加速,产生开始按钮点击事件
|
||||
if (Global.Settings.StartWhenOpened)
|
||||
ControlButton_Click(null, null);
|
||||
});
|
||||
|
||||
Netch.TimePoint("Post Form Load", false);
|
||||
}
|
||||
|
||||
private void RecordSize()
|
||||
@@ -239,8 +222,12 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private void AddServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private void AddServerToolStripMenuItem_Click([NotNull] object? sender, EventArgs? e)
|
||||
{
|
||||
if (sender == null)
|
||||
throw new ArgumentNullException(nameof(sender));
|
||||
|
||||
// TODO get Util from Tag
|
||||
var s = ((ToolStripMenuItem) sender).Text;
|
||||
|
||||
var start = s.IndexOf("[", StringComparison.Ordinal) + 1;
|
||||
@@ -266,25 +253,6 @@ namespace Netch.Forms
|
||||
Show();
|
||||
}
|
||||
|
||||
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
try
|
||||
{
|
||||
ModeHelper.Load();
|
||||
LoadModes();
|
||||
NotifyTip(i18N.Translate("Modes have been reload"));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
finally
|
||||
{
|
||||
Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Subscription
|
||||
@@ -299,33 +267,16 @@ namespace Netch.Forms
|
||||
|
||||
private async void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Global.Settings.UseProxyToUpdateSubscription = false;
|
||||
await UpdateServersFromSubscribe();
|
||||
}
|
||||
|
||||
private async void UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Global.Settings.UseProxyToUpdateSubscription = true;
|
||||
await UpdateServersFromSubscribe(true);
|
||||
}
|
||||
|
||||
private async Task UpdateServersFromSubscribe(bool useProxy = false)
|
||||
private async Task UpdateServersFromSubscribe()
|
||||
{
|
||||
void DisableItems(bool v)
|
||||
{
|
||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ProfileGroupBox.Enabled = ControlButton.Enabled = v;
|
||||
}
|
||||
|
||||
var server = ServerComboBox.SelectedItem as Server;
|
||||
if (useProxy)
|
||||
{
|
||||
if (server == null)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a server first"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Global.Settings.SubscribeLink.Count <= 0)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("No subscription link"));
|
||||
@@ -334,22 +285,10 @@ namespace Netch.Forms
|
||||
|
||||
StatusText(i18N.Translate("Starting update subscription"));
|
||||
DisableItems(false);
|
||||
|
||||
try
|
||||
{
|
||||
string? proxyServer = null;
|
||||
if (useProxy)
|
||||
{
|
||||
var mode = new Models.Mode
|
||||
{
|
||||
Remark = "ProxyUpdate",
|
||||
Type = 5
|
||||
};
|
||||
|
||||
await MainController.StartAsync(server!, mode);
|
||||
proxyServer = $"http://127.0.0.1:{Global.Settings.HTTPLocalPort}";
|
||||
}
|
||||
|
||||
await Subscription.UpdateServersAsync(proxyServer);
|
||||
await Subscription.UpdateServersAsync();
|
||||
|
||||
LoadServers();
|
||||
Configuration.Save();
|
||||
@@ -358,13 +297,10 @@ namespace Netch.Forms
|
||||
catch (Exception e)
|
||||
{
|
||||
NotifyTip(i18N.Translate("update servers failed") + "\n" + e.Message, info: false);
|
||||
Logging.Error("更新服务器 失败!" + e);
|
||||
Global.Logger.Error("更新服务器 失败!" + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (useProxy)
|
||||
await MainController.StopAsync();
|
||||
|
||||
DisableItems(true);
|
||||
}
|
||||
}
|
||||
@@ -377,12 +313,12 @@ namespace Netch.Forms
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
void OnNewVersionNotFound(object o, EventArgs args)
|
||||
void OnNewVersionNotFound(object? o, EventArgs? args)
|
||||
{
|
||||
NotifyTip(i18N.Translate("Already latest version"));
|
||||
}
|
||||
|
||||
void OnNewVersionFoundFailed(object o, EventArgs args)
|
||||
void OnNewVersionFoundFailed(object? o, EventArgs? args)
|
||||
{
|
||||
NotifyTip(i18N.Translate("New version found failed"), info: false);
|
||||
}
|
||||
@@ -428,90 +364,6 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
UpdateACL(true);
|
||||
}
|
||||
|
||||
private void updateACLToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
UpdateACL(false);
|
||||
}
|
||||
|
||||
private async void UpdateACL(bool useProxy)
|
||||
{
|
||||
Enabled = false;
|
||||
StatusText(i18N.TranslateFormat("Updating {0}", "ACL"));
|
||||
try
|
||||
{
|
||||
if (useProxy)
|
||||
{
|
||||
if (!(ServerComboBox.SelectedItem is Server server))
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a server first"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
var mode = new Models.Mode
|
||||
{
|
||||
Remark = "ProxyUpdate",
|
||||
Type = 5
|
||||
};
|
||||
|
||||
await MainController.StartAsync(server, mode);
|
||||
}
|
||||
}
|
||||
|
||||
var req = WebUtil.CreateRequest(Global.Settings.ACL);
|
||||
if (useProxy)
|
||||
req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
|
||||
|
||||
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, Global.UserACL));
|
||||
NotifyTip(i18N.Translate("ACL updated successfully"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false);
|
||||
Logging.Error("更新 ACL 失败!" + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (useProxy)
|
||||
await MainController.StopAsync();
|
||||
|
||||
StatusText();
|
||||
Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async void updatePACToolStripMenuItem_Click(object sender, EventArgs eventArgs)
|
||||
{
|
||||
Enabled = false;
|
||||
|
||||
StatusText(i18N.TranslateFormat("Updating {0}", "PAC"));
|
||||
try
|
||||
{
|
||||
var req = WebUtil.CreateRequest(Global.Settings.PAC);
|
||||
|
||||
var pac = Path.Combine(Global.NetchDir, "bin\\pac.txt");
|
||||
|
||||
await WebUtil.DownloadFileAsync(req, pac);
|
||||
|
||||
NotifyTip(i18N.Translate("PAC updated successfully"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
NotifyTip(i18N.Translate("PAC update failed") + "\n" + e.Message, info: false);
|
||||
Logging.Error("更新 PAC 失败!" + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
StatusText();
|
||||
Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
@@ -531,26 +383,6 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private async void UninstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
StatusText(i18N.TranslateFormat("Uninstalling {0}", "TUN/TAP driver"));
|
||||
try
|
||||
{
|
||||
await Task.Run(TUNTAP.deltapall);
|
||||
NotifyTip(i18N.TranslateFormat("{0} has been uninstalled", "TUN/TAP driver"));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logging.Error($"卸载 TUN/TAP 适配器失败: {exception}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
StatusText();
|
||||
Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveNetchFirewallRulesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Firewall.RemoveNetchFwRules();
|
||||
@@ -579,7 +411,8 @@ namespace Netch.Forms
|
||||
return;
|
||||
}
|
||||
|
||||
if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK)
|
||||
if (MessageBoxX.Show(i18N.Translate($"Download and install now?\n\n{UpdateChecker.GetLatestReleaseContent()}"), confirm: true) !=
|
||||
DialogResult.OK)
|
||||
return;
|
||||
|
||||
NotifyTip(i18N.Translate("Start downloading new version"));
|
||||
@@ -599,8 +432,8 @@ namespace Netch.Forms
|
||||
{
|
||||
if (exception is not MessageException)
|
||||
{
|
||||
Logging.Error($"更新失败: {exception}");
|
||||
Utils.Utils.Open(Logging.LogFile);
|
||||
Global.Logger.Error($"更新失败: {exception}");
|
||||
Global.Logger.ShowLog();
|
||||
}
|
||||
|
||||
NotifyTip(exception.Message, info: false);
|
||||
@@ -633,9 +466,7 @@ namespace Netch.Forms
|
||||
if (!IsWaiting())
|
||||
{
|
||||
// 停止
|
||||
State = State.Stopping;
|
||||
await MainController.StopAsync();
|
||||
State = State.Stopped;
|
||||
await StopAsyncCore();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -654,9 +485,6 @@ namespace Netch.Forms
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除模式搜索框文本选择
|
||||
ModeComboBox.Select(0, 0);
|
||||
|
||||
State = State.Starting;
|
||||
|
||||
try
|
||||
@@ -795,7 +623,7 @@ namespace Netch.Forms
|
||||
ServerHelper.DelayTestHelper.TestDelayFinished += OnTestDelayFinished;
|
||||
_ = Task.Run(ServerHelper.DelayTestHelper.TestAllDelay);
|
||||
|
||||
void OnTestDelayFinished(object o1, EventArgs e1)
|
||||
void OnTestDelayFinished(object? o1, EventArgs? e1)
|
||||
{
|
||||
Refresh();
|
||||
|
||||
@@ -1004,7 +832,6 @@ namespace Netch.Forms
|
||||
private void ActiveProfile(Profile profile)
|
||||
{
|
||||
ProfileNameText.Text = profile.ProfileName;
|
||||
ModeComboBox.ResetCompletionList();
|
||||
|
||||
var server = ServerComboBox.Items.Cast<Server>().FirstOrDefault(s => s.Remark.Equals(profile.ServerRemark));
|
||||
var mode = ModeComboBox.Items.Cast<Models.Mode>().FirstOrDefault(m => m.Remark.Equals(profile.ModeRemark));
|
||||
@@ -1034,8 +861,11 @@ namespace Netch.Forms
|
||||
return profile;
|
||||
}
|
||||
|
||||
private async void ProfileButton_Click(object sender, EventArgs e)
|
||||
private async void ProfileButton_Click([NotNull] object? sender, EventArgs? e)
|
||||
{
|
||||
if (sender == null)
|
||||
throw new ArgumentNullException(nameof(sender));
|
||||
|
||||
var profileButton = (Button) sender;
|
||||
var profile = (Profile?) profileButton.Tag;
|
||||
var index = ProfileTable.Controls.IndexOf(profileButton);
|
||||
@@ -1123,10 +953,7 @@ namespace Netch.Forms
|
||||
EditServerPictureBox.Enabled = DeleteModePictureBox.Enabled = DeleteServerPictureBox.Enabled = enabled;
|
||||
|
||||
// 启动需要禁用的控件
|
||||
UninstallServiceToolStripMenuItem.Enabled = UpdateACLToolStripMenuItem.Enabled = updateACLWithProxyToolStripMenuItem.Enabled =
|
||||
updatePACToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
|
||||
UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Enabled = UninstallTapDriverToolStripMenuItem.Enabled =
|
||||
ReloadModesToolStripMenuItem.Enabled = enabled;
|
||||
UninstallServiceToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = enabled;
|
||||
}
|
||||
|
||||
_state = value;
|
||||
@@ -1178,6 +1005,27 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StopAsyncCore()
|
||||
{
|
||||
State = State.Stopping;
|
||||
await MainController.StopAsync();
|
||||
State = State.Stopped;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (IsWaiting())
|
||||
return;
|
||||
|
||||
if (InvokeRequired)
|
||||
{
|
||||
Invoke(new Action(Stop));
|
||||
return;
|
||||
}
|
||||
|
||||
StopAsyncCore().Wait();
|
||||
}
|
||||
|
||||
private bool IsWaiting()
|
||||
{
|
||||
return State == State.Waiting || State == State.Stopped;
|
||||
@@ -1257,7 +1105,7 @@ namespace Netch.Forms
|
||||
{
|
||||
if (natType > 0 && natType < 5)
|
||||
{
|
||||
NatTypeStatusLightLabel.Visible = Global.Flags.IsWindows10Upper;
|
||||
NatTypeStatusLightLabel.Visible = Flags.IsWindows10Upper;
|
||||
var c = natType switch
|
||||
{
|
||||
1 => Color.LimeGreen,
|
||||
@@ -1330,7 +1178,7 @@ namespace Netch.Forms
|
||||
if (!IsWaiting())
|
||||
{
|
||||
_resumeFlag = true;
|
||||
Logging.Info("操作系统即将挂起,自动停止");
|
||||
Global.Logger.Info("操作系统即将挂起,自动停止");
|
||||
ControlButton_Click(null, null);
|
||||
}
|
||||
|
||||
@@ -1339,7 +1187,7 @@ namespace Netch.Forms
|
||||
if (_resumeFlag)
|
||||
{
|
||||
_resumeFlag = false;
|
||||
Logging.Info("操作系统即将从挂起状态继续,自动重启");
|
||||
Global.Logger.Info("操作系统即将从挂起状态继续,自动重启");
|
||||
ControlButton_Click(null, null);
|
||||
}
|
||||
|
||||
@@ -1387,8 +1235,8 @@ namespace Netch.Forms
|
||||
if (File.Exists(file))
|
||||
File.Delete(file);
|
||||
|
||||
if (!IsWaiting())
|
||||
await MainController.StopAsync();
|
||||
if (IsWaiting())
|
||||
await StopAsyncCore();
|
||||
|
||||
Dispose();
|
||||
Environment.Exit(Environment.ExitCode);
|
||||
@@ -1424,13 +1272,15 @@ namespace Netch.Forms
|
||||
{
|
||||
UpdateChecker.NewVersionFound += OnUpdateCheckerOnNewVersionFound;
|
||||
UpdateChecker.Check(Global.Settings.CheckBetaUpdate).Wait();
|
||||
if (Flags.AlwaysShowNewVersionFound)
|
||||
OnUpdateCheckerOnNewVersionFound(null!, null!);
|
||||
}
|
||||
finally
|
||||
{
|
||||
UpdateChecker.NewVersionFound -= OnUpdateCheckerOnNewVersionFound;
|
||||
}
|
||||
|
||||
void OnUpdateCheckerOnNewVersionFound(object o, EventArgs eventArgs)
|
||||
void OnUpdateCheckerOnNewVersionFound(object? o, EventArgs? eventArgs)
|
||||
{
|
||||
NotifyTip($"{i18N.Translate(@"New version available", ": ")}{UpdateChecker.LatestVersionNumber}");
|
||||
NewVersionLabel.Text = i18N.Translate("New version available");
|
||||
@@ -1481,8 +1331,14 @@ namespace Netch.Forms
|
||||
|
||||
#region NotifyIcon
|
||||
|
||||
private void ShowMainFormToolStripButton_Click(object sender, EventArgs e)
|
||||
public void ShowMainFormToolStripButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (InvokeRequired)
|
||||
{
|
||||
Invoke(new Action(() => ShowMainFormToolStripButton_Click(sender, e)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (WindowState == FormWindowState.Minimized)
|
||||
{
|
||||
Visible = true;
|
||||
@@ -1515,7 +1371,7 @@ namespace Netch.Forms
|
||||
|
||||
public void NotifyTip(string text, int timeout = 0, bool info = true)
|
||||
{
|
||||
// 会阻塞线程 timeout 秒
|
||||
// 会阻塞线程 timeout 秒(?)
|
||||
NotifyIcon.ShowBalloonTip(timeout, UpdateChecker.Name, text, info ? ToolTipIcon.Info : ToolTipIcon.Error);
|
||||
}
|
||||
|
||||
|
||||
60
Netch/Forms/MainForm.resx
Normal file
60
Netch/Forms/MainForm.resx
Normal file
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.WindowsAPICodePack.Dialogs;
|
||||
using Netch.Controllers;
|
||||
@@ -135,7 +134,6 @@ namespace Netch.Forms.Mode
|
||||
|
||||
var mode = new Models.Mode(fullName)
|
||||
{
|
||||
BypassChina = false,
|
||||
Type = 0,
|
||||
Remark = RemarkTextBox.Text
|
||||
};
|
||||
@@ -149,7 +147,7 @@ namespace Netch.Forms.Mode
|
||||
Close();
|
||||
}
|
||||
|
||||
private void RemarkTextBox_TextChanged(object sender, EventArgs e)
|
||||
private void RemarkTextBox_TextChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
BeginInvoke(new Action(() =>
|
||||
{
|
||||
@@ -195,7 +193,8 @@ namespace Netch.Forms.Mode
|
||||
foreach (string dir in Directory.GetDirectories(directory))
|
||||
ScanDirectory(dir, list, maxCount);
|
||||
|
||||
list.AddRange(Directory.GetFiles(directory).Select(Path.GetFileName).Where(s => s.EndsWith(".exe")).Select(s => s.ToRegexString()));
|
||||
list.AddRange(
|
||||
Directory.GetFiles(directory).Select(s => Path.GetFileName(s)).Where(s => s.EndsWith(".exe")).Select(s => s.ToRegexString()));
|
||||
|
||||
if (maxCount != 0 && list.Count > maxCount)
|
||||
throw new Exception("The number of results is greater than maxCount");
|
||||
@@ -203,7 +202,7 @@ namespace Netch.Forms.Mode
|
||||
|
||||
private void ValidationButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (NFController.CheckRules(Rules, out var results))
|
||||
if (!NFController.CheckRules(Rules, out var results))
|
||||
MessageBoxX.Show(NFController.GenerateInvalidRulesMessage(results), LogLevel.WARNING);
|
||||
else
|
||||
MessageBoxX.Show("Fine");
|
||||
|
||||
120
Netch/Forms/Mode/Process.resx
Normal file
120
Netch/Forms/Mode/Process.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
14
Netch/Forms/Mode/Route.Designer.cs
generated
14
Netch/Forms/Mode/Route.Designer.cs
generated
@@ -72,7 +72,7 @@ namespace Netch.Forms.Mode
|
||||
this.comboBox1.FormattingEnabled = true;
|
||||
this.comboBox1.Location = new System.Drawing.Point(84, 49);
|
||||
this.comboBox1.Name = "comboBox1";
|
||||
this.comboBox1.Size = new System.Drawing.Size(138, 20);
|
||||
this.comboBox1.Size = new System.Drawing.Size(138, 25);
|
||||
this.comboBox1.TabIndex = 11;
|
||||
//
|
||||
// FilenameLabel
|
||||
@@ -80,7 +80,7 @@ namespace Netch.Forms.Mode
|
||||
this.FilenameLabel.AutoSize = true;
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(12, 79);
|
||||
this.FilenameLabel.Name = "FilenameLabel";
|
||||
this.FilenameLabel.Size = new System.Drawing.Size(53, 12);
|
||||
this.FilenameLabel.Size = new System.Drawing.Size(59, 17);
|
||||
this.FilenameLabel.TabIndex = 6;
|
||||
this.FilenameLabel.Text = "Filename";
|
||||
//
|
||||
@@ -89,7 +89,7 @@ namespace Netch.Forms.Mode
|
||||
this.FilenameTextBox.Location = new System.Drawing.Point(84, 76);
|
||||
this.FilenameTextBox.Name = "FilenameTextBox";
|
||||
this.FilenameTextBox.ReadOnly = true;
|
||||
this.FilenameTextBox.Size = new System.Drawing.Size(250, 21);
|
||||
this.FilenameTextBox.Size = new System.Drawing.Size(250, 23);
|
||||
this.FilenameTextBox.TabIndex = 5;
|
||||
//
|
||||
// ActionLabel
|
||||
@@ -97,7 +97,7 @@ namespace Netch.Forms.Mode
|
||||
this.ActionLabel.AutoSize = true;
|
||||
this.ActionLabel.Location = new System.Drawing.Point(12, 52);
|
||||
this.ActionLabel.Name = "ActionLabel";
|
||||
this.ActionLabel.Size = new System.Drawing.Size(41, 12);
|
||||
this.ActionLabel.Size = new System.Drawing.Size(44, 17);
|
||||
this.ActionLabel.TabIndex = 0;
|
||||
this.ActionLabel.Text = "Action";
|
||||
//
|
||||
@@ -105,7 +105,7 @@ namespace Netch.Forms.Mode
|
||||
//
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(84, 22);
|
||||
this.RemarkTextBox.Name = "RemarkTextBox";
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(250, 21);
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(250, 23);
|
||||
this.RemarkTextBox.TabIndex = 1;
|
||||
this.RemarkTextBox.TextChanged += new System.EventHandler(this.RemarkTextBox_TextChanged);
|
||||
//
|
||||
@@ -114,7 +114,7 @@ namespace Netch.Forms.Mode
|
||||
this.RemarkLabel.AutoSize = true;
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(12, 25);
|
||||
this.RemarkLabel.Name = "RemarkLabel";
|
||||
this.RemarkLabel.Size = new System.Drawing.Size(41, 12);
|
||||
this.RemarkLabel.Size = new System.Drawing.Size(53, 17);
|
||||
this.RemarkLabel.TabIndex = 0;
|
||||
this.RemarkLabel.Text = "Remark";
|
||||
//
|
||||
@@ -161,7 +161,7 @@ namespace Netch.Forms.Mode
|
||||
//
|
||||
// Route
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(356, 419);
|
||||
this.Controls.Add(this.ConfigurationGroupBox);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
|
||||
@@ -8,26 +9,7 @@ namespace Netch.Forms.Mode
|
||||
{
|
||||
public partial class Route : Form
|
||||
{
|
||||
class Item
|
||||
{
|
||||
private string _text;
|
||||
|
||||
public Item(int value, string text)
|
||||
{
|
||||
_text = text;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => i18N.Translate(_text);
|
||||
set => _text = value;
|
||||
}
|
||||
|
||||
public int Value { get; set; }
|
||||
}
|
||||
|
||||
private readonly Item[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")};
|
||||
private readonly TagItem<int>[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")};
|
||||
|
||||
private readonly Models.Mode? _mode;
|
||||
|
||||
@@ -41,8 +23,8 @@ namespace Netch.Forms.Mode
|
||||
InitializeComponent();
|
||||
Icon = Resources.icon;
|
||||
comboBox1.DataSource = _items;
|
||||
comboBox1.ValueMember = "Value";
|
||||
comboBox1.DisplayMember = "Text";
|
||||
comboBox1.ValueMember = nameof(TagItem<int>.Value);
|
||||
comboBox1.DisplayMember = nameof(TagItem<int>.Text);
|
||||
}
|
||||
|
||||
private void Route_Load(object sender, EventArgs e)
|
||||
@@ -110,12 +92,9 @@ namespace Netch.Forms.Mode
|
||||
Close();
|
||||
}
|
||||
|
||||
private void RemarkTextBox_TextChanged(object sender, EventArgs e)
|
||||
private void RemarkTextBox_TextChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
BeginInvoke(new Action(() =>
|
||||
{
|
||||
FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text);
|
||||
}));
|
||||
BeginInvoke(new Action(() => { FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text); }));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Netch/Forms/Mode/Route.resx
Normal file
60
Netch/Forms/Mode/Route.resx
Normal file
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
416
Netch/Forms/SettingForm.Designer.cs
generated
416
Netch/Forms/SettingForm.Designer.cs
generated
@@ -38,8 +38,6 @@ namespace Netch.Forms
|
||||
this.Socks5PortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.HTTPPortLabel = new System.Windows.Forms.Label();
|
||||
this.HTTPPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.RedirectorLabel = new System.Windows.Forms.Label();
|
||||
this.RedirectorTextBox = new System.Windows.Forms.TextBox();
|
||||
this.AllowDevicesCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ResolveServerHostnameCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ServerPingTypeLabel = new System.Windows.Forms.Label();
|
||||
@@ -53,24 +51,20 @@ namespace Netch.Forms
|
||||
this.StartedPingIntervalTextBox = new System.Windows.Forms.TextBox();
|
||||
this.STUNServerLabel = new System.Windows.Forms.Label();
|
||||
this.STUN_ServerComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.AclLabel = new System.Windows.Forms.Label();
|
||||
this.AclAddrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.LanguageLabel = new System.Windows.Forms.Label();
|
||||
this.LanguageComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.NFTabPage = new System.Windows.Forms.TabPage();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.ProcessProxyProtocolLabel = new System.Windows.Forms.Label();
|
||||
this.ProcessProxyProtocolComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.DNSRedirectorCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.RDRDNSLabel = new System.Windows.Forms.Label();
|
||||
this.RDRDNSTextBox = new System.Windows.Forms.TextBox();
|
||||
this.ICMPRedirectorCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.RDRICMPLabel = new System.Windows.Forms.Label();
|
||||
this.ModifiedICMPTextBox = new System.Windows.Forms.TextBox();
|
||||
this.DNSHijackCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.DNSHijackHostTextBox = new System.Windows.Forms.TextBox();
|
||||
this.ICMPHijackCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ICMPHijackHostTextBox = new System.Windows.Forms.TextBox();
|
||||
this.RedirectorSSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ChildProcessHandleCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.TAPTabPage = new System.Windows.Forms.TabPage();
|
||||
this.TUNTAPGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.WinTUNTabPage = new System.Windows.Forms.TabPage();
|
||||
this.WinTUNGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.TUNTAPAddressLabel = new System.Windows.Forms.Label();
|
||||
this.TUNTAPAddressTextBox = new System.Windows.Forms.TextBox();
|
||||
this.TUNTAPNetmaskLabel = new System.Windows.Forms.Label();
|
||||
@@ -81,7 +75,6 @@ namespace Netch.Forms
|
||||
this.TUNTAPDNSTextBox = new System.Windows.Forms.TextBox();
|
||||
this.UseCustomDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ProxyDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.UseFakeDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.GlobalBypassIPsButton = new System.Windows.Forms.Button();
|
||||
this.v2rayTabPage = new System.Windows.Forms.TabPage();
|
||||
this.XrayConeCheckBox = new System.Windows.Forms.CheckBox();
|
||||
@@ -124,8 +117,8 @@ namespace Netch.Forms
|
||||
this.PortGroupBox.SuspendLayout();
|
||||
this.NFTabPage.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.TAPTabPage.SuspendLayout();
|
||||
this.TUNTAPGroupBox.SuspendLayout();
|
||||
this.WinTUNTabPage.SuspendLayout();
|
||||
this.WinTUNGroupBox.SuspendLayout();
|
||||
this.v2rayTabPage.SuspendLayout();
|
||||
this.KCPGroupBox.SuspendLayout();
|
||||
this.OtherTabPage.SuspendLayout();
|
||||
@@ -138,7 +131,7 @@ namespace Netch.Forms
|
||||
this.TabControl.Appearance = System.Windows.Forms.TabAppearance.FlatButtons;
|
||||
this.TabControl.Controls.Add(this.GeneralTabPage);
|
||||
this.TabControl.Controls.Add(this.NFTabPage);
|
||||
this.TabControl.Controls.Add(this.TAPTabPage);
|
||||
this.TabControl.Controls.Add(this.WinTUNTabPage);
|
||||
this.TabControl.Controls.Add(this.v2rayTabPage);
|
||||
this.TabControl.Controls.Add(this.OtherTabPage);
|
||||
this.TabControl.Controls.Add(this.AioDNSTabPage);
|
||||
@@ -164,14 +157,12 @@ namespace Netch.Forms
|
||||
this.GeneralTabPage.Controls.Add(this.StartedPingIntervalTextBox);
|
||||
this.GeneralTabPage.Controls.Add(this.STUNServerLabel);
|
||||
this.GeneralTabPage.Controls.Add(this.STUN_ServerComboBox);
|
||||
this.GeneralTabPage.Controls.Add(this.AclLabel);
|
||||
this.GeneralTabPage.Controls.Add(this.AclAddrTextBox);
|
||||
this.GeneralTabPage.Controls.Add(this.LanguageLabel);
|
||||
this.GeneralTabPage.Controls.Add(this.LanguageComboBox);
|
||||
this.GeneralTabPage.Location = new System.Drawing.Point(4, 25);
|
||||
this.GeneralTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.GeneralTabPage.Name = "GeneralTabPage";
|
||||
this.GeneralTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.GeneralTabPage.Size = new System.Drawing.Size(461, 325);
|
||||
this.GeneralTabPage.Size = new System.Drawing.Size(461, 321);
|
||||
this.GeneralTabPage.TabIndex = 0;
|
||||
this.GeneralTabPage.Text = "General";
|
||||
//
|
||||
@@ -181,8 +172,6 @@ namespace Netch.Forms
|
||||
this.PortGroupBox.Controls.Add(this.Socks5PortTextBox);
|
||||
this.PortGroupBox.Controls.Add(this.HTTPPortLabel);
|
||||
this.PortGroupBox.Controls.Add(this.HTTPPortTextBox);
|
||||
this.PortGroupBox.Controls.Add(this.RedirectorLabel);
|
||||
this.PortGroupBox.Controls.Add(this.RedirectorTextBox);
|
||||
this.PortGroupBox.Controls.Add(this.AllowDevicesCheckBox);
|
||||
this.PortGroupBox.Location = new System.Drawing.Point(8, 6);
|
||||
this.PortGroupBox.Name = "PortGroupBox";
|
||||
@@ -196,7 +185,7 @@ namespace Netch.Forms
|
||||
this.Socks5PortLabel.AutoSize = true;
|
||||
this.Socks5PortLabel.Location = new System.Drawing.Point(9, 25);
|
||||
this.Socks5PortLabel.Name = "Socks5PortLabel";
|
||||
this.Socks5PortLabel.Size = new System.Drawing.Size(41, 12);
|
||||
this.Socks5PortLabel.Size = new System.Drawing.Size(49, 17);
|
||||
this.Socks5PortLabel.TabIndex = 0;
|
||||
this.Socks5PortLabel.Text = "Socks5";
|
||||
//
|
||||
@@ -204,7 +193,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.Socks5PortTextBox.Location = new System.Drawing.Point(120, 22);
|
||||
this.Socks5PortTextBox.Name = "Socks5PortTextBox";
|
||||
this.Socks5PortTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.Socks5PortTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.Socks5PortTextBox.TabIndex = 1;
|
||||
this.Socks5PortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -213,7 +202,7 @@ namespace Netch.Forms
|
||||
this.HTTPPortLabel.AutoSize = true;
|
||||
this.HTTPPortLabel.Location = new System.Drawing.Point(9, 54);
|
||||
this.HTTPPortLabel.Name = "HTTPPortLabel";
|
||||
this.HTTPPortLabel.Size = new System.Drawing.Size(29, 12);
|
||||
this.HTTPPortLabel.Size = new System.Drawing.Size(38, 17);
|
||||
this.HTTPPortLabel.TabIndex = 2;
|
||||
this.HTTPPortLabel.Text = "HTTP";
|
||||
//
|
||||
@@ -221,33 +210,16 @@ namespace Netch.Forms
|
||||
//
|
||||
this.HTTPPortTextBox.Location = new System.Drawing.Point(120, 51);
|
||||
this.HTTPPortTextBox.Name = "HTTPPortTextBox";
|
||||
this.HTTPPortTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.HTTPPortTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.HTTPPortTextBox.TabIndex = 3;
|
||||
this.HTTPPortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// RedirectorLabel
|
||||
//
|
||||
this.RedirectorLabel.AutoSize = true;
|
||||
this.RedirectorLabel.Location = new System.Drawing.Point(9, 83);
|
||||
this.RedirectorLabel.Name = "RedirectorLabel";
|
||||
this.RedirectorLabel.Size = new System.Drawing.Size(89, 12);
|
||||
this.RedirectorLabel.TabIndex = 4;
|
||||
this.RedirectorLabel.Text = "Redirector TCP";
|
||||
//
|
||||
// RedirectorTextBox
|
||||
//
|
||||
this.RedirectorTextBox.Location = new System.Drawing.Point(120, 80);
|
||||
this.RedirectorTextBox.Name = "RedirectorTextBox";
|
||||
this.RedirectorTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.RedirectorTextBox.TabIndex = 5;
|
||||
this.RedirectorTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// AllowDevicesCheckBox
|
||||
//
|
||||
this.AllowDevicesCheckBox.AutoSize = true;
|
||||
this.AllowDevicesCheckBox.Location = new System.Drawing.Point(6, 107);
|
||||
this.AllowDevicesCheckBox.Name = "AllowDevicesCheckBox";
|
||||
this.AllowDevicesCheckBox.Size = new System.Drawing.Size(204, 16);
|
||||
this.AllowDevicesCheckBox.Size = new System.Drawing.Size(206, 21);
|
||||
this.AllowDevicesCheckBox.TabIndex = 6;
|
||||
this.AllowDevicesCheckBox.Text = "Allow other Devices to connect";
|
||||
this.AllowDevicesCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -258,7 +230,7 @@ namespace Netch.Forms
|
||||
this.ResolveServerHostnameCheckBox.AutoSize = true;
|
||||
this.ResolveServerHostnameCheckBox.Location = new System.Drawing.Point(267, 15);
|
||||
this.ResolveServerHostnameCheckBox.Name = "ResolveServerHostnameCheckBox";
|
||||
this.ResolveServerHostnameCheckBox.Size = new System.Drawing.Size(162, 16);
|
||||
this.ResolveServerHostnameCheckBox.Size = new System.Drawing.Size(176, 21);
|
||||
this.ResolveServerHostnameCheckBox.TabIndex = 1;
|
||||
this.ResolveServerHostnameCheckBox.Text = "Resolve Server Hostname";
|
||||
this.ResolveServerHostnameCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -268,7 +240,7 @@ namespace Netch.Forms
|
||||
this.ServerPingTypeLabel.AutoSize = true;
|
||||
this.ServerPingTypeLabel.Location = new System.Drawing.Point(267, 44);
|
||||
this.ServerPingTypeLabel.Name = "ServerPingTypeLabel";
|
||||
this.ServerPingTypeLabel.Size = new System.Drawing.Size(89, 12);
|
||||
this.ServerPingTypeLabel.Size = new System.Drawing.Size(98, 17);
|
||||
this.ServerPingTypeLabel.TabIndex = 2;
|
||||
this.ServerPingTypeLabel.Text = "ServerPingType";
|
||||
//
|
||||
@@ -277,7 +249,7 @@ namespace Netch.Forms
|
||||
this.ICMPingRadioBtn.AutoSize = true;
|
||||
this.ICMPingRadioBtn.Location = new System.Drawing.Point(268, 63);
|
||||
this.ICMPingRadioBtn.Name = "ICMPingRadioBtn";
|
||||
this.ICMPingRadioBtn.Size = new System.Drawing.Size(65, 16);
|
||||
this.ICMPingRadioBtn.Size = new System.Drawing.Size(75, 21);
|
||||
this.ICMPingRadioBtn.TabIndex = 3;
|
||||
this.ICMPingRadioBtn.TabStop = true;
|
||||
this.ICMPingRadioBtn.Text = "ICMPing";
|
||||
@@ -286,9 +258,9 @@ namespace Netch.Forms
|
||||
// TCPingRadioBtn
|
||||
//
|
||||
this.TCPingRadioBtn.AutoSize = true;
|
||||
this.TCPingRadioBtn.Location = new System.Drawing.Point(332, 63);
|
||||
this.TCPingRadioBtn.Location = new System.Drawing.Point(366, 64);
|
||||
this.TCPingRadioBtn.Name = "TCPingRadioBtn";
|
||||
this.TCPingRadioBtn.Size = new System.Drawing.Size(59, 16);
|
||||
this.TCPingRadioBtn.Size = new System.Drawing.Size(66, 21);
|
||||
this.TCPingRadioBtn.TabIndex = 4;
|
||||
this.TCPingRadioBtn.TabStop = true;
|
||||
this.TCPingRadioBtn.Text = "TCPing";
|
||||
@@ -299,7 +271,7 @@ namespace Netch.Forms
|
||||
this.ProfileCountLabel.AutoSize = true;
|
||||
this.ProfileCountLabel.Location = new System.Drawing.Point(12, 160);
|
||||
this.ProfileCountLabel.Name = "ProfileCountLabel";
|
||||
this.ProfileCountLabel.Size = new System.Drawing.Size(77, 12);
|
||||
this.ProfileCountLabel.Size = new System.Drawing.Size(79, 17);
|
||||
this.ProfileCountLabel.TabIndex = 5;
|
||||
this.ProfileCountLabel.Text = "ProfileCount";
|
||||
//
|
||||
@@ -307,7 +279,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.ProfileCountTextBox.Location = new System.Drawing.Point(120, 157);
|
||||
this.ProfileCountTextBox.Name = "ProfileCountTextBox";
|
||||
this.ProfileCountTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.ProfileCountTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.ProfileCountTextBox.TabIndex = 6;
|
||||
this.ProfileCountTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -316,7 +288,7 @@ namespace Netch.Forms
|
||||
this.DetectionTickLabel.AutoSize = true;
|
||||
this.DetectionTickLabel.Location = new System.Drawing.Point(225, 160);
|
||||
this.DetectionTickLabel.Name = "DetectionTickLabel";
|
||||
this.DetectionTickLabel.Size = new System.Drawing.Size(119, 12);
|
||||
this.DetectionTickLabel.Size = new System.Drawing.Size(117, 17);
|
||||
this.DetectionTickLabel.TabIndex = 7;
|
||||
this.DetectionTickLabel.Text = "Detection Tick(sec)";
|
||||
//
|
||||
@@ -324,7 +296,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.DetectionTickTextBox.Location = new System.Drawing.Point(366, 157);
|
||||
this.DetectionTickTextBox.Name = "DetectionTickTextBox";
|
||||
this.DetectionTickTextBox.Size = new System.Drawing.Size(68, 21);
|
||||
this.DetectionTickTextBox.Size = new System.Drawing.Size(68, 23);
|
||||
this.DetectionTickTextBox.TabIndex = 8;
|
||||
this.DetectionTickTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -333,7 +305,7 @@ namespace Netch.Forms
|
||||
this.StartedPingLabel.AutoSize = true;
|
||||
this.StartedPingLabel.Location = new System.Drawing.Point(12, 187);
|
||||
this.StartedPingLabel.Name = "StartedPingLabel";
|
||||
this.StartedPingLabel.Size = new System.Drawing.Size(137, 12);
|
||||
this.StartedPingLabel.Size = new System.Drawing.Size(126, 17);
|
||||
this.StartedPingLabel.TabIndex = 9;
|
||||
this.StartedPingLabel.Text = "Delay test after start";
|
||||
//
|
||||
@@ -341,7 +313,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.StartedPingIntervalTextBox.Location = new System.Drawing.Point(177, 184);
|
||||
this.StartedPingIntervalTextBox.Name = "StartedPingIntervalTextBox";
|
||||
this.StartedPingIntervalTextBox.Size = new System.Drawing.Size(68, 21);
|
||||
this.StartedPingIntervalTextBox.Size = new System.Drawing.Size(68, 23);
|
||||
this.StartedPingIntervalTextBox.TabIndex = 10;
|
||||
this.StartedPingIntervalTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -350,7 +322,7 @@ namespace Netch.Forms
|
||||
this.STUNServerLabel.AutoSize = true;
|
||||
this.STUNServerLabel.Location = new System.Drawing.Point(12, 216);
|
||||
this.STUNServerLabel.Name = "STUNServerLabel";
|
||||
this.STUNServerLabel.Size = new System.Drawing.Size(71, 12);
|
||||
this.STUNServerLabel.Size = new System.Drawing.Size(82, 17);
|
||||
this.STUNServerLabel.TabIndex = 11;
|
||||
this.STUNServerLabel.Text = "STUN Server";
|
||||
//
|
||||
@@ -359,32 +331,15 @@ namespace Netch.Forms
|
||||
this.STUN_ServerComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
|
||||
this.STUN_ServerComboBox.Location = new System.Drawing.Point(120, 213);
|
||||
this.STUN_ServerComboBox.Name = "STUN_ServerComboBox";
|
||||
this.STUN_ServerComboBox.Size = new System.Drawing.Size(314, 20);
|
||||
this.STUN_ServerComboBox.Size = new System.Drawing.Size(314, 25);
|
||||
this.STUN_ServerComboBox.TabIndex = 12;
|
||||
//
|
||||
// AclLabel
|
||||
//
|
||||
this.AclLabel.AutoSize = true;
|
||||
this.AclLabel.Location = new System.Drawing.Point(12, 248);
|
||||
this.AclLabel.Name = "AclLabel";
|
||||
this.AclLabel.Size = new System.Drawing.Size(65, 12);
|
||||
this.AclLabel.TabIndex = 13;
|
||||
this.AclLabel.Text = "Custom ACL";
|
||||
//
|
||||
// AclAddrTextBox
|
||||
//
|
||||
this.AclAddrTextBox.Location = new System.Drawing.Point(120, 245);
|
||||
this.AclAddrTextBox.Name = "AclAddrTextBox";
|
||||
this.AclAddrTextBox.Size = new System.Drawing.Size(314, 21);
|
||||
this.AclAddrTextBox.TabIndex = 14;
|
||||
this.AclAddrTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// LanguageLabel
|
||||
//
|
||||
this.LanguageLabel.AutoSize = true;
|
||||
this.LanguageLabel.Location = new System.Drawing.Point(12, 277);
|
||||
this.LanguageLabel.Location = new System.Drawing.Point(12, 254);
|
||||
this.LanguageLabel.Name = "LanguageLabel";
|
||||
this.LanguageLabel.Size = new System.Drawing.Size(53, 12);
|
||||
this.LanguageLabel.Size = new System.Drawing.Size(65, 17);
|
||||
this.LanguageLabel.TabIndex = 15;
|
||||
this.LanguageLabel.Text = "Language";
|
||||
//
|
||||
@@ -392,9 +347,9 @@ namespace Netch.Forms
|
||||
//
|
||||
this.LanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.LanguageComboBox.FormattingEnabled = true;
|
||||
this.LanguageComboBox.Location = new System.Drawing.Point(120, 274);
|
||||
this.LanguageComboBox.Location = new System.Drawing.Point(120, 251);
|
||||
this.LanguageComboBox.Name = "LanguageComboBox";
|
||||
this.LanguageComboBox.Size = new System.Drawing.Size(121, 20);
|
||||
this.LanguageComboBox.Size = new System.Drawing.Size(121, 25);
|
||||
this.LanguageComboBox.TabIndex = 16;
|
||||
//
|
||||
// NFTabPage
|
||||
@@ -403,10 +358,10 @@ namespace Netch.Forms
|
||||
this.NFTabPage.Controls.Add(this.groupBox1);
|
||||
this.NFTabPage.Controls.Add(this.RedirectorSSCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.ChildProcessHandleCheckBox);
|
||||
this.NFTabPage.Location = new System.Drawing.Point(4, 25);
|
||||
this.NFTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.NFTabPage.Name = "NFTabPage";
|
||||
this.NFTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.NFTabPage.Size = new System.Drawing.Size(461, 325);
|
||||
this.NFTabPage.Size = new System.Drawing.Size(461, 321);
|
||||
this.NFTabPage.TabIndex = 1;
|
||||
this.NFTabPage.Text = "Process Mode";
|
||||
//
|
||||
@@ -414,12 +369,10 @@ namespace Netch.Forms
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.ProcessProxyProtocolLabel);
|
||||
this.groupBox1.Controls.Add(this.ProcessProxyProtocolComboBox);
|
||||
this.groupBox1.Controls.Add(this.DNSRedirectorCheckBox);
|
||||
this.groupBox1.Controls.Add(this.RDRDNSLabel);
|
||||
this.groupBox1.Controls.Add(this.RDRDNSTextBox);
|
||||
this.groupBox1.Controls.Add(this.ICMPRedirectorCheckBox);
|
||||
this.groupBox1.Controls.Add(this.RDRICMPLabel);
|
||||
this.groupBox1.Controls.Add(this.ModifiedICMPTextBox);
|
||||
this.groupBox1.Controls.Add(this.DNSHijackCheckBox);
|
||||
this.groupBox1.Controls.Add(this.DNSHijackHostTextBox);
|
||||
this.groupBox1.Controls.Add(this.ICMPHijackCheckBox);
|
||||
this.groupBox1.Controls.Add(this.ICMPHijackHostTextBox);
|
||||
this.groupBox1.Location = new System.Drawing.Point(5, 6);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(450, 117);
|
||||
@@ -431,7 +384,7 @@ namespace Netch.Forms
|
||||
this.ProcessProxyProtocolLabel.AutoSize = true;
|
||||
this.ProcessProxyProtocolLabel.Location = new System.Drawing.Point(23, 21);
|
||||
this.ProcessProxyProtocolLabel.Name = "ProcessProxyProtocolLabel";
|
||||
this.ProcessProxyProtocolLabel.Size = new System.Drawing.Size(89, 12);
|
||||
this.ProcessProxyProtocolLabel.Size = new System.Drawing.Size(93, 17);
|
||||
this.ProcessProxyProtocolLabel.TabIndex = 0;
|
||||
this.ProcessProxyProtocolLabel.Text = "Proxy Protocol";
|
||||
//
|
||||
@@ -441,71 +394,55 @@ namespace Netch.Forms
|
||||
this.ProcessProxyProtocolComboBox.FormattingEnabled = true;
|
||||
this.ProcessProxyProtocolComboBox.Location = new System.Drawing.Point(118, 16);
|
||||
this.ProcessProxyProtocolComboBox.Name = "ProcessProxyProtocolComboBox";
|
||||
this.ProcessProxyProtocolComboBox.Size = new System.Drawing.Size(191, 20);
|
||||
this.ProcessProxyProtocolComboBox.Size = new System.Drawing.Size(191, 25);
|
||||
this.ProcessProxyProtocolComboBox.TabIndex = 1;
|
||||
//
|
||||
// DNSRedirectorCheckBox
|
||||
// DNSHijackCheckBox
|
||||
//
|
||||
this.DNSRedirectorCheckBox.AutoSize = true;
|
||||
this.DNSRedirectorCheckBox.Location = new System.Drawing.Point(6, 51);
|
||||
this.DNSRedirectorCheckBox.Name = "DNSRedirectorCheckBox";
|
||||
this.DNSRedirectorCheckBox.Size = new System.Drawing.Size(108, 16);
|
||||
this.DNSRedirectorCheckBox.TabIndex = 2;
|
||||
this.DNSRedirectorCheckBox.Text = "DNS Redirector";
|
||||
this.DNSRedirectorCheckBox.UseVisualStyleBackColor = true;
|
||||
this.DNSHijackCheckBox.AutoSize = true;
|
||||
this.DNSHijackCheckBox.Location = new System.Drawing.Point(6, 51);
|
||||
this.DNSHijackCheckBox.Name = "DNSHijackCheckBox";
|
||||
this.DNSHijackCheckBox.Size = new System.Drawing.Size(196, 21);
|
||||
this.DNSHijackCheckBox.TabIndex = 2;
|
||||
this.DNSHijackCheckBox.Text = "Handle process\'s DNS Hijack";
|
||||
this.DNSHijackCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RDRDNSLabel
|
||||
// DNSHijackHostTextBox
|
||||
//
|
||||
this.RDRDNSLabel.AutoSize = true;
|
||||
this.RDRDNSLabel.Location = new System.Drawing.Point(224, 52);
|
||||
this.RDRDNSLabel.Name = "RDRDNSLabel";
|
||||
this.RDRDNSLabel.Size = new System.Drawing.Size(23, 12);
|
||||
this.RDRDNSLabel.TabIndex = 3;
|
||||
this.RDRDNSLabel.Text = "DNS";
|
||||
this.DNSHijackHostTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.DNSHijackCheckBox, "Checked", true));
|
||||
this.DNSHijackHostTextBox.Location = new System.Drawing.Point(253, 46);
|
||||
this.DNSHijackHostTextBox.Name = "DNSHijackHostTextBox";
|
||||
this.DNSHijackHostTextBox.Size = new System.Drawing.Size(191, 23);
|
||||
this.DNSHijackHostTextBox.TabIndex = 4;
|
||||
this.DNSHijackHostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// RDRDNSTextBox
|
||||
// ICMPHijackCheckBox
|
||||
//
|
||||
this.RDRDNSTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.DNSRedirectorCheckBox, "Checked", true));
|
||||
this.RDRDNSTextBox.Location = new System.Drawing.Point(253, 46);
|
||||
this.RDRDNSTextBox.Name = "RDRDNSTextBox";
|
||||
this.RDRDNSTextBox.Size = new System.Drawing.Size(191, 21);
|
||||
this.RDRDNSTextBox.TabIndex = 4;
|
||||
this.RDRDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.ICMPHijackCheckBox.AutoSize = true;
|
||||
this.ICMPHijackCheckBox.Enabled = false;
|
||||
this.ICMPHijackCheckBox.Location = new System.Drawing.Point(6, 81);
|
||||
this.ICMPHijackCheckBox.Name = "ICMPHijackCheckBox";
|
||||
this.ICMPHijackCheckBox.Size = new System.Drawing.Size(139, 21);
|
||||
this.ICMPHijackCheckBox.TabIndex = 5;
|
||||
this.ICMPHijackCheckBox.Text = "Global ICMP Hijack";
|
||||
this.ICMPHijackCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ICMPRedirectorCheckBox
|
||||
// ICMPHijackHostTextBox
|
||||
//
|
||||
this.ICMPRedirectorCheckBox.AutoSize = true;
|
||||
this.ICMPRedirectorCheckBox.Location = new System.Drawing.Point(6, 81);
|
||||
this.ICMPRedirectorCheckBox.Name = "ICMPRedirectorCheckBox";
|
||||
this.ICMPRedirectorCheckBox.Size = new System.Drawing.Size(114, 16);
|
||||
this.ICMPRedirectorCheckBox.TabIndex = 5;
|
||||
this.ICMPRedirectorCheckBox.Text = "ICMP Redirector";
|
||||
this.ICMPRedirectorCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RDRICMPLabel
|
||||
//
|
||||
this.RDRICMPLabel.AutoSize = true;
|
||||
this.RDRICMPLabel.Location = new System.Drawing.Point(218, 81);
|
||||
this.RDRICMPLabel.Name = "RDRICMPLabel";
|
||||
this.RDRICMPLabel.Size = new System.Drawing.Size(29, 12);
|
||||
this.RDRICMPLabel.TabIndex = 6;
|
||||
this.RDRICMPLabel.Text = "ICMP";
|
||||
//
|
||||
// ModifiedICMPTextBox
|
||||
//
|
||||
this.ModifiedICMPTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.ICMPRedirectorCheckBox, "Checked", true));
|
||||
this.ModifiedICMPTextBox.Location = new System.Drawing.Point(253, 78);
|
||||
this.ModifiedICMPTextBox.Name = "ModifiedICMPTextBox";
|
||||
this.ModifiedICMPTextBox.Size = new System.Drawing.Size(191, 21);
|
||||
this.ModifiedICMPTextBox.TabIndex = 7;
|
||||
this.ModifiedICMPTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.ICMPHijackHostTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.ICMPHijackCheckBox, "Checked", true));
|
||||
this.ICMPHijackHostTextBox.Enabled = false;
|
||||
this.ICMPHijackHostTextBox.Location = new System.Drawing.Point(253, 78);
|
||||
this.ICMPHijackHostTextBox.Name = "ICMPHijackHostTextBox";
|
||||
this.ICMPHijackHostTextBox.Size = new System.Drawing.Size(191, 23);
|
||||
this.ICMPHijackHostTextBox.TabIndex = 7;
|
||||
this.ICMPHijackHostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// RedirectorSSCheckBox
|
||||
//
|
||||
this.RedirectorSSCheckBox.AutoSize = true;
|
||||
this.RedirectorSSCheckBox.Location = new System.Drawing.Point(11, 129);
|
||||
this.RedirectorSSCheckBox.Name = "RedirectorSSCheckBox";
|
||||
this.RedirectorSSCheckBox.Size = new System.Drawing.Size(102, 16);
|
||||
this.RedirectorSSCheckBox.Size = new System.Drawing.Size(106, 21);
|
||||
this.RedirectorSSCheckBox.TabIndex = 1;
|
||||
this.RedirectorSSCheckBox.Text = "Redirector SS";
|
||||
this.RedirectorSSCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -513,51 +450,50 @@ namespace Netch.Forms
|
||||
// ChildProcessHandleCheckBox
|
||||
//
|
||||
this.ChildProcessHandleCheckBox.AutoSize = true;
|
||||
this.ChildProcessHandleCheckBox.Enabled = false;
|
||||
this.ChildProcessHandleCheckBox.Location = new System.Drawing.Point(11, 151);
|
||||
this.ChildProcessHandleCheckBox.Name = "ChildProcessHandleCheckBox";
|
||||
this.ChildProcessHandleCheckBox.Size = new System.Drawing.Size(144, 16);
|
||||
this.ChildProcessHandleCheckBox.Size = new System.Drawing.Size(150, 21);
|
||||
this.ChildProcessHandleCheckBox.TabIndex = 2;
|
||||
this.ChildProcessHandleCheckBox.Text = "Child Process Handle";
|
||||
this.ChildProcessHandleCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TAPTabPage
|
||||
// WinTUNTabPage
|
||||
//
|
||||
this.TAPTabPage.BackColor = System.Drawing.SystemColors.ButtonFace;
|
||||
this.TAPTabPage.Controls.Add(this.TUNTAPGroupBox);
|
||||
this.TAPTabPage.Controls.Add(this.GlobalBypassIPsButton);
|
||||
this.TAPTabPage.Location = new System.Drawing.Point(4, 25);
|
||||
this.TAPTabPage.Name = "TAPTabPage";
|
||||
this.TAPTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.TAPTabPage.Size = new System.Drawing.Size(461, 325);
|
||||
this.TAPTabPage.TabIndex = 2;
|
||||
this.TAPTabPage.Text = "TUN/TAP";
|
||||
this.WinTUNTabPage.BackColor = System.Drawing.SystemColors.ButtonFace;
|
||||
this.WinTUNTabPage.Controls.Add(this.WinTUNGroupBox);
|
||||
this.WinTUNTabPage.Controls.Add(this.GlobalBypassIPsButton);
|
||||
this.WinTUNTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.WinTUNTabPage.Name = "WinTUNTabPage";
|
||||
this.WinTUNTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.WinTUNTabPage.Size = new System.Drawing.Size(461, 321);
|
||||
this.WinTUNTabPage.TabIndex = 2;
|
||||
this.WinTUNTabPage.Text = "WinTUN";
|
||||
//
|
||||
// TUNTAPGroupBox
|
||||
// WinTUNGroupBox
|
||||
//
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPAddressLabel);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPAddressTextBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPNetmaskLabel);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPNetmaskTextBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPGatewayLabel);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPGatewayTextBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPDNSLabel);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPDNSTextBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.ProxyDNSCheckBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.UseFakeDNSCheckBox);
|
||||
this.TUNTAPGroupBox.Location = new System.Drawing.Point(6, 6);
|
||||
this.TUNTAPGroupBox.Name = "TUNTAPGroupBox";
|
||||
this.TUNTAPGroupBox.Size = new System.Drawing.Size(420, 187);
|
||||
this.TUNTAPGroupBox.TabIndex = 0;
|
||||
this.TUNTAPGroupBox.TabStop = false;
|
||||
this.TUNTAPGroupBox.Text = "TUN/TAP";
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPAddressLabel);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPAddressTextBox);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPNetmaskLabel);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPNetmaskTextBox);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPGatewayLabel);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPGatewayTextBox);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPDNSLabel);
|
||||
this.WinTUNGroupBox.Controls.Add(this.TUNTAPDNSTextBox);
|
||||
this.WinTUNGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
|
||||
this.WinTUNGroupBox.Controls.Add(this.ProxyDNSCheckBox);
|
||||
this.WinTUNGroupBox.Location = new System.Drawing.Point(6, 6);
|
||||
this.WinTUNGroupBox.Name = "WinTUNGroupBox";
|
||||
this.WinTUNGroupBox.Size = new System.Drawing.Size(420, 175);
|
||||
this.WinTUNGroupBox.TabIndex = 0;
|
||||
this.WinTUNGroupBox.TabStop = false;
|
||||
//
|
||||
// TUNTAPAddressLabel
|
||||
//
|
||||
this.TUNTAPAddressLabel.AutoSize = true;
|
||||
this.TUNTAPAddressLabel.Location = new System.Drawing.Point(9, 25);
|
||||
this.TUNTAPAddressLabel.Name = "TUNTAPAddressLabel";
|
||||
this.TUNTAPAddressLabel.Size = new System.Drawing.Size(47, 12);
|
||||
this.TUNTAPAddressLabel.Size = new System.Drawing.Size(56, 17);
|
||||
this.TUNTAPAddressLabel.TabIndex = 0;
|
||||
this.TUNTAPAddressLabel.Text = "Address";
|
||||
//
|
||||
@@ -565,7 +501,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.TUNTAPAddressTextBox.Location = new System.Drawing.Point(120, 22);
|
||||
this.TUNTAPAddressTextBox.Name = "TUNTAPAddressTextBox";
|
||||
this.TUNTAPAddressTextBox.Size = new System.Drawing.Size(294, 21);
|
||||
this.TUNTAPAddressTextBox.Size = new System.Drawing.Size(294, 23);
|
||||
this.TUNTAPAddressTextBox.TabIndex = 1;
|
||||
this.TUNTAPAddressTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -574,7 +510,7 @@ namespace Netch.Forms
|
||||
this.TUNTAPNetmaskLabel.AutoSize = true;
|
||||
this.TUNTAPNetmaskLabel.Location = new System.Drawing.Point(9, 54);
|
||||
this.TUNTAPNetmaskLabel.Name = "TUNTAPNetmaskLabel";
|
||||
this.TUNTAPNetmaskLabel.Size = new System.Drawing.Size(47, 12);
|
||||
this.TUNTAPNetmaskLabel.Size = new System.Drawing.Size(60, 17);
|
||||
this.TUNTAPNetmaskLabel.TabIndex = 2;
|
||||
this.TUNTAPNetmaskLabel.Text = "Netmask";
|
||||
//
|
||||
@@ -582,7 +518,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.TUNTAPNetmaskTextBox.Location = new System.Drawing.Point(120, 51);
|
||||
this.TUNTAPNetmaskTextBox.Name = "TUNTAPNetmaskTextBox";
|
||||
this.TUNTAPNetmaskTextBox.Size = new System.Drawing.Size(294, 21);
|
||||
this.TUNTAPNetmaskTextBox.Size = new System.Drawing.Size(294, 23);
|
||||
this.TUNTAPNetmaskTextBox.TabIndex = 3;
|
||||
this.TUNTAPNetmaskTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -591,7 +527,7 @@ namespace Netch.Forms
|
||||
this.TUNTAPGatewayLabel.AutoSize = true;
|
||||
this.TUNTAPGatewayLabel.Location = new System.Drawing.Point(9, 83);
|
||||
this.TUNTAPGatewayLabel.Name = "TUNTAPGatewayLabel";
|
||||
this.TUNTAPGatewayLabel.Size = new System.Drawing.Size(47, 12);
|
||||
this.TUNTAPGatewayLabel.Size = new System.Drawing.Size(57, 17);
|
||||
this.TUNTAPGatewayLabel.TabIndex = 4;
|
||||
this.TUNTAPGatewayLabel.Text = "Gateway";
|
||||
//
|
||||
@@ -599,7 +535,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.TUNTAPGatewayTextBox.Location = new System.Drawing.Point(120, 80);
|
||||
this.TUNTAPGatewayTextBox.Name = "TUNTAPGatewayTextBox";
|
||||
this.TUNTAPGatewayTextBox.Size = new System.Drawing.Size(294, 21);
|
||||
this.TUNTAPGatewayTextBox.Size = new System.Drawing.Size(294, 23);
|
||||
this.TUNTAPGatewayTextBox.TabIndex = 5;
|
||||
this.TUNTAPGatewayTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -608,16 +544,16 @@ namespace Netch.Forms
|
||||
this.TUNTAPDNSLabel.AutoSize = true;
|
||||
this.TUNTAPDNSLabel.Location = new System.Drawing.Point(9, 112);
|
||||
this.TUNTAPDNSLabel.Name = "TUNTAPDNSLabel";
|
||||
this.TUNTAPDNSLabel.Size = new System.Drawing.Size(23, 12);
|
||||
this.TUNTAPDNSLabel.Size = new System.Drawing.Size(73, 17);
|
||||
this.TUNTAPDNSLabel.TabIndex = 6;
|
||||
this.TUNTAPDNSLabel.Text = "DNS";
|
||||
this.TUNTAPDNSLabel.Text = "DNS Hijack";
|
||||
//
|
||||
// TUNTAPDNSTextBox
|
||||
//
|
||||
this.TUNTAPDNSTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.UseCustomDNSCheckBox, "Checked", true));
|
||||
this.TUNTAPDNSTextBox.Location = new System.Drawing.Point(120, 110);
|
||||
this.TUNTAPDNSTextBox.Name = "TUNTAPDNSTextBox";
|
||||
this.TUNTAPDNSTextBox.Size = new System.Drawing.Size(294, 21);
|
||||
this.TUNTAPDNSTextBox.Size = new System.Drawing.Size(294, 23);
|
||||
this.TUNTAPDNSTextBox.TabIndex = 7;
|
||||
this.TUNTAPDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -626,7 +562,7 @@ namespace Netch.Forms
|
||||
this.UseCustomDNSCheckBox.AutoSize = true;
|
||||
this.UseCustomDNSCheckBox.Location = new System.Drawing.Point(10, 139);
|
||||
this.UseCustomDNSCheckBox.Name = "UseCustomDNSCheckBox";
|
||||
this.UseCustomDNSCheckBox.Size = new System.Drawing.Size(108, 16);
|
||||
this.UseCustomDNSCheckBox.Size = new System.Drawing.Size(127, 21);
|
||||
this.UseCustomDNSCheckBox.TabIndex = 8;
|
||||
this.UseCustomDNSCheckBox.Text = "Use Custom DNS";
|
||||
this.UseCustomDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -637,22 +573,11 @@ namespace Netch.Forms
|
||||
this.ProxyDNSCheckBox.AutoSize = true;
|
||||
this.ProxyDNSCheckBox.Location = new System.Drawing.Point(175, 139);
|
||||
this.ProxyDNSCheckBox.Name = "ProxyDNSCheckBox";
|
||||
this.ProxyDNSCheckBox.Size = new System.Drawing.Size(216, 16);
|
||||
this.ProxyDNSCheckBox.Size = new System.Drawing.Size(228, 21);
|
||||
this.ProxyDNSCheckBox.TabIndex = 9;
|
||||
this.ProxyDNSCheckBox.Text = "Proxy DNS in Proxy Rule IPs Mode";
|
||||
this.ProxyDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// UseFakeDNSCheckBox
|
||||
//
|
||||
this.UseFakeDNSCheckBox.AutoSize = true;
|
||||
this.UseFakeDNSCheckBox.Location = new System.Drawing.Point(10, 160);
|
||||
this.UseFakeDNSCheckBox.Name = "UseFakeDNSCheckBox";
|
||||
this.UseFakeDNSCheckBox.Size = new System.Drawing.Size(96, 16);
|
||||
this.UseFakeDNSCheckBox.TabIndex = 10;
|
||||
this.UseFakeDNSCheckBox.Text = "Use Fake DNS";
|
||||
this.UseFakeDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.UseFakeDNSCheckBox.Visible = false;
|
||||
//
|
||||
// GlobalBypassIPsButton
|
||||
//
|
||||
this.GlobalBypassIPsButton.Location = new System.Drawing.Point(6, 199);
|
||||
@@ -670,10 +595,10 @@ namespace Netch.Forms
|
||||
this.v2rayTabPage.Controls.Add(this.TLSAllowInsecureCheckBox);
|
||||
this.v2rayTabPage.Controls.Add(this.UseMuxCheckBox);
|
||||
this.v2rayTabPage.Controls.Add(this.KCPGroupBox);
|
||||
this.v2rayTabPage.Location = new System.Drawing.Point(4, 25);
|
||||
this.v2rayTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.v2rayTabPage.Name = "v2rayTabPage";
|
||||
this.v2rayTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.v2rayTabPage.Size = new System.Drawing.Size(461, 325);
|
||||
this.v2rayTabPage.Size = new System.Drawing.Size(461, 321);
|
||||
this.v2rayTabPage.TabIndex = 3;
|
||||
this.v2rayTabPage.Text = "V2Ray";
|
||||
//
|
||||
@@ -682,7 +607,7 @@ namespace Netch.Forms
|
||||
this.XrayConeCheckBox.AutoSize = true;
|
||||
this.XrayConeCheckBox.Location = new System.Drawing.Point(6, 15);
|
||||
this.XrayConeCheckBox.Name = "XrayConeCheckBox";
|
||||
this.XrayConeCheckBox.Size = new System.Drawing.Size(336, 16);
|
||||
this.XrayConeCheckBox.Size = new System.Drawing.Size(340, 21);
|
||||
this.XrayConeCheckBox.TabIndex = 0;
|
||||
this.XrayConeCheckBox.Text = "FullCone Support (Required Server Xray-core v1.3.0+)";
|
||||
this.XrayConeCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -692,7 +617,7 @@ namespace Netch.Forms
|
||||
this.TLSAllowInsecureCheckBox.AutoSize = true;
|
||||
this.TLSAllowInsecureCheckBox.Location = new System.Drawing.Point(6, 42);
|
||||
this.TLSAllowInsecureCheckBox.Name = "TLSAllowInsecureCheckBox";
|
||||
this.TLSAllowInsecureCheckBox.Size = new System.Drawing.Size(126, 16);
|
||||
this.TLSAllowInsecureCheckBox.Size = new System.Drawing.Size(131, 21);
|
||||
this.TLSAllowInsecureCheckBox.TabIndex = 1;
|
||||
this.TLSAllowInsecureCheckBox.Text = "TLS AllowInsecure";
|
||||
this.TLSAllowInsecureCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -702,7 +627,7 @@ namespace Netch.Forms
|
||||
this.UseMuxCheckBox.AutoSize = true;
|
||||
this.UseMuxCheckBox.Location = new System.Drawing.Point(148, 42);
|
||||
this.UseMuxCheckBox.Name = "UseMuxCheckBox";
|
||||
this.UseMuxCheckBox.Size = new System.Drawing.Size(66, 16);
|
||||
this.UseMuxCheckBox.Size = new System.Drawing.Size(78, 21);
|
||||
this.UseMuxCheckBox.TabIndex = 2;
|
||||
this.UseMuxCheckBox.Text = "Use Mux";
|
||||
this.UseMuxCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -734,7 +659,7 @@ namespace Netch.Forms
|
||||
this.mtuLabel.AutoSize = true;
|
||||
this.mtuLabel.Location = new System.Drawing.Point(6, 26);
|
||||
this.mtuLabel.Name = "mtuLabel";
|
||||
this.mtuLabel.Size = new System.Drawing.Size(23, 12);
|
||||
this.mtuLabel.Size = new System.Drawing.Size(30, 17);
|
||||
this.mtuLabel.TabIndex = 0;
|
||||
this.mtuLabel.Text = "mtu";
|
||||
//
|
||||
@@ -742,16 +667,16 @@ namespace Netch.Forms
|
||||
//
|
||||
this.mtuTextBox.Location = new System.Drawing.Point(103, 17);
|
||||
this.mtuTextBox.Name = "mtuTextBox";
|
||||
this.mtuTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.mtuTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.mtuTextBox.TabIndex = 1;
|
||||
this.mtuTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// ttiLabel
|
||||
//
|
||||
this.ttiLabel.AutoSize = true;
|
||||
this.ttiLabel.Location = new System.Drawing.Point(224, 26);
|
||||
this.ttiLabel.Location = new System.Drawing.Point(216, 26);
|
||||
this.ttiLabel.Name = "ttiLabel";
|
||||
this.ttiLabel.Size = new System.Drawing.Size(23, 12);
|
||||
this.ttiLabel.Size = new System.Drawing.Size(19, 17);
|
||||
this.ttiLabel.TabIndex = 2;
|
||||
this.ttiLabel.Text = "tti";
|
||||
//
|
||||
@@ -759,7 +684,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.ttiTextBox.Location = new System.Drawing.Point(331, 17);
|
||||
this.ttiTextBox.Name = "ttiTextBox";
|
||||
this.ttiTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.ttiTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.ttiTextBox.TabIndex = 3;
|
||||
this.ttiTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -768,7 +693,7 @@ namespace Netch.Forms
|
||||
this.uplinkCapacityLabel.AutoSize = true;
|
||||
this.uplinkCapacityLabel.Location = new System.Drawing.Point(6, 68);
|
||||
this.uplinkCapacityLabel.Name = "uplinkCapacityLabel";
|
||||
this.uplinkCapacityLabel.Size = new System.Drawing.Size(89, 12);
|
||||
this.uplinkCapacityLabel.Size = new System.Drawing.Size(92, 17);
|
||||
this.uplinkCapacityLabel.TabIndex = 4;
|
||||
this.uplinkCapacityLabel.Text = "uplinkCapacity";
|
||||
//
|
||||
@@ -776,16 +701,16 @@ namespace Netch.Forms
|
||||
//
|
||||
this.uplinkCapacityTextBox.Location = new System.Drawing.Point(103, 59);
|
||||
this.uplinkCapacityTextBox.Name = "uplinkCapacityTextBox";
|
||||
this.uplinkCapacityTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.uplinkCapacityTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.uplinkCapacityTextBox.TabIndex = 5;
|
||||
this.uplinkCapacityTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// downlinkCapacityLabel
|
||||
//
|
||||
this.downlinkCapacityLabel.AutoSize = true;
|
||||
this.downlinkCapacityLabel.Location = new System.Drawing.Point(224, 68);
|
||||
this.downlinkCapacityLabel.Location = new System.Drawing.Point(216, 68);
|
||||
this.downlinkCapacityLabel.Name = "downlinkCapacityLabel";
|
||||
this.downlinkCapacityLabel.Size = new System.Drawing.Size(101, 12);
|
||||
this.downlinkCapacityLabel.Size = new System.Drawing.Size(109, 17);
|
||||
this.downlinkCapacityLabel.TabIndex = 6;
|
||||
this.downlinkCapacityLabel.Text = "downlinkCapacity";
|
||||
//
|
||||
@@ -793,7 +718,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.downlinkCapacityTextBox.Location = new System.Drawing.Point(331, 65);
|
||||
this.downlinkCapacityTextBox.Name = "downlinkCapacityTextBox";
|
||||
this.downlinkCapacityTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.downlinkCapacityTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.downlinkCapacityTextBox.TabIndex = 7;
|
||||
this.downlinkCapacityTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -802,7 +727,7 @@ namespace Netch.Forms
|
||||
this.readBufferSizeLabel.AutoSize = true;
|
||||
this.readBufferSizeLabel.Location = new System.Drawing.Point(6, 109);
|
||||
this.readBufferSizeLabel.Name = "readBufferSizeLabel";
|
||||
this.readBufferSizeLabel.Size = new System.Drawing.Size(89, 12);
|
||||
this.readBufferSizeLabel.Size = new System.Drawing.Size(93, 17);
|
||||
this.readBufferSizeLabel.TabIndex = 8;
|
||||
this.readBufferSizeLabel.Text = "readBufferSize";
|
||||
//
|
||||
@@ -810,16 +735,16 @@ namespace Netch.Forms
|
||||
//
|
||||
this.readBufferSizeTextBox.Location = new System.Drawing.Point(103, 100);
|
||||
this.readBufferSizeTextBox.Name = "readBufferSizeTextBox";
|
||||
this.readBufferSizeTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.readBufferSizeTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.readBufferSizeTextBox.TabIndex = 9;
|
||||
this.readBufferSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// writeBufferSizeLabel
|
||||
//
|
||||
this.writeBufferSizeLabel.AutoSize = true;
|
||||
this.writeBufferSizeLabel.Location = new System.Drawing.Point(224, 109);
|
||||
this.writeBufferSizeLabel.Location = new System.Drawing.Point(216, 109);
|
||||
this.writeBufferSizeLabel.Name = "writeBufferSizeLabel";
|
||||
this.writeBufferSizeLabel.Size = new System.Drawing.Size(95, 12);
|
||||
this.writeBufferSizeLabel.Size = new System.Drawing.Size(94, 17);
|
||||
this.writeBufferSizeLabel.TabIndex = 10;
|
||||
this.writeBufferSizeLabel.Text = "writeBufferSize";
|
||||
//
|
||||
@@ -827,7 +752,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.writeBufferSizeTextBox.Location = new System.Drawing.Point(331, 106);
|
||||
this.writeBufferSizeTextBox.Name = "writeBufferSizeTextBox";
|
||||
this.writeBufferSizeTextBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.writeBufferSizeTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.writeBufferSizeTextBox.TabIndex = 11;
|
||||
this.writeBufferSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -836,7 +761,7 @@ namespace Netch.Forms
|
||||
this.congestionCheckBox.AutoSize = true;
|
||||
this.congestionCheckBox.Location = new System.Drawing.Point(8, 139);
|
||||
this.congestionCheckBox.Name = "congestionCheckBox";
|
||||
this.congestionCheckBox.Size = new System.Drawing.Size(84, 16);
|
||||
this.congestionCheckBox.Size = new System.Drawing.Size(91, 21);
|
||||
this.congestionCheckBox.TabIndex = 12;
|
||||
this.congestionCheckBox.Text = "congestion";
|
||||
this.congestionCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -852,10 +777,10 @@ namespace Netch.Forms
|
||||
this.OtherTabPage.Controls.Add(this.CheckUpdateWhenOpenedCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.CheckBetaUpdateCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.UpdateServersWhenOpenedCheckBox);
|
||||
this.OtherTabPage.Location = new System.Drawing.Point(4, 25);
|
||||
this.OtherTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.OtherTabPage.Name = "OtherTabPage";
|
||||
this.OtherTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.OtherTabPage.Size = new System.Drawing.Size(461, 325);
|
||||
this.OtherTabPage.Size = new System.Drawing.Size(461, 321);
|
||||
this.OtherTabPage.TabIndex = 4;
|
||||
this.OtherTabPage.Text = "Others";
|
||||
//
|
||||
@@ -864,7 +789,7 @@ namespace Netch.Forms
|
||||
this.ExitWhenClosedCheckBox.AutoSize = true;
|
||||
this.ExitWhenClosedCheckBox.Location = new System.Drawing.Point(6, 6);
|
||||
this.ExitWhenClosedCheckBox.Name = "ExitWhenClosedCheckBox";
|
||||
this.ExitWhenClosedCheckBox.Size = new System.Drawing.Size(120, 16);
|
||||
this.ExitWhenClosedCheckBox.Size = new System.Drawing.Size(123, 21);
|
||||
this.ExitWhenClosedCheckBox.TabIndex = 0;
|
||||
this.ExitWhenClosedCheckBox.Text = "Exit when closed";
|
||||
this.ExitWhenClosedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -875,7 +800,7 @@ namespace Netch.Forms
|
||||
this.StopWhenExitedCheckBox.AutoSize = true;
|
||||
this.StopWhenExitedCheckBox.Location = new System.Drawing.Point(200, 6);
|
||||
this.StopWhenExitedCheckBox.Name = "StopWhenExitedCheckBox";
|
||||
this.StopWhenExitedCheckBox.Size = new System.Drawing.Size(120, 16);
|
||||
this.StopWhenExitedCheckBox.Size = new System.Drawing.Size(127, 21);
|
||||
this.StopWhenExitedCheckBox.TabIndex = 1;
|
||||
this.StopWhenExitedCheckBox.Text = "Stop when exited";
|
||||
this.StopWhenExitedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -886,7 +811,7 @@ namespace Netch.Forms
|
||||
this.StartWhenOpenedCheckBox.AutoSize = true;
|
||||
this.StartWhenOpenedCheckBox.Location = new System.Drawing.Point(6, 28);
|
||||
this.StartWhenOpenedCheckBox.Name = "StartWhenOpenedCheckBox";
|
||||
this.StartWhenOpenedCheckBox.Size = new System.Drawing.Size(126, 16);
|
||||
this.StartWhenOpenedCheckBox.Size = new System.Drawing.Size(137, 21);
|
||||
this.StartWhenOpenedCheckBox.TabIndex = 2;
|
||||
this.StartWhenOpenedCheckBox.Text = "Start when opened";
|
||||
this.StartWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -897,7 +822,7 @@ namespace Netch.Forms
|
||||
this.MinimizeWhenStartedCheckBox.AutoSize = true;
|
||||
this.MinimizeWhenStartedCheckBox.Location = new System.Drawing.Point(200, 28);
|
||||
this.MinimizeWhenStartedCheckBox.Name = "MinimizeWhenStartedCheckBox";
|
||||
this.MinimizeWhenStartedCheckBox.Size = new System.Drawing.Size(150, 16);
|
||||
this.MinimizeWhenStartedCheckBox.Size = new System.Drawing.Size(158, 21);
|
||||
this.MinimizeWhenStartedCheckBox.TabIndex = 3;
|
||||
this.MinimizeWhenStartedCheckBox.Text = "Minimize when started";
|
||||
this.MinimizeWhenStartedCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -907,7 +832,7 @@ namespace Netch.Forms
|
||||
this.RunAtStartupCheckBox.AutoSize = true;
|
||||
this.RunAtStartupCheckBox.Location = new System.Drawing.Point(6, 50);
|
||||
this.RunAtStartupCheckBox.Name = "RunAtStartupCheckBox";
|
||||
this.RunAtStartupCheckBox.Size = new System.Drawing.Size(108, 16);
|
||||
this.RunAtStartupCheckBox.Size = new System.Drawing.Size(109, 21);
|
||||
this.RunAtStartupCheckBox.TabIndex = 4;
|
||||
this.RunAtStartupCheckBox.Text = "Run at startup";
|
||||
this.RunAtStartupCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -917,7 +842,7 @@ namespace Netch.Forms
|
||||
this.CheckUpdateWhenOpenedCheckBox.AutoSize = true;
|
||||
this.CheckUpdateWhenOpenedCheckBox.Location = new System.Drawing.Point(200, 50);
|
||||
this.CheckUpdateWhenOpenedCheckBox.Name = "CheckUpdateWhenOpenedCheckBox";
|
||||
this.CheckUpdateWhenOpenedCheckBox.Size = new System.Drawing.Size(168, 16);
|
||||
this.CheckUpdateWhenOpenedCheckBox.Size = new System.Drawing.Size(190, 21);
|
||||
this.CheckUpdateWhenOpenedCheckBox.TabIndex = 5;
|
||||
this.CheckUpdateWhenOpenedCheckBox.Text = "Check update when opened";
|
||||
this.CheckUpdateWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -928,7 +853,7 @@ namespace Netch.Forms
|
||||
this.CheckBetaUpdateCheckBox.AutoSize = true;
|
||||
this.CheckBetaUpdateCheckBox.Location = new System.Drawing.Point(200, 72);
|
||||
this.CheckBetaUpdateCheckBox.Name = "CheckBetaUpdateCheckBox";
|
||||
this.CheckBetaUpdateCheckBox.Size = new System.Drawing.Size(126, 16);
|
||||
this.CheckBetaUpdateCheckBox.Size = new System.Drawing.Size(137, 21);
|
||||
this.CheckBetaUpdateCheckBox.TabIndex = 6;
|
||||
this.CheckBetaUpdateCheckBox.Text = "Check Beta update";
|
||||
this.CheckBetaUpdateCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -939,7 +864,7 @@ namespace Netch.Forms
|
||||
this.UpdateServersWhenOpenedCheckBox.AutoSize = true;
|
||||
this.UpdateServersWhenOpenedCheckBox.Location = new System.Drawing.Point(200, 94);
|
||||
this.UpdateServersWhenOpenedCheckBox.Name = "UpdateServersWhenOpenedCheckBox";
|
||||
this.UpdateServersWhenOpenedCheckBox.Size = new System.Drawing.Size(180, 16);
|
||||
this.UpdateServersWhenOpenedCheckBox.Size = new System.Drawing.Size(200, 21);
|
||||
this.UpdateServersWhenOpenedCheckBox.TabIndex = 7;
|
||||
this.UpdateServersWhenOpenedCheckBox.Text = "Update Servers when opened";
|
||||
this.UpdateServersWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
@@ -953,10 +878,10 @@ namespace Netch.Forms
|
||||
this.AioDNSTabPage.Controls.Add(this.ChinaDNSTextBox);
|
||||
this.AioDNSTabPage.Controls.Add(this.OtherDNSLabel);
|
||||
this.AioDNSTabPage.Controls.Add(this.OtherDNSTextBox);
|
||||
this.AioDNSTabPage.Location = new System.Drawing.Point(4, 25);
|
||||
this.AioDNSTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.AioDNSTabPage.Name = "AioDNSTabPage";
|
||||
this.AioDNSTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.AioDNSTabPage.Size = new System.Drawing.Size(461, 325);
|
||||
this.AioDNSTabPage.Size = new System.Drawing.Size(461, 321);
|
||||
this.AioDNSTabPage.TabIndex = 5;
|
||||
this.AioDNSTabPage.Text = "AioDNS";
|
||||
this.AioDNSTabPage.UseVisualStyleBackColor = true;
|
||||
@@ -964,51 +889,51 @@ namespace Netch.Forms
|
||||
// AioDNSRuleRuleLabel
|
||||
//
|
||||
this.AioDNSRuleRuleLabel.AutoSize = true;
|
||||
this.AioDNSRuleRuleLabel.Location = new System.Drawing.Point(16, 27);
|
||||
this.AioDNSRuleRuleLabel.Location = new System.Drawing.Point(16, 30);
|
||||
this.AioDNSRuleRuleLabel.Name = "AioDNSRuleRuleLabel";
|
||||
this.AioDNSRuleRuleLabel.Size = new System.Drawing.Size(59, 12);
|
||||
this.AioDNSRuleRuleLabel.Size = new System.Drawing.Size(56, 17);
|
||||
this.AioDNSRuleRuleLabel.TabIndex = 0;
|
||||
this.AioDNSRuleRuleLabel.Text = "Rule File";
|
||||
//
|
||||
// AioDNSRulePathTextBox
|
||||
//
|
||||
this.AioDNSRulePathTextBox.Enabled = false;
|
||||
this.AioDNSRulePathTextBox.Location = new System.Drawing.Point(147, 24);
|
||||
this.AioDNSRulePathTextBox.Location = new System.Drawing.Point(150, 30);
|
||||
this.AioDNSRulePathTextBox.Name = "AioDNSRulePathTextBox";
|
||||
this.AioDNSRulePathTextBox.Size = new System.Drawing.Size(201, 21);
|
||||
this.AioDNSRulePathTextBox.Size = new System.Drawing.Size(201, 23);
|
||||
this.AioDNSRulePathTextBox.TabIndex = 1;
|
||||
//
|
||||
// ChinaDNSLabel
|
||||
//
|
||||
this.ChinaDNSLabel.AutoSize = true;
|
||||
this.ChinaDNSLabel.Location = new System.Drawing.Point(16, 64);
|
||||
this.ChinaDNSLabel.Location = new System.Drawing.Point(16, 70);
|
||||
this.ChinaDNSLabel.Name = "ChinaDNSLabel";
|
||||
this.ChinaDNSLabel.Size = new System.Drawing.Size(59, 12);
|
||||
this.ChinaDNSLabel.Size = new System.Drawing.Size(70, 17);
|
||||
this.ChinaDNSLabel.TabIndex = 2;
|
||||
this.ChinaDNSLabel.Text = "China DNS";
|
||||
//
|
||||
// ChinaDNSTextBox
|
||||
//
|
||||
this.ChinaDNSTextBox.Location = new System.Drawing.Point(147, 61);
|
||||
this.ChinaDNSTextBox.Location = new System.Drawing.Point(150, 70);
|
||||
this.ChinaDNSTextBox.Name = "ChinaDNSTextBox";
|
||||
this.ChinaDNSTextBox.Size = new System.Drawing.Size(201, 21);
|
||||
this.ChinaDNSTextBox.Size = new System.Drawing.Size(201, 23);
|
||||
this.ChinaDNSTextBox.TabIndex = 3;
|
||||
this.ChinaDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// OtherDNSLabel
|
||||
//
|
||||
this.OtherDNSLabel.AutoSize = true;
|
||||
this.OtherDNSLabel.Location = new System.Drawing.Point(16, 103);
|
||||
this.OtherDNSLabel.Location = new System.Drawing.Point(16, 110);
|
||||
this.OtherDNSLabel.Name = "OtherDNSLabel";
|
||||
this.OtherDNSLabel.Size = new System.Drawing.Size(59, 12);
|
||||
this.OtherDNSLabel.Size = new System.Drawing.Size(71, 17);
|
||||
this.OtherDNSLabel.TabIndex = 4;
|
||||
this.OtherDNSLabel.Text = "Other DNS";
|
||||
//
|
||||
// OtherDNSTextBox
|
||||
//
|
||||
this.OtherDNSTextBox.Location = new System.Drawing.Point(147, 100);
|
||||
this.OtherDNSTextBox.Location = new System.Drawing.Point(150, 110);
|
||||
this.OtherDNSTextBox.Name = "OtherDNSTextBox";
|
||||
this.OtherDNSTextBox.Size = new System.Drawing.Size(201, 21);
|
||||
this.OtherDNSTextBox.Size = new System.Drawing.Size(201, 23);
|
||||
this.OtherDNSTextBox.TabIndex = 5;
|
||||
this.OtherDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -1059,9 +984,9 @@ namespace Netch.Forms
|
||||
this.NFTabPage.PerformLayout();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.TAPTabPage.ResumeLayout(false);
|
||||
this.TUNTAPGroupBox.ResumeLayout(false);
|
||||
this.TUNTAPGroupBox.PerformLayout();
|
||||
this.WinTUNTabPage.ResumeLayout(false);
|
||||
this.WinTUNGroupBox.ResumeLayout(false);
|
||||
this.WinTUNGroupBox.PerformLayout();
|
||||
this.v2rayTabPage.ResumeLayout(false);
|
||||
this.v2rayTabPage.PerformLayout();
|
||||
this.KCPGroupBox.ResumeLayout(false);
|
||||
@@ -1083,19 +1008,16 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.TabControl TabControl;
|
||||
private System.Windows.Forms.TabPage GeneralTabPage;
|
||||
private System.Windows.Forms.TabPage NFTabPage;
|
||||
private System.Windows.Forms.TabPage TAPTabPage;
|
||||
private System.Windows.Forms.TabPage WinTUNTabPage;
|
||||
private System.Windows.Forms.TabPage v2rayTabPage;
|
||||
private System.Windows.Forms.GroupBox PortGroupBox;
|
||||
private System.Windows.Forms.Label RedirectorLabel;
|
||||
private System.Windows.Forms.TextBox RedirectorTextBox;
|
||||
private System.Windows.Forms.CheckBox AllowDevicesCheckBox;
|
||||
private System.Windows.Forms.Label HTTPPortLabel;
|
||||
private System.Windows.Forms.TextBox HTTPPortTextBox;
|
||||
private System.Windows.Forms.Label Socks5PortLabel;
|
||||
private System.Windows.Forms.TextBox Socks5PortTextBox;
|
||||
private System.Windows.Forms.CheckBox ResolveServerHostnameCheckBox;
|
||||
private System.Windows.Forms.GroupBox TUNTAPGroupBox;
|
||||
private System.Windows.Forms.CheckBox UseFakeDNSCheckBox;
|
||||
private System.Windows.Forms.GroupBox WinTUNGroupBox;
|
||||
private System.Windows.Forms.CheckBox ProxyDNSCheckBox;
|
||||
private System.Windows.Forms.CheckBox UseCustomDNSCheckBox;
|
||||
private System.Windows.Forms.Label TUNTAPDNSLabel;
|
||||
@@ -1107,7 +1029,7 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.Label TUNTAPAddressLabel;
|
||||
private System.Windows.Forms.TextBox TUNTAPAddressTextBox;
|
||||
private System.Windows.Forms.Button GlobalBypassIPsButton;
|
||||
private System.Windows.Forms.CheckBox DNSRedirectorCheckBox;
|
||||
private System.Windows.Forms.CheckBox DNSHijackCheckBox;
|
||||
private System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
||||
private System.Windows.Forms.TabPage OtherTabPage;
|
||||
@@ -1121,8 +1043,6 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.CheckBox ExitWhenClosedCheckBox;
|
||||
private System.Windows.Forms.Label LanguageLabel;
|
||||
private System.Windows.Forms.ComboBox LanguageComboBox;
|
||||
private System.Windows.Forms.TextBox AclAddrTextBox;
|
||||
private System.Windows.Forms.Label AclLabel;
|
||||
private System.Windows.Forms.Label DetectionTickLabel;
|
||||
private System.Windows.Forms.TextBox DetectionTickTextBox;
|
||||
private System.Windows.Forms.Label StartedPingLabel;
|
||||
@@ -1153,18 +1073,16 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.Label ChinaDNSLabel;
|
||||
private System.Windows.Forms.TextBox OtherDNSTextBox;
|
||||
private System.Windows.Forms.TextBox ChinaDNSTextBox;
|
||||
private System.Windows.Forms.TextBox RDRDNSTextBox;
|
||||
private System.Windows.Forms.Label RDRDNSLabel;
|
||||
private System.Windows.Forms.TextBox DNSHijackHostTextBox;
|
||||
private System.Windows.Forms.CheckBox RedirectorSSCheckBox;
|
||||
private System.Windows.Forms.Label ServerPingTypeLabel;
|
||||
private System.Windows.Forms.RadioButton TCPingRadioBtn;
|
||||
private System.Windows.Forms.RadioButton ICMPingRadioBtn;
|
||||
private System.Windows.Forms.ComboBox ProcessProxyProtocolComboBox;
|
||||
private System.Windows.Forms.Label ProcessProxyProtocolLabel;
|
||||
private System.Windows.Forms.CheckBox ICMPRedirectorCheckBox;
|
||||
private System.Windows.Forms.TextBox ModifiedICMPTextBox;
|
||||
private System.Windows.Forms.Label RDRICMPLabel;
|
||||
private System.Windows.Forms.CheckBox ICMPHijackCheckBox;
|
||||
private System.Windows.Forms.CheckBox ChildProcessHandleCheckBox;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.TextBox ICMPHijackHostTextBox;
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@ using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
|
||||
@@ -26,20 +26,15 @@ namespace Netch.Forms
|
||||
#region General
|
||||
|
||||
BindTextBox<ushort>(Socks5PortTextBox,
|
||||
p => p.ToString() != HTTPPortTextBox.Text && p.ToString() != RedirectorTextBox.Text,
|
||||
p => p.ToString() != HTTPPortTextBox.Text,
|
||||
p => Global.Settings.Socks5LocalPort = p,
|
||||
Global.Settings.Socks5LocalPort);
|
||||
|
||||
BindTextBox<ushort>(HTTPPortTextBox,
|
||||
p => p.ToString() != Socks5PortTextBox.Text && p.ToString() != RedirectorTextBox.Text,
|
||||
p => p.ToString() != Socks5PortTextBox.Text,
|
||||
p => Global.Settings.HTTPLocalPort = p,
|
||||
Global.Settings.HTTPLocalPort);
|
||||
|
||||
BindTextBox<ushort>(RedirectorTextBox,
|
||||
p => p.ToString() != Socks5PortTextBox.Text && p.ToString() != HTTPPortTextBox.Text,
|
||||
p => Global.Settings.RedirectorTCPPort = p,
|
||||
Global.Settings.RedirectorTCPPort);
|
||||
|
||||
BindCheckBox(AllowDevicesCheckBox,
|
||||
c => Global.Settings.LocalAddress = AllowDevicesCheckBox.Checked ? "0.0.0.0" : "127.0.0.1",
|
||||
Global.Settings.LocalAddress switch {"127.0.0.1" => false, "0.0.0.0" => true, _ => false});
|
||||
@@ -68,7 +63,7 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning($"Load stun.txt failed: {e.Message}");
|
||||
Global.Logger.Warning($"Load stun.txt failed: {e.Message}");
|
||||
stuns = null;
|
||||
}
|
||||
|
||||
@@ -97,33 +92,33 @@ namespace Netch.Forms
|
||||
Global.Settings.STUN_Server + ":" + Global.Settings.STUN_Server_Port,
|
||||
stuns);
|
||||
|
||||
BindTextBox<string>(AclAddrTextBox, s => true, s => Global.Settings.ACL = s, Global.Settings.ACL);
|
||||
|
||||
BindListComboBox(LanguageComboBox,
|
||||
o => Global.Settings.Language = o.ToString(),
|
||||
i18N.GetTranslateList().Cast<object>().ToArray(),
|
||||
Global.Settings.Language);
|
||||
BindListComboBox(LanguageComboBox, o => Global.Settings.Language = o.ToString(), i18N.GetTranslateList(), Global.Settings.Language);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Process Mode
|
||||
|
||||
BindCheckBox(DNSRedirectorCheckBox, b => Global.Settings.RedirectDNS = b, Global.Settings.RedirectDNS);
|
||||
BindCheckBox(DNSHijackCheckBox, b => Global.Settings.Redirector.DNSHijack = b, Global.Settings.Redirector.DNSHijack);
|
||||
|
||||
BindTextBox(RDRDNSTextBox, s => DnsUtils.TrySplit(s, out _, 2), s => Global.Settings.RedirectDNSAddr = s, Global.Settings.RedirectDNSAddr);
|
||||
BindTextBox(DNSHijackHostTextBox, s => true, s => Global.Settings.Redirector.DNSHijackHost = s, Global.Settings.Redirector.DNSHijackHost);
|
||||
|
||||
BindCheckBox(ICMPRedirectorCheckBox, b => Global.Settings.RedirectICMP = b, Global.Settings.RedirectICMP);
|
||||
BindCheckBox(ICMPHijackCheckBox, b => Global.Settings.Redirector.ICMPHijack = b, Global.Settings.Redirector.ICMPHijack);
|
||||
|
||||
BindTextBox(ModifiedICMPTextBox, s => DnsUtils.TrySplit(s, out _, 2), s => Global.Settings.RedirectICMPAddr = s, Global.Settings.RedirectICMPAddr);
|
||||
BindTextBox(ICMPHijackHostTextBox,
|
||||
s => IPAddress.TryParse(s, out _),
|
||||
s => Global.Settings.Redirector.ICMPHost = s,
|
||||
Global.Settings.Redirector.ICMPHost);
|
||||
|
||||
BindCheckBox(RedirectorSSCheckBox, s => Global.Settings.RedirectorSS = s, Global.Settings.RedirectorSS);
|
||||
BindCheckBox(RedirectorSSCheckBox, s => Global.Settings.Redirector.RedirectorSS = s, Global.Settings.Redirector.RedirectorSS);
|
||||
|
||||
BindCheckBox(ChildProcessHandleCheckBox, s => Global.Settings.ChildProcessHandle = s, Global.Settings.ChildProcessHandle);
|
||||
BindCheckBox(ChildProcessHandleCheckBox,
|
||||
s => Global.Settings.Redirector.ChildProcessHandle = s,
|
||||
Global.Settings.Redirector.ChildProcessHandle);
|
||||
|
||||
BindListComboBox(ProcessProxyProtocolComboBox,
|
||||
s => Global.Settings.ProcessProxyProtocol = (PortType) Enum.Parse(typeof(PortType), s.ToString(), false),
|
||||
Enum.GetNames(typeof(PortType)).Cast<object>().ToArray(),
|
||||
Global.Settings.ProcessProxyProtocol.ToString());
|
||||
s => Global.Settings.Redirector.ProxyProtocol = (PortType) Enum.Parse(typeof(PortType), s.ToString(), false),
|
||||
Enum.GetNames(typeof(PortType)),
|
||||
Global.Settings.Redirector.ProxyProtocol.ToString());
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -147,16 +142,15 @@ namespace Netch.Forms
|
||||
BindCheckBox(UseCustomDNSCheckBox, b => { Global.Settings.TUNTAP.UseCustomDNS = b; }, Global.Settings.TUNTAP.UseCustomDNS);
|
||||
|
||||
BindTextBox(TUNTAPDNSTextBox,
|
||||
s => !UseCustomDNSCheckBox.Checked || DnsUtils.TrySplit(s, out _, 2),
|
||||
_ => true,
|
||||
s =>
|
||||
{
|
||||
if (UseCustomDNSCheckBox.Checked)
|
||||
Global.Settings.TUNTAP.DNS = DnsUtils.Split(s).ToList();
|
||||
Global.Settings.TUNTAP.HijackDNS = s;
|
||||
},
|
||||
DnsUtils.Join(Global.Settings.TUNTAP.DNS));
|
||||
Global.Settings.TUNTAP.HijackDNS);
|
||||
|
||||
BindCheckBox(ProxyDNSCheckBox, b => Global.Settings.TUNTAP.ProxyDNS = b, Global.Settings.TUNTAP.ProxyDNS);
|
||||
BindCheckBox(UseFakeDNSCheckBox, b => Global.Settings.TUNTAP.UseFakeDNS = b, Global.Settings.TUNTAP.UseFakeDNS);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -217,17 +211,11 @@ namespace Netch.Forms
|
||||
|
||||
#region AioDNS
|
||||
|
||||
BindTextBox(AioDNSRulePathTextBox, s => true, s => Global.Settings.AioDNS.RulePath = s, Global.Settings.AioDNS.RulePath);
|
||||
BindTextBox(AioDNSRulePathTextBox, _ => true, s => Global.Settings.AioDNS.RulePath = s, Global.Settings.AioDNS.RulePath);
|
||||
|
||||
BindTextBox(ChinaDNSTextBox,
|
||||
s => IPAddress.TryParse(s, out _),
|
||||
s => Global.Settings.AioDNS.ChinaDNS = s,
|
||||
Global.Settings.AioDNS.ChinaDNS);
|
||||
BindTextBox(ChinaDNSTextBox, _ => true, s => Global.Settings.AioDNS.ChinaDNS = s, Global.Settings.AioDNS.ChinaDNS);
|
||||
|
||||
BindTextBox(OtherDNSTextBox,
|
||||
s => IPAddress.TryParse(s, out _),
|
||||
s => Global.Settings.AioDNS.OtherDNS = s,
|
||||
Global.Settings.AioDNS.OtherDNS);
|
||||
BindTextBox(OtherDNSTextBox, _ => true, s => Global.Settings.AioDNS.OtherDNS = s, Global.Settings.AioDNS.OtherDNS);
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -235,13 +223,12 @@ namespace Netch.Forms
|
||||
private void SettingForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null);
|
||||
Task.Run(() => BeginInvoke(new Action(() => UseFakeDNSCheckBox.Visible = Global.Flags.SupportFakeDns)));
|
||||
}
|
||||
|
||||
private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
if (UseCustomDNSCheckBox.Checked)
|
||||
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any() ? DnsUtils.Join(Global.Settings.TUNTAP.DNS) : "1.1.1.1";
|
||||
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.HijackDNS;
|
||||
else
|
||||
TUNTAPDNSTextBox.Text = "AioDNS";
|
||||
}
|
||||
@@ -320,14 +307,19 @@ namespace Netch.Forms
|
||||
_saveActions.Add(control, c => save.Invoke(((RadioButton) c).Checked));
|
||||
}
|
||||
|
||||
private void BindListComboBox(ComboBox control, Action<object> save, object[] values, object value, string propertyName = "SelectedItem")
|
||||
private void BindListComboBox<T>(ComboBox comboBox, Action<T> save, IEnumerable<T> values, T value) where T : notnull
|
||||
{
|
||||
if (control.DropDownStyle != ComboBoxStyle.DropDownList)
|
||||
if (comboBox.DropDownStyle != ComboBoxStyle.DropDownList)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
control.Items.AddRange(values);
|
||||
_saveActions.Add(control, c => save.Invoke(((ComboBox) c).SelectedItem));
|
||||
Load += (_, _) => { control.SelectedItem = value; };
|
||||
var tagItems = values.Select(o => new TagItem<T>(o, o.ToString()!)).ToArray();
|
||||
comboBox.Items.AddRange(tagItems.Cast<object>().ToArray());
|
||||
|
||||
comboBox.ValueMember = nameof(TagItem<T>.Value);
|
||||
comboBox.DisplayMember = nameof(TagItem<T>.Text);
|
||||
|
||||
_saveActions.Add(comboBox, c => save.Invoke(((TagItem<T>) ((ComboBox) c).SelectedItem).Value));
|
||||
Load += (_, _) => { comboBox.SelectedItem = tagItems.SingleOrDefault(t => t.Value.Equals(value)); };
|
||||
}
|
||||
|
||||
private void BindComboBox(ComboBox control, Func<string, bool> check, Action<string> save, string value, object[]? values = null)
|
||||
|
||||
@@ -1,64 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
||||
@@ -2,37 +2,21 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Forms;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Loggers;
|
||||
|
||||
namespace Netch
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
/// <summary>
|
||||
/// 换行
|
||||
/// </summary>
|
||||
public const string EOF = "\r\n";
|
||||
|
||||
public const string UserACL = "data\\user.acl";
|
||||
public const string BuiltinACL = "bin\\default.acl";
|
||||
|
||||
public static readonly string NetchDir = Application.StartupPath;
|
||||
|
||||
public static readonly string NetchExecutable = Application.ExecutablePath;
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体的静态实例
|
||||
/// </summary>
|
||||
private static readonly Lazy<MainForm> LazyMainForm = new(() => new MainForm());
|
||||
|
||||
private static readonly Lazy<Mutex> LazyMutex = new(() => new Mutex(false, "Global\\Netch"));
|
||||
|
||||
public static Mutex Mutex => LazyMutex.Value;
|
||||
|
||||
/// <summary>
|
||||
/// 用于读取和写入的配置
|
||||
/// </summary>
|
||||
@@ -43,15 +27,22 @@ namespace Netch
|
||||
/// </summary>
|
||||
public static readonly List<Mode> Modes = new();
|
||||
|
||||
public static class Flags
|
||||
public static readonly string NetchDir;
|
||||
public static readonly string NetchExecutable;
|
||||
|
||||
static Global()
|
||||
{
|
||||
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
|
||||
|
||||
private static readonly Lazy<bool> LazySupportFakeDns = new(() => new TUNTAPController().TestFakeDNS());
|
||||
|
||||
public static bool SupportFakeDns => LazySupportFakeDns.Value;
|
||||
NetchExecutable = Application.ExecutablePath;
|
||||
NetchDir = Application.StartupPath;
|
||||
#if DEBUG
|
||||
Logger = new ConsoleLogger();
|
||||
#else
|
||||
Logger = new FileLogger();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static ILogger Logger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体的静态实例
|
||||
/// </summary>
|
||||
|
||||
11
Netch/Interfaces/ILogger.cs
Normal file
11
Netch/Interfaces/ILogger.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Netch.Interfaces
|
||||
{
|
||||
public interface ILogger
|
||||
{
|
||||
void Info(string text);
|
||||
void Warning(string text);
|
||||
void Error(string text);
|
||||
void Debug(string s);
|
||||
void ShowLog();
|
||||
}
|
||||
}
|
||||
33
Netch/Interops/AioDNSInterops.cs
Normal file
33
Netch/Interops/AioDNSInterops.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public static class AioDNSInterops
|
||||
{
|
||||
private const string aiodns_bin = "aiodns.bin";
|
||||
|
||||
public static bool Dial(NameList name, string value)
|
||||
{
|
||||
return aiodns_dial(name, Encoding.UTF8.GetBytes(value));
|
||||
}
|
||||
|
||||
[DllImport(aiodns_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aiodns_dial(NameList name, byte[] value);
|
||||
|
||||
[DllImport(aiodns_bin, EntryPoint = "aiodns_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool Init();
|
||||
|
||||
[DllImport(aiodns_bin, EntryPoint = "aiodns_free", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void Free();
|
||||
|
||||
public enum NameList
|
||||
{
|
||||
TYPE_REST,
|
||||
TYPE_ADDR,
|
||||
TYPE_LIST,
|
||||
TYPE_CDNS,
|
||||
TYPE_ODNS
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Netch/Interops/NFAPI.cs
Normal file
20
Netch/Interops/NFAPI.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public static class NFAPI
|
||||
{
|
||||
private const string nfapinet_bin = "nfapinet.dll";
|
||||
|
||||
[DllImport(nfapinet_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern NF_STATUS nf_registerDriver(string driverName);
|
||||
|
||||
[DllImport(nfapinet_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern NF_STATUS nf_unRegisterDriver(string driverName);
|
||||
}
|
||||
}
|
||||
11
Netch/Interops/NF_STATUS.cs
Normal file
11
Netch/Interops/NF_STATUS.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public enum NF_STATUS : int
|
||||
{
|
||||
NF_STATUS_SUCCESS = 0,
|
||||
NF_STATUS_FAIL = -1,
|
||||
NF_STATUS_INVALID_ENDPOINT_ID = -2,
|
||||
NF_STATUS_NOT_INITIALIZED = -3,
|
||||
NF_STATUS_IO_ERROR = -4
|
||||
}
|
||||
}
|
||||
79
Netch/Interops/RedirectorInterop.cs
Normal file
79
Netch/Interops/RedirectorInterop.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public static class RedirectorInterop
|
||||
{
|
||||
public enum NameList
|
||||
{
|
||||
TYPE_FILTERLOOPBACK,
|
||||
TYPE_FILTERICMP,
|
||||
TYPE_FILTERTCP,
|
||||
TYPE_FILTERUDP,
|
||||
|
||||
TYPE_CLRNAME,
|
||||
TYPE_ADDNAME,
|
||||
TYPE_BYPNAME,
|
||||
|
||||
TYPE_DNSHOST,
|
||||
|
||||
TYPE_TCPLISN,
|
||||
TYPE_TCPTYPE,
|
||||
TYPE_TCPHOST,
|
||||
TYPE_TCPUSER,
|
||||
TYPE_TCPPASS,
|
||||
TYPE_TCPMETH,
|
||||
TYPE_TCPPROT,
|
||||
TYPE_TCPPRPA,
|
||||
TYPE_TCPOBFS,
|
||||
TYPE_TCPOBPA,
|
||||
|
||||
TYPE_UDPLISN,
|
||||
TYPE_UDPTYPE,
|
||||
TYPE_UDPHOST,
|
||||
TYPE_UDPUSER,
|
||||
TYPE_UDPPASS,
|
||||
TYPE_UDPMETH,
|
||||
TYPE_UDPPROT,
|
||||
TYPE_UDPPRPA,
|
||||
TYPE_UDPOBFS,
|
||||
TYPE_UDPOBPA
|
||||
}
|
||||
|
||||
public static bool Dial(NameList name, string value)
|
||||
{
|
||||
Global.Logger.Debug($"Dial {name} {value}");
|
||||
return aio_dial(name, value);
|
||||
}
|
||||
|
||||
public static bool Init()
|
||||
{
|
||||
return aio_init();
|
||||
}
|
||||
|
||||
public static bool Free()
|
||||
{
|
||||
return aio_free();
|
||||
}
|
||||
|
||||
public const int UdpNameListOffset = (int) NameList.TYPE_UDPLISN - (int) NameList.TYPE_TCPLISN;
|
||||
|
||||
private const string Redirector_bin = "Redirector.bin";
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_dial(NameList name, [MarshalAs(UnmanagedType.LPWStr)] string value);
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_init();
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_free();
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong aio_getUP();
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong aio_getDL();
|
||||
}
|
||||
}
|
||||
73
Netch/Interops/TUNInterop.cs
Normal file
73
Netch/Interops/TUNInterop.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public static class TUNInterop
|
||||
{
|
||||
public enum NameList
|
||||
{
|
||||
TYPE_BYPBIND,
|
||||
TYPE_BYPLIST,
|
||||
TYPE_DNSADDR,
|
||||
TYPE_ADAPMTU,
|
||||
TYPE_TCPREST,
|
||||
TYPE_TCPTYPE,
|
||||
TYPE_TCPHOST,
|
||||
TYPE_TCPUSER,
|
||||
TYPE_TCPPASS,
|
||||
TYPE_TCPMETH,
|
||||
TYPE_TCPPROT,
|
||||
TYPE_TCPPRPA,
|
||||
TYPE_TCPOBFS,
|
||||
TYPE_TCPOBPA,
|
||||
TYPE_UDPREST,
|
||||
TYPE_UDPTYPE,
|
||||
TYPE_UDPHOST,
|
||||
TYPE_UDPUSER,
|
||||
TYPE_UDPPASS,
|
||||
TYPE_UDPMETH,
|
||||
TYPE_UDPPROT,
|
||||
TYPE_UDPPRPA,
|
||||
TYPE_UDPOBFS,
|
||||
TYPE_UDPOBPA
|
||||
}
|
||||
|
||||
public static bool Dial(NameList name, string value)
|
||||
{
|
||||
Global.Logger.Debug($"Dial {name} {value}");
|
||||
return tun_dial(name, Encoding.UTF8.GetBytes(value));
|
||||
}
|
||||
|
||||
public static bool Init()
|
||||
{
|
||||
return tun_init();
|
||||
}
|
||||
|
||||
public static bool Free()
|
||||
{
|
||||
return tun_free();
|
||||
}
|
||||
|
||||
private const string tun2socks_bin = "tun2socks.bin";
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool tun_dial(NameList name, byte[] value);
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool tun_init();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool tun_free();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern ulong tun_luid();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong tun_getUP();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern ulong tun_getDL();
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,31 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
|
||||
namespace Netch.Models.GitHubRelease
|
||||
{
|
||||
[Serializable]
|
||||
public struct SuffixVersion : ICloneable, IComparable, IComparable<SuffixVersion>, IEquatable<SuffixVersion>
|
||||
public struct SuffixVersion : IComparable, IComparable<SuffixVersion>
|
||||
{
|
||||
public int Major { get; }
|
||||
public Version Version { get; }
|
||||
|
||||
public int Minor { get; }
|
||||
public string Suffix { get; }
|
||||
|
||||
public int Patch { get; }
|
||||
|
||||
public string PreRelease { get; }
|
||||
|
||||
public int Build { get; }
|
||||
|
||||
public SuffixVersion(int major, int minor, int patch, string preRelease, int build)
|
||||
public SuffixVersion(Version version, string suffix)
|
||||
{
|
||||
Major = major;
|
||||
Minor = minor;
|
||||
Patch = patch;
|
||||
PreRelease = preRelease;
|
||||
Build = build;
|
||||
Version = version;
|
||||
Suffix = suffix;
|
||||
}
|
||||
|
||||
public SuffixVersion(Version version, string preRelease, int build)
|
||||
public static SuffixVersion Parse(string? input)
|
||||
{
|
||||
Major = version.Major;
|
||||
Minor = version.Minor;
|
||||
Patch = version.Build;
|
||||
PreRelease = preRelease;
|
||||
Build = build;
|
||||
}
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
public static SuffixVersion Parse(string input)
|
||||
{
|
||||
var splitStr = input.Split('-');
|
||||
var dotNetVersion = Version.Parse(splitStr[0]);
|
||||
var preRelease = new StringBuilder();
|
||||
var build = 0;
|
||||
var split = input.Split('-');
|
||||
var dotNetVersion = Version.Parse(split[0]);
|
||||
var preRelease = split.ElementAtOrDefault(1) ?? string.Empty;
|
||||
|
||||
if (splitStr.Length > 1)
|
||||
foreach (var c in splitStr[1])
|
||||
if (int.TryParse(c.ToString(), out var n))
|
||||
build = build * 10 + n;
|
||||
else
|
||||
preRelease.Append(c);
|
||||
|
||||
return new SuffixVersion(dotNetVersion, preRelease.ToString(), build);
|
||||
return new SuffixVersion(dotNetVersion, preRelease);
|
||||
}
|
||||
|
||||
public static bool TryParse(string input, out SuffixVersion result)
|
||||
@@ -65,17 +42,12 @@ namespace Netch.Models.GitHubRelease
|
||||
}
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
public int CompareTo(object? obj)
|
||||
{
|
||||
return new SuffixVersion(Major, Major, Patch, PreRelease, Build);
|
||||
}
|
||||
if (obj is not SuffixVersion version)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is SuffixVersion version)
|
||||
return CompareTo(version);
|
||||
|
||||
return -1;
|
||||
return CompareTo(version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,57 +58,27 @@ namespace Netch.Models.GitHubRelease
|
||||
/// </returns>
|
||||
public int CompareTo(SuffixVersion other)
|
||||
{
|
||||
var majorComparison = Major.CompareTo(other.Major);
|
||||
if (majorComparison != 0)
|
||||
return majorComparison;
|
||||
var versionComparison = Version.CompareTo(other.Version);
|
||||
if (versionComparison != 0)
|
||||
return versionComparison;
|
||||
|
||||
var minorComparison = Minor.CompareTo(other.Minor);
|
||||
if (minorComparison != 0)
|
||||
return minorComparison;
|
||||
if (Suffix == string.Empty)
|
||||
return other.Suffix == string.Empty ? 0 : 1;
|
||||
|
||||
var patchComparison = Patch.CompareTo(other.Patch);
|
||||
if (patchComparison != 0)
|
||||
return patchComparison;
|
||||
|
||||
if (PreRelease == string.Empty)
|
||||
return other.PreRelease == string.Empty ? 0 : 1;
|
||||
|
||||
if (other.PreRelease == string.Empty)
|
||||
if (other.Suffix == string.Empty)
|
||||
return -1;
|
||||
|
||||
var suffixComparison = string.Compare(PreRelease, other.PreRelease, StringComparison.Ordinal);
|
||||
if (suffixComparison != 0)
|
||||
return suffixComparison;
|
||||
|
||||
return Build.CompareTo(other.Build);
|
||||
}
|
||||
|
||||
public bool Equals(SuffixVersion other)
|
||||
{
|
||||
return Major == other.Major && Minor == other.Minor && Patch == other.Patch && PreRelease == other.PreRelease && Build == other.Build;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is SuffixVersion other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Major;
|
||||
hashCode = (hashCode * 397) ^ Minor;
|
||||
hashCode = (hashCode * 397) ^ Patch;
|
||||
hashCode = (hashCode * 397) ^ (PreRelease != null ? PreRelease.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ Build;
|
||||
return hashCode;
|
||||
}
|
||||
var suffixComparison = string.Compare(Suffix, other.Suffix, StringComparison.OrdinalIgnoreCase);
|
||||
return suffixComparison;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Major}.{Minor}.{Patch}{(string.IsNullOrEmpty(PreRelease) ? "" : "-")}{PreRelease}{(Build == 0 ? "" : Build.ToString())}";
|
||||
var s = Version.ToString();
|
||||
if (Suffix != string.Empty)
|
||||
s += $"-{Suffix}";
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Models.GitHubRelease
|
||||
{
|
||||
public class VersionComparer : IComparer<object>
|
||||
{
|
||||
public int Compare(object x, object y)
|
||||
public int Compare(object? x, object? y)
|
||||
{
|
||||
if (x == null)
|
||||
throw new ArgumentNullException(nameof(x));
|
||||
|
||||
if (y == null)
|
||||
throw new ArgumentNullException(nameof(y));
|
||||
|
||||
return VersionUtil.CompareVersion(x.ToString(), y.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Netch.Models.GitHubRelease
|
||||
/// <returns> =0:versions are equal</returns>
|
||||
/// <returns> >0:version1 is greater</returns>
|
||||
/// <returns> <0:version2 is greater</returns>
|
||||
public static int CompareVersion(string v1, string v2)
|
||||
public static int CompareVersion(string? v1, string? v2)
|
||||
{
|
||||
var version1 = SuffixVersion.Parse(v1);
|
||||
var version2 = SuffixVersion.Parse(v2);
|
||||
|
||||
@@ -3,13 +3,12 @@ using System.Net.NetworkInformation;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public interface IAdapter
|
||||
public interface IAdapter
|
||||
{
|
||||
public abstract int Index { get; }
|
||||
int InterfaceIndex { get; }
|
||||
|
||||
public abstract IPAddress Gateway { get; }
|
||||
|
||||
public abstract NetworkInterface NetworkInterface { get; }
|
||||
IPAddress Gateway { get; }
|
||||
|
||||
NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace Netch.Models
|
||||
{
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR
|
||||
ERROR,
|
||||
DEBUG
|
||||
}
|
||||
}
|
||||
52
Netch/Models/Loggers/ConsoleLogger.cs
Normal file
52
Netch/Models/Loggers/ConsoleLogger.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Netch.Interfaces;
|
||||
|
||||
namespace Netch.Models.Loggers
|
||||
{
|
||||
public class ConsoleLogger : ILogger
|
||||
{
|
||||
public void Info(string text)
|
||||
{
|
||||
Write(text, LogLevel.INFO);
|
||||
}
|
||||
|
||||
public void Warning(string text)
|
||||
{
|
||||
Write(text, LogLevel.WARNING);
|
||||
}
|
||||
|
||||
public void Error(string text)
|
||||
{
|
||||
Write(text, LogLevel.ERROR);
|
||||
}
|
||||
|
||||
private void Write(string text, LogLevel logLevel)
|
||||
{
|
||||
var contents = $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Constants.EOF}";
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.DEBUG:
|
||||
case LogLevel.INFO:
|
||||
case LogLevel.WARNING:
|
||||
Console.Write(contents);
|
||||
break;
|
||||
case LogLevel.ERROR:
|
||||
Console.Error.Write(contents);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void Debug(string s)
|
||||
{
|
||||
#if DEBUG
|
||||
Write(s, LogLevel.DEBUG);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void ShowLog()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Netch/Models/Loggers/FileLogger.cs
Normal file
48
Netch/Models/Loggers/FileLogger.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Netch.Interfaces;
|
||||
|
||||
namespace Netch.Models.Loggers
|
||||
{
|
||||
public class FileLogger : ILogger
|
||||
{
|
||||
public string LogFile { get; set; }= Path.Combine(Global.NetchDir, "logging\\application.log");
|
||||
|
||||
private readonly object _fileLock = new();
|
||||
|
||||
public void Info(string text)
|
||||
{
|
||||
Write(text, LogLevel.INFO);
|
||||
}
|
||||
|
||||
public void Warning(string text)
|
||||
{
|
||||
Write(text, LogLevel.WARNING);
|
||||
}
|
||||
|
||||
public void Error(string text)
|
||||
{
|
||||
Write(text, LogLevel.ERROR);
|
||||
}
|
||||
|
||||
public void Write(string text, LogLevel logLevel)
|
||||
{
|
||||
var contents = $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Constants.EOF}";
|
||||
|
||||
lock (_fileLock)
|
||||
File.AppendAllText(LogFile, contents);
|
||||
}
|
||||
|
||||
public void Debug(string s)
|
||||
{
|
||||
#if DEBUG
|
||||
Write(s, LogLevel.DEBUG);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void ShowLog()
|
||||
{
|
||||
Utils.Utils.Open(LogFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Netch/Models/MessageException.cs
Normal file
15
Netch/Models/MessageException.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class MessageException : Exception
|
||||
{
|
||||
public MessageException()
|
||||
{
|
||||
}
|
||||
|
||||
public MessageException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Netch.Controllers;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
@@ -14,7 +13,7 @@ namespace Netch.Models
|
||||
|
||||
public string? FullName { get; private set; }
|
||||
|
||||
public Mode(string? fullName = default)
|
||||
public Mode(string? fullName)
|
||||
{
|
||||
_lazyRule = new Lazy<List<string>>(ReadRules);
|
||||
if (fullName == null)
|
||||
@@ -35,10 +34,8 @@ namespace Netch.Models
|
||||
|
||||
var typeResult = int.TryParse(split.ElementAtOrDefault(1), out var type);
|
||||
Type = typeResult ? type : 0;
|
||||
// TODO throw NotSupportedModeTypeException
|
||||
|
||||
var bypassChinaResult = int.TryParse(split.ElementAtOrDefault(2), out var bypassChina);
|
||||
BypassChina = this.ClientRouting() && bypassChinaResult && bypassChina == 1;
|
||||
if (!ModeHelper.ModeTypes.Contains(Type))
|
||||
throw new NotSupportedException($"not support mode \"[{Type}]{Remark}\".");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -46,11 +43,6 @@ namespace Netch.Models
|
||||
/// </summary>
|
||||
public List<string> Rule => _lazyRule.Value;
|
||||
|
||||
/// <summary>
|
||||
/// 绕过中国(0. 不绕过 1. 绕过)
|
||||
/// </summary>
|
||||
public bool BypassChina { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
@@ -161,7 +153,7 @@ namespace Netch.Models
|
||||
/// <returns>模式文件字符串</returns>
|
||||
public string ToFileString()
|
||||
{
|
||||
return $"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}{Global.EOF}{string.Join(Global.EOF, Rule)}";
|
||||
return $"# {Remark}, {Type}{Constants.EOF}{string.Join(Constants.EOF, Rule)}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,11 +164,5 @@ namespace Netch.Models
|
||||
{
|
||||
return mode.Type is 0 or 2;
|
||||
}
|
||||
|
||||
/// Socks5 分流是否能被有效实施
|
||||
public static bool ClientRouting(this Mode mode)
|
||||
{
|
||||
return mode.Type is not (1 or 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using Microsoft.Win32;
|
||||
using Netch.Controllers;
|
||||
using Netch.Utils;
|
||||
using Vanara.PInvoke;
|
||||
|
||||
@@ -11,7 +9,7 @@ namespace Netch.Models
|
||||
{
|
||||
public class OutboundAdapter : IAdapter
|
||||
{
|
||||
public OutboundAdapter(bool logging = true)
|
||||
public OutboundAdapter()
|
||||
{
|
||||
// 寻找出口适配器
|
||||
if (IpHlpApi.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) != 0)
|
||||
@@ -23,22 +21,20 @@ namespace Netch.Models
|
||||
.First(ni => ni.Supports(NetworkInterfaceComponent.IPv4) &&
|
||||
ni.GetIPProperties().GetIPv4Properties().Index == pRoute.dwForwardIfIndex);
|
||||
|
||||
Index = (int) pRoute.dwForwardIfIndex;
|
||||
Address = new IPAddress(pRoute.dwForwardNextHop.S_addr);
|
||||
InterfaceIndex = (int) pRoute.dwForwardIfIndex;
|
||||
Gateway = new IPAddress(pRoute.dwForwardNextHop.S_un_b);
|
||||
_parametersRegistry =
|
||||
Registry.LocalMachine.OpenSubKey($@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{NetworkInterface.Id}", true)!;
|
||||
|
||||
if (logging)
|
||||
{
|
||||
Logging.Info($"出口 网关 地址:{Gateway}");
|
||||
Logging.Info($"出口适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {Index}");
|
||||
}
|
||||
Global.Logger.Info($"出口 网关 地址:{Gateway}");
|
||||
Global.Logger.Info($"出口适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
|
||||
}
|
||||
|
||||
public IPAddress Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 索引
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
public int InterfaceIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 网关
|
||||
@@ -46,24 +42,5 @@ namespace Netch.Models
|
||||
public IPAddress Gateway { get; }
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
|
||||
|
||||
public string DNS
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return (string) _parametersRegistry.GetValue("NameServer");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
set => _parametersRegistry.SetValue("NameServer", value, RegistryValueKind.String);
|
||||
}
|
||||
|
||||
private readonly RegistryKey _parametersRegistry;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
@@ -49,7 +48,7 @@ namespace Netch.Models
|
||||
case bool b:
|
||||
return b ? $"{prefix}{key}" : null;
|
||||
default:
|
||||
if ((value?.ToString() ?? null).IsNullOrWhiteSpace())
|
||||
if (string.IsNullOrWhiteSpace(value?.ToString()))
|
||||
return p.IsDefined(typeof(OptionalAttribute)) ? null : throw new RequiredArgumentValueInvalidException(p.Name, this, null);
|
||||
|
||||
if (p.IsDefined(typeof(QuoteAttribute)))
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// TUN/TAP 适配器配置类
|
||||
/// </summary>
|
||||
public class TUNTAPConfig
|
||||
public class TUNConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 地址
|
||||
@@ -16,7 +16,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// DNS
|
||||
/// </summary>
|
||||
public List<string> DNS { get; set; } = new();
|
||||
public string HijackDNS { get; set; } = "tcp://1.1.1.1:53";
|
||||
|
||||
/// <summary>
|
||||
/// 网关
|
||||
@@ -36,12 +36,12 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 使用自定义 DNS 设置
|
||||
/// </summary>
|
||||
public bool UseCustomDNS { get; set; } = false;
|
||||
public bool UseCustomDNS { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 使用Fake DNS
|
||||
/// 全局绕过 IP 列表
|
||||
/// </summary>
|
||||
public bool UseFakeDNS { get; set; } = false;
|
||||
public List<string> BypassIPs { get; set; } = new();
|
||||
}
|
||||
|
||||
public class KcpConfig
|
||||
@@ -76,13 +76,45 @@ namespace Netch.Models
|
||||
|
||||
public class AioDNSConfig
|
||||
{
|
||||
public string ChinaDNS { get; set; } = "223.5.5.5";
|
||||
public string ChinaDNS { get; set; } = "tcp://223.5.5.5:53";
|
||||
|
||||
public string OtherDNS { get; set; } = "1.1.1.1";
|
||||
public string OtherDNS { get; set; } = "tcp://1.1.1.1:53";
|
||||
|
||||
public string Protocol { get; set; } = "tcp";
|
||||
public ushort ListenPort { get; set; } = 53;
|
||||
|
||||
public string RulePath { get; set; } = "bin\\china_site_list";
|
||||
public string RulePath { get; set; } = "bin\\aiodns.conf";
|
||||
}
|
||||
|
||||
public class RedirectorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 不代理TCP
|
||||
/// </summary>
|
||||
public PortType ProxyProtocol { get; set; } = PortType.Both;
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启DNS转发
|
||||
/// </summary>
|
||||
public bool DNSHijack { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 转发DNS地址
|
||||
/// </summary>
|
||||
public string DNSHijackHost { get; set; } = "1.1.1.1:53";
|
||||
|
||||
public string ICMPHost { get; set; } = "1.2.4.8";
|
||||
|
||||
public bool ICMPHijack { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用RDR内置SS
|
||||
/// </summary>
|
||||
public bool RedirectorSS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否代理子进程
|
||||
/// </summary>
|
||||
public bool ChildProcessHandle { get; set; } = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,23 +122,15 @@ namespace Netch.Models
|
||||
/// </summary>
|
||||
public class Setting
|
||||
{
|
||||
public RedirectorConfig Redirector { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 服务器列表
|
||||
/// </summary>
|
||||
public List<Server> Server { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// ACL规则
|
||||
/// </summary>
|
||||
public string ACL { get; set; } = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/banAD.acl";
|
||||
|
||||
public AioDNSConfig AioDNS { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 全局绕过 IP 列表
|
||||
/// </summary>
|
||||
public List<string> BypassIPs { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 是否检查 Beta 更新
|
||||
/// </summary>
|
||||
@@ -150,42 +174,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 模式选择位置
|
||||
/// </summary>
|
||||
public int ModeComboBoxSelectedIndex { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 转发DNS地址
|
||||
/// </summary>
|
||||
public string RedirectDNSAddr { get; set; } = "8.8.8.8";
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启DNS转发
|
||||
/// </summary>
|
||||
public bool RedirectDNS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 转发ICMP地址
|
||||
/// </summary>
|
||||
public string RedirectICMPAddr { get; set; } = "1.2.4.8";
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启ICMP转发
|
||||
/// </summary>
|
||||
public bool RedirectICMP { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// GFWList
|
||||
/// </summary>
|
||||
public string PAC { get; set; } = "https://raw.githubusercontent.com/HMBSbige/Text_Translation/master/ShadowsocksR/ss_white.pac";
|
||||
|
||||
/// <summary>
|
||||
/// PAC端口
|
||||
/// </summary>
|
||||
public ushort Pac_Port { get; set; } = 2803;
|
||||
|
||||
/// <summary>
|
||||
/// 不代理TCP
|
||||
/// </summary>
|
||||
public PortType ProcessProxyProtocol { get; set; } = PortType.Both;
|
||||
public int ModeComboBoxSelectedIndex { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 快捷配置数量
|
||||
@@ -202,21 +191,6 @@ namespace Netch.Models
|
||||
/// </summary>
|
||||
public byte ProfileTableColumnCount { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用RDR内置SS
|
||||
/// </summary>
|
||||
public bool RedirectorSS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否代理子进程
|
||||
/// </summary>
|
||||
public bool ChildProcessHandle { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Redirector TCP 占用端口
|
||||
/// </summary>
|
||||
public ushort RedirectorTCPPort { get; set; } = 3901;
|
||||
|
||||
/// <summary>
|
||||
/// 网页请求超时 毫秒
|
||||
/// </summary>
|
||||
@@ -225,7 +199,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 解析服务器主机名
|
||||
/// </summary>
|
||||
public bool ResolveServerHostname { get; set; } = false;
|
||||
public bool ResolveServerHostname { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否开机启动软件
|
||||
@@ -235,7 +209,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 服务器选择位置
|
||||
/// </summary>
|
||||
public int ServerComboBoxSelectedIndex { get; set; } = 0;
|
||||
public int ServerComboBoxSelectedIndex { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器测试方式 false.ICMPing true.TCPing
|
||||
@@ -280,25 +254,24 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// TUNTAP 适配器配置
|
||||
/// </summary>
|
||||
public TUNTAPConfig TUNTAP { get; set; } = new();
|
||||
public TUNConfig TUNTAP { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 是否打开软件时更新订阅
|
||||
/// </summary>
|
||||
public bool UpdateServersWhenOpened { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 使用代理更新订阅
|
||||
/// </summary>
|
||||
public bool UseProxyToUpdateSubscription { get; set; } = false;
|
||||
|
||||
public V2rayConfig V2RayConfig { get; set; } = new();
|
||||
|
||||
public bool? AlwaysStartPACServer { get; set; }
|
||||
|
||||
public Setting Clone()
|
||||
{
|
||||
return (Setting) MemberwiseClone();
|
||||
}
|
||||
|
||||
public void Set(Setting value)
|
||||
{
|
||||
foreach (var p in typeof(Setting).GetProperties())
|
||||
p.SetValue(this, p.GetValue(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Netch/Models/TagItem.cs
Normal file
19
Netch/Models/TagItem.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
internal class TagItem<T>
|
||||
{
|
||||
private readonly string _text;
|
||||
|
||||
public TagItem(T value, string text)
|
||||
{
|
||||
_text = text;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Text => i18N.Translate(_text);
|
||||
|
||||
public T Value { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using Netch.Controllers;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class TapAdapter : IAdapter
|
||||
{
|
||||
public TapAdapter()
|
||||
{
|
||||
Index = -1;
|
||||
ComponentID = TUNTAP.GetComponentID() ?? throw new MessageException("TAP 适配器未安装");
|
||||
|
||||
// 根据 ComponentID 寻找 Tap适配器
|
||||
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.Id == ComponentID);
|
||||
Index = NetworkInterface.GetIPProperties().GetIPv4Properties().Index;
|
||||
Logging.Info($"TAP 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {Index}");
|
||||
}
|
||||
|
||||
public string ComponentID { get; }
|
||||
|
||||
public int Index { get; }
|
||||
|
||||
public IPAddress Gateway => IPAddress.Parse(Global.Settings.TUNTAP.Gateway);
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
}
|
||||
27
Netch/Models/TunAdapter.cs
Normal file
27
Netch/Models/TunAdapter.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using Netch.Interops;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class TunAdapter : IAdapter
|
||||
{
|
||||
public TunAdapter()
|
||||
{
|
||||
InterfaceIndex = (int) NativeMethods.ConvertLuidToIndex(TUNInterop.tun_luid());
|
||||
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.GetIPProperties().GetIPv4Properties().Index == InterfaceIndex);
|
||||
Gateway = IPAddress.Parse(Global.Settings.TUNTAP.Gateway);
|
||||
|
||||
Global.Logger.Info($"WinTUN 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
|
||||
}
|
||||
|
||||
|
||||
public int InterfaceIndex { get; }
|
||||
|
||||
public IPAddress Gateway { get; }
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,21 @@ namespace Netch
|
||||
{
|
||||
public static class NativeMethods
|
||||
{
|
||||
/// <summary>
|
||||
/// 分配 IP 地址
|
||||
/// </summary>
|
||||
/// <param name="inet">AF_INET / AF_INET6</param>
|
||||
/// <param name="address">目标地址</param>
|
||||
/// <param name="cidr">CIDR</param>
|
||||
/// <param name="index">适配器索引</param>
|
||||
/// <returns>是否成功</returns>
|
||||
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl, EntryPoint = "CreateUnicastIP")]
|
||||
public static extern bool CreateUnicastIP(int inet, string address, int cidr, int index);
|
||||
|
||||
/// <summary>
|
||||
/// 创建路由规则
|
||||
/// </summary>
|
||||
/// <param name="inet">AF_INET / AF_INET6</param>
|
||||
/// <param name="address">目标地址</param>
|
||||
/// <param name="cidr">CIDR</param>
|
||||
/// <param name="gateway">网关地址</param>
|
||||
@@ -14,11 +26,12 @@ namespace Netch
|
||||
/// <param name="metric">跃点数</param>
|
||||
/// <returns>是否成功</returns>
|
||||
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl, EntryPoint = "CreateRoute")]
|
||||
public static extern bool CreateRoute(string address, int cidr, string gateway, int index, int metric = 0);
|
||||
public static extern bool CreateRoute(int inet, string address, int cidr, string gateway, int index, int metric = 0);
|
||||
|
||||
/// <summary>
|
||||
/// 删除路由规则
|
||||
/// </summary>
|
||||
/// <param name="inet">AF_INET / AF_INET6</param>
|
||||
/// <param name="address">目标地址</param>
|
||||
/// <param name="cidr">掩码地址</param>
|
||||
/// <param name="gateway">网关地址</param>
|
||||
@@ -26,15 +39,12 @@ namespace Netch
|
||||
/// <param name="metric">跃点数</param>
|
||||
/// <returns>是否成功</returns>
|
||||
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl, EntryPoint = "DeleteRoute")]
|
||||
public static extern bool DeleteRoute(string address, int cidr, string gateway, int index, int metric = 0);
|
||||
public static extern bool DeleteRoute(int inet, string address, int cidr, string gateway, int index, int metric = 0);
|
||||
|
||||
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern ulong ConvertLuidToIndex(ulong luid);
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
110
Netch/Netch.cs
110
Netch/Netch.cs
@@ -1,42 +1,20 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
using Vanara.PInvoke;
|
||||
using static Vanara.PInvoke.User32;
|
||||
using static Vanara.PInvoke.Kernel32;
|
||||
|
||||
namespace Netch
|
||||
{
|
||||
public static class Netch
|
||||
{
|
||||
private static readonly Stopwatch Stopwatch = new();
|
||||
|
||||
public static void StartStopwatch(string name)
|
||||
{
|
||||
if (Stopwatch.IsRunning)
|
||||
throw new Exception();
|
||||
|
||||
Stopwatch.Start();
|
||||
Console.WriteLine($"Start {name} Stopwatch");
|
||||
}
|
||||
|
||||
public static void TimePoint(string name, bool restart = true)
|
||||
{
|
||||
if (!Stopwatch.IsRunning)
|
||||
throw new Exception();
|
||||
|
||||
Stopwatch.Stop();
|
||||
Console.WriteLine($"{name} Stopwatch: {Stopwatch.ElapsedMilliseconds}");
|
||||
if (restart)
|
||||
Stopwatch.Restart();
|
||||
}
|
||||
public static readonly SingleInstance.SingleInstance SingleInstance = new($"Global\\{nameof(Netch)}");
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点
|
||||
@@ -45,18 +23,20 @@ namespace Netch
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
#if DEBUG
|
||||
AttachConsole();
|
||||
AttachAllocConsole();
|
||||
#else
|
||||
if (args.Contains("-console"))
|
||||
AttachConsole();
|
||||
if (args.Contains(Constants.Parameter.Console))
|
||||
AttachAllocConsole();
|
||||
#endif
|
||||
StartStopwatch("Netch");
|
||||
|
||||
if (args.Contains(Constants.Parameter.ForceUpdate))
|
||||
Flags.AlwaysShowNewVersionFound = true;
|
||||
|
||||
// 设置当前目录
|
||||
Directory.SetCurrentDirectory(Global.NetchDir);
|
||||
Environment.SetEnvironmentVariable("PATH",
|
||||
Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) + ";" + Path.Combine(Global.NetchDir, "bin"),
|
||||
EnvironmentVariableTarget.Process);
|
||||
var binPath = Path.Combine(Global.NetchDir, "bin");
|
||||
Environment.SetEnvironmentVariable("PATH", $"{Environment.GetEnvironmentVariable("PATH")};{binPath}");
|
||||
AddDllDirectory(binPath);
|
||||
|
||||
Updater.Updater.CleanOld(Global.NetchDir);
|
||||
|
||||
@@ -66,20 +46,19 @@ namespace Netch
|
||||
if (!Directory.Exists(item))
|
||||
Directory.CreateDirectory(item);
|
||||
|
||||
TimePoint("Clean Old, Create Directory");
|
||||
// 加载配置
|
||||
Configuration.Load();
|
||||
|
||||
TimePoint("Load Configuration");
|
||||
// 检查是否已经运行
|
||||
if (!Global.Mutex.WaitOne(0, false))
|
||||
if (!SingleInstance.IsFirstInstance)
|
||||
{
|
||||
ShowOpened();
|
||||
|
||||
// 退出进程
|
||||
Environment.Exit(1);
|
||||
SingleInstance.PassArgumentsToFirstInstance(args.Append(Constants.Parameter.Show));
|
||||
Environment.Exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SingleInstance.ArgumentsReceived.Subscribe(SingleInstance_ArgumentsReceived);
|
||||
SingleInstance.ListenForArgumentsFromSuccessiveInstances();
|
||||
|
||||
// 清理上一次的日志文件,防止淤积占用磁盘空间
|
||||
if (Directory.Exists("logging"))
|
||||
{
|
||||
@@ -101,66 +80,37 @@ namespace Netch
|
||||
Environment.Exit(2);
|
||||
}
|
||||
|
||||
Logging.Info($"版本: {UpdateChecker.Owner}/{UpdateChecker.Repo}@{UpdateChecker.Version}");
|
||||
Task.Run(() => { Logging.Info($"主程序 SHA256: {Utils.Utils.SHA256CheckSum(Global.NetchExecutable)}"); });
|
||||
|
||||
TimePoint("Get Info, Pre-Form");
|
||||
Global.Logger.Info($"版本: {UpdateChecker.Owner}/{UpdateChecker.Repo}@{UpdateChecker.Version}");
|
||||
Task.Run(() => { Global.Logger.Info($"主程序 SHA256: {Utils.Utils.SHA256CheckSum(Global.NetchExecutable)}"); });
|
||||
|
||||
// 绑定错误捕获
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||
Application.ThreadException += Application_OnException;
|
||||
|
||||
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(Global.MainForm);
|
||||
}
|
||||
|
||||
private static void AttachConsole()
|
||||
private static void AttachAllocConsole()
|
||||
{
|
||||
if (!NativeMethods.AttachConsole(-1))
|
||||
NativeMethods.AllocConsole();
|
||||
if (!AttachConsole(ATTACH_PARENT_PROCESS))
|
||||
AllocConsole();
|
||||
}
|
||||
|
||||
public static void Application_OnException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
Logging.Error(e.Exception.ToString());
|
||||
Utils.Utils.Open(Logging.LogFile);
|
||||
Global.Logger.Error(e.Exception.ToString());
|
||||
Global.Logger.ShowLog();
|
||||
}
|
||||
|
||||
private static void ShowOpened()
|
||||
private static void SingleInstance_ArgumentsReceived(IEnumerable<string> args)
|
||||
{
|
||||
HWND GetWindowHandleByPidAndTitle(int process, string title)
|
||||
if (args.Contains(Constants.Parameter.Show))
|
||||
{
|
||||
var sb = new StringBuilder(256);
|
||||
HWND pLast = IntPtr.Zero;
|
||||
do
|
||||
{
|
||||
pLast = FindWindowEx(HWND.NULL, pLast, null, null);
|
||||
GetWindowThreadProcessId(pLast, out var id);
|
||||
if (id != process)
|
||||
continue;
|
||||
|
||||
if (GetWindowText(pLast, sb, sb.Capacity) <= 0)
|
||||
continue;
|
||||
|
||||
if (sb.ToString().Equals(title))
|
||||
return pLast;
|
||||
} while (pLast != IntPtr.Zero);
|
||||
|
||||
return HWND.NULL;
|
||||
Global.MainForm.ShowMainFormToolStripButton_Click(null!, null!);
|
||||
}
|
||||
|
||||
var self = Process.GetCurrentProcess();
|
||||
var activeProcess = Process.GetProcessesByName("Netch").Single(p => p.Id != self.Id);
|
||||
HWND handle = activeProcess.MainWindowHandle;
|
||||
if (handle.IsNull)
|
||||
handle = GetWindowHandleByPidAndTitle(activeProcess.Id, "Netch");
|
||||
|
||||
if (handle.IsNull)
|
||||
return;
|
||||
|
||||
ShowWindow(handle, ShowWindowCommand.SW_NORMAL);
|
||||
SwitchToThisWindow(handle, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,86 +2,64 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>true</UseWPF>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<StartupObject>Netch.Netch</StartupObject>
|
||||
<ApplicationManifest>App.manifest</ApplicationManifest>
|
||||
<ApplicationIcon>Resources\Netch.ico</ApplicationIcon>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnableNETAnalyzers>false</EnableNETAnalyzers>
|
||||
<AnalysisMode>Default</AnalysisMode>
|
||||
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Platforms>x64</Platforms>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<!-- <EnableNETAnalyzers>true</EnableNETAnalyzers>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
<NoWarn />
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn />
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove=".gitignore" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HMBSbige.SingleInstance" Version="5.0.0" />
|
||||
<PackageReference Include="MaxMind.GeoIP2" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.66" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="Nullable.Extended.Analyzer" Version="1.2.4089">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="5.0.1" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.9.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.3.5" />
|
||||
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.3.7" />
|
||||
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="3.3.5" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="3.3.7" />
|
||||
<PackageReference Include="WindowsFirewallHelper" Version="2.0.4.70-beta2" />
|
||||
<PackageReference Include="WindowsProxy" Version="5.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<!-- .NET Framework -->
|
||||
<PackageReference Include="ILMerge" Version="3.0.41" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Web" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' != 'net'">
|
||||
<!-- .NET Core -->
|
||||
<PackageReference Include="System.Management" Version="5.0.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SearchComboBox\SearchComboBox.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove=".gitignore" />
|
||||
<None Visible="false" Include="..\binaries\**" LinkBase="bin" CopyToPublishDirectory="PreserveNewest" CopyToOutputDirectory="PreserveNewest" />
|
||||
<None Update="..\binaries\NTT.exe">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</None>
|
||||
<None Remove="..\binaries\.git" />
|
||||
<None Visible="false" Include="..\translations\i18n\**" LinkBase="i18n" CopyToPublishDirectory="PreserveNewest" CopyToOutputDirectory="PreserveNewest" />
|
||||
<None Visible="false" Include="..\modes\mode\**" LinkBase="mode" CopyToPublishDirectory="PreserveNewest" CopyToOutputDirectory="PreserveNewest" />
|
||||
@@ -98,9 +76,7 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Forms\Mode\Route.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Forms\Mode\Route.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -108,7 +84,6 @@
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Remove="Forms\LogForm.resx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -117,14 +92,6 @@
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="set TargetFramework=$(TargetFramework)
set Configuration=$(Configuration)
set ILMergeConsolePath=$(ILMergeConsolePath)
set TargetDir=$(TargetDir)
set SolutionDir=$(SolutionDir)
$(ProjectDir)PostBuild.bat" />
|
||||
</Target>
|
||||
|
||||
<Target Condition="'$(PublishSingleFile)' == 'true'" AfterTargets="_ComputeFilesToBundle" Name="RemoveDupeAssemblies">
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
if %Configuration%==Release if %TargetFramework%==net48 (
|
||||
:: Merge dlls
|
||||
%ILMergeConsolePath% /wildcards /out:%TargetDir%Netch.exe ^
|
||||
/lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" ^
|
||||
/targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8" ^
|
||||
%TargetDir%Netch.exe ^
|
||||
%TargetDir%*.dll
|
||||
|
||||
DEL /f %TargetDir%*.dll >NUL 2>&1
|
||||
)
|
||||
|
||||
if %Configuration%==Release (
|
||||
DEL /f %TargetDir%*.config >NUL 2>&1
|
||||
DEL /f %TargetDir%*.pdb >NUL 2>&1
|
||||
)
|
||||
|
||||
RD /s /Q %TargetDir%x86 >NUL 2>&1
|
||||
RD /s /Q %TargetDir%de %TargetDir%es %TargetDir%fr %TargetDir%it %TargetDir%pl %TargetDir%ru %TargetDir%zh-CN >NUL 2>&1
|
||||
|
||||
exit 0
|
||||
@@ -3,7 +3,6 @@
|
||||
"Information": "信息",
|
||||
"Error": "错误",
|
||||
|
||||
"If this is your first time using this software,\n please check https://netch.org to install supports first,\n or the program may report errors.": "如果你是第一次使用本软件,\n请务必前往 https://netch.org 安装程序所需依赖,\n否则程序将无法正常运行!",
|
||||
"Missing File or runtime components": "缺少文件或运行库",
|
||||
"Please extract all files then run the program!": "请先解压所有文件再执行程序!",
|
||||
|
||||
@@ -20,7 +19,6 @@
|
||||
"SetupBypass": "设置绕行规则",
|
||||
"Test failed": "测试失败",
|
||||
"Starting update subscription": "正在更新订阅",
|
||||
"Starting update ACL": "正在更新 ACL",
|
||||
"Subscription updated": "订阅更新完毕",
|
||||
"Register driver": "正在注册驱动",
|
||||
|
||||
@@ -67,7 +65,6 @@
|
||||
"Subscribe": "订阅",
|
||||
"Manage Subscribe Links": "管理订阅链接",
|
||||
"Update Servers From Subscribe Links": "从订阅链接更新服务器",
|
||||
"Update Servers From Subscribe Links With Proxy": "使用代理从订阅链接更新服务器",
|
||||
"No subscription link": "没有任何一条订阅链接",
|
||||
"Updating {0}": "正在更新 {0}",
|
||||
"Update {1} server(s) from {0}": "从 {0} 更新 {1} 个服务器",
|
||||
@@ -85,21 +82,10 @@
|
||||
"Uninstall {0}": "卸载 {0}",
|
||||
"Uninstalling {0}": "正在卸载 {0} 中",
|
||||
"{0} has been uninstalled": "{0} 已卸载",
|
||||
"Reload Modes": "重载模式",
|
||||
"Modes have been reload": "模式已重载",
|
||||
"Clean DNS Cache": "清理 DNS 缓存",
|
||||
"DNS cache cleanup succeeded": "DNS 缓存清理成功",
|
||||
"Remove Netch Firewall Rules": "移除 Netch 防火墙规则",
|
||||
|
||||
"Update PAC": "更新 PAC",
|
||||
"PAC updated successfully": "PAC 更新成功",
|
||||
"PAC update failed": "PAC 更新失败",
|
||||
|
||||
"Update ACL": "更新 ACL 规则",
|
||||
"Update ACL with proxy": "使用代理更新 ACL 规则",
|
||||
"ACL updated successfully": "ACL 更新成功",
|
||||
"ACL update failed": "ACL 更新失败",
|
||||
|
||||
"Open Directory": "打开目录",
|
||||
|
||||
"About": "关于",
|
||||
@@ -155,25 +141,21 @@
|
||||
"Gateway": "网关",
|
||||
"Use Custom DNS": "使用自定义 DNS",
|
||||
"Proxy DNS in Proxy Rule IPs Mode": "在 代理规则IP 模式下代理 DNS",
|
||||
"Use Fake DNS": "使用 Fake DNS",
|
||||
"Exit when closed": "关闭时退出",
|
||||
"Stop when exited": "退出时停止",
|
||||
"Global Bypass IPs": "全局直连 IP",
|
||||
"Check update when opened": "打开软件时检查更新",
|
||||
"Check Beta update": "检查 Beta 更新",
|
||||
"Update Servers when opened": "打开软件时更新服务器",
|
||||
"SS DLL": "SS DLL",
|
||||
"Modify System DNS": "修改系统 DNS",
|
||||
"Proxy Protocol": "代理协议",
|
||||
"DNS Redirector": "DNS转发",
|
||||
"ICMP Redirector": "ICMP转发",
|
||||
"Handle process's DNS Hijack": "被代理进程 DNS 劫持",
|
||||
"Global ICMP Hijack": "全局 ICMP 劫持",
|
||||
"Child Process Handle": "子进程代理",
|
||||
"ProfileCount": "快捷配置数量",
|
||||
"Delay test after start": "启动后延迟测试",
|
||||
"ServerPingType": "测速方式",
|
||||
"Detection Tick(sec)": "检测心跳(秒)",
|
||||
"STUN Server": "STUN 服务器",
|
||||
"Custom ACL": "自定义 ACL 规则",
|
||||
"Language": "语言",
|
||||
"Resolve Server Hostname": "解析服务器主机名",
|
||||
"FullCone Support (Required Server Xray-core v1.3.0+)": "FullCone 支持(需服务端 Xray-core v1.3.0+)",
|
||||
@@ -186,12 +168,5 @@
|
||||
"Exit": "退出",
|
||||
|
||||
"The {0} port is in use.": "{0} 端口已被占用",
|
||||
"The {0} port is reserved by system.": "{0} 端口是系统保留端口",
|
||||
|
||||
"[Web Proxy] Bypass LAN": "[网页代理] 绕过局域网",
|
||||
"[Non Web Proxy] Bypass LAN": "[不设置代理] 绕过局域网",
|
||||
"[TUN/TAP] Bypass LAN": "[TUN/TAP] 绕过局域网",
|
||||
"[Web Proxy] Bypass LAN and China": "[网页代理] 绕过局域网和中国大陆",
|
||||
"[Non Web Proxy] Bypass LAN and China": "[不设置代理] 绕过局域网和中国大陆",
|
||||
"[TUN/TAP] Bypass LAN and China": "[TUN/TAP] 绕过局域网和中国大陆"
|
||||
"The {0} port is reserved by system.": "{0} 端口是系统保留端口"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
|
||||
@@ -10,9 +8,9 @@ namespace Netch.Servers.Shadowsocks
|
||||
{
|
||||
public override string MainFile { get; protected set; } = "Shadowsocks.exe";
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"listening at"};
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"listening at"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"Invalid config path", "usage", "plugin service exit unexpectedly"};
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"Invalid config path", "usage", "plugin service exit unexpectedly"};
|
||||
|
||||
public override string Name { get; } = "Shadowsocks";
|
||||
|
||||
@@ -37,9 +35,6 @@ namespace Netch.Servers.Shadowsocks
|
||||
plugin_opts = server.PluginOption
|
||||
};
|
||||
|
||||
if (mode.BypassChina)
|
||||
command.acl = $"{Path.GetFullPath(File.Exists(Global.UserACL) ? Global.UserACL : Global.BuiltinACL)}";
|
||||
|
||||
StartInstanceAuto(command.ToString());
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Netch.Servers.Shadowsocks
|
||||
var server = (Shadowsocks) s;
|
||||
if (!SSGlobal.EncryptMethods.Contains(server.EncryptMethod))
|
||||
{
|
||||
Logging.Error($"不支持的 SS 加密方式:{server.EncryptMethod}");
|
||||
Global.Logger.Error($"不支持的 SS 加密方式:{server.EncryptMethod}");
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
|
||||
@@ -10,9 +8,9 @@ namespace Netch.Servers.ShadowsocksR
|
||||
{
|
||||
public override string MainFile { get; protected set; } = "ShadowsocksR.exe";
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"listening at"};
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"listening at"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"Invalid config path", "usage"};
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"Invalid config path", "usage"};
|
||||
|
||||
public override string Name { get; } = "ShadowsocksR";
|
||||
|
||||
@@ -40,9 +38,6 @@ namespace Netch.Servers.ShadowsocksR
|
||||
u = true
|
||||
};
|
||||
|
||||
if (mode.BypassChina)
|
||||
command.acl = $"{Path.GetFullPath(File.Exists(Global.UserACL) ? Global.UserACL : Global.BuiltinACL)}";
|
||||
|
||||
StartInstanceAuto(command.ToString());
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Netch.Servers.ShadowsocksR
|
||||
// https://github.com/shadowsocksr-backup/shadowsocks-rss/wiki/SSR-QRcode-scheme
|
||||
// ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
|
||||
var paraStr =
|
||||
$"/?obfsparam={ShareLink.URLSafeBase64Encode(server.OBFSParam)}&protoparam={ShareLink.URLSafeBase64Encode(server.ProtocolParam)}&remarks={ShareLink.URLSafeBase64Encode(server.Remark)}";
|
||||
$"/?obfsparam={ShareLink.URLSafeBase64Encode(server.OBFSParam ?? "")}&protoparam={ShareLink.URLSafeBase64Encode(server.ProtocolParam ?? "")}&remarks={ShareLink.URLSafeBase64Encode(server.Remark)}";
|
||||
|
||||
return "ssr://" +
|
||||
ShareLink.URLSafeBase64Encode(
|
||||
@@ -146,19 +146,19 @@ namespace Netch.Servers.ShadowsocksR
|
||||
var server = (ShadowsocksR) s;
|
||||
if (!SSRGlobal.EncryptMethods.Contains(server.EncryptMethod))
|
||||
{
|
||||
Logging.Error($"不支持的 SSR 加密方式:{server.EncryptMethod}");
|
||||
Global.Logger.Error($"不支持的 SSR 加密方式:{server.EncryptMethod}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SSRGlobal.Protocols.Contains(server.Protocol))
|
||||
{
|
||||
Logging.Error($"不支持的 SSR 协议:{server.Protocol}");
|
||||
Global.Logger.Error($"不支持的 SSR 协议:{server.Protocol}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SSRGlobal.OBFSs.Contains(server.OBFS))
|
||||
{
|
||||
Logging.Error($"不支持的 SSR 混淆:{server.OBFS}");
|
||||
Global.Logger.Error($"不支持的 SSR 混淆:{server.OBFS}");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ namespace Netch.Servers.Trojan
|
||||
{
|
||||
public override string MainFile { get; protected set; } = "Trojan.exe";
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"started"};
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"started"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"exiting"};
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"exiting"};
|
||||
|
||||
public override string Name { get; } = "Trojan";
|
||||
|
||||
|
||||
@@ -65,25 +65,6 @@ namespace Netch.Servers.V2ray.Utils
|
||||
outboundTag = "block"
|
||||
};
|
||||
|
||||
if (mode.BypassChina)
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 0:
|
||||
directRuleObject.ip.Add("geoip:cn");
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (Global.Flags.SupportFakeDns && Global.Settings.TUNTAP.UseFakeDNS)
|
||||
directRuleObject.domain.Add("geosite:cn");
|
||||
else
|
||||
directRuleObject.ip.Add("geoip:cn");
|
||||
|
||||
break;
|
||||
default:
|
||||
directRuleObject.domain.Add("geosite:cn");
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode.Type is 0 or 1 or 2)
|
||||
blockRuleObject.ip.Add("geoip:private");
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace Netch.Servers.V2ray
|
||||
{
|
||||
public override string MainFile { get; protected set; } = "xray.exe";
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"started"};
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"started"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"config file not readable", "failed to"};
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"config file not readable", "failed to"};
|
||||
|
||||
public override string Name { get; } = "Xray";
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
|
||||
@@ -91,10 +92,31 @@ namespace Netch.Updater
|
||||
|
||||
#region Apply Update
|
||||
|
||||
private static readonly ImmutableArray<string> KeepDirectories = new List<string> {"data", "mode\\Custom"}.ToImmutableArray();
|
||||
private static readonly ImmutableArray<string> KeepDirectories = new List<string> {"data", "mode\\Custom", "logging"}.ToImmutableArray();
|
||||
|
||||
private void ApplyUpdate()
|
||||
{
|
||||
var mainForm = Global.MainForm;
|
||||
|
||||
#region PreUpdate
|
||||
|
||||
ModeHelper.SuspendWatcher = true;
|
||||
// Stop and Save
|
||||
mainForm.Stop();
|
||||
Configuration.Save();
|
||||
|
||||
// Backup Configuration file
|
||||
try
|
||||
{
|
||||
File.Copy(Configuration.SettingFileFullName, Configuration.SettingFileFullName + ".bak", true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// extract Update file to {tempDirectory}\extract
|
||||
var extractPath = Path.Combine(_tempDirectory, "extract");
|
||||
int exitCode;
|
||||
@@ -107,11 +129,10 @@ namespace Netch.Updater
|
||||
// move {tempDirectory}\extract\Netch to install folder
|
||||
MoveAllFilesOver(Path.Combine(extractPath, "Netch"), _installDirectory);
|
||||
|
||||
// save, release mutex, then exit
|
||||
Configuration.Save();
|
||||
Global.MainForm.Invoke(new Action(() => { Global.Mutex.ReleaseMutex(); }));
|
||||
// release mutex, exit
|
||||
mainForm.Invoke(new Action(Netch.SingleInstance.Dispose));
|
||||
Process.Start(Global.NetchExecutable);
|
||||
Global.MainForm.Exit(true, false);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private void MarkFilesOld()
|
||||
@@ -126,7 +147,7 @@ namespace Netch.Updater
|
||||
if (extendedKeepDirectories.Any(p => file.StartsWith(p)))
|
||||
continue;
|
||||
|
||||
if (Path.GetFileName(file) is ModeHelper.DISABLE_MODE_DIRECTORY_FILENAME)
|
||||
if (Path.GetFileName(file) is ModeHelper.DisableModeDirectoryFileName)
|
||||
continue;
|
||||
|
||||
filesToDelete.Add(file);
|
||||
@@ -134,7 +155,15 @@ namespace Netch.Updater
|
||||
|
||||
// rename files
|
||||
foreach (var file in filesToDelete)
|
||||
File.Move(file, file + ".old");
|
||||
try
|
||||
{
|
||||
File.Move(file, file + ".old");
|
||||
}
|
||||
catch
|
||||
{
|
||||
Global.Logger.Error($"failed to rename file \"{file}\"");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private int Extract(string destDirName, bool overwrite)
|
||||
|
||||
@@ -6,7 +6,6 @@ using Microsoft.Diagnostics.Tracing.Parsers;
|
||||
using Microsoft.Diagnostics.Tracing.Session;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Shadowsocks;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
@@ -45,7 +44,7 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void NetTraffic()
|
||||
{
|
||||
if (!Global.Flags.IsWindows10Upper)
|
||||
if (!Flags.IsWindows10Upper)
|
||||
return;
|
||||
|
||||
var counterLock = new object();
|
||||
@@ -69,9 +68,6 @@ namespace Netch.Utils
|
||||
{
|
||||
case null:
|
||||
break;
|
||||
case HTTPController httpController:
|
||||
instances.Add(httpController.PrivoxyController.Instance!);
|
||||
break;
|
||||
case NFController _:
|
||||
instances.Add(Process.GetCurrentProcess());
|
||||
break;
|
||||
@@ -82,7 +78,7 @@ namespace Netch.Utils
|
||||
|
||||
var processList = instances.Select(instance => instance.Id).ToList();
|
||||
|
||||
Logging.Info("流量统计进程:" + string.Join(",", instances.Select(instance => $"({instance.Id})" + instance.ProcessName).ToArray()));
|
||||
Global.Logger.Info("流量统计进程:" + string.Join(",", instances.Select(instance => $"({instance.Id})" + instance.ProcessName).ToArray()));
|
||||
|
||||
received = 0;
|
||||
|
||||
|
||||
@@ -12,12 +12,10 @@ namespace Netch.Utils
|
||||
/// <summary>
|
||||
/// 数据目录
|
||||
/// </summary>
|
||||
public const string DATA_DIR = "data";
|
||||
public static string DataDirectoryFullName => Path.Combine(Global.NetchDir, "data");
|
||||
|
||||
public static string SettingFileFullName => $"{DataDirectoryFullName}\\settings.json";
|
||||
|
||||
/// <summary>
|
||||
/// 设置
|
||||
/// </summary>
|
||||
public static readonly string SETTINGS_JSON = $"{DATA_DIR}\\settings.json";
|
||||
private static readonly JsonSerializerOptions JsonSerializerOptions = Global.NewDefaultJsonSerializerOptions;
|
||||
|
||||
static Configuration()
|
||||
@@ -31,11 +29,11 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void Load()
|
||||
{
|
||||
if (File.Exists(SETTINGS_JSON))
|
||||
if (File.Exists(SettingFileFullName))
|
||||
{
|
||||
try
|
||||
{
|
||||
using var fileStream = File.OpenRead(SETTINGS_JSON);
|
||||
using var fileStream = File.OpenRead(SettingFileFullName);
|
||||
var settings = JsonSerializer.DeserializeAsync<Setting>(fileStream, JsonSerializerOptions).Result!;
|
||||
|
||||
CheckSetting(settings);
|
||||
@@ -44,8 +42,8 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.ToString());
|
||||
Utils.Open(Logging.LogFile);
|
||||
Global.Logger.Error(e.ToString());
|
||||
Global.Logger.ShowLog();
|
||||
Environment.Exit(-1);
|
||||
Global.Settings = null!;
|
||||
}
|
||||
@@ -64,6 +62,9 @@ namespace Netch.Utils
|
||||
if (settings.Profiles.Any(p => settings.Profiles.Any(p1 => p1 != p && p1.Index == p.Index)))
|
||||
for (var i = 0; i < settings.Profiles.Count; i++)
|
||||
settings.Profiles[i].Index = i;
|
||||
|
||||
settings.AioDNS.ChinaDNS = Utils.HostAppendPort(settings.AioDNS.ChinaDNS);
|
||||
settings.AioDNS.OtherDNS = Utils.HostAppendPort(settings.AioDNS.OtherDNS);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,10 +72,10 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void Save()
|
||||
{
|
||||
if (!Directory.Exists(DATA_DIR))
|
||||
Directory.CreateDirectory(DATA_DIR);
|
||||
if (!Directory.Exists(DataDirectoryFullName))
|
||||
Directory.CreateDirectory(DataDirectoryFullName);
|
||||
|
||||
File.WriteAllBytes(SETTINGS_JSON, JsonSerializer.SerializeToUtf8Bytes(Global.Settings, JsonSerializerOptions));
|
||||
File.WriteAllBytes(SettingFileFullName, JsonSerializer.SerializeToUtf8Bytes(Global.Settings, JsonSerializerOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace Netch.Utils
|
||||
{
|
||||
if (!FirewallWAS.IsSupported)
|
||||
{
|
||||
Logging.Warning("不支持防火墙");
|
||||
Global.Logger.Warning("不支持防火墙");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning("添加防火墙规则错误(如已关闭防火墙则可无视此错误)\n" + e);
|
||||
Global.Logger.Warning("添加防火墙规则错误(如已关闭防火墙则可无视此错误)\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning("清除防火墙规则错误\n" + e);
|
||||
Global.Logger.Warning("清除防火墙规则错误\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Netch.Utils.HttpProxyHandler
|
||||
{
|
||||
public class HttpWebServer
|
||||
{
|
||||
private readonly Func<HttpListenerRequest, string>? _responderMethod;
|
||||
private HttpListener? _listener;
|
||||
|
||||
public HttpWebServer(string[] prefixes, Func<HttpListenerRequest, string> method)
|
||||
{
|
||||
_listener = new HttpListener();
|
||||
|
||||
// URI prefixes are required, for example
|
||||
// "http://localhost:8080/index/".
|
||||
if (prefixes == null || prefixes.Length == 0)
|
||||
throw new ArgumentException("prefixes");
|
||||
|
||||
// A responder method is required
|
||||
if (method == null)
|
||||
throw new ArgumentException("method");
|
||||
|
||||
foreach (var s in prefixes)
|
||||
_listener.Prefixes.Add(s);
|
||||
|
||||
_responderMethod = method;
|
||||
_listener.Start();
|
||||
}
|
||||
|
||||
public HttpWebServer(Func<HttpListenerRequest, string> method, params string[] prefixes) : this(prefixes, method)
|
||||
{
|
||||
}
|
||||
|
||||
public void StartWaitingRequest()
|
||||
{
|
||||
Logging.Info("Webserver running...");
|
||||
while (_listener?.IsListening ?? false)
|
||||
{
|
||||
HttpListenerContext ctx;
|
||||
try
|
||||
{
|
||||
ctx = _listener.GetContext();
|
||||
}
|
||||
catch
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var rstr = _responderMethod!(ctx.Request);
|
||||
var buf = Encoding.UTF8.GetBytes(rstr);
|
||||
ctx.Response.StatusCode = 200;
|
||||
ctx.Response.ContentType = "application/x-ns-proxy-autoconfig";
|
||||
ctx.Response.ContentLength64 = buf.Length;
|
||||
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ctx.Response.OutputStream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (_listener != null)
|
||||
{
|
||||
_listener.Stop();
|
||||
_listener.Close();
|
||||
_listener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
|
||||
namespace Netch.Utils.HttpProxyHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供PAC功能支持
|
||||
/// </summary>
|
||||
internal static class PACServerHandle
|
||||
{
|
||||
private static HttpWebServer? _httpWebServer;
|
||||
private static string? _pacContent;
|
||||
public static readonly string PacPrefix= $"http://127.0.0.1:{Global.Settings.Pac_Port}/pac/";
|
||||
|
||||
public static string InitPACServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
_pacContent = GetPacList("127.0.0.1");
|
||||
|
||||
_httpWebServer = new HttpWebServer(SendResponse, PacPrefix);
|
||||
Task.Run(() => _httpWebServer.StartWaitingRequest());
|
||||
|
||||
var pacUrl = GetPacUrl();
|
||||
Logging.Info($"Webserver InitServer OK: {pacUrl}");
|
||||
return pacUrl;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logging.Error("Webserver InitServer Failed");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static string SendResponse(HttpListenerRequest request)
|
||||
{
|
||||
return _pacContent!;
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
_httpWebServer?.Stop();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
_httpWebServer = null;
|
||||
}
|
||||
|
||||
private static string GetPacList(string address)
|
||||
{
|
||||
try
|
||||
{
|
||||
var proxy = $"PROXY {address}:{Global.Settings.HTTPLocalPort};";
|
||||
var pacfile = Path.Combine(Global.NetchDir, "bin\\pac.txt");
|
||||
|
||||
var pac = File.ReadAllText(pacfile, Encoding.UTF8).Replace("__PROXY__", proxy);
|
||||
return pac;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new MessageException("Pac file not found!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取PAC地址
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetPacUrl()
|
||||
{
|
||||
return PacPrefix + $"?t={DateTime.Now:yyyyMMddHHmmssfff}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class Logging
|
||||
{
|
||||
public const string LogFile = "logging\\application.log";
|
||||
|
||||
private static readonly object FileLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
public static void Info(string text)
|
||||
{
|
||||
Write(text, LogLevel.INFO);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
public static void Warning(string text)
|
||||
{
|
||||
Write(text, LogLevel.WARNING);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
public static void Error(string text)
|
||||
{
|
||||
Write(text, LogLevel.ERROR);
|
||||
}
|
||||
|
||||
private static void Write(string text, LogLevel logLevel)
|
||||
{
|
||||
var contents = $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Global.EOF}";
|
||||
#if DEBUG
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.INFO:
|
||||
case LogLevel.WARNING:
|
||||
Console.Write(contents);
|
||||
break;
|
||||
case LogLevel.ERROR:
|
||||
Console.Error.Write(contents);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null);
|
||||
}
|
||||
#else
|
||||
lock (FileLock)
|
||||
File.AppendAllText(LogFile, contents);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,16 +10,17 @@ namespace Netch.Utils
|
||||
{
|
||||
public static class ModeHelper
|
||||
{
|
||||
private const string MODE_DIR = "mode";
|
||||
public const string DISABLE_MODE_DIRECTORY_FILENAME = "disabled";
|
||||
public const string DisableModeDirectoryFileName = "disabled";
|
||||
|
||||
public static readonly string ModeDirectory = Path.Combine(Global.NetchDir, $"{MODE_DIR}\\");
|
||||
public static string ModeDirectoryFullName => Path.Combine(Global.NetchDir, "mode");
|
||||
|
||||
private static readonly FileSystemWatcher FileSystemWatcher;
|
||||
|
||||
public static bool SuspendWatcher { get; set; } = false;
|
||||
|
||||
static ModeHelper()
|
||||
{
|
||||
FileSystemWatcher = new FileSystemWatcher(ModeDirectory)
|
||||
FileSystemWatcher = new FileSystemWatcher(ModeDirectoryFullName)
|
||||
{
|
||||
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName,
|
||||
IncludeSubdirectories = true,
|
||||
@@ -34,18 +35,25 @@ namespace Netch.Utils
|
||||
|
||||
private static void OnModeChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
if (SuspendWatcher)
|
||||
return;
|
||||
|
||||
Load();
|
||||
Global.MainForm.LoadModes();
|
||||
}
|
||||
|
||||
public static string GetRelativePath(string fullName)
|
||||
{
|
||||
return fullName.Substring(ModeDirectory.Length);
|
||||
var length = ModeDirectoryFullName.Length;
|
||||
if (!ModeDirectoryFullName.EndsWith("\\"))
|
||||
length++;
|
||||
|
||||
return fullName.Substring(length);
|
||||
}
|
||||
|
||||
public static string GetFullPath(string relativeName)
|
||||
{
|
||||
return Path.Combine(ModeDirectory, relativeName);
|
||||
return Path.Combine(ModeDirectoryFullName, relativeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,7 +62,7 @@ namespace Netch.Utils
|
||||
public static void Load()
|
||||
{
|
||||
Global.Modes.Clear();
|
||||
LoadModeDirectory(ModeDirectory);
|
||||
LoadModeDirectory(ModeDirectoryFullName);
|
||||
|
||||
Sort();
|
||||
}
|
||||
@@ -67,7 +75,7 @@ namespace Netch.Utils
|
||||
LoadModeDirectory(directory);
|
||||
|
||||
// skip Directory with a disabled file in
|
||||
if (File.Exists(Path.Combine(modeDirectory, DISABLE_MODE_DIRECTORY_FILENAME)))
|
||||
if (File.Exists(Path.Combine(modeDirectory, DisableModeDirectoryFileName)))
|
||||
return;
|
||||
|
||||
foreach (var file in Directory.GetFiles(modeDirectory).Where(f => f.EndsWith(".txt")))
|
||||
@@ -75,9 +83,9 @@ namespace Netch.Utils
|
||||
{
|
||||
Global.Modes.Add(new Mode(file));
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
// ignored
|
||||
Global.Logger.Warning($"Load mode \"{file}\" failed: {e.Message}");
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -101,43 +109,40 @@ namespace Netch.Utils
|
||||
|
||||
public static bool SkipServerController(Server server, Mode mode)
|
||||
{
|
||||
return mode.Type switch
|
||||
{
|
||||
0 => server switch
|
||||
{
|
||||
Socks5 => true,
|
||||
Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.RedirectorSS => true,
|
||||
_ => false
|
||||
},
|
||||
_ => false
|
||||
};
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 0:
|
||||
return server switch
|
||||
{
|
||||
Socks5 => true,
|
||||
Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.Redirector.RedirectorSS => true,
|
||||
_ => false
|
||||
};
|
||||
case 1:
|
||||
case 2:
|
||||
return server is Socks5;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static IModeController? GetModeControllerByType(int type, out ushort? port, out string portName)
|
||||
public static readonly int[] ModeTypes = {0, 1, 2, 6};
|
||||
|
||||
public static IModeController GetModeControllerByType(int type, out ushort? port, out string portName)
|
||||
{
|
||||
port = null;
|
||||
portName = string.Empty;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
port = Global.Settings.RedirectorTCPPort;
|
||||
portName = "Redirector TCP";
|
||||
return new NFController();
|
||||
case 1:
|
||||
case 2:
|
||||
return new TUNTAPController();
|
||||
case 3:
|
||||
case 5:
|
||||
port = Global.Settings.HTTPLocalPort;
|
||||
portName = "HTTP";
|
||||
StatusPortInfoText.HttpPort = (ushort) port;
|
||||
return new HTTPController();
|
||||
case 4:
|
||||
return null;
|
||||
return new TUNController();
|
||||
case 6:
|
||||
return new PcapController();
|
||||
default:
|
||||
Logging.Error("未知模式类型");
|
||||
Global.Logger.Error("未知模式类型");
|
||||
throw new MessageException("未知模式类型");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using Netch.Models;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
using static Vanara.PInvoke.Ws2_32;
|
||||
using Range = Netch.Models.Range;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
@@ -24,20 +24,18 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("获取保留端口失败: " + e);
|
||||
Global.Logger.Error("获取保留端口失败: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Process? GetProcessByUsedTcpPort(ushort port)
|
||||
public static IEnumerable<Process> GetProcessByUsedTcpPort(ushort port)
|
||||
{
|
||||
if (port == 0)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
var row = GetTcpTable2().SingleOrDefault(r => ntohs((ushort) r.dwLocalPort) == port);
|
||||
if (row.dwOwningPid == 0)
|
||||
return null;
|
||||
var row = GetTcpTable2().Where(r => ntohs((ushort) r.dwLocalPort) == port).Where(r => r.dwOwningPid is not (0 or 4));
|
||||
|
||||
return Process.GetProcessById((int) row.dwOwningPid);
|
||||
return row.Select(r => Process.GetProcessById((int) r.dwOwningPid));
|
||||
}
|
||||
|
||||
private static void GetReservedPortRange(PortType portType, ref List<Range> targetList)
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using Netch.Models;
|
||||
using Range = Netch.Models.Range;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
@@ -16,7 +17,7 @@ namespace Netch.Utils
|
||||
.GetExportedTypes()
|
||||
.Where(type => type.GetInterfaces().Contains(typeof(IServerUtil)));
|
||||
|
||||
ServerUtils = serversUtilsTypes.Select(t => (IServerUtil) Activator.CreateInstance(t)).OrderBy(util => util.Priority);
|
||||
ServerUtils = serversUtilsTypes.Select(t => (IServerUtil) Activator.CreateInstance(t)!).OrderBy(util => util.Priority);
|
||||
}
|
||||
|
||||
public static Type GetTypeByTypeName(string typeName)
|
||||
|
||||
@@ -32,17 +32,16 @@ namespace Netch.Utils
|
||||
|
||||
try
|
||||
{
|
||||
list.AddRange(JsonSerializer.Deserialize<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
|
||||
}));
|
||||
list.AddRange(JsonSerializer.Deserialize<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 (JsonException)
|
||||
{
|
||||
@@ -56,16 +55,16 @@ namespace Netch.Utils
|
||||
catch (Exception e)
|
||||
{
|
||||
errorFlag = true;
|
||||
Logging.Error(e.ToString());
|
||||
Global.Logger.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (errorFlag)
|
||||
Utils.Open(Logging.LogFile);
|
||||
Global.Logger.ShowLog();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.ToString());
|
||||
Global.Logger.Error(e.ToString());
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -90,7 +89,7 @@ namespace Netch.Utils
|
||||
if (util != null)
|
||||
list.AddRange(util.ParseUri(text));
|
||||
else
|
||||
Logging.Warning($"无法处理 {scheme} 协议订阅链接");
|
||||
Global.Logger.Warning($"无法处理 {scheme} 协议订阅链接");
|
||||
}
|
||||
|
||||
foreach (var node in list.Where(node => !node.Remark.IsNullOrWhiteSpace()))
|
||||
|
||||
@@ -60,12 +60,12 @@ namespace Netch.Utils
|
||||
|
||||
public static string[] SplitRemoveEmptyEntriesAndTrimEntries(this string value, params char[] separator)
|
||||
{
|
||||
return value.Split(separator).Select(s => s.Trim()).Where(s => s != string.Empty).ToArray();
|
||||
return value.Split(separator, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
}
|
||||
|
||||
public static string[] SplitTrimEntries(this string value, params char[] separator)
|
||||
{
|
||||
return value.Split(separator).Select(s => s.Trim()).ToArray();
|
||||
return value.Split(separator, StringSplitOptions.TrimEntries);
|
||||
}
|
||||
|
||||
public static string[] SplitRemoveEmptyEntries(this string value, params char[] separator)
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Netch.Utils
|
||||
catch (Exception e)
|
||||
{
|
||||
Global.MainForm.NotifyTip($"{i18N.TranslateFormat("Update servers error from {0}", item.Remark)}\n{e.Message}", info: false);
|
||||
Logging.Error(e.ToString());
|
||||
Global.Logger.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32;
|
||||
using Netch.Controllers;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class TUNTAP
|
||||
{
|
||||
public static string TUNTAP_COMPONENT_ID_0901 = "tap0901";
|
||||
public static string TUNTAP_COMPONENT_ID_0801 = "tap0801";
|
||||
public static string NETWORK_KEY = @"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}";
|
||||
public static string ADAPTER_KEY = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}";
|
||||
|
||||
/// <summary>
|
||||
/// 获取 TUN/TAP 适配器 ID
|
||||
/// </summary>
|
||||
/// <returns>适配器 ID</returns>
|
||||
public static string? GetComponentID()
|
||||
{
|
||||
try
|
||||
{
|
||||
var adaptersRegistry = Registry.LocalMachine.OpenSubKey(ADAPTER_KEY)!;
|
||||
|
||||
foreach (var keyName in adaptersRegistry.GetSubKeyNames().Where(s => s is not ("Configuration" or "Properties")))
|
||||
{
|
||||
var adapterRegistry = adaptersRegistry.OpenSubKey(keyName)!;
|
||||
var componentId = adapterRegistry.GetValue("ComponentId")?.ToString();
|
||||
if (componentId == null)
|
||||
continue;
|
||||
|
||||
if (componentId == TUNTAP_COMPONENT_ID_0901 || componentId == TUNTAP_COMPONENT_ID_0801)
|
||||
return (string) (adapterRegistry.GetValue("NetCfgInstanceId") ??
|
||||
throw new Exception("Tap adapter have no NetCfgInstanceId key"));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning(e.ToString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 TUN/TAP 适配器名称
|
||||
/// </summary>
|
||||
/// <param name="componentId">适配器 ID</param>
|
||||
/// <returns>适配器名称</returns>
|
||||
public static string GetName(string componentId)
|
||||
{
|
||||
var registry = Registry.LocalMachine.OpenSubKey($"{NETWORK_KEY}\\{componentId}\\Connection");
|
||||
|
||||
return registry.GetValue("Name", "").ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 TUN/TAP 适配器
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool Create()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载tap网卡
|
||||
/// </summary>
|
||||
public static void deltapall()
|
||||
{
|
||||
Logging.Info("卸载 TUN/TAP 适配器");
|
||||
var installProcess = new Process
|
||||
{StartInfo = {WindowStyle = ProcessWindowStyle.Hidden, FileName = Path.Combine("bin/tap-driver", "deltapall.bat")}};
|
||||
|
||||
installProcess.Start();
|
||||
installProcess.WaitForExit();
|
||||
installProcess.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安装tap网卡
|
||||
/// </summary>
|
||||
public static void AddTap()
|
||||
{
|
||||
Logging.Info("安装 TUN/TAP 适配器");
|
||||
//安装Tap Driver
|
||||
using var process = Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = Path.Combine("bin/tap-driver", "addtap.bat"),
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
})!;
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
Thread.Sleep(1000);
|
||||
if (GetComponentID() == null)
|
||||
throw new MessageException("TAP 驱动安装失败,找不到 ComponentID 注册表项");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,8 +105,8 @@ namespace Netch.Utils
|
||||
try
|
||||
{
|
||||
var sha256 = SHA256.Create();
|
||||
var fileStream = File.OpenRead(filePath);
|
||||
return sha256.ComputeHash(fileStream).Aggregate(string.Empty, (current, b) => current + b.ToString("x2"));
|
||||
using var fileStream = File.OpenRead(filePath);
|
||||
return string.Concat(sha256.ComputeHash(fileStream).Select(b => b.ToString("x2")));
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -116,7 +116,10 @@ namespace Netch.Utils
|
||||
|
||||
public static string GetFileVersion(string file)
|
||||
{
|
||||
return File.Exists(file) ? FileVersionInfo.GetVersionInfo(file).FileVersion : string.Empty;
|
||||
if (File.Exists(file))
|
||||
return FileVersionInfo.GetVersionInfo(file).FileVersion ?? "";
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void DrawCenterComboBox(object sender, DrawItemEventArgs e)
|
||||
@@ -222,5 +225,55 @@ namespace Netch.Utils
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task ProcessRunHiddenAsync(string fileName, string arguments = "", bool print = true)
|
||||
{
|
||||
var p = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = arguments,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
Verb = "runas",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
Global.Logger.Debug($"{fileName} {arguments}");
|
||||
|
||||
p.Start();
|
||||
var output = await p.StandardOutput.ReadToEndAsync();
|
||||
var error = await p.StandardError.ReadToEndAsync();
|
||||
if (print)
|
||||
{
|
||||
Console.Write(output);
|
||||
Console.Write(error);
|
||||
}
|
||||
|
||||
p.WaitForExit();
|
||||
}
|
||||
|
||||
public static int SubnetToCidr(string value)
|
||||
{
|
||||
var subnet = IPAddress.Parse(value);
|
||||
return SubnetToCidr(subnet);
|
||||
}
|
||||
|
||||
public static int SubnetToCidr(IPAddress subnet)
|
||||
{
|
||||
return subnet.GetAddressBytes().Sum(b => Convert.ToString(b, 2).Count(c => c == '1'));
|
||||
}
|
||||
|
||||
public static string HostAppendPort(string host, ushort port = 53)
|
||||
{
|
||||
if (!host.Contains(':'))
|
||||
host += $":{port}";
|
||||
|
||||
return host;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -30,13 +29,6 @@ namespace Netch.Utils
|
||||
return req;
|
||||
}
|
||||
|
||||
public static IPEndPoint BestLocalEndPoint(IPEndPoint remoteIPEndPoint)
|
||||
{
|
||||
var testSocket = new Socket(remoteIPEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
|
||||
testSocket.Connect(remoteIPEndPoint);
|
||||
return (IPEndPoint) testSocket.LocalEndPoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步下载
|
||||
/// </summary>
|
||||
@@ -44,9 +36,9 @@ namespace Netch.Utils
|
||||
/// <returns></returns>
|
||||
public static async Task<byte[]> DownloadBytesAsync(HttpWebRequest req)
|
||||
{
|
||||
using var webResponse = (HttpWebResponse) await req.GetResponseAsync();
|
||||
using var memoryStream = new MemoryStream();
|
||||
using var input = webResponse.GetResponseStream();
|
||||
using var webResponse = req.GetResponseAsync();
|
||||
await using var memoryStream = new MemoryStream();
|
||||
await using var input = webResponse.Result.GetResponseStream();
|
||||
|
||||
await input.CopyToAsync(memoryStream);
|
||||
return memoryStream.ToArray();
|
||||
@@ -77,7 +69,7 @@ namespace Netch.Utils
|
||||
public static async Task<string> DownloadStringAsync(HttpWebRequest req, string encoding = "UTF-8")
|
||||
{
|
||||
using var webResponse = await req.GetResponseAsync();
|
||||
using var responseStream = webResponse.GetResponseStream();
|
||||
await using var responseStream = webResponse.GetResponseStream();
|
||||
using var streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encoding));
|
||||
|
||||
return await streamReader.ReadToEndAsync();
|
||||
@@ -92,8 +84,8 @@ namespace Netch.Utils
|
||||
public static async Task DownloadFileAsync(HttpWebRequest req, string fileFullPath)
|
||||
{
|
||||
using var webResponse = (HttpWebResponse) await req.GetResponseAsync();
|
||||
using var input = webResponse.GetResponseStream();
|
||||
using var fileStream = File.OpenWrite(fileFullPath);
|
||||
await using var input = webResponse.GetResponseStream();
|
||||
await using var fileStream = File.OpenWrite(fileFullPath);
|
||||
|
||||
await input.CopyToAsync(fileStream);
|
||||
fileStream.Flush();
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Netch.Utils
|
||||
{
|
||||
var oldLangCode = LangCode;
|
||||
LangCode = languages.FirstOrDefault(s => GetLanguage(s).Equals(GetLanguage(LangCode))) ?? "en-US";
|
||||
Logging.Info($"找不到语言 {oldLangCode}, 使用 {LangCode}");
|
||||
Global.Logger.Info($"找不到语言 {oldLangCode}, 使用 {LangCode}");
|
||||
}
|
||||
|
||||
switch (LangCode)
|
||||
@@ -61,7 +61,7 @@ namespace Netch.Utils
|
||||
|
||||
if (!dictionary.Any())
|
||||
{
|
||||
Logging.Error($"{LangCode} 语言文件错误");
|
||||
Global.Logger.Error($"{LangCode} 语言文件错误");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Netch.Utils
|
||||
var a = new StringBuilder();
|
||||
foreach (var t in text)
|
||||
if (t is string)
|
||||
a.Append(Data.Contains(t) ? Data[t].ToString() : t);
|
||||
a.Append(Data[t]?.ToString() ?? t);
|
||||
else
|
||||
a.Append(t);
|
||||
|
||||
|
||||
22
README.md
22
README.md
@@ -17,10 +17,11 @@ Game network accelerator
|
||||
- [Netch](#netch)
|
||||
- [TOC](#toc)
|
||||
- [Description](#description)
|
||||
- [Sponsor](#sponsor)
|
||||
- [Sponsor](#sponsor)
|
||||
- [Donate](#donate)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Requirements](#requirements)
|
||||
- [Quote](#quote)
|
||||
|
||||
## Description
|
||||
Netch is an open source game network accelerator. Unlike SSTap, which needs to add rules to function as a blacklist proxy, Netch is more similar to SocksCap64, which can scan the game directory to get their process names specifically and forward their network traffic through the proxy server
|
||||
@@ -36,7 +37,7 @@ Currently supports the following protocols
|
||||
As well, Netch avoid the restricted NAT problem caused by SSTap. You can use an NATTypeTester to test out what your NAT type is. When using SSTap to speed up some P2P gaming connections or the game is required for that kind of open NAT type, you may experience some bad situations such as unable to join the game
|
||||
|
||||
## Sponsor
|
||||
<a href="https://www.jetbrains.com/?from=Netch"><img src="images/jetbrains-variant-4.svg" alt="JetBrains" width="200"/></a>
|
||||
<a href="https://www.jetbrains.com/?from=Netch"><img src="jetbrains.svg" alt="JetBrains" width="200"/></a>
|
||||
|
||||
- [RabbitHosts](https://rabbithosts.com/cart.php)
|
||||
- [ManSora](https://www.mansora.co/cart.php)
|
||||
@@ -49,24 +50,21 @@ As well, Netch avoid the restricted NAT problem caused by SSTap. You can use an
|
||||

|
||||
|
||||
## Requirements
|
||||
- [.NET Framework 4.8 (Included in Windows 10 1903+)](https://dotnet.microsoft.com/download/dotnet-framework/net48)
|
||||
- [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0/runtime)
|
||||
|
||||
## Quote
|
||||
- [core](https://github.com/aiocloud/core)
|
||||
- [aiodns](https://github.com/aiocloud/aiodns)
|
||||
- [tun2socks](https://github.com/aiocloud/tun2socks)
|
||||
- [Redirector](https://github.com/aiocloud/Redirector)
|
||||
- [go-tun2socks](https://github.com/eycorsican/go-tun2socks)
|
||||
- [RouteHelper](https://github.com/aiocloud/RouteHelper)
|
||||
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
|
||||
- [NetFilter SDK](https://netfiltersdk.com)
|
||||
- [pcap2socks](https://github.com/zhxie/pcap2socks)
|
||||
- [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev)
|
||||
- [shadowsocksr-libev](https://github.com/shadowsocksrr/shadowsocksr-libev)
|
||||
- [Xray-core](https://github.com/XTLS/Xray-core)
|
||||
- [trojan](https://github.com/trojan-gfw/trojan)
|
||||
- [ACL4SSR](https://github.com/ACL4SSR/ACL4SSR)
|
||||
- [PAC](https://github.com/HMBSbige/Text_Translation/blob/master/ShadowsocksR/ss_white.pac)
|
||||
- [xray-core](https://github.com/XTLS/Xray-core)
|
||||
- [dnsmasq-china-list](https://github.com/felixonmars/dnsmasq-china-list)
|
||||
- [tap-windows6](https://github.com/OpenVPN/tap-windows6)
|
||||
- [Privoxy](https://www.privoxy.org/)
|
||||
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
|
||||
- [NetFilter SDK](https://netfiltersdk.com/)
|
||||
- [pcap2socks](https://github.com/zhxie/pcap2socks)
|
||||
|
||||
[](https://starchart.cc/NetchX/Netch)
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
游戏加速工具
|
||||
|
||||
## TOC
|
||||
- [Netch](#Netch)
|
||||
- [TOC](#TOC)
|
||||
- [Netch](#netch)
|
||||
- [TOC](#toc)
|
||||
- [简介](#简介)
|
||||
- [赞助商](#赞助商)
|
||||
- [赞助商](#赞助商)
|
||||
- [捐赠](#捐赠)
|
||||
- [依赖](#依赖)
|
||||
- [语言支持](#语言支持)
|
||||
- [语言支持](#语言支持)
|
||||
- [引用](#引用)
|
||||
|
||||
## 简介
|
||||
Netch 是一款 Windows 平台的开源游戏加速工具,Netch 可以实现类似 SocksCap64 那样的进程代理,也可以实现 SSTap 那样的全局 TUN/TAP 代理,和 Shadowsocks-Windows 那样的本地 Socks5,HTTP 和系统代理
|
||||
@@ -34,7 +35,7 @@ Netch 是一款 Windows 平台的开源游戏加速工具,Netch 可以实现
|
||||
与此同时 Netch 避免了 SSTap 的 NAT 问题 ,检查 NAT 类型即可知道是否有 NAT 问题。使用 SSTap 加速部分 P2P 联机,对 NAT 类型有要求的游戏时,可能会因为 NAT 类型严格遇到无法加入联机,或者其他影响游戏体验的情况
|
||||
|
||||
## 赞助商
|
||||
<a href="https://www.jetbrains.com/?from=Netch"><img src="images/jetbrains-variant-4.svg" alt="JetBrains" width="200"/></a>
|
||||
<a href="https://www.jetbrains.com/?from=Netch"><img src="jetbrains.svg" alt="JetBrains" width="200"/></a>
|
||||
|
||||
- [RabbitHosts](https://rabbithosts.com/cart.php)
|
||||
- [ManSora](https://www.mansora.co/cart.php)
|
||||
@@ -44,7 +45,7 @@ Netch 是一款 Windows 平台的开源游戏加速工具,Netch 可以实现
|
||||
- XMR *48ju3ELNZEa6wwPBMexCJ9G218BGY2XwhH6B6bmkFuJ3QgM4hPw2Pra35jPtuBZSc7SLNWeBpiWJZWjQeMAiLnTx2tH2Efx*
|
||||
|
||||
## 依赖
|
||||
- [.NET Framework 4.8 (Windows 10 1903+ 已包含)](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net48-offline-installer)
|
||||
- [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0/runtime)
|
||||
|
||||
## 语言支持
|
||||
Netch 内置 en-US 和 zh-CN,外置 zh-TW 等,默认根据系统语言选择语言。
|
||||
@@ -54,17 +55,16 @@ Netch 内置 en-US 和 zh-CN,外置 zh-TW 等,默认根据系统语言选择
|
||||
## 引用
|
||||
- [core](https://github.com/aiocloud/core)
|
||||
- [aiodns](https://github.com/aiocloud/aiodns)
|
||||
- [tun2socks](https://github.com/aiocloud/tun2socks)
|
||||
- [Redirector](https://github.com/aiocloud/Redirector)
|
||||
- [go-tun2socks](https://github.com/eycorsican/go-tun2socks)
|
||||
- [RouteHelper](https://github.com/aiocloud/RouteHelper)
|
||||
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
|
||||
- [NetFilter SDK](https://netfiltersdk.com)
|
||||
- [pcap2socks](https://github.com/zhxie/pcap2socks)
|
||||
- [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev)
|
||||
- [shadowsocksr-libev](https://github.com/shadowsocksrr/shadowsocksr-libev)
|
||||
- [Xray-core](https://github.com/XTLS/Xray-core)
|
||||
- [trojan](https://github.com/trojan-gfw/trojan)
|
||||
- [ACL4SSR](https://github.com/ACL4SSR/ACL4SSR)
|
||||
- [PAC](https://github.com/HMBSbige/Text_Translation/blob/master/ShadowsocksR/ss_white.pac)
|
||||
- [xray-core](https://github.com/XTLS/Xray-core)
|
||||
- [dnsmasq-china-list](https://github.com/felixonmars/dnsmasq-china-list)
|
||||
- [tap-windows6](https://github.com/OpenVPN/tap-windows6)
|
||||
- [Privoxy](https://www.privoxy.org/)
|
||||
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
|
||||
- [NetFilter SDK](https://netfiltersdk.com/)
|
||||
- [pcap2socks](https://github.com/zhxie/pcap2socks)
|
||||
|
||||
[](https://starchart.cc/NetchX/Netch)
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SearchComboBox")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SearchComboBox")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a8715af4-acc6-43f9-9381-4294c5360623")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user