Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d1853e991 | ||
|
|
859299c712 | ||
|
|
7fbb0013b0 | ||
|
|
837cfbd03b | ||
|
|
cdc5d72cfa | ||
|
|
8dcf5c5b90 | ||
|
|
67fe6ac3d8 | ||
|
|
438eaba4d5 | ||
|
|
3c8baa99d5 | ||
|
|
e70658f311 | ||
|
|
2dd10cf5a1 | ||
|
|
96781a784b | ||
|
|
9748fbb076 | ||
|
|
aa5e4378ab |
@@ -1,29 +1,39 @@
|
|||||||
namespace AmazTool
|
namespace AmazTool
|
||||||
{
|
{
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 应用程序的主入口点。
|
|
||||||
/// </summary>
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length == 0)
|
if (args.Length == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine(Resx.Resource.Guidelines);
|
Utils.WriteLine(Resx.Resource.Guidelines);
|
||||||
Thread.Sleep(5000);
|
Utils.Waiting(5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var argData = Uri.UnescapeDataString(string.Join(" ", args));
|
var argData = Uri.UnescapeDataString(string.Join(" ", args));
|
||||||
if (argData.Equals("rebootas"))
|
if (argData.Equals("rebootas"))
|
||||||
{
|
{
|
||||||
Thread.Sleep(1000);
|
Utils.Waiting(1);
|
||||||
Utils.StartV2RayN();
|
Utils.StartV2RayN();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpgradeApp.Upgrade(argData);
|
var tryTimes = 0;
|
||||||
|
UpgradeApp.Init();
|
||||||
|
while (tryTimes++ < 3)
|
||||||
|
{
|
||||||
|
if (!UpgradeApp.Upgrade(argData))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils.WriteLine(Resx.Resource.Restartv2rayN);
|
||||||
|
Utils.Waiting(3);
|
||||||
|
Utils.StartV2RayN();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,19 +6,99 @@ namespace AmazTool
|
|||||||
{
|
{
|
||||||
internal class UpgradeApp
|
internal class UpgradeApp
|
||||||
{
|
{
|
||||||
public static void Upgrade(string fileName)
|
public static bool Upgrade(string fileName)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
|
Utils.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
|
||||||
|
|
||||||
Utils.Waiting(5);
|
|
||||||
|
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
{
|
{
|
||||||
Console.WriteLine(Resx.Resource.UpgradeFileNotFound);
|
Utils.WriteLine(Resx.Resource.UpgradeFileNotFound);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(Resx.Resource.TryTerminateProcess);
|
Utils.Waiting(5);
|
||||||
|
|
||||||
|
KillV2rayN();
|
||||||
|
|
||||||
|
Utils.WriteLine(Resx.Resource.StartUnzipping);
|
||||||
|
StringBuilder sb = new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var splitKey = "/";
|
||||||
|
|
||||||
|
using var archive = ZipFile.OpenRead(fileName);
|
||||||
|
foreach (var entry in archive.Entries)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (entry.Length == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils.WriteLine(entry.FullName);
|
||||||
|
|
||||||
|
var lst = entry.FullName.Split(splitKey);
|
||||||
|
if (lst.Length == 1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fullName = string.Join(splitKey, lst[1..lst.Length]);
|
||||||
|
var entryOutputPath = Utils.GetPath(fullName);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!);
|
||||||
|
//In the bin folder, if the file already exists, it will be skipped
|
||||||
|
if (fullName.StartsWith("bin") && File.Exists(entryOutputPath))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entry.ExtractToFile(entryOutputPath, true);
|
||||||
|
|
||||||
|
Utils.WriteLine(entryOutputPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
sb.Append(ex.Message);
|
||||||
|
sb.Append(ex.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
sb.Append(Resx.Resource.FailedUpgrade + ex.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb.Length <= 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils.WriteLine(sb.ToString());
|
||||||
|
Utils.WriteLine(Resx.Resource.FailedUpgrade);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Init()
|
||||||
|
{
|
||||||
|
//Process temporary files generated by the last update
|
||||||
|
var files = Directory.GetFiles(Utils.GetPath(""), "*.tmp");
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (file.Contains(Utils.AmazTool))
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var destFileName = $"{Utils.GetExePath()}{Guid.NewGuid().ToString("N")[..8]}.tmp";
|
||||||
|
File.Move(Utils.GetExePath(), destFileName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool KillV2rayN()
|
||||||
|
{
|
||||||
|
Utils.WriteLine(Resx.Resource.TryTerminateProcess);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var existing = Process.GetProcessesByName(Utils.V2rayN);
|
var existing = Process.GetProcessesByName(Utils.V2rayN);
|
||||||
@@ -35,71 +115,10 @@ namespace AmazTool
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Access may be denied without admin right. The user may not be an administrator.
|
// Access may be denied without admin right. The user may not be an administrator.
|
||||||
Console.WriteLine(Resx.Resource.FailedTerminateProcess + ex.StackTrace);
|
Utils.WriteLine(Resx.Resource.FailedTerminateProcess + ex.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(Resx.Resource.StartUnzipping);
|
return true;
|
||||||
StringBuilder sb = new();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var thisAppOldFile = $"{Utils.GetExePath()}.tmp";
|
|
||||||
File.Delete(thisAppOldFile);
|
|
||||||
var splitKey = "/";
|
|
||||||
|
|
||||||
using var archive = ZipFile.OpenRead(fileName);
|
|
||||||
foreach (var entry in archive.Entries)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (entry.Length == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine(entry.FullName);
|
|
||||||
|
|
||||||
var lst = entry.FullName.Split(splitKey);
|
|
||||||
if (lst.Length == 1)
|
|
||||||
continue;
|
|
||||||
var fullName = string.Join(splitKey, lst[1..lst.Length]);
|
|
||||||
|
|
||||||
if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
File.Move(Utils.GetExePath(), thisAppOldFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
var entryOutputPath = Utils.GetPath(fullName);
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!);
|
|
||||||
//In the bin folder, if the file already exists, it will be skipped
|
|
||||||
if (fullName.StartsWith("bin") && File.Exists(entryOutputPath))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entry.ExtractToFile(entryOutputPath, true);
|
|
||||||
|
|
||||||
Console.WriteLine(entryOutputPath);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
sb.Append(ex.StackTrace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(Resx.Resource.FailedUpgrade + ex.StackTrace);
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine(Resx.Resource.FailedUpgrade + sb.ToString());
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine(Resx.Resource.Restartv2rayN);
|
|
||||||
Utils.Waiting(2);
|
|
||||||
|
|
||||||
Utils.StartV2RayN();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace AmazTool
|
namespace AmazTool
|
||||||
{
|
{
|
||||||
@@ -14,9 +14,9 @@ namespace AmazTool
|
|||||||
return AppDomain.CurrentDomain.BaseDirectory;
|
return AppDomain.CurrentDomain.BaseDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetPath(string fileName)
|
public static string GetPath(string? fileName)
|
||||||
{
|
{
|
||||||
string startupPath = StartupPath();
|
var startupPath = StartupPath();
|
||||||
if (string.IsNullOrEmpty(fileName))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
return startupPath;
|
return startupPath;
|
||||||
@@ -25,6 +25,7 @@ namespace AmazTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string V2rayN => "v2rayN";
|
public static string V2rayN => "v2rayN";
|
||||||
|
public static string AmazTool => "AmazTool";
|
||||||
|
|
||||||
public static void StartV2RayN()
|
public static void StartV2RayN()
|
||||||
{
|
{
|
||||||
@@ -44,9 +45,14 @@ namespace AmazTool
|
|||||||
{
|
{
|
||||||
for (var i = second; i > 0; i--)
|
for (var i = second; i > 0; i--)
|
||||||
{
|
{
|
||||||
Console.WriteLine(i);
|
Utils.WriteLine(i);
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteLine(object obj)
|
||||||
|
{
|
||||||
|
Console.WriteLine(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.10.0</Version>
|
<Version>7.10.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -5,21 +5,21 @@
|
|||||||
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
|
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.2.4" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.2.5" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.2.4" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.2.5" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.4" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.5" />
|
||||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.4" />
|
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.5" />
|
||||||
<PackageVersion Include="CliWrap" Version="3.8.1" />
|
<PackageVersion Include="CliWrap" Version="3.8.1" />
|
||||||
<PackageVersion Include="Downloader" Version="3.3.3" />
|
<PackageVersion Include="Downloader" Version="3.3.3" />
|
||||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.2.0" />
|
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
|
||||||
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
|
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
|
||||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||||
<PackageVersion Include="QRCoder" Version="1.6.0" />
|
<PackageVersion Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageVersion Include="ReactiveUI" Version="20.1.63" />
|
<PackageVersion Include="ReactiveUI" Version="20.1.63" />
|
||||||
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
<PackageVersion Include="ReactiveUI.WPF" Version="20.1.63" />
|
<PackageVersion Include="ReactiveUI.WPF" Version="20.1.63" />
|
||||||
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.4" />
|
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.5" />
|
||||||
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.4" />
|
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.5" />
|
||||||
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
||||||
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageVersion Include="TaskScheduler" Version="2.12.0" />
|
<PackageVersion Include="TaskScheduler" Version="2.12.0" />
|
||||||
|
|||||||
Submodule v2rayN/GlobalHotKeys updated: 35901e2eaa...b3b635ef46
@@ -265,7 +265,8 @@ namespace ServiceLib
|
|||||||
"utp",
|
"utp",
|
||||||
"wechat-video",
|
"wechat-video",
|
||||||
"dtls",
|
"dtls",
|
||||||
"wireguard"
|
"wireguard",
|
||||||
|
"dns"
|
||||||
];
|
];
|
||||||
|
|
||||||
public static readonly List<string> CoreTypes =
|
public static readonly List<string> CoreTypes =
|
||||||
|
|||||||
@@ -80,8 +80,6 @@ namespace ServiceLib.Handler
|
|||||||
Logging.SaveLog($"v2rayN start up | {Utils.GetRuntimeInfo()}");
|
Logging.SaveLog($"v2rayN start up | {Utils.GetRuntimeInfo()}");
|
||||||
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
|
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
|
||||||
|
|
||||||
ClearExpiredFiles();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,16 +90,6 @@ namespace ServiceLib.Handler
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearExpiredFiles()
|
|
||||||
{
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
FileManager.DeleteExpiredFiles(Utils.GetLogPath(), DateTime.Now.AddMonths(-1));
|
|
||||||
FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1));
|
|
||||||
FileManager.DeleteExpiredFiles(Utils.GetBinConfigPath(), DateTime.Now.AddHours(-1));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Init
|
#endregion Init
|
||||||
|
|
||||||
#region Config
|
#region Config
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ namespace ServiceLib.Handler
|
|||||||
task.Settings.RunOnlyIfIdle = false;
|
task.Settings.RunOnlyIfIdle = false;
|
||||||
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
||||||
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
||||||
task.Triggers.Add(new Microsoft.Win32.TaskScheduler.LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });
|
task.Triggers.Add(new Microsoft.Win32.TaskScheduler.LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(30) });
|
||||||
task.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
|
task.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
|
||||||
task.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(fileName.AppendQuotes(), null, Path.GetDirectoryName(fileName)));
|
task.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(fileName.AppendQuotes(), null, Path.GetDirectoryName(fileName)));
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ namespace ServiceLib.Handler
|
|||||||
private static readonly Lazy<ClashApiHandler> instance = new(() => new());
|
private static readonly Lazy<ClashApiHandler> instance = new(() => new());
|
||||||
public static ClashApiHandler Instance => instance.Value;
|
public static ClashApiHandler Instance => instance.Value;
|
||||||
|
|
||||||
|
private static readonly string _tag = "ClashApiHandler";
|
||||||
private Dictionary<string, ProxiesItem>? _proxies;
|
private Dictionary<string, ProxiesItem>? _proxies;
|
||||||
public Dictionary<string, object> ProfileContent { get; set; }
|
public Dictionary<string, object> ProfileContent { get; set; }
|
||||||
private static readonly string _tag = "ClashApiHandler";
|
|
||||||
|
|
||||||
public async Task<Tuple<ClashProxies, ClashProviders>?> GetClashProxiesAsync(Config config)
|
public async Task<Tuple<ClashProxies, ClashProviders>?> GetClashProxiesAsync(Config config)
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ namespace ServiceLib.Handler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lstProxy = new List<ClashProxyModel>();
|
lstProxy = new List<ClashProxyModel>();
|
||||||
foreach (KeyValuePair<string, ProxiesItem> kv in _proxies)
|
foreach (var kv in _proxies)
|
||||||
{
|
{
|
||||||
if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
|
if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ namespace ServiceLib.Handler
|
|||||||
item.Remarks = profileItem.Remarks;
|
item.Remarks = profileItem.Remarks;
|
||||||
item.Address = profileItem.Address;
|
item.Address = profileItem.Address;
|
||||||
item.Port = profileItem.Port;
|
item.Port = profileItem.Port;
|
||||||
|
item.Ports = profileItem.Ports;
|
||||||
|
|
||||||
item.Id = profileItem.Id;
|
item.Id = profileItem.Id;
|
||||||
item.AlterId = profileItem.AlterId;
|
item.AlterId = profileItem.AlterId;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
item.Path = Utils.UrlDecode(query["obfs-password"] ?? "");
|
item.Path = Utils.UrlDecode(query["obfs-password"] ?? "");
|
||||||
item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false";
|
item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false";
|
||||||
|
|
||||||
|
item.Ports = Utils.UrlDecode(query["mport"] ?? "").Replace('-', ':');
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +55,10 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path));
|
dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path));
|
||||||
}
|
}
|
||||||
dicQuery.Add("insecure", item.AllowInsecure.ToLower() == "true" ? "1" : "0");
|
dicQuery.Add("insecure", item.AllowInsecure.ToLower() == "true" ? "1" : "0");
|
||||||
|
if (Utils.IsNotEmpty(item.Ports))
|
||||||
|
{
|
||||||
|
dicQuery.Add("mport", Utils.UrlEncode(item.Ports.Replace(':', '-')));
|
||||||
|
}
|
||||||
|
|
||||||
return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark);
|
return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,6 @@ namespace ServiceLib.Handler
|
|||||||
public async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
await InitData();
|
await InitData();
|
||||||
_ = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
await Task.Delay(1000 * 600);
|
|
||||||
await SaveQueueIndexIds();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
|
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace ServiceLib.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
public class TaskHandler
|
public class TaskHandler
|
||||||
{
|
{
|
||||||
@@ -7,65 +7,91 @@
|
|||||||
|
|
||||||
public void RegUpdateTask(Config config, Action<bool, string> updateFunc)
|
public void RegUpdateTask(Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
Task.Run(() => UpdateTaskRunSubscription(config, updateFunc));
|
Task.Run(() => ScheduledTasks(config, updateFunc));
|
||||||
Task.Run(() => UpdateTaskRunGeo(config, updateFunc));
|
}
|
||||||
|
|
||||||
|
private async Task ScheduledTasks(Config config, Action<bool, string> updateFunc)
|
||||||
|
{
|
||||||
|
Logging.SaveLog("Setup Scheduled Tasks");
|
||||||
|
|
||||||
|
var numOfExecuted = 1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
//1 minute
|
||||||
|
await Task.Delay(1000 * 60);
|
||||||
|
|
||||||
|
//Execute once 1 minute
|
||||||
|
await UpdateTaskRunSubscription(config, updateFunc);
|
||||||
|
|
||||||
|
//Execute once 20 minute
|
||||||
|
if (numOfExecuted % 20 == 0)
|
||||||
|
{
|
||||||
|
//Logging.SaveLog("Execute save config");
|
||||||
|
|
||||||
|
await ConfigHandler.SaveConfig(config);
|
||||||
|
await ProfileExHandler.Instance.SaveTo();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Execute once 1 hour
|
||||||
|
if (numOfExecuted % 60 == 0)
|
||||||
|
{
|
||||||
|
//Logging.SaveLog("Execute delete expired files");
|
||||||
|
|
||||||
|
FileManager.DeleteExpiredFiles(Utils.GetBinConfigPath(), DateTime.Now.AddHours(-1));
|
||||||
|
FileManager.DeleteExpiredFiles(Utils.GetLogPath(), DateTime.Now.AddMonths(-1));
|
||||||
|
FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1));
|
||||||
|
|
||||||
|
//Check once 1 hour
|
||||||
|
await UpdateTaskRunGeo(config, numOfExecuted / 60, updateFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
numOfExecuted++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateTaskRunSubscription(Config config, Action<bool, string> updateFunc)
|
private async Task UpdateTaskRunSubscription(Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
await Task.Delay(60000);
|
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||||
Logging.SaveLog("UpdateTaskRunSubscription");
|
var lstSubs = (await AppHandler.Instance.SubItems())?
|
||||||
|
.Where(t => t.AutoUpdateInterval > 0)
|
||||||
|
.Where(t => updateTime - t.UpdateTime >= t.AutoUpdateInterval * 60)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var updateHandle = new UpdateService();
|
if (lstSubs is not { Count: > 0 })
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
return;
|
||||||
var lstSubs = (await AppHandler.Instance.SubItems())
|
}
|
||||||
.Where(t => t.AutoUpdateInterval > 0)
|
|
||||||
.Where(t => updateTime - t.UpdateTime >= t.AutoUpdateInterval * 60)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
foreach (var item in lstSubs)
|
Logging.SaveLog("Execute update subscription");
|
||||||
|
var updateHandle = new UpdateService();
|
||||||
|
|
||||||
|
foreach (var item in lstSubs)
|
||||||
|
{
|
||||||
|
await updateHandle.UpdateSubscriptionProcess(config, item.Id, true, (bool success, string msg) =>
|
||||||
{
|
{
|
||||||
await updateHandle.UpdateSubscriptionProcess(config, item.Id, true, (bool success, string msg) =>
|
updateFunc?.Invoke(success, msg);
|
||||||
{
|
if (success)
|
||||||
updateFunc?.Invoke(success, msg);
|
{
|
||||||
if (success)
|
Logging.SaveLog($"Update subscription end. {msg}");
|
||||||
Logging.SaveLog("subscription" + msg);
|
}
|
||||||
});
|
});
|
||||||
item.UpdateTime = updateTime;
|
item.UpdateTime = updateTime;
|
||||||
await ConfigHandler.AddSubItem(config, item);
|
await ConfigHandler.AddSubItem(config, item);
|
||||||
|
await Task.Delay(1000);
|
||||||
await Task.Delay(5000);
|
|
||||||
}
|
|
||||||
await Task.Delay(60000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateTaskRunGeo(Config config, Action<bool, string> updateFunc)
|
private async Task UpdateTaskRunGeo(Config config, int hours, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
var autoUpdateGeoTime = DateTime.Now;
|
if (config.GuiItem.AutoUpdateInterval > 0 && hours > 0 && hours % config.GuiItem.AutoUpdateInterval == 0)
|
||||||
|
|
||||||
//await Task.Delay(1000 * 120);
|
|
||||||
Logging.SaveLog("UpdateTaskRunGeo");
|
|
||||||
|
|
||||||
var updateHandle = new UpdateService();
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
await Task.Delay(1000 * 3600);
|
Logging.SaveLog("Execute update geo files");
|
||||||
|
|
||||||
var dtNow = DateTime.Now;
|
var updateHandle = new UpdateService();
|
||||||
if (config.GuiItem.AutoUpdateInterval > 0)
|
await updateHandle.UpdateGeoFileAll(config, (bool success, string msg) =>
|
||||||
{
|
{
|
||||||
if ((dtNow - autoUpdateGeoTime).Hours % config.GuiItem.AutoUpdateInterval == 0)
|
updateFunc?.Invoke(false, msg);
|
||||||
{
|
});
|
||||||
await updateHandle.UpdateGeoFileAll(config, (bool success, string msg) =>
|
|
||||||
{
|
|
||||||
updateFunc?.Invoke(false, msg);
|
|
||||||
});
|
|
||||||
autoUpdateGeoTime = dtNow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ namespace ServiceLib.Models
|
|||||||
{
|
{
|
||||||
public int UpMbps { get; set; }
|
public int UpMbps { get; set; }
|
||||||
public int DownMbps { get; set; }
|
public int DownMbps { get; set; }
|
||||||
|
public int HopInterval { get; set; } = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace ServiceLib.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
@@ -64,11 +64,11 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
[PrimaryKey]
|
[PrimaryKey]
|
||||||
public string IndexId { get; set; }
|
public string IndexId { get; set; }
|
||||||
|
|
||||||
public EConfigType ConfigType { get; set; }
|
public EConfigType ConfigType { get; set; }
|
||||||
public int ConfigVersion { get; set; }
|
public int ConfigVersion { get; set; }
|
||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
public string Ports { get; set; }
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public int AlterId { get; set; }
|
public int AlterId { get; set; }
|
||||||
public string Security { get; set; }
|
public string Security { get; set; }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace ServiceLib.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class SingboxConfig
|
public class SingboxConfig
|
||||||
{
|
{
|
||||||
@@ -101,21 +101,23 @@
|
|||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
public string? server { get; set; }
|
public string? server { get; set; }
|
||||||
public int? server_port { get; set; }
|
public int? server_port { get; set; }
|
||||||
public string uuid { get; set; }
|
public List<string>? server_ports { get; set; }
|
||||||
public string security { get; set; }
|
public string? uuid { get; set; }
|
||||||
|
public string? security { get; set; }
|
||||||
public int? alter_id { get; set; }
|
public int? alter_id { get; set; }
|
||||||
public string flow { get; set; }
|
public string? flow { get; set; }
|
||||||
|
public string? hop_interval { get; set; }
|
||||||
public int? up_mbps { get; set; }
|
public int? up_mbps { get; set; }
|
||||||
public int? down_mbps { get; set; }
|
public int? down_mbps { get; set; }
|
||||||
public string auth_str { get; set; }
|
public string? auth_str { get; set; }
|
||||||
public int? recv_window_conn { get; set; }
|
public int? recv_window_conn { get; set; }
|
||||||
public int? recv_window { get; set; }
|
public int? recv_window { get; set; }
|
||||||
public bool? disable_mtu_discovery { get; set; }
|
public bool? disable_mtu_discovery { get; set; }
|
||||||
public string? detour { get; set; }
|
public string? detour { get; set; }
|
||||||
public string method { get; set; }
|
public string? method { get; set; }
|
||||||
public string username { get; set; }
|
public string? username { get; set; }
|
||||||
public string password { get; set; }
|
public string? password { get; set; }
|
||||||
public string congestion_control { get; set; }
|
public string? congestion_control { get; set; }
|
||||||
public string? version { get; set; }
|
public string? version { get; set; }
|
||||||
public string? network { get; set; }
|
public string? network { get; set; }
|
||||||
public string? packet_encoding { get; set; }
|
public string? packet_encoding { get; set; }
|
||||||
|
|||||||
@@ -291,6 +291,8 @@ namespace ServiceLib.Models
|
|||||||
public object request { get; set; }
|
public object request { get; set; }
|
||||||
|
|
||||||
public object response { get; set; }
|
public object response { get; set; }
|
||||||
|
|
||||||
|
public string? domain { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KcpSettings4Ray
|
public class KcpSettings4Ray
|
||||||
|
|||||||
20
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
20
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -2483,7 +2483,7 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Address(Ip,Ipv6) 的本地化字符串。
|
/// 查找类似 Address(Ipv4,Ipv6) 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbLocalAddress {
|
public static string TbLocalAddress {
|
||||||
get {
|
get {
|
||||||
@@ -2536,6 +2536,24 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Server port range 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbPorts7 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbPorts7", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Will cover the port, separate with commas (,) 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbPorts7Tips {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbPorts7Tips", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Socks port 的本地化字符串。
|
/// 查找类似 Socks port 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1319,7 +1319,7 @@
|
|||||||
<value>Previous proxy remarks</value>
|
<value>Previous proxy remarks</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLocalAddress" xml:space="preserve">
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
<value>آدرس (IP, IPv6)</value>
|
<value>آدرس (IPv4, IPv6)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbReserved" xml:space="preserve">
|
<data name="TbReserved" xml:space="preserve">
|
||||||
<value>Reserved(2,3,4)</value>
|
<value>Reserved(2,3,4)</value>
|
||||||
@@ -1396,4 +1396,10 @@
|
|||||||
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
||||||
<value>Removed {0} invalid test results.</value>
|
<value>Removed {0} invalid test results.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbPorts7" xml:space="preserve">
|
||||||
|
<value>Server port range</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPorts7Tips" xml:space="preserve">
|
||||||
|
<value>Will cover the port, separate with commas (,)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1100,7 +1100,7 @@
|
|||||||
<value>Fenntartva (2,3,4)</value>
|
<value>Fenntartva (2,3,4)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLocalAddress" xml:space="preserve">
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
<value>Cím (Ip,Ipv6)</value>
|
<value>Cím (Ipv4,Ipv6)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPath7" xml:space="preserve">
|
<data name="TbPath7" xml:space="preserve">
|
||||||
<value>obfs jelszó</value>
|
<value>obfs jelszó</value>
|
||||||
@@ -1396,4 +1396,10 @@
|
|||||||
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
||||||
<value>Removed {0} invalid test results.</value>
|
<value>Removed {0} invalid test results.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbPorts7" xml:space="preserve">
|
||||||
|
<value>Server port range</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPorts7Tips" xml:space="preserve">
|
||||||
|
<value>Will cover the port, separate with commas (,)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1100,7 +1100,7 @@
|
|||||||
<value>Reserved(2,3,4)</value>
|
<value>Reserved(2,3,4)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLocalAddress" xml:space="preserve">
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
<value>Address(Ip,Ipv6)</value>
|
<value>Address(Ipv4,Ipv6)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPath7" xml:space="preserve">
|
<data name="TbPath7" xml:space="preserve">
|
||||||
<value>obfs password</value>
|
<value>obfs password</value>
|
||||||
@@ -1396,4 +1396,10 @@
|
|||||||
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
||||||
<value>Removed {0} invalid test results.</value>
|
<value>Removed {0} invalid test results.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbPorts7" xml:space="preserve">
|
||||||
|
<value>Server port range</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPorts7Tips" xml:space="preserve">
|
||||||
|
<value>Will cover the port, separate with commas (,)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1052,7 +1052,7 @@
|
|||||||
<value>obfs password</value>
|
<value>obfs password</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLocalAddress" xml:space="preserve">
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
<value>Address(Ip,Ipv6)</value>
|
<value>Address(Ipv4,Ipv6)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
|
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
|
||||||
<value>Default domain strategy for outbound</value>
|
<value>Default domain strategy for outbound</value>
|
||||||
@@ -1396,4 +1396,10 @@
|
|||||||
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
||||||
<value>Removed {0} invalid test results.</value>
|
<value>Removed {0} invalid test results.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbPorts7" xml:space="preserve">
|
||||||
|
<value>Server port range</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPorts7Tips" xml:space="preserve">
|
||||||
|
<value>Will cover the port, separate with commas (,)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1097,7 +1097,7 @@
|
|||||||
<value>Reserved(2,3,4)</value>
|
<value>Reserved(2,3,4)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLocalAddress" xml:space="preserve">
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
<value>Address(Ip,Ipv6)</value>
|
<value>Address(Ipv4,Ipv6)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPath7" xml:space="preserve">
|
<data name="TbPath7" xml:space="preserve">
|
||||||
<value>混淆密码(obfs password)</value>
|
<value>混淆密码(obfs password)</value>
|
||||||
@@ -1393,4 +1393,10 @@
|
|||||||
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
||||||
<value>移除无效测试结果 {0} 个。</value>
|
<value>移除无效测试结果 {0} 个。</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbPorts7" xml:space="preserve">
|
||||||
|
<value>跳跃端口范围</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPorts7Tips" xml:space="preserve">
|
||||||
|
<value>会覆盖端口,多组时用逗号(,)隔开</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1326,7 +1326,7 @@
|
|||||||
<value>Reserved(2,3,4)</value>
|
<value>Reserved(2,3,4)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLocalAddress" xml:space="preserve">
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
<value>Address(Ip,Ipv6)</value>
|
<value>Address(Ipv4,Ipv6)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||||
<value>使用系統hosts</value>
|
<value>使用系統hosts</value>
|
||||||
@@ -1394,4 +1394,10 @@
|
|||||||
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
<data name="RemoveInvalidServerResultTip" xml:space="preserve">
|
||||||
<value>移除無效測試結果 {0} 個。</value>
|
<value>移除無效測試結果 {0} 個。</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbPorts7" xml:space="preserve">
|
||||||
|
<value>跳躍端口範圍</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPorts7Tips" xml:space="preserve">
|
||||||
|
<value>會覆蓋端口,多組時用逗號(,)隔開</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -730,6 +730,16 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
|
|
||||||
outbound.up_mbps = _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null;
|
outbound.up_mbps = _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null;
|
||||||
outbound.down_mbps = _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null;
|
outbound.down_mbps = _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null;
|
||||||
|
if (node.Ports.IsNotEmpty())
|
||||||
|
{
|
||||||
|
outbound.server_port = null;
|
||||||
|
outbound.server_ports = node.Ports.Split(',')
|
||||||
|
.Where(p => p.Trim().IsNotEmpty())
|
||||||
|
.Select(p => p.Replace('-', ':'))
|
||||||
|
.ToList();
|
||||||
|
outbound.hop_interval = _config.HysteriaItem.HopInterval > 0 ? $"{_config.HysteriaItem.HopInterval}s" : null;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
|
|||||||
@@ -915,7 +915,8 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
kcpSettings.writeBufferSize = _config.KcpItem.WriteBufferSize;
|
kcpSettings.writeBufferSize = _config.KcpItem.WriteBufferSize;
|
||||||
kcpSettings.header = new Header4Ray
|
kcpSettings.header = new Header4Ray
|
||||||
{
|
{
|
||||||
type = node.HeaderType
|
type = node.HeaderType,
|
||||||
|
domain = host.IsNullOrEmpty() ? null : host
|
||||||
};
|
};
|
||||||
if (Utils.IsNotEmpty(path))
|
if (Utils.IsNotEmpty(path))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ namespace ServiceLib.Services
|
|||||||
await RunAsync(actionType, selecteds);
|
await RunAsync(actionType, selecteds);
|
||||||
await ProfileExHandler.Instance.SaveTo();
|
await ProfileExHandler.Instance.SaveTo();
|
||||||
UpdateFunc("", ResUI.SpeedtestingCompleted);
|
UpdateFunc("", ResUI.SpeedtestingCompleted);
|
||||||
|
|
||||||
FileManager.DeleteExpiredFiles(Utils.GetBinConfigPath(), DateTime.Now.AddHours(-1));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,26 +53,31 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
var lastTime = DateTime.Now;
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var numOfExecuted = 1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await Task.Delay(1000 * 5);
|
||||||
|
numOfExecuted++;
|
||||||
|
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_config.ClashUIItem.ConnectionsRefreshInterval <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfExecuted % _config.ClashUIItem.ConnectionsRefreshInterval != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
await GetClashConnections();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Observable.Interval(TimeSpan.FromSeconds(5))
|
|
||||||
.Subscribe(async x =>
|
|
||||||
{
|
|
||||||
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var dtNow = DateTime.Now;
|
|
||||||
if (_config.ClashUIItem.ConnectionsRefreshInterval > 0)
|
|
||||||
{
|
|
||||||
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ConnectionsRefreshInterval == 0)
|
|
||||||
{
|
|
||||||
await GetClashConnections();
|
|
||||||
lastTime = dtNow;
|
|
||||||
}
|
|
||||||
Task.Delay(1000).Wait();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
await ProxiesReload();
|
|
||||||
_ = DelayTestTask();
|
_ = DelayTestTask();
|
||||||
|
await ProxiesReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DoRulemodeSelected(bool c)
|
private async Task DoRulemodeSelected(bool c)
|
||||||
@@ -383,8 +383,6 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task ProxiesDelayTest(bool blAll)
|
private async Task ProxiesDelayTest(bool blAll)
|
||||||
{
|
{
|
||||||
//UpdateHandler(false, "Clash Proxies Latency Test");
|
|
||||||
|
|
||||||
ClashApiHandler.Instance.ClashProxiesDelayTest(blAll, _proxyDetails.ToList(), async (item, result) =>
|
ClashApiHandler.Instance.ClashProxiesDelayTest(blAll, _proxyDetails.ToList(), async (item, result) =>
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
@@ -434,13 +432,13 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
public async Task DelayTestTask()
|
public async Task DelayTestTask()
|
||||||
{
|
{
|
||||||
var lastTime = DateTime.Now;
|
Task.Run(async () =>
|
||||||
_ = Task.Run(async () =>
|
|
||||||
{
|
{
|
||||||
|
var numOfExecuted = 1;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
await Task.Delay(1000 * 60);
|
await Task.Delay(1000 * 60);
|
||||||
|
numOfExecuted++;
|
||||||
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -449,13 +447,11 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var dtNow = DateTime.Now;
|
if (numOfExecuted % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0)
|
||||||
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
await ProxiesDelayTest();
|
await ProxiesDelayTest();
|
||||||
lastTime = dtNow;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace v2rayN.Desktop.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
var vKey = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
|
var vKey = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
|
||||||
var modifiers = Modifiers.NoRepeat;
|
var modifiers = Modifiers.None;
|
||||||
if (item.Control)
|
if (item.Control)
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Control;
|
modifiers |= Modifiers.Control;
|
||||||
|
|||||||
@@ -308,7 +308,7 @@
|
|||||||
<Grid
|
<Grid
|
||||||
x:Name="gridHysteria2"
|
x:Name="gridHysteria2"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
ColumnDefinitions="180,Auto"
|
ColumnDefinitions="180,Auto,Auto"
|
||||||
IsVisible="False"
|
IsVisible="False"
|
||||||
RowDefinitions="Auto,Auto,Auto,Auto">
|
RowDefinitions="Auto,Auto,Auto,Auto">
|
||||||
|
|
||||||
@@ -337,6 +337,26 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbPorts7}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtPorts7"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Watermark="1000:2000,3000:4000" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbPorts7Tips}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
x:Name="gridTuic"
|
x:Name="gridTuic"
|
||||||
@@ -429,7 +449,8 @@
|
|||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}"
|
||||||
|
Watermark="2,3,4" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
@@ -442,7 +463,8 @@
|
|||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}"
|
||||||
|
Watermark="Ipv4,Ipv6" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="5"
|
Grid.Row="5"
|
||||||
@@ -456,7 +478,8 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left"
|
||||||
|
Watermark="1500" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
case EConfigType.Hysteria2:
|
case EConfigType.Hysteria2:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Ports, v => v.txtPorts7.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
x:Name="txtContent"
|
x:Name="txtContent"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Width="300"
|
Width="300"
|
||||||
|
MaxHeight="100"
|
||||||
Margin="{StaticResource MarginTb8}"
|
Margin="{StaticResource MarginTb8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
MaxLines="1" />
|
TextWrapping="WrapWithOverflow" />
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views
|
namespace v2rayN.Desktop.Views
|
||||||
{
|
{
|
||||||
@@ -17,7 +18,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
txtContent.Text = url;
|
txtContent.Text = url;
|
||||||
imgQrcode.Source = GetQRCode(url);
|
imgQrcode.Source = GetQRCode(url);
|
||||||
|
|
||||||
// btnCancel.Click += (s, e) => this.Close();
|
txtContent.GotFocus += (_, _) => Dispatcher.UIThread.Post(() => { txtContent.SelectAll(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap? GetQRCode(string? url)
|
private Bitmap? GetQRCode(string? url)
|
||||||
@@ -29,7 +30,9 @@ namespace v2rayN.Desktop.Views
|
|||||||
private Bitmap? ByteToBitmap(byte[]? bytes)
|
private Bitmap? ByteToBitmap(byte[]? bytes)
|
||||||
{
|
{
|
||||||
if (bytes is null)
|
if (bytes is null)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
using var ms = new MemoryStream(bytes);
|
using var ms = new MemoryStream(bytes);
|
||||||
return new Bitmap(ms);
|
return new Bitmap(ms);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.AddServerWindow"
|
x:Class="v2rayN.Views.AddServerWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
@@ -432,6 +432,7 @@
|
|||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="180" />
|
<ColumnDefinition Width="180" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -463,6 +464,30 @@
|
|||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbPorts7}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtPorts7"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
materialDesign:HintAssist.Hint="1000:2000,3000:4000"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbPorts7Tips}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
x:Name="gridTuic"
|
x:Name="gridTuic"
|
||||||
@@ -585,6 +610,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
|
materialDesign:HintAssist.Hint="2,3,4"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -600,6 +626,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
|
materialDesign:HintAssist.Hint="Ipv4,Ipv6"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -616,6 +643,7 @@
|
|||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
|
materialDesign:HintAssist.Hint="1500"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ namespace v2rayN.Views
|
|||||||
case EConfigType.Hysteria2:
|
case EConfigType.Hysteria2:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Ports, v => v.txtPorts7.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
|
|||||||
Reference in New Issue
Block a user