Compare commits

...

42 Commits
6.55 ... 6.56

Author SHA1 Message Date
2dust
b02ad6cdab up 6.56 2024-09-01 19:56:11 +08:00
2dust
f7b16952ea PackageReference 2024-09-01 19:51:18 +08:00
2dust
f0d05a7d4e Refactor check updates 2024-09-01 16:39:45 +08:00
2dust
d6ca317b20 xray mux add more option
https://github.com/2dust/v2rayN/issues/5565
2024-08-31 10:12:21 +08:00
2dust
2879fddfd9 sinb-box mux add padding option
https://github.com/2dust/v2rayN/issues/5544
2024-08-31 09:38:15 +08:00
2dust
b6c09470fc Add global exception catching 2024-08-30 13:47:53 +08:00
2dust
9fdf6c6c32 Bug fix 2024-08-30 13:15:25 +08:00
2dust
79085af994 Bug fix 2024-08-30 12:59:43 +08:00
2dust
d189f4b443 Add custom config Socks port to the group
https://github.com/2dust/v2rayN/issues/5576
2024-08-30 10:12:40 +08:00
2dust
c9d65e5cd9 Fix
https://github.com/2dust/v2rayN/issues/5595
2024-08-30 09:31:44 +08:00
2dust
639d62588a Refactor click event 2024-08-29 20:32:00 +08:00
2dust
6c9db51fd5 Creating a new desktop app with avaloniaui 2024-08-29 15:48:51 +08:00
2dust
f0dbb6b22c Bug fix 2024-08-29 15:19:03 +08:00
2dust
f10f7b6268 Add Portable Mode for mihomo 2024-08-29 10:10:55 +08:00
2dust
48a5cbc552 Check for standalone windows .Net version 2024-08-29 10:09:45 +08:00
2dust
6721d150e0 Refactor QRCodeHelper 2024-08-28 10:20:37 +08:00
2dust
54c16cad7d Adding OSPlatform Processing 2024-08-27 19:44:50 +08:00
2dust
ae3ab15245 Add Socks Protocol string 2024-08-27 16:09:07 +08:00
2dust
d3c0f50fec Adjustment of server binding 2024-08-27 13:18:18 +08:00
2dust
43753b1b7a Add linux download url 2024-08-27 13:06:39 +08:00
2dust
6f3e4b3682 Adding OSPlatform Processing 2024-08-26 18:45:41 +08:00
2dust
b57cdd31bd Refactor_updateView to add task 2024-08-22 19:51:10 +08:00
2dust
b936c194e4 Refactor v2rayUpgrade 2024-08-22 15:23:29 +08:00
2dust
064431421a Bug fix 2024-08-21 21:12:01 +08:00
TTG
9d49c7aad0 Update custom_routing_white (#5566) 2024-08-21 11:18:15 +08:00
2dust
a6f27e5071 Code clean 2024-08-20 14:30:45 +08:00
2dust
8d1d10b783 Refactoring Project 2024-08-20 14:15:29 +08:00
2dust
61bea05f63 Refactoring Project 2024-08-19 18:15:54 +08:00
2dust
bbe7c7b884 Optimized code 2024-08-18 15:04:56 +08:00
Milinda Brantini
a432852b78 Update cidr for direct outboundTag (#5550)
Signed-off-by: Milinda Brantini <C_A_T_T_E_R_Y@outlook.com>
2024-08-18 09:59:33 +08:00
2dust
770e8b8cfa >Export Base64-encoded Share Links to Clipboard 2024-08-17 20:53:42 +08:00
2dust
7faabdc375 Refactor code to decouple view and viewmodel 2024-08-17 10:53:02 +08:00
2dust
a9860418ba Optimized code 2024-08-15 21:03:00 +08:00
2dust
30ff9d0ea9 Optimized code
CoreInfoHandler
2024-08-15 20:13:59 +08:00
2dust
bbc2298939 Bug fix
https://github.com/2dust/v2rayN/issues/5517
2024-08-15 13:58:07 +08:00
2dust
3286e8e24d Refactor code to decouple view and viewmodel 2024-08-15 13:51:30 +08:00
2dust
372f3991e1 Refactor code to decouple view and viewmodel 2024-08-12 20:25:31 +08:00
2dust
9aa5c0d135 Refactor code to decouple view and viewmodel 2024-08-11 20:44:29 +08:00
2dust
9e9808e489 Refactor code to decouple view and viewmodel 2024-08-11 15:45:55 +08:00
2dust
3dd75b17cf Clean code 2024-08-10 19:20:31 +08:00
2dust
2504b4737b Refactor code to decouple view and viewmodel 2024-08-10 14:44:25 +08:00
2dust
8ff04dca0d Refactor code to decouple view and viewmodel 2024-08-10 10:02:00 +08:00
254 changed files with 11388 additions and 3493 deletions

View File

@@ -9,9 +9,9 @@
</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.Tools" Version="2.65.0">
<PackageReference Include="Grpc.Tools" Version="2.66.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View 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;
}
}

View File

@@ -1,10 +1,9 @@
using Downloader;
using System.IO;
using System.Net;
namespace v2rayN
namespace ServiceLib.Common
{
internal class DownloaderHelper
public class DownloaderHelper
{
private static readonly Lazy<DownloaderHelper> _instance = new(() => new());
public static DownloaderHelper Instance => _instance.Value;
@@ -169,6 +168,10 @@ namespace v2rayN
{
progress.Report(101);
}
else if (value.Error != null)
{
throw value.Error;
}
}
};

View File

@@ -1,8 +1,7 @@
using System.IO;
using System.IO.Compression;
using System.IO.Compression;
using System.Text;
namespace v2rayN
namespace ServiceLib.Common
{
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)
{
return NonExclusiveReadAllText(path, Encoding.Default);
@@ -86,5 +101,20 @@ namespace v2rayN
}
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;
}
}
}

View File

@@ -1,10 +1,8 @@
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
namespace v2rayN
namespace ServiceLib.Common
{
/// <summary>
/// </summary>

View File

@@ -1,7 +1,7 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace v2rayN
namespace ServiceLib.Common
{
/*
* See:

View File

@@ -1,11 +1,10 @@
using System.IO;
using System.Text.Json;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace v2rayN
namespace ServiceLib.Common
{
internal class JsonUtils
public class JsonUtils
{
/// <summary>
/// DeepCopy

View File

@@ -1,9 +1,8 @@
using NLog;
using NLog.Config;
using NLog.Targets;
using System.IO;
namespace v2rayN
namespace ServiceLib.Common
{
public class Logging
{

View 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);
}
}
}

View File

@@ -1,7 +1,7 @@
using System.Linq.Expressions;
using System.Reflection;
namespace v2rayN
namespace ServiceLib.Common
{
public static class QueryableExtension
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN
namespace ServiceLib.Common
{
public class SemanticVersion
{

View File

@@ -1,7 +1,7 @@
using SQLite;
using System.Collections;
namespace v2rayN
namespace ServiceLib.Common
{
public sealed class SQLiteHelper
{

View File

@@ -1,9 +1,8 @@
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)
{

View File

@@ -1,9 +1,5 @@
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
using System.Collections.Specialized;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.NetworkInformation;
@@ -11,17 +7,12 @@ using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
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操作
@@ -345,14 +336,6 @@ namespace v2rayN
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>
/// idn to idc
/// </summary>
@@ -384,6 +367,7 @@ namespace v2rayN
public static bool IsBase64String(string plainText)
{
if (plainText.IsNullOrEmpty()) return false;
var buffer = new Span<byte>(new byte[plainText.Length]);
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)
{
if (string.IsNullOrWhiteSpace(text))
@@ -516,29 +495,6 @@ namespace v2rayN
#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)
{
if (enableSecurityProtocolTls13)
@@ -614,58 +570,36 @@ namespace v2rayN
string location = GetExePath();
if (blFull)
{
return string.Format("v2rayN - V{0} - {1}",
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString(),
return string.Format("{0} - V{1} - {2}",
Global.AppName,
GetVersionInfo(),
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
}
else
{
return string.Format("v2rayN/{0}",
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString());
return string.Format("{0}/{1}",
Global.AppName,
GetVersionInfo());
}
}
catch (Exception ex)
{
Logging.SaveLog(ex.Message, ex);
return string.Empty;
return Global.AppName;
}
}
/// <summary>
/// 获取剪贴板数
/// </summary>
/// <returns></returns>
public static string? GetClipboardData()
public static string GetVersionInfo()
{
string? strData = string.Empty;
try
{
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(DataFormats.UnicodeText))
{
strData = data.GetData(DataFormats.UnicodeText)?.ToString();
}
return strData;
string location = GetExePath();
return FileVersionInfo.GetVersionInfo(location)?.FileVersion ?? "0.0";
}
catch (Exception ex)
{
Logging.SaveLog(ex.Message, ex);
}
return strData;
}
/// <summary>
/// 拷贝至剪贴板
/// </summary>
/// <returns></returns>
public static void SetClipboardData(string strData)
{
try
{
Clipboard.SetText(strData);
}
catch
{
return "0.0";
}
}
@@ -693,26 +627,6 @@ namespace v2rayN
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)
{
var fileName = Path.GetFileName(url);
@@ -752,23 +666,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>
/// 获取系统hosts
/// </summary>
@@ -800,6 +697,24 @@ namespace v2rayN
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
#region TempPath
@@ -945,186 +860,5 @@ namespace v2rayN
}
#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
}
}

View File

@@ -1,9 +1,9 @@
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace v2rayN.Common
namespace ServiceLib.Common
{
internal class YamlUtils
public class YamlUtils
{
#region YAML

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum EConfigType
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum ECoreType
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum EGirdOrientation
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum EGlobalHotkey
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum EInboundProtocol
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum EMove
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum ERuleMode
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum EServerColName
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum ESpeedActionType
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum ESysProxyType
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Enums
namespace ServiceLib.Enums
{
public enum ETransport
{

View File

@@ -0,0 +1,44 @@
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,
}
}

View File

@@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ReactiveUI />
</Weavers>

View File

@@ -1,11 +1,10 @@
using v2rayN.Enums;
namespace v2rayN
namespace ServiceLib
{
internal class Global
public class Global
{
#region const
public const string AppName = "v2rayN";
public const string GithubUrl = "https://github.com";
public const string GithubApiUrl = "https://api.github.com/repos";
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 CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
public const string ClashMixinConfigFileName = "Mixin.yaml";
public const string V2raySampleClient = "v2rayN.Sample.SampleClientConfig";
public const string SingboxSampleClient = "v2rayN.Sample.SingboxSampleClientConfig";
public const string V2raySampleHttpRequestFileName = "v2rayN.Sample.SampleHttpRequest";
public const string V2raySampleHttpResponseFileName = "v2rayN.Sample.SampleHttpResponse";
public const string V2raySampleInbound = "v2rayN.Sample.SampleInbound";
public const string V2raySampleOutbound = "v2rayN.Sample.SampleOutbound";
public const string SingboxSampleOutbound = "v2rayN.Sample.SingboxSampleOutbound";
public const string CustomRoutingFileName = "v2rayN.Sample.custom_routing_";
public const string TunSingboxDNSFileName = "v2rayN.Sample.tun_singbox_dns";
public const string TunSingboxInboundFileName = "v2rayN.Sample.tun_singbox_inbound";
public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules";
public const string DNSV2rayNormalFileName = "v2rayN.Sample.dns_v2ray_normal";
public const string DNSSingboxNormalFileName = "v2rayN.Sample.dns_singbox_normal";
public const string ClashMixinYaml = "v2rayN.Sample.clash_mixin_yaml";
public const string ClashTunYaml = "v2rayN.Sample.clash_tun_yaml";
public const string V2raySampleClient = "ServiceLib.Sample.SampleClientConfig";
public const string SingboxSampleClient = "ServiceLib.Sample.SingboxSampleClientConfig";
public const string V2raySampleHttpRequestFileName = "ServiceLib.Sample.SampleHttpRequest";
public const string V2raySampleHttpResponseFileName = "ServiceLib.Sample.SampleHttpResponse";
public const string V2raySampleInbound = "ServiceLib.Sample.SampleInbound";
public const string V2raySampleOutbound = "ServiceLib.Sample.SampleOutbound";
public const string SingboxSampleOutbound = "ServiceLib.Sample.SingboxSampleOutbound";
public const string CustomRoutingFileName = "ServiceLib.Sample.custom_routing_";
public const string TunSingboxDNSFileName = "ServiceLib.Sample.tun_singbox_dns";
public const string TunSingboxInboundFileName = "ServiceLib.Sample.tun_singbox_inbound";
public const string TunSingboxRulesFileName = "ServiceLib.Sample.tun_singbox_rules";
public const string DNSV2rayNormalFileName = "ServiceLib.Sample.dns_v2ray_normal";
public const string DNSSingboxNormalFileName = "ServiceLib.Sample.dns_singbox_normal";
public const string ClashMixinYaml = "ServiceLib.Sample.clash_mixin_yaml";
public const string ClashTunYaml = "ServiceLib.Sample.clash_tun_yaml";
public const string DefaultSecurity = "auto";
public const string DefaultNetwork = "tcp";
@@ -61,6 +60,7 @@ namespace v2rayN
public const string InboundAPIProtocol = "dokodemo-door";
public const string HttpProtocol = "http://";
public const string HttpsProtocol = "https://";
public const string SocksProtocol = "socks://";
public const string UserEMail = "t@t.tt";
public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
@@ -73,6 +73,7 @@ namespace v2rayN
public const int MaxPort = 65536;
public const string CommandClearMsg = "CommandClearMsg";
public const string CommandSendMsgView = "CommandSendMsgView";
public const string CommandSendSnackMsg = "CommandSendSnackMsg";
public const string CommandStopSpeedTest = "CommandStopSpeedTest";
public const string CommandRefreshProfiles = "CommandRefreshProfiles";
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> 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> 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> InboundTags = new() { "socks", "http", "socks2", "http2" };
public static readonly List<string> RuleProtocols = new() { "http", "tls", "bittorrent" };

View 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;

View File

@@ -1,26 +1,15 @@
using v2rayN.Models;
using static v2rayN.Models.ClashProxies;
using static ServiceLib.Models.ClashProxies;
namespace v2rayN.Handler
namespace ServiceLib.Handler
{
public sealed class ClashApiHandler
{
private static readonly Lazy<ClashApiHandler> instance = new(() => new());
public static ClashApiHandler Instance => instance.Value;
private Dictionary<String, ProxiesItem> _proxies;
private Dictionary<String, ProxiesItem>? _proxies;
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)
{
Task.Run(() => GetClashProxiesAsync(config, update));
@@ -40,10 +29,11 @@ namespace v2rayN.Handler
if (clashProxies != null || clashProviders != null)
{
_proxies = clashProxies?.proxies;
update(clashProxies, clashProviders);
return;
}
Thread.Sleep(5000);
Task.Delay(5000).Wait();
}
update(null, null);
}
@@ -56,19 +46,18 @@ namespace v2rayN.Handler
{
for (int i = 0; i < 5; i++)
{
if (GetProxies() != null)
if (_proxies != null)
{
break;
}
Thread.Sleep(5000);
Task.Delay(5000).Wait();
}
var proxies = GetProxies();
if (proxies == null)
if (_proxies == null)
{
return;
}
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()))
{
@@ -87,7 +76,7 @@ namespace v2rayN.Handler
return;
}
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>();
foreach (var it in lstProxy)
@@ -106,7 +95,7 @@ namespace v2rayN.Handler
}
Task.WaitAll(tasks.ToArray());
Thread.Sleep(1000);
Task.Delay(1000).Wait();
update(null, "");
});
}
@@ -148,8 +137,7 @@ namespace v2rayN.Handler
{
Task.Run(async () =>
{
var proxies = GetProxies();
if (proxies == null)
if (_proxies == null)
{
return;
}

View File

@@ -1,18 +1,13 @@
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
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>
internal class ConfigHandler
public class ConfigHandler
{
private static string configRes = Global.ConfigFileName;
private static readonly object objLock = new();
@@ -178,6 +173,13 @@ namespace v2rayN.Handler
config.speedTestItem.speedPingTestUrl = Global.SpeedPingTestUrl;
}
config.mux4RayItem ??= new()
{
concurrency = 8,
xudpConcurrency = 16,
xudpProxyUDP443 = "reject"
};
if (config.mux4SboxItem == null)
{
config.mux4SboxItem = new()
@@ -206,7 +208,6 @@ namespace v2rayN.Handler
};
}
LazyConfig.Instance.SetConfig(config);
return 0;
}
@@ -356,13 +357,64 @@ namespace v2rayN.Handler
#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>
/// Add or edit server
/// </summary>
/// <param name="config"></param>
/// <param name="profileItem"></param>
/// <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;
@@ -620,7 +672,21 @@ namespace v2rayN.Handler
/// <returns></returns>
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;
}
@@ -1092,7 +1158,7 @@ namespace v2rayN.Handler
var profileItem = LazyConfig.Instance.GetProfileItem(indexId) ?? new();
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.configType = EConfigType.Custom;
profileItem.coreType = coreType;
@@ -1190,7 +1256,7 @@ namespace v2rayN.Handler
var addStatus = profileItem.configType switch
{
EConfigType.VMess => AddServer(config, profileItem, false),
EConfigType.VMess => AddVMessServer(config, profileItem, false),
EConfigType.Shadowsocks => AddShadowsocksServer(config, profileItem, false),
EConfigType.Socks => AddSocksServer(config, profileItem, false),
EConfigType.Trojan => AddTrojanServer(config, profileItem, false),
@@ -1223,7 +1289,10 @@ namespace v2rayN.Handler
{
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;
//Is sing-box array configuration
@@ -1247,6 +1316,7 @@ namespace v2rayN.Handler
{
it.subid = subid;
it.isSub = isSub;
it.preSocksPort = preSocksPort;
if (AddCustomServer(config, it, true) == 0)
{
count++;
@@ -1303,6 +1373,7 @@ namespace v2rayN.Handler
}
profileItem.subid = subid;
profileItem.isSub = isSub;
profileItem.preSocksPort = preSocksPort;
if (AddCustomServer(config, profileItem, true) == 0)
{
return 1;
@@ -1347,6 +1418,10 @@ namespace v2rayN.Handler
public static int AddBatchServers(Config config, string strData, string subid, bool isSub)
{
if (Utils.IsNullOrEmpty(strData))
{
return -1;
}
List<ProfileItem>? lstOriSub = null;
if (isSub && !Utils.IsNullOrEmpty(subid))
{
@@ -1420,21 +1495,42 @@ namespace v2rayN.Handler
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.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;
if (SQLiteHelper.Instance.Table<SubItem>().Count() > 0)
{
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;
}

View File

@@ -1,15 +1,9 @@
using System.IO;
using v2rayN.Common;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.CoreConfig
namespace ServiceLib.Handler.CoreConfig
{
/// <summary>
/// Core configuration file processing class
/// </summary>
internal class CoreConfigClash
public class CoreConfigClash
{
private Config _config;

View File

@@ -1,14 +1,9 @@
using System.IO;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.CoreConfig
namespace ServiceLib.Handler.CoreConfig
{
/// <summary>
/// Core configuration file processing class
/// </summary>
internal class CoreConfigHandler
public class CoreConfigHandler
{
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;
return -1;
}
var config = LazyConfig.Instance.GetConfig();
var config = LazyConfig.Instance.Config;
msg = ResUI.InitialConfiguration;
if (node.configType == EConfigType.Custom)

View File

@@ -1,14 +1,10 @@
using System.Data;
using System.IO;
using System.Net;
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;
@@ -706,6 +702,7 @@ namespace v2rayN.Handler.CoreConfig
enabled = true,
protocol = _config.mux4SboxItem.protocol,
max_connections = _config.mux4SboxItem.max_connections,
padding = _config.mux4SboxItem.padding,
};
outbound.multiplex = mux;
}
@@ -987,7 +984,7 @@ namespace v2rayN.Handler.CoreConfig
{
lstDnsExe = new();
lstDirectExe = new();
var coreInfo = LazyConfig.Instance.GetCoreInfo();
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
foreach (var it in coreInfo)
{
if (it.coreType == ECoreType.v2rayN)

View File

@@ -1,13 +1,10 @@
using System.Net;
using System.Net.NetworkInformation;
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;
@@ -773,7 +770,9 @@ namespace v2rayN.Handler.CoreConfig
if (enabled)
{
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
{

View File

@@ -1,17 +1,12 @@
using System.Diagnostics;
using System.IO;
using System.Text;
using v2rayN.Enums;
using v2rayN.Handler.CoreConfig;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler
namespace ServiceLib.Handler
{
/// <summary>
/// Core process processing class
/// </summary>
internal class CoreHandler
public class CoreHandler
{
private Config _config;
private Process? _process;
@@ -46,12 +41,6 @@ namespace v2rayN.Handler
ShowMsg(false, msg);
ShowMsg(true, $"{node.GetSummary()}");
CoreStop();
if (_config.tunModeItem.enableTun)
{
Thread.Sleep(1000);
Utils.RemoveTunDevice();
}
CoreStart(node);
//In tun mode, do a delay check and restart the core
@@ -114,7 +103,7 @@ namespace v2rayN.Handler
if (!hasProc)
{
var coreInfo = LazyConfig.Instance.GetCoreInfo();
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
foreach (var it in coreInfo)
{
if (it.coreType == ECoreType.v2rayN)
@@ -127,7 +116,7 @@ namespace v2rayN.Handler
foreach (Process p in existing)
{
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);
}
@@ -162,7 +151,7 @@ namespace v2rayN.Handler
string fileName = string.Empty;
foreach (string name in coreInfo.coreExes)
{
string vName = $"{name}.exe";
string vName = Utils.GetExeName(name);
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
if (File.Exists(vName))
{
@@ -195,7 +184,7 @@ namespace v2rayN.Handler
//}
var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
_config.runningCoreType = coreType;
var coreInfo = LazyConfig.Instance.GetCoreInfo(coreType);
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
var displayLog = node.configType != EConfigType.Custom || node.displayLog;
var proc = RunProcess(node, coreInfo, "", displayLog);
@@ -229,7 +218,7 @@ namespace v2rayN.Handler
coreType = preCoreType,
configType = EConfigType.Socks,
address = Global.Loopback,
port = node.preSocksPort
port = node.preSocksPort.Value,
};
_config.runningCoreType = preCoreType;
}
@@ -238,7 +227,7 @@ namespace v2rayN.Handler
string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
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);
if (proc2 is not null)
{
@@ -256,7 +245,7 @@ namespace v2rayN.Handler
ShowMsg(false, configPath);
try
{
var coreInfo = LazyConfig.Instance.GetCoreInfo(coreType);
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
var proc = RunProcess(new(), coreInfo, $" -c {Global.CoreSpeedtestConfigFileName}", true);
if (proc is null)
{

View 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("")}\"";
}
}
}

View File

@@ -1,18 +1,14 @@
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Sockets;
using v2rayN.Enums;
using v2rayN.Resx;
namespace v2rayN.Handler
namespace ServiceLib.Handler
{
/// <summary>
///Download
/// </summary>
internal class DownloadHandle
public class DownloadHandler
{
public event EventHandler<ResultEventArgs>? UpdateCompleted;
@@ -34,7 +30,7 @@ namespace v2rayN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
var progress = new Progress<string>();
progress.ProgressChanged += (sender, value) =>
@@ -66,7 +62,7 @@ namespace v2rayN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, $"{ResUI.Downloading} {url}"));
var progress = new Progress<double>();
@@ -96,7 +92,7 @@ namespace v2rayN.Handler
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
{
AllowAutoRedirect = false,
@@ -185,7 +181,7 @@ namespace v2rayN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
var webProxy = GetWebProxy(blProxy);
var client = new HttpClient(new SocketsHttpHandler()
{
@@ -230,7 +226,7 @@ namespace v2rayN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
var webProxy = GetWebProxy(blProxy);
@@ -264,7 +260,7 @@ namespace v2rayN.Handler
try
{
var config = LazyConfig.Instance.GetConfig();
var config = LazyConfig.Instance.Config;
int responseTime = await GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10);
return responseTime;
}

View File

@@ -1,11 +1,8 @@
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)
{

View File

@@ -1,9 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class ClashFmt : BaseFmt
public class ClashFmt : BaseFmt
{
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class FmtHandler
public class FmtHandler
{
public static string? GetShareUri(ProfileItem item)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class Hysteria2Fmt : BaseFmt
public class Hysteria2Fmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -1,9 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class NaiveproxyFmt : BaseFmt
public class NaiveproxyFmt : BaseFmt
{
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
{

View File

@@ -1,11 +1,8 @@
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)
{

View File

@@ -1,9 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class SingboxFmt : BaseFmt
public class SingboxFmt : BaseFmt
{
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class SocksFmt : BaseFmt
public class SocksFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class TrojanFmt : BaseFmt
public class TrojanFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class TuicFmt : BaseFmt
public class TuicFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -1,9 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class V2rayFmt : BaseFmt
public class V2rayFmt : BaseFmt
{
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class VLESSFmt : BaseFmt
public class VLESSFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class VmessFmt : BaseFmt
public class VmessFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -1,10 +1,6 @@
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
internal class WireguardFmt : BaseFmt
public class WireguardFmt : BaseFmt
{
public static ProfileItem? Resolve(string str, out string msg)
{

View File

@@ -0,0 +1,244 @@
using System.Runtime.InteropServices;
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
}
}

View File

@@ -1,24 +1,16 @@
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using ReactiveUI;
namespace v2rayN.Handler
namespace ServiceLib.Handler
{
public class NoticeHandler
{
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
public NoticeHandler(ISnackbarMessageQueue snackbarMessageQueue)
{
_snackbarMessageQueue = snackbarMessageQueue ?? throw new ArgumentNullException(nameof(snackbarMessageQueue));
}
public void Enqueue(string? content)
{
if (content.IsNullOrEmpty())
{
return;
}
_snackbarMessageQueue?.Enqueue(content);
MessageBus.Current.SendMessage(content, Global.CommandSendSnackMsg);
}
public void SendMessage(string? content)

View File

@@ -1,10 +1,10 @@
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 ConcurrentBag<ProfileExItem> _lstProfileEx = [];

View File

@@ -1,27 +1,19 @@
using ReactiveUI;
using System.Diagnostics;
using System.Diagnostics;
using System.Net;
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 CoreHandler _coreHandler;
private List<ServerTestItem> _selecteds;
private ESpeedActionType _actionType;
private Action<string, string, string> _updateFunc;
private Action<SpeedTestResult> _updateFunc;
private bool _exitLoop = false;
public SpeedtestHandler(Config config)
{
_config = config;
}
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<string, string, string> update)
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> update)
{
_config = config;
_coreHandler = coreHandler;
@@ -91,6 +83,12 @@ namespace v2rayN.Handler
}
}
public void ExitLoop()
{
_exitLoop = true;
UpdateFunc("", ResUI.SpeedtestingStop);
}
private Task RunTcping()
{
try
@@ -146,7 +144,7 @@ namespace v2rayN.Handler
return Task.CompletedTask;
}
DownloadHandle downloadHandle = new DownloadHandle();
DownloadHandler downloadHandle = new DownloadHandler();
List<Task> tasks = new();
foreach (var it in _selecteds)
@@ -213,22 +211,11 @@ namespace v2rayN.Handler
string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new();
var exitLoop = false;
MessageBus.Current.Listen<string>(Global.CommandStopSpeedTest)
.Subscribe(x =>
{
if (!exitLoop)
{
UpdateFunc("", ResUI.SpeedtestingStop);
}
exitLoop = true;
});
DownloadHandler downloadHandle = new();
foreach (var it in _selecteds)
{
if (exitLoop)
if (_exitLoop)
{
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
continue;
@@ -286,22 +273,11 @@ namespace v2rayN.Handler
string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new();
var exitLoop = false;
MessageBus.Current.Listen<string>(Global.CommandStopSpeedTest)
.Subscribe(x =>
{
if (!exitLoop)
{
UpdateFunc("", ResUI.SpeedtestingStop);
}
exitLoop = true;
});
DownloadHandler downloadHandle = new();
foreach (var it in _selecteds)
{
if (exitLoop)
if (_exitLoop)
{
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
continue;
@@ -358,7 +334,7 @@ namespace v2rayN.Handler
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);
//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 = "")
{
_updateFunc(indexId, delay, speed);
_updateFunc(new() { IndexId = indexId, Delay = delay, Speed = speed });
}
}
}

View File

@@ -1,8 +1,6 @@
using v2rayN.Models;
namespace v2rayN.Handler.Statistics
namespace ServiceLib.Handler.Statistics
{
internal class StatisticsHandler
public class StatisticsHandler
{
private static readonly Lazy<StatisticsHandler> instance = new(() => new());
public static StatisticsHandler Instance => instance.Value;

View File

@@ -1,11 +1,9 @@
using System.Net.WebSockets;
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 bool _exitFlag;

View File

@@ -1,12 +1,10 @@
using Grpc.Core;
using Grpc.Net.Client;
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 GrpcChannel? _channel;

View 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);
}
}
}
}

View File

@@ -1,18 +1,11 @@
using DynamicData;
using Splat;
using System.Diagnostics;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
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 Config _config;
@@ -39,36 +32,15 @@ namespace v2rayN.Handler
_updateFunc = update;
var url = string.Empty;
DownloadHandle downloadHandle = new();
DownloadHandler downloadHandle = new();
downloadHandle.UpdateCompleted += (sender2, args) =>
{
if (args.Success)
{
_updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);
try
{
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
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)
{
_updateFunc(false, ex.Message);
}
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
fileName = Utils.UrlEncode(fileName);
_updateFunc(true, fileName);
}
else
{
@@ -78,37 +50,38 @@ namespace v2rayN.Handler
downloadHandle.Error += (sender2, args) =>
{
_updateFunc(false, args.GetException().Message);
_updateFunc(false, "");
};
AbsoluteCompleted += (sender2, args) =>
{
if (args.Success)
{
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "v2rayN"));
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN));
_updateFunc(false, args.Msg);
url = args.Url;
AskToDownload(downloadHandle, url, true).ContinueWith(task =>
{
_updateFunc(false, url);
_updateFunc(false, "");
});
}
else
{
Locator.Current.GetService<NoticeHandler>()?.Enqueue(args.Msg);
_updateFunc(false, args.Msg);
_updateFunc(false, "");
}
};
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, "v2rayN"));
CheckUpdateAsync(ECoreType.v2rayN, preRelease);
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, ECoreType.v2rayN));
CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease);
}
public void CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)
public async void CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)
{
_config = config;
_updateFunc = update;
var url = string.Empty;
DownloadHandle downloadHandle = new();
DownloadHandler downloadHandle = new();
downloadHandle.UpdateCompleted += (sender2, args) =>
{
if (args.Success)
@@ -132,30 +105,31 @@ namespace v2rayN.Handler
};
downloadHandle.Error += (sender2, args) =>
{
_updateFunc(true, args.GetException().Message);
_updateFunc(false, args.GetException().Message);
_updateFunc(false, "");
};
AbsoluteCompleted += (sender2, args) =>
{
if (args.Success)
{
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "Core"));
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type));
_updateFunc(false, args.Msg);
url = args.Url;
AskToDownload(downloadHandle, url, true).ContinueWith(task =>
{
_updateFunc(false, url);
_updateFunc(false, "");
});
}
else
{
Locator.Current.GetService<NoticeHandler>()?.Enqueue(args.Msg);
_updateFunc(false, args.Msg);
_updateFunc(false, "");
}
};
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, "Core"));
CheckUpdateAsync(type, preRelease);
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, type));
CheckUpdateAsync(downloadHandle, type, preRelease);
}
public void UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> update)
@@ -195,7 +169,7 @@ namespace v2rayN.Handler
continue;
}
var downloadHandle = new DownloadHandle();
var downloadHandle = new DownloadHandler();
downloadHandle.Error += (sender2, args) =>
{
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
@@ -233,10 +207,7 @@ namespace v2rayN.Handler
result = Utils.Base64Decode(result);
}
var lstUrl = new List<string>
{
item.moreUrl.TrimEx().Split(",")
};
var lstUrl = item.moreUrl.TrimEx().Split(",") ?? [];
foreach (var it in lstUrl)
{
var url2 = Utils.GetPunycode(it);
@@ -300,6 +271,7 @@ namespace v2rayN.Handler
{
await UpdateGeoFile("geosite", _config, update);
await UpdateGeoFile("geoip", _config, update);
_updateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
});
}
@@ -307,7 +279,7 @@ namespace v2rayN.Handler
{
Task.Run(async () =>
{
var time = await (new DownloadHandle()).RunAvailabilityCheck(null);
var time = await (new DownloadHandler()).RunAvailabilityCheck(null);
update(false, string.Format(ResUI.TestMeOutput, time));
});
@@ -315,14 +287,14 @@ namespace v2rayN.Handler
#region private
private async void CheckUpdateAsync(ECoreType type, bool preRelease)
private async void CheckUpdateAsync(DownloadHandler downloadHandle, ECoreType type, bool preRelease)
{
try
{
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
string url = coreInfo.coreReleaseApiUrl;
var result = await (new DownloadHandle()).DownloadStringAsync(url, true, "");
var result = await downloadHandle.DownloadStringAsync(url, true, Global.AppName);
if (!Utils.IsNullOrEmpty(result))
{
ResponseHandler(type, result, preRelease);
@@ -341,17 +313,17 @@ namespace v2rayN.Handler
}
/// <summary>
/// 获取V2RayCore版本
/// 获取Core版本
/// </summary>
private SemanticVersion GetCoreVersion(ECoreType type)
{
try
{
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
string filePath = string.Empty;
foreach (string name in coreInfo.coreExes)
{
string vName = $"{name}.exe";
string vName = Utils.GetExeName(name);
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
if (File.Exists(vName))
{
@@ -417,11 +389,10 @@ namespace v2rayN.Handler
var version = new SemanticVersion(gitHubRelease?.TagName!);
var body = gitHubRelease?.Body;
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
SemanticVersion curVersion;
string message;
string url;
string? url;
switch (type)
{
case ECoreType.v2fly:
@@ -431,23 +402,7 @@ namespace v2rayN.Handler
{
curVersion = GetCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
string osBit = "64";
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);
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"));
break;
}
case ECoreType.clash:
@@ -456,62 +411,21 @@ namespace v2rayN.Handler
{
curVersion = GetCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, type, curVersion);
switch (RuntimeInformation.ProcessArchitecture)
{
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"));
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"));
break;
}
case ECoreType.sing_box:
{
curVersion = GetCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
switch (RuntimeInformation.ProcessArchitecture)
{
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);
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"), version);
break;
}
case ECoreType.v2rayN:
{
curVersion = new SemanticVersion(FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString());
curVersion = new SemanticVersion(Utils.GetVersionInfo());
message = string.Format(ResUI.IsLatestN, type, curVersion);
switch (RuntimeInformation.ProcessArchitecture)
{
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;
}
url = string.Format(GetUrlFromCore(coreInfo), version);
break;
}
default:
@@ -533,24 +447,49 @@ namespace v2rayN.Handler
}
}
private async Task AskToDownload(DownloadHandle downloadHandle, string url, bool blAsk)
private string? GetUrlFromCore(CoreInfo? coreInfo)
{
bool blDownload = false;
if (blAsk)
if (Utils.IsWindows())
{
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;
}
if (blDownload)
{
await downloadHandle.DownloadFileAsync(url, true, 600);
return RuntimeInformation.ProcessArchitecture switch
{
Architecture.Arm64 => coreInfo?.coreDownloadUrlLinuxArm64,
Architecture.X86 => coreInfo?.coreDownloadUrlLinux32,
Architecture.X64 => coreInfo?.coreDownloadUrlLinux64,
_ => null,
};
}
return null;
}
private async Task AskToDownload(DownloadHandler downloadHandle, string url, bool blAsk)
{
//bool blDownload = false;
//if (blAsk)
//{
// if (UI.ShowYesNo(string.Format(ResUI.DownloadYesNo, url)) == MessageBoxResult.Yes)
// {
// blDownload = true;
// }
//}
//else
//{
// blDownload = true;
//}
//if (blDownload)
//{
await downloadHandle.DownloadFileAsync(url, true, 60);
//}
}
private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> update)
@@ -559,7 +498,7 @@ namespace v2rayN.Handler
_updateFunc = update;
var url = string.Format(Global.GeoUrl, geoName);
DownloadHandle downloadHandle = new();
DownloadHandler downloadHandle = new();
downloadHandle.UpdateCompleted += (sender2, args) =>
{
if (args.Success)
@@ -571,11 +510,6 @@ namespace v2rayN.Handler
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
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");
File.Copy(fileName, targetPath, true);

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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; }
}
}

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class ClashConnectionModel
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class ClashConnections
{

View File

@@ -1,6 +1,6 @@
using static v2rayN.Models.ClashProxies;
using static ServiceLib.Models.ClashProxies;
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class ClashProviders
{

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class ClashProxies
{

View File

@@ -1,26 +1,18 @@
using ReactiveUI.Fody.Helpers;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class ClashProxyModel
{
[Reactive]
public string name { get; set; }
[Reactive]
public string type { get; set; }
[Reactive]
public string now { get; set; }
[Reactive]
public int delay { get; set; }
[Reactive]
public string delayName { get; set; }
[Reactive]
public bool isActive { get; set; }
}
}

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class ComboItem
{

View File

@@ -1,6 +1,4 @@
using v2rayN.Enums;
namespace v2rayN.Models
namespace ServiceLib.Models
{
/// <summary>
/// 本软件配置文件实体类
@@ -43,6 +41,7 @@ namespace v2rayN.Models
public UIItem uiItem { get; set; }
public ConstItem constItem { get; set; }
public SpeedTestItem speedTestItem { get; set; }
public Mux4RayItem mux4RayItem { get; set; }
public Mux4SboxItem mux4SboxItem { get; set; }
public HysteriaItem hysteriaItem { get; set; }
public ClashUIItem clashUIItem { get; set; }

View File

@@ -1,7 +1,4 @@
using System.Windows.Input;
using v2rayN.Enums;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class CoreBasicItem
@@ -152,7 +149,7 @@ namespace v2rayN.Models
public bool Shift { get; set; }
public Key? KeyCode { get; set; }
public int? KeyCode { get; set; }
}
[Serializable]
@@ -200,11 +197,20 @@ namespace v2rayN.Models
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]
public class Mux4SboxItem
{
public string protocol { get; set; }
public int max_connections { get; set; }
public bool? padding { get; set; }
}
[Serializable]

View File

@@ -1,6 +1,4 @@
using v2rayN.Enums;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class CoreInfo
@@ -20,6 +18,9 @@ namespace v2rayN.Models
public string coreDownloadUrl64 { 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 versionArg { get; set; }

View File

@@ -1,7 +1,6 @@
using SQLite;
using v2rayN.Enums;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class DNSItem

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class GitHubReleaseAsset
{

View File

@@ -1,6 +1,6 @@
using SQLite;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class ProfileExItem

View File

@@ -1,7 +1,6 @@
using SQLite;
using v2rayN.Enums;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class ProfileItem
@@ -179,7 +178,7 @@ namespace v2rayN.Models
public ECoreType? coreType { get; set; }
public int preSocksPort { get; set; }
public int? preSocksPort { get; set; }
public string fingerprint { get; set; }

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class ProfileItemModel : ProfileItem

View File

@@ -1,6 +1,6 @@
using SQLite;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class RoutingItem

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class RoutingItemModel : RoutingItem

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class RulesItem

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class RulesItemModel : RulesItem

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class ServerSpeedItem : ServerStatItem

View File

@@ -1,6 +1,6 @@
using SQLite;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class ServerStatItem

View File

@@ -1,9 +1,7 @@
using v2rayN.Enums;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
internal class ServerTestItem
public class ServerTestItem
{
public string indexId { get; set; }
public string address { get; set; }

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class SingboxConfig
{
@@ -150,6 +150,7 @@
public bool enabled { get; set; }
public string protocol { get; set; }
public int max_connections { get; set; }
public bool? padding { get; set; }
}
public class Utls4Sbox

View 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; }
}
}

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
public class SsSIP008
{

View File

@@ -1,6 +1,6 @@
using SQLite;
namespace v2rayN.Models
namespace ServiceLib.Models
{
[Serializable]
public class SubItem
@@ -31,5 +31,7 @@ namespace v2rayN.Models
public string? prevProfile { get; set; }
public string? nextProfile { get; set; }
public int? preSocksPort { get; set; }
}
}

View File

@@ -1,6 +1,6 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
internal class SysProxyConfig
public class SysProxyConfig
{
public bool UserSettingsRecorded;
public string Flags;

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace v2rayN.Models
namespace ServiceLib.Models
{
/// <summary>
/// v2ray配置文件实体类 例子SampleConfig.txt
@@ -343,15 +343,10 @@ namespace v2rayN.Models
public class Mux4Ray
{
/// <summary>
///
/// </summary>
public bool enabled { get; set; }
/// <summary>
///
/// </summary>
public int concurrency { get; set; }
public int? concurrency { get; set; }
public int? xudpConcurrency { get; set; }
public string? xudpProxyUDP443 { get; set; }
}
public class Response4Ray

View File

@@ -1,4 +1,4 @@
namespace v2rayN.Models
namespace ServiceLib.Models
{
/// <summary>
/// Tcp伪装http的Request只要Host

View File

@@ -1,12 +1,12 @@
using System.Text.Json.Serialization;
namespace v2rayN.Models
namespace ServiceLib.Models
{
/// <summary>
/// https://github.com/2dust/v2rayN/wiki/
/// </summary>
[Serializable]
internal class VmessQRCode
public class VmessQRCode
{
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public int v { get; set; } = 2;

View File

@@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace v2rayN.Resx {
namespace ServiceLib.Resx {
using System;
@@ -39,7 +39,7 @@ namespace v2rayN.Resx {
public static global::System.Resources.ResourceManager ResourceManager {
get {
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;
}
return resourceMan;
@@ -79,7 +79,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 Batch export share URL to clipboard successfully 的本地化字符串。
/// 查找类似 Export Share Link to Clipboard Successfully 的本地化字符串。
/// </summary>
public static string BatchExportURLSuccessfully {
get {
@@ -610,7 +610,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 Import bulk URL from clipboard (Ctrl+V) 的本地化字符串。
/// 查找类似 Importing Share Links from clipboard (Ctrl+V) 的本地化字符串。
/// </summary>
public static string menuAddServerViaClipboard {
get {
@@ -772,7 +772,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 Export selected server for client configuration 的本地化字符串。
/// 查找类似 Export selected server for complete configuration 的本地化字符串。
/// </summary>
public static string menuExport2ClientConfig {
get {
@@ -781,7 +781,16 @@ namespace v2rayN.Resx {
}
/// <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>
public static string menuExport2ShareUrl {
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>
/// 查找类似 Global Hotkey Setting 的本地化字符串。
/// </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>
/// 查找类似 Sort by test result 的本地化字符串。
/// </summary>
@@ -1934,7 +1961,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 Scan import URL successfully 的本地化字符串。
/// 查找类似 Scan import the shared link successfully 的本地化字符串。
/// </summary>
public static string SuccessfullyImportedServerViaScan {
get {
@@ -2303,7 +2330,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 txtPreSocksPort 的本地化字符串。
/// 查找类似 Socks port 的本地化字符串。
/// </summary>
public static string TbPreSocksPort {
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>
/// 查找类似 PrivateKey 的本地化字符串。
/// </summary>
@@ -3498,5 +3534,14 @@ namespace v2rayN.Resx {
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);
}
}
}
}

View File

@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<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 name="CheckServerSettings" xml:space="preserve">
<value>Please check the server settings first</value>
@@ -299,7 +299,7 @@
<value>{0} servers have been imported from clipboard</value>
</data>
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
<value>Scan import URL successfully</value>
<value>Scan import the shared link successfully</value>
</data>
<data name="TestMeOutput" xml:space="preserve">
<value>The ping of current service: {0} ms</value>
@@ -491,7 +491,7 @@
<value>Language (Restart)</value>
</data>
<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 name="menuAddServerViaScan" xml:space="preserve">
<value>Scan QR code on the screen (Ctrl+S)</value>
@@ -524,10 +524,10 @@
<value>Test servers with tcping (Ctrl+O)</value>
</data>
<data name="menuExport2ClientConfig" xml:space="preserve">
<value>Export selected server for client configuration</value>
<value>Export selected server for complete configuration</value>
</data>
<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 name="menuAddCustomServer" xml:space="preserve">
<value>Add a custom configuration server</value>
@@ -668,7 +668,7 @@
<value>Encryption</value>
</data>
<data name="TbPreSocksPort" xml:space="preserve">
<value>txtPreSocksPort</value>
<value>Socks port</value>
</data>
<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>
@@ -1264,4 +1264,19 @@
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
<value>Auto column width adjustment</value>
</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>

View File

@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BatchExportURLSuccessfully" xml:space="preserve">
<value>批量导出分享URL至剪贴板成功</value>
<value>导出分享链接至剪贴板成功</value>
</data>
<data name="CheckServerSettings" xml:space="preserve">
<value>请先检查服务器设置</value>
@@ -299,7 +299,7 @@
<value>成功从剪贴板导入 {0} 个服务器</value>
</data>
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
<value>扫描导入URL成功</value>
<value>扫描导入分享链接成功</value>
</data>
<data name="TestMeOutput" xml:space="preserve">
<value>当前服务的真连接延迟: {0} ms</value>
@@ -491,7 +491,7 @@
<value>语言(重启)</value>
</data>
<data name="menuAddServerViaClipboard" xml:space="preserve">
<value>从剪贴板导入批量URL (Ctrl+V)</value>
<value>从剪贴板导入分享链接 (Ctrl+V)</value>
</data>
<data name="menuAddServerViaScan" xml:space="preserve">
<value>扫描屏幕上的二维码 (Ctrl+S)</value>
@@ -524,10 +524,10 @@
<value>测试服务器延迟Tcping(多选) (Ctrl+O)</value>
</data>
<data name="menuExport2ClientConfig" xml:space="preserve">
<value>导出所选服务器为客户端配置</value>
<value>导出所选服务器完整配置</value>
</data>
<data name="menuExport2ShareUrl" xml:space="preserve">
<value>批量导出分享URL至剪贴板(多选) (Ctrl+C)</value>
<value>导出分享链接至剪贴板(多选) (Ctrl+C)</value>
</data>
<data name="menuAddCustomServer" xml:space="preserve">
<value>添加自定义配置服务器</value>
@@ -1261,4 +1261,19 @@
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
<value>自动调整列宽</value>
</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>

View File

@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BatchExportURLSuccessfully" xml:space="preserve">
<value>批次匯出分享URL至剪貼簿成功</value>
<value>匯出分享链接至剪貼簿成功</value>
</data>
<data name="CheckServerSettings" xml:space="preserve">
<value>請先檢查伺服器設定</value>
@@ -298,7 +298,7 @@
<value>成功從剪貼簿匯入 {0} 個伺服器</value>
</data>
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
<value>掃描匯入URL成功</value>
<value>掃描匯入分享链接成功</value>
</data>
<data name="TestMeOutput" xml:space="preserve">
<value>目前服務的真連接延遲: {0} ms</value>
@@ -490,7 +490,7 @@
<value>語言(重啟)</value>
</data>
<data name="menuAddServerViaClipboard" xml:space="preserve">
<value>從剪貼簿匯入批次URL (Ctrl+V)</value>
<value>從剪貼簿導入分享鏈接 (Ctrl+V)</value>
</data>
<data name="menuAddServerViaScan" xml:space="preserve">
<value>掃描螢幕上的二維碼 (Ctrl+S)</value>
@@ -523,10 +523,10 @@
<value>測試伺服器延遲Tcping(多選) (Ctrl+O)</value>
</data>
<data name="menuExport2ClientConfig" xml:space="preserve">
<value>匯出所選伺服器為用戶端配置</value>
<value>匯出所選伺服器完整配置</value>
</data>
<data name="menuExport2ShareUrl" xml:space="preserve">
<value>批次匯出分享URL至剪貼簿(多選) (Ctrl+C)</value>
<value>匯出分享链接至剪貼簿(多選) (Ctrl+C)</value>
</data>
<data name="menuAddCustomServer" xml:space="preserve">
<value>新增自訂配置伺服器</value>
@@ -1141,4 +1141,19 @@
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
<value>自動調整列寬</value>
</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>

Some files were not shown because too many files have changed in this diff Show More