mirror of
https://github.com/2dust/v2rayN.git
synced 2025-12-10 21:40:10 +05:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c22b57927c | ||
|
|
81b84d235c | ||
|
|
488e8aab00 | ||
|
|
fc43a9a726 | ||
|
|
31947fdcb3 | ||
|
|
34c7963d28 | ||
|
|
d91b0afb9a | ||
|
|
82eb3fd6bd | ||
|
|
3d3d3f83df | ||
|
|
6879c75bc8 | ||
|
|
b02ad6cdab | ||
|
|
f7b16952ea | ||
|
|
f0d05a7d4e | ||
|
|
d6ca317b20 | ||
|
|
2879fddfd9 | ||
|
|
b6c09470fc | ||
|
|
9fdf6c6c32 | ||
|
|
79085af994 | ||
|
|
d189f4b443 | ||
|
|
c9d65e5cd9 | ||
|
|
639d62588a | ||
|
|
6c9db51fd5 | ||
|
|
f0dbb6b22c | ||
|
|
f10f7b6268 | ||
|
|
48a5cbc552 | ||
|
|
6721d150e0 | ||
|
|
54c16cad7d | ||
|
|
ae3ab15245 | ||
|
|
d3c0f50fec | ||
|
|
43753b1b7a | ||
|
|
6f3e4b3682 | ||
|
|
b57cdd31bd | ||
|
|
b936c194e4 | ||
|
|
064431421a | ||
|
|
9d49c7aad0 | ||
|
|
a6f27e5071 | ||
|
|
8d1d10b783 | ||
|
|
61bea05f63 | ||
|
|
bbe7c7b884 | ||
|
|
a432852b78 | ||
|
|
770e8b8cfa | ||
|
|
7faabdc375 | ||
|
|
a9860418ba | ||
|
|
30ff9d0ea9 | ||
|
|
bbc2298939 | ||
|
|
3286e8e24d | ||
|
|
372f3991e1 | ||
|
|
9aa5c0d135 | ||
|
|
9e9808e489 | ||
|
|
3dd75b17cf | ||
|
|
2504b4737b | ||
|
|
8ff04dca0d |
File diff suppressed because it is too large
Load Diff
@@ -9,9 +9,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.27.3" />
|
<PackageReference Include="Google.Protobuf" Version="3.28.0" />
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.65.0" />
|
<PackageReference Include="Grpc.Net.Client" Version="2.65.0" />
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.65.0">
|
<PackageReference Include="Grpc.Tools" Version="2.66.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
11
v2rayN/ServiceLib/Base/MyReactiveObject.cs
Normal file
11
v2rayN/ServiceLib/Base/MyReactiveObject.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace ServiceLib.Base
|
||||||
|
{
|
||||||
|
public class MyReactiveObject : ReactiveObject
|
||||||
|
{
|
||||||
|
protected static Config? _config;
|
||||||
|
protected Func<EViewAction, object?, Task<bool>>? _updateView;
|
||||||
|
protected NoticeHandler? _noticeHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using Downloader;
|
using Downloader;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
internal class DownloaderHelper
|
public class DownloaderHelper
|
||||||
{
|
{
|
||||||
private static readonly Lazy<DownloaderHelper> _instance = new(() => new());
|
private static readonly Lazy<DownloaderHelper> _instance = new(() => new());
|
||||||
public static DownloaderHelper Instance => _instance.Value;
|
public static DownloaderHelper Instance => _instance.Value;
|
||||||
@@ -169,11 +168,15 @@ namespace v2rayN
|
|||||||
{
|
{
|
||||||
progress.Report(101);
|
progress.Report(101);
|
||||||
}
|
}
|
||||||
|
else if (value.Error != null)
|
||||||
|
{
|
||||||
|
throw value.Error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using var cts = new CancellationTokenSource();
|
using var cts = new CancellationTokenSource();
|
||||||
await downloader.DownloadFileTaskAsync(url, fileName, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);
|
await downloader.DownloadFileTaskAsync(url, fileName, cts.Token);
|
||||||
|
|
||||||
downloadOpt = null;
|
downloadOpt = null;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
using System.IO;
|
using System.IO.Compression;
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
public static class FileManager
|
public static class FileManager
|
||||||
{
|
{
|
||||||
@@ -34,6 +33,22 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void UncompressedFile(string fileName, string toPath, string? toName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInfo fileInfo = new(fileName);
|
||||||
|
using FileStream originalFileStream = fileInfo.OpenRead();
|
||||||
|
using FileStream decompressedFileStream = File.Create(toName != null ? Path.Combine(toPath, toName) : toPath);
|
||||||
|
using GZipStream decompressionStream = new(originalFileStream, CompressionMode.Decompress);
|
||||||
|
decompressionStream.CopyTo(decompressedFileStream);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static string NonExclusiveReadAllText(string path)
|
public static string NonExclusiveReadAllText(string path)
|
||||||
{
|
{
|
||||||
return NonExclusiveReadAllText(path, Encoding.Default);
|
return NonExclusiveReadAllText(path, Encoding.Default);
|
||||||
@@ -86,5 +101,19 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ZipFile.CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
using System.IO;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* See:
|
* See:
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
using System.IO;
|
using System.Text.Json;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
internal class JsonUtils
|
public class JsonUtils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DeepCopy
|
/// DeepCopy
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Config;
|
using NLog.Config;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
public class Logging
|
public class Logging
|
||||||
{
|
{
|
||||||
15
v2rayN/ServiceLib/Common/QRCodeHelper.cs
Normal file
15
v2rayN/ServiceLib/Common/QRCodeHelper.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using QRCoder;
|
||||||
|
|
||||||
|
namespace ServiceLib.Common
|
||||||
|
{
|
||||||
|
public class QRCodeHelper
|
||||||
|
{
|
||||||
|
public static byte[]? GenQRCode(string? url)
|
||||||
|
{
|
||||||
|
using QRCodeGenerator qrGenerator = new();
|
||||||
|
using QRCodeData qrCodeData = qrGenerator.CreateQrCode(url ?? string.Empty, QRCodeGenerator.ECCLevel.Q);
|
||||||
|
using PngByteQRCode qrCode = new(qrCodeData);
|
||||||
|
return qrCode.GetGraphic(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
public static class QueryableExtension
|
public static class QueryableExtension
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
public class SemanticVersion
|
public class SemanticVersion
|
||||||
{
|
{
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
this.minor = int.Parse(parts[1]);
|
this.minor = int.Parse(parts[1]);
|
||||||
this.patch = 0;
|
this.patch = 0;
|
||||||
}
|
}
|
||||||
else if (parts.Length == 3)
|
else if (parts.Length == 3 || parts.Length == 4)
|
||||||
{
|
{
|
||||||
this.major = int.Parse(parts[0]);
|
this.major = int.Parse(parts[0]);
|
||||||
this.minor = int.Parse(parts[1]);
|
this.minor = int.Parse(parts[1]);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
public sealed class SQLiteHelper
|
public sealed class SQLiteHelper
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
internal static class StringEx
|
public static class StringEx
|
||||||
{
|
{
|
||||||
public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value)
|
public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value)
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
using Microsoft.Win32;
|
using System.Collections.Specialized;
|
||||||
using Microsoft.Win32.TaskScheduler;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
@@ -11,17 +7,12 @@ using System.Net.Sockets;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Security.Principal;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Interop;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
|
|
||||||
namespace v2rayN
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
internal class Utils
|
public class Utils
|
||||||
{
|
{
|
||||||
#region 资源Json操作
|
#region 资源Json操作
|
||||||
|
|
||||||
@@ -345,14 +336,6 @@ namespace v2rayN
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageSource IconToImageSource(Icon icon)
|
|
||||||
{
|
|
||||||
return Imaging.CreateBitmapSourceFromHIcon(
|
|
||||||
icon.Handle,
|
|
||||||
new System.Windows.Int32Rect(0, 0, icon.Width, icon.Height),
|
|
||||||
BitmapSizeOptions.FromEmptyOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// idn to idc
|
/// idn to idc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -384,6 +367,7 @@ namespace v2rayN
|
|||||||
|
|
||||||
public static bool IsBase64String(string plainText)
|
public static bool IsBase64String(string plainText)
|
||||||
{
|
{
|
||||||
|
if (plainText.IsNullOrEmpty()) return false;
|
||||||
var buffer = new Span<byte>(new byte[plainText.Length]);
|
var buffer = new Span<byte>(new byte[plainText.Length]);
|
||||||
return Convert.TryFromBase64String(plainText, buffer, out int _);
|
return Convert.TryFromBase64String(plainText, buffer, out int _);
|
||||||
}
|
}
|
||||||
@@ -420,11 +404,6 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 文本
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool IsNullOrEmpty(string? text)
|
public static bool IsNullOrEmpty(string? text)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
@@ -516,29 +495,6 @@ namespace v2rayN
|
|||||||
|
|
||||||
#region 测速
|
#region 测速
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 取得本机 IP Address
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
//public static List<string> GetHostIPAddress()
|
|
||||||
//{
|
|
||||||
// List<string> lstIPAddress = new List<string>();
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// IPHostEntry IpEntry = Dns.GetHostEntry(Dns.GetHostName());
|
|
||||||
// foreach (IPAddress ipa in IpEntry.AddressList)
|
|
||||||
// {
|
|
||||||
// if (ipa.AddressFamily == AddressFamily.InterNetwork)
|
|
||||||
// lstIPAddress.Add(ipa.ToString());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// SaveLog(ex.Message, ex);
|
|
||||||
// }
|
|
||||||
// return lstIPAddress;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public static void SetSecurityProtocol(bool enableSecurityProtocolTls13)
|
public static void SetSecurityProtocol(bool enableSecurityProtocolTls13)
|
||||||
{
|
{
|
||||||
if (enableSecurityProtocolTls13)
|
if (enableSecurityProtocolTls13)
|
||||||
@@ -614,58 +570,35 @@ namespace v2rayN
|
|||||||
string location = GetExePath();
|
string location = GetExePath();
|
||||||
if (blFull)
|
if (blFull)
|
||||||
{
|
{
|
||||||
return string.Format("v2rayN - V{0} - {1}",
|
return string.Format("{0} - V{1} - {2}",
|
||||||
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString(),
|
Global.AppName,
|
||||||
|
GetVersionInfo(),
|
||||||
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
|
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return string.Format("v2rayN/{0}",
|
return string.Format("{0}/{1}",
|
||||||
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString());
|
Global.AppName,
|
||||||
|
GetVersionInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
return string.Empty;
|
return Global.AppName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static string GetVersionInfo()
|
||||||
/// 获取剪贴板数
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string? GetClipboardData()
|
|
||||||
{
|
{
|
||||||
string? strData = string.Empty;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IDataObject data = Clipboard.GetDataObject();
|
return Assembly.GetExecutingAssembly()?.GetName()?.Version?.ToString() ?? "0.0";
|
||||||
if (data.GetDataPresent(DataFormats.UnicodeText))
|
|
||||||
{
|
|
||||||
strData = data.GetData(DataFormats.UnicodeText)?.ToString();
|
|
||||||
}
|
|
||||||
return strData;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
return "0.0";
|
||||||
return strData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 拷贝至剪贴板
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static void SetClipboardData(string strData)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Clipboard.SetText(strData);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,26 +626,6 @@ namespace v2rayN
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// IsAdministrator
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool IsAdministrator()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsIdentity current = WindowsIdentity.GetCurrent();
|
|
||||||
WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);
|
|
||||||
//WindowsBuiltInRole可以枚举出很多权限,例如系统用户、User、Guest等等
|
|
||||||
return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetDownloadFileName(string url)
|
public static string GetDownloadFileName(string url)
|
||||||
{
|
{
|
||||||
var fileName = Path.GetFileName(url);
|
var fileName = Path.GetFileName(url);
|
||||||
@@ -752,23 +665,6 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetDarkBorder(System.Windows.Window window, bool dark)
|
|
||||||
{
|
|
||||||
// Make sure the handle is created before the window is shown
|
|
||||||
IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).EnsureHandle();
|
|
||||||
int attribute = dark ? 1 : 0;
|
|
||||||
uint attributeSize = (uint)Marshal.SizeOf(attribute);
|
|
||||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ref attribute, attributeSize);
|
|
||||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsLightTheme()
|
|
||||||
{
|
|
||||||
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
|
|
||||||
var value = key?.GetValue("AppsUseLightTheme");
|
|
||||||
return value is int i && i > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取系统hosts
|
/// 获取系统hosts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -800,6 +696,24 @@ namespace v2rayN
|
|||||||
return systemHosts;
|
return systemHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetExeName(string name)
|
||||||
|
{
|
||||||
|
if (IsWindows())
|
||||||
|
{
|
||||||
|
return $"{name}.exe";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
|
public static bool IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
public static bool IsOSX() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||||
|
|
||||||
#endregion 杂项
|
#endregion 杂项
|
||||||
|
|
||||||
#region TempPath
|
#region TempPath
|
||||||
@@ -945,186 +859,5 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion TempPath
|
#endregion TempPath
|
||||||
|
|
||||||
#region 开机自动启动等
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开机自动启动
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="run"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static void SetAutoRun(string AutoRunRegPath, string AutoRunName, bool run)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var autoRunName = $"{AutoRunName}_{GetMD5(StartupPath())}";
|
|
||||||
|
|
||||||
//delete first
|
|
||||||
RegWriteValue(AutoRunRegPath, autoRunName, "");
|
|
||||||
if (IsAdministrator())
|
|
||||||
{
|
|
||||||
AutoStart(autoRunName, "", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (run)
|
|
||||||
{
|
|
||||||
string exePath = GetExePath();
|
|
||||||
if (IsAdministrator())
|
|
||||||
{
|
|
||||||
AutoStart(autoRunName, exePath, "");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RegWriteValue(AutoRunRegPath, autoRunName, exePath.AppendQuotes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string? RegReadValue(string path, string name, string def)
|
|
||||||
{
|
|
||||||
RegistryKey? regKey = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
regKey = Registry.CurrentUser.OpenSubKey(path, false);
|
|
||||||
string? value = regKey?.GetValue(name) as string;
|
|
||||||
if (IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
regKey?.Close();
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RegWriteValue(string path, string name, object value)
|
|
||||||
{
|
|
||||||
RegistryKey? regKey = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
regKey = Registry.CurrentUser.CreateSubKey(path);
|
|
||||||
if (IsNullOrEmpty(value.ToString()))
|
|
||||||
{
|
|
||||||
regKey?.DeleteValue(name, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
regKey?.SetValue(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
regKey?.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Auto Start via TaskService
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="taskName"></param>
|
|
||||||
/// <param name="fileName"></param>
|
|
||||||
/// <param name="description"></param>
|
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
|
||||||
public static void AutoStart(string taskName, string fileName, string description)
|
|
||||||
{
|
|
||||||
if (Utils.IsNullOrEmpty(taskName))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string TaskName = taskName;
|
|
||||||
var logonUser = WindowsIdentity.GetCurrent().Name;
|
|
||||||
string taskDescription = description;
|
|
||||||
string deamonFileName = fileName;
|
|
||||||
|
|
||||||
using var taskService = new TaskService();
|
|
||||||
var tasks = taskService.RootFolder.GetTasks(new Regex(TaskName));
|
|
||||||
foreach (var t in tasks)
|
|
||||||
{
|
|
||||||
taskService.RootFolder.DeleteTask(t.Name);
|
|
||||||
}
|
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var task = taskService.NewTask();
|
|
||||||
task.RegistrationInfo.Description = taskDescription;
|
|
||||||
task.Settings.DisallowStartIfOnBatteries = false;
|
|
||||||
task.Settings.StopIfGoingOnBatteries = false;
|
|
||||||
task.Settings.RunOnlyIfIdle = false;
|
|
||||||
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
|
||||||
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
|
||||||
task.Triggers.Add(new LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });
|
|
||||||
task.Principal.RunLevel = TaskRunLevel.Highest;
|
|
||||||
task.Actions.Add(new ExecAction(deamonFileName.AppendQuotes(), null, Path.GetDirectoryName(deamonFileName)));
|
|
||||||
|
|
||||||
taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveTunDevice()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
|
|
||||||
var guid = new Guid(sum);
|
|
||||||
string pnputilPath = @"C:\Windows\System32\pnputil.exe";
|
|
||||||
string arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
|
|
||||||
|
|
||||||
// Try to remove the device
|
|
||||||
Process proc = new()
|
|
||||||
{
|
|
||||||
StartInfo = new()
|
|
||||||
{
|
|
||||||
FileName = pnputilPath,
|
|
||||||
Arguments = arg,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
proc.Start();
|
|
||||||
var output = proc.StandardOutput.ReadToEnd();
|
|
||||||
proc.WaitForExit();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion 开机自动启动等
|
|
||||||
|
|
||||||
#region Windows API
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum DWMWINDOWATTRIBUTE : uint
|
|
||||||
{
|
|
||||||
DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
|
|
||||||
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("dwmapi.dll")]
|
|
||||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
|
||||||
|
|
||||||
#endregion Windows API
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using YamlDotNet.Serialization;
|
using YamlDotNet.Serialization;
|
||||||
using YamlDotNet.Serialization.NamingConventions;
|
using YamlDotNet.Serialization.NamingConventions;
|
||||||
|
|
||||||
namespace v2rayN.Common
|
namespace ServiceLib.Common
|
||||||
{
|
{
|
||||||
internal class YamlUtils
|
public class YamlUtils
|
||||||
{
|
{
|
||||||
#region YAML
|
#region YAML
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum EConfigType
|
public enum EConfigType
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum ECoreType
|
public enum ECoreType
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum EGirdOrientation
|
public enum EGirdOrientation
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum EGlobalHotkey
|
public enum EGlobalHotkey
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum EInboundProtocol
|
public enum EInboundProtocol
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum EMove
|
public enum EMove
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum ERuleMode
|
public enum ERuleMode
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum EServerColName
|
public enum EServerColName
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum ESpeedActionType
|
public enum ESpeedActionType
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum ESysProxyType
|
public enum ESysProxyType
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Enums
|
namespace ServiceLib.Enums
|
||||||
{
|
{
|
||||||
public enum ETransport
|
public enum ETransport
|
||||||
{
|
{
|
||||||
45
v2rayN/ServiceLib/Enums/EViewAction.cs
Normal file
45
v2rayN/ServiceLib/Enums/EViewAction.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
namespace ServiceLib.Enums
|
||||||
|
{
|
||||||
|
public enum EViewAction
|
||||||
|
{
|
||||||
|
CloseWindow,
|
||||||
|
ShowYesNo,
|
||||||
|
SaveFileDialog,
|
||||||
|
AddBatchRoutingRulesYesNo,
|
||||||
|
AdjustMainLvColWidth,
|
||||||
|
UpdateSysProxy,
|
||||||
|
SetClipboardData,
|
||||||
|
AddServerViaClipboard,
|
||||||
|
ImportRulesFromClipboard,
|
||||||
|
ProfilesFocus,
|
||||||
|
ShareSub,
|
||||||
|
ShareServer,
|
||||||
|
ShowHideWindow,
|
||||||
|
ScanScreenTask,
|
||||||
|
Shutdown,
|
||||||
|
BrowseServer,
|
||||||
|
ImportRulesFromFile,
|
||||||
|
SubEditWindow,
|
||||||
|
RoutingRuleSettingWindow,
|
||||||
|
RoutingRuleDetailsWindow,
|
||||||
|
AddServerWindow,
|
||||||
|
AddServer2Window,
|
||||||
|
DNSSettingWindow,
|
||||||
|
RoutingSettingWindow,
|
||||||
|
OptionSettingWindow,
|
||||||
|
GlobalHotkeySettingWindow,
|
||||||
|
SubSettingWindow,
|
||||||
|
DispatcherSpeedTest,
|
||||||
|
DispatcherRefreshConnections,
|
||||||
|
DispatcherRefreshProxyGroups,
|
||||||
|
DispatcherProxiesDelayTest,
|
||||||
|
DispatcherStatistics,
|
||||||
|
DispatcherServerAvailability,
|
||||||
|
DispatcherReload,
|
||||||
|
DispatcherRefreshServersBiz,
|
||||||
|
DispatcherRefreshIcon,
|
||||||
|
DispatcherCheckUpdate,
|
||||||
|
DispatcherCheckUpdateFinished,
|
||||||
|
DispatcherShowMsg,
|
||||||
|
}
|
||||||
|
}
|
||||||
3
v2rayN/ServiceLib/FodyWeavers.xml
Normal file
3
v2rayN/ServiceLib/FodyWeavers.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||||
|
<ReactiveUI />
|
||||||
|
</Weavers>
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib
|
||||||
|
|
||||||
namespace v2rayN
|
|
||||||
{
|
{
|
||||||
internal class Global
|
public class Global
|
||||||
{
|
{
|
||||||
#region const
|
#region const
|
||||||
|
|
||||||
|
public const string AppName = "v2rayN";
|
||||||
public const string GithubUrl = "https://github.com";
|
public const string GithubUrl = "https://github.com";
|
||||||
public const string GithubApiUrl = "https://api.github.com/repos";
|
public const string GithubApiUrl = "https://api.github.com/repos";
|
||||||
public const string V2flyCoreUrl = "https://github.com/v2fly/v2ray-core/releases";
|
public const string V2flyCoreUrl = "https://github.com/v2fly/v2ray-core/releases";
|
||||||
@@ -32,21 +31,21 @@ namespace v2rayN
|
|||||||
public const string CoreSpeedtestConfigFileName = "configSpeedtest.json";
|
public const string CoreSpeedtestConfigFileName = "configSpeedtest.json";
|
||||||
public const string CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
|
public const string CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
|
||||||
public const string ClashMixinConfigFileName = "Mixin.yaml";
|
public const string ClashMixinConfigFileName = "Mixin.yaml";
|
||||||
public const string V2raySampleClient = "v2rayN.Sample.SampleClientConfig";
|
public const string V2raySampleClient = "ServiceLib.Sample.SampleClientConfig";
|
||||||
public const string SingboxSampleClient = "v2rayN.Sample.SingboxSampleClientConfig";
|
public const string SingboxSampleClient = "ServiceLib.Sample.SingboxSampleClientConfig";
|
||||||
public const string V2raySampleHttpRequestFileName = "v2rayN.Sample.SampleHttpRequest";
|
public const string V2raySampleHttpRequestFileName = "ServiceLib.Sample.SampleHttpRequest";
|
||||||
public const string V2raySampleHttpResponseFileName = "v2rayN.Sample.SampleHttpResponse";
|
public const string V2raySampleHttpResponseFileName = "ServiceLib.Sample.SampleHttpResponse";
|
||||||
public const string V2raySampleInbound = "v2rayN.Sample.SampleInbound";
|
public const string V2raySampleInbound = "ServiceLib.Sample.SampleInbound";
|
||||||
public const string V2raySampleOutbound = "v2rayN.Sample.SampleOutbound";
|
public const string V2raySampleOutbound = "ServiceLib.Sample.SampleOutbound";
|
||||||
public const string SingboxSampleOutbound = "v2rayN.Sample.SingboxSampleOutbound";
|
public const string SingboxSampleOutbound = "ServiceLib.Sample.SingboxSampleOutbound";
|
||||||
public const string CustomRoutingFileName = "v2rayN.Sample.custom_routing_";
|
public const string CustomRoutingFileName = "ServiceLib.Sample.custom_routing_";
|
||||||
public const string TunSingboxDNSFileName = "v2rayN.Sample.tun_singbox_dns";
|
public const string TunSingboxDNSFileName = "ServiceLib.Sample.tun_singbox_dns";
|
||||||
public const string TunSingboxInboundFileName = "v2rayN.Sample.tun_singbox_inbound";
|
public const string TunSingboxInboundFileName = "ServiceLib.Sample.tun_singbox_inbound";
|
||||||
public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules";
|
public const string TunSingboxRulesFileName = "ServiceLib.Sample.tun_singbox_rules";
|
||||||
public const string DNSV2rayNormalFileName = "v2rayN.Sample.dns_v2ray_normal";
|
public const string DNSV2rayNormalFileName = "ServiceLib.Sample.dns_v2ray_normal";
|
||||||
public const string DNSSingboxNormalFileName = "v2rayN.Sample.dns_singbox_normal";
|
public const string DNSSingboxNormalFileName = "ServiceLib.Sample.dns_singbox_normal";
|
||||||
public const string ClashMixinYaml = "v2rayN.Sample.clash_mixin_yaml";
|
public const string ClashMixinYaml = "ServiceLib.Sample.clash_mixin_yaml";
|
||||||
public const string ClashTunYaml = "v2rayN.Sample.clash_tun_yaml";
|
public const string ClashTunYaml = "ServiceLib.Sample.clash_tun_yaml";
|
||||||
|
|
||||||
public const string DefaultSecurity = "auto";
|
public const string DefaultSecurity = "auto";
|
||||||
public const string DefaultNetwork = "tcp";
|
public const string DefaultNetwork = "tcp";
|
||||||
@@ -61,6 +60,7 @@ namespace v2rayN
|
|||||||
public const string InboundAPIProtocol = "dokodemo-door";
|
public const string InboundAPIProtocol = "dokodemo-door";
|
||||||
public const string HttpProtocol = "http://";
|
public const string HttpProtocol = "http://";
|
||||||
public const string HttpsProtocol = "https://";
|
public const string HttpsProtocol = "https://";
|
||||||
|
public const string SocksProtocol = "socks://";
|
||||||
|
|
||||||
public const string UserEMail = "t@t.tt";
|
public const string UserEMail = "t@t.tt";
|
||||||
public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
|
public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
|
||||||
@@ -73,6 +73,7 @@ namespace v2rayN
|
|||||||
public const int MaxPort = 65536;
|
public const int MaxPort = 65536;
|
||||||
public const string CommandClearMsg = "CommandClearMsg";
|
public const string CommandClearMsg = "CommandClearMsg";
|
||||||
public const string CommandSendMsgView = "CommandSendMsgView";
|
public const string CommandSendMsgView = "CommandSendMsgView";
|
||||||
|
public const string CommandSendSnackMsg = "CommandSendSnackMsg";
|
||||||
public const string CommandStopSpeedTest = "CommandStopSpeedTest";
|
public const string CommandStopSpeedTest = "CommandStopSpeedTest";
|
||||||
public const string CommandRefreshProfiles = "CommandRefreshProfiles";
|
public const string CommandRefreshProfiles = "CommandRefreshProfiles";
|
||||||
public const string DelayUnit = "";
|
public const string DelayUnit = "";
|
||||||
@@ -179,7 +180,7 @@ namespace v2rayN
|
|||||||
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
|
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
|
||||||
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
|
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
|
||||||
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" };
|
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" };
|
||||||
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
|
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
|
||||||
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
|
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
|
||||||
public static readonly List<string> InboundTags = new() { "socks", "http", "socks2", "http2" };
|
public static readonly List<string> InboundTags = new() { "socks", "http", "socks2", "http2" };
|
||||||
public static readonly List<string> RuleProtocols = new() { "http", "tls", "bittorrent" };
|
public static readonly List<string> RuleProtocols = new() { "http", "tls", "bittorrent" };
|
||||||
9
v2rayN/ServiceLib/GlobalUsings.cs
Normal file
9
v2rayN/ServiceLib/GlobalUsings.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
global using ServiceLib.Base;
|
||||||
|
global using ServiceLib.Common;
|
||||||
|
global using ServiceLib.Enums;
|
||||||
|
global using ServiceLib.Handler;
|
||||||
|
global using ServiceLib.Handler.CoreConfig;
|
||||||
|
global using ServiceLib.Handler.Fmt;
|
||||||
|
global using ServiceLib.Handler.Statistics;
|
||||||
|
global using ServiceLib.Models;
|
||||||
|
global using ServiceLib.Resx;
|
||||||
@@ -1,26 +1,15 @@
|
|||||||
using v2rayN.Models;
|
using static ServiceLib.Models.ClashProxies;
|
||||||
using static v2rayN.Models.ClashProxies;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
public sealed class ClashApiHandler
|
public sealed class ClashApiHandler
|
||||||
{
|
{
|
||||||
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 Dictionary<String, ProxiesItem> _proxies;
|
private Dictionary<String, ProxiesItem>? _proxies;
|
||||||
public Dictionary<string, object> ProfileContent { get; set; }
|
public Dictionary<string, object> ProfileContent { get; set; }
|
||||||
|
|
||||||
public void SetProxies(Dictionary<String, ProxiesItem> proxies)
|
|
||||||
{
|
|
||||||
_proxies = proxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<String, ProxiesItem> GetProxies()
|
|
||||||
{
|
|
||||||
return _proxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetClashProxies(Config config, Action<ClashProxies, ClashProviders> update)
|
public void GetClashProxies(Config config, Action<ClashProxies, ClashProviders> update)
|
||||||
{
|
{
|
||||||
Task.Run(() => GetClashProxiesAsync(config, update));
|
Task.Run(() => GetClashProxiesAsync(config, update));
|
||||||
@@ -40,10 +29,11 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
if (clashProxies != null || clashProviders != null)
|
if (clashProxies != null || clashProviders != null)
|
||||||
{
|
{
|
||||||
|
_proxies = clashProxies?.proxies;
|
||||||
update(clashProxies, clashProviders);
|
update(clashProxies, clashProviders);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Thread.Sleep(5000);
|
Task.Delay(5000).Wait();
|
||||||
}
|
}
|
||||||
update(null, null);
|
update(null, null);
|
||||||
}
|
}
|
||||||
@@ -56,19 +46,18 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
if (GetProxies() != null)
|
if (_proxies != null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Thread.Sleep(5000);
|
Task.Delay(5000).Wait();
|
||||||
}
|
}
|
||||||
var proxies = GetProxies();
|
if (_proxies == null)
|
||||||
if (proxies == null)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lstProxy = new List<ClashProxyModel>();
|
lstProxy = new List<ClashProxyModel>();
|
||||||
foreach (KeyValuePair<string, ProxiesItem> kv in proxies)
|
foreach (KeyValuePair<string, ProxiesItem> kv in _proxies)
|
||||||
{
|
{
|
||||||
if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
|
if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
|
||||||
{
|
{
|
||||||
@@ -87,7 +76,7 @@ namespace v2rayN.Handler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var urlBase = $"{GetApiUrl()}/proxies";
|
var urlBase = $"{GetApiUrl()}/proxies";
|
||||||
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.GetConfig().speedTestItem.speedPingTestUrl;
|
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.Config.speedTestItem.speedPingTestUrl;
|
||||||
|
|
||||||
List<Task> tasks = new List<Task>();
|
List<Task> tasks = new List<Task>();
|
||||||
foreach (var it in lstProxy)
|
foreach (var it in lstProxy)
|
||||||
@@ -106,7 +95,7 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
Task.WaitAll(tasks.ToArray());
|
Task.WaitAll(tasks.ToArray());
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Task.Delay(1000).Wait();
|
||||||
update(null, "");
|
update(null, "");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -148,8 +137,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var proxies = GetProxies();
|
if (_proxies == null)
|
||||||
if (proxies == null)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,13 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.IO;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Handler.CoreConfig;
|
|
||||||
using v2rayN.Handler.Fmt;
|
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本软件配置文件处理类
|
/// 本软件配置文件处理类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class ConfigHandler
|
public class ConfigHandler
|
||||||
{
|
{
|
||||||
private static string configRes = Global.ConfigFileName;
|
private static string configRes = Global.ConfigFileName;
|
||||||
private static readonly object objLock = new();
|
private static readonly object objLock = new();
|
||||||
@@ -129,20 +124,16 @@ namespace v2rayN.Handler
|
|||||||
mtu = 9000,
|
mtu = 9000,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (config.guiItem == null)
|
config.guiItem ??= new()
|
||||||
{
|
{
|
||||||
config.guiItem = new()
|
enableStatistics = false,
|
||||||
{
|
};
|
||||||
enableStatistics = false,
|
config.msgUIItem ??= new();
|
||||||
};
|
|
||||||
}
|
config.uiItem ??= new UIItem()
|
||||||
if (config.uiItem == null)
|
|
||||||
{
|
{
|
||||||
config.uiItem = new UIItem()
|
enableAutoAdjustMainLvColWidth = true
|
||||||
{
|
};
|
||||||
enableAutoAdjustMainLvColWidth = true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (config.uiItem.mainColumnItem == null)
|
if (config.uiItem.mainColumnItem == null)
|
||||||
{
|
{
|
||||||
config.uiItem.mainColumnItem = new();
|
config.uiItem.mainColumnItem = new();
|
||||||
@@ -178,6 +169,13 @@ namespace v2rayN.Handler
|
|||||||
config.speedTestItem.speedPingTestUrl = Global.SpeedPingTestUrl;
|
config.speedTestItem.speedPingTestUrl = Global.SpeedPingTestUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.mux4RayItem ??= new()
|
||||||
|
{
|
||||||
|
concurrency = 8,
|
||||||
|
xudpConcurrency = 16,
|
||||||
|
xudpProxyUDP443 = "reject"
|
||||||
|
};
|
||||||
|
|
||||||
if (config.mux4SboxItem == null)
|
if (config.mux4SboxItem == null)
|
||||||
{
|
{
|
||||||
config.mux4SboxItem = new()
|
config.mux4SboxItem = new()
|
||||||
@@ -206,7 +204,6 @@ namespace v2rayN.Handler
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyConfig.Instance.SetConfig(config);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,13 +353,64 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
#region Server
|
#region Server
|
||||||
|
|
||||||
|
public static int AddServer(Config config, ProfileItem profileItem)
|
||||||
|
{
|
||||||
|
var item = LazyConfig.Instance.GetProfileItem(profileItem.indexId);
|
||||||
|
if (item is null)
|
||||||
|
{
|
||||||
|
item = profileItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.coreType = profileItem.coreType;
|
||||||
|
item.remarks = profileItem.remarks;
|
||||||
|
item.address = profileItem.address;
|
||||||
|
item.port = profileItem.port;
|
||||||
|
|
||||||
|
item.id = profileItem.id;
|
||||||
|
item.alterId = profileItem.alterId;
|
||||||
|
item.security = profileItem.security;
|
||||||
|
item.flow = profileItem.flow;
|
||||||
|
|
||||||
|
item.network = profileItem.network;
|
||||||
|
item.headerType = profileItem.headerType;
|
||||||
|
item.requestHost = profileItem.requestHost;
|
||||||
|
item.path = profileItem.path;
|
||||||
|
|
||||||
|
item.streamSecurity = profileItem.streamSecurity;
|
||||||
|
item.sni = profileItem.sni;
|
||||||
|
item.allowInsecure = profileItem.allowInsecure;
|
||||||
|
item.fingerprint = profileItem.fingerprint;
|
||||||
|
item.alpn = profileItem.alpn;
|
||||||
|
|
||||||
|
item.publicKey = profileItem.publicKey;
|
||||||
|
item.shortId = profileItem.shortId;
|
||||||
|
item.spiderX = profileItem.spiderX;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret = item.configType switch
|
||||||
|
{
|
||||||
|
EConfigType.VMess => AddVMessServer(config, item),
|
||||||
|
EConfigType.Shadowsocks => AddShadowsocksServer(config, item),
|
||||||
|
EConfigType.Socks => AddSocksServer(config, item),
|
||||||
|
EConfigType.Http => AddHttpServer(config, item),
|
||||||
|
EConfigType.Trojan => AddTrojanServer(config, item),
|
||||||
|
EConfigType.VLESS => AddVlessServer(config, item),
|
||||||
|
EConfigType.Hysteria2 => AddHysteria2Server(config, item),
|
||||||
|
EConfigType.Tuic => AddTuicServer(config, item),
|
||||||
|
EConfigType.Wireguard => AddWireguardServer(config, item),
|
||||||
|
_ => -1,
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add or edit server
|
/// Add or edit server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config"></param>
|
/// <param name="config"></param>
|
||||||
/// <param name="profileItem"></param>
|
/// <param name="profileItem"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static int AddServer(Config config, ProfileItem profileItem, bool toFile = true)
|
public static int AddVMessServer(Config config, ProfileItem profileItem, bool toFile = true)
|
||||||
{
|
{
|
||||||
profileItem.configType = EConfigType.VMess;
|
profileItem.configType = EConfigType.VMess;
|
||||||
|
|
||||||
@@ -620,7 +668,21 @@ namespace v2rayN.Handler
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static int EditCustomServer(Config config, ProfileItem profileItem)
|
public static int EditCustomServer(Config config, ProfileItem profileItem)
|
||||||
{
|
{
|
||||||
if (SQLiteHelper.Instance.Update(profileItem) > 0)
|
var item = LazyConfig.Instance.GetProfileItem(profileItem.indexId);
|
||||||
|
if (item is null)
|
||||||
|
{
|
||||||
|
item = profileItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.remarks = profileItem.remarks;
|
||||||
|
item.address = profileItem.address;
|
||||||
|
item.coreType = profileItem.coreType;
|
||||||
|
item.displayLog = profileItem.displayLog;
|
||||||
|
item.preSocksPort = profileItem.preSocksPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SQLiteHelper.Instance.Update(item) > 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1092,7 +1154,7 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
var profileItem = LazyConfig.Instance.GetProfileItem(indexId) ?? new();
|
var profileItem = LazyConfig.Instance.GetProfileItem(indexId) ?? new();
|
||||||
profileItem.indexId = indexId;
|
profileItem.indexId = indexId;
|
||||||
profileItem.remarks = coreType == ECoreType.sing_box ? Resx.ResUI.menuSetDefaultMultipleServer : Resx.ResUI.menuSetDefaultLoadBalanceServer;
|
profileItem.remarks = coreType == ECoreType.sing_box ? ResUI.menuSetDefaultMultipleServer : ResUI.menuSetDefaultLoadBalanceServer;
|
||||||
profileItem.address = Global.CoreMultipleLoadConfigFileName;
|
profileItem.address = Global.CoreMultipleLoadConfigFileName;
|
||||||
profileItem.configType = EConfigType.Custom;
|
profileItem.configType = EConfigType.Custom;
|
||||||
profileItem.coreType = coreType;
|
profileItem.coreType = coreType;
|
||||||
@@ -1190,7 +1252,7 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
var addStatus = profileItem.configType switch
|
var addStatus = profileItem.configType switch
|
||||||
{
|
{
|
||||||
EConfigType.VMess => AddServer(config, profileItem, false),
|
EConfigType.VMess => AddVMessServer(config, profileItem, false),
|
||||||
EConfigType.Shadowsocks => AddShadowsocksServer(config, profileItem, false),
|
EConfigType.Shadowsocks => AddShadowsocksServer(config, profileItem, false),
|
||||||
EConfigType.Socks => AddSocksServer(config, profileItem, false),
|
EConfigType.Socks => AddSocksServer(config, profileItem, false),
|
||||||
EConfigType.Trojan => AddTrojanServer(config, profileItem, false),
|
EConfigType.Trojan => AddTrojanServer(config, profileItem, false),
|
||||||
@@ -1223,7 +1285,10 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
var subRemarks = LazyConfig.Instance.GetSubItem(subid)?.remarks;
|
|
||||||
|
var subItem = LazyConfig.Instance.GetSubItem(subid);
|
||||||
|
var subRemarks = subItem?.remarks;
|
||||||
|
var preSocksPort = subItem?.preSocksPort;
|
||||||
|
|
||||||
List<ProfileItem>? lstProfiles = null;
|
List<ProfileItem>? lstProfiles = null;
|
||||||
//Is sing-box array configuration
|
//Is sing-box array configuration
|
||||||
@@ -1247,6 +1312,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
it.subid = subid;
|
it.subid = subid;
|
||||||
it.isSub = isSub;
|
it.isSub = isSub;
|
||||||
|
it.preSocksPort = preSocksPort;
|
||||||
if (AddCustomServer(config, it, true) == 0)
|
if (AddCustomServer(config, it, true) == 0)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -1303,6 +1369,7 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
profileItem.subid = subid;
|
profileItem.subid = subid;
|
||||||
profileItem.isSub = isSub;
|
profileItem.isSub = isSub;
|
||||||
|
profileItem.preSocksPort = preSocksPort;
|
||||||
if (AddCustomServer(config, profileItem, true) == 0)
|
if (AddCustomServer(config, profileItem, true) == 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1347,6 +1414,10 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
public static int AddBatchServers(Config config, string strData, string subid, bool isSub)
|
public static int AddBatchServers(Config config, string strData, string subid, bool isSub)
|
||||||
{
|
{
|
||||||
|
if (Utils.IsNullOrEmpty(strData))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
List<ProfileItem>? lstOriSub = null;
|
List<ProfileItem>? lstOriSub = null;
|
||||||
if (isSub && !Utils.IsNullOrEmpty(subid))
|
if (isSub && !Utils.IsNullOrEmpty(subid))
|
||||||
{
|
{
|
||||||
@@ -1420,21 +1491,43 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
public static int AddSubItem(Config config, SubItem subItem)
|
public static int AddSubItem(Config config, SubItem subItem)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(subItem.id))
|
var item = LazyConfig.Instance.GetSubItem(subItem.id);
|
||||||
|
if (item is null)
|
||||||
{
|
{
|
||||||
subItem.id = Utils.GetGUID(false);
|
item = subItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.remarks = subItem.remarks;
|
||||||
|
item.url = subItem.url;
|
||||||
|
item.moreUrl = subItem.moreUrl;
|
||||||
|
item.enabled = subItem.enabled;
|
||||||
|
item.autoUpdateInterval = subItem.autoUpdateInterval;
|
||||||
|
item.userAgent = subItem.userAgent;
|
||||||
|
item.sort = subItem.sort;
|
||||||
|
item.filter = subItem.filter;
|
||||||
|
item.updateTime = subItem.updateTime;
|
||||||
|
item.convertTarget = subItem.convertTarget;
|
||||||
|
item.prevProfile = subItem.prevProfile;
|
||||||
|
item.nextProfile = subItem.nextProfile;
|
||||||
|
item.preSocksPort = subItem.preSocksPort;
|
||||||
|
}
|
||||||
|
|
||||||
if (subItem.sort <= 0)
|
if (Utils.IsNullOrEmpty(item.id))
|
||||||
|
{
|
||||||
|
item.id = Utils.GetGUID(false);
|
||||||
|
|
||||||
|
if (item.sort <= 0)
|
||||||
{
|
{
|
||||||
var maxSort = 0;
|
var maxSort = 0;
|
||||||
if (SQLiteHelper.Instance.Table<SubItem>().Count() > 0)
|
if (SQLiteHelper.Instance.Table<SubItem>().Count() > 0)
|
||||||
{
|
{
|
||||||
maxSort = SQLiteHelper.Instance.Table<SubItem>().Max(t => t == null ? 0 : t.sort);
|
maxSort = SQLiteHelper.Instance.Table<SubItem>().Max(t => t == null ? 0 : t.sort);
|
||||||
}
|
}
|
||||||
subItem.sort = maxSort + 1;
|
item.sort = maxSort + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SQLiteHelper.Instance.Replace(subItem) > 0)
|
if (SQLiteHelper.Instance.Replace(item) > 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,9 @@
|
|||||||
using System.IO;
|
namespace ServiceLib.Handler.CoreConfig
|
||||||
using v2rayN.Common;
|
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.CoreConfig
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Core configuration file processing class
|
/// Core configuration file processing class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class CoreConfigClash
|
public class CoreConfigClash
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
using System.IO;
|
namespace ServiceLib.Handler.CoreConfig
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.CoreConfig
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Core configuration file processing class
|
/// Core configuration file processing class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class CoreConfigHandler
|
public class CoreConfigHandler
|
||||||
{
|
{
|
||||||
public static int GenerateClientConfig(ProfileItem node, string? fileName, out string msg, out string content)
|
public static int GenerateClientConfig(ProfileItem node, string? fileName, out string msg, out string content)
|
||||||
{
|
{
|
||||||
@@ -20,7 +15,7 @@ namespace v2rayN.Handler.CoreConfig
|
|||||||
msg = ResUI.CheckServerSettings;
|
msg = ResUI.CheckServerSettings;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
var config = LazyConfig.Instance.GetConfig();
|
var config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
msg = ResUI.InitialConfiguration;
|
msg = ResUI.InitialConfiguration;
|
||||||
if (node.configType == EConfigType.Custom)
|
if (node.configType == EConfigType.Custom)
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.CoreConfig
|
namespace ServiceLib.Handler.CoreConfig
|
||||||
{
|
{
|
||||||
internal class CoreConfigSingbox
|
public class CoreConfigSingbox
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
|
||||||
@@ -706,6 +702,7 @@ namespace v2rayN.Handler.CoreConfig
|
|||||||
enabled = true,
|
enabled = true,
|
||||||
protocol = _config.mux4SboxItem.protocol,
|
protocol = _config.mux4SboxItem.protocol,
|
||||||
max_connections = _config.mux4SboxItem.max_connections,
|
max_connections = _config.mux4SboxItem.max_connections,
|
||||||
|
padding = _config.mux4SboxItem.padding,
|
||||||
};
|
};
|
||||||
outbound.multiplex = mux;
|
outbound.multiplex = mux;
|
||||||
}
|
}
|
||||||
@@ -987,7 +984,7 @@ namespace v2rayN.Handler.CoreConfig
|
|||||||
{
|
{
|
||||||
lstDnsExe = new();
|
lstDnsExe = new();
|
||||||
lstDirectExe = new();
|
lstDirectExe = new();
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo();
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||||
foreach (var it in coreInfo)
|
foreach (var it in coreInfo)
|
||||||
{
|
{
|
||||||
if (it.coreType == ECoreType.v2rayN)
|
if (it.coreType == ECoreType.v2rayN)
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.CoreConfig
|
namespace ServiceLib.Handler.CoreConfig
|
||||||
{
|
{
|
||||||
internal class CoreConfigV2ray
|
public class CoreConfigV2ray
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
|
||||||
@@ -773,7 +770,9 @@ namespace v2rayN.Handler.CoreConfig
|
|||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
outbound.mux.enabled = true;
|
outbound.mux.enabled = true;
|
||||||
outbound.mux.concurrency = 8;
|
outbound.mux.concurrency = _config.mux4RayItem.concurrency;
|
||||||
|
outbound.mux.xudpConcurrency = _config.mux4RayItem.xudpConcurrency;
|
||||||
|
outbound.mux.xudpProxyUDP443 = _config.mux4RayItem.xudpProxyUDP443;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1098,7 +1097,7 @@ namespace v2rayN.Handler.CoreConfig
|
|||||||
address = Utils.IsNullOrEmpty(dNSItem?.domainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.domainDNSAddress,
|
address = Utils.IsNullOrEmpty(dNSItem?.domainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.domainDNSAddress,
|
||||||
domains = [node.address]
|
domains = [node.address]
|
||||||
};
|
};
|
||||||
servers.AsArray().Insert(0, JsonUtils.SerializeToNode(dnsServer));
|
servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1,17 +1,12 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Handler.CoreConfig;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Core process processing class
|
/// Core process processing class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class CoreHandler
|
public class CoreHandler
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
private Process? _process;
|
private Process? _process;
|
||||||
@@ -46,12 +41,6 @@ namespace v2rayN.Handler
|
|||||||
ShowMsg(false, msg);
|
ShowMsg(false, msg);
|
||||||
ShowMsg(true, $"{node.GetSummary()}");
|
ShowMsg(true, $"{node.GetSummary()}");
|
||||||
CoreStop();
|
CoreStop();
|
||||||
if (_config.tunModeItem.enableTun)
|
|
||||||
{
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
Utils.RemoveTunDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
CoreStart(node);
|
CoreStart(node);
|
||||||
|
|
||||||
//In tun mode, do a delay check and restart the core
|
//In tun mode, do a delay check and restart the core
|
||||||
@@ -114,7 +103,7 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
if (!hasProc)
|
if (!hasProc)
|
||||||
{
|
{
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo();
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||||
foreach (var it in coreInfo)
|
foreach (var it in coreInfo)
|
||||||
{
|
{
|
||||||
if (it.coreType == ECoreType.v2rayN)
|
if (it.coreType == ECoreType.v2rayN)
|
||||||
@@ -127,7 +116,7 @@ namespace v2rayN.Handler
|
|||||||
foreach (Process p in existing)
|
foreach (Process p in existing)
|
||||||
{
|
{
|
||||||
string? path = p.MainModule?.FileName;
|
string? path = p.MainModule?.FileName;
|
||||||
if (path == $"{Utils.GetBinPath(vName, it.coreType.ToString())}.exe")
|
if (path == Utils.GetExeName(Utils.GetBinPath(vName, it.coreType.ToString())))
|
||||||
{
|
{
|
||||||
KillProcess(p);
|
KillProcess(p);
|
||||||
}
|
}
|
||||||
@@ -162,7 +151,7 @@ namespace v2rayN.Handler
|
|||||||
string fileName = string.Empty;
|
string fileName = string.Empty;
|
||||||
foreach (string name in coreInfo.coreExes)
|
foreach (string name in coreInfo.coreExes)
|
||||||
{
|
{
|
||||||
string vName = $"{name}.exe";
|
string vName = Utils.GetExeName(name);
|
||||||
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
|
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
|
||||||
if (File.Exists(vName))
|
if (File.Exists(vName))
|
||||||
{
|
{
|
||||||
@@ -195,7 +184,7 @@ namespace v2rayN.Handler
|
|||||||
//}
|
//}
|
||||||
var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
|
var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
|
||||||
_config.runningCoreType = coreType;
|
_config.runningCoreType = coreType;
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo(coreType);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||||
|
|
||||||
var displayLog = node.configType != EConfigType.Custom || node.displayLog;
|
var displayLog = node.configType != EConfigType.Custom || node.displayLog;
|
||||||
var proc = RunProcess(node, coreInfo, "", displayLog);
|
var proc = RunProcess(node, coreInfo, "", displayLog);
|
||||||
@@ -229,7 +218,7 @@ namespace v2rayN.Handler
|
|||||||
coreType = preCoreType,
|
coreType = preCoreType,
|
||||||
configType = EConfigType.Socks,
|
configType = EConfigType.Socks,
|
||||||
address = Global.Loopback,
|
address = Global.Loopback,
|
||||||
port = node.preSocksPort
|
port = node.preSocksPort.Value,
|
||||||
};
|
};
|
||||||
_config.runningCoreType = preCoreType;
|
_config.runningCoreType = preCoreType;
|
||||||
}
|
}
|
||||||
@@ -238,7 +227,7 @@ namespace v2rayN.Handler
|
|||||||
string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
|
string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
|
||||||
if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0)
|
if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0)
|
||||||
{
|
{
|
||||||
var coreInfo2 = LazyConfig.Instance.GetCoreInfo(preCoreType);
|
var coreInfo2 = CoreInfoHandler.Instance.GetCoreInfo(preCoreType);
|
||||||
var proc2 = RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true);
|
var proc2 = RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true);
|
||||||
if (proc2 is not null)
|
if (proc2 is not null)
|
||||||
{
|
{
|
||||||
@@ -256,7 +245,7 @@ namespace v2rayN.Handler
|
|||||||
ShowMsg(false, configPath);
|
ShowMsg(false, configPath);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo(coreType);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||||
var proc = RunProcess(new(), coreInfo, $" -c {Global.CoreSpeedtestConfigFileName}", true);
|
var proc = RunProcess(new(), coreInfo, $" -c {Global.CoreSpeedtestConfigFileName}", true);
|
||||||
if (proc is null)
|
if (proc is null)
|
||||||
{
|
{
|
||||||
217
v2rayN/ServiceLib/Handler/CoreInfoHandler.cs
Normal file
217
v2rayN/ServiceLib/Handler/CoreInfoHandler.cs
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
using System.Runtime.Intrinsics.X86;
|
||||||
|
|
||||||
|
namespace ServiceLib.Handler
|
||||||
|
{
|
||||||
|
public sealed class CoreInfoHandler
|
||||||
|
{
|
||||||
|
private static readonly Lazy<CoreInfoHandler> _instance = new(() => new());
|
||||||
|
private List<CoreInfo>? _coreInfo;
|
||||||
|
public static CoreInfoHandler Instance => _instance.Value;
|
||||||
|
|
||||||
|
public CoreInfoHandler()
|
||||||
|
{
|
||||||
|
InitCoreInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CoreInfo? GetCoreInfo(ECoreType coreType)
|
||||||
|
{
|
||||||
|
if (_coreInfo == null)
|
||||||
|
{
|
||||||
|
InitCoreInfo();
|
||||||
|
}
|
||||||
|
return _coreInfo?.FirstOrDefault(t => t.coreType == coreType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CoreInfo> GetCoreInfo()
|
||||||
|
{
|
||||||
|
if (_coreInfo == null)
|
||||||
|
{
|
||||||
|
InitCoreInfo();
|
||||||
|
}
|
||||||
|
return _coreInfo ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitCoreInfo()
|
||||||
|
{
|
||||||
|
_coreInfo = [];
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.v2rayN,
|
||||||
|
coreUrl = Global.NUrl,
|
||||||
|
coreReleaseApiUrl = Global.NUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN-32.zip",
|
||||||
|
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip",
|
||||||
|
coreDownloadUrlArm64 = Global.NUrl + "/download/{0}/v2rayN-arm64.zip",
|
||||||
|
coreDownloadUrlLinux32 = Global.NUrl + "/download/{0}/v2rayN-linux-32.zip",
|
||||||
|
coreDownloadUrlLinux64 = Global.NUrl + "/download/{0}/v2rayN-linux-64.zip",
|
||||||
|
coreDownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip",
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.v2fly,
|
||||||
|
coreExes = new List<string> { "wv2ray", "v2ray" },
|
||||||
|
arguments = "",
|
||||||
|
coreUrl = Global.V2flyCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
match = "V2Ray",
|
||||||
|
versionArg = "-version",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.SagerNet,
|
||||||
|
coreExes = new List<string> { "SagerNet", "v2ray" },
|
||||||
|
arguments = "run",
|
||||||
|
coreUrl = Global.SagerNetCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.SagerNetCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
match = "V2Ray",
|
||||||
|
versionArg = "version",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.v2fly_v5,
|
||||||
|
coreExes = new List<string> { "v2ray" },
|
||||||
|
arguments = "run -c config.json -format jsonv5",
|
||||||
|
coreUrl = Global.V2flyCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
match = "V2Ray",
|
||||||
|
versionArg = "version",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.Xray,
|
||||||
|
coreExes = new List<string> { "xray", "wxray" },
|
||||||
|
arguments = "run {0}",
|
||||||
|
coreUrl = Global.XrayCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
coreDownloadUrl32 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-32.zip",
|
||||||
|
coreDownloadUrl64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
|
||||||
|
coreDownloadUrlArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-arm64-v8a.zip",
|
||||||
|
coreDownloadUrlLinux32 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-32.zip",
|
||||||
|
coreDownloadUrlLinux64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-64.zip",
|
||||||
|
coreDownloadUrlLinuxArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-arm64-v8a.zip",
|
||||||
|
match = "Xray",
|
||||||
|
versionArg = "-version",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.clash,
|
||||||
|
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
|
||||||
|
arguments = "-f config.json" + PortableMode(),
|
||||||
|
coreUrl = Global.ClashCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.ClashCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
match = "v",
|
||||||
|
versionArg = "-v",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.clash_meta,
|
||||||
|
coreExes = new List<string> { "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" },
|
||||||
|
arguments = "-f config.json" + PortableMode(),
|
||||||
|
coreUrl = Global.ClashMetaCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.ClashMetaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
match = "v",
|
||||||
|
versionArg = "-v",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.mihomo,
|
||||||
|
coreExes = new List<string> { $"mihomo-windows-amd64{(Avx2.X64.IsSupported ? "" : "-compatible")}", "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-windows-386", "mihomo", "clash" },
|
||||||
|
arguments = "-f config.json" + PortableMode(),
|
||||||
|
coreUrl = Global.MihomoCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
coreDownloadUrl32 = Global.ClashMetaCoreUrl + "/download/{0}/mihomo-windows-386-{0}.zip",
|
||||||
|
coreDownloadUrl64 = Global.ClashMetaCoreUrl + "/download/{0}/mihomo-windows-amd64-compatible-{0}.zip",
|
||||||
|
coreDownloadUrlArm64 = Global.ClashMetaCoreUrl + "/download/{0}/mihomo-windows-arm64-{0}.zip",
|
||||||
|
coreDownloadUrlLinux32 = Global.ClashMetaCoreUrl + "/download/{0}/mihomo-linux-386-{0}.gz",
|
||||||
|
coreDownloadUrlLinux64 = Global.ClashMetaCoreUrl + "/download/{0}/mihomo-linux-amd64-compatible-{0}.gz",
|
||||||
|
coreDownloadUrlLinuxArm64 = Global.ClashMetaCoreUrl + "/download/{0}/mihomo-linux-arm64-{0}.gz",
|
||||||
|
match = "Mihomo",
|
||||||
|
versionArg = "-v",
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.hysteria,
|
||||||
|
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
||||||
|
arguments = "",
|
||||||
|
coreUrl = Global.HysteriaCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.naiveproxy,
|
||||||
|
coreExes = new List<string> { "naiveproxy", "naive" },
|
||||||
|
arguments = "config.json",
|
||||||
|
coreUrl = Global.NaiveproxyCoreUrl,
|
||||||
|
redirectInfo = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.tuic,
|
||||||
|
coreExes = new List<string> { "tuic-client", "tuic" },
|
||||||
|
arguments = "-c config.json",
|
||||||
|
coreUrl = Global.TuicCoreUrl,
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.sing_box,
|
||||||
|
coreExes = new List<string> { "sing-box-client", "sing-box" },
|
||||||
|
arguments = "run {0} --disable-color",
|
||||||
|
coreUrl = Global.SingboxCoreUrl,
|
||||||
|
redirectInfo = true,
|
||||||
|
coreReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
coreDownloadUrl32 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-386.zip",
|
||||||
|
coreDownloadUrl64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-amd64.zip",
|
||||||
|
coreDownloadUrlArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-arm64.zip",
|
||||||
|
coreDownloadUrlLinux32 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-386.tar.gz",
|
||||||
|
coreDownloadUrlLinux64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-amd64.tar.gz",
|
||||||
|
coreDownloadUrlLinuxArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-arm64.tar.gz",
|
||||||
|
match = "sing-box",
|
||||||
|
versionArg = "version",
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.juicity,
|
||||||
|
coreExes = new List<string> { "juicity-client", "juicity" },
|
||||||
|
arguments = "run -c config.json",
|
||||||
|
coreUrl = Global.JuicityCoreUrl
|
||||||
|
});
|
||||||
|
|
||||||
|
_coreInfo.Add(new CoreInfo
|
||||||
|
{
|
||||||
|
coreType = ECoreType.hysteria2,
|
||||||
|
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
||||||
|
arguments = "",
|
||||||
|
coreUrl = Global.HysteriaCoreUrl,
|
||||||
|
coreReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
redirectInfo = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private string PortableMode()
|
||||||
|
{
|
||||||
|
return $" -d \"{Utils.GetBinPath("")}\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,14 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///Download
|
///Download
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class DownloadHandle
|
public class DownloadHandler
|
||||||
{
|
{
|
||||||
public event EventHandler<ResultEventArgs>? UpdateCompleted;
|
public event EventHandler<ResultEventArgs>? UpdateCompleted;
|
||||||
|
|
||||||
@@ -34,7 +30,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||||
|
|
||||||
var progress = new Progress<string>();
|
var progress = new Progress<string>();
|
||||||
progress.ProgressChanged += (sender, value) =>
|
progress.ProgressChanged += (sender, value) =>
|
||||||
@@ -62,11 +58,11 @@ namespace v2rayN.Handler
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DownloadFileAsync(string url, bool blProxy, int downloadTimeout)
|
public async Task DownloadFileAsync(string url, string fileName, bool blProxy, int downloadTimeout)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||||
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, $"{ResUI.Downloading} {url}"));
|
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, $"{ResUI.Downloading} {url}"));
|
||||||
|
|
||||||
var progress = new Progress<double>();
|
var progress = new Progress<double>();
|
||||||
@@ -78,7 +74,7 @@ namespace v2rayN.Handler
|
|||||||
var webProxy = GetWebProxy(blProxy);
|
var webProxy = GetWebProxy(blProxy);
|
||||||
await DownloaderHelper.Instance.DownloadFileAsync(webProxy,
|
await DownloaderHelper.Instance.DownloadFileAsync(webProxy,
|
||||||
url,
|
url,
|
||||||
Utils.GetTempPath(Utils.GetDownloadFileName(url)),
|
fileName,
|
||||||
progress,
|
progress,
|
||||||
downloadTimeout);
|
downloadTimeout);
|
||||||
}
|
}
|
||||||
@@ -96,7 +92,7 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
public async Task<string?> UrlRedirectAsync(string url, bool blProxy)
|
public async Task<string?> UrlRedirectAsync(string url, bool blProxy)
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||||
var webRequestHandler = new SocketsHttpHandler
|
var webRequestHandler = new SocketsHttpHandler
|
||||||
{
|
{
|
||||||
AllowAutoRedirect = false,
|
AllowAutoRedirect = false,
|
||||||
@@ -185,7 +181,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||||
var webProxy = GetWebProxy(blProxy);
|
var webProxy = GetWebProxy(blProxy);
|
||||||
var client = new HttpClient(new SocketsHttpHandler()
|
var client = new HttpClient(new SocketsHttpHandler()
|
||||||
{
|
{
|
||||||
@@ -230,7 +226,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||||
|
|
||||||
var webProxy = GetWebProxy(blProxy);
|
var webProxy = GetWebProxy(blProxy);
|
||||||
|
|
||||||
@@ -264,7 +260,7 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var config = LazyConfig.Instance.GetConfig();
|
var config = LazyConfig.Instance.Config;
|
||||||
int responseTime = await GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10);
|
int responseTime = await GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10);
|
||||||
return responseTime;
|
return responseTime;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.IO;
|
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
namespace ServiceLib.Handler.Fmt
|
||||||
{
|
{
|
||||||
internal class BaseFmt
|
public class BaseFmt
|
||||||
{
|
{
|
||||||
protected static string GetIpv6(string address)
|
protected static string GetIpv6(string address)
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class ClashFmt : BaseFmt
|
public class ClashFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class FmtHandler
|
public class FmtHandler
|
||||||
{
|
{
|
||||||
public static string? GetShareUri(ProfileItem item)
|
public static string? GetShareUri(ProfileItem item)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class Hysteria2Fmt : BaseFmt
|
public class Hysteria2Fmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class NaiveproxyFmt : BaseFmt
|
public class NaiveproxyFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
namespace ServiceLib.Handler.Fmt
|
||||||
{
|
{
|
||||||
internal class ShadowsocksFmt : BaseFmt
|
public class ShadowsocksFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class SingboxFmt : BaseFmt
|
public class SingboxFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class SocksFmt : BaseFmt
|
public class SocksFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class TrojanFmt : BaseFmt
|
public class TrojanFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class TuicFmt : BaseFmt
|
public class TuicFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class V2rayFmt : BaseFmt
|
public class V2rayFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class VLESSFmt : BaseFmt
|
public class VLESSFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class VmessFmt : BaseFmt
|
public class VmessFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Handler.Fmt
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Fmt
|
|
||||||
{
|
{
|
||||||
internal class WireguardFmt : BaseFmt
|
public class WireguardFmt : BaseFmt
|
||||||
{
|
{
|
||||||
public static ProfileItem? Resolve(string str, out string msg)
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
{
|
{
|
||||||
242
v2rayN/ServiceLib/Handler/LazyConfig.cs
Normal file
242
v2rayN/ServiceLib/Handler/LazyConfig.cs
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
namespace ServiceLib.Handler
|
||||||
|
{
|
||||||
|
public sealed class LazyConfig
|
||||||
|
{
|
||||||
|
private static readonly Lazy<LazyConfig> _instance = new(() => new());
|
||||||
|
private Config _config;
|
||||||
|
private int? _statePort;
|
||||||
|
private int? _statePort2;
|
||||||
|
|
||||||
|
public static LazyConfig Instance => _instance.Value;
|
||||||
|
public Config Config => _config;
|
||||||
|
|
||||||
|
public int StatePort
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
_statePort ??= Utils.GetFreePort(GetLocalPort(EInboundProtocol.api));
|
||||||
|
return _statePort.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StatePort2
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
_statePort2 ??= Utils.GetFreePort(GetLocalPort(EInboundProtocol.api2));
|
||||||
|
return _statePort2.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Job? _processJob;
|
||||||
|
|
||||||
|
public LazyConfig()
|
||||||
|
{
|
||||||
|
SQLiteHelper.Instance.CreateTable<SubItem>();
|
||||||
|
SQLiteHelper.Instance.CreateTable<ProfileItem>();
|
||||||
|
SQLiteHelper.Instance.CreateTable<ServerStatItem>();
|
||||||
|
SQLiteHelper.Instance.CreateTable<RoutingItem>();
|
||||||
|
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
|
||||||
|
SQLiteHelper.Instance.CreateTable<DNSItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Config
|
||||||
|
|
||||||
|
public void SetConfig(Config config) => _config = config;
|
||||||
|
|
||||||
|
public int GetLocalPort(EInboundProtocol protocol)
|
||||||
|
{
|
||||||
|
var localPort = _config.inbound.FirstOrDefault(t => t.protocol == nameof(EInboundProtocol.socks))?.localPort ?? 10808;
|
||||||
|
return localPort + (int)protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddProcess(IntPtr processHandle)
|
||||||
|
{
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
|
_processJob ??= new();
|
||||||
|
_processJob?.AddProcess(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Config
|
||||||
|
|
||||||
|
#region SqliteHelper
|
||||||
|
|
||||||
|
public List<SubItem> SubItems()
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<SubItem>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubItem GetSubItem(string subid)
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<SubItem>().FirstOrDefault(t => t.id == subid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProfileItem> ProfileItems(string subid)
|
||||||
|
{
|
||||||
|
if (Utils.IsNullOrEmpty(subid))
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<ProfileItem>().ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> ProfileItemIndexes(string subid)
|
||||||
|
{
|
||||||
|
if (Utils.IsNullOrEmpty(subid))
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<ProfileItem>().Select(t => t.indexId).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).Select(t => t.indexId).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProfileItemModel> ProfileItems(string subid, string filter)
|
||||||
|
{
|
||||||
|
var sql = @$"select a.*
|
||||||
|
,b.remarks subRemarks
|
||||||
|
from ProfileItem a
|
||||||
|
left join SubItem b on a.subid = b.id
|
||||||
|
where 1=1 ";
|
||||||
|
if (!Utils.IsNullOrEmpty(subid))
|
||||||
|
{
|
||||||
|
sql += $" and a.subid = '{subid}'";
|
||||||
|
}
|
||||||
|
if (!Utils.IsNullOrEmpty(filter))
|
||||||
|
{
|
||||||
|
if (filter.Contains('\''))
|
||||||
|
{
|
||||||
|
filter = filter.Replace("'", "");
|
||||||
|
}
|
||||||
|
sql += String.Format(" and (a.remarks like '%{0}%' or a.address like '%{0}%') ", filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQLiteHelper.Instance.Query<ProfileItemModel>(sql).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProfileItemModel> ProfileItemsEx(string subid, string filter)
|
||||||
|
{
|
||||||
|
var lstModel = ProfileItems(_config.subIndexId, filter);
|
||||||
|
|
||||||
|
ConfigHandler.SetDefaultServer(_config, lstModel);
|
||||||
|
|
||||||
|
var lstServerStat = (_config.guiItem.enableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
|
||||||
|
var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
|
||||||
|
lstModel = (from t in lstModel
|
||||||
|
join t2 in lstServerStat on t.indexId equals t2.indexId into t2b
|
||||||
|
from t22 in t2b.DefaultIfEmpty()
|
||||||
|
join t3 in lstProfileExs on t.indexId equals t3.indexId into t3b
|
||||||
|
from t33 in t3b.DefaultIfEmpty()
|
||||||
|
select new ProfileItemModel
|
||||||
|
{
|
||||||
|
indexId = t.indexId,
|
||||||
|
configType = t.configType,
|
||||||
|
remarks = t.remarks,
|
||||||
|
address = t.address,
|
||||||
|
port = t.port,
|
||||||
|
security = t.security,
|
||||||
|
network = t.network,
|
||||||
|
streamSecurity = t.streamSecurity,
|
||||||
|
subid = t.subid,
|
||||||
|
subRemarks = t.subRemarks,
|
||||||
|
isActive = t.indexId == _config.indexId,
|
||||||
|
sort = t33 == null ? 0 : t33.sort,
|
||||||
|
delay = t33 == null ? 0 : t33.delay,
|
||||||
|
delayVal = t33?.delay != 0 ? $"{t33?.delay} {Global.DelayUnit}" : string.Empty,
|
||||||
|
speedVal = t33?.speed != 0 ? $"{t33?.speed} {Global.SpeedUnit}" : string.Empty,
|
||||||
|
todayDown = t22 == null ? "" : Utils.HumanFy(t22.todayDown),
|
||||||
|
todayUp = t22 == null ? "" : Utils.HumanFy(t22.todayUp),
|
||||||
|
totalDown = t22 == null ? "" : Utils.HumanFy(t22.totalDown),
|
||||||
|
totalUp = t22 == null ? "" : Utils.HumanFy(t22.totalUp)
|
||||||
|
}).OrderBy(t => t.sort).ToList();
|
||||||
|
|
||||||
|
return lstModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileItem? GetProfileItem(string indexId)
|
||||||
|
{
|
||||||
|
if (Utils.IsNullOrEmpty(indexId))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.indexId == indexId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileItem? GetProfileItemViaRemarks(string remarks)
|
||||||
|
{
|
||||||
|
if (Utils.IsNullOrEmpty(remarks))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.remarks == remarks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RoutingItem> RoutingItems()
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoutingItem GetRoutingItem(string id)
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<RoutingItem>().FirstOrDefault(it => it.locked == false && it.id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DNSItem> DNSItems()
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<DNSItem>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DNSItem GetDNSItem(ECoreType eCoreType)
|
||||||
|
{
|
||||||
|
return SQLiteHelper.Instance.Table<DNSItem>().FirstOrDefault(it => it.coreType == eCoreType);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion SqliteHelper
|
||||||
|
|
||||||
|
#region Core Type
|
||||||
|
|
||||||
|
public List<string> GetShadowsocksSecurities(ProfileItem profileItem)
|
||||||
|
{
|
||||||
|
var coreType = GetCoreType(profileItem, EConfigType.Shadowsocks);
|
||||||
|
switch (coreType)
|
||||||
|
{
|
||||||
|
case ECoreType.v2fly:
|
||||||
|
return Global.SsSecurities;
|
||||||
|
|
||||||
|
case ECoreType.Xray:
|
||||||
|
return Global.SsSecuritiesInXray;
|
||||||
|
|
||||||
|
case ECoreType.sing_box:
|
||||||
|
return Global.SsSecuritiesInSingbox;
|
||||||
|
}
|
||||||
|
return Global.SsSecuritiesInSagerNet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType)
|
||||||
|
{
|
||||||
|
if (profileItem?.coreType != null)
|
||||||
|
{
|
||||||
|
return (ECoreType)profileItem.coreType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_config.coreTypeItem == null)
|
||||||
|
{
|
||||||
|
return ECoreType.Xray;
|
||||||
|
}
|
||||||
|
var item = _config.coreTypeItem.FirstOrDefault(it => it.configType == eConfigType);
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
return ECoreType.Xray;
|
||||||
|
}
|
||||||
|
return item.coreType;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Core Type
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,16 @@
|
|||||||
using MaterialDesignThemes.Wpf;
|
using ReactiveUI;
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
public class NoticeHandler
|
public class NoticeHandler
|
||||||
{
|
{
|
||||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
|
||||||
|
|
||||||
public NoticeHandler(ISnackbarMessageQueue snackbarMessageQueue)
|
|
||||||
{
|
|
||||||
_snackbarMessageQueue = snackbarMessageQueue ?? throw new ArgumentNullException(nameof(snackbarMessageQueue));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Enqueue(string? content)
|
public void Enqueue(string? content)
|
||||||
{
|
{
|
||||||
if (content.IsNullOrEmpty())
|
if (content.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_snackbarMessageQueue?.Enqueue(content);
|
MessageBus.Current.SendMessage(content, Global.CommandSendSnackMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessage(string? content)
|
public void SendMessage(string? content)
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Reactive.Linq;
|
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
//using System.Reactive.Linq;
|
||||||
|
|
||||||
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
internal class ProfileExHandler
|
public class ProfileExHandler
|
||||||
{
|
{
|
||||||
private static readonly Lazy<ProfileExHandler> _instance = new(() => new());
|
private static readonly Lazy<ProfileExHandler> _instance = new(() => new());
|
||||||
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
||||||
@@ -1,27 +1,19 @@
|
|||||||
using ReactiveUI;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
internal class SpeedtestHandler
|
public class SpeedtestHandler
|
||||||
{
|
{
|
||||||
private Config? _config;
|
private Config? _config;
|
||||||
private CoreHandler _coreHandler;
|
private CoreHandler _coreHandler;
|
||||||
private List<ServerTestItem> _selecteds;
|
private List<ServerTestItem> _selecteds;
|
||||||
private ESpeedActionType _actionType;
|
private ESpeedActionType _actionType;
|
||||||
private Action<string, string, string> _updateFunc;
|
private Action<SpeedTestResult> _updateFunc;
|
||||||
|
private bool _exitLoop = false;
|
||||||
|
|
||||||
public SpeedtestHandler(Config config)
|
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> update)
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<string, string, string> update)
|
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_coreHandler = coreHandler;
|
_coreHandler = coreHandler;
|
||||||
@@ -91,6 +83,12 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ExitLoop()
|
||||||
|
{
|
||||||
|
_exitLoop = true;
|
||||||
|
UpdateFunc("", ResUI.SpeedtestingStop);
|
||||||
|
}
|
||||||
|
|
||||||
private Task RunTcping()
|
private Task RunTcping()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -146,7 +144,7 @@ namespace v2rayN.Handler
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadHandle downloadHandle = new DownloadHandle();
|
DownloadHandler downloadHandle = new DownloadHandler();
|
||||||
|
|
||||||
List<Task> tasks = new();
|
List<Task> tasks = new();
|
||||||
foreach (var it in _selecteds)
|
foreach (var it in _selecteds)
|
||||||
@@ -213,22 +211,11 @@ namespace v2rayN.Handler
|
|||||||
string url = _config.speedTestItem.speedTestUrl;
|
string url = _config.speedTestItem.speedTestUrl;
|
||||||
var timeout = _config.speedTestItem.speedTestTimeout;
|
var timeout = _config.speedTestItem.speedTestTimeout;
|
||||||
|
|
||||||
DownloadHandle downloadHandle = new();
|
DownloadHandler downloadHandle = new();
|
||||||
|
|
||||||
var exitLoop = false;
|
|
||||||
MessageBus.Current.Listen<string>(Global.CommandStopSpeedTest)
|
|
||||||
.Subscribe(x =>
|
|
||||||
{
|
|
||||||
if (!exitLoop)
|
|
||||||
{
|
|
||||||
UpdateFunc("", ResUI.SpeedtestingStop);
|
|
||||||
}
|
|
||||||
exitLoop = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var it in _selecteds)
|
foreach (var it in _selecteds)
|
||||||
{
|
{
|
||||||
if (exitLoop)
|
if (_exitLoop)
|
||||||
{
|
{
|
||||||
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
|
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
|
||||||
continue;
|
continue;
|
||||||
@@ -286,22 +273,11 @@ namespace v2rayN.Handler
|
|||||||
string url = _config.speedTestItem.speedTestUrl;
|
string url = _config.speedTestItem.speedTestUrl;
|
||||||
var timeout = _config.speedTestItem.speedTestTimeout;
|
var timeout = _config.speedTestItem.speedTestTimeout;
|
||||||
|
|
||||||
DownloadHandle downloadHandle = new();
|
DownloadHandler downloadHandle = new();
|
||||||
|
|
||||||
var exitLoop = false;
|
|
||||||
MessageBus.Current.Listen<string>(Global.CommandStopSpeedTest)
|
|
||||||
.Subscribe(x =>
|
|
||||||
{
|
|
||||||
if (!exitLoop)
|
|
||||||
{
|
|
||||||
UpdateFunc("", ResUI.SpeedtestingStop);
|
|
||||||
}
|
|
||||||
exitLoop = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var it in _selecteds)
|
foreach (var it in _selecteds)
|
||||||
{
|
{
|
||||||
if (exitLoop)
|
if (_exitLoop)
|
||||||
{
|
{
|
||||||
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
|
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
|
||||||
continue;
|
continue;
|
||||||
@@ -358,7 +334,7 @@ namespace v2rayN.Handler
|
|||||||
await RunSpeedTestMulti();
|
await RunSpeedTestMulti();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> GetRealPingTime(DownloadHandle downloadHandle, IWebProxy webProxy)
|
private async Task<string> GetRealPingTime(DownloadHandler downloadHandle, IWebProxy webProxy)
|
||||||
{
|
{
|
||||||
int responseTime = await downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10);
|
int responseTime = await downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10);
|
||||||
//string output = Utile.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
|
//string output = Utile.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
|
||||||
@@ -408,7 +384,7 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
private void UpdateFunc(string indexId, string delay, string speed = "")
|
private void UpdateFunc(string indexId, string delay, string speed = "")
|
||||||
{
|
{
|
||||||
_updateFunc(indexId, delay, speed);
|
_updateFunc(new() { IndexId = indexId, Delay = delay, Speed = speed });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
using v2rayN.Models;
|
namespace ServiceLib.Handler.Statistics
|
||||||
|
|
||||||
namespace v2rayN.Handler.Statistics
|
|
||||||
{
|
{
|
||||||
internal class StatisticsHandler
|
public class StatisticsHandler
|
||||||
{
|
{
|
||||||
private static readonly Lazy<StatisticsHandler> instance = new(() => new());
|
private static readonly Lazy<StatisticsHandler> instance = new(() => new());
|
||||||
public static StatisticsHandler Instance => instance.Value;
|
public static StatisticsHandler Instance => instance.Value;
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Statistics
|
namespace ServiceLib.Handler.Statistics
|
||||||
{
|
{
|
||||||
internal class StatisticsSingbox
|
public class StatisticsSingbox
|
||||||
{
|
{
|
||||||
private Config _config;
|
private Config _config;
|
||||||
private bool _exitFlag;
|
private bool _exitFlag;
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
using ProtosLib.Statistics;
|
using ProtosLib.Statistics;
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler.Statistics
|
namespace ServiceLib.Handler.Statistics
|
||||||
{
|
{
|
||||||
internal class StatisticsV2ray
|
public class StatisticsV2ray
|
||||||
{
|
{
|
||||||
private Models.Config _config;
|
private Models.Config _config;
|
||||||
private GrpcChannel? _channel;
|
private GrpcChannel? _channel;
|
||||||
76
v2rayN/ServiceLib/Handler/TaskHandler.cs
Normal file
76
v2rayN/ServiceLib/Handler/TaskHandler.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
namespace ServiceLib.Handler
|
||||||
|
{
|
||||||
|
public class TaskHandler
|
||||||
|
{
|
||||||
|
private static readonly Lazy<TaskHandler> _instance = new(() => new());
|
||||||
|
public static TaskHandler Instance => _instance.Value;
|
||||||
|
|
||||||
|
public TaskHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegUpdateTask(Config config, Action<bool, string> update)
|
||||||
|
{
|
||||||
|
Task.Run(() => UpdateTaskRunSubscription(config, update));
|
||||||
|
Task.Run(() => UpdateTaskRunGeo(config, update));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateTaskRunSubscription(Config config, Action<bool, string> update)
|
||||||
|
{
|
||||||
|
await Task.Delay(60000);
|
||||||
|
Logging.SaveLog("UpdateTaskRunSubscription");
|
||||||
|
|
||||||
|
var updateHandle = new UpdateHandler();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||||
|
var lstSubs = LazyConfig.Instance.SubItems()
|
||||||
|
.Where(t => t.autoUpdateInterval > 0)
|
||||||
|
.Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var item in lstSubs)
|
||||||
|
{
|
||||||
|
updateHandle.UpdateSubscriptionProcess(config, item.id, true, (bool success, string msg) =>
|
||||||
|
{
|
||||||
|
update(success, msg);
|
||||||
|
if (success)
|
||||||
|
Logging.SaveLog("subscription" + msg);
|
||||||
|
});
|
||||||
|
item.updateTime = updateTime;
|
||||||
|
ConfigHandler.AddSubItem(config, item);
|
||||||
|
|
||||||
|
await Task.Delay(5000);
|
||||||
|
}
|
||||||
|
await Task.Delay(60000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateTaskRunGeo(Config config, Action<bool, string> update)
|
||||||
|
{
|
||||||
|
var autoUpdateGeoTime = DateTime.Now;
|
||||||
|
|
||||||
|
await Task.Delay(1000 * 120);
|
||||||
|
Logging.SaveLog("UpdateTaskRunGeo");
|
||||||
|
|
||||||
|
var updateHandle = new UpdateHandler();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var dtNow = DateTime.Now;
|
||||||
|
if (config.guiItem.autoUpdateInterval > 0)
|
||||||
|
{
|
||||||
|
if ((dtNow - autoUpdateGeoTime).Hours % config.guiItem.autoUpdateInterval == 0)
|
||||||
|
{
|
||||||
|
updateHandle.UpdateGeoFileAll(config, (bool success, string msg) =>
|
||||||
|
{
|
||||||
|
update(false, msg);
|
||||||
|
});
|
||||||
|
autoUpdateGeoTime = dtNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(1000 * 3600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,17 @@
|
|||||||
using DynamicData;
|
using System.Diagnostics;
|
||||||
using Splat;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Windows;
|
|
||||||
using v2rayN.Enums;
|
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
|
||||||
|
|
||||||
namespace v2rayN.Handler
|
namespace ServiceLib.Handler
|
||||||
{
|
{
|
||||||
internal class UpdateHandle
|
public class UpdateHandler
|
||||||
{
|
{
|
||||||
private Action<bool, string> _updateFunc;
|
private Action<bool, string> _updateFunc;
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
private int _timeout = 30;
|
||||||
|
|
||||||
public event EventHandler<ResultEventArgs> AbsoluteCompleted;
|
private class ResultEventArgs
|
||||||
|
|
||||||
public class ResultEventArgs : EventArgs
|
|
||||||
{
|
{
|
||||||
public bool Success;
|
public bool Success;
|
||||||
public string Msg;
|
public string Msg;
|
||||||
@@ -33,37 +25,66 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckUpdateGuiN(Config config, Action<bool, string> update, bool preRelease)
|
public async Task CheckUpdateGuiN(Config config, Action<bool, string> update, bool preRelease)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_updateFunc = update;
|
_updateFunc = update;
|
||||||
var url = string.Empty;
|
var url = string.Empty;
|
||||||
|
var fileName = string.Empty;
|
||||||
|
|
||||||
DownloadHandle downloadHandle = new();
|
DownloadHandler downloadHandle = new();
|
||||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||||
{
|
{
|
||||||
if (args.Success)
|
if (args.Success)
|
||||||
{
|
{
|
||||||
_updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);
|
_updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);
|
||||||
|
_updateFunc(true, Utils.UrlEncode(fileName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_updateFunc(false, args.Msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
downloadHandle.Error += (sender2, args) =>
|
||||||
|
{
|
||||||
|
_updateFunc(false, args.GetException().Message);
|
||||||
|
};
|
||||||
|
|
||||||
|
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, ECoreType.v2rayN));
|
||||||
|
var args = await CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease);
|
||||||
|
if (args.Success)
|
||||||
|
{
|
||||||
|
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN));
|
||||||
|
_updateFunc(false, args.Msg);
|
||||||
|
|
||||||
|
url = args.Url;
|
||||||
|
fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||||
|
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_updateFunc(false, args.Msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
_updateFunc = update;
|
||||||
|
var url = string.Empty;
|
||||||
|
var fileName = string.Empty;
|
||||||
|
|
||||||
|
DownloadHandler downloadHandle = new();
|
||||||
|
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||||
|
{
|
||||||
|
if (args.Success)
|
||||||
|
{
|
||||||
|
_updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);
|
||||||
|
_updateFunc(false, ResUI.MsgUnpacking);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
|
_updateFunc(true, fileName);
|
||||||
fileName = Utils.UrlEncode(fileName);
|
|
||||||
Process process = new()
|
|
||||||
{
|
|
||||||
StartInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = "v2rayUpgrade.exe",
|
|
||||||
Arguments = fileName.AppendQuotes(),
|
|
||||||
WorkingDirectory = Utils.StartupPath()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
process.Start();
|
|
||||||
if (process.Id > 0)
|
|
||||||
{
|
|
||||||
_updateFunc(true, "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -79,83 +100,25 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
_updateFunc(false, args.GetException().Message);
|
_updateFunc(false, args.GetException().Message);
|
||||||
};
|
};
|
||||||
AbsoluteCompleted += (sender2, args) =>
|
|
||||||
|
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, type));
|
||||||
|
var args = await CheckUpdateAsync(downloadHandle, type, preRelease);
|
||||||
|
if (args.Success)
|
||||||
{
|
{
|
||||||
if (args.Success)
|
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type));
|
||||||
{
|
_updateFunc(false, args.Msg);
|
||||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "v2rayN"));
|
|
||||||
_updateFunc(false, args.Msg);
|
|
||||||
|
|
||||||
url = args.Url;
|
url = args.Url;
|
||||||
AskToDownload(downloadHandle, url, true).ContinueWith(task =>
|
fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||||
{
|
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||||
_updateFunc(false, url);
|
}
|
||||||
});
|
else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Locator.Current.GetService<NoticeHandler>()?.Enqueue(args.Msg);
|
|
||||||
_updateFunc(false, args.Msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, "v2rayN"));
|
|
||||||
CheckUpdateAsync(ECoreType.v2rayN, preRelease);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
_updateFunc = update;
|
|
||||||
var url = string.Empty;
|
|
||||||
|
|
||||||
DownloadHandle downloadHandle = new();
|
|
||||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
|
||||||
{
|
{
|
||||||
if (args.Success)
|
if (!args.Msg.IsNullOrEmpty())
|
||||||
{
|
|
||||||
_updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);
|
|
||||||
_updateFunc(false, ResUI.MsgUnpacking);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_updateFunc(true, url);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_updateFunc(false, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
_updateFunc(false, args.Msg);
|
_updateFunc(false, args.Msg);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
downloadHandle.Error += (sender2, args) =>
|
|
||||||
{
|
|
||||||
_updateFunc(true, args.GetException().Message);
|
|
||||||
};
|
|
||||||
|
|
||||||
AbsoluteCompleted += (sender2, args) =>
|
|
||||||
{
|
|
||||||
if (args.Success)
|
|
||||||
{
|
|
||||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "Core"));
|
|
||||||
_updateFunc(false, args.Msg);
|
|
||||||
|
|
||||||
url = args.Url;
|
|
||||||
AskToDownload(downloadHandle, url, true).ContinueWith(task =>
|
|
||||||
{
|
|
||||||
_updateFunc(false, url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Locator.Current.GetService<NoticeHandler>()?.Enqueue(args.Msg);
|
|
||||||
_updateFunc(false, args.Msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, "Core"));
|
|
||||||
CheckUpdateAsync(type, preRelease);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> update)
|
public void UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> update)
|
||||||
@@ -195,7 +158,7 @@ namespace v2rayN.Handler
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var downloadHandle = new DownloadHandle();
|
var downloadHandle = new DownloadHandler();
|
||||||
downloadHandle.Error += (sender2, args) =>
|
downloadHandle.Error += (sender2, args) =>
|
||||||
{
|
{
|
||||||
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
|
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
|
||||||
@@ -233,10 +196,7 @@ namespace v2rayN.Handler
|
|||||||
result = Utils.Base64Decode(result);
|
result = Utils.Base64Decode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
var lstUrl = new List<string>
|
var lstUrl = item.moreUrl.TrimEx().Split(",") ?? [];
|
||||||
{
|
|
||||||
item.moreUrl.TrimEx().Split(",")
|
|
||||||
};
|
|
||||||
foreach (var it in lstUrl)
|
foreach (var it in lstUrl)
|
||||||
{
|
{
|
||||||
var url2 = Utils.GetPunycode(it);
|
var url2 = Utils.GetPunycode(it);
|
||||||
@@ -294,20 +254,18 @@ namespace v2rayN.Handler
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateGeoFileAll(Config config, Action<bool, string> update)
|
public async Task UpdateGeoFileAll(Config config, Action<bool, string> update)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
await UpdateGeoFile("geosite", _config, update);
|
||||||
{
|
await UpdateGeoFile("geoip", _config, update);
|
||||||
await UpdateGeoFile("geosite", _config, update);
|
_updateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
|
||||||
await UpdateGeoFile("geoip", _config, update);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunAvailabilityCheck(Action<bool, string> update)
|
public void RunAvailabilityCheck(Action<bool, string> update)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var time = await (new DownloadHandle()).RunAvailabilityCheck(null);
|
var time = await (new DownloadHandler()).RunAvailabilityCheck(null);
|
||||||
|
|
||||||
update(false, string.Format(ResUI.TestMeOutput, time));
|
update(false, string.Format(ResUI.TestMeOutput, time));
|
||||||
});
|
});
|
||||||
@@ -315,43 +273,43 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
#region private
|
#region private
|
||||||
|
|
||||||
private async void CheckUpdateAsync(ECoreType type, bool preRelease)
|
private async Task<ResultEventArgs> CheckUpdateAsync(DownloadHandler downloadHandle, ECoreType type, bool preRelease)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||||
string url = coreInfo.coreReleaseApiUrl;
|
var url = coreInfo?.coreReleaseApiUrl;
|
||||||
|
|
||||||
var result = await (new DownloadHandle()).DownloadStringAsync(url, true, "");
|
var result = await downloadHandle.DownloadStringAsync(url, true, Global.AppName);
|
||||||
if (!Utils.IsNullOrEmpty(result))
|
if (!Utils.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
ResponseHandler(type, result, preRelease);
|
return await ParseDownloadUrl(type, result, preRelease);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.SaveLog("StatusCode error: " + url);
|
return new ResultEventArgs(false, "");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
_updateFunc(false, ex.Message);
|
_updateFunc(false, ex.Message);
|
||||||
|
return new ResultEventArgs(false, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取V2RayCore版本
|
/// 获取Core版本
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private SemanticVersion GetCoreVersion(ECoreType type)
|
private SemanticVersion GetCoreVersion(ECoreType type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||||
string filePath = string.Empty;
|
string filePath = string.Empty;
|
||||||
foreach (string name in coreInfo.coreExes)
|
foreach (string name in coreInfo.coreExes)
|
||||||
{
|
{
|
||||||
string vName = $"{name}.exe";
|
string vName = Utils.GetExeName(name);
|
||||||
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
|
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
|
||||||
if (File.Exists(vName))
|
if (File.Exists(vName))
|
||||||
{
|
{
|
||||||
@@ -408,7 +366,7 @@ namespace v2rayN.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResponseHandler(ECoreType type, string gitHubReleaseApi, bool preRelease)
|
private async Task<ResultEventArgs> ParseDownloadUrl(ECoreType type, string gitHubReleaseApi, bool preRelease)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -417,11 +375,10 @@ namespace v2rayN.Handler
|
|||||||
var version = new SemanticVersion(gitHubRelease?.TagName!);
|
var version = new SemanticVersion(gitHubRelease?.TagName!);
|
||||||
var body = gitHubRelease?.Body;
|
var body = gitHubRelease?.Body;
|
||||||
|
|
||||||
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||||
|
|
||||||
SemanticVersion curVersion;
|
SemanticVersion curVersion;
|
||||||
string message;
|
string message;
|
||||||
string url;
|
string? url;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ECoreType.v2fly:
|
case ECoreType.v2fly:
|
||||||
@@ -431,23 +388,7 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
curVersion = GetCoreVersion(type);
|
curVersion = GetCoreVersion(type);
|
||||||
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
|
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
|
||||||
string osBit = "64";
|
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"));
|
||||||
switch (RuntimeInformation.ProcessArchitecture)
|
|
||||||
{
|
|
||||||
case Architecture.Arm64:
|
|
||||||
osBit = "arm64-v8a";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Architecture.X86:
|
|
||||||
osBit = "32";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
osBit = "64";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
url = string.Format(coreInfo.coreDownloadUrl64, version.ToVersionString("v"), osBit);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ECoreType.clash:
|
case ECoreType.clash:
|
||||||
@@ -456,62 +397,21 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
curVersion = GetCoreVersion(type);
|
curVersion = GetCoreVersion(type);
|
||||||
message = string.Format(ResUI.IsLatestCore, type, curVersion);
|
message = string.Format(ResUI.IsLatestCore, type, curVersion);
|
||||||
switch (RuntimeInformation.ProcessArchitecture)
|
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"));
|
||||||
{
|
|
||||||
case Architecture.Arm64:
|
|
||||||
url = coreInfo.coreDownloadUrlArm64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Architecture.X86:
|
|
||||||
url = coreInfo.coreDownloadUrl32;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
url = coreInfo.coreDownloadUrl64;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
url = string.Format(url, version.ToVersionString("v"));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ECoreType.sing_box:
|
case ECoreType.sing_box:
|
||||||
{
|
{
|
||||||
curVersion = GetCoreVersion(type);
|
curVersion = GetCoreVersion(type);
|
||||||
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
|
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
|
||||||
switch (RuntimeInformation.ProcessArchitecture)
|
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"), version);
|
||||||
{
|
|
||||||
case Architecture.Arm64:
|
|
||||||
url = coreInfo.coreDownloadUrlArm64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Architecture.X86:
|
|
||||||
url = coreInfo.coreDownloadUrl32;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
url = coreInfo.coreDownloadUrl64;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
url = string.Format(url, version.ToVersionString("v"), version);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ECoreType.v2rayN:
|
case ECoreType.v2rayN:
|
||||||
{
|
{
|
||||||
curVersion = new SemanticVersion(FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString());
|
curVersion = new SemanticVersion(Utils.GetVersionInfo());
|
||||||
message = string.Format(ResUI.IsLatestN, type, curVersion);
|
message = string.Format(ResUI.IsLatestN, type, curVersion);
|
||||||
switch (RuntimeInformation.ProcessArchitecture)
|
url = string.Format(GetUrlFromCore(coreInfo), version);
|
||||||
{
|
|
||||||
case Architecture.Arm64:
|
|
||||||
url = string.Format(coreInfo.coreDownloadUrlArm64, version);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Architecture.X86:
|
|
||||||
url = string.Format(coreInfo.coreDownloadUrl32, version);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
url = string.Format(coreInfo.coreDownloadUrl64, version);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -520,37 +420,42 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
if (curVersion >= version && version != new SemanticVersion(0, 0, 0))
|
if (curVersion >= version && version != new SemanticVersion(0, 0, 0))
|
||||||
{
|
{
|
||||||
AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message));
|
return new ResultEventArgs(false, message);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbsoluteCompleted?.Invoke(this, new ResultEventArgs(true, body, url));
|
return new ResultEventArgs(true, body, url);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
_updateFunc(false, ex.Message);
|
_updateFunc(false, ex.Message);
|
||||||
|
return new ResultEventArgs(false, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AskToDownload(DownloadHandle downloadHandle, string url, bool blAsk)
|
private string? GetUrlFromCore(CoreInfo? coreInfo)
|
||||||
{
|
{
|
||||||
bool blDownload = false;
|
if (Utils.IsWindows())
|
||||||
if (blAsk)
|
|
||||||
{
|
{
|
||||||
if (UI.ShowYesNo(string.Format(ResUI.DownloadYesNo, url)) == MessageBoxResult.Yes)
|
return RuntimeInformation.ProcessArchitecture switch
|
||||||
{
|
{
|
||||||
blDownload = true;
|
Architecture.Arm64 => coreInfo?.coreDownloadUrlArm64,
|
||||||
}
|
Architecture.X86 => coreInfo?.coreDownloadUrl32,
|
||||||
|
Architecture.X64 => coreInfo?.coreDownloadUrl64,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else if (Utils.IsLinux())
|
||||||
{
|
{
|
||||||
blDownload = true;
|
return RuntimeInformation.ProcessArchitecture switch
|
||||||
}
|
{
|
||||||
if (blDownload)
|
Architecture.Arm64 => coreInfo?.coreDownloadUrlLinuxArm64,
|
||||||
{
|
Architecture.X86 => coreInfo?.coreDownloadUrlLinux32,
|
||||||
await downloadHandle.DownloadFileAsync(url, true, 600);
|
Architecture.X64 => coreInfo?.coreDownloadUrlLinux64,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> update)
|
private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> update)
|
||||||
@@ -558,8 +463,9 @@ namespace v2rayN.Handler
|
|||||||
_config = config;
|
_config = config;
|
||||||
_updateFunc = update;
|
_updateFunc = update;
|
||||||
var url = string.Format(Global.GeoUrl, geoName);
|
var url = string.Format(Global.GeoUrl, geoName);
|
||||||
|
var fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||||
|
|
||||||
DownloadHandle downloadHandle = new();
|
DownloadHandler downloadHandle = new();
|
||||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||||
{
|
{
|
||||||
if (args.Success)
|
if (args.Success)
|
||||||
@@ -568,14 +474,8 @@ namespace v2rayN.Handler
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
|
|
||||||
if (File.Exists(fileName))
|
if (File.Exists(fileName))
|
||||||
{
|
{
|
||||||
//Global.coreTypes.ForEach(it =>
|
|
||||||
//{
|
|
||||||
// string targetPath = Utile.GetBinPath($"{geoName}.dat", (ECoreType)Enum.Parse(typeof(ECoreType), it));
|
|
||||||
// File.Copy(fileName, targetPath, true);
|
|
||||||
//});
|
|
||||||
string targetPath = Utils.GetBinPath($"{geoName}.dat");
|
string targetPath = Utils.GetBinPath($"{geoName}.dat");
|
||||||
File.Copy(fileName, targetPath, true);
|
File.Copy(fileName, targetPath, true);
|
||||||
|
|
||||||
@@ -597,7 +497,8 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
_updateFunc(false, args.GetException().Message);
|
_updateFunc(false, args.GetException().Message);
|
||||||
};
|
};
|
||||||
await AskToDownload(downloadHandle, url, false);
|
|
||||||
|
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion private
|
#endregion private
|
||||||
11
v2rayN/ServiceLib/Models/CheckUpdateItem.cs
Normal file
11
v2rayN/ServiceLib/Models/CheckUpdateItem.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace ServiceLib.Models
|
||||||
|
{
|
||||||
|
public class CheckUpdateItem
|
||||||
|
{
|
||||||
|
public bool? isSelected { get; set; }
|
||||||
|
public string coreType { get; set; }
|
||||||
|
public string? remarks { get; set; }
|
||||||
|
public string? fileName { get; set; }
|
||||||
|
public bool? isFinished { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class ClashConnectionModel
|
public class ClashConnectionModel
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class ClashConnections
|
public class ClashConnections
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using static v2rayN.Models.ClashProxies;
|
using static ServiceLib.Models.ClashProxies;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class ClashProviders
|
public class ClashProviders
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class ClashProxies
|
public class ClashProxies
|
||||||
{
|
{
|
||||||
@@ -1,26 +1,18 @@
|
|||||||
using ReactiveUI.Fody.Helpers;
|
namespace ServiceLib.Models
|
||||||
|
|
||||||
namespace v2rayN.Models
|
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ClashProxyModel
|
public class ClashProxyModel
|
||||||
{
|
{
|
||||||
[Reactive]
|
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public string now { get; set; }
|
public string now { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public int delay { get; set; }
|
public int delay { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public string delayName { get; set; }
|
public string delayName { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public bool isActive { get; set; }
|
public bool isActive { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class ComboItem
|
public class ComboItem
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Models
|
||||||
|
|
||||||
namespace v2rayN.Models
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本软件配置文件实体类
|
/// 本软件配置文件实体类
|
||||||
@@ -40,9 +38,11 @@ namespace v2rayN.Models
|
|||||||
public GrpcItem grpcItem { get; set; }
|
public GrpcItem grpcItem { get; set; }
|
||||||
public RoutingBasicItem routingBasicItem { get; set; }
|
public RoutingBasicItem routingBasicItem { get; set; }
|
||||||
public GUIItem guiItem { get; set; }
|
public GUIItem guiItem { get; set; }
|
||||||
|
public MsgUIItem msgUIItem { get; set; }
|
||||||
public UIItem uiItem { get; set; }
|
public UIItem uiItem { get; set; }
|
||||||
public ConstItem constItem { get; set; }
|
public ConstItem constItem { get; set; }
|
||||||
public SpeedTestItem speedTestItem { get; set; }
|
public SpeedTestItem speedTestItem { get; set; }
|
||||||
|
public Mux4RayItem mux4RayItem { get; set; }
|
||||||
public Mux4SboxItem mux4SboxItem { get; set; }
|
public Mux4SboxItem mux4SboxItem { get; set; }
|
||||||
public HysteriaItem hysteriaItem { get; set; }
|
public HysteriaItem hysteriaItem { get; set; }
|
||||||
public ClashUIItem clashUIItem { get; set; }
|
public ClashUIItem clashUIItem { get; set; }
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
using System.Windows.Input;
|
namespace ServiceLib.Models
|
||||||
using v2rayN.Enums;
|
|
||||||
|
|
||||||
namespace v2rayN.Models
|
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class CoreBasicItem
|
public class CoreBasicItem
|
||||||
@@ -110,6 +107,13 @@ namespace v2rayN.Models
|
|||||||
public bool enableLog { get; set; } = true;
|
public bool enableLog { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class MsgUIItem
|
||||||
|
{
|
||||||
|
public string? mainMsgFilter { get; set; }
|
||||||
|
public bool? autoRefresh { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class UIItem
|
public class UIItem
|
||||||
{
|
{
|
||||||
@@ -129,7 +133,6 @@ namespace v2rayN.Models
|
|||||||
public bool enableDragDropSort { get; set; }
|
public bool enableDragDropSort { get; set; }
|
||||||
public bool doubleClick2Activate { get; set; }
|
public bool doubleClick2Activate { get; set; }
|
||||||
public bool autoHideStartup { get; set; }
|
public bool autoHideStartup { get; set; }
|
||||||
public string mainMsgFilter { get; set; }
|
|
||||||
public List<ColumnItem> mainColumnItem { get; set; }
|
public List<ColumnItem> mainColumnItem { get; set; }
|
||||||
public bool showInTaskbar { get; set; }
|
public bool showInTaskbar { get; set; }
|
||||||
}
|
}
|
||||||
@@ -152,7 +155,7 @@ namespace v2rayN.Models
|
|||||||
|
|
||||||
public bool Shift { get; set; }
|
public bool Shift { get; set; }
|
||||||
|
|
||||||
public Key? KeyCode { get; set; }
|
public int? KeyCode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@@ -200,11 +203,20 @@ namespace v2rayN.Models
|
|||||||
public int Index { get; set; }
|
public int Index { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class Mux4RayItem
|
||||||
|
{
|
||||||
|
public int? concurrency { get; set; }
|
||||||
|
public int? xudpConcurrency { get; set; }
|
||||||
|
public string? xudpProxyUDP443 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Mux4SboxItem
|
public class Mux4SboxItem
|
||||||
{
|
{
|
||||||
public string protocol { get; set; }
|
public string protocol { get; set; }
|
||||||
public int max_connections { get; set; }
|
public int max_connections { get; set; }
|
||||||
|
public bool? padding { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Models
|
||||||
|
|
||||||
namespace v2rayN.Models
|
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class CoreInfo
|
public class CoreInfo
|
||||||
@@ -20,6 +18,9 @@ namespace v2rayN.Models
|
|||||||
public string coreDownloadUrl64 { get; set; }
|
public string coreDownloadUrl64 { get; set; }
|
||||||
|
|
||||||
public string coreDownloadUrlArm64 { get; set; }
|
public string coreDownloadUrlArm64 { get; set; }
|
||||||
|
public string? coreDownloadUrlLinux32 { get; set; }
|
||||||
|
public string? coreDownloadUrlLinux64 { get; set; }
|
||||||
|
public string? coreDownloadUrlLinuxArm64 { get; set; }
|
||||||
|
|
||||||
public string match { get; set; }
|
public string match { get; set; }
|
||||||
public string versionArg { get; set; }
|
public string versionArg { get; set; }
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
using v2rayN.Enums;
|
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class DNSItem
|
public class DNSItem
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class GitHubReleaseAsset
|
public class GitHubReleaseAsset
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ProfileExItem
|
public class ProfileExItem
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
using v2rayN.Enums;
|
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ProfileItem
|
public class ProfileItem
|
||||||
@@ -179,7 +178,7 @@ namespace v2rayN.Models
|
|||||||
|
|
||||||
public ECoreType? coreType { get; set; }
|
public ECoreType? coreType { get; set; }
|
||||||
|
|
||||||
public int preSocksPort { get; set; }
|
public int? preSocksPort { get; set; }
|
||||||
|
|
||||||
public string fingerprint { get; set; }
|
public string fingerprint { get; set; }
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ProfileItemModel : ProfileItem
|
public class ProfileItemModel : ProfileItem
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RoutingItem
|
public class RoutingItem
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RoutingItemModel : RoutingItem
|
public class RoutingItemModel : RoutingItem
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RulesItem
|
public class RulesItem
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RulesItemModel : RulesItem
|
public class RulesItemModel : RulesItem
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ServerSpeedItem : ServerStatItem
|
public class ServerSpeedItem : ServerStatItem
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ServerStatItem
|
public class ServerStatItem
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
using v2rayN.Enums;
|
namespace ServiceLib.Models
|
||||||
|
|
||||||
namespace v2rayN.Models
|
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
internal class ServerTestItem
|
public class ServerTestItem
|
||||||
{
|
{
|
||||||
public string indexId { get; set; }
|
public string indexId { get; set; }
|
||||||
public string address { get; set; }
|
public string address { get; set; }
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class SingboxConfig
|
public class SingboxConfig
|
||||||
{
|
{
|
||||||
@@ -150,6 +150,7 @@
|
|||||||
public bool enabled { get; set; }
|
public bool enabled { get; set; }
|
||||||
public string protocol { get; set; }
|
public string protocol { get; set; }
|
||||||
public int max_connections { get; set; }
|
public int max_connections { get; set; }
|
||||||
|
public bool? padding { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Utls4Sbox
|
public class Utls4Sbox
|
||||||
12
v2rayN/ServiceLib/Models/SpeedTestResult.cs
Normal file
12
v2rayN/ServiceLib/Models/SpeedTestResult.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace ServiceLib.Models
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class SpeedTestResult
|
||||||
|
{
|
||||||
|
public string? IndexId { get; set; }
|
||||||
|
|
||||||
|
public string? Delay { get; set; }
|
||||||
|
|
||||||
|
public string? Speed { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class SsSIP008
|
public class SsSIP008
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class SubItem
|
public class SubItem
|
||||||
@@ -31,5 +31,7 @@ namespace v2rayN.Models
|
|||||||
public string? prevProfile { get; set; }
|
public string? prevProfile { get; set; }
|
||||||
|
|
||||||
public string? nextProfile { get; set; }
|
public string? nextProfile { get; set; }
|
||||||
|
|
||||||
|
public int? preSocksPort { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
internal class SysProxyConfig
|
public class SysProxyConfig
|
||||||
{
|
{
|
||||||
public bool UserSettingsRecorded;
|
public bool UserSettingsRecorded;
|
||||||
public string Flags;
|
public string Flags;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// v2ray配置文件实体类 例子SampleConfig.txt
|
/// v2ray配置文件实体类 例子SampleConfig.txt
|
||||||
@@ -343,15 +343,10 @@ namespace v2rayN.Models
|
|||||||
|
|
||||||
public class Mux4Ray
|
public class Mux4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public bool enabled { get; set; }
|
public bool enabled { get; set; }
|
||||||
|
public int? concurrency { get; set; }
|
||||||
/// <summary>
|
public int? xudpConcurrency { get; set; }
|
||||||
///
|
public string? xudpProxyUDP443 { get; set; }
|
||||||
/// </summary>
|
|
||||||
public int concurrency { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Response4Ray
|
public class Response4Ray
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tcp伪装http的Request,只要Host
|
/// Tcp伪装http的Request,只要Host
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace v2rayN.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://github.com/2dust/v2rayN/wiki/
|
/// https://github.com/2dust/v2rayN/wiki/
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
internal class VmessQRCode
|
public class VmessQRCode
|
||||||
{
|
{
|
||||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||||
public int v { get; set; } = 2;
|
public int v { get; set; } = 2;
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace v2rayN.Resx {
|
namespace ServiceLib.Resx {
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ namespace v2rayN.Resx {
|
|||||||
public static global::System.Resources.ResourceManager ResourceManager {
|
public static global::System.Resources.ResourceManager ResourceManager {
|
||||||
get {
|
get {
|
||||||
if (object.ReferenceEquals(resourceMan, null)) {
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("v2rayN.Resx.ResUI", typeof(ResUI).Assembly);
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ServiceLib.Resx.ResUI", typeof(ResUI).Assembly);
|
||||||
resourceMan = temp;
|
resourceMan = temp;
|
||||||
}
|
}
|
||||||
return resourceMan;
|
return resourceMan;
|
||||||
@@ -79,7 +79,7 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Batch export share URL to clipboard successfully 的本地化字符串。
|
/// 查找类似 Export Share Link to Clipboard Successfully 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string BatchExportURLSuccessfully {
|
public static string BatchExportURLSuccessfully {
|
||||||
get {
|
get {
|
||||||
@@ -610,7 +610,7 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Import bulk URL from clipboard (Ctrl+V) 的本地化字符串。
|
/// 查找类似 Importing Share Links from clipboard (Ctrl+V) 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string menuAddServerViaClipboard {
|
public static string menuAddServerViaClipboard {
|
||||||
get {
|
get {
|
||||||
@@ -772,7 +772,7 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Export selected server for client configuration 的本地化字符串。
|
/// 查找类似 Export selected server for complete configuration 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string menuExport2ClientConfig {
|
public static string menuExport2ClientConfig {
|
||||||
get {
|
get {
|
||||||
@@ -781,7 +781,16 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Export share URLs to clipboard (Ctrl+C) 的本地化字符串。
|
/// 查找类似 Export selected server for complete configuration to clipboard 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuExport2ClientConfigClipboard {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuExport2ClientConfigClipboard", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Export Share Link to Clipboard (Ctrl+C) 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string menuExport2ShareUrl {
|
public static string menuExport2ShareUrl {
|
||||||
get {
|
get {
|
||||||
@@ -789,6 +798,15 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Export Base64-encoded Share Links to Clipboard 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuExport2ShareUrlBase64 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuExport2ShareUrlBase64", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Global Hotkey Setting 的本地化字符串。
|
/// 查找类似 Global Hotkey Setting 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1302,6 +1320,15 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Show or hide the main window 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuShowOrHideMainWindow {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuShowOrHideMainWindow", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Sort by test result 的本地化字符串。
|
/// 查找类似 Sort by test result 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1934,7 +1961,7 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Scan import URL successfully 的本地化字符串。
|
/// 查找类似 Scan import the shared link successfully 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string SuccessfullyImportedServerViaScan {
|
public static string SuccessfullyImportedServerViaScan {
|
||||||
get {
|
get {
|
||||||
@@ -2303,7 +2330,7 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 txtPreSocksPort 的本地化字符串。
|
/// 查找类似 Socks port 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TbPreSocksPort {
|
public static string TbPreSocksPort {
|
||||||
get {
|
get {
|
||||||
@@ -2311,6 +2338,15 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Custom config socks port 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbPreSocksPort4Sub {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbPreSocksPort4Sub", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 PrivateKey 的本地化字符串。
|
/// 查找类似 PrivateKey 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -3498,5 +3534,14 @@ namespace v2rayN.Resx {
|
|||||||
return ResourceManager.GetString("UngroupedServers", resourceCulture);
|
return ResourceManager.GetString("UngroupedServers", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 You are currently running a standalone package, please manually download the SelfContained.7z file to unzip and overwrite it! 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string UpdateStandalonePackageTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("UpdateStandalonePackageTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="BatchExportURLSuccessfully" xml:space="preserve">
|
<data name="BatchExportURLSuccessfully" xml:space="preserve">
|
||||||
<value>Batch export share URL to clipboard successfully</value>
|
<value>Export Share Link to Clipboard Successfully</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="CheckServerSettings" xml:space="preserve">
|
<data name="CheckServerSettings" xml:space="preserve">
|
||||||
<value>Please check the server settings first</value>
|
<value>Please check the server settings first</value>
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
<value>{0} servers have been imported from clipboard</value>
|
<value>{0} servers have been imported from clipboard</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
||||||
<value>Scan import URL successfully</value>
|
<value>Scan import the shared link successfully</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TestMeOutput" xml:space="preserve">
|
<data name="TestMeOutput" xml:space="preserve">
|
||||||
<value>The ping of current service: {0} ms</value>
|
<value>The ping of current service: {0} ms</value>
|
||||||
@@ -491,7 +491,7 @@
|
|||||||
<value>Language (Restart)</value>
|
<value>Language (Restart)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
||||||
<value>Import bulk URL from clipboard (Ctrl+V)</value>
|
<value>Importing Share Links from clipboard (Ctrl+V)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaScan" xml:space="preserve">
|
<data name="menuAddServerViaScan" xml:space="preserve">
|
||||||
<value>Scan QR code on the screen (Ctrl+S)</value>
|
<value>Scan QR code on the screen (Ctrl+S)</value>
|
||||||
@@ -524,10 +524,10 @@
|
|||||||
<value>Test servers with tcping (Ctrl+O)</value>
|
<value>Test servers with tcping (Ctrl+O)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuExport2ClientConfig" xml:space="preserve">
|
<data name="menuExport2ClientConfig" xml:space="preserve">
|
||||||
<value>Export selected server for client configuration</value>
|
<value>Export selected server for complete configuration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuExport2ShareUrl" xml:space="preserve">
|
<data name="menuExport2ShareUrl" xml:space="preserve">
|
||||||
<value>Export share URLs to clipboard (Ctrl+C)</value>
|
<value>Export Share Link to Clipboard (Ctrl+C)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddCustomServer" xml:space="preserve">
|
<data name="menuAddCustomServer" xml:space="preserve">
|
||||||
<value>Add a custom configuration server</value>
|
<value>Add a custom configuration server</value>
|
||||||
@@ -668,7 +668,7 @@
|
|||||||
<value>Encryption</value>
|
<value>Encryption</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPreSocksPort" xml:space="preserve">
|
<data name="TbPreSocksPort" xml:space="preserve">
|
||||||
<value>txtPreSocksPort</value>
|
<value>Socks port</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipPreSocksPort" xml:space="preserve">
|
<data name="TipPreSocksPort" xml:space="preserve">
|
||||||
<value>* After setting this value, an socks service will be started using Xray/sing-box(Tun) to provide functions such as speed display</value>
|
<value>* After setting this value, an socks service will be started using Xray/sing-box(Tun) to provide functions such as speed display</value>
|
||||||
@@ -1264,4 +1264,19 @@
|
|||||||
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
||||||
<value>Auto column width adjustment</value>
|
<value>Auto column width adjustment</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
|
||||||
|
<value>Export Base64-encoded Share Links to Clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
|
||||||
|
<value>Export selected server for complete configuration to clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuShowOrHideMainWindow" xml:space="preserve">
|
||||||
|
<value>Show or hide the main window</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
|
<value>You are currently running a standalone package, please manually download the SelfContained.7z file to unzip and overwrite it!</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
|
<value>Custom config socks port</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="BatchExportURLSuccessfully" xml:space="preserve">
|
<data name="BatchExportURLSuccessfully" xml:space="preserve">
|
||||||
<value>批量导出分享URL至剪贴板成功</value>
|
<value>导出分享链接至剪贴板成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="CheckServerSettings" xml:space="preserve">
|
<data name="CheckServerSettings" xml:space="preserve">
|
||||||
<value>请先检查服务器设置</value>
|
<value>请先检查服务器设置</value>
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
<value>成功从剪贴板导入 {0} 个服务器</value>
|
<value>成功从剪贴板导入 {0} 个服务器</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
||||||
<value>扫描导入URL成功</value>
|
<value>扫描导入分享链接成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TestMeOutput" xml:space="preserve">
|
<data name="TestMeOutput" xml:space="preserve">
|
||||||
<value>当前服务的真连接延迟: {0} ms</value>
|
<value>当前服务的真连接延迟: {0} ms</value>
|
||||||
@@ -491,7 +491,7 @@
|
|||||||
<value>语言(重启)</value>
|
<value>语言(重启)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
||||||
<value>从剪贴板导入批量URL (Ctrl+V)</value>
|
<value>从剪贴板导入分享链接 (Ctrl+V)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaScan" xml:space="preserve">
|
<data name="menuAddServerViaScan" xml:space="preserve">
|
||||||
<value>扫描屏幕上的二维码 (Ctrl+S)</value>
|
<value>扫描屏幕上的二维码 (Ctrl+S)</value>
|
||||||
@@ -524,10 +524,10 @@
|
|||||||
<value>测试服务器延迟Tcping(多选) (Ctrl+O)</value>
|
<value>测试服务器延迟Tcping(多选) (Ctrl+O)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuExport2ClientConfig" xml:space="preserve">
|
<data name="menuExport2ClientConfig" xml:space="preserve">
|
||||||
<value>导出所选服务器为客户端配置</value>
|
<value>导出所选服务器完整配置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuExport2ShareUrl" xml:space="preserve">
|
<data name="menuExport2ShareUrl" xml:space="preserve">
|
||||||
<value>批量导出分享URL至剪贴板(多选) (Ctrl+C)</value>
|
<value>导出分享链接至剪贴板(多选) (Ctrl+C)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddCustomServer" xml:space="preserve">
|
<data name="menuAddCustomServer" xml:space="preserve">
|
||||||
<value>添加自定义配置服务器</value>
|
<value>添加自定义配置服务器</value>
|
||||||
@@ -1261,4 +1261,19 @@
|
|||||||
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
||||||
<value>自动调整列宽</value>
|
<value>自动调整列宽</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
|
||||||
|
<value>导出分享链接至剪贴板(多选) Base64编码</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
|
||||||
|
<value>导出所选服务器完整配置至剪贴板</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuShowOrHideMainWindow" xml:space="preserve">
|
||||||
|
<value>显示或隐藏主界面</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
|
<value>您当前运行的是独立包,请手动下载 SelfContained.7z文件解压覆盖</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
|
<value>自定义配置的Socks端口</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="BatchExportURLSuccessfully" xml:space="preserve">
|
<data name="BatchExportURLSuccessfully" xml:space="preserve">
|
||||||
<value>批次匯出分享URL至剪貼簿成功</value>
|
<value>匯出分享链接至剪貼簿成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="CheckServerSettings" xml:space="preserve">
|
<data name="CheckServerSettings" xml:space="preserve">
|
||||||
<value>請先檢查伺服器設定</value>
|
<value>請先檢查伺服器設定</value>
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
<value>成功從剪貼簿匯入 {0} 個伺服器</value>
|
<value>成功從剪貼簿匯入 {0} 個伺服器</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
||||||
<value>掃描匯入URL成功</value>
|
<value>掃描匯入分享链接成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TestMeOutput" xml:space="preserve">
|
<data name="TestMeOutput" xml:space="preserve">
|
||||||
<value>目前服務的真連接延遲: {0} ms</value>
|
<value>目前服務的真連接延遲: {0} ms</value>
|
||||||
@@ -490,7 +490,7 @@
|
|||||||
<value>語言(重啟)</value>
|
<value>語言(重啟)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
||||||
<value>從剪貼簿匯入批次URL (Ctrl+V)</value>
|
<value>從剪貼簿導入分享鏈接 (Ctrl+V)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddServerViaScan" xml:space="preserve">
|
<data name="menuAddServerViaScan" xml:space="preserve">
|
||||||
<value>掃描螢幕上的二維碼 (Ctrl+S)</value>
|
<value>掃描螢幕上的二維碼 (Ctrl+S)</value>
|
||||||
@@ -523,10 +523,10 @@
|
|||||||
<value>測試伺服器延遲Tcping(多選) (Ctrl+O)</value>
|
<value>測試伺服器延遲Tcping(多選) (Ctrl+O)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuExport2ClientConfig" xml:space="preserve">
|
<data name="menuExport2ClientConfig" xml:space="preserve">
|
||||||
<value>匯出所選伺服器為用戶端配置</value>
|
<value>匯出所選伺服器完整配置</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuExport2ShareUrl" xml:space="preserve">
|
<data name="menuExport2ShareUrl" xml:space="preserve">
|
||||||
<value>批次匯出分享URL至剪貼簿(多選) (Ctrl+C)</value>
|
<value>匯出分享链接至剪貼簿(多選) (Ctrl+C)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddCustomServer" xml:space="preserve">
|
<data name="menuAddCustomServer" xml:space="preserve">
|
||||||
<value>新增自訂配置伺服器</value>
|
<value>新增自訂配置伺服器</value>
|
||||||
@@ -1141,4 +1141,19 @@
|
|||||||
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
||||||
<value>自動調整列寬</value>
|
<value>自動調整列寬</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
|
||||||
|
<value>匯出分享链接至剪貼簿(多選) Base64编码</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
|
||||||
|
<value>匯出所選伺服器完整配置至剪貼簿</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuShowOrHideMainWindow" xml:space="preserve">
|
||||||
|
<value>顯示或隱藏主介面</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
|
<value>您目前運行的是獨立包,請手動下載 SelfContained.7z檔案解壓縮覆蓋</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
|
<value>自訂配置的Socks端口</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user