diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index c2001036..e1daa015 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -290,6 +290,26 @@ public class Global "tuic" ]; + public static readonly List NaiveProxyCoreTypes = + [ + "naiveproxy" + ]; + + public static readonly List JuicityProxyCoreTypes = + [ + "juicity" + ]; + + public static readonly List BrookCoreTypes = + [ + "brook" + ]; + + public static readonly List ShadowquicCoreTypes = + [ + "shadowquic" + ]; + public static readonly List SupportSplitConfigTypes = [ EConfigType.VMess, @@ -488,13 +508,20 @@ public class Global "" ]; - public static readonly List TuicCongestionControls = + public static readonly List CongestionControls = [ "cubic", "new_reno", "bbr" ]; + public static readonly List NaiveProxyProtocols = + [ + "https", + "http", + "quic" + ]; + public static readonly List allowSelectType = [ "selector", diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 848d4f35..ade49c61 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -270,6 +270,10 @@ public class ConfigHandler EConfigType.TUIC => await AddTuicServer(config, item), EConfigType.WireGuard => await AddWireguardServer(config, item), EConfigType.Anytls => await AddAnytlsServer(config, item), + EConfigType.NaiveProxy => await AddNaiveServer(config, item), + EConfigType.Juicity => await AddJuicityServer(config, item), + EConfigType.Brook => await AddBrookServer(config, item), + EConfigType.Shadowquic => await AddShadowquicServer(config, item), _ => -1, }; return ret; @@ -738,9 +742,9 @@ public class ConfigHandler profileItem.Security = profileItem.Security.TrimEx(); profileItem.Network = string.Empty; - if (!Global.TuicCongestionControls.Contains(profileItem.HeaderType)) + if (!Global.CongestionControls.Contains(profileItem.HeaderType)) { - profileItem.HeaderType = Global.TuicCongestionControls.FirstOrDefault()!; + profileItem.HeaderType = Global.CongestionControls.FirstOrDefault()!; } if (profileItem.StreamSecurity.IsNullOrEmpty()) @@ -823,6 +827,140 @@ public class ConfigHandler return 0; } + /// + /// Add or edit a Naive server + /// Validates and processes Naive-specific settings + /// + /// Current configuration + /// Naive profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed + public static async Task AddNaiveServer(Config config, ProfileItem profileItem, bool toFile = true) + { + profileItem.ConfigType = EConfigType.NaiveProxy; + profileItem.CoreType = ECoreType.naiveproxy; + + profileItem.Address = profileItem.Address.TrimEx(); + profileItem.Id = profileItem.Id.TrimEx(); + profileItem.Network = string.Empty; + if (profileItem.StreamSecurity.IsNullOrEmpty()) + { + profileItem.StreamSecurity = Global.StreamSecurity; + } + if (profileItem.Id.IsNullOrEmpty()) + { + return -1; + } + await AddServerCommon(config, profileItem, toFile); + return 0; + } + + /// + /// Add or edit a Juicity server + /// Validates and processes Juicity-specific settings + /// + /// Current configuration + /// Juicity profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed + public static async Task AddJuicityServer(Config config, ProfileItem profileItem, bool toFile = true) + { + profileItem.ConfigType = EConfigType.Juicity; + profileItem.CoreType = ECoreType.juicity; + + profileItem.Address = profileItem.Address.TrimEx(); + profileItem.Id = profileItem.Id.TrimEx(); + profileItem.Security = profileItem.Security.TrimEx(); + profileItem.Network = string.Empty; + + if (!Global.CongestionControls.Contains(profileItem.HeaderType)) + { + profileItem.HeaderType = Global.CongestionControls.FirstOrDefault()!; + } + + if (profileItem.StreamSecurity.IsNullOrEmpty()) + { + profileItem.StreamSecurity = Global.StreamSecurity; + } + if (profileItem.Alpn.IsNullOrEmpty()) + { + profileItem.Alpn = "h3"; + } + if (profileItem.Id.IsNullOrEmpty()) + { + return -1; + } + + await AddServerCommon(config, profileItem, toFile); + + return 0; + } + + /// + /// Add or edit a Brook server + /// Validates and processes Brook-specific settings + /// + /// Current configuration + /// Brook profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed + public static async Task AddBrookServer(Config config, ProfileItem profileItem, bool toFile = true) + { + profileItem.ConfigType = EConfigType.Brook; + profileItem.CoreType = ECoreType.brook; + + profileItem.Address = profileItem.Address.TrimEx(); + profileItem.Id = profileItem.Id.TrimEx(); + profileItem.Network = string.Empty; + if (profileItem.Id.IsNullOrEmpty()) + { + return -1; + } + await AddServerCommon(config, profileItem, toFile); + return 0; + } + + /// + /// Add or edit a Shadowquic server + /// Validates and processes Shadowquic-specific settings + /// + /// Current configuration + /// Shadowquic profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed + public static async Task AddShadowquicServer(Config config, ProfileItem profileItem, bool toFile = true) + { + profileItem.ConfigType = EConfigType.Shadowquic; + profileItem.CoreType = ECoreType.shadowquic; + + profileItem.Address = profileItem.Address.TrimEx(); + profileItem.Id = profileItem.Id.TrimEx(); + profileItem.Security = profileItem.Security.TrimEx(); + profileItem.Network = string.Empty; + + if (!Global.CongestionControls.Contains(profileItem.HeaderType)) + { + profileItem.HeaderType = Global.CongestionControls.FirstOrDefault()!; + } + + if (profileItem.StreamSecurity.IsNullOrEmpty()) + { + profileItem.StreamSecurity = Global.StreamSecurity; + } + if (profileItem.Alpn.IsNullOrEmpty()) + { + profileItem.Alpn = "h3"; + } + if (profileItem.Id.IsNullOrEmpty()) + { + return -1; + } + + await AddServerCommon(config, profileItem, toFile); + + return 0; + } + /// /// Sort the server list by the specified column /// Updates the sort order in the profile extension data @@ -1296,6 +1434,10 @@ public class ConfigHandler EConfigType.TUIC => await AddTuicServer(config, profileItem, false), EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false), EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false), + EConfigType.NaiveProxy => await AddNaiveServer(config, profileItem, false), + EConfigType.Juicity => await AddJuicityServer(config, profileItem, false), + EConfigType.Brook => await AddBrookServer(config, profileItem, false), + EConfigType.Shadowquic => await AddShadowquicServer(config, profileItem, false), _ => -1, }; diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 62ed61c2..b998e8b4 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -663,6 +663,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Add [Brook] Configuration 的本地化字符串。 + /// + public static string menuAddBrookServer { + get { + return ResourceManager.GetString("menuAddBrookServer", resourceCulture); + } + } + /// /// 查找类似 Add a custom configuration Configuration 的本地化字符串。 /// @@ -690,6 +699,24 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Add [Juicity] Configuration 的本地化字符串。 + /// + public static string menuAddJuicityServer { + get { + return ResourceManager.GetString("menuAddJuicityServer", resourceCulture); + } + } + + /// + /// 查找类似 Add [Naive] Configuration 的本地化字符串。 + /// + public static string menuAddNaiveServer { + get { + return ResourceManager.GetString("menuAddNaiveServer", resourceCulture); + } + } + /// /// 查找类似 Import Share Links from clipboard (Ctrl+V) 的本地化字符串。 /// @@ -717,6 +744,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Add [Shadowquic] Configuration 的本地化字符串。 + /// + public static string menuAddShadowquicServer { + get { + return ResourceManager.GetString("menuAddShadowquicServer", resourceCulture); + } + } + /// /// 查找类似 Add [Shadowsocks] Configuration 的本地化字符串。 /// @@ -2472,6 +2508,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Proxy Protocol 的本地化字符串。 + /// + public static string TbHeaderType100 { + get { + return ResourceManager.GetString("TbHeaderType100", resourceCulture); + } + } + /// /// 查找类似 Congestion control 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index ee776c78..aee7a852 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1413,4 +1413,19 @@ Routing Core defaults to sing-box when Tun is enabled. + + افزودن سرور [Brook] + + + افزودن سرور [Juicity] + + + افزودن سرور [Naive] + + + افزودن سرور [Shadowquic] + + + Proxy Protocol + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 6fdfc7dd..167f3b88 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1413,4 +1413,19 @@ Routing Core defaults to sing-box when Tun is enabled. + + [Brook] szerver hozzáadása + + + [Juicity] szerver hozzáadása + + + [Naive] szerver hozzáadása + + + [Shadowquic] szerver hozzáadása + + + Proxy Protocol + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index bffcea43..eaf705b6 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1413,4 +1413,19 @@ Routing Core defaults to sing-box when Tun is enabled. + + Add [Brook] Configuration + + + Add [Juicity] Configuration + + + Add [Naive] Configuration + + + Add [Shadowquic] Configuration + + + Proxy Protocol + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 42843dc4..bb855dfe 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1413,4 +1413,19 @@ Routing Core defaults to sing-box when Tun is enabled. + + Добавить сервер [Brook] + + + Добавить сервер [Juicity] + + + Добавить сервер [Naive] + + + Добавить сервер [Shadowquic] + + + Proxy Protocol + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index a9ed87cc..fa4f1e8b 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1410,4 +1410,19 @@ 启用 Tun 时,路由 Core 为 sing-box + + 添加 [Brook] 配置文件 + + + 添加 [Juicity] 配置文件 + + + 添加 [Naive] 配置文件 + + + 添加 [Shadowquic] 配置文件 + + + 代理协议 + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 3e99f83a..ebea5465 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1410,4 +1410,19 @@ Routing Core defaults to sing-box when Tun is enabled. + + 新增 [Brook] 設定檔 + + + 新增 [Juicity] 設定檔 + + + 新增 [Naive] 設定檔 + + + 新增 [Shadowquic] 設定檔 + + + Proxy Protocol + \ No newline at end of file diff --git a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index 36e20a87..0dc991cb 100644 --- a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -25,6 +25,10 @@ public class MainWindowViewModel : MyReactiveObject public ReactiveCommand AddServerViaClipboardCmd { get; } public ReactiveCommand AddServerViaScanCmd { get; } public ReactiveCommand AddServerViaImageCmd { get; } + public ReactiveCommand AddBrookServerCmd { get; } + public ReactiveCommand AddJuicityServerCmd { get; } + public ReactiveCommand AddNaiveServerCmd { get; } + public ReactiveCommand AddShadowquicServerCmd { get; } //Subscription public ReactiveCommand SubSettingCmd { get; } @@ -116,6 +120,22 @@ public class MainWindowViewModel : MyReactiveObject { await AddServerAsync(true, EConfigType.Anytls); }); + AddBrookServerCmd = ReactiveCommand.CreateFromTask(async () => + { + await AddServerAsync(true, EConfigType.Brook); + }); + AddJuicityServerCmd = ReactiveCommand.CreateFromTask(async () => + { + await AddServerAsync(true, EConfigType.Juicity); + }); + AddNaiveServerCmd = ReactiveCommand.CreateFromTask(async () => + { + await AddServerAsync(true, EConfigType.NaiveProxy); + }); + AddShadowquicServerCmd = ReactiveCommand.CreateFromTask(async () => + { + await AddServerAsync(true, EConfigType.Shadowquic); + }); AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () => { await AddServerAsync(true, EConfigType.Custom); diff --git a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs index 39d6e68a..fae84814 100644 --- a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs @@ -91,7 +91,7 @@ public partial class AddServerWindow : WindowBase cmbFingerprint.IsEnabled = false; cmbFingerprint.SelectedValue = string.Empty; - cmbHeaderType8.ItemsSource = Global.TuicCongestionControls; + cmbHeaderType8.ItemsSource = Global.CongestionControls; break; case EConfigType.WireGuard: diff --git a/v2rayN/v2rayN/Views/AddServerWindow.xaml b/v2rayN/v2rayN/Views/AddServerWindow.xaml index acea0c28..2f5c73c0 100644 --- a/v2rayN/v2rayN/Views/AddServerWindow.xaml +++ b/v2rayN/v2rayN/Views/AddServerWindow.xaml @@ -736,6 +736,199 @@ Margin="{StaticResource Margin4}" Style="{StaticResource DefTextBox}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vm.SelectedSource.Id, v => v.txtId10.Text).DisposeWith(disposables); break; + + case EConfigType.NaiveProxy: + this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId100.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType100.Text).DisposeWith(disposables); + break; + + case EConfigType.Juicity: + this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId101.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity101.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType101.Text).DisposeWith(disposables); + break; + + case EConfigType.Brook: + this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId102.Text).DisposeWith(disposables); + break; + + case EConfigType.Shadowquic: + this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId103.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity103.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType103.Text).DisposeWith(disposables); + break; } this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.Text).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml b/v2rayN/v2rayN/Views/MainWindow.xaml index 0b8c30b3..59b6e6ed 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml +++ b/v2rayN/v2rayN/Views/MainWindow.xaml @@ -112,6 +112,23 @@ x:Name="menuAddAnytlsServer" Height="{StaticResource MenuItemHeight}" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" /> + + + + + diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs index 08bdd90b..b4d41965 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -81,6 +81,10 @@ public partial class MainWindow this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables); + this.BindCommand(ViewModel, vm => vm.AddBrookServerCmd, v => v.menuAddBrookServer).DisposeWith(disposables); + this.BindCommand(ViewModel, vm => vm.AddJuicityServerCmd, v => v.menuAddJuicityServer).DisposeWith(disposables); + this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables); + this.BindCommand(ViewModel, vm => vm.AddShadowquicServerCmd, v => v.menuAddShadowquicServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);