Compare commits

...

21 Commits

Author SHA1 Message Date
2dust 019869ec28 up 7.0.3 2024-10-27 15:01:14 +08:00
2dust b7f4fd7469 Add font settings for Desktop 2024-10-27 14:59:06 +08:00
2dust 1273d2aee1 Improved font settings 2024-10-27 14:57:45 +08:00
2dust 88990b4828 Bug fix
0efb0b5e3e
2024-10-26 18:00:22 +08:00
2dust 2f02c2970c UseShellExecute = true 2024-10-26 17:55:36 +08:00
2dust ade789c6d4 Update UpgradeApp.cs 2024-10-26 17:55:08 +08:00
2dust 9738f90970 up 7.0.2 2024-10-26 15:00:57 +08:00
2dust 6ed0741339 Bug fix
https://github.com/2dust/v2rayN/issues/5923
2024-10-26 14:57:28 +08:00
2dust e6b1e22245 Update UpgradeApp.cs 2024-10-26 14:42:58 +08:00
2dust 6b922be0c6 Set AssemblyName to v2rayN 2024-10-26 10:42:29 +08:00
2dust 6e35a260e8 Bug fix
https://github.com/2dust/v2rayN/issues/5915
2024-10-26 09:55:22 +08:00
2dust 1106fd8cf1 Give upgrade app execute permission at runtime 2024-10-25 20:32:47 +08:00
2dust fb92b90d5c Bug fix
https://github.com/2dust/v2rayN/issues/5909
2024-10-25 17:58:54 +08:00
2dust 5effbee50b Fix
https://github.com/2dust/v2rayN/issues/5905
2024-10-25 17:41:01 +08:00
2dust 9bc50a9f34 up 7.0.1 2024-10-25 13:50:17 +08:00
2dust 2a5a339c27 Update UpgradeApp.cs 2024-10-25 11:56:15 +08:00
2dust 78d182fff3 Add a warning about the use of insecure HTTP protocol subscription address 2024-10-25 11:06:04 +08:00
2dust 0efb0b5e3e Give core execute permission at runtime 2024-10-25 10:10:55 +08:00
2dust a2e8755730 Xray Asset Location use XRAY_LOCATION_ASSET 2024-10-25 09:31:16 +08:00
2dust 06ddedbc4c The core folder is all lowercase letters 2024-10-25 09:27:11 +08:00
2dust fa148cdf42 Bug fix 2024-10-25 09:01:59 +08:00
28 changed files with 320 additions and 246 deletions
+18 -32
View File
@@ -1,6 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.IO.Compression; using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace AmazTool namespace AmazTool
@@ -12,7 +11,7 @@ namespace AmazTool
Console.WriteLine(fileName); Console.WriteLine(fileName);
Console.WriteLine("In progress, please wait...(正在进行中,请等待)"); Console.WriteLine("In progress, please wait...(正在进行中,请等待)");
Thread.Sleep(5000); Thread.Sleep(9000);
if (!File.Exists(fileName)) if (!File.Exists(fileName))
{ {
@@ -20,18 +19,15 @@ namespace AmazTool
return; return;
} }
Console.WriteLine("Try to end the process(尝试结束进程).");
try try
{ {
Process[] existing = Process.GetProcessesByName(V2rayN()); var path = GetPath(V2rayN);
foreach (Process p in existing) Console.WriteLine(path);
{ var existing = Process.GetProcessesByName(V2rayN);
var path = p.MainModule?.FileName ?? ""; var pp = existing.FirstOrDefault(p => p.MainModule?.FileName != null && p.MainModule?.FileName.Contains(path) == true);
if (path.StartsWith(GetPath(V2rayN()))) pp?.Kill();
{ pp?.WaitForExit(1000);
p.Kill();
p.WaitForExit(100);
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -40,6 +36,7 @@ namespace AmazTool
"Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN,否则可能升级失败。\n\n" + ex.StackTrace); "Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN,否则可能升级失败。\n\n" + ex.StackTrace);
} }
Console.WriteLine("Start extracting files(开始解压文件).");
StringBuilder sb = new(); StringBuilder sb = new();
try try
{ {
@@ -57,6 +54,8 @@ namespace AmazTool
continue; continue;
} }
Console.WriteLine(entry.FullName);
var lst = entry.FullName.Split(splitKey); var lst = entry.FullName.Split(splitKey);
if (lst.Length == 1) continue; if (lst.Length == 1) continue;
string fullName = string.Join(splitKey, lst[1..lst.Length]); string fullName = string.Join(splitKey, lst[1..lst.Length]);
@@ -81,22 +80,22 @@ namespace AmazTool
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine("Upgrade Failed(升级失败)." + ex.StackTrace); Console.WriteLine("Upgrade Failed(升级失败)." + ex.StackTrace);
return; //return;
} }
if (sb.Length > 0) if (sb.Length > 0)
{ {
Console.WriteLine("Upgrade Failed.\n" + Console.WriteLine("Upgrade Failed(升级失败)." + sb.ToString());
"(升级失败)." + sb.ToString()); //return;
return;
} }
Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)"); Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)");
Thread.Sleep(3000); Thread.Sleep(9000);
Process process = new() Process process = new()
{ {
StartInfo = new() StartInfo = new()
{ {
FileName = V2rayN(), UseShellExecute = true,
FileName = V2rayN,
WorkingDirectory = StartupPath() WorkingDirectory = StartupPath()
} }
}; };
@@ -123,19 +122,6 @@ namespace AmazTool
return Path.Combine(startupPath, fileName); return Path.Combine(startupPath, fileName);
} }
private static string V2rayN() private static string V2rayN => "v2rayN";
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (File.Exists(GetPath("v2rayN.exe")))
return "v2rayN";
else
return "v2rayN.Desktop";
}
else
{
return "v2rayN.Desktop";
}
}
} }
} }
+8 -1
View File
@@ -720,7 +720,7 @@ namespace ServiceLib.Common
} }
if (coreType != null) if (coreType != null)
{ {
tempPath = Path.Combine(tempPath, coreType.ToString()); tempPath = Path.Combine(tempPath, coreType.ToLower().ToString());
if (!Directory.Exists(tempPath)) if (!Directory.Exists(tempPath))
{ {
Directory.CreateDirectory(tempPath); Directory.CreateDirectory(tempPath);
@@ -818,6 +818,13 @@ namespace ServiceLib.Common
return await GetCliWrapOutput("/bin/bash", arg); return await GetCliWrapOutput("/bin/bash", arg);
} }
public static async Task<string?> GetLinuxFontFamily(string lang)
{
// var arg = new List<string>() { "-c", $"fc-list :lang={lang} family" };
var arg = new List<string>() { "-c", $"fc-list : family" };
return await GetCliWrapOutput("/bin/bash", arg);
}
#endregion Platform #endregion Platform
} }
} }
+1
View File
@@ -19,6 +19,7 @@
Shutdown, Shutdown,
BrowseServer, BrowseServer,
ImportRulesFromFile, ImportRulesFromFile,
InitSettingFont,
SubEditWindow, SubEditWindow,
RoutingRuleSettingWindow, RoutingRuleSettingWindow,
RoutingRuleDetailsWindow, RoutingRuleDetailsWindow,
+1 -1
View File
@@ -159,7 +159,7 @@
await ConfigHandler.SetDefaultServer(_config, lstModel); await ConfigHandler.SetDefaultServer(_config, lstModel);
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? []; var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = ProfileExHandler.Instance.ProfileExs; var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
lstModel = (from t in lstModel lstModel = (from t in lstModel
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
from t22 in t2b.DefaultIfEmpty() from t22 in t2b.DefaultIfEmpty()
+1 -1
View File
@@ -28,7 +28,7 @@ namespace ServiceLib.Handler
return new Tuple<ClashProxies, ClashProviders>(clashProxies, clashProviders); return new Tuple<ClashProxies, ClashProviders>(clashProxies, clashProviders);
} }
await Task.Delay(5000); await Task.Delay(2000);
} }
return null; return null;
+4 -2
View File
@@ -746,7 +746,7 @@ namespace ServiceLib.Handler
{ {
return -1; return -1;
} }
var lstProfileExs = ProfileExHandler.Instance.ProfileExs; var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
var lstProfile = (from t in lstModel var lstProfile = (from t in lstModel
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty() from t33 in t3b.DefaultIfEmpty()
@@ -1340,7 +1340,9 @@ namespace ServiceLib.Handler
//Do not allow http protocol //Do not allow http protocol
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost)) if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
{ {
return -1; //TODO Temporary reminder to be removed later
NoticeHandler.Instance.Enqueue(ResUI.InsecureUrlProtocol);
//return -1;
} }
var queryVars = Utils.ParseQueryString(uri.Query); var queryVars = Utils.ParseQueryString(uri.Query);
+5 -11
View File
@@ -12,18 +12,12 @@
if (node.ConfigType == EConfigType.Custom) if (node.ConfigType == EConfigType.Custom)
{ {
if (node.CoreType is ECoreType.mihomo) result = node.CoreType switch
{ {
result = await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName); ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName),
} ECoreType.sing_box => await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName),
if (node.CoreType is ECoreType.sing_box) _ => await GenerateClientCustomConfig(node, fileName)
{ };
result = await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName);
}
else
{
result = await GenerateClientCustomConfig(node, fileName);
}
} }
else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box) else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
{ {
+35 -16
View File
@@ -15,13 +15,38 @@ namespace ServiceLib.Handler
private Process? _processPre; private Process? _processPre;
private Action<bool, string>? _updateFunc; private Action<bool, string>? _updateFunc;
public void Init(Config config, Action<bool, string> updateFunc) public async Task Init(Config config, Action<bool, string> updateFunc)
{ {
_config = config; _config = config;
_updateFunc = updateFunc; _updateFunc = updateFunc;
Environment.SetEnvironmentVariable("v2ray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("V2RAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("xray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("XRAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
if (Utils.IsLinux())
{
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
foreach (var it in coreInfo)
{
if (it.CoreType == ECoreType.v2rayN)
{
if (Utils.UpgradeAppExists(out var fileName))
{
await Utils.SetLinuxChmod(fileName);
}
continue;
}
foreach (var name in it.CoreExes)
{
var exe = Utils.GetBinPath(Utils.GetExeName(name), it.CoreType.ToString());
if (File.Exists(exe))
{
await Utils.SetLinuxChmod(exe);
}
}
}
}
} }
public async Task LoadCore(ProfileItem? node) public async Task LoadCore(ProfileItem? node)
@@ -109,17 +134,12 @@ namespace ServiceLib.Handler
{ {
continue; continue;
} }
foreach (string vName in it.CoreExes) foreach (var name in it.CoreExes)
{ {
var existing = Process.GetProcessesByName(vName); var path = Utils.GetBinPath(Utils.GetExeName(name), it.CoreType.ToString());
foreach (Process p in existing) var existing = Process.GetProcessesByName(name);
{ var pp = existing.FirstOrDefault(p => p.MainModule?.FileName != null && p.MainModule?.FileName.Contains(path) == true);
string? path = p.MainModule?.FileName; await KillProcess(pp);
if (path == Utils.GetExeName(Utils.GetBinPath(vName, it.CoreType.ToString())))
{
await KillProcess(p);
}
}
} }
} }
} }
@@ -148,10 +168,9 @@ namespace ServiceLib.Handler
private string CoreFindExe(CoreInfo coreInfo) private string CoreFindExe(CoreInfo coreInfo)
{ {
string fileName = string.Empty; string fileName = string.Empty;
foreach (string name in coreInfo.CoreExes) foreach (var name in coreInfo.CoreExes)
{ {
string vName = Utils.GetExeName(name); var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
vName = Utils.GetBinPath(vName, coreInfo.CoreType.ToString());
if (File.Exists(vName)) if (File.Exists(vName))
{ {
fileName = vName; fileName = vName;
@@ -9,27 +9,31 @@ namespace ServiceLib.Handler
private static readonly Lazy<ProfileExHandler> _instance = new(() => new()); private static readonly Lazy<ProfileExHandler> _instance = new(() => new());
private ConcurrentBag<ProfileExItem> _lstProfileEx = []; private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
private Queue<string> _queIndexIds = new(); private Queue<string> _queIndexIds = new();
public ConcurrentBag<ProfileExItem> ProfileExs => _lstProfileEx;
public static ProfileExHandler Instance => _instance.Value; public static ProfileExHandler Instance => _instance.Value;
public ProfileExHandler() public ProfileExHandler()
{ {
Init(); //Init();
} }
private async Task Init() public async Task Init()
{ {
await InitData(); await InitData();
await Task.Run(async () => Task.Run(async () =>
{ {
while (true) while (true)
{ {
await SaveQueueIndexIds();
await Task.Delay(1000 * 600); await Task.Delay(1000 * 600);
await SaveQueueIndexIds();
} }
}); });
} }
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
{
return _lstProfileEx;
}
private async Task InitData() private async Task InitData()
{ {
await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )"); await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )");
+27
View File
@@ -294,6 +294,24 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Please do not use the insecure HTTP protocol subscription address 的本地化字符串。
/// </summary>
public static string InsecureUrlProtocol {
get {
return ResourceManager.GetString("InsecureUrlProtocol", resourceCulture);
}
}
/// <summary>
/// 查找类似 Invalid address (Url) 的本地化字符串。
/// </summary>
public static string InvalidUrlTip {
get {
return ResourceManager.GetString("InvalidUrlTip", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 {0} {1} already up to date. 的本地化字符串。 /// 查找类似 {0} {1} already up to date. 的本地化字符串。
/// </summary> /// </summary>
@@ -2842,6 +2860,15 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Install the font to the system and restart the settings 的本地化字符串。
/// </summary>
public static string TbSettingsCurrentFontFamilyLinuxTip {
get {
return ResourceManager.GetString("TbSettingsCurrentFontFamilyLinuxTip", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Copy the font TTF/TTC file to the directory guiFonts, restart the settings 的本地化字符串。 /// 查找类似 Copy the font TTF/TTC file to the directory guiFonts, restart the settings 的本地化字符串。
/// </summary> /// </summary>
+9
View File
@@ -1354,4 +1354,13 @@
<data name="menuAddServerViaImage" xml:space="preserve"> <data name="menuAddServerViaImage" xml:space="preserve">
<value>Scan QR code in the image</value> <value>Scan QR code in the image</value>
</data> </data>
<data name="InvalidUrlTip" xml:space="preserve">
<value>Invalid address (Url)</value>
</data>
<data name="InsecureUrlProtocol" xml:space="preserve">
<value>Please do not use the insecure HTTP protocol subscription address</value>
</data>
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
<value>Install the font to the system and restart the settings</value>
</data>
</root> </root>
@@ -1351,4 +1351,13 @@
<data name="menuAddServerViaImage" xml:space="preserve"> <data name="menuAddServerViaImage" xml:space="preserve">
<value>扫描图片中的二维码</value> <value>扫描图片中的二维码</value>
</data> </data>
<data name="InvalidUrlTip" xml:space="preserve">
<value>地址(Url)无效</value>
</data>
<data name="InsecureUrlProtocol" xml:space="preserve">
<value>请不要使用不安全的HTTP协议订阅地址</value>
</data>
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
<value>安装字体到系统中,重启设置</value>
</data>
</root> </root>
@@ -1231,4 +1231,13 @@
<data name="menuAddServerViaImage" xml:space="preserve"> <data name="menuAddServerViaImage" xml:space="preserve">
<value>掃描圖片中的二維碼</value> <value>掃描圖片中的二維碼</value>
</data> </data>
<data name="InvalidUrlTip" xml:space="preserve">
<value>地址(Url)無效</value>
</data>
<data name="InsecureUrlProtocol" xml:space="preserve">
<value>請不要使用不安全的HTTP協定訂閱位址</value>
</data>
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
<value>安裝字體到系統中,重新啟動設定</value>
</data>
</root> </root>
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Version>7.0.0</Version> <Version>7.0.3</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+2 -3
View File
@@ -309,10 +309,9 @@ namespace ServiceLib.Services
{ {
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type); var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
string filePath = string.Empty; string filePath = string.Empty;
foreach (string name in coreInfo.CoreExes) foreach (var name in coreInfo.CoreExes)
{ {
string vName = Utils.GetExeName(name); var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
vName = Utils.GetBinPath(vName, coreInfo.CoreType.ToString());
if (File.Exists(vName)) if (File.Exists(vName))
{ {
filePath = vName; filePath = vName;
@@ -96,7 +96,7 @@ namespace ServiceLib.ViewModels
private async Task Init() private async Task Init()
{ {
await ProxiesReload(); await ProxiesReload();
await DelayTestTask(); DelayTestTask();
} }
private async Task DoRulemodeSelected(bool c) private async Task DoRulemodeSelected(bool c)
@@ -434,25 +434,29 @@ namespace ServiceLib.ViewModels
public async Task DelayTestTask() public async Task DelayTestTask()
{ {
var lastTime = DateTime.Now; var lastTime = DateTime.Now;
Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000 * 60);
Observable.Interval(TimeSpan.FromSeconds(60)) if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
.Subscribe(async x => {
{ continue;
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box))) }
{ if (_config.ClashUIItem.ProxiesAutoDelayTestInterval <= 0)
return; {
} continue;
var dtNow = DateTime.Now; }
if (_config.ClashUIItem.ProxiesAutoDelayTestInterval > 0) var dtNow = DateTime.Now;
{ if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0)
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval == 0) {
{ continue;
await ProxiesDelayTest(); }
lastTime = dtNow; await ProxiesDelayTest();
} lastTime = dtNow;
Task.Delay(1000).Wait(); }
} });
});
} }
#endregion task #endregion task
@@ -208,7 +208,8 @@ namespace ServiceLib.ViewModels
await ConfigHandler.InitBuiltinRouting(_config); await ConfigHandler.InitBuiltinRouting(_config);
await ConfigHandler.InitBuiltinDNS(_config); await ConfigHandler.InitBuiltinDNS(_config);
CoreHandler.Instance.Init(_config, UpdateHandler); await ProfileExHandler.Instance.Init();
await CoreHandler.Instance.Init(_config, UpdateHandler);
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler); TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
if (_config.GuiItem.EnableStatistics) if (_config.GuiItem.EnableStatistics)
@@ -312,6 +313,7 @@ namespace ServiceLib.ViewModels
{ {
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
{ {
UseShellExecute = true,
FileName = fileName, FileName = fileName,
Arguments = arg.AppendQuotes(), Arguments = arg.AppendQuotes(),
WorkingDirectory = Utils.StartupPath() WorkingDirectory = Utils.StartupPath()
@@ -389,6 +391,10 @@ namespace ServiceLib.ViewModels
RefreshServers(); RefreshServers();
NoticeHandler.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret)); NoticeHandler.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));
} }
else
{
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
}
} }
public async Task AddServerViaScanAsync() public async Task AddServerViaScanAsync()
@@ -433,6 +439,10 @@ namespace ServiceLib.ViewModels
RefreshServers(); RefreshServers();
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan); NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan);
} }
else
{
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
}
} }
} }
@@ -117,6 +117,8 @@ namespace ServiceLib.ViewModels
private async Task Init() private async Task Init()
{ {
await _updateView?.Invoke(EViewAction.InitSettingFont, null);
#region Core #region Core
var inbound = _config.Inbound[0]; var inbound = _config.Inbound[0];
@@ -176,13 +176,14 @@ namespace ServiceLib.ViewModels
return; return;
} }
var lst = new List<RulesItem4Ray>(); var lst = new List<RulesItem>();
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
var item = _rules.FirstOrDefault(t => t.Id == it?.Id); var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
if (item != null) if (item != null)
{ {
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.DeepCopy(item); //JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
item2.Id = null;
lst.Add(item2 ?? new()); lst.Add(item2 ?? new());
} }
} }
@@ -104,6 +104,18 @@ namespace ServiceLib.ViewModels
public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
SelectedRouting = new();
SelectedServer = new();
RunningServerToolTipText = "-";
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
{
EnableTun = true;
}
else
{
_config.TunModeItem.EnableTun = EnableTun = false;
}
#region WhenAnyValue && ReactiveCommand #region WhenAnyValue && ReactiveCommand
@@ -179,19 +191,6 @@ namespace ServiceLib.ViewModels
private async Task Init() private async Task Init()
{ {
SelectedRouting = new();
SelectedServer = new();
RunningServerToolTipText = "-";
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
{
EnableTun = true;
}
else
{
_config.TunModeItem.EnableTun = EnableTun = false;
}
await RefreshRoutingsMenu(); await RefreshRoutingsMenu();
await InboundDisplayStatus(); await InboundDisplayStatus();
await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, true); await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, true);
@@ -39,14 +39,14 @@ namespace ServiceLib.ViewModels
var uri = Utils.TryUri(url); var uri = Utils.TryUri(url);
if (uri == null) if (uri == null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.LvUrl); NoticeHandler.Instance.Enqueue(ResUI.InvalidUrlTip);
return; return;
} }
//Do not allow http protocol //Do not allow http protocol
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost)) if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
{ {
NoticeHandler.Instance.Enqueue(ResUI.LvUrl); NoticeHandler.Instance.Enqueue(ResUI.InsecureUrlProtocol);
return; //return;
} }
} }
@@ -1,5 +1,7 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Styling; using Avalonia.Styling;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
@@ -9,14 +11,11 @@ namespace v2rayN.Desktop.ViewModels
{ {
public class ThemeSettingViewModel : MyReactiveObject public class ThemeSettingViewModel : MyReactiveObject
{ {
[Reactive] [Reactive] public bool ColorModeDark { get; set; }
public bool ColorModeDark { get; set; }
[Reactive] [Reactive] public int CurrentFontSize { get; set; }
public int CurrentFontSize { get; set; }
[Reactive] [Reactive] public string CurrentLanguage { get; set; }
public string CurrentLanguage { get; set; }
public ThemeSettingViewModel() public ThemeSettingViewModel()
{ {
@@ -29,6 +28,7 @@ namespace v2rayN.Desktop.ViewModels
private void RestoreUI() private void RestoreUI()
{ {
ModifyTheme(_config.UiItem.ColorModeDark); ModifyTheme(_config.UiItem.ColorModeDark);
ModifyFontFamily();
} }
private void BindingUI() private void BindingUI()
@@ -38,34 +38,34 @@ namespace v2rayN.Desktop.ViewModels
CurrentLanguage = _config.UiItem.CurrentLanguage; CurrentLanguage = _config.UiItem.CurrentLanguage;
this.WhenAnyValue(x => x.ColorModeDark) this.WhenAnyValue(x => x.ColorModeDark)
.Subscribe(c => .Subscribe(c =>
{ {
if (_config.UiItem.ColorModeDark != ColorModeDark) if (_config.UiItem.ColorModeDark != ColorModeDark)
{ {
_config.UiItem.ColorModeDark = ColorModeDark; _config.UiItem.ColorModeDark = ColorModeDark;
ModifyTheme(ColorModeDark); ModifyTheme(ColorModeDark);
ConfigHandler.SaveConfig(_config); ConfigHandler.SaveConfig(_config);
} }
}); });
this.WhenAnyValue( this.WhenAnyValue(
x => x.CurrentFontSize, x => x.CurrentFontSize,
y => y > 0) y => y > 0)
.Subscribe(c => .Subscribe(c =>
{ {
if (CurrentFontSize >= Global.MinFontSize) if (CurrentFontSize >= Global.MinFontSize)
{ {
_config.UiItem.CurrentFontSize = CurrentFontSize; _config.UiItem.CurrentFontSize = CurrentFontSize;
double size = CurrentFontSize; double size = CurrentFontSize;
ModifyFontSize(size); ModifyFontSize(size);
ConfigHandler.SaveConfig(_config); ConfigHandler.SaveConfig(_config);
} }
}); });
this.WhenAnyValue( this.WhenAnyValue(
x => x.CurrentLanguage, x => x.CurrentLanguage,
y => y != null && !y.IsNullOrEmpty()) y => y != null && !y.IsNullOrEmpty())
.Subscribe(c => .Subscribe(c =>
{ {
if (Utils.IsNotEmpty(CurrentLanguage) && _config.UiItem.CurrentLanguage != CurrentLanguage) if (Utils.IsNotEmpty(CurrentLanguage) && _config.UiItem.CurrentLanguage != CurrentLanguage)
@@ -89,53 +89,51 @@ namespace v2rayN.Desktop.ViewModels
private void ModifyFontSize(double size) private void ModifyFontSize(double size)
{ {
Style buttonStyle = new(x => x.OfType<Button>()); Style style = new(x => Selectors.Or(
buttonStyle.Add(new Setter() x.OfType<Button>(),
x.OfType<TextBox>(),
x.OfType<TextBlock>(),
x.OfType<Menu>(),
x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>()
));
style.Add(new Setter()
{ {
Property = Button.FontSizeProperty, Property = TemplatedControl.FontSizeProperty,
Value = size, Value = size,
}); });
Application.Current?.Styles.Add(buttonStyle); Application.Current?.Styles.Add(style);
}
Style textStyle = new(x => x.OfType<TextBox>()); private void ModifyFontFamily()
textStyle.Add(new Setter() {
var currentFontFamily = _config.UiItem.CurrentFontFamily;
if (currentFontFamily.IsNullOrEmpty())
{ {
Property = TextBox.FontSizeProperty, return;
Value = size, }
});
Application.Current?.Styles.Add(textStyle);
Style textBlockStyle = new(x => x.OfType<TextBlock>()); try
textBlockStyle.Add(new Setter()
{ {
Property = TextBlock.FontSizeProperty, Style style = new(x => Selectors.Or(
Value = size, x.OfType<Button>(),
}); x.OfType<TextBox>(),
Application.Current?.Styles.Add(textBlockStyle); x.OfType<TextBlock>(),
x.OfType<Menu>(),
Style menuStyle = new(x => x.OfType<Menu>()); x.OfType<DataGridRow>(),
menuStyle.Add(new Setter() x.OfType<ListBoxItem>()
));
style.Add(new Setter()
{
Property = TemplatedControl.FontFamilyProperty,
Value = new FontFamily(currentFontFamily),
});
Application.Current?.Styles.Add(style);
}
catch (Exception ex)
{ {
Property = Menu.FontSizeProperty, Logging.SaveLog("ModifyFontFamily", ex);
Value = size, }
});
Application.Current?.Styles.Add(menuStyle);
Style dataStyle = new(x => x.OfType<DataGridRow>());
dataStyle.Add(new Setter()
{
Property = DataGridRow.FontSizeProperty,
Value = size,
});
Application.Current?.Styles.Add(dataStyle);
Style listStyle = new(x => x.OfType<ListBoxItem>());
listStyle.Add(new Setter()
{
Property = ListBoxItem.FontSizeProperty,
Value = size,
});
Application.Current?.Styles.Add(listStyle);
} }
} }
} }
@@ -161,10 +161,7 @@
<RowDefinition Height="8" /> <RowDefinition Height="8" />
<RowDefinition Height="1*" /> <RowDefinition Height="1*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock <TextBlock Grid.Row="0" Text="{Binding Name}" />
Grid.Row="0"
Text="{Binding Name}"
TextWrapping="WrapWithOverflow" />
<DockPanel Grid.Row="2"> <DockPanel Grid.Row="2">
<TextBlock <TextBlock
DockPanel.Dock="Right" DockPanel.Dock="Right"
@@ -533,7 +533,6 @@
Grid.Column="0" Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
IsVisible="False"
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamily}" /> Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamily}" />
<ComboBox <ComboBox
x:Name="cmbcurrentFontFamily" x:Name="cmbcurrentFontFamily"
@@ -541,15 +540,13 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Classes="Margin8" Classes="Margin8"
IsVisible="False"
MaxDropDownHeight="1000" /> MaxDropDownHeight="1000" />
<TextBlock <TextBlock
Grid.Row="16" Grid.Row="16"
Grid.Column="2" Grid.Column="2"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
IsVisible="False" Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyLinuxTip}"
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyTip}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
@@ -677,7 +674,6 @@
Classes="Margin8" Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsChinaUserTip}" Text="{x:Static resx:ResUI.TbSettingsChinaUserTip}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>
@@ -15,7 +15,6 @@ namespace v2rayN.Desktop.Views
btnCancel.Click += (s, e) => this.Close(); btnCancel.Click += (s, e) => this.Close();
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
// var lstFonts = GetFonts(Utils.GetFontsPath());
ViewModel = new OptionSettingViewModel(UpdateViewHandler); ViewModel = new OptionSettingViewModel(UpdateViewHandler);
@@ -100,9 +99,6 @@ namespace v2rayN.Desktop.Views
cmbMainGirdOrientation.Items.Add(it.ToString()); cmbMainGirdOrientation.Items.Add(it.ToString());
} }
//lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
//cmbcurrentFontFamily.Items.Add(string.Empty);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
@@ -182,58 +178,53 @@ namespace v2rayN.Desktop.Views
// WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false); // WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false);
this.Close(true); this.Close(true);
break; break;
case EViewAction.InitSettingFont:
await InitSettingFont();
break;
} }
return await Task.FromResult(true); return await Task.FromResult(true);
} }
//private List<string> GetFonts(string path) private async Task InitSettingFont()
//{ {
// var lstFonts = new List<string>(); var lstFonts = await GetFonts();
// try lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
// { cmbcurrentFontFamily.Items.Add(string.Empty);
// string[] searchPatterns = { "*.ttf", "*.ttc" }; }
// var files = new List<string>();
// foreach (var pattern in searchPatterns) private async Task<List<string>> GetFonts()
// { {
// files.AddRange(Directory.GetFiles(path, pattern)); var lstFonts = new List<string>();
// } try
// var culture = _config.uiItem.currentLanguage == Global.Languages[0] ? "zh-cn" : "en-us"; {
// var culture2 = "en-us"; if (Utils.IsWindows())
// foreach (var ttf in files) {
// { return lstFonts;
// var families = Fonts.GetFontFamilies(Utils.GetFontsPath(ttf)); }
// foreach (FontFamily family in families) else if (Utils.IsLinux())
// { {
// var typefaces = family.GetTypefaces(); var result = await Utils.GetLinuxFontFamily("zh");
// foreach (Typeface typeface in typefaces) if (result.IsNullOrEmpty())
// { {
// typeface.TryGetGlyphTypeface(out GlyphTypeface glyph); return lstFonts;
// //var fontFace = glyph.Win32FaceNames[new CultureInfo("en-us")]; }
// //if (!fontFace.Equals("Regular") && !fontFace.Equals("Normal"))
// //{ var lst = result.Split(Environment.NewLine)
// // continue; .Where(t => t.IsNotEmpty())
// //} .ToList()
// var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)]; .Select(t => t.Split(",").FirstOrDefault() ?? "")
// if (Utils.IsNullOrEmpty(fontFamily)) .OrderBy(t => t)
// { .ToList();
// fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)]; return lst;
// if (Utils.IsNullOrEmpty(fontFamily)) }
// { }
// continue; catch (Exception ex)
// } {
// } Logging.SaveLog("fill fonts error", ex);
// lstFonts.Add(fontFamily); }
// break; return lstFonts;
// } }
// }
// }
// }
// catch (Exception ex)
// {
// Logging.SaveLog("fill fonts error", ex);
// }
// return lstFonts;
//}
private void ClbdestOverride_SelectionChanged(object? sender, SelectionChangedEventArgs e) private void ClbdestOverride_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{ {
@@ -8,6 +8,7 @@
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright> <Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<AssemblyName>v2rayN</AssemblyName>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+2
View File
@@ -284,6 +284,8 @@ namespace v2rayN.Views
switch (e.Key) switch (e.Key)
{ {
case Key.V: case Key.V:
if (_backupAndRestoreView?.IsVisible == true) return;
var clipboardData = WindowsUtils.GetClipboardData(); var clipboardData = WindowsUtils.GetClipboardData();
ViewModel?.AddServerViaClipboardAsync(clipboardData); ViewModel?.AddServerViaClipboardAsync(clipboardData);
break; break;
@@ -17,7 +17,6 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow; this.Owner = Application.Current.MainWindow;
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
var lstFonts = GetFonts(Utils.GetFontsPath());
ViewModel = new OptionSettingViewModel(UpdateViewHandler); ViewModel = new OptionSettingViewModel(UpdateViewHandler);
@@ -102,9 +101,6 @@ namespace v2rayN.Views
cmbMainGirdOrientation.Items.Add(it.ToString()); cmbMainGirdOrientation.Items.Add(it.ToString());
} }
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
cmbcurrentFontFamily.Items.Add(string.Empty);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
@@ -191,11 +187,22 @@ namespace v2rayN.Views
WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false); WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false);
this.DialogResult = true; this.DialogResult = true;
break; break;
case EViewAction.InitSettingFont:
await InitSettingFont();
break;
} }
return await Task.FromResult(true); return await Task.FromResult(true);
} }
private List<string> GetFonts(string path) private async Task InitSettingFont()
{
var lstFonts = await GetFonts(Utils.GetFontsPath());
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
cmbcurrentFontFamily.Items.Add(string.Empty);
}
private async Task<List<string>> GetFonts(string path)
{ {
var lstFonts = new List<string>(); var lstFonts = new List<string>();
try try
@@ -241,7 +248,7 @@ namespace v2rayN.Views
{ {
Logging.SaveLog("fill fonts error", ex); Logging.SaveLog("fill fonts error", ex);
} }
return lstFonts; return lstFonts.OrderBy(t => t).ToList();
} }
private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)