mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d99eb1c5a | ||
|
|
487798f6a1 | ||
|
|
30084fbd1e | ||
|
|
abc7821fa5 | ||
|
|
45d3e2ac53 | ||
|
|
c5c95e2ab9 | ||
|
|
03ea032e5b | ||
|
|
d784586628 | ||
|
|
7042fcbadb | ||
|
|
43705b324e | ||
|
|
1ab65c9851 | ||
|
|
206cb18ef5 | ||
|
|
ffa329dd39 | ||
|
|
ab1b522e66 | ||
|
|
c328f75399 | ||
|
|
ca34cfdbb2 | ||
|
|
563565b3b4 | ||
|
|
752ba1b967 | ||
|
|
996ac3a03f | ||
|
|
36aa2c2b35 | ||
|
|
f4e1334118 | ||
|
|
24123174df | ||
|
|
22cbcd48ea | ||
|
|
c8f0865808 | ||
|
|
db822ea6a0 | ||
|
|
516c170a5d | ||
|
|
7c8290e665 | ||
|
|
1775221407 | ||
|
|
3edcd48d3c | ||
|
|
7d9dec3b76 | ||
|
|
9d4e6dde50 | ||
|
|
e0ca23fd20 | ||
|
|
a6831aa8b1 | ||
|
|
44c6900b42 | ||
|
|
6af239fcf9 | ||
|
|
a8154611aa | ||
|
|
a659ac3df1 | ||
|
|
1ea3b3ccb5 | ||
|
|
6622914248 | ||
|
|
04152d92ab | ||
|
|
4172bb0c7b | ||
|
|
c7d9f87920 | ||
|
|
ced1590435 | ||
|
|
3f25366982 | ||
|
|
ae3aee7478 | ||
|
|
77e1d5a80c | ||
|
|
5580969d16 | ||
|
|
23a3549f87 | ||
|
|
4b3d4d6d96 | ||
|
|
2f7bdc8e0b | ||
|
|
484527fdf6 | ||
|
|
01f60926ce | ||
|
|
99480e99c3 | ||
|
|
c696277b6b | ||
|
|
a7dd83448b | ||
|
|
0aa4a981fc | ||
|
|
2b7483b696 | ||
|
|
585a84321f | ||
|
|
dc7c48b1bb | ||
|
|
95aa3db415 | ||
|
|
276e516396 | ||
|
|
3fa3c1cfcb | ||
|
|
2d848f6708 | ||
|
|
504709b7da | ||
|
|
e37d1f21ba | ||
|
|
e2a20d5bb0 | ||
|
|
01cd51744f | ||
|
|
d3582340b0 | ||
|
|
98ece46832 | ||
|
|
bedafc23d4 |
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check Other
|
- name: Check Other
|
||||||
id: check_other
|
id: check_other
|
||||||
uses: andstor/file-existence-action@v1
|
uses: andstor/file-existence-action@v2
|
||||||
with:
|
with:
|
||||||
files: .\other\release\aiodns.bin
|
files: .\other\release\aiodns.bin
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
if: steps.check_other.outputs.files_exists == 'false'
|
if: steps.check_other.outputs.files_exists == 'false'
|
||||||
with:
|
with:
|
||||||
go-version: ^1.18.3
|
go-version: stable
|
||||||
|
|
||||||
- name: Setup C++
|
- name: Setup C++
|
||||||
uses: msys2/setup-msys2@v2
|
uses: msys2/setup-msys2@v2
|
||||||
@@ -73,7 +73,7 @@ jobs:
|
|||||||
profile: minimal
|
profile: minimal
|
||||||
|
|
||||||
- name: Setup MSBuild
|
- name: Setup MSBuild
|
||||||
uses: microsoft/setup-msbuild@v1.0.3
|
uses: microsoft/setup-msbuild@v1.3.1
|
||||||
with:
|
with:
|
||||||
vs-prerelease: true
|
vs-prerelease: true
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check Other
|
- name: Check Other
|
||||||
id: check_other
|
id: check_other
|
||||||
uses: andstor/file-existence-action@v1
|
uses: andstor/file-existence-action@v2
|
||||||
with:
|
with:
|
||||||
files: .\other\release\aiodns.bin
|
files: .\other\release\aiodns.bin
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ jobs:
|
|||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
if: steps.check_other.outputs.files_exists == 'false'
|
if: steps.check_other.outputs.files_exists == 'false'
|
||||||
with:
|
with:
|
||||||
go-version: ^1.18.3
|
go-version: stable
|
||||||
|
|
||||||
- name: Setup C++
|
- name: Setup C++
|
||||||
uses: msys2/setup-msys2@v2
|
uses: msys2/setup-msys2@v2
|
||||||
|
|||||||
20
.github/workflows/stale.yml
vendored
Normal file
20
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Close stale issues and PRs
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close-issues:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v7
|
||||||
|
with:
|
||||||
|
days-before-issue-stale: 30
|
||||||
|
days-before-issue-close: 14
|
||||||
|
days-before-pr-stale: 30
|
||||||
|
days-before-pr-close: 14
|
||||||
|
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
|
||||||
|
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
|
||||||
@@ -37,7 +37,7 @@ public class NFController : IModeController
|
|||||||
|
|
||||||
Dial(NameList.AIO_FILTERLOOPBACK, _mode.FilterLoopback);
|
Dial(NameList.AIO_FILTERLOOPBACK, _mode.FilterLoopback);
|
||||||
Dial(NameList.AIO_FILTERINTRANET, _mode.FilterIntranet);
|
Dial(NameList.AIO_FILTERINTRANET, _mode.FilterIntranet);
|
||||||
Dial(NameList.AIO_FILTERPARENT, _mode.FilterParent ?? _rdrConfig.HandleOnlyDNS);
|
Dial(NameList.AIO_FILTERPARENT, _mode.FilterParent ?? _rdrConfig.FilterParent);
|
||||||
Dial(NameList.AIO_FILTERICMP, _mode.FilterICMP ?? _rdrConfig.FilterICMP);
|
Dial(NameList.AIO_FILTERICMP, _mode.FilterICMP ?? _rdrConfig.FilterICMP);
|
||||||
if (_mode.FilterICMP ?? _rdrConfig.FilterICMP)
|
if (_mode.FilterICMP ?? _rdrConfig.FilterICMP)
|
||||||
Dial(NameList.AIO_ICMPING, (_mode.FilterICMP != null ? _mode.ICMPDelay ?? 10 : _rdrConfig.ICMPDelay).ToString());
|
Dial(NameList.AIO_ICMPING, (_mode.FilterICMP != null ? _mode.ICMPDelay ?? 10 : _rdrConfig.ICMPDelay).ToString());
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class PcapController : Guard, IModeController
|
|||||||
|
|
||||||
public override string Name => "pcap2socks";
|
public override string Name => "pcap2socks";
|
||||||
|
|
||||||
public ModeFeature Features => 0;
|
public ModeFeature Features => ModeFeature.SupportSocks5Auth;
|
||||||
|
|
||||||
public async Task StartAsync(Socks5Server server, Mode mode)
|
public async Task StartAsync(Socks5Server server, Mode mode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public static class UpdateChecker
|
|||||||
public const string Name = @"Netch";
|
public const string Name = @"Netch";
|
||||||
public const string Copyright = @"Copyright © 2019 - 2022";
|
public const string Copyright = @"Copyright © 2019 - 2022";
|
||||||
|
|
||||||
public const string AssemblyVersion = @"1.9.6";
|
public const string AssemblyVersion = @"1.9.7";
|
||||||
private const string Suffix = @"";
|
private const string Suffix = @"";
|
||||||
|
|
||||||
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";
|
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";
|
||||||
@@ -103,4 +103,4 @@ public static class UpdateChecker
|
|||||||
var ordered = releases.OrderByDescending(release => release.tag_name, new VersionUtil.VersionComparer());
|
var ordered = releases.OrderByDescending(release => release.tag_name, new VersionUtil.VersionComparer());
|
||||||
return ordered.ElementAt(0);
|
return ordered.ElementAt(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
Netch/Forms/SettingForm.Designer.cs
generated
13
Netch/Forms/SettingForm.Designer.cs
generated
@@ -80,6 +80,7 @@ namespace Netch.Forms
|
|||||||
this.XrayConeCheckBox = new System.Windows.Forms.CheckBox();
|
this.XrayConeCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
this.TLSAllowInsecureCheckBox = new System.Windows.Forms.CheckBox();
|
this.TLSAllowInsecureCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
this.UseMuxCheckBox = new System.Windows.Forms.CheckBox();
|
this.UseMuxCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
|
this.TCPFastOpenBox = new System.Windows.Forms.CheckBox();
|
||||||
this.KCPGroupBox = new System.Windows.Forms.GroupBox();
|
this.KCPGroupBox = new System.Windows.Forms.GroupBox();
|
||||||
this.mtuLabel = new System.Windows.Forms.Label();
|
this.mtuLabel = new System.Windows.Forms.Label();
|
||||||
this.mtuTextBox = new System.Windows.Forms.TextBox();
|
this.mtuTextBox = new System.Windows.Forms.TextBox();
|
||||||
@@ -590,6 +591,7 @@ namespace Netch.Forms
|
|||||||
this.v2rayTabPage.Controls.Add(this.XrayConeCheckBox);
|
this.v2rayTabPage.Controls.Add(this.XrayConeCheckBox);
|
||||||
this.v2rayTabPage.Controls.Add(this.TLSAllowInsecureCheckBox);
|
this.v2rayTabPage.Controls.Add(this.TLSAllowInsecureCheckBox);
|
||||||
this.v2rayTabPage.Controls.Add(this.UseMuxCheckBox);
|
this.v2rayTabPage.Controls.Add(this.UseMuxCheckBox);
|
||||||
|
this.v2rayTabPage.Controls.Add(this.TCPFastOpenBox);
|
||||||
this.v2rayTabPage.Controls.Add(this.KCPGroupBox);
|
this.v2rayTabPage.Controls.Add(this.KCPGroupBox);
|
||||||
this.v2rayTabPage.Location = new System.Drawing.Point(4, 29);
|
this.v2rayTabPage.Location = new System.Drawing.Point(4, 29);
|
||||||
this.v2rayTabPage.Name = "v2rayTabPage";
|
this.v2rayTabPage.Name = "v2rayTabPage";
|
||||||
@@ -628,6 +630,16 @@ namespace Netch.Forms
|
|||||||
this.UseMuxCheckBox.Text = "Use Mux";
|
this.UseMuxCheckBox.Text = "Use Mux";
|
||||||
this.UseMuxCheckBox.UseVisualStyleBackColor = true;
|
this.UseMuxCheckBox.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
// TCPFastOpenBox
|
||||||
|
//
|
||||||
|
this.TCPFastOpenBox.AutoSize = true;
|
||||||
|
this.TCPFastOpenBox.Location = new System.Drawing.Point(300, 42);
|
||||||
|
this.TCPFastOpenBox.Name = "TCPFastOpenBox";
|
||||||
|
this.TCPFastOpenBox.Size = new System.Drawing.Size(131, 21);
|
||||||
|
this.TCPFastOpenBox.TabIndex = 3;
|
||||||
|
this.TCPFastOpenBox.Text = "TCP FastOpen";
|
||||||
|
this.TCPFastOpenBox.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
// KCPGroupBox
|
// KCPGroupBox
|
||||||
//
|
//
|
||||||
this.KCPGroupBox.Controls.Add(this.mtuLabel);
|
this.KCPGroupBox.Controls.Add(this.mtuLabel);
|
||||||
@@ -1063,6 +1075,7 @@ namespace Netch.Forms
|
|||||||
private System.Windows.Forms.GroupBox KCPGroupBox;
|
private System.Windows.Forms.GroupBox KCPGroupBox;
|
||||||
private System.Windows.Forms.CheckBox congestionCheckBox;
|
private System.Windows.Forms.CheckBox congestionCheckBox;
|
||||||
private System.Windows.Forms.CheckBox TLSAllowInsecureCheckBox;
|
private System.Windows.Forms.CheckBox TLSAllowInsecureCheckBox;
|
||||||
|
private System.Windows.Forms.CheckBox TCPFastOpenBox;
|
||||||
private System.Windows.Forms.Label mtuLabel;
|
private System.Windows.Forms.Label mtuLabel;
|
||||||
private System.Windows.Forms.TextBox mtuTextBox;
|
private System.Windows.Forms.TextBox mtuTextBox;
|
||||||
private System.Windows.Forms.Label writeBufferSizeLabel;
|
private System.Windows.Forms.Label writeBufferSizeLabel;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public partial class SettingForm : BindingForm
|
|||||||
BindCheckBox(UseCustomDNSCheckBox, b => { Global.Settings.TUNTAP.UseCustomDNS = b; }, Global.Settings.TUNTAP.UseCustomDNS);
|
BindCheckBox(UseCustomDNSCheckBox, b => { Global.Settings.TUNTAP.UseCustomDNS = b; }, Global.Settings.TUNTAP.UseCustomDNS);
|
||||||
|
|
||||||
BindTextBox(TUNTAPDNSTextBox,
|
BindTextBox(TUNTAPDNSTextBox,
|
||||||
s => true,
|
s => UseCustomDNSCheckBox.Checked ? IPAddress.TryParse(s, out _) : true,
|
||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
if (UseCustomDNSCheckBox.Checked)
|
if (UseCustomDNSCheckBox.Checked)
|
||||||
@@ -120,11 +120,11 @@ public partial class SettingForm : BindingForm
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region V2Ray
|
#region V2Ray
|
||||||
|
|
||||||
BindCheckBox(XrayConeCheckBox, b => Global.Settings.V2RayConfig.XrayCone = b, Global.Settings.V2RayConfig.XrayCone);
|
BindCheckBox(XrayConeCheckBox, b => Global.Settings.V2RayConfig.XrayCone = b, Global.Settings.V2RayConfig.XrayCone);
|
||||||
|
|
||||||
BindCheckBox(TLSAllowInsecureCheckBox, b => Global.Settings.V2RayConfig.AllowInsecure = b, Global.Settings.V2RayConfig.AllowInsecure);
|
BindCheckBox(TLSAllowInsecureCheckBox, b => Global.Settings.V2RayConfig.AllowInsecure = b, Global.Settings.V2RayConfig.AllowInsecure);
|
||||||
BindCheckBox(UseMuxCheckBox, b => Global.Settings.V2RayConfig.UseMux = b, Global.Settings.V2RayConfig.UseMux);
|
BindCheckBox(UseMuxCheckBox, b => Global.Settings.V2RayConfig.UseMux = b, Global.Settings.V2RayConfig.UseMux);
|
||||||
|
BindCheckBox(TCPFastOpenBox, b => Global.Settings.V2RayConfig.TCPFastOpen = b, Global.Settings.V2RayConfig.TCPFastOpen);
|
||||||
|
|
||||||
BindTextBox<int>(mtuTextBox, i => true, i => Global.Settings.V2RayConfig.KcpConfig.mtu = i, Global.Settings.V2RayConfig.KcpConfig.mtu);
|
BindTextBox<int>(mtuTextBox, i => true, i => Global.Settings.V2RayConfig.KcpConfig.mtu = i, Global.Settings.V2RayConfig.KcpConfig.mtu);
|
||||||
BindTextBox<int>(ttiTextBox, i => true, i => Global.Settings.V2RayConfig.KcpConfig.tti = i, Global.Settings.V2RayConfig.KcpConfig.tti);
|
BindTextBox<int>(ttiTextBox, i => true, i => Global.Settings.V2RayConfig.KcpConfig.tti = i, Global.Settings.V2RayConfig.KcpConfig.tti);
|
||||||
|
|||||||
@@ -11,4 +11,6 @@ public class V2rayConfig
|
|||||||
public bool V2rayNShareLink { get; set; } = true;
|
public bool V2rayNShareLink { get; set; } = true;
|
||||||
|
|
||||||
public bool XrayCone { get; set; } = true;
|
public bool XrayCone { get; set; } = true;
|
||||||
|
|
||||||
|
public bool TCPFastOpen { get; set; } = false;
|
||||||
}
|
}
|
||||||
@@ -38,17 +38,17 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1">
|
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Fody" Version="6.6.2">
|
<PackageReference Include="Fody" Version="6.6.4">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="HMBSbige.SingleInstance" Version="6.0.0" />
|
<PackageReference Include="HMBSbige.SingleInstance" Version="6.0.0" />
|
||||||
<PackageReference Include="MaxMind.GeoIP2" Version="5.1.0" />
|
<PackageReference Include="MaxMind.GeoIP2" Version="5.1.0" />
|
||||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.0.1" GeneratePathProperty="true" />
|
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.0.7" GeneratePathProperty="true" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.2.32" />
|
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.5.22" />
|
||||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.588-beta">
|
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.588-beta">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
@@ -57,17 +57,17 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0" />
|
<PackageReference Include="Serilog.Extensions.Hosting" Version="5.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||||
<PackageReference Include="Stun.Net" Version="6.2.0" />
|
<PackageReference Include="Stun.Net" Version="6.2.0" />
|
||||||
<PackageReference Include="System.Management" Version="6.0.0" />
|
<PackageReference Include="System.Management" Version="7.0.0" />
|
||||||
<PackageReference Include="TaskScheduler" Version="2.10.1" />
|
<PackageReference Include="TaskScheduler" Version="2.10.1" />
|
||||||
<PackageReference Include="WindowsFirewallHelper" Version="2.2.0.86" />
|
<PackageReference Include="WindowsFirewallHelper" Version="2.2.0.86" />
|
||||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
|
<PackageReference Include="System.ServiceProcess.ServiceController" Version="7.0.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
|
||||||
<PackageReference Include="WindowsJobAPI" Version="6.0.0" />
|
<PackageReference Include="WindowsJobAPI" Version="6.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,9 @@
|
|||||||
|
|
||||||
"Address": "地址",
|
"Address": "地址",
|
||||||
"Username": "用户名",
|
"Username": "用户名",
|
||||||
|
"User": "用户",
|
||||||
"Password": "密码",
|
"Password": "密码",
|
||||||
|
"Version": "版本",
|
||||||
"User ID": "用户 ID",
|
"User ID": "用户 ID",
|
||||||
"Alter ID": "额外 ID",
|
"Alter ID": "额外 ID",
|
||||||
"Transfer Protocol": "传输协议",
|
"Transfer Protocol": "传输协议",
|
||||||
@@ -70,7 +72,7 @@
|
|||||||
"Plugin Options": "插件参数",
|
"Plugin Options": "插件参数",
|
||||||
"Remote Address": "远端地址",
|
"Remote Address": "远端地址",
|
||||||
"Local Addresses": "本地地址(可多个)",
|
"Local Addresses": "本地地址(可多个)",
|
||||||
"Public Key": "节点公钥",
|
"Public Key": "公钥",
|
||||||
"Private Key": "私钥",
|
"Private Key": "私钥",
|
||||||
"PSK": "节点预共享密钥",
|
"PSK": "节点预共享密钥",
|
||||||
|
|
||||||
@@ -182,6 +184,7 @@
|
|||||||
"STUN Server": "STUN 服务器",
|
"STUN Server": "STUN 服务器",
|
||||||
"Language": "语言",
|
"Language": "语言",
|
||||||
"FullCone Support (Required Server Xray-core v1.3.0+)": "FullCone 支持(需服务端 Xray-core v1.3.0+)",
|
"FullCone Support (Required Server Xray-core v1.3.0+)": "FullCone 支持(需服务端 Xray-core v1.3.0+)",
|
||||||
|
"TCP FastOpen": "TCP 快速打开",
|
||||||
"Disable Support Warning": "停用支持警告",
|
"Disable Support Warning": "停用支持警告",
|
||||||
|
|
||||||
"Profile": "配置名",
|
"Profile": "配置名",
|
||||||
|
|||||||
19
Netch/Servers/SSH/SSHForm.cs
Normal file
19
Netch/Servers/SSH/SSHForm.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Netch.Forms;
|
||||||
|
|
||||||
|
namespace Netch.Servers;
|
||||||
|
|
||||||
|
[Fody.ConfigureAwait(true)]
|
||||||
|
public class SSHForm : ServerForm
|
||||||
|
{
|
||||||
|
public SSHForm(SSHServer? server = default)
|
||||||
|
{
|
||||||
|
server ??= new SSHServer();
|
||||||
|
Server = server;
|
||||||
|
CreateTextBox("User", "User", s => true, s => server.User = s, server.User);
|
||||||
|
CreateTextBox("Password", "Password", s => true, s => server.Password = s, server.Password);
|
||||||
|
CreateTextBox("PrivateKey", "Private Key", s => true, s => server.PrivateKey = s, server.PrivateKey);
|
||||||
|
CreateTextBox("PublicKey", "Public Key", s => true, s => server.PublicKey = s, server.PublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string TypeName { get; } = "SSH";
|
||||||
|
}
|
||||||
33
Netch/Servers/SSH/SSHServer.cs
Normal file
33
Netch/Servers/SSH/SSHServer.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Netch.Models;
|
||||||
|
|
||||||
|
namespace Netch.Servers;
|
||||||
|
|
||||||
|
public class SSHServer : Server
|
||||||
|
{
|
||||||
|
public override string Type { get; } = "SSH";
|
||||||
|
|
||||||
|
public override string MaskedData()
|
||||||
|
{
|
||||||
|
return $"{User}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户
|
||||||
|
/// </summary>
|
||||||
|
public string User { get; set; } = "root";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
public string Password { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 私钥
|
||||||
|
/// </summary>
|
||||||
|
public string PrivateKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主机公钥
|
||||||
|
/// </summary>
|
||||||
|
public string? PublicKey { get; set; }
|
||||||
|
}
|
||||||
53
Netch/Servers/SSH/SSHUtil.cs
Normal file
53
Netch/Servers/SSH/SSHUtil.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Netch.Interfaces;
|
||||||
|
using Netch.Models;
|
||||||
|
using Netch.Utils;
|
||||||
|
|
||||||
|
namespace Netch.Servers;
|
||||||
|
|
||||||
|
public class SSHUtil : IServerUtil
|
||||||
|
{
|
||||||
|
public ushort Priority { get; } = 4;
|
||||||
|
|
||||||
|
public string TypeName { get; } = "SSH";
|
||||||
|
|
||||||
|
public string FullName { get; } = "SSH";
|
||||||
|
|
||||||
|
public string ShortName { get; } = "SSH";
|
||||||
|
|
||||||
|
public string[] UriScheme { get; } = { "ssh" };
|
||||||
|
|
||||||
|
public Type ServerType { get; } = typeof(SSHServer);
|
||||||
|
|
||||||
|
public void Edit(Server s)
|
||||||
|
{
|
||||||
|
new SSHForm((SSHServer)s).ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Create()
|
||||||
|
{
|
||||||
|
new SSHForm().ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetShareLink(Server s)
|
||||||
|
{
|
||||||
|
return V2rayUtils.GetVShareLink(s, "ssh");
|
||||||
|
}
|
||||||
|
|
||||||
|
public IServerController GetController()
|
||||||
|
{
|
||||||
|
return new V2rayController();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Server> ParseUri(string text)
|
||||||
|
{
|
||||||
|
return V2rayUtils.ParseVUri(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckServer(Server s)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,11 @@ public class Socks5Form : ServerForm
|
|||||||
Server = server;
|
Server = server;
|
||||||
CreateTextBox("Username", "Username", s => true, s => server.Username = s, server.Username.ValueOrDefault());
|
CreateTextBox("Username", "Username", s => true, s => server.Username = s, server.Username.ValueOrDefault());
|
||||||
CreateTextBox("Password", "Password", s => true, s => server.Password = s, server.Password.ValueOrDefault());
|
CreateTextBox("Password", "Password", s => true, s => server.Password = s, server.Password.ValueOrDefault());
|
||||||
|
CreateComboBox("Version",
|
||||||
|
"Version",
|
||||||
|
SOCKSGlobal.Versions,
|
||||||
|
s => server.Version = s,
|
||||||
|
server.Version);
|
||||||
(_remoteHostnameLabel, _remoteHostnameTextBox) = CreateTextBox("RemoteHostname",
|
(_remoteHostnameLabel, _remoteHostnameTextBox) = CreateTextBox("RemoteHostname",
|
||||||
"Remote Address",
|
"Remote Address",
|
||||||
s => true,
|
s => true,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace Netch.Servers;
|
|||||||
|
|
||||||
public class Socks5Server : Server
|
public class Socks5Server : Server
|
||||||
{
|
{
|
||||||
public override string Type { get; } = "Socks5";
|
public override string Type { get; } = "SOCKS";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 密码
|
/// 密码
|
||||||
@@ -18,6 +18,11 @@ public class Socks5Server : Server
|
|||||||
|
|
||||||
public string? RemoteHostname { get; set; }
|
public string? RemoteHostname { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 版本
|
||||||
|
/// </summary>
|
||||||
|
public string Version { get; set; } = SOCKSGlobal.Versions[0];
|
||||||
|
|
||||||
public override string MaskedData()
|
public override string MaskedData()
|
||||||
{
|
{
|
||||||
return $"Auth: {Auth()}";
|
return $"Auth: {Auth()}";
|
||||||
@@ -48,4 +53,14 @@ public class Socks5Server : Server
|
|||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password);
|
return !string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SOCKSGlobal
|
||||||
|
{
|
||||||
|
public static readonly List<string> Versions = new()
|
||||||
|
{
|
||||||
|
"5",
|
||||||
|
"4a",
|
||||||
|
"4"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -7,11 +7,11 @@ public class Socks5Util : IServerUtil
|
|||||||
{
|
{
|
||||||
public ushort Priority { get; } = 0;
|
public ushort Priority { get; } = 0;
|
||||||
|
|
||||||
public string TypeName { get; } = "Socks5";
|
public string TypeName { get; } = "SOCKS";
|
||||||
|
|
||||||
public string FullName { get; } = "Socks5";
|
public string FullName { get; } = "SOCKS";
|
||||||
|
|
||||||
public string ShortName { get; } = "S5";
|
public string ShortName { get; } = "SOCKS";
|
||||||
|
|
||||||
public string[] UriScheme { get; } = { };
|
public string[] UriScheme { get; } = { };
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,16 @@ public class OutboundConfiguration
|
|||||||
|
|
||||||
public object[] servers { get; set; }
|
public object[] servers { get; set; }
|
||||||
|
|
||||||
|
public string version { get; set; }
|
||||||
|
|
||||||
public string address { get; set; }
|
public string address { get; set; }
|
||||||
|
|
||||||
|
public string user { get; set; }
|
||||||
|
|
||||||
public ushort port { get; set; }
|
public ushort port { get; set; }
|
||||||
|
|
||||||
|
public string password { get; set; }
|
||||||
|
|
||||||
public string packetEncoding { get; set; }
|
public string packetEncoding { get; set; }
|
||||||
|
|
||||||
public string plugin { get; set; }
|
public string plugin { get; set; }
|
||||||
@@ -56,6 +62,8 @@ public class OutboundConfiguration
|
|||||||
|
|
||||||
public string peerPublicKey { get; set; }
|
public string peerPublicKey { get; set; }
|
||||||
|
|
||||||
|
public string publicKey { get; set; }
|
||||||
|
|
||||||
public string privateKey { get; set; }
|
public string privateKey { get; set; }
|
||||||
|
|
||||||
public string preSharedKey { get; set; }
|
public string preSharedKey { get; set; }
|
||||||
@@ -81,6 +89,8 @@ public class ShadowsocksServerItem
|
|||||||
public string method { get; set; }
|
public string method { get; set; }
|
||||||
|
|
||||||
public string password { get; set; }
|
public string password { get; set; }
|
||||||
|
|
||||||
|
public string flow { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Mux
|
public class Mux
|
||||||
@@ -113,6 +123,8 @@ public class StreamSettings
|
|||||||
public TlsSettings xtlsSettings { get; set; }
|
public TlsSettings xtlsSettings { get; set; }
|
||||||
|
|
||||||
public GrpcSettings grpcSettings { get; set; }
|
public GrpcSettings grpcSettings { get; set; }
|
||||||
|
|
||||||
|
public Sockopt sockopt { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Transport
|
#region Transport
|
||||||
@@ -180,4 +192,9 @@ public class GrpcSettings
|
|||||||
public bool multiMode { get; set; }
|
public bool multiMode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Sockopt
|
||||||
|
{
|
||||||
|
public bool tcpFastOpen { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -42,7 +42,7 @@ public static class V2rayConfigUtils
|
|||||||
|
|
||||||
switch (server)
|
switch (server)
|
||||||
{
|
{
|
||||||
case Socks5Server socks5:
|
case Socks5Server socks:
|
||||||
{
|
{
|
||||||
outbound.protocol = "socks";
|
outbound.protocol = "socks";
|
||||||
outbound.settings.servers = new object[]
|
outbound.settings.servers = new object[]
|
||||||
@@ -51,19 +51,20 @@ public static class V2rayConfigUtils
|
|||||||
{
|
{
|
||||||
address = await server.AutoResolveHostnameAsync(),
|
address = await server.AutoResolveHostnameAsync(),
|
||||||
port = server.Port,
|
port = server.Port,
|
||||||
users = socks5.Auth()
|
users = socks.Auth()
|
||||||
? new[]
|
? new[]
|
||||||
{
|
{
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
user = socks5.Username,
|
user = socks.Username,
|
||||||
pass = socks5.Password,
|
pass = socks.Password,
|
||||||
level = 1
|
level = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
outbound.settings.version = socks.Version;
|
||||||
|
|
||||||
outbound.mux.enabled = false;
|
outbound.mux.enabled = false;
|
||||||
outbound.mux.concurrency = -1;
|
outbound.mux.concurrency = -1;
|
||||||
@@ -82,8 +83,8 @@ public static class V2rayConfigUtils
|
|||||||
{
|
{
|
||||||
new User
|
new User
|
||||||
{
|
{
|
||||||
id = vless.UserID,
|
id = getUUID(vless.UserID),
|
||||||
flow = vless.Flow.ValueOrDefault(),
|
flow = vless.TLSSecureType == "xtls" ? "xtls-rprx-direct" : "",
|
||||||
encryption = vless.EncryptMethod
|
encryption = vless.EncryptMethod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +126,7 @@ public static class V2rayConfigUtils
|
|||||||
{
|
{
|
||||||
new User
|
new User
|
||||||
{
|
{
|
||||||
id = vmess.UserID,
|
id = getUUID(vmess.UserID),
|
||||||
alterId = vmess.AlterID,
|
alterId = vmess.AlterID,
|
||||||
security = vmess.EncryptMethod
|
security = vmess.EncryptMethod
|
||||||
}
|
}
|
||||||
@@ -144,59 +145,73 @@ public static class V2rayConfigUtils
|
|||||||
}
|
}
|
||||||
case ShadowsocksServer ss:
|
case ShadowsocksServer ss:
|
||||||
outbound.protocol = "shadowsocks";
|
outbound.protocol = "shadowsocks";
|
||||||
outbound.settings = new OutboundConfiguration
|
outbound.settings.servers = new[]
|
||||||
{
|
{
|
||||||
servers = new[]
|
new ShadowsocksServerItem
|
||||||
{
|
{
|
||||||
new ShadowsocksServerItem
|
address = await server.AutoResolveHostnameAsync(),
|
||||||
{
|
port = server.Port,
|
||||||
address = await server.AutoResolveHostnameAsync(),
|
method = ss.EncryptMethod,
|
||||||
port = server.Port,
|
password = ss.Password
|
||||||
method = ss.EncryptMethod,
|
}
|
||||||
password = ss.Password,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugin = ss.Plugin ?? "",
|
|
||||||
pluginOpts = ss.PluginOption ?? ""
|
|
||||||
};
|
};
|
||||||
|
outbound.settings.plugin = ss.Plugin ?? "";
|
||||||
|
outbound.settings.pluginOpts = ss.PluginOption ?? "";
|
||||||
|
|
||||||
|
if (Global.Settings.V2RayConfig.TCPFastOpen)
|
||||||
|
{
|
||||||
|
outbound.streamSettings = new StreamSettings
|
||||||
|
{
|
||||||
|
sockopt = new Sockopt
|
||||||
|
{
|
||||||
|
tcpFastOpen = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShadowsocksRServer ssr:
|
case ShadowsocksRServer ssr:
|
||||||
outbound.protocol = "shadowsocks";
|
outbound.protocol = "shadowsocks";
|
||||||
outbound.settings = new OutboundConfiguration
|
outbound.settings.servers = new[]
|
||||||
{
|
{
|
||||||
servers = new[]
|
new ShadowsocksServerItem
|
||||||
{
|
{
|
||||||
new ShadowsocksServerItem
|
address = await server.AutoResolveHostnameAsync(),
|
||||||
{
|
port = server.Port,
|
||||||
address = await server.AutoResolveHostnameAsync(),
|
method = ssr.EncryptMethod,
|
||||||
port = server.Port,
|
password = ssr.Password,
|
||||||
method = ssr.EncryptMethod,
|
|
||||||
password = ssr.Password,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugin = "shadowsocksr",
|
|
||||||
pluginArgs = new string[]
|
|
||||||
{
|
|
||||||
"--obfs=" + ssr.OBFS,
|
|
||||||
"--obfs-param=" + ssr.OBFSParam ?? "",
|
|
||||||
"--protocol=" + ssr.Protocol,
|
|
||||||
"--protocol-param=" + ssr.ProtocolParam ?? ""
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
outbound.settings.plugin = "shadowsocksr";
|
||||||
|
outbound.settings.pluginArgs = new string[]
|
||||||
|
{
|
||||||
|
"--obfs=" + ssr.OBFS,
|
||||||
|
"--obfs-param=" + ssr.OBFSParam ?? "",
|
||||||
|
"--protocol=" + ssr.Protocol,
|
||||||
|
"--protocol-param=" + ssr.ProtocolParam ?? ""
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Global.Settings.V2RayConfig.TCPFastOpen)
|
||||||
|
{
|
||||||
|
outbound.streamSettings = new StreamSettings
|
||||||
|
{
|
||||||
|
sockopt = new Sockopt
|
||||||
|
{
|
||||||
|
tcpFastOpen = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TrojanServer trojan:
|
case TrojanServer trojan:
|
||||||
outbound.protocol = "trojan";
|
outbound.protocol = "trojan";
|
||||||
outbound.settings = new OutboundConfiguration
|
outbound.settings.servers = new[]
|
||||||
{
|
{
|
||||||
servers = new[]
|
new ShadowsocksServerItem // I'm not serious
|
||||||
{
|
{
|
||||||
new ShadowsocksServerItem // I'm not serious
|
address = await server.AutoResolveHostnameAsync(),
|
||||||
{
|
port = server.Port,
|
||||||
address = await server.AutoResolveHostnameAsync(),
|
method = "",
|
||||||
port = server.Port,
|
password = trojan.Password,
|
||||||
method = "",
|
flow = trojan.TLSSecureType == "xtls" ? "xtls-rprx-direct" : ""
|
||||||
password = trojan.Password
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -223,21 +238,57 @@ public static class V2rayConfigUtils
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Global.Settings.V2RayConfig.TCPFastOpen)
|
||||||
|
{
|
||||||
|
outbound.streamSettings.sockopt = new Sockopt
|
||||||
|
{
|
||||||
|
tcpFastOpen = true
|
||||||
|
};
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WireGuardServer wg:
|
case WireGuardServer wg:
|
||||||
outbound.protocol = "wireguard";
|
outbound.protocol = "wireguard";
|
||||||
outbound.settings = new OutboundConfiguration
|
outbound.settings.address = await server.AutoResolveHostnameAsync();
|
||||||
|
outbound.settings.port = server.Port;
|
||||||
|
outbound.settings.localAddresses = wg.LocalAddresses.SplitOrDefault();
|
||||||
|
outbound.settings.peerPublicKey = wg.PeerPublicKey;
|
||||||
|
outbound.settings.privateKey = wg.PrivateKey;
|
||||||
|
outbound.settings.preSharedKey = wg.PreSharedKey;
|
||||||
|
outbound.settings.mtu = wg.MTU;
|
||||||
|
|
||||||
|
if (Global.Settings.V2RayConfig.TCPFastOpen)
|
||||||
{
|
{
|
||||||
address = await server.AutoResolveHostnameAsync(),
|
outbound.streamSettings = new StreamSettings
|
||||||
port = server.Port,
|
{
|
||||||
localAddresses = wg.LocalAddresses.SplitOrDefault(),
|
sockopt = new Sockopt
|
||||||
peerPublicKey = wg.PeerPublicKey,
|
{
|
||||||
privateKey = wg.PrivateKey,
|
tcpFastOpen = true
|
||||||
preSharedKey = wg.PreSharedKey,
|
}
|
||||||
mtu = wg.MTU
|
};
|
||||||
};
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SSHServer ssh:
|
||||||
|
outbound.protocol = "ssh";
|
||||||
|
outbound.settings.address = await server.AutoResolveHostnameAsync();
|
||||||
|
outbound.settings.port = server.Port;
|
||||||
|
outbound.settings.user = ssh.User;
|
||||||
|
outbound.settings.password = ssh.Password;
|
||||||
|
outbound.settings.privateKey = ssh.PrivateKey;
|
||||||
|
outbound.settings.publicKey = ssh.PublicKey;
|
||||||
|
|
||||||
|
if (Global.Settings.V2RayConfig.TCPFastOpen)
|
||||||
|
{
|
||||||
|
outbound.streamSettings = new StreamSettings
|
||||||
|
{
|
||||||
|
sockopt = new Sockopt
|
||||||
|
{
|
||||||
|
tcpFastOpen = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return outbound;
|
return outbound;
|
||||||
@@ -364,6 +415,23 @@ public static class V2rayConfigUtils
|
|||||||
throw new MessageException($"transfer protocol \"{server.TransferProtocol}\" not implemented yet");
|
throw new MessageException($"transfer protocol \"{server.TransferProtocol}\" not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Global.Settings.V2RayConfig.TCPFastOpen)
|
||||||
|
{
|
||||||
|
streamSettings.sockopt = new Sockopt
|
||||||
|
{
|
||||||
|
tcpFastOpen = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return streamSettings;
|
return streamSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string getUUID(string uuid)
|
||||||
|
{
|
||||||
|
if (uuid.Length == 36 || uuid.Length == 32)
|
||||||
|
{
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
return uuid.GenerateUUIDv5();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -55,8 +55,6 @@ public static class V2rayUtils
|
|||||||
if (server.TLSSecureType != "none")
|
if (server.TLSSecureType != "none")
|
||||||
{
|
{
|
||||||
server.ServerName = parameter.Get("sni") ?? "";
|
server.ServerName = parameter.Get("sni") ?? "";
|
||||||
if (server.TLSSecureType == "xtls")
|
|
||||||
((VLESSServer)server).Flow = "xtls-rprx-direct"; // splice doesn't support Windows
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +135,7 @@ public static class V2rayUtils
|
|||||||
|
|
||||||
if (server.TLSSecureType == "xtls")
|
if (server.TLSSecureType == "xtls")
|
||||||
{
|
{
|
||||||
var flow = ((VLESSServer)server).Flow;
|
parameter.Add("flow", "xtls-rprx-direct");
|
||||||
if (!flow.IsNullOrWhiteSpace())
|
|
||||||
parameter.Add("flow", flow!.Replace("-udp443", ""));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ internal class VLESSForm : ServerForm
|
|||||||
s => server.EncryptMethod = !string.IsNullOrWhiteSpace(s) ? s : "none",
|
s => server.EncryptMethod = !string.IsNullOrWhiteSpace(s) ? s : "none",
|
||||||
server.EncryptMethod);
|
server.EncryptMethod);
|
||||||
|
|
||||||
CreateTextBox("Flow", "Flow", s => true, s => server.Flow = s, server.Flow);
|
|
||||||
CreateComboBox("TransferProtocol",
|
CreateComboBox("TransferProtocol",
|
||||||
"Transfer Protocol",
|
"Transfer Protocol",
|
||||||
VLESSGlobal.TransferProtocols,
|
VLESSGlobal.TransferProtocols,
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ public class VLESSServer : VMessServer
|
|||||||
/// 伪装类型
|
/// 伪装类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string FakeType { get; set; } = VLESSGlobal.FakeTypes[0];
|
public override string FakeType { get; set; } = VLESSGlobal.FakeTypes[0];
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
public string? Flow { get; set; } = "xtls-rprx-direct";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VLESSGlobal
|
public class VLESSGlobal
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using Microsoft.VisualStudio.Threading;
|
||||||
|
|
||||||
namespace Netch.Utils;
|
namespace Netch.Utils;
|
||||||
|
|
||||||
public static class DnsUtils
|
public static class DnsUtils
|
||||||
{
|
{
|
||||||
|
private static readonly AsyncSemaphore Lock = new(1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 缓存
|
/// 缓存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -14,6 +17,7 @@ public static class DnsUtils
|
|||||||
|
|
||||||
public static async Task<IPAddress?> LookupAsync(string hostname, AddressFamily inet = AddressFamily.Unspecified, int timeout = 3000)
|
public static async Task<IPAddress?> LookupAsync(string hostname, AddressFamily inet = AddressFamily.Unspecified, int timeout = 3000)
|
||||||
{
|
{
|
||||||
|
using var _ = await Lock.EnterAsync();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var cacheResult = inet switch
|
var cacheResult = inet switch
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Netch.Utils;
|
namespace Netch.Utils;
|
||||||
|
|
||||||
@@ -78,4 +79,30 @@ public static class StringExtension
|
|||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(value) ? value.Split(',') : default;
|
return !string.IsNullOrWhiteSpace(value) ? value.Split(',') : default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GenerateUUIDv5(this string str)
|
||||||
|
{
|
||||||
|
// https://github.com/XTLS/Xray-core/discussions/715
|
||||||
|
// https://xray-uuid.ducksoft.site/
|
||||||
|
|
||||||
|
SHA1 sha1 = new SHA1CryptoServiceProvider();
|
||||||
|
|
||||||
|
// example string: "example"
|
||||||
|
List<byte> byteSource = new List<byte>();
|
||||||
|
byteSource.AddRange(new byte[16]);
|
||||||
|
byteSource.AddRange(Encoding.UTF8.GetBytes(str));
|
||||||
|
|
||||||
|
byte[] Sha1Bytes = sha1.ComputeHash(byteSource.ToArray()).Skip(0).Take(16).ToArray();
|
||||||
|
sha1.Dispose();
|
||||||
|
|
||||||
|
//UUIDv5: [254 181 68 49 48 27 82 187 166 221 225 233 62 129 187 158]
|
||||||
|
|
||||||
|
Sha1Bytes[6] = (byte)((Sha1Bytes[6] & 0x0f) | (5 << 4));
|
||||||
|
Sha1Bytes[8] = (byte)(Sha1Bytes[8] & (0xff >> 2) | (0x02 << 6));
|
||||||
|
|
||||||
|
return BitConverter.ToString(Sha1Bytes).Replace("-", "")
|
||||||
|
.Insert(8, "-").Insert(13, "-").Insert(18, "-").Insert(23, "-")
|
||||||
|
.ToLower();
|
||||||
|
//UUIDv5: feb54431-301b-52bb-a6dd-e1e93e81bb9e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -94,6 +94,9 @@ public static class Utils
|
|||||||
|
|
||||||
public static async Task<string> Sha256CheckSumAsync(string filePath)
|
public static async Task<string> Sha256CheckSumAsync(string filePath)
|
||||||
{
|
{
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
return "";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true);
|
await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Set-Location (Split-Path $MyInvocation.MyCommand.Path -Parent)
|
Set-Location (Split-Path $MyInvocation.MyCommand.Path -Parent)
|
||||||
|
|
||||||
git clone https://github.com/SagerNet/v2ray-core.git -b 'v5.0.14' src
|
git clone https://github.com/SagerNet/v2ray-core.git -b 'v5.0.16' src
|
||||||
if ( -Not $? ) {
|
if ( -Not $? ) {
|
||||||
exit $lastExitCode
|
exit $lastExitCode
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ $Env:GOROOT_FINAL='/usr'
|
|||||||
|
|
||||||
$Env:GOOS='windows'
|
$Env:GOOS='windows'
|
||||||
$Env:GOARCH='amd64'
|
$Env:GOARCH='amd64'
|
||||||
go mod tidy # necessary
|
go get -u ./...
|
||||||
|
go mod tidy
|
||||||
go build -a -trimpath -asmflags '-s -w' -ldflags '-s -w -buildid=' -o '..\..\release\v2ray-sn.exe' '.\main'
|
go build -a -trimpath -asmflags '-s -w' -ldflags '-s -w -buildid=' -o '..\..\release\v2ray-sn.exe' '.\main'
|
||||||
exit $lastExitCode
|
exit $lastExitCode
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# `In preparation for 2.0, this repository will be cleared of all 1.0 related releases and code`
|
||||||
<p align="center"><img src="https://github.com/NetchX/Netch/blob/main/Netch/Resources/Netch.png?raw=true" width="128" /></p>
|
<p align="center"><img src="https://github.com/NetchX/Netch/blob/main/Netch/Resources/Netch.png?raw=true" width="128" /></p>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ bool SocksHelper::Handshake(SOCKET client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Password */
|
/* Password */
|
||||||
buffer[1 + plength] = 0x00;
|
buffer[1 + 1 + ulength] = 0x00;
|
||||||
if (plength != 0)
|
if (plength != 0)
|
||||||
{
|
{
|
||||||
buffer[1 + ulength] = plength;
|
buffer[1 + 1 + ulength] = plength;
|
||||||
memcpy(buffer + 1 + 1 + ulength + 1, tgtPassword.c_str(), plength);
|
memcpy(buffer + 1 + 1 + ulength + 1, tgtPassword.c_str(), plength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
197
Storage/i18n/fa-IR
Normal file
197
Storage/i18n/fa-IR
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
{
|
||||||
|
": ": ":",
|
||||||
|
"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.": "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.",
|
||||||
|
"Missing File or runtime components": "فایل یا اجزای زمان اجرا از دست رفته است",
|
||||||
|
"Please extract all files then run the program!": "لطفا تمام فایل ها را استخراج کنید سپس برنامه را اجرا کنید!",
|
||||||
|
|
||||||
|
"Start": "شروع کنید",
|
||||||
|
"Stop": "متوقف کردن",
|
||||||
|
"Waiting for command": "منتظر فرمان",
|
||||||
|
"Starting": "درحال اجرا شدن",
|
||||||
|
"Start failed": "شروع ناموفق بود",
|
||||||
|
"Started": "اجرا شد",
|
||||||
|
"Stopping": "در حال متوقف شدن",
|
||||||
|
"Stopped": "متوقف شد",
|
||||||
|
"Starting {0}": "{0}درحال شروع ",
|
||||||
|
"Starting NatTester": "NAT درحال اجرا تست کننده",
|
||||||
|
"SetupBypass": "راه اندازی Bypass",
|
||||||
|
"Test failed": "تست به خطا خورد",
|
||||||
|
"Starting update subscription": "در حال اجرای بروزرسانی اشتراک پذیری",
|
||||||
|
"Starting update ACL": "شروع بروزرسانی ACL",
|
||||||
|
"Subscription updated": "اشتراک به روز شد",
|
||||||
|
"Register driver": "نصب درایورها",
|
||||||
|
|
||||||
|
"Server": "سرور",
|
||||||
|
"Import Servers From Clipboard": "تنظیمات سرور را از کلیپ بورد وارد کنید",
|
||||||
|
"Add [{0}] Server": "سرور [{0}] را اضافه کنید",
|
||||||
|
"Netch is now minimized to the notification bar, double click this icon to restore.": "Netch در نوار اعلان به حداقل رسیده است. برای بازیابی روی این نماد دوبار کلیک کنید.",
|
||||||
|
"New version available": "نسخه جدید وجود دارد",
|
||||||
|
"Already latest version": "در حال حاضر آخرین نسخه است",
|
||||||
|
"New version found failed": "نسخه جدیدی پیدا نشد",
|
||||||
|
"Mode": "حالت",
|
||||||
|
"Help": "کمک",
|
||||||
|
"Check for updates": "به روز رسانی را بررسی کنید",
|
||||||
|
"Download and install now?": "آیا مطمئن هستید که می خواهید اکنون دانلود و نصب کنید؟",
|
||||||
|
"Start downloading new version": "در حال دانلود بروزرسانی ها",
|
||||||
|
"Download update failed": "به روز رسانی نا موفق بود",
|
||||||
|
"Create Process Mode": "پروفایل جدید",
|
||||||
|
"Edit Process Mode": "ویرایش نمایه",
|
||||||
|
"Create Route Table Rule": "قانون جدید جدول لوت",
|
||||||
|
"Edit Route Table Rule": "قوانین جدول لوت را ویرایش کنید",
|
||||||
|
|
||||||
|
"Address": "آدرس سرور",
|
||||||
|
"Username": "نام کاربری",
|
||||||
|
"Password": "کلمه عبور",
|
||||||
|
"User ID": "User ID",
|
||||||
|
"Alter ID": "Alter ID",
|
||||||
|
"Transfer Protocol": "پروتکل انتقال",
|
||||||
|
"Fake Type": "نوع انتقال",
|
||||||
|
"Host": "میزبان",
|
||||||
|
"Path": "مسیر",
|
||||||
|
"QUIC Security": "روش رمزگذاری QUIC",
|
||||||
|
"QUIC Secret": "کلید رمزگذاری QUIC",
|
||||||
|
"TLS Secure": "امنیت TLS",
|
||||||
|
"Use Mux": "استفاده از mux",
|
||||||
|
"Encrypt Method": "روش رمزگذاری",
|
||||||
|
"Protocol": "پروتکل",
|
||||||
|
"Protocol Param": "پارامترهای پروتکل",
|
||||||
|
"OBFS": "OBFS",
|
||||||
|
"OBFS Param": "OBFS パラメータ",
|
||||||
|
"Saved": "ذخیره تکمیل شد",
|
||||||
|
"Plugin": "پلاگین",
|
||||||
|
"Plugin Options": "پارامترهای افزونه",
|
||||||
|
|
||||||
|
"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}": "سرورهای {1} به روز شده از {0}",
|
||||||
|
"Update servers error from {0}": "بهروزرسانی سرور از {0} انجام نشد",
|
||||||
|
"Confirm deletion?": "آیا مطمئنید که میخواهید حذف کنید؟",
|
||||||
|
"DeleteServer": "سرور اشتراک را حذف کنید",
|
||||||
|
"CopyLink": "لینک را کپی کنید",
|
||||||
|
"Status": "وضعیت",
|
||||||
|
"Link": "ارتباط دادن",
|
||||||
|
"Unselect": "لغو انتخاب کنید",
|
||||||
|
|
||||||
|
"Options": "گزینه",
|
||||||
|
"NF Service": "سرویس NF",
|
||||||
|
"TUN/TAP driver": "TUN/TAP درایور",
|
||||||
|
"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": "قانون نچ فایروال را حذف کنید",
|
||||||
|
|
||||||
|
"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": "اطلاعات نسخه",
|
||||||
|
"FAQ": "سوالات متداول",
|
||||||
|
"Telegram Channel": "کانال تلگرام",
|
||||||
|
"Sponsor": "حامی",
|
||||||
|
|
||||||
|
"Configuration": "تنظیم اطلاعات",
|
||||||
|
|
||||||
|
"Please press Stop button first": "لطفا ابتدا روی دکمه توقف کلیک کنید",
|
||||||
|
"Please select a server first": "لطفا ابتدا یک سرور انتخاب کنید",
|
||||||
|
"Please select a mode first": "لطفا ابتدا یک حالت را انتخاب کنید",
|
||||||
|
"Please enter a profile name first": "لطفا ابتدا نام پروفایل خود را وارد کنید",
|
||||||
|
"No saved profile here. Save a profile first by Ctrl+Click on the button": "هیچ پروفایلی در اینجا ذخیره نشده است. Ctrl + کلیک چپ را فشار دهید تا نمایه ذخیره شود",
|
||||||
|
|
||||||
|
"Used": "استفاده شده",
|
||||||
|
"Test done": "تست تکمیل شد",
|
||||||
|
|
||||||
|
"Remark": "Remark",
|
||||||
|
"Filename": "نام فایل",
|
||||||
|
"Use Custom Filename": "ذخیره با نام فایل دلخواه ",
|
||||||
|
"Add": "جدید",
|
||||||
|
"Scan": "اسکن کنید",
|
||||||
|
"Save": "نگاه داشتن",
|
||||||
|
"Modify": "تغییر دادن",
|
||||||
|
"Select a folder": "پوشه را انتخاب کنید",
|
||||||
|
"Please enter an process name (xxx.exe)": "نام فرآیند را وارد کنید (xxx.exe)",
|
||||||
|
"Rule does not conform to C++ regular expression syntax": "قانون با نحو عبارت منظم C++ مطابقت ندارد",
|
||||||
|
"Scan completed": "اسکن کامل شد",
|
||||||
|
"Mode added successfully": "حالت جدید تکمیل شد",
|
||||||
|
"Mode updated successfully": "ویرایش حالت تکمیل شد",
|
||||||
|
"Unable to add empty rule": "قانون خالی اضافه نمی شود",
|
||||||
|
"Please enter a mode remark": "لطفا نکات را وارد کنید",
|
||||||
|
"File already exists.\n Please Change the filename": "فایل ای با همین نام از قبل وجود دارد. لطفاً نام فایل دیگری را برگزینید",
|
||||||
|
"Please enter a mode filename": "نام حالت را وارد کنید",
|
||||||
|
|
||||||
|
"Proxy Rule IPs": "قوانین پروکسی برای آی پی ها",
|
||||||
|
"Bypass Rule IPs": "آدرس IP را نادیده بگیرید",
|
||||||
|
|
||||||
|
"Delete": "حذف",
|
||||||
|
"Delete or not ? Will clean up the corresponding group of items in the server list": "آیا مطمئن هستید که می خواهید آن را حذف کنید؟ در صورت حذف، سرور مربوطه از لیست حذف خواهد شد",
|
||||||
|
"Remark can not be empty": "یادداشت نمی تواند خالی باشد",
|
||||||
|
"Link can not be empty": "لینک نمی تواند خالی باشد",
|
||||||
|
"Link must start with http:// or https://": "پیوندها باید با http:// یا https:// شروع شوند",
|
||||||
|
|
||||||
|
"Settings": "تنظیمات",
|
||||||
|
"Start when opened": "با شروع برنامه به طور خودکار وصل شوید",
|
||||||
|
"Minimize when started": "به صورت خودکار هنگام شروع برنامه کمینه کنید",
|
||||||
|
"Run at startup": "ثبت نام برای راه اندازی",
|
||||||
|
"Local Port": "شماره پورت محلی",
|
||||||
|
"Allow other Devices to connect": "اتصال از دستگاه های دیگر را مجاز کنید",
|
||||||
|
"Netmask": "Netmask",
|
||||||
|
"Gateway": "Gateway",
|
||||||
|
"Use Custom DNS": "از DNS سفارشی استفاده کنید",
|
||||||
|
"Proxy DNS in Proxy Rule IPs Mode": "Proxy DNS in Proxy Rule IPs Mode",
|
||||||
|
"Use Fake DNS": "از DNS جعلی استفاده کنید",
|
||||||
|
"Exit when closed": "پس از قطع اتصال، برنامه به طور خودکار خاتمه یابد",
|
||||||
|
"Stop when exited": "هنگامی که برنامه خارج می شود، اتصال را به طور خودکار قطع کنید",
|
||||||
|
"Global Bypass IPs": "IP Bypass جهانی",
|
||||||
|
"Check update when opened": "هنگامی که برنامه شروع به کار می کند، به طور خودکار ارتقاء را بررسی کنید",
|
||||||
|
"Check Beta update": "به روز رسانی های بتا را بررسی کنید",
|
||||||
|
"Update Servers when opened": "به روز رسانی سرور در هنگام راه اندازی",
|
||||||
|
"SS DLL": "SS DLL",
|
||||||
|
"Modify System DNS": "تغییر DNS سیستم",
|
||||||
|
"Proxy Protocol": "پروتکل پروکسی",
|
||||||
|
"DNS Redirector": "DNS فوروارد",
|
||||||
|
"ICMP Redirector": "ICMP Forward",
|
||||||
|
"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 سمت سرور نسخه 1.3.0+)",
|
||||||
|
|
||||||
|
"Profile": "پروفایل",
|
||||||
|
"Profiles": "لیست پروفایل",
|
||||||
|
"None": "هیچ یک",
|
||||||
|
|
||||||
|
"Show": "نمایش دادن",
|
||||||
|
"Exit": "خروج",
|
||||||
|
|
||||||
|
"The {0} port is in use.": "پورت {0} در حال حاضر در حال استفاده است",
|
||||||
|
"The {0} port is reserved by system.": "{0} برای سیستم رزرو شده است",
|
||||||
|
|
||||||
|
"[Web Proxy] Bypass LAN": "[پراکسی وب] آدرس LAN را نادیده بگیرید",
|
||||||
|
"[Non Web Proxy] Bypass LAN": "[پراکسی غیر وب] آدرس LAN را نادیده بگیرید",
|
||||||
|
"[TUN/TAP] Bypass LAN": "[TUN/TAP] آدرس LAN را نادیده بگیرید",
|
||||||
|
"[Web Proxy] Bypass LAN and China": "[پراکسی وب] آدرس های LAN و آدرس های سرزمین اصلی چین را نادیده بگیرید",
|
||||||
|
"[Non Web Proxy] Bypass LAN and China": "[پراکسی غیر وب] آدرس های LAN و آدرس های سرزمین اصلی چین را نادیده بگیرید",
|
||||||
|
"[TUN/TAP] Bypass LAN and China": "[TUN/TAP] آدرس های LAN و آدرس های سرزمین اصلی چین را نادیده بگیرید"
|
||||||
|
}
|
||||||
@@ -2,4 +2,4 @@
|
|||||||
install.exe
|
install.exe
|
||||||
VRChat.exe
|
VRChat.exe
|
||||||
UnityCrashHandler64.exe
|
UnityCrashHandler64.exe
|
||||||
youtube-dl.exe
|
yt-dlp.exe
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
@@ -11,5 +15,32 @@ namespace Tests
|
|||||||
{
|
{
|
||||||
Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
|
Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
|
||||||
}
|
}
|
||||||
|
[TestMethod]
|
||||||
|
public void VLESS_UUID5()
|
||||||
|
{
|
||||||
|
//https://github.com/XTLS/Xray-core/discussions/715
|
||||||
|
|
||||||
|
byte[] bytes = new byte[16];
|
||||||
|
var str = "example";
|
||||||
|
|
||||||
|
SHA1 sha1 = new SHA1CryptoServiceProvider();
|
||||||
|
byte[] StrBytes = Encoding.UTF8.GetBytes(str);
|
||||||
|
|
||||||
|
List<byte> byteSource = new List<byte>();
|
||||||
|
byteSource.AddRange(bytes);
|
||||||
|
byteSource.AddRange(StrBytes);
|
||||||
|
|
||||||
|
byte[] Sha1Bytes = sha1.ComputeHash(byteSource.ToArray()).Skip(0).Take(16).ToArray();
|
||||||
|
sha1.Dispose();
|
||||||
|
|
||||||
|
//UUIDv5: [254 181 68 49 48 27 82 187 166 221 225 233 62 129 187 158]
|
||||||
|
|
||||||
|
Sha1Bytes[6] = (byte)((Sha1Bytes[6] & 0x0f) | (5 << 4));
|
||||||
|
Sha1Bytes[8] = (byte)(Sha1Bytes[8] & (0xff >> 2) | (0x02 << 6));
|
||||||
|
|
||||||
|
var result = BitConverter.ToString(Sha1Bytes).Replace("-", "").Insert(8, "-").Insert(13, "-").Insert(18, "-").Insert(23, "-").ToLower();
|
||||||
|
Console.WriteLine(result);
|
||||||
|
//UUIDv5: feb54431-301b-52bb-a6dd-e1e93e81bb9e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
<PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
|
||||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ if ( -Not ( Test-Path ".\Netch\bin\$Configuration" ) ) {
|
|||||||
-c $Configuration `
|
-c $Configuration `
|
||||||
-r 'win-x64' `
|
-r 'win-x64' `
|
||||||
-p:Platform='x64' `
|
-p:Platform='x64' `
|
||||||
-p:SelfContained=$False `
|
-p:SelfContained=$SelfContained `
|
||||||
-p:PublishTrimmed=$PublishReadyToRun `
|
-p:PublishTrimmed=$PublishReadyToRun `
|
||||||
-p:PublishSingleFile=$PublishSingleFile `
|
-p:PublishSingleFile=$PublishSingleFile `
|
||||||
-p:PublishReadyToRun=$PublishReadyToRun `
|
-p:PublishReadyToRun=$PublishReadyToRun `
|
||||||
@@ -103,4 +103,4 @@ if ( $Configuration.Equals('Release') ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Pop-Location
|
Pop-Location
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user