From ea42246d1b2cc8740b31676d9a9d6343d0536592 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Fri, 25 Apr 2025 14:38:33 +0800
Subject: [PATCH 01/39] Improved AmazTool
---
v2rayN/AmazTool/Program.cs | 84 +++++++++++++++++++++++++++++++++-----
1 file changed, 73 insertions(+), 11 deletions(-)
diff --git a/v2rayN/AmazTool/Program.cs b/v2rayN/AmazTool/Program.cs
index d71c25c2..4df39682 100644
--- a/v2rayN/AmazTool/Program.cs
+++ b/v2rayN/AmazTool/Program.cs
@@ -5,21 +5,83 @@ internal static class Program
[STAThread]
private static void Main(string[] args)
{
- if (args.Length == 0)
+ try
{
- Console.WriteLine(Resx.Resource.Guidelines);
- Thread.Sleep(5000);
- return;
- }
+ // If no arguments are provided, display usage guidelines and exit
+ if (args.Length == 0)
+ {
+ ShowHelp();
+ return;
+ }
- var argData = Uri.UnescapeDataString(string.Join(" ", args));
- if (argData.Equals("rebootas"))
+ // Log all arguments for debugging purposes
+ foreach (var arg in args)
+ {
+ Console.WriteLine(arg);
+ }
+
+ // Parse command based on first argument
+ switch (args[0].ToLowerInvariant())
+ {
+ case "rebootas":
+ // Handle application restart
+ HandleRebootAsync();
+ break;
+
+ case "help":
+ case "--help":
+ case "-h":
+ case "/?":
+ // Display help information
+ ShowHelp();
+ break;
+
+ default:
+ // Default behavior: handle as upgrade data
+ // Maintain backward compatibility with existing usage pattern
+ var argData = Uri.UnescapeDataString(string.Join(" ", args));
+ HandleUpgrade(argData);
+ break;
+ }
+ }
+ catch (Exception ex)
{
- Thread.Sleep(1000);
- Utils.StartV2RayN();
- return;
+ // Global exception handling
+ Console.WriteLine($"An error occurred: {ex.Message}");
+ Console.WriteLine("Press any key to exit...");
+ Console.ReadKey();
}
+ }
- UpgradeApp.Upgrade(argData);
+ ///
+ /// Display help information and usage guidelines
+ ///
+ private static void ShowHelp()
+ {
+ Console.WriteLine(Resx.Resource.Guidelines);
+ Console.WriteLine("Available commands:");
+ Console.WriteLine(" rebootas - Restart the application");
+ Console.WriteLine(" help - Display this help information");
+ Thread.Sleep(5000);
+ }
+
+ ///
+ /// Handle application restart
+ ///
+ private static void HandleRebootAsync()
+ {
+ Console.WriteLine("Restarting application...");
+ Thread.Sleep(1000);
+ Utils.StartV2RayN();
+ }
+
+ ///
+ /// Handle application upgrade with the provided data
+ ///
+ /// Data for the upgrade process
+ private static void HandleUpgrade(string upgradeData)
+ {
+ Console.WriteLine("Upgrading application...");
+ UpgradeApp.Upgrade(upgradeData);
}
}
From c6d347d49a62751f59acf9c8c54d332bc7f2204d Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Fri, 25 Apr 2025 15:19:49 +0800
Subject: [PATCH 02/39] Refactor the Linux version to not store sudo password
---
v2rayN/ServiceLib/Enums/EViewAction.cs | 1 +
v2rayN/ServiceLib/Handler/AppHandler.cs | 2 +
v2rayN/ServiceLib/Handler/CoreHandler.cs | 30 +++-----
v2rayN/ServiceLib/Models/ConfigItems.cs | 1 -
v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 2 +-
v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 4 +-
v2rayN/ServiceLib/Resx/ResUI.hu.resx | 2 +-
v2rayN/ServiceLib/Resx/ResUI.resx | 2 +-
v2rayN/ServiceLib/Resx/ResUI.ru.resx | 2 +-
v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 10 +--
v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 10 +--
.../ViewModels/OptionSettingViewModel.cs | 8 +--
.../ViewModels/StatusBarViewModel.cs | 14 ++--
.../Views/OptionSettingWindow.axaml | 22 ------
.../Views/OptionSettingWindow.axaml.cs | 5 --
.../Views/StatusBarView.axaml.cs | 20 ++++++
.../Views/SudoPasswordInputView.axaml | 70 +++++++++++++++++++
.../Views/SudoPasswordInputView.axaml.cs | 33 +++++++++
18 files changed, 161 insertions(+), 77 deletions(-)
create mode 100644 v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml
create mode 100644 v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml.cs
diff --git a/v2rayN/ServiceLib/Enums/EViewAction.cs b/v2rayN/ServiceLib/Enums/EViewAction.cs
index 75142925..a72e8765 100644
--- a/v2rayN/ServiceLib/Enums/EViewAction.cs
+++ b/v2rayN/ServiceLib/Enums/EViewAction.cs
@@ -20,6 +20,7 @@ public enum EViewAction
BrowseServer,
ImportRulesFromFile,
InitSettingFont,
+ PasswordInput,
SubEditWindow,
RoutingRuleSettingWindow,
RoutingRuleDetailsWindow,
diff --git a/v2rayN/ServiceLib/Handler/AppHandler.cs b/v2rayN/ServiceLib/Handler/AppHandler.cs
index 0b8054f1..3f9fdf74 100644
--- a/v2rayN/ServiceLib/Handler/AppHandler.cs
+++ b/v2rayN/ServiceLib/Handler/AppHandler.cs
@@ -40,6 +40,8 @@ public sealed class AppHandler
}
}
+ public string LinuxSudoPwd { get; set; }
+
#endregion Property
#region Init
diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs
index 41ea866d..499d8999 100644
--- a/v2rayN/ServiceLib/Handler/CoreHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs
@@ -229,9 +229,7 @@ public class CoreHandler
{
return _config.TunModeItem.EnableTun
&& eCoreType == ECoreType.sing_box
- && (Utils.IsNonWindows())
- //&& _config.TunModeItem.LinuxSudoPwd.IsNotEmpty()
- ;
+ && Utils.IsNonWindows();
}
#endregion Private
@@ -288,13 +286,11 @@ public class CoreHandler
}
proc.Start();
- if (isNeedSudo && _config.TunModeItem.LinuxSudoPwd.IsNotEmpty())
+ if (isNeedSudo && AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
{
- var pwd = DesUtils.Decrypt(_config.TunModeItem.LinuxSudoPwd);
+ await proc.StandardInput.WriteLineAsync();
await Task.Delay(10);
- await proc.StandardInput.WriteLineAsync(pwd);
- await Task.Delay(10);
- await proc.StandardInput.WriteLineAsync(pwd);
+ await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
}
if (isNeedSudo)
_linuxSudoPid = proc.Id;
@@ -333,7 +329,7 @@ public class CoreHandler
proc.StartInfo.FileName = shFilePath;
proc.StartInfo.Arguments = "";
proc.StartInfo.WorkingDirectory = "";
- if (_config.TunModeItem.LinuxSudoPwd.IsNotEmpty())
+ if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
{
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
proc.StartInfo.RedirectStandardInput = true;
@@ -342,7 +338,7 @@ public class CoreHandler
private async Task KillProcessAsLinuxSudo()
{
- var cmdLine = $"kill {_linuxSudoPid}";
+ var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
Process proc = new()
{
@@ -357,15 +353,13 @@ public class CoreHandler
};
proc.Start();
- if (_config.TunModeItem.LinuxSudoPwd.IsNotEmpty())
+ if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
{
try
{
- var pwd = DesUtils.Decrypt(_config.TunModeItem.LinuxSudoPwd);
+ await proc.StandardInput.WriteLineAsync();
await Task.Delay(10);
- await proc.StandardInput.WriteLineAsync(pwd);
- await Task.Delay(10);
- await proc.StandardInput.WriteLineAsync(pwd);
+ await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
}
catch (Exception)
{
@@ -375,7 +369,7 @@ public class CoreHandler
var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await proc.WaitForExitAsync(timeout.Token);
- await Task.Delay(3000);
+ await Task.Delay(1000);
}
private async Task CreateLinuxShellFile(string cmdLine, string fileName)
@@ -389,10 +383,6 @@ public class CoreHandler
{
sb.AppendLine($"{cmdLine}");
}
- else if (_config.TunModeItem.LinuxSudoPwd.IsNullOrEmpty())
- {
- sb.AppendLine($"pkexec {cmdLine}");
- }
else
{
sb.AppendLine($"sudo -S {cmdLine}");
diff --git a/v2rayN/ServiceLib/Models/ConfigItems.cs b/v2rayN/ServiceLib/Models/ConfigItems.cs
index b3fa1b98..47c96a3f 100644
--- a/v2rayN/ServiceLib/Models/ConfigItems.cs
+++ b/v2rayN/ServiceLib/Models/ConfigItems.cs
@@ -147,7 +147,6 @@ public class TunModeItem
public int Mtu { get; set; }
public bool EnableExInbound { get; set; }
public bool EnableIPv6Address { get; set; }
- public string? LinuxSudoPwd { get; set; }
}
[Serializable]
diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index 0b9cc936..ac507c45 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -3247,7 +3247,7 @@ namespace ServiceLib.Resx {
}
///
- /// 查找类似 The password is encrypted and stored only in local files 的本地化字符串。
+ /// 查找类似 The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart. 的本地化字符串。
///
public static string TbSettingsLinuxSudoPasswordTip {
get {
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index a937a262..adf4eb0e 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
@@ -1339,7 +1339,7 @@
رمز عبور sudo سیستم
- رمز عبور رمزگذاری شده و فقط در فایل های محلی ذخیره می شود.
+ The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.
لطفاً ابتدا رمز عبور sudo را در تنظیمات حالت Tun تنظیم کنید
@@ -1416,4 +1416,4 @@
صادر کردن سرور
-
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
index 05a12c10..130c3579 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
@@ -1339,7 +1339,7 @@
Rendszer sudo jelszó
- A jelszó titkosítva és csak a helyi fájlokban tárolva.
+ The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.
Kérlek, először állítsd be a sudo jelszót a Tun módban
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index 1fb3d23b..7ec5d653 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1339,7 +1339,7 @@
System sudo password
- The password is encrypted and stored only in local files
+ The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.
Please set the sudo password in Tun mode settings first
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index 824ea29a..9103641b 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1339,7 +1339,7 @@
System sudo password
- Пароль зашифрован и хранится только в локальных файлах..
+ The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.
Please set the sudo password in Tun mode settings first
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index a5f07957..150a9353 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1071,13 +1071,13 @@
拥塞控制算法
-
+
前置代理配置文件别名
-
+
落地代理配置文件別名
-
+
请确保配置文件别名存在并唯一
@@ -1336,7 +1336,7 @@
系统的 sudo 密码
- 密码已加密且只存储在本地文件中,无密码则每次都要输入
+ 输入的密码无法校验,所以请确保输入正确。如果因为输入错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。
请先在 Tun 模式设置中设置 sudo 密码
@@ -1413,4 +1413,4 @@
导出配置文件
-
+
\ 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 b8a5011a..e827d0ea 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1071,13 +1071,13 @@
擁塞控制算法
-
+
前置代理設定檔別名
-
+
落地代理設定檔別名
-
+
請確保設定檔別名存在並且唯一
@@ -1336,7 +1336,7 @@
系統的 sudo 密碼
- 密碼已加密且只儲存在本機檔案中,無密碼則每次都要輸入
+ 輸入的密碼無法校驗,所以請確保輸入正確。如果因為輸入錯誤導致無法正常運作時,請重新啟動本應用。 密碼不會存儲,每次重啟後都需要再次輸入。
請先在 Tun 模式設定中設定 sudo 密碼
@@ -1413,4 +1413,4 @@
匯出設定檔
-
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
index b99339d6..fd26eb32 100644
--- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
@@ -88,7 +88,6 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public int TunMtu { get; set; }
[Reactive] public bool TunEnableExInbound { get; set; }
[Reactive] public bool TunEnableIPv6Address { get; set; }
- [Reactive] public string TunLinuxSudoPassword { get; set; }
#endregion Tun mode
@@ -205,7 +204,6 @@ public class OptionSettingViewModel : MyReactiveObject
TunMtu = _config.TunModeItem.Mtu;
TunEnableExInbound = _config.TunModeItem.EnableExInbound;
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
- TunLinuxSudoPassword = _config.TunModeItem.LinuxSudoPwd;
#endregion Tun mode
@@ -358,11 +356,7 @@ public class OptionSettingViewModel : MyReactiveObject
_config.TunModeItem.Mtu = TunMtu;
_config.TunModeItem.EnableExInbound = TunEnableExInbound;
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
- if (TunLinuxSudoPassword != _config.TunModeItem.LinuxSudoPwd)
- {
- _config.TunModeItem.LinuxSudoPwd = DesUtils.Encrypt(TunLinuxSudoPassword);
- }
-
+
//coreType
await SaveCoreType();
diff --git a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
index 00cc391a..ec6ec39e 100644
--- a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
@@ -436,11 +436,13 @@ public class StatusBarViewModel : MyReactiveObject
Locator.Current.GetService()?.RebootAsAdmin();
return;
}
- else if (Utils.IsOSX())
+ else
{
- _config.TunModeItem.EnableTun = false;
- NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
- return;
+ if (await _updateView?.Invoke(EViewAction.PasswordInput, null) == false)
+ {
+ _config.TunModeItem.EnableTun = false;
+ return;
+ }
}
}
await ConfigHandler.SaveConfig(_config);
@@ -456,11 +458,11 @@ public class StatusBarViewModel : MyReactiveObject
}
else if (Utils.IsLinux())
{
- return _config.TunModeItem.LinuxSudoPwd.IsNotEmpty();
+ return AppHandler.Instance.LinuxSudoPwd.IsNotEmpty();
}
else if (Utils.IsOSX())
{
- return _config.TunModeItem.LinuxSudoPwd.IsNotEmpty();
+ return AppHandler.Instance.LinuxSudoPwd.IsNotEmpty();
}
return false;
}
diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
index 8c9351d7..3ad9b178 100644
--- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
@@ -784,28 +784,6 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
-
-
-
diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs
index 58aceaf1..4faa0c27 100644
--- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs
@@ -153,7 +153,6 @@ public partial class OptionSettingWindow : ReactiveWindow vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunEnableExInbound, v => v.togEnableExInbound.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
- this.Bind(ViewModel, vm => vm.TunLinuxSudoPassword, v => v.txtLinuxSudoPassword.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
@@ -170,10 +169,6 @@ public partial class OptionSettingWindow : ReactiveWindow
return false;
await AvaUtils.SetClipboardData(this, (string)obj);
break;
+
+ case EViewAction.PasswordInput:
+ return await PasswordInputAsync();
+ break;
}
return await Task.FromResult(true);
}
@@ -96,6 +102,20 @@ public partial class StatusBarView : ReactiveUserControl
}
}
+ private async Task PasswordInputAsync()
+ {
+ var dialog = new SudoPasswordInputView();
+ var obj = await DialogHost.Show(dialog);
+ if (obj == null)
+ {
+ togEnableTun.IsChecked = false;
+ return false;
+ }
+
+ AppHandler.Instance.LinuxSudoPwd = obj.ToString() ?? string.Empty;
+ return true;
+ }
+
private void TxtRunningServerDisplay_Tapped(object? sender, Avalonia.Input.TappedEventArgs e)
{
ViewModel?.TestServerAvailability();
diff --git a/v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml b/v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml
new file mode 100644
index 00000000..507cbb49
--- /dev/null
+++ b/v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml.cs
new file mode 100644
index 00000000..8276faf4
--- /dev/null
+++ b/v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml.cs
@@ -0,0 +1,33 @@
+using Avalonia.Controls;
+using Avalonia.Threading;
+using DialogHostAvalonia;
+
+namespace v2rayN.Desktop.Views;
+
+public partial class SudoPasswordInputView : UserControl
+{
+ public SudoPasswordInputView()
+ {
+ InitializeComponent();
+
+ this.Loaded += (s, e) => txtPassword.Focus();
+
+ btnSave.Click += (_, _) =>
+ {
+ if (string.IsNullOrEmpty(txtPassword.Text))
+ {
+ txtPassword.Focus();
+ return;
+ }
+ Dispatcher.UIThread.Post(() =>
+ {
+ DialogHost.Close(null, txtPassword.Text);
+ });
+ };
+
+ btnCancel.Click += (_, _) =>
+ {
+ DialogHost.Close(null);
+ };
+ }
+}
From 0032a3d27af7d91010233bed494105120f0cff5b Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Fri, 25 Apr 2025 16:36:28 +0800
Subject: [PATCH 03/39] Fix kill process for linux
---
v2rayN/ServiceLib/Handler/CoreHandler.cs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs
index 499d8999..a2f24df8 100644
--- a/v2rayN/ServiceLib/Handler/CoreHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs
@@ -155,6 +155,12 @@ public class CoreHandler
{
try
{
+ if (_linuxSudoPid > 0)
+ {
+ await KillProcessAsLinuxSudo();
+ _linuxSudoPid = -1;
+ }
+
if (_process != null)
{
await ProcUtils.ProcessKill(_process, true);
@@ -166,12 +172,6 @@ public class CoreHandler
await ProcUtils.ProcessKill(_processPre, true);
_processPre = null;
}
-
- if (_linuxSudoPid > 0)
- {
- await KillProcessAsLinuxSudo();
- }
- _linuxSudoPid = -1;
}
catch (Exception ex)
{
@@ -390,7 +390,7 @@ public class CoreHandler
await File.WriteAllTextAsync(shFilePath, sb.ToString());
await Utils.SetLinuxChmod(shFilePath);
- Logging.SaveLog(shFilePath);
+ //Logging.SaveLog(shFilePath);
return shFilePath;
}
From adf3b955d6a4546425fabbc99e1fce2955bd4840 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sat, 26 Apr 2025 09:50:31 +0800
Subject: [PATCH 04/39] Refactor Linux to run Tun as sudo
---
v2rayN/ServiceLib/Handler/AppHandler.cs | 9 --
v2rayN/ServiceLib/Handler/CoreAdminHandler.cs | 144 ++++++++++++++++++
v2rayN/ServiceLib/Handler/CoreHandler.cs | 136 +++--------------
.../ViewModels/StatusBarViewModel.cs | 2 +-
.../v2rayN.Desktop/Views/MainWindow.axaml.cs | 2 +-
v2rayN/v2rayN/Views/MainWindow.xaml.cs | 2 +-
6 files changed, 171 insertions(+), 124 deletions(-)
create mode 100644 v2rayN/ServiceLib/Handler/CoreAdminHandler.cs
diff --git a/v2rayN/ServiceLib/Handler/AppHandler.cs b/v2rayN/ServiceLib/Handler/AppHandler.cs
index 3f9fdf74..906e2ba3 100644
--- a/v2rayN/ServiceLib/Handler/AppHandler.cs
+++ b/v2rayN/ServiceLib/Handler/AppHandler.cs
@@ -31,15 +31,6 @@ public sealed class AppHandler
}
}
- public bool IsAdministrator
- {
- get
- {
- _isAdministrator ??= Utils.IsAdministrator();
- return _isAdministrator.Value;
- }
- }
-
public string LinuxSudoPwd { get; set; }
#endregion Property
diff --git a/v2rayN/ServiceLib/Handler/CoreAdminHandler.cs b/v2rayN/ServiceLib/Handler/CoreAdminHandler.cs
new file mode 100644
index 00000000..85d90fc3
--- /dev/null
+++ b/v2rayN/ServiceLib/Handler/CoreAdminHandler.cs
@@ -0,0 +1,144 @@
+using System.Diagnostics;
+using System.Text;
+using CliWrap;
+
+namespace ServiceLib.Handler;
+
+public class CoreAdminHandler
+{
+ private static readonly Lazy _instance = new(() => new());
+ public static CoreAdminHandler Instance => _instance.Value;
+ private Config _config;
+ private Action? _updateFunc;
+ private const string _tag = "CoreAdminHandler";
+ private int _linuxSudoPid = -1;
+
+ public async Task Init(Config config, Action updateFunc)
+ {
+ if (_config != null)
+ {
+ return;
+ }
+ _config = config;
+ _updateFunc = updateFunc;
+ }
+
+ private void UpdateFunc(bool notify, string msg)
+ {
+ _updateFunc?.Invoke(notify, msg);
+ }
+
+ public async Task RunProcessAsLinuxSudo(string fileName, CoreInfo coreInfo, string configPath)
+ {
+ try
+ {
+ var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
+ var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
+
+ Process proc = new()
+ {
+ StartInfo = new()
+ {
+ FileName = shFilePath,
+ Arguments = "",
+ WorkingDirectory = Utils.GetBinConfigPath(),
+ UseShellExecute = false,
+ RedirectStandardInput = true,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true,
+ StandardInputEncoding = Encoding.UTF8,
+ StandardOutputEncoding = Encoding.UTF8,
+ StandardErrorEncoding = Encoding.UTF8,
+ }
+ };
+
+ proc.OutputDataReceived += (sender, e) =>
+ {
+ if (e.Data.IsNotEmpty())
+ {
+ UpdateFunc(false, e.Data + Environment.NewLine);
+ }
+ };
+ proc.ErrorDataReceived += (sender, e) =>
+ {
+ if (e.Data.IsNotEmpty())
+ {
+ UpdateFunc(false, e.Data + Environment.NewLine);
+ }
+ };
+
+ proc.Start();
+ proc.BeginOutputReadLine();
+ proc.BeginErrorReadLine();
+
+ await Task.Delay(10);
+ await proc.StandardInput.WriteLineAsync();
+ await Task.Delay(10);
+ await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
+
+ await Task.Delay(100);
+ if (proc is null or { HasExited: true })
+ {
+ throw new Exception(ResUI.FailedToRunCore);
+ }
+
+ _linuxSudoPid = proc.Id;
+
+ return proc;
+ }
+ catch (Exception ex)
+ {
+ Logging.SaveLog(_tag, ex);
+ UpdateFunc(false, ex.Message);
+ return null;
+ }
+ }
+
+ public async Task KillProcessAsLinuxSudo()
+ {
+ if (_linuxSudoPid < 0)
+ {
+ return;
+ }
+
+ try
+ {
+ var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
+ var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
+
+ var result = await Cli.Wrap(shFilePath)
+ .WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
+ .ExecuteAsync();
+
+ _linuxSudoPid = -1;
+ }
+ catch (Exception ex)
+ {
+ Logging.SaveLog(_tag, ex);
+ UpdateFunc(false, ex.Message);
+ }
+ }
+
+ private async Task CreateLinuxShellFile(string cmdLine, string fileName)
+ {
+ var shFilePath = Utils.GetBinConfigPath(fileName);
+ File.Delete(shFilePath);
+
+ var sb = new StringBuilder();
+ sb.AppendLine("#!/bin/sh");
+ if (Utils.IsAdministrator())
+ {
+ sb.AppendLine($"{cmdLine}");
+ }
+ else
+ {
+ sb.AppendLine($"sudo -S {cmdLine}");
+ }
+
+ await File.WriteAllTextAsync(shFilePath, sb.ToString());
+ await Utils.SetLinuxChmod(shFilePath);
+
+ return shFilePath;
+ }
+}
diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs
index a2f24df8..97918693 100644
--- a/v2rayN/ServiceLib/Handler/CoreHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs
@@ -13,7 +13,7 @@ public class CoreHandler
private Config _config;
private Process? _process;
private Process? _processPre;
- private int _linuxSudoPid = -1;
+ private bool _linuxSudo = false;
private Action? _updateFunc;
private const string _tag = "CoreHandler";
@@ -155,21 +155,21 @@ public class CoreHandler
{
try
{
- if (_linuxSudoPid > 0)
+ if (_linuxSudo)
{
- await KillProcessAsLinuxSudo();
- _linuxSudoPid = -1;
+ await CoreAdminHandler.Instance.KillProcessAsLinuxSudo();
+ _linuxSudo = false;
}
if (_process != null)
{
- await ProcUtils.ProcessKill(_process, true);
+ await ProcUtils.ProcessKill(_process, Utils.IsWindows());
_process = null;
}
if (_processPre != null)
{
- await ProcUtils.ProcessKill(_processPre, true);
+ await ProcUtils.ProcessKill(_processPre, Utils.IsWindows());
_processPre = null;
}
}
@@ -225,13 +225,6 @@ public class CoreHandler
_updateFunc?.Invoke(notify, msg);
}
- private bool IsNeedSudo(ECoreType eCoreType)
- {
- return _config.TunModeItem.EnableTun
- && eCoreType == ECoreType.sing_box
- && Utils.IsNonWindows();
- }
-
#endregion Private
#region Process
@@ -245,6 +238,16 @@ public class CoreHandler
return null;
}
+ if (mayNeedSudo
+ && _config.TunModeItem.EnableTun
+ && coreInfo.CoreType == ECoreType.sing_box
+ && Utils.IsNonWindows())
+ {
+ _linuxSudo = true;
+ await CoreAdminHandler.Instance.Init(_config, _updateFunc);
+ return await CoreAdminHandler.Instance.RunProcessAsLinuxSudo(fileName, coreInfo, configPath);
+ }
+
try
{
Process proc = new()
@@ -263,38 +266,25 @@ public class CoreHandler
}
};
- var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
- if (isNeedSudo)
- {
- await RunProcessAsLinuxSudo(proc, fileName, coreInfo, configPath);
- }
-
if (displayLog)
{
proc.OutputDataReceived += (sender, e) =>
{
- if (e.Data.IsNullOrEmpty())
- return;
- UpdateFunc(false, e.Data + Environment.NewLine);
+ if (e.Data.IsNotEmpty())
+ {
+ UpdateFunc(false, e.Data + Environment.NewLine);
+ }
};
proc.ErrorDataReceived += (sender, e) =>
{
- if (e.Data.IsNullOrEmpty())
- return;
- UpdateFunc(false, e.Data + Environment.NewLine);
+ if (e.Data.IsNotEmpty())
+ {
+ UpdateFunc(false, e.Data + Environment.NewLine);
+ }
};
}
proc.Start();
- if (isNeedSudo && AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
- {
- await proc.StandardInput.WriteLineAsync();
- await Task.Delay(10);
- await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
- }
- if (isNeedSudo)
- _linuxSudoPid = proc.Id;
-
if (displayLog)
{
proc.BeginOutputReadLine();
@@ -318,82 +308,4 @@ public class CoreHandler
}
#endregion Process
-
- #region Linux
-
- private async Task RunProcessAsLinuxSudo(Process proc, string fileName, CoreInfo coreInfo, string configPath)
- {
- var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
-
- var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
- proc.StartInfo.FileName = shFilePath;
- proc.StartInfo.Arguments = "";
- proc.StartInfo.WorkingDirectory = "";
- if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
- {
- proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
- proc.StartInfo.RedirectStandardInput = true;
- }
- }
-
- private async Task KillProcessAsLinuxSudo()
- {
- var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
- var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
- Process proc = new()
- {
- StartInfo = new()
- {
- FileName = shFilePath,
- UseShellExecute = false,
- CreateNoWindow = true,
- StandardInputEncoding = Encoding.UTF8,
- RedirectStandardInput = true
- }
- };
- proc.Start();
-
- if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
- {
- try
- {
- await proc.StandardInput.WriteLineAsync();
- await Task.Delay(10);
- await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
- }
- catch (Exception)
- {
- // ignored
- }
- }
-
- var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
- await proc.WaitForExitAsync(timeout.Token);
- await Task.Delay(1000);
- }
-
- private async Task CreateLinuxShellFile(string cmdLine, string fileName)
- {
- //Shell scripts
- var shFilePath = Utils.GetBinConfigPath(AppHandler.Instance.IsAdministrator ? "root_" + fileName : fileName);
- File.Delete(shFilePath);
- var sb = new StringBuilder();
- sb.AppendLine("#!/bin/sh");
- if (AppHandler.Instance.IsAdministrator)
- {
- sb.AppendLine($"{cmdLine}");
- }
- else
- {
- sb.AppendLine($"sudo -S {cmdLine}");
- }
-
- await File.WriteAllTextAsync(shFilePath, sb.ToString());
- await Utils.SetLinuxChmod(shFilePath);
- //Logging.SaveLog(shFilePath);
-
- return shFilePath;
- }
-
- #endregion Linux
}
diff --git a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
index ec6ec39e..2c48d0bf 100644
--- a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
@@ -454,7 +454,7 @@ public class StatusBarViewModel : MyReactiveObject
{
if (Utils.IsWindows())
{
- return AppHandler.Instance.IsAdministrator;
+ return Utils.IsAdministrator();
}
else if (Utils.IsLinux())
{
diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
index 91328046..34852a50 100644
--- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
@@ -143,7 +143,7 @@ public partial class MainWindow : ReactiveWindow
}
else
{
- if (AppHandler.Instance.IsAdministrator)
+ if (Utils.IsAdministrator())
{
this.Title = $"{Utils.GetVersion()} - {ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp}";
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp);
diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs
index b837f65c..b3869cae 100644
--- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs
@@ -132,7 +132,7 @@ public partial class MainWindow
}
});
- this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
+ this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
if (!_config.GuiItem.EnableHWA)
{
From 1c04144573cd2e57df137cbf42f9b33d6626bc24 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sat, 26 Apr 2025 09:53:19 +0800
Subject: [PATCH 05/39] Code clean
---
.../Views/StatusBarView.axaml.cs | 1 -
v2rayN/v2rayN/App.xaml | 2 +-
v2rayN/v2rayN/Views/MainWindow.xaml | 47 ++++++++++--------
v2rayN/v2rayN/Views/ProfilesView.xaml | 16 +++---
.../Views/RoutingRuleDetailsWindow.xaml | 6 +--
.../Views/RoutingRuleSettingWindow.xaml | 6 +--
v2rayN/v2rayN/Views/StatusBarView.xaml | 49 ++++++++++++-------
v2rayN/v2rayN/Views/SubEditWindow.xaml | 6 +--
v2rayN/v2rayN/Views/SubSettingWindow.xaml | 6 +--
v2rayN/v2rayN/Views/ThemeSettingView.xaml | 4 +-
10 files changed, 80 insertions(+), 63 deletions(-)
diff --git a/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs
index 3c44e2d4..b646b5d6 100644
--- a/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs
@@ -8,7 +8,6 @@ using DialogHostAvalonia;
using ReactiveUI;
using Splat;
using v2rayN.Desktop.Common;
-using static QRCoder.PayloadGenerator;
namespace v2rayN.Desktop.Views;
diff --git a/v2rayN/v2rayN/App.xaml b/v2rayN/v2rayN/App.xaml
index 2be80ccb..49a31268 100644
--- a/v2rayN/v2rayN/App.xaml
+++ b/v2rayN/v2rayN/App.xaml
@@ -1,9 +1,9 @@
diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml b/v2rayN/v2rayN/Views/MainWindow.xaml
index 6c233ef4..ea2cbe2d 100644
--- a/v2rayN/v2rayN/Views/MainWindow.xaml
+++ b/v2rayN/v2rayN/Views/MainWindow.xaml
@@ -1,14 +1,14 @@
- The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.
+ رمز عبوری که وارد کرده اید تایید نمی شود، بنابراین مطمئن شوید که آن را به درستی وارد کرده اید. اگر برنامه به دلیل ورودی نادرست به درستی کار نمی کند، لطفاً برنامه را مجدداً راه اندازی کنید. رمز عبور ذخیره نمی شود و پس از هر بار راه اندازی مجدد باید آن را دوباره وارد کنید.
لطفاً ابتدا رمز عبور sudo را در تنظیمات حالت Tun تنظیم کنید
@@ -1416,4 +1416,4 @@
صادر کردن سرور
-
\ No newline at end of file
+
From be3dbfb8e3c2635c981b8f66a58aa6c12d9a9d7e Mon Sep 17 00:00:00 2001
From: Reza Bakhshi Laktasaraei
<74649066+rezabakhshilaktasaraei@users.noreply.github.com>
Date: Sat, 26 Apr 2025 06:01:00 +0330
Subject: [PATCH 07/39] Fix Tab navigation in ToolBar by setting
KeyboardNavigation to Continue (#7185)
---
v2rayN/v2rayN/Views/MainWindow.xaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml b/v2rayN/v2rayN/Views/MainWindow.xaml
index ea2cbe2d..925d1f84 100644
--- a/v2rayN/v2rayN/Views/MainWindow.xaml
+++ b/v2rayN/v2rayN/Views/MainWindow.xaml
@@ -40,7 +40,8 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
ClipToBounds="True"
- Style="{StaticResource MaterialDesignToolBar}">
+ Style="{StaticResource MaterialDesignToolBar}"
+ KeyboardNavigation.TabNavigation="Continue">
@@ -198,7 +210,13 @@
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
DisplayMemberPath="Text"
FontSize="{DynamicResource StdFontSize}"
- Style="{StaticResource MaterialDesignFilledComboBox}" />
+ Style="{StaticResource MaterialDesignFilledComboBox}">
+
+
+
+
From 514dce960a831b77f0792181000ea41913a45d6a Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Mon, 28 Apr 2025 15:57:09 +0800
Subject: [PATCH 12/39] up 7.12.0
---
v2rayN/Directory.Build.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index 8dcfcaaa..d96f5a37 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.11.3
+ 7.12.0
From 5a0fdd971a6a65ecf4ecdf5662f2ecaa07491c71 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Wed, 30 Apr 2025 14:12:02 +0800
Subject: [PATCH 13/39] Bug fix
https://github.com/2dust/v2rayN/issues/7211
---
.../Services/CoreConfig/CoreConfigSingboxService.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
index 34ae6f79..65655f09 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
@@ -989,12 +989,12 @@ public class CoreConfigSingboxService
});
}
- singboxConfig.route.rules.Insert(0, new()
+ singboxConfig.route.rules.Add(new()
{
outbound = Global.DirectTag,
clash_mode = ERuleMode.Direct.ToString()
});
- singboxConfig.route.rules.Insert(0, new()
+ singboxConfig.route.rules.Add(new()
{
outbound = Global.ProxyTag,
clash_mode = ERuleMode.Global.ToString()
@@ -1278,12 +1278,12 @@ public class CoreConfigSingboxService
detour = Global.DirectTag,
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom,
});
- dns4Sbox.rules.Insert(0, new()
+ dns4Sbox.rules.Add(new()
{
server = tag,
clash_mode = ERuleMode.Direct.ToString()
});
- dns4Sbox.rules.Insert(0, new()
+ dns4Sbox.rules.Add(new()
{
server = dns4Sbox.servers.Where(t => t.detour == Global.ProxyTag).Select(t => t.tag).FirstOrDefault() ?? "remote",
clash_mode = ERuleMode.Global.ToString()
From e590547b30b215b85fc582ead848501a1b34b988 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Fri, 2 May 2025 10:44:20 +0800
Subject: [PATCH 14/39] Revert "Bug fix"
This reverts commit 5a0fdd971a6a65ecf4ecdf5662f2ecaa07491c71.
---
.../Services/CoreConfig/CoreConfigSingboxService.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
index 65655f09..54054d43 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
@@ -1278,12 +1278,12 @@ public class CoreConfigSingboxService
detour = Global.DirectTag,
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom,
});
- dns4Sbox.rules.Add(new()
+ dns4Sbox.rules.Insert(0, new()
{
server = tag,
clash_mode = ERuleMode.Direct.ToString()
});
- dns4Sbox.rules.Add(new()
+ dns4Sbox.rules.Insert(0, new()
{
server = dns4Sbox.servers.Where(t => t.detour == Global.ProxyTag).Select(t => t.tag).FirstOrDefault() ?? "remote",
clash_mode = ERuleMode.Global.ToString()
From 13b164acaccae6b9eab0801e85825e923f165ace Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sat, 3 May 2025 11:29:36 +0800
Subject: [PATCH 15/39] Enhanced sorting function, can sort by statistics
---
v2rayN/ServiceLib/Handler/ConfigHandler.cs | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index a23b1c67..a8bf06bb 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -799,8 +799,11 @@ public class ConfigHandler
{
return -1;
}
+ var lstServerStat = (config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
var lstProfile = (from t in lstModel
+ join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
+ from t22 in t2b.DefaultIfEmpty()
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty()
select new ProfileItemModel
@@ -815,7 +818,11 @@ public class ConfigHandler
StreamSecurity = t.StreamSecurity,
Delay = t33?.Delay ?? 0,
Speed = t33?.Speed ?? 0,
- Sort = t33?.Sort ?? 0
+ Sort = t33?.Sort ?? 0,
+ TodayDown = (t22?.TodayDown ?? 0).ToString("D16"),
+ TodayUp = (t22?.TodayUp ?? 0).ToString("D16"),
+ TotalDown = (t22?.TotalDown ?? 0).ToString("D16"),
+ TotalUp = (t22?.TotalUp ?? 0).ToString("D16"),
}).ToList();
Enum.TryParse(colName, true, out EServerColName name);
@@ -833,6 +840,10 @@ public class ConfigHandler
EServerColName.DelayVal => lstProfile.OrderBy(t => t.Delay).ToList(),
EServerColName.SpeedVal => lstProfile.OrderBy(t => t.Speed).ToList(),
EServerColName.SubRemarks => lstProfile.OrderBy(t => t.Subid).ToList(),
+ EServerColName.TodayDown => lstProfile.OrderBy(t => t.TodayDown).ToList(),
+ EServerColName.TodayUp => lstProfile.OrderBy(t => t.TodayUp).ToList(),
+ EServerColName.TotalDown => lstProfile.OrderBy(t => t.TotalDown).ToList(),
+ EServerColName.TotalUp => lstProfile.OrderBy(t => t.TotalUp).ToList(),
_ => lstProfile
};
}
@@ -849,6 +860,10 @@ public class ConfigHandler
EServerColName.DelayVal => lstProfile.OrderByDescending(t => t.Delay).ToList(),
EServerColName.SpeedVal => lstProfile.OrderByDescending(t => t.Speed).ToList(),
EServerColName.SubRemarks => lstProfile.OrderByDescending(t => t.Subid).ToList(),
+ EServerColName.TodayDown => lstProfile.OrderByDescending(t => t.TodayDown).ToList(),
+ EServerColName.TodayUp => lstProfile.OrderByDescending(t => t.TodayUp).ToList(),
+ EServerColName.TotalDown => lstProfile.OrderByDescending(t => t.TotalDown).ToList(),
+ EServerColName.TotalUp => lstProfile.OrderByDescending(t => t.TotalUp).ToList(),
_ => lstProfile
};
}
From 8b4e2f8f238ed406eb4268e331fe16a013c58c53 Mon Sep 17 00:00:00 2001
From: DHR60
Date: Sun, 4 May 2025 17:28:57 +0800
Subject: [PATCH 16/39] Fix DNS (#7233)
* Fix DNS
* Removes expectIPs from remote DNS
---
v2rayN/ServiceLib/Sample/dns_v2ray_normal | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/v2rayN/ServiceLib/Sample/dns_v2ray_normal b/v2rayN/ServiceLib/Sample/dns_v2ray_normal
index 3f9c8b22..fdb30dae 100644
--- a/v2rayN/ServiceLib/Sample/dns_v2ray_normal
+++ b/v2rayN/ServiceLib/Sample/dns_v2ray_normal
@@ -6,11 +6,10 @@
"servers": [
{
"address": "1.1.1.1",
+ "skipFallback": true,
"domains": [
- "geosite:geolocation-!cn"
- ],
- "expectIPs": [
- "geoip:!cn"
+ "domain:googleapis.cn",
+ "domain:gstatic.com"
]
},
{
@@ -23,6 +22,7 @@
"geoip:cn"
]
},
+ "1.1.1.1",
"8.8.8.8",
"https://dns.google/dns-query"
]
From 693a96fff2beddb12588ca2121ae1f8f5467c5ec Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 4 May 2025 17:44:04 +0800
Subject: [PATCH 17/39] Update Directory.Packages.props
---
v2rayN/Directory.Packages.props | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props
index d96899fb..e9c8d492 100644
--- a/v2rayN/Directory.Packages.props
+++ b/v2rayN/Directory.Packages.props
@@ -5,10 +5,10 @@
false
-
-
-
-
+
+
+
+
@@ -27,4 +27,4 @@
-
+
\ No newline at end of file
From 8ea76fd3180aa3e54db31d110a521c88bc5db039 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 4 May 2025 17:44:36 +0800
Subject: [PATCH 18/39] up 7.12.1
---
v2rayN/Directory.Build.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index d96f5a37..259e5316 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.12.0
+ 7.12.1
From 897a4e5635ee41720685bfe192c0dae664e8c66e Mon Sep 17 00:00:00 2001
From: DHR60
Date: Mon, 5 May 2025 13:59:14 +0800
Subject: [PATCH 19/39] Move exe direct rule before clash_mode (#7236)
---
.../CoreConfig/CoreConfigSingboxService.cs | 41 ++++++++++---------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
index 54054d43..358fbaf0 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
@@ -979,26 +979,6 @@ public class CoreConfigSingboxService
try
{
var dnsOutbound = "dns_out";
- if (!_config.Inbound.First().SniffingEnabled)
- {
- singboxConfig.route.rules.Add(new()
- {
- port = [53],
- network = ["udp"],
- outbound = dnsOutbound
- });
- }
-
- singboxConfig.route.rules.Add(new()
- {
- outbound = Global.DirectTag,
- clash_mode = ERuleMode.Direct.ToString()
- });
- singboxConfig.route.rules.Add(new()
- {
- outbound = Global.ProxyTag,
- clash_mode = ERuleMode.Global.ToString()
- });
if (_config.TunModeItem.EnableTun)
{
@@ -1025,6 +1005,27 @@ public class CoreConfigSingboxService
});
}
+ if (!_config.Inbound.First().SniffingEnabled)
+ {
+ singboxConfig.route.rules.Add(new()
+ {
+ port = [53],
+ network = ["udp"],
+ outbound = dnsOutbound
+ });
+ }
+
+ singboxConfig.route.rules.Add(new()
+ {
+ outbound = Global.DirectTag,
+ clash_mode = ERuleMode.Direct.ToString()
+ });
+ singboxConfig.route.rules.Add(new()
+ {
+ outbound = Global.ProxyTag,
+ clash_mode = ERuleMode.Global.ToString()
+ });
+
var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing != null)
{
From 82b366cd9b0aef8d3e44f86ab968e60c75bdb261 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Wed, 7 May 2025 14:28:55 +0800
Subject: [PATCH 20/39] Fix
https://github.com/2dust/v2rayN/issues/7244
---
v2rayN/v2rayN.Desktop/App.axaml.cs | 2 +-
.../Views/ClashConnectionsView.axaml.cs | 11 +++++++++--
v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs | 11 +++++++++--
v2rayN/v2rayN/App.xaml.cs | 2 +-
v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs | 11 +++++++++--
v2rayN/v2rayN/Views/ProfilesView.xaml.cs | 11 +++++++++--
6 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/v2rayN/v2rayN.Desktop/App.axaml.cs b/v2rayN/v2rayN.Desktop/App.axaml.cs
index b797c90b..7626edfd 100644
--- a/v2rayN/v2rayN.Desktop/App.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/App.axaml.cs
@@ -43,7 +43,7 @@ public partial class App : Application
{
if (e.ExceptionObject != null)
{
- Logging.SaveLog("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject!);
+ Logging.SaveLog("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject);
}
}
diff --git a/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs
index b4426c29..c39724eb 100644
--- a/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/ClashConnectionsView.axaml.cs
@@ -52,9 +52,16 @@ public partial class ClashConnectionsView : ReactiveUserControl
private void AutofitColumnWidth()
{
- foreach (var it in lstProfiles.Columns)
+ try
{
- it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
+ foreach (var it in lstProfiles.Columns)
+ {
+ it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logging.SaveLog("ProfilesView", ex);
}
}
diff --git a/v2rayN/v2rayN/App.xaml.cs b/v2rayN/v2rayN/App.xaml.cs
index 86518fa0..0a282733 100644
--- a/v2rayN/v2rayN/App.xaml.cs
+++ b/v2rayN/v2rayN/App.xaml.cs
@@ -56,7 +56,7 @@ public partial class App : Application
{
if (e.ExceptionObject != null)
{
- Logging.SaveLog("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject!);
+ Logging.SaveLog("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject);
}
}
diff --git a/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs b/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs
index 54f3adee..18b97d2a 100644
--- a/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs
+++ b/v2rayN/v2rayN/Views/ClashConnectionsView.xaml.cs
@@ -55,9 +55,16 @@ public partial class ClashConnectionsView
private void AutofitColumnWidth()
{
- foreach (var it in lstConnections.Columns)
+ try
{
- it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
+ foreach (var it in lstConnections.Columns)
+ {
+ it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logging.SaveLog("ClashConnectionsView", ex);
}
}
diff --git a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs
index daefd332..3501747e 100644
--- a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs
+++ b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs
@@ -323,9 +323,16 @@ public partial class ProfilesView
private void AutofitColumnWidth()
{
- foreach (var it in lstProfiles.Columns)
+ try
{
- it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
+ foreach (var it in lstProfiles.Columns)
+ {
+ it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logging.SaveLog("ProfilesView", ex);
}
}
From 3d462c4be3fde44b842083bbc56e4b385c6efd04 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Thu, 8 May 2025 15:56:52 +0800
Subject: [PATCH 21/39] Fix
https://github.com/2dust/v2rayN/issues/7247
---
.../Services/CoreConfig/CoreConfigSingboxService.cs | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
index 358fbaf0..18bebed4 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
@@ -1088,14 +1088,11 @@ public class CoreConfigSingboxService
if (item.Port.IsNotEmpty())
{
- if (item.Port.Contains("-"))
- {
- rule.port_range = new List { item.Port.Replace("-", ":") };
- }
- else
- {
- rule.port = new List { item.Port.ToInt() };
- }
+ var portRanges = item.Port.Split(',').Where(it => it.Contains('-')).Select(it => it.Replace("-", ":")).ToList();
+ var ports = item.Port.Split(',').Where(it => !it.Contains('-')).Select(it => it.ToInt()).ToList();
+
+ rule.port_range = portRanges.Count > 0 ? portRanges : null;
+ rule.port = ports.Count > 0 ? ports : null;
}
if (item.Network.IsNotEmpty())
{
From 3a4a96f87a22d216ef862649313e4635aaf2d204 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Fri, 9 May 2025 14:33:41 +0800
Subject: [PATCH 22/39] Fix
https://github.com/2dust/v2rayN/issues/7258
---
v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs
index 71b4c0c2..5892236f 100644
--- a/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs
+++ b/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs
@@ -6,9 +6,9 @@ public class VmessFmt : BaseFmt
{
msg = ResUI.ConfigurationFormatIncorrect;
ProfileItem? item;
- if (str.IndexOf('?') > 0 && str.IndexOf('&') > 0)
+ if (str.IndexOf('@') > 0)
{
- item = ResolveStdVmess(str);
+ item = ResolveStdVmess(str) ?? ResolveVmess(str, out msg);
}
else
{
From d3b95d781ad6091cfac654c91a8cd8f4a3ba9e81 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 11 May 2025 10:38:48 +0800
Subject: [PATCH 23/39] Removed the function of displaying the current
connection IP
https://github.com/2dust/v2rayN/discussions/7268
---
v2rayN/ServiceLib/Services/UpdateService.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayN/ServiceLib/Services/UpdateService.cs
index f896e4ad..914bddc5 100644
--- a/v2rayN/ServiceLib/Services/UpdateService.cs
+++ b/v2rayN/ServiceLib/Services/UpdateService.cs
@@ -248,12 +248,12 @@ public class UpdateService
var downloadHandle = new DownloadService();
var time = await downloadHandle.RunAvailabilityCheck(null);
var ip = Global.None;
- if (time > 0)
- {
- var result = await downloadHandle.TryDownloadString(Global.IPAPIUrl, true, Global.IPAPIUrl);
- var ipInfo = JsonUtils.Deserialize(result);
- ip = $"({ipInfo?.country_code}) {ipInfo?.ip}";
- }
+ //if (time > 0)
+ //{
+ // var result = await downloadHandle.TryDownloadString(Global.IPAPIUrl, true, Global.IPAPIUrl);
+ // var ipInfo = JsonUtils.Deserialize(result);
+ // ip = $"({ipInfo?.country_code}) {ipInfo?.ip}";
+ //}
return string.Format(ResUI.TestMeOutput, time, ip);
}
From 8381fefb787ebbc3eabc7a821ef5212f5e3b7429 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 11 May 2025 10:39:02 +0800
Subject: [PATCH 24/39] up 7.12.2
---
v2rayN/Directory.Build.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index 259e5316..c909084d 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.12.1
+ 7.12.2
From a2cfe6fa5146781cb7f30fd4a28339d47cab58d4 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 11 May 2025 16:59:00 +0800
Subject: [PATCH 25/39] Added the current connection information test url
option
https://github.com/2dust/v2rayN/discussions/7268
---
v2rayN/ServiceLib/Global.cs | 12 +++++-
v2rayN/ServiceLib/Handler/ConfigHandler.cs | 2 +-
.../ServiceLib/Handler/ConnectionHandler.cs | 42 +++++++++++++++++++
v2rayN/ServiceLib/Models/ConfigItems.cs | 1 +
v2rayN/ServiceLib/Models/IPAPIInfo.cs | 13 ++++--
v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 9 ++++
v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 5 ++-
v2rayN/ServiceLib/Resx/ResUI.hu.resx | 3 ++
v2rayN/ServiceLib/Resx/ResUI.resx | 3 ++
v2rayN/ServiceLib/Resx/ResUI.ru.resx | 3 ++
v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 3 ++
v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 3 ++
v2rayN/ServiceLib/Services/UpdateService.cs | 15 -------
.../ViewModels/OptionSettingViewModel.cs | 5 ++-
.../ViewModels/StatusBarViewModel.cs | 2 +-
.../Views/OptionSettingWindow.axaml | 16 ++++++-
.../Views/OptionSettingWindow.axaml.cs | 5 +++
v2rayN/v2rayN/Views/OptionSettingWindow.xaml | 17 ++++++++
.../v2rayN/Views/OptionSettingWindow.xaml.cs | 5 +++
19 files changed, 139 insertions(+), 25 deletions(-)
create mode 100644 v2rayN/ServiceLib/Handler/ConnectionHandler.cs
diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs
index 78459920..68908b27 100644
--- a/v2rayN/ServiceLib/Global.cs
+++ b/v2rayN/ServiceLib/Global.cs
@@ -8,9 +8,7 @@ public class Global
public const string GithubUrl = "https://github.com";
public const string GithubApiUrl = "https://api.github.com/repos";
public const string GeoUrl = "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/{0}.dat";
- public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
public const string SingboxRulesetUrl = @"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-{0}/{1}.srs";
- public const string IPAPIUrl = "https://api.ip.sb/geoip";
public const string PromotionUrl = @"aHR0cHM6Ly85LjIzNDQ1Ni54eXovYWJjLmh0bWw=";
public const string ConfigFileName = "guiNConfig.json";
@@ -519,5 +517,15 @@ public class Global
@"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb"
];
+ public static readonly List IPAPIUrls =
+ [
+ @"https://speed.cloudflare.com/meta",
+ @"https://api.ip.sb/geoip",
+ @"https://api-ipv4.ip.sb/geoip",
+ @"https://api-ipv6.ip.sb/geoip",
+ @"https://api.ipapi.is",
+ @""
+ ];
+
#endregion const
}
diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index a8bf06bb..6a25b56f 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -122,7 +122,7 @@ public class ConfigHandler
}
if (config.SpeedTestItem.SpeedPingTestUrl.IsNullOrEmpty())
{
- config.SpeedTestItem.SpeedPingTestUrl = Global.SpeedPingTestUrl;
+ config.SpeedTestItem.SpeedPingTestUrl = Global.SpeedPingTestUrls.First();
}
if (config.SpeedTestItem.MixedConcurrencyCount < 1)
{
diff --git a/v2rayN/ServiceLib/Handler/ConnectionHandler.cs b/v2rayN/ServiceLib/Handler/ConnectionHandler.cs
new file mode 100644
index 00000000..3cfc6020
--- /dev/null
+++ b/v2rayN/ServiceLib/Handler/ConnectionHandler.cs
@@ -0,0 +1,42 @@
+namespace ServiceLib.Handler;
+
+public class ConnectionHandler
+{
+ private static readonly Lazy _instance = new(() => new());
+ public static ConnectionHandler Instance => _instance.Value;
+
+ public async Task RunAvailabilityCheck()
+ {
+ var downloadHandle = new DownloadService();
+ var time = await downloadHandle.RunAvailabilityCheck(null);
+ var ip = time > 0 ? await GetIPInfo(downloadHandle) ?? Global.None : Global.None;
+
+ return string.Format(ResUI.TestMeOutput, time, ip);
+ }
+
+ private async Task GetIPInfo(DownloadService downloadHandle)
+ {
+ var url = AppHandler.Instance.Config.SpeedTestItem.IPAPIUrl;
+ if (url.IsNullOrEmpty())
+ {
+ return null;
+ }
+
+ var result = await downloadHandle.TryDownloadString(url, true, "");
+ if (result == null)
+ {
+ return null;
+ }
+
+ var ipInfo = JsonUtils.Deserialize(result);
+ if (ipInfo == null)
+ {
+ return null;
+ }
+
+ var ip = ipInfo.ip ?? ipInfo.clientIp ?? ipInfo.ip_addr ?? ipInfo.query;
+ var country = ipInfo.country_code ?? ipInfo.country ?? ipInfo.countryCode ?? ipInfo.location?.country_code;
+
+ return $"({country ?? "unknown"}) {ip}";
+ }
+}
diff --git a/v2rayN/ServiceLib/Models/ConfigItems.cs b/v2rayN/ServiceLib/Models/ConfigItems.cs
index 47c96a3f..afd7e7cc 100644
--- a/v2rayN/ServiceLib/Models/ConfigItems.cs
+++ b/v2rayN/ServiceLib/Models/ConfigItems.cs
@@ -156,6 +156,7 @@ public class SpeedTestItem
public string SpeedTestUrl { get; set; }
public string SpeedPingTestUrl { get; set; }
public int MixedConcurrencyCount { get; set; }
+ public string IPAPIUrl { get; set; }
}
[Serializable]
diff --git a/v2rayN/ServiceLib/Models/IPAPIInfo.cs b/v2rayN/ServiceLib/Models/IPAPIInfo.cs
index 21063946..7ba16727 100644
--- a/v2rayN/ServiceLib/Models/IPAPIInfo.cs
+++ b/v2rayN/ServiceLib/Models/IPAPIInfo.cs
@@ -3,10 +3,17 @@ namespace ServiceLib.Models;
internal class IPAPIInfo
{
public string? ip { get; set; }
- public string? city { get; set; }
- public string? region { get; set; }
- public string? region_code { get; set; }
+ public string? clientIp { get; set; }
+ public string? ip_addr { get; set; }
+ public string? query { get; set; }
public string? country { get; set; }
public string? country_name { get; set; }
public string? country_code { get; set; }
+ public string? countryCode { get; set; }
+ public LocationInfo? location { get; set; }
+}
+
+public class LocationInfo
+{
+ public string? country_code { get; set; }
}
diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index ac507c45..9ba7a90d 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -3201,6 +3201,15 @@ namespace ServiceLib.Resx {
}
}
+ ///
+ /// 查找类似 Current connection info test URL 的本地化字符串。
+ ///
+ public static string TbSettingsIPAPIUrl {
+ get {
+ return ResourceManager.GetString("TbSettingsIPAPIUrl", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Keep older entries when de-duplicating 的本地化字符串。
///
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index adb95f2c..d10e18e7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
@@ -1416,4 +1416,7 @@
صادر کردن سرور
-
+
+ Current connection info test URL
+
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
index 130c3579..4f8824b7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
@@ -1416,4 +1416,7 @@
Export server
+
+ Current connection info test URL
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index 7ec5d653..240aa55b 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1416,4 +1416,7 @@
Export Configuration
+
+ Current connection info test URL
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index 9103641b..4468989f 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1416,4 +1416,7 @@
Export server
+
+ Current connection info test URL
+
\ 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 150a9353..97305242 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1413,4 +1413,7 @@
导出配置文件
+
+ 当前连接信息测试地址
+
\ 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 e827d0ea..35148566 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1413,4 +1413,7 @@
匯出設定檔
+
+ 目前連接資訊測試地址
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayN/ServiceLib/Services/UpdateService.cs
index 914bddc5..5c509519 100644
--- a/v2rayN/ServiceLib/Services/UpdateService.cs
+++ b/v2rayN/ServiceLib/Services/UpdateService.cs
@@ -243,21 +243,6 @@ public class UpdateService
_updateFunc?.Invoke(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
}
- public async Task RunAvailabilityCheck()
- {
- var downloadHandle = new DownloadService();
- var time = await downloadHandle.RunAvailabilityCheck(null);
- var ip = Global.None;
- //if (time > 0)
- //{
- // var result = await downloadHandle.TryDownloadString(Global.IPAPIUrl, true, Global.IPAPIUrl);
- // var ipInfo = JsonUtils.Deserialize(result);
- // ip = $"({ipInfo?.country_code}) {ipInfo?.ip}";
- //}
-
- return string.Format(ResUI.TestMeOutput, time, ip);
- }
-
#region CheckUpdate private
private async Task CheckUpdateAsync(DownloadService downloadHandle, ECoreType type, bool preRelease)
diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
index fd26eb32..57d8cac7 100644
--- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
@@ -70,6 +70,7 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public string GeoFileSourceUrl { get; set; }
[Reactive] public string SrsFileSourceUrl { get; set; }
[Reactive] public string RoutingRulesSourceUrl { get; set; }
+ [Reactive] public string IPAPIUrl { get; set; }
#endregion UI
@@ -186,6 +187,7 @@ public class OptionSettingViewModel : MyReactiveObject
GeoFileSourceUrl = _config.ConstItem.GeoSourceUrl;
SrsFileSourceUrl = _config.ConstItem.SrsSourceUrl;
RoutingRulesSourceUrl = _config.ConstItem.RouteRulesTemplateSourceUrl;
+ IPAPIUrl = _config.SpeedTestItem.IPAPIUrl;
#endregion UI
@@ -344,6 +346,7 @@ public class OptionSettingViewModel : MyReactiveObject
_config.ConstItem.GeoSourceUrl = GeoFileSourceUrl;
_config.ConstItem.SrsSourceUrl = SrsFileSourceUrl;
_config.ConstItem.RouteRulesTemplateSourceUrl = RoutingRulesSourceUrl;
+ _config.SpeedTestItem.IPAPIUrl = IPAPIUrl;
//systemProxy
_config.SystemProxyItem.SystemProxyExceptions = systemProxyExceptions;
@@ -356,7 +359,7 @@ public class OptionSettingViewModel : MyReactiveObject
_config.TunModeItem.Mtu = TunMtu;
_config.TunModeItem.EnableExInbound = TunEnableExInbound;
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
-
+
//coreType
await SaveCoreType();
diff --git a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
index 2c48d0bf..82b48aff 100644
--- a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
@@ -320,7 +320,7 @@ public class StatusBarViewModel : MyReactiveObject
var msg = await Task.Run(async () =>
{
- return await (new UpdateService()).RunAvailabilityCheck();
+ return await ConnectionHandler.Instance.RunAvailabilityCheck();
});
NoticeHandler.Instance.SendMessageEx(msg);
diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
index 3ad9b178..004f68a4 100644
--- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
@@ -343,7 +343,7 @@
+ RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
+
+
+
+
diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs
index 4faa0c27..fd319d92 100644
--- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs
@@ -92,6 +92,10 @@ public partial class OptionSettingWindow : ReactiveWindow
+ {
+ cmbIPAPIUrl.Items.Add(it);
+ });
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
{
cmbMainGirdOrientation.Items.Add(it.ToString());
@@ -143,6 +147,7 @@ public partial class OptionSettingWindow : ReactiveWindow vm.GeoFileSourceUrl, v => v.cmbGetFilesSourceUrl.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SrsFileSourceUrl, v => v.cmbSrsFilesSourceUrl.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RoutingRulesSourceUrl, v => v.cmbRoutingRulesSourceUrl.SelectedValue).DisposeWith(disposables);
+ this.Bind(ViewModel, vm => vm.IPAPIUrl, v => v.cmbIPAPIUrl.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.notProxyLocalAddress, v => v.tognotProxyLocalAddress.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.SelectedValue).DisposeWith(disposables);
diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
index 374dce35..f9b4b13c 100644
--- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
+++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
@@ -552,6 +552,7 @@
+
@@ -942,6 +943,22 @@
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsChinaUserTip}"
TextWrapping="Wrap" />
+
+
+
diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs
index b0b5440c..ecdc39f0 100644
--- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs
@@ -101,6 +101,10 @@ public partial class OptionSettingWindow
{
cmbRoutingRulesSourceUrl.Items.Add(it);
});
+ Global.IPAPIUrls.ForEach(it =>
+ {
+ cmbIPAPIUrl.Items.Add(it);
+ });
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
{
cmbMainGirdOrientation.Items.Add(it.ToString());
@@ -162,6 +166,7 @@ public partial class OptionSettingWindow
this.Bind(ViewModel, vm => vm.GeoFileSourceUrl, v => v.cmbGetFilesSourceUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SrsFileSourceUrl, v => v.cmbSrsFilesSourceUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RoutingRulesSourceUrl, v => v.cmbRoutingRulesSourceUrl.Text).DisposeWith(disposables);
+ this.Bind(ViewModel, vm => vm.IPAPIUrl, v => v.cmbIPAPIUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.notProxyLocalAddress, v => v.tognotProxyLocalAddress.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);
From 331e8ce960d08b414b67d800d8d4d159a7ae173e Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 11 May 2025 19:19:26 +0800
Subject: [PATCH 26/39] up 7.12.3
---
v2rayN/Directory.Build.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index c909084d..8111da39 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.12.2
+ 7.12.3
From 01b021b2c379a0569c04a5493bfcf462c2f28ea0 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Mon, 12 May 2025 20:28:28 +0800
Subject: [PATCH 27/39] Bug fix
https://github.com/2dust/v2rayN/issues/7279
---
v2rayN/ServiceLib/Services/UpdateService.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayN/ServiceLib/Services/UpdateService.cs
index 5c509519..636f3616 100644
--- a/v2rayN/ServiceLib/Services/UpdateService.cs
+++ b/v2rayN/ServiceLib/Services/UpdateService.cs
@@ -194,11 +194,11 @@ public class UpdateService
{
if (Utils.IsBase64String(result2))
{
- result += Utils.Base64Decode(result2);
+ result += Environment.NewLine + Utils.Base64Decode(result2);
}
else
{
- result += result2;
+ result += Environment.NewLine + result2;
}
}
}
From 4f8648cbc9ec0a349495689d8c10d057b8ebd2d2 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Mon, 12 May 2025 20:29:34 +0800
Subject: [PATCH 28/39] Fix
https://github.com/2dust/v2rayN/issues/7270
---
v2rayN/v2rayN/Views/ProfilesView.xaml | 9 +++------
v2rayN/v2rayN/Views/StatusBarView.xaml | 21 +++------------------
2 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/v2rayN/v2rayN/Views/ProfilesView.xaml b/v2rayN/v2rayN/Views/ProfilesView.xaml
index 18431152..393bf062 100644
--- a/v2rayN/v2rayN/Views/ProfilesView.xaml
+++ b/v2rayN/v2rayN/Views/ProfilesView.xaml
@@ -18,9 +18,6 @@
-
@@ -28,10 +25,10 @@
+ ItemContainerStyle="{StaticResource MyChipListBoxItem}"
+ Style="{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBox}">
diff --git a/v2rayN/v2rayN/Views/StatusBarView.xaml b/v2rayN/v2rayN/Views/StatusBarView.xaml
index 61c6c105..bc5534db 100644
--- a/v2rayN/v2rayN/Views/StatusBarView.xaml
+++ b/v2rayN/v2rayN/Views/StatusBarView.xaml
@@ -92,12 +92,7 @@
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}"
- Style="{StaticResource MaterialDesignFloatingHintComboBox}">
-
-
-
+ Style="{StaticResource MaterialDesignFloatingHintComboBox}">
@@ -190,12 +185,7 @@
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}"
- Style="{StaticResource MaterialDesignFilledComboBox}">
-
-
-
+ Style="{StaticResource MaterialDesignFilledComboBox}">
@@ -210,12 +200,7 @@
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
DisplayMemberPath="Text"
FontSize="{DynamicResource StdFontSize}"
- Style="{StaticResource MaterialDesignFilledComboBox}">
-
-
-
+ Style="{StaticResource MaterialDesignFilledComboBox}">
From 5824e18ed6cc62c4f7294347d12723daa2a0988f Mon Sep 17 00:00:00 2001
From: Pk-web6936 <202365630+Pk-web6936@users.noreply.github.com>
Date: Thu, 15 May 2025 14:51:53 +0330
Subject: [PATCH 29/39] Update Persian translate (#7273)
---
v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index d10e18e7..0e18c4be 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
@@ -1417,6 +1417,6 @@
صادر کردن سرور
- Current connection info test URL
+ URL آزمایش اطلاعات اتصال فعلی
-
\ No newline at end of file
+
From 5d2aea6b4feb14731577715be4d22d7d673f30ad Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sat, 17 May 2025 14:51:18 +0800
Subject: [PATCH 30/39] Change the inbound of the xray configuration file from
socks to mixed
---
.../Services/CoreConfig/CoreConfigV2rayService.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs
index 618f5da8..ccbfb057 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs
@@ -328,7 +328,7 @@ public class CoreConfigV2rayService
{
listen = Global.Loopback,
port = port,
- protocol = EInboundProtocol.socks.ToString(),
+ protocol = EInboundProtocol.mixed.ToString(),
};
inbound.tag = inbound.protocol + inbound.port.ToString();
v2rayConfig.inbounds.Add(inbound);
@@ -403,7 +403,7 @@ public class CoreConfigV2rayService
tag = $"{EInboundProtocol.socks}{port}",
listen = Global.Loopback,
port = port,
- protocol = EInboundProtocol.socks.ToString(),
+ protocol = EInboundProtocol.mixed.ToString(),
});
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -507,7 +507,7 @@ public class CoreConfigV2rayService
}
inbound.tag = protocol.ToString();
inbound.port = inItem.LocalPort + (int)protocol;
- inbound.protocol = EInboundProtocol.socks.ToString();
+ inbound.protocol = EInboundProtocol.mixed.ToString();
inbound.settings.udp = inItem.UdpEnabled;
inbound.sniffing.enabled = inItem.SniffingEnabled;
inbound.sniffing.destOverride = inItem.DestOverride;
From b9613875ce111554d60130acb5dd20dbfb40c85b Mon Sep 17 00:00:00 2001
From: DHR60
Date: Wed, 21 May 2025 19:57:23 +0800
Subject: [PATCH 31/39] Determine .exe suffix based on OS in
GenRoutingDirectExe (#7322)
* Determine .exe suffix based on OS in GenRoutingDirectExe
* Uses Utils.GetExeName
---
.../CoreConfig/CoreConfigSingboxService.cs | 28 ++++++++++---------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
index 18bebed4..ba436903 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
@@ -1048,28 +1048,30 @@ public class CoreConfigSingboxService
private void GenRoutingDirectExe(out List lstDnsExe, out List lstDirectExe)
{
- lstDnsExe = new();
- lstDirectExe = new();
- var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
- foreach (var it in coreInfo)
+ var dnsExeSet = new HashSet(StringComparer.OrdinalIgnoreCase);
+ var directExeSet = new HashSet(StringComparer.OrdinalIgnoreCase);
+
+ var coreInfoResult = CoreInfoHandler.Instance.GetCoreInfo();
+
+ foreach (var coreConfig in coreInfoResult)
{
- if (it.CoreType == ECoreType.v2rayN)
+ if (coreConfig.CoreType == ECoreType.v2rayN)
{
continue;
}
- foreach (var it2 in it.CoreExes)
- {
- if (!lstDnsExe.Contains(it2) && it.CoreType != ECoreType.sing_box)
- {
- lstDnsExe.Add($"{it2}.exe");
- }
- if (!lstDirectExe.Contains(it2))
+ foreach (var baseExeName in coreConfig.CoreExes)
+ {
+ if (coreConfig.CoreType != ECoreType.sing_box)
{
- lstDirectExe.Add($"{it2}.exe");
+ dnsExeSet.Add(Utils.GetExeName(baseExeName));
}
+ directExeSet.Add(Utils.GetExeName(baseExeName));
}
}
+
+ lstDnsExe = new List(dnsExeSet);
+ lstDirectExe = new List(directExeSet);
}
private async Task GenRoutingUserRule(RulesItem item, List rules)
From 2ab1b9068f2fb83492a4e9ef976d0372d3275584 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Wed, 21 May 2025 20:00:41 +0800
Subject: [PATCH 32/39] up 7.12.4
---
v2rayN/Directory.Build.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index 8111da39..90340a75 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.12.3
+ 7.12.4
From 2f3fba73dec5c942e3b63dbe853623116673c549 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 25 May 2025 19:11:42 +0800
Subject: [PATCH 33/39] Bug fix
https://github.com/2dust/v2rayN/issues/7333
---
v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs | 2 +-
v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs | 2 +-
v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml.cs | 4 ++--
v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml.cs | 2 +-
v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml.cs | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
index 34852a50..e368d297 100644
--- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
@@ -388,7 +388,7 @@ public partial class MainWindow : ReactiveWindow
private async void MenuClose_Click(object? sender, RoutedEventArgs e)
{
- if (await UI.ShowYesNo(this, ResUI.menuExitTips) == ButtonResult.No)
+ if (await UI.ShowYesNo(this, ResUI.menuExitTips) != ButtonResult.Yes)
{
return;
}
diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs
index e225cc65..9bcdb85a 100644
--- a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs
@@ -138,7 +138,7 @@ public partial class ProfilesView : ReactiveUserControl
break;
case EViewAction.ShowYesNo:
- if (await UI.ShowYesNo(_window, ResUI.RemoveServer) == ButtonResult.No)
+ if (await UI.ShowYesNo(_window, ResUI.RemoveServer) != ButtonResult.Yes)
{
return false;
}
diff --git a/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml.cs
index 1fbe5c2b..1cae4c0b 100644
--- a/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml.cs
@@ -80,14 +80,14 @@ public partial class RoutingRuleSettingWindow : ReactiveWindow
break;
case EViewAction.ShowYesNo:
- if (await UI.ShowYesNo(this, ResUI.RemoveServer) == ButtonResult.No)
+ if (await UI.ShowYesNo(this, ResUI.RemoveServer) != ButtonResult.Yes)
{
return false;
}
From 4875b37f700d009e94fc5715610b30f29bcf12fb Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 25 May 2025 19:12:06 +0800
Subject: [PATCH 34/39] up 7.12.5
---
v2rayN/Directory.Build.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index 90340a75..78438651 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.12.4
+ 7.12.5
From 608a6c387a9037f3a5299a7216ed7ec3bfefdd37 Mon Sep 17 00:00:00 2001
From: Yuri Tukhachevsky
Date: Mon, 26 May 2025 13:48:31 +0800
Subject: [PATCH 35/39] add support for UKUI (#7348)
---
v2rayN/ServiceLib/Sample/proxy_set_linux_sh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/v2rayN/ServiceLib/Sample/proxy_set_linux_sh b/v2rayN/ServiceLib/Sample/proxy_set_linux_sh
index 6267fd35..a2db3763 100644
--- a/v2rayN/ServiceLib/Sample/proxy_set_linux_sh
+++ b/v2rayN/ServiceLib/Sample/proxy_set_linux_sh
@@ -95,6 +95,11 @@ detect_desktop_environment() {
return
fi
+ if [[ "$XDG_CURRENT_DESKTOP" == *"UKUI"* ]] || [[ "$XDG_SESSION_DESKTOP" == *"ukui"* ]]; then
+ echo "gnome"
+ return
+ fi
+
local KDE_ENVIRONMENTS=("KDE" "plasma")
for ENV in "${KDE_ENVIRONMENTS[@]}"; do
if [ "$XDG_CURRENT_DESKTOP" == "$ENV" ] || [ "$XDG_SESSION_DESKTOP" == "$ENV" ]; then
From 3812ccc780dd52160a59b7e414de52915bc6a5b3 Mon Sep 17 00:00:00 2001
From: Yuri Tukhachevsky
Date: Wed, 28 May 2025 09:05:55 +0800
Subject: [PATCH 36/39] Add support for DDE and MATE (#7353)
* add support for UKUI
* Add support for DDE and MATE
---
v2rayN/ServiceLib/Sample/proxy_set_linux_sh | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/v2rayN/ServiceLib/Sample/proxy_set_linux_sh b/v2rayN/ServiceLib/Sample/proxy_set_linux_sh
index a2db3763..335cce0e 100644
--- a/v2rayN/ServiceLib/Sample/proxy_set_linux_sh
+++ b/v2rayN/ServiceLib/Sample/proxy_set_linux_sh
@@ -100,6 +100,16 @@ detect_desktop_environment() {
return
fi
+ if [[ "$XDG_CURRENT_DESKTOP" == *"DDE"* ]] || [[ "$XDG_SESSION_DESKTOP" == *"dde"* ]]; then
+ echo "gnome"
+ return
+ fi
+
+ if [[ "$XDG_CURRENT_DESKTOP" == *"MATE"* ]] || [[ "$XDG_SESSION_DESKTOP" == *"mate"* ]]; then
+ echo "gnome"
+ return
+ fi
+
local KDE_ENVIRONMENTS=("KDE" "plasma")
for ENV in "${KDE_ENVIRONMENTS[@]}"; do
if [ "$XDG_CURRENT_DESKTOP" == "$ENV" ] || [ "$XDG_SESSION_DESKTOP" == "$ENV" ]; then
From fb4b8b2789b0c84449f2d411bdbc44994aa9de5e Mon Sep 17 00:00:00 2001
From: Miheichev Aleksandr Sergeevich
Date: Wed, 28 May 2025 15:03:50 +0300
Subject: [PATCH 37/39] Revision of the Russian translation (#7342)
* Revision of the Russian translation
* Fix: remove duplicate TbSettingsSocksPortTip and refine three Russian strings
* refactor: improve Russian translations and fix punctuation
- Standardized punctuation in tooltips and messages (replaced semicolons with commas where appropriate)
- Improved consistency in server type labels (moved square brackets in "[TUIC] server" and similar)
- Enhanced clarity in "Speed Ping Test URL" to "URL for real ping test"
- Simplified "NeedRebootTips" message
- Fixed minor grammatical and formatting issues in various UI strings
- Removed duplicate "TbSettingsStartBootTip" entry
- Improved tooltip for port settings
---
v2rayN/ServiceLib/Resx/ResUI.ru.resx | 376 +++++++++++++--------------
1 file changed, 188 insertions(+), 188 deletions(-)
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index 4468989f..ddef42d4 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1,17 +1,17 @@
-
@@ -118,16 +118,16 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- Экспортирование URL в буфер обмена успешно завершено
+ Ссылка успешно скопирована в буфер обмена
- Пожалуйста, сначала проверьте настройки сервера
+ Сначала проверьте настройки сервера
Недопустимый формат конфигурации
- Обратите внимание, что пользовательская конфигурация полностью зависит от вашей собственной конфигурации и работает не со всеми настройками. Если вы хотите использовать системный прокси, пожалуйста, измените порт прослушивания вручную.
+ Обратите внимание, что пользовательская конфигурация полностью зависит от вашей собственной конфигурации и работает не со всеми настройками. Если вы хотите использовать системный прокси, то измените порт прослушивания вручную
Загрузка...
@@ -136,13 +136,13 @@
Скорость загрузки
- Хотите загрузить? {0}
+ Хотите загрузить {0}?
Не удалось преобразовать файл конфигурации
- Не удалось создать файл конфигурации по умолчаниюe
+ Не удалось создать файл конфигурации по умолчанию
Не удалось получить конфигурацию по умолчанию
@@ -154,37 +154,37 @@
Не удалось прочитать файл конфигурации
- Пожалуйста, укажите порт сервера в правильном формате
+ Укажите порт сервера в правильном формате
- Пожалуйста, укажите локальный порт прослушивания
+ Введите локальный порт для прослушивания
- Пожалуйста, введите пароль
+ Введите пароль
- Пожалуйста, заполните адрес сервера
+ Введите адрес сервера
- Пожалуйста, заполните идентификатор пользователя
+ Введите идентификатор пользователя
- Некорректная конфигурация, пожалуйста, проверьте
+ Некорректная конфигурация. Проверьте
Исходная конфигурация
- {0} {1} является последней версией.
+ {0} {1} является последней версией
- {0} {1} является последней версией.
+ {0} {1} является последней версией
Адрес
- Безопасность
+ Метод шифрования
Порт
@@ -199,7 +199,7 @@
Загружено трафика сегодня
- Отдано трафика сегодня
+ Отправлено сегодня
Всего загружено
@@ -214,13 +214,13 @@
Ядро успешно загружено
- Не удалось импортировать содержимое подписки
+ Не удалось импортировать подписку
Содержимое подписки успешно импортировано
- Нет установлены подписки
+ Нет установленных подписок
Парсинг {0} прошел успешно
@@ -235,7 +235,7 @@
Некорректное содержимое подписки
- распаковывается...
+ Распаковка…
Обновление подписки закончено
@@ -244,37 +244,37 @@
Обновление подписки начинается
- Успешное обновление ядра
+ Ядро успешно обновлено
Успешное обновление ядра! Перезапуск службы...
- Не является протоколом Vmess или SS
+ Не является протоколом VMess или Shadowsocks
- Файл Core (имя файла: {1}) не найден в папке ({0}), загрузите и поместите его в папку, адрес загрузки: {2}
+ Файл ядра ({1}) не найден в папке {0}. Скачайте по адресу {2} и поместите его туда
Сканирование завершено, не найден корректный QR код
- операция безуспешна, проверьте и попробуйте ещё раз
+ Операция безуспешна, проверьте и попробуйте ещё раз
- Пожалуйста, заполните примечания
+ Введите примечания
- Пожалуйста, выберите метод шифрования
+ Выберите метод шифрования
- Пожалуйста, выберите протокол
+ Выберите протокол
Сначала выберите сервер
- Удаление дублей завершено. Старая: {0}, Новая: {1}.
+ Удаление дублей завершено. Старая: {0}, Новая: {1}
Вы уверены, что хотите удалить сервер?
@@ -286,16 +286,16 @@
Запуск сервиса ({0})...
- Конфигурация успешна {0}
+ Конфигурация выполнена успешно {0}
- Пользовательский сервер конфигурации успешно импортирован.
+ Пользовательская конфигурация сервера успешно импортирована
- {0} серверов импортировано из буфера обмена.
+ {0} серверов импортировано из буфера обмена
- Сканирование URL-адреса импорта успешна.
+ Сканирование URL-адреса импорта прошло успешно
Задержка текущего сервера: {0} мс, {1}
@@ -310,7 +310,7 @@
Вы уверены, что хотите удалить правила?
- {0}, Один из обязательных..
+ {0}: одно из обязательных полей
Примечания
@@ -322,13 +322,13 @@
Количество
- Пожалуйста, заполните адрес (Url)
+ Введите URL-адрес
- Вы хотите добавить правила? Выберите «Да», чтобы добавить, выберите иное, чтобы заменить
+ Хотите добавить правила? Выберите «Да» для добавления или «Нет» для замены
- Загрузка GeoFile: {0} успешна
+ Загрузка GeoFile {0} прошла успешно
Информация
@@ -337,49 +337,49 @@
Пользовательская иконка
- Пожалуйста, заполните правильный пользовательский DNS
+ Введите корректный пользовательский DNS
- *ws путь
+ *WebSocket-путь
- *h2 путь
+ *HTTP2-путь
- *QUIC ключ/Kcp seed
+ *QUIC-ключ / KCP-seed
- *grpc serviceName
+ Имя сервиса *gRPC
- *http хосты разделенные запятыми (,)
+ *http-хосты, разделённые запятыми (,)
- *ws хост
+ *WebSocket-хост
- *h2 хосты разделенные запятыми (,)
+ *HTTP2-хосты, разделённые запятыми (,)
- * безопасность QUIC
+ Безопасность *QUIC
- * тип TCP камуфляжа
+ Тип *TCP-камуфляжа
- * тип KCP камуфляжа
+ Тип *KCP-камуфляжа
- * тип QUIC камуфляжа
+ Тип *QUIC-камуфляжа
- * режим grpc
+ Режим *gRPC
TLS
- *Kcp seed
+ *KCP-seed
Не удалось зарегистрировать глобальную горячую клавишу {0}, причина: {1}
@@ -391,10 +391,10 @@
Разгруппировано
- Все сервера
+ Все серверы
- Пожалуйста, просмотрите, чтобы импортировать конфигурацию сервера
+ Выберите файл конфигурации сервера для импорта
Тестирование...
@@ -436,7 +436,7 @@
Настройки маршрутизации
- Сервера
+ Серверы
Настройки
@@ -445,7 +445,7 @@
Обновить текущую подписку без прокси
- Обновить текущую подписку с прокси
+ Обновить подписку через прокси
Группа подписки
@@ -571,7 +571,7 @@
Сортировка
- User Agent
+ Заголовок User-Agent
Отмена
@@ -628,7 +628,7 @@
TLS
- * По-умолчанию TCP
+ *По-умолчанию TCP
Ядро
@@ -658,10 +658,10 @@
Шифрования
- txtPreSocksPort
+ Порт SOCKS
- * После установки этого значения служба socks будет запущена с использованием Xray/sing-box(Tun) для обеспечения таких функций, как отображение скорости
+ * После установки этого значения служба SOCKS будет запущена с использованием Xray/sing-box(TUN) для обеспечения таких функций, как отображение скорости
Просмотр
@@ -697,7 +697,7 @@
Разрешить небезопасные
- Outbound Freedom domainStrategy
+ «Freedom»: стратегия обработки доменов исходящего трафика
Автоматически регулировать ширину столбца после обновления подписки
@@ -712,7 +712,7 @@
Исключение. Не используйте прокси-сервер для адресов, начинающихся с (,), используйте точку с запятой (;)
- Display real-time speed
+ Показывать скорость в реальном времени
Сохранить старые при удалении дублей
@@ -721,10 +721,10 @@
Записывать логи
- Уровень логгирования
+ Уровень записи логов
- Включите мультиплексирование Mux
+ Включить мультиплексирование Mux
Настройки v2rayN
@@ -733,16 +733,16 @@
Пароль аутентификации
- Пользовательский DNS (если несколько делите с запятыми (,))
+ Пользовательский DNS (если несколько, то делите запятыми (,))
- Set Win10 UWP Loopback
+ Разрешить loopback для приложений UWP (Win10)
Включить сниффинг
- Mixed Port
+ Смешанный порт
Автозапуск
@@ -751,7 +751,7 @@
Включить статистику (требуется перезагрузка)
- URL-адрес конверсии подписки
+ URL конвертации подписок
Настройки системного прокси
@@ -766,7 +766,7 @@
Включить UDP
- Auth user
+ Имя пользователя (логин)
Очистить системный прокси
@@ -816,6 +816,9 @@
Вверх (U)
+
+ Переместить вверх/вниз
+
Фильтр, поддерживает regex
@@ -850,13 +853,13 @@
2.Прямой домен или IP
- 1.Прокси-домен или IP
+ 1.Прокси домен или IP
Предустановленный список наборов правил
- * Установите правила, разделенные запятыми (,); Запятая в регулярке заменена на <COMMA>
+ *Разделяйте правила запятыми (,). Литерал «,» — <COMMA>. Префикс # — отключить правило
Импорт правил из буфера обмена
@@ -883,16 +886,16 @@
Удалить правила (Delete)
- RoutingRuleDetailsSetting
+ Детальные настройки правил маршрутизации
Домен и IP автоматически сортируются при сохранении
- Ruleobject Doc
+ Документация RuleObject
- Поддержка DnsObject
+ Поддерживаются DNS-объекты, нажмите для просмотра документации
Необязательное поле
@@ -913,16 +916,16 @@
Тест задержки и скорости всех серверов (Ctrl+E)
- Задержка (ms)
+ Задержка (мс)
- Скорость (M/s)
+ Скорость (МБ/с)
Не удалось запустить ядро, посмотрите логи
- Remarks regular filter
+ Фильтр примечаний (Regex)
Показать логи
@@ -934,7 +937,7 @@
Новый порт для локальной сети
- Настройки TunMode
+ Настройки режима TUN
Перейти в группу
@@ -958,22 +961,22 @@
Тест завершен
- TLS отпечаток по умлочанию
+ TLS отпечаток по умолчанию
User-Agent
- Этот параметр действителен только для TCP/HTTP и WS
+ Параметр действует только для TCP/HTTP и WebSocket (WS)
Шрифт (требуется перезагрузка)
- Скопируйте файл шрифта TTF/TTC в каталог guiFonts, перезапустите настройки
+ Скопируйте файл шрифта TTF/TTC в каталог guiFonts и заново откройте окно настроек
- Pac порт = +3; Xray API порт = +4; mihomo API порт = +5;
+ Pac порт = +3,Xray API порт = +4, mihomo API порт = +5
Установите это с правами администратора
@@ -982,13 +985,10 @@
Размер шрифта
- Таймаут одиночного спидтеста
+ Тайм-аут одиночного тестирования скорости
- URL спидтеста
-
-
- Move up and down
+ URL для тестирования скорости
PublicKey
@@ -1003,19 +1003,19 @@
Включить аппаратное ускорение (требуется перезагрузка)
- Ожидание тестирования (нажмите ESC для отмены)...
+ Ожидание тестирования (нажмите ESC для отмены)…
- Please turn off when there is an abnormal disconnection
+ Отключите при аномальном разрыве соединения
- Updates are not enabled, skip this subscription
+ Обновления не включены — подписка пропущена
Перезагрузить как администратор
- More URLs, separated by commas; Subscription conversion will be invalid
+ Дополнительные URL через запятую, конвертация подписки недоступна
{0} : {1}/s↑ | {2}/s↓
@@ -1024,13 +1024,13 @@
Интервал автоматического обновления в минутах
- Включить логгирование в файл
+ Включить запись логов в файл
Преобразовать тип цели
- Если преобразование не требуется, оставьте поле пустым.
+ Если преобразование не требуется, оставьте поле пустым
Настройки DNS
@@ -1039,7 +1039,7 @@
Настройки DNS sing-box
- Пожалуйста, заполните структуру DNS. Нажмите, чтобы просмотреть документ.
+ Заполните структуру DNS, нажмите, чтобы открыть документ
Нажмите, чтобы импортировать конфигурацию DNS по умолчанию
@@ -1048,88 +1048,88 @@
Стратегия домена для sing-box
- sing-box Mux Protocol
+ Протокол Mux для sing-box
- Full process name (Tun mode)
+ Полное имя процесса (режим TUN)
- IP or IP CIDR
+ IP-адрес или сеть CIDR
Домен
- Добавить [Hysteria2] сервер
+ Добавить сервер [Hysteria2]
- Hysteria Max bandwidth (Up/Dw)
+ Максимальная пропускная способность Hysteria (загрузка/отдача)
Использовать системные узлы
- Добавить [TUIC] сервер
+ Добавить сервер [TUIC]
Контроль перегрузок
- Previous proxy remarks
+ Примечания к предыдущему прокси
- Next proxy remarks
+ Примечания к следующему прокси
- Пожалуйста, убедитесь, что примечание существует и является уникальным.
+ Убедитесь, что примечание существует и является уникальным
- Enable additional Inbound
+ Включить дополнительный входящий канал
Включить IPv6 адреса
- Добавить [WireGuard] сервер
+ Добавить сервер [WireGuard]
- PrivateKey
+ Приватный ключ
- Reserved(2,3,4)
+ Зарезервировано (2, 3, 4)
- Адрес(Ipv4,Ipv6)
+ Адрес (Ipv4,Ipv6)
- obfs password
+ Пароль obfs
- (Domain or IP or ProcName) and Port and Protocol and InboundTag => OutboundTag
+ (Домен или IP или имя процесса) и порт, и протокол, и InboundTag => OutboundTag
Автоматическая прокрутка в конец
- URL-адрес для проверки скорости пинга
+ URL для быстрой проверки реальной задержки
- Updating subscription, only determine remarks exists
+ Обновляя подписку, проверять лишь наличие примечаний
Отмена тестирования...
- *grpc Authority
+ *gRPC Authority
- Добавить [HTTP] сервер
+ Добавить сервер [HTTP]
- Use Xray and enable non-Tun mode, which conflicts with the group previous proxy
+ Используйте Xray и отключите режим TUN, так как он конфликтует с предыдущим прокси-сервером группы
- Включить фрагмент
+ Включить фрагментацию (Fragment)
Включить файл кэша для sing-box (файлы наборов правил)
@@ -1138,7 +1138,7 @@
Пользовательский набор правил для sing-box
- Successful operation. Click the settings menu to reboot the app.
+ Операция успешна. Перезапустите приложение
Открыть место хранения
@@ -1147,7 +1147,7 @@
Сортировка
- Chain
+ Цепочка
По умолчанию
@@ -1159,7 +1159,7 @@
Скорость загрузки
- Download Traffic
+ Скачанный трафик
Узел
@@ -1177,10 +1177,10 @@
Тип
- Скорость загрузки
+ Скорость отдачи
- Upload Traffic
+ Отправленный трафик
Соединения
@@ -1198,13 +1198,13 @@
Режим правила
- Direct
+ Прямое соединение
- Global
+ Глобальный режим
- Do not change
+ Не менять
Правила
@@ -1213,13 +1213,13 @@
Тест задержки
- Part Node Latency Test
+ Тест задержки выбранных узлов
Обновить прокси
- Активировать узел (Enter)
+ Сделать узел активным (Enter)
Стратегия домена по умолчанию для исходящих
@@ -1234,7 +1234,7 @@
Автоматическая регулировка ширины столбца
- Export Base64-encoded Share Links to Clipboard
+ Экспорт ссылок в формате Base64 в буфер обмена
Экспортировать выбранный сервер для полной конфигурации в буфер обмена
@@ -1243,7 +1243,7 @@
Показать или скрыть главное окно
- Пользовательская конфигурация порта socks
+ Пользовательская конфигурация порта SOCKS
Резервное копирование и восстановление
@@ -1255,28 +1255,28 @@
Восстановить из файла
- Backup to remote (WebDAV)
+ Резервное копирование на удалённый сервер (WebDAV)
- Restore from remote (WebDAV)
+ Восстановить с удалённого сервера (WebDAV)
- Local
+ Локально
- Remote (WebDAV)
+ Удалённо (WebDAV)
- WebDav Url
+ URL WebDAV
- WebDav User Name
+ Имя пользователя WebDAV
- WebDav Password
+ Пароль WebDAV
- WebDav Check
+ Проверить WebDAV
Имя удаленной папки (необязательно)
@@ -1285,16 +1285,16 @@
Неверный файл резервной копии
- Host filter
+ Фильтр хостов
- Active
+ Активный
- Источник geo файлов
+ Источник файлов Geo (необязательно)
- Источник sing-box srs файлов
+ Источник файлов наборов правил sing-box (необязательно)
Программы для обновления не существует
@@ -1315,7 +1315,7 @@
Иран
- Используйте Настройки -> Региональные пресеты вместо изменения этого поля
+ Пользователи из Китая могут пропустить этот пункт
Сканировать QR-код с изображения
@@ -1324,7 +1324,7 @@
Неверный адрес (Url)
- Пожалуйста, не используйте небезопасный адрес подписки по протоколу HTTP.
+ Не используйте небезопасный адрес подписки по протоколу HTTP
Установите шрифт в систему и перезапустите настройки
@@ -1333,43 +1333,43 @@
Вы уверены, что хотите выйти?
- Remarks Memo
+ Заметка (Memo)
- System sudo password
+ Пароль sudo системы
- The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.
+ Введенный вами пароль не может быть подтвержден, поэтому убедитесь, что вы ввели его правильно. Если приложение не работает должным образом из-за неправильного ввода, то перезапустите его. Пароль не будет сохранен, и вам придется вводить его заново после каждого перезапуска
- Please set the sudo password in Tun mode settings first
+ Сначала задайте пароль sudo в настройках TUN-режима
- Пожалуйста, не запускайте программу как суперпользователь.
+ Не запускайте программу как суперпользователь
- *xhttp mode
+ *XHTTP-режим
- XHTTP Extra raw JSON, format: { XHTTPObject }
+ Дополнительный XHTTP сырой JSON, формат: { XHTTPObject }
Скрыть в трее при закрытии окна
- The number of concurrent during multi-test
+ Количество одновременно выполняемых тестов при многоэтапном тестировании
Исключение. Не используйте прокси-сервер для адресов с запятой (,)
- Sniffing type
+ Тип сниффинга
- Enable second mixed port
+ Включить второй смешанный порт
- socks: local port, socks2: second local port, socks3: LAN port
+ socks: локальный порт, socks2: второй локальный порт, socks3: LAN порт
Темы
@@ -1378,7 +1378,7 @@
Копировать команду прокси в буфер обмена
- Starting retesting failed parts, {0} remaining. Press ESC to terminate...
+ Повторное тестирование неудачных элементов, осталось {0}. Нажмите ESC для остановки…
По результату теста
@@ -1387,36 +1387,36 @@
Удалить недействительные по результатам теста
- Удалено {0} недействительных.
+ Удалено {0} недействительных
Диапазон портов сервера
- Will cover the port, separate with commas (,)
+ Заменит указанный порт, перечисляйте через запятую (,)
- Multi-server to custom configuration
+ От мультиконфигурации к пользовательской конфигурации
- Multi-server Random by Xray
+ Случайный (Xray)
- Multi-server RoundRobin by Xray
+ Круговой (Xray)
- Multi-server LeastPing by Xray
+ Минимальное RTT (минимальное время туда-обратно) (Xray)
- Multi-server LeastLoad by Xray
+ Минимальная нагрузка (Xray)
- Multi-server LeastPing by sing-box
+ Минимальное RTT (минимальное время туда-обратно) (sing-box)
- Export server
+ Экспортировать конфигурацию
- Current connection info test URL
+ URL для тестирования текущего соединения
-
\ No newline at end of file
+
From 9985b68b6b6a1fe5ca58214f361b60cdf97f1c00 Mon Sep 17 00:00:00 2001
From: duolaameng <67215517+1411430556@users.noreply.github.com>
Date: Wed, 28 May 2025 20:04:12 +0800
Subject: [PATCH 38/39] Update LICENSE (#7327)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
完善版权信息:项目名称、时间、作者
---
LICENSE | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/LICENSE b/LICENSE
index 94a9ed02..bfbc868f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
- Copyright (C)
+ Copyright (C) 2019-Present 2dust
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
- Copyright (C)
+ v2rayN Copyright (C) 2019-Present 2dust
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
From 87f7e650762a4cddcb9f51d23795e0ed7bcd8315 Mon Sep 17 00:00:00 2001
From: Miheichev Aleksandr Sergeevich
Date: Mon, 2 Jun 2025 04:52:49 +0300
Subject: [PATCH 39/39] docs: improve README.md formatting and readability
(#7376)
- Split long line for better readability
- Add consistent spacing between sections
- Remove extra blank lines
- Update sing-box link to point to main repo instead of releases
---
README.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 9ece02d5..4d728c9b 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,18 @@
# v2rayN
-A GUI client for Windows, Linux and macOS, support [Xray](https://github.com/XTLS/Xray-core) and [sing-box](https://github.com/SagerNet/sing-box/releases) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
+A GUI client for Windows, Linux and macOS, support [Xray](https://github.com/XTLS/Xray-core)
+and [sing-box](https://github.com/SagerNet/sing-box)
+and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
[](https://github.com/2dust/v2rayN/commits/master)
[](https://www.codefactor.io/repository/github/2dust/v2rayn)
[](https://github.com/2dust/v2rayN/releases)
[](https://t.me/v2rayn)
-
## How to use
Read the [Wiki](https://github.com/2dust/v2rayN/wiki) for details.
## Telegram Channel
+
[github_2dust](https://t.me/github_2dust)