Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
072f773245 | ||
|
|
0086f65a96 | ||
|
|
281f14f47e | ||
|
|
9fd20ff001 | ||
|
|
7df90a6034 | ||
|
|
019869ec28 | ||
|
|
b7f4fd7469 | ||
|
|
1273d2aee1 | ||
|
|
88990b4828 | ||
|
|
2f02c2970c | ||
|
|
ade789c6d4 | ||
|
|
9738f90970 | ||
|
|
6ed0741339 | ||
|
|
e6b1e22245 | ||
|
|
6b922be0c6 | ||
|
|
6e35a260e8 | ||
|
|
1106fd8cf1 | ||
|
|
fb92b90d5c | ||
|
|
5effbee50b | ||
|
|
9bc50a9f34 | ||
|
|
2a5a339c27 | ||
|
|
78d182fff3 | ||
|
|
0efb0b5e3e | ||
|
|
a2e8755730 | ||
|
|
06ddedbc4c | ||
|
|
fa148cdf42 |
@@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,40 +37,41 @@ namespace ServiceLib.Common
|
|||||||
foreach (var filePath in files)
|
foreach (var filePath in files)
|
||||||
{
|
{
|
||||||
var file = new FileInfo(filePath);
|
var file = new FileInfo(filePath);
|
||||||
if (file.CreationTime < now)
|
if (file.CreationTime >= now) continue;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
file.Delete();
|
||||||
{
|
}
|
||||||
file.Delete();
|
catch
|
||||||
}
|
{
|
||||||
catch { }
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveLog(string strContent)
|
public static void SaveLog(string strContent)
|
||||||
{
|
{
|
||||||
if (LogManager.IsLoggingEnabled())
|
if (!LogManager.IsLoggingEnabled()) return;
|
||||||
{
|
|
||||||
var logger = LogManager.GetLogger("Log1");
|
LogManager.GetLogger("Log1").Info(strContent);
|
||||||
logger.Info(strContent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveLog(string strTitle, Exception ex)
|
public static void SaveLog(string strTitle, Exception ex)
|
||||||
{
|
{
|
||||||
if (LogManager.IsLoggingEnabled())
|
if (!LogManager.IsLoggingEnabled()) return;
|
||||||
|
|
||||||
|
var logger = LogManager.GetLogger("Log2");
|
||||||
|
logger.Debug($"{strTitle},{ex.Message}");
|
||||||
|
logger.Debug(ex.StackTrace);
|
||||||
|
if (ex?.InnerException != null)
|
||||||
{
|
{
|
||||||
var logger = LogManager.GetLogger("Log2");
|
logger.Error(ex.InnerException);
|
||||||
logger.Debug($"{strTitle},{ex.Message}");
|
|
||||||
logger.Debug(ex.StackTrace);
|
|
||||||
if (ex?.InnerException != null)
|
|
||||||
{
|
|
||||||
logger.Error(ex.InnerException);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
Shutdown,
|
Shutdown,
|
||||||
BrowseServer,
|
BrowseServer,
|
||||||
ImportRulesFromFile,
|
ImportRulesFromFile,
|
||||||
|
InitSettingFont,
|
||||||
SubEditWindow,
|
SubEditWindow,
|
||||||
RoutingRuleSettingWindow,
|
RoutingRuleSettingWindow,
|
||||||
RoutingRuleDetailsWindow,
|
RoutingRuleDetailsWindow,
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
public bool InitComponents()
|
public bool InitComponents()
|
||||||
{
|
{
|
||||||
Logging.Setup();
|
Logging.Setup();
|
||||||
Logging.LoggingEnabled(true);
|
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
|
||||||
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
||||||
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
||||||
Logging.ClearLogs();
|
Logging.ClearLogs();
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 )");
|
||||||
|
|||||||
@@ -88,6 +88,8 @@
|
|||||||
public int TrayMenuServersLimit { get; set; } = 20;
|
public int TrayMenuServersLimit { get; set; } = 20;
|
||||||
|
|
||||||
public bool EnableHWA { get; set; } = false;
|
public bool EnableHWA { get; set; } = false;
|
||||||
|
|
||||||
|
public bool EnableLog { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|||||||
27
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
27
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -42,15 +42,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "代理GFW",
|
"remarks": "代理IP",
|
||||||
"outboundTag": "proxy",
|
|
||||||
"domain": [
|
|
||||||
"geosite:gfw",
|
|
||||||
"geosite:greatfire"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"remarks": "代理Google等",
|
|
||||||
"outboundTag": "proxy",
|
"outboundTag": "proxy",
|
||||||
"ip": [
|
"ip": [
|
||||||
"1.0.0.1",
|
"1.0.0.1",
|
||||||
@@ -65,6 +57,14 @@
|
|||||||
"geoip:twitter"
|
"geoip:twitter"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"remarks": "代理GFW",
|
||||||
|
"outboundTag": "proxy",
|
||||||
|
"domain": [
|
||||||
|
"geosite:gfw",
|
||||||
|
"geosite:greatfire"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"remarks": "最终直连",
|
"remarks": "最终直连",
|
||||||
"port": "0-65535",
|
"port": "0-65535",
|
||||||
|
|||||||
@@ -34,19 +34,6 @@
|
|||||||
"geosite:private"
|
"geosite:private"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"remarks": "绕过中国域名",
|
|
||||||
"outboundTag": "direct",
|
|
||||||
"domain": [
|
|
||||||
"domain:dns.alidns.com",
|
|
||||||
"domain:doh.pub",
|
|
||||||
"domain:dot.pub",
|
|
||||||
"domain:doh.360.cn",
|
|
||||||
"domain:dot.360.cn",
|
|
||||||
"geosite:cn",
|
|
||||||
"geosite:geolocation-cn"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"remarks": "绕过中国IP",
|
"remarks": "绕过中国IP",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "direct",
|
||||||
@@ -73,6 +60,19 @@
|
|||||||
"geoip:cn"
|
"geoip:cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"remarks": "绕过中国域名",
|
||||||
|
"outboundTag": "direct",
|
||||||
|
"domain": [
|
||||||
|
"domain:dns.alidns.com",
|
||||||
|
"domain:doh.pub",
|
||||||
|
"domain:dot.pub",
|
||||||
|
"domain:doh.360.cn",
|
||||||
|
"domain:dot.360.cn",
|
||||||
|
"geosite:cn",
|
||||||
|
"geosite:geolocation-cn"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"remarks": "最终代理",
|
"remarks": "最终代理",
|
||||||
"port": "0-65535",
|
"port": "0-65535",
|
||||||
|
|||||||
@@ -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.4</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="16.1.3" />
|
<PackageReference Include="YamlDotNet" Version="16.1.3" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageReference Include="CliWrap" Version="3.6.6" />
|
<PackageReference Include="CliWrap" Version="3.6.7" />
|
||||||
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
||||||
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ namespace ServiceLib.Services
|
|||||||
_updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
|
_updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
|
||||||
var subItem = await AppHandler.Instance.SubItems();
|
var subItem = await AppHandler.Instance.SubItems();
|
||||||
|
|
||||||
if (subItem == null || subItem.Count <= 0)
|
if (subItem is not { Count: > 0 })
|
||||||
{
|
{
|
||||||
_updateFunc?.Invoke(false, ResUI.MsgNoValidSubscription);
|
_updateFunc?.Invoke(false, ResUI.MsgNoValidSubscription);
|
||||||
return;
|
return;
|
||||||
@@ -122,10 +122,10 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
foreach (var item in subItem)
|
foreach (var item in subItem)
|
||||||
{
|
{
|
||||||
string id = item.Id.TrimEx();
|
var id = item.Id.TrimEx();
|
||||||
string url = item.Url.TrimEx();
|
var url = item.Url.TrimEx();
|
||||||
string userAgent = item.UserAgent.TrimEx();
|
var userAgent = item.UserAgent.TrimEx();
|
||||||
string hashCode = $"{item.Remarks}->";
|
var hashCode = $"{item.Remarks}->";
|
||||||
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || Utils.IsNotEmpty(subId) && item.Id != subId)
|
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || Utils.IsNotEmpty(subId) && item.Id != subId)
|
||||||
{
|
{
|
||||||
//_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
|
//_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
|
||||||
@@ -219,7 +219,7 @@ namespace ServiceLib.Services
|
|||||||
_updateFunc?.Invoke(false, $"{hashCode}{result}");
|
_updateFunc?.Invoke(false, $"{hashCode}{result}");
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = await ConfigHandler.AddBatchServers(config, result, id, true);
|
var ret = await ConfigHandler.AddBatchServers(config, result, id, true);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("FailedImportSubscription");
|
Logging.SaveLog("FailedImportSubscription");
|
||||||
@@ -231,6 +231,8 @@ namespace ServiceLib.Services
|
|||||||
: $"{hashCode}{ResUI.MsgFailedImportSubscription}");
|
: $"{hashCode}{ResUI.MsgFailedImportSubscription}");
|
||||||
}
|
}
|
||||||
_updateFunc?.Invoke(false, "-------------------------------------------------------");
|
_updateFunc?.Invoke(false, "-------------------------------------------------------");
|
||||||
|
|
||||||
|
await ConfigHandler.DedupServerList(config, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateFunc?.Invoke(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
|
_updateFunc?.Invoke(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
|
||||||
@@ -309,10 +311,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,8 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Notifications;
|
||||||
|
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 +12,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 +29,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 +39,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 +90,54 @@ 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<ContextMenu>(),
|
||||||
|
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<ContextMenu>(),
|
||||||
menuStyle.Add(new Setter()
|
x.OfType<DataGridRow>(),
|
||||||
|
x.OfType<ListBoxItem>(),
|
||||||
|
x.OfType<WindowNotificationManager>()
|
||||||
|
));
|
||||||
|
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>
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.4" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.4" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.4" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.4" />
|
||||||
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
||||||
<PackageReference Include="MessageBox.Avalonia" Version="3.1.6.13" />
|
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||||
<PackageReference Include="Semi.Avalonia" Version="11.1.0.4" />
|
<PackageReference Include="Semi.Avalonia" Version="11.1.0.4" />
|
||||||
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.1.0.4" />
|
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.1.0.4" />
|
||||||
<PackageReference Include="ReactiveUI" Version="20.1.63" />
|
<PackageReference Include="ReactiveUI" Version="20.1.63" />
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user