Compare commits

...

22 Commits
6.21 ... 6.22

Author SHA1 Message Date
2dust
34b4b9d099 up 6.22 2023-04-13 16:00:30 +08:00
2dust
0808ec1612 Add Check update for sing-box core 2023-04-13 15:50:28 +08:00
2dust
6b12549cd9 bug fixes 2023-04-12 20:15:17 +08:00
2dust
92baf9025a Update StatisticsHandler.cs 2023-04-12 15:30:07 +08:00
2dust
d58861ab88 Adjust some style 2023-04-12 14:26:37 +08:00
2dust
142230e56a Fix description 2023-04-12 14:08:30 +08:00
2dust
b8959c8f12 Optimize server filter 2023-04-12 11:34:42 +08:00
2dust
3fa22fdc55 bug fixes 2023-04-11 20:18:49 +08:00
2dust
a1c743e59c bug fixes 2023-04-10 17:30:27 +08:00
2dust
ebd0f45c10 Adjust VLESS flow config 2023-04-10 16:21:19 +08:00
2dust
fce6c46250 Can set the update interval for each subscription 2023-04-10 16:00:32 +08:00
2dust
6114e4ff55 Temporary fix for arm64 grpc issues 2023-04-10 11:28:53 +08:00
2dust
cc3d1ff7de Update Package Reference 2023-04-09 09:13:28 +08:00
2dust
2f721c8535 Merge pull request #3635 from kidfruit/core-arm
Core arm
2023-04-09 08:26:33 +08:00
kidfruit
ddb790104f delete .vs 2023-04-08 12:57:11 +08:00
liqi
181dfd2f51 add arm64 download path for core 2023-04-07 21:32:28 +08:00
liqi
fca062f75a add arm64 download path for core 2023-04-07 18:13:37 +08:00
2dust
52b84c3201 bug fixes 2023-04-07 15:38:30 +08:00
2dust
e1021a6832 Merge pull request #3631 from fonaix/master
fix bug #3630
2023-04-07 15:37:28 +08:00
fonaix
aa338d2da5 fix bug #3630 2023-04-07 15:21:09 +08:00
2dust
44471c4926 Update README.md 2023-04-07 13:56:16 +08:00
2dust
930c7e4ce5 Update README.md 2023-04-07 13:55:32 +08:00
31 changed files with 276 additions and 159 deletions

View File

@@ -1,5 +1,5 @@
# v2rayN
A V2Ray client for Windows, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core)
A GUI client for Windows, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayN)](https://github.com/2dust/v2rayN/commits/master)
@@ -7,15 +7,16 @@ A V2Ray client for Windows, support [Xray core](https://github.com/XTLS/Xray-cor
[![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayN/latest/total?logo=github)](https://github.com/2dust/v2rayN/releases)
[![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen.svg)](https://t.me/v2rayn)
### How to use
- If you are new to this, please download v2rayN-Core.zip from [releases](https://github.com/2dust/v2rayN/releases)
- Otherwise please download v2rayN.zip (you will also need to download v2ray core into the same folder with v2rayN.exe)
## How to use
- If you are new to this, please download v2rayN-With-Core.zip from [releases](https://github.com/2dust/v2rayN/releases)
- Otherwise please download v2rayN.zip (you will also need to download cores in the bin directory)
- Run v2rayN.exe
### Requirements
- Microsoft [.NET Framework 4.8 Runtime](https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net48-offline-installer)
- v2fly core [https://github.com/v2fly/v2ray-core/releases](https://github.com/v2fly/v2ray-core/releases)
- Xray core [https://github.com/XTLS/Xray-core/releases](https://github.com/XTLS/Xray-core/releases)
## Requirements
- [Microsoft .NET 6.0 Desktop Runtime ](https://download.visualstudio.microsoft.com/download/pr/513d13b7-b456-45af-828b-b7b7981ff462/edf44a743b78f8b54a2cec97ce888346/windowsdesktop-runtime-6.0.15-win-x64.exe)
- [Supported cores](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
### Telegram Channel
## Telegram Channel
[github_2dust](https://t.me/github_2dust)

View File

@@ -9,13 +9,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf">
<Version>3.21.9</Version>
</PackageReference>
<PackageReference Include="Grpc.Core">
<Version>2.46.5</Version>
</PackageReference>
<PackageReference Include="Grpc.Tools" Version="2.50.0">
<PackageReference Include="Google.Protobuf" Version="3.22.3" />
<PackageReference Include="Grpc.Core" Version="2.46.6" />
<PackageReference Include="Grpc.Tools" Version="2.53.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -1,4 +1,5 @@
using System.Windows;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Threading;
using v2rayN.Handler;
using v2rayN.Mode;
@@ -64,6 +65,10 @@ namespace v2rayN
Environment.Exit(0);
return;
}
if (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.X64)
{
_config.guiItem.enableStatistics = false;
}
}
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
@@ -79,7 +84,7 @@ namespace v2rayN
}
}
private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
Utils.SaveLog("TaskScheduler_UnobservedTaskException", e.Exception);
}

View File

@@ -463,9 +463,9 @@ namespace v2rayN.Handler
}
if (lstProfile.Count > 0)
{
return SetDefaultServerIndex(ref config, lstProfile[0].indexId);
return SetDefaultServerIndex(ref config, lstProfile.Where(t => t.port > 0).FirstOrDefault()?.indexId);
}
return SetDefaultServerIndex(ref config, SqliteHelper.Instance.Table<ProfileItem>().Select(t => t.indexId).FirstOrDefault());
return SetDefaultServerIndex(ref config, SqliteHelper.Instance.Table<ProfileItem>().Where(t => t.port > 0).Select(t => t.indexId).FirstOrDefault());
}
public static ProfileItem? GetDefaultServer(ref Config config)
{
@@ -797,7 +797,7 @@ namespace v2rayN.Handler
if (!Global.flows.Contains(profileItem.flow))
{
return -1;
profileItem.flow = Global.flows.First();
}
AddServerCommon(ref config, profileItem, toFile);
@@ -871,8 +871,7 @@ namespace v2rayN.Handler
return false;
}
return o.configVersion == n.configVersion
&& o.configType == n.configType
return o.configType == n.configType
&& o.address == n.address
&& o.port == n.port
&& o.id == n.id
@@ -941,7 +940,11 @@ namespace v2rayN.Handler
//Check for duplicate indexId
List<string>? lstDbIndexId = null;
List<ProfileItem> lstAdd = new();
string[] arrData = clipboardData.Split(Environment.NewLine.ToCharArray());
var arrData = clipboardData.Split(Environment.NewLine.ToCharArray()).Where(t => !t.IsNullOrEmpty());
if (isSub)
{
arrData = arrData.Distinct();
}
foreach (string str in arrData)
{
//maybe sub
@@ -1014,7 +1017,7 @@ namespace v2rayN.Handler
addStatus = AddVlessServer(ref config, profileItem, false);
}
if (addStatus == 0)
if (addStatus == 0 && profileItem.port > 0)
{
countServers++;
lstAdd.Add(profileItem);

View File

@@ -456,14 +456,8 @@ namespace v2rayN.Handler
boundStreamSettings(node, "out", outbound.streamSettings);
if (node.streamSecurity == Global.StreamSecurityReality)
{
usersItem.flow = node.flow;
outbound.mux.enabled = false;
outbound.mux.concurrency = -1;
}
else if (node.streamSecurity == Global.StreamSecurity)
if (node.streamSecurity == Global.StreamSecurityReality
|| node.streamSecurity == Global.StreamSecurity)
{
if (!Utils.IsNullOrEmpty(node.flow))
{
@@ -834,11 +828,11 @@ namespace v2rayN.Handler
/// <param name="fileName"></param>
/// <param name="msg"></param>
/// <returns></returns>
private static int GenerateClientCustomConfig(ProfileItem node, string fileName, out string msg)
private static int GenerateClientCustomConfig(ProfileItem node, string? fileName, out string msg)
{
try
{
if (node == null)
if (node == null || fileName is null)
{
msg = ResUI.CheckServerSettings;
return -1;
@@ -916,7 +910,8 @@ namespace v2rayN.Handler
{
try
{
if (node == null)
if (node == null
|| node.port <= 0)
{
msg = ResUI.CheckServerSettings;
return -1;

View File

@@ -214,7 +214,7 @@ namespace v2rayN.Handler
}
catch (Exception ex)
{
Utils.SaveLog(Utils.ToJson(node));
//Utils.SaveLog(Utils.ToJson(node));
Utils.SaveLog(ex.Message, ex);
string msg = ex.Message;
ShowMsg(true, msg);

View File

@@ -200,8 +200,9 @@ namespace v2rayN.Handler
coreType = ECoreType.v2rayN,
coreUrl = Global.NUrl,
coreReleaseApiUrl = Global.NUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN.zip",
coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN-32.zip",
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip",
coreDownloadUrlArm64 = Global.NUrl + "/download/{0}/v2rayN-arm64.zip"
});
coreInfos.Add(new CoreInfo
@@ -213,6 +214,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrlArm64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray",
versionArg = "-version",
redirectInfo = true,
@@ -227,6 +229,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.SagerNetCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrlArm64 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray",
versionArg = "version",
redirectInfo = true,
@@ -241,6 +244,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrlArm64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray",
versionArg = "version",
redirectInfo = true,
@@ -255,6 +259,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.xrayCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
coreDownloadUrl64 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
coreDownloadUrlArm64 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
match = "Xray",
versionArg = "-version",
redirectInfo = true,
@@ -269,6 +274,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.clashCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.clashCoreUrl + "/download/{0}/clash-windows-386-{0}.zip",
coreDownloadUrl64 = Global.clashCoreUrl + "/download/{0}/clash-windows-amd64-{0}.zip",
coreDownloadUrlArm64 = Global.clashCoreUrl + "/download/{0}/clash-windows-arm64-{0}.zip",
match = "v",
versionArg = "-v",
redirectInfo = true,
@@ -283,6 +289,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.clashMetaCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-386-{0}.zip",
coreDownloadUrl64 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-amd64-compatible-{0}.zip",
coreDownloadUrlArm64 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-arm64-{0}.zip",
match = "v",
versionArg = "-v",
redirectInfo = true,
@@ -297,6 +304,7 @@ namespace v2rayN.Handler
coreReleaseApiUrl = Global.hysteriaCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-386.exe",
coreDownloadUrl64 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-amd64.exe",
coreDownloadUrlArm64 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-arm64.exe",
redirectInfo = true,
});
@@ -324,7 +332,13 @@ namespace v2rayN.Handler
coreExes = new List<string> { "sing-box-client", "sing-box" },
arguments = "run",
coreUrl = Global.singboxCoreUrl,
redirectInfo = true,
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",
match = "sing-box",
versionArg = "version",
});
}

View File

@@ -11,14 +11,6 @@ namespace v2rayN.Handler
public sealed class MainFormHandler
{
private static readonly Lazy<MainFormHandler> instance = new(() => new());
//Action<bool, string> _updateUI;
//private DownloadHandle downloadHandle2;
//private Config _config;
//private V2rayHandler _v2rayHandler;
//private List<int> _selecteds;
//private Thread _workThread;
//Action<int, string> _updateFunc;
public static MainFormHandler Instance => instance.Value;
public Icon GetNotifyIcon(Config config)
@@ -285,37 +277,52 @@ namespace v2rayN.Handler
public void UpdateTask(Config config, Action<bool, string> update)
{
Task.Run(() => UpdateTaskRun(config, update));
Task.Run(() => UpdateTaskRunSubscription(config, update));
Task.Run(() => UpdateTaskRunGeo(config, update));
}
private void UpdateTaskRun(Config config, Action<bool, string> update)
private void UpdateTaskRunSubscription(Config config, Action<bool, string> update)
{
Thread.Sleep(60000);
Utils.SaveLog("UpdateTaskRunSubscription");
var updateHandle = new UpdateHandle();
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)
Utils.SaveLog("subscription" + msg);
});
item.updateTime = updateTime;
ConfigHandler.AddSubItem(ref config, item);
Thread.Sleep(5000);
}
Thread.Sleep(60000);
}
}
private void UpdateTaskRunGeo(Config config, Action<bool, string> update)
{
var autoUpdateSubTime = DateTime.Now;
var autoUpdateGeoTime = DateTime.Now;
Thread.Sleep(60000);
Utils.SaveLog("UpdateTaskRun");
Thread.Sleep(1000 * 120);
Utils.SaveLog("UpdateTaskRunGeo");
var updateHandle = new UpdateHandle();
while (true)
{
var dtNow = DateTime.Now;
if (config.guiItem.autoUpdateSubInterval > 0)
{
if ((dtNow - autoUpdateSubTime).Hours % config.guiItem.autoUpdateSubInterval == 0)
{
updateHandle.UpdateSubscriptionProcess(config, "", true, (bool success, string msg) =>
{
update(success, msg);
if (success)
Utils.SaveLog("subscription" + msg);
});
autoUpdateSubTime = dtNow;
}
Thread.Sleep(60000);
}
if (config.guiItem.autoUpdateInterval > 0)
{
if ((dtNow - autoUpdateGeoTime).Hours % config.guiItem.autoUpdateInterval == 0)

View File

@@ -243,7 +243,7 @@ namespace v2rayN.Handler
WebProxy webProxy = new(Global.Loopback, it.port);
await downloadHandle.DownloadDataAsync(url, webProxy, timeout, async (bool success, string msg) =>
await downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>
{
decimal.TryParse(msg, out decimal dec);
if (dec > 0)
@@ -294,7 +294,7 @@ namespace v2rayN.Handler
if (item is null) continue;
WebProxy webProxy = new(Global.Loopback, it.port);
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, async (bool success, string msg) =>
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>
{
decimal.TryParse(msg, out decimal dec);
if (dec > 0)

View File

@@ -134,6 +134,8 @@ namespace v2rayN.Handler
private void Init()
{
SqliteHelper.Instance.Execute($"delete from ServerStatItem where indexId not in ( select indexId from ProfileItem )");
long ticks = DateTime.Now.Date.Ticks;
SqliteHelper.Instance.Execute($"update ServerStatItem set todayUp = 0,todayDown=0,dateNow={ticks} where dateNow<>{ticks}");

View File

@@ -2,6 +2,7 @@
using Splat;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
@@ -402,7 +403,10 @@ namespace v2rayN.Handler
break;
case ECoreType.clash:
case ECoreType.clash_meta:
version = Regex.Match(echo, $"v[0-9.]+").Groups[0].Value;
version = Regex.Match(echo, $"v[0-9.]+").Groups[0].Value;
break;
case ECoreType.sing_box:
version = Regex.Match(echo, $"([0-9.]+)").Groups[1].Value;
break;
}
return version;
@@ -442,7 +446,20 @@ namespace v2rayN.Handler
{
curVersion = "v" + getCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, curVersion);
string osBit = Environment.Is64BitProcess ? "64" : "32";
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, osBit);
break;
}
@@ -451,21 +468,56 @@ namespace v2rayN.Handler
{
curVersion = getCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, curVersion);
if (Environment.Is64BitProcess)
switch (RuntimeInformation.ProcessArchitecture)
{
url = string.Format(coreInfo.coreDownloadUrl64, version);
case Architecture.Arm64:
url = coreInfo.coreDownloadUrlArm64;
break;
case Architecture.X86:
url = coreInfo.coreDownloadUrl32;
break;
default:
url = coreInfo.coreDownloadUrl64;
break;
}
else
url = string.Format(url, version);
break;
}
case ECoreType.sing_box:
{
curVersion = "v" + getCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, curVersion);
switch (RuntimeInformation.ProcessArchitecture)
{
url = string.Format(coreInfo.coreDownloadUrl32, version);
case Architecture.Arm64:
url = coreInfo.coreDownloadUrlArm64;
break;
case Architecture.X86:
url = coreInfo.coreDownloadUrl32;
break;
default:
url = coreInfo.coreDownloadUrl64;
break;
}
url = string.Format(url, version, version.Replace("v", ""));
break;
}
case ECoreType.v2rayN:
{
curVersion = FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString();
message = string.Format(ResUI.IsLatestN, curVersion);
url = string.Format(coreInfo.coreDownloadUrl64, version);
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;
}
break;
}
default:

View File

@@ -17,6 +17,8 @@
public string coreDownloadUrl64 { get; set; }
public string coreDownloadUrlArm64 { get; set; }
public string match { get; set; }
public string versionArg { get; set; }

View File

@@ -22,5 +22,8 @@ namespace v2rayN.Mode
public string filter { get; set; }
public int autoUpdateInterval { get; set; }
public long updateTime { get; set; }
}
}

View File

@@ -366,6 +366,15 @@ namespace v2rayN.Resx {
}
}
/// <summary>
/// 查找类似 Automatic update interval(minutes) 的本地化字符串。
/// </summary>
public static string LvAutoUpdateInterval {
get {
return ResourceManager.GetString("LvAutoUpdateInterval", resourceCulture);
}
}
/// <summary>
/// 查找类似 Count 的本地化字符串。
/// </summary>
@@ -1402,7 +1411,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 Servers Filter 的本地化字符串。
/// 查找类似 Servers Filter, press Enter to execute 的本地化字符串。
/// </summary>
public static string MsgServerTitle {
get {
@@ -2257,15 +2266,6 @@ namespace v2rayN.Resx {
}
}
/// <summary>
/// 查找类似 Automatic update interval of subscriptions (hours) 的本地化字符串。
/// </summary>
public static string TbSettingsAutoUpdate {
get {
return ResourceManager.GetString("TbSettingsAutoUpdate", resourceCulture);
}
}
/// <summary>
/// 查找类似 Automatic update interval of and Geo (hours) 的本地化字符串。
/// </summary>
@@ -2509,6 +2509,15 @@ namespace v2rayN.Resx {
}
}
/// <summary>
/// 查找类似 Enable logging to file 的本地化字符串。
/// </summary>
public static string TbSettingsLogEnabledToFile {
get {
return ResourceManager.GetString("TbSettingsLogEnabledToFile", resourceCulture);
}
}
/// <summary>
/// 查找类似 Log Level 的本地化字符串。
/// </summary>

View File

@@ -724,9 +724,6 @@
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
<value>Auto hide startup</value>
</data>
<data name="TbSettingsAutoUpdate" xml:space="preserve">
<value>فاصله به روز رسانی خودکار اشتراک ها (ساعت)</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>فاصله به روز رسانی خودکار و Geo (ساعت)</value>
</data>

View File

@@ -434,7 +434,7 @@
<value>Local</value>
</data>
<data name="MsgServerTitle" xml:space="preserve">
<value>Servers Filter</value>
<value>Servers Filter, press Enter to execute</value>
</data>
<data name="menuCheckUpdate" xml:space="preserve">
<value>Check Update</value>
@@ -724,9 +724,6 @@
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
<value>Auto hide startup</value>
</data>
<data name="TbSettingsAutoUpdate" xml:space="preserve">
<value>Automatic update interval of subscriptions (hours)</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>Automatic update interval of and Geo (hours)</value>
</data>
@@ -1111,4 +1108,10 @@
<data name="SpeedDisplayText" xml:space="preserve">
<value>{0}:{1}/s↑ | {2}/s↓</value>
</data>
<data name="LvAutoUpdateInterval" xml:space="preserve">
<value>Automatic update interval(minutes)</value>
</data>
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
<value>Enable logging to file</value>
</data>
</root>

View File

@@ -724,9 +724,6 @@
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
<value>Auto hide startup</value>
</data>
<data name="TbSettingsAutoUpdate" xml:space="preserve">
<value>Интервал автоматического обновления подписок в часах</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>Интервал автоматического обновления Geo в часах</value>
</data>

View File

@@ -434,7 +434,7 @@
<value>本地</value>
</data>
<data name="MsgServerTitle" xml:space="preserve">
<value>服务器过滤器</value>
<value>服务器过滤器,按回车执行</value>
</data>
<data name="menuCheckUpdate" xml:space="preserve">
<value>检查更新</value>
@@ -724,9 +724,6 @@
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
<value>启动后隐藏窗口</value>
</data>
<data name="TbSettingsAutoUpdate" xml:space="preserve">
<value>自动更新订阅的间隔(单位小时)</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>自动更新Geo文件的间隔(单位小时)</value>
</data>
@@ -770,7 +767,7 @@
<value>去重时保留序号较小的项</value>
</data>
<data name="TbSettingsLogEnabled" xml:space="preserve">
<value>启用日志(默认关闭)</value>
<value>启用日志</value>
</data>
<data name="TbSettingsLogLevel" xml:space="preserve">
<value>日志等级</value>
@@ -1108,4 +1105,10 @@
<data name="LvMoreUrl" xml:space="preserve">
<value>更多地址(url),用逗号(,)分隔</value>
</data>
<data name="LvAutoUpdateInterval" xml:space="preserve">
<value>自动更新间隔(分钟)</value>
</data>
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
<value>启用日志存到文件</value>
</data>
</root>

View File

@@ -367,23 +367,22 @@ namespace v2rayN
if (GBs > 0)
{
// multi GB
/*ulong TBs = GBs / factor;
long TBs = GBs / factor;
if (TBs > 0)
{
// 你是魔鬼吗? 用这么多流量
result = TBs + GBs % factor / (factor + 0.0);
result = TBs + (GBs % factor / (factor + 0.0));
unit = "TB";
return;
}*/
result = GBs + MBs % factor / (factor + 0.0);
}
result = GBs + (MBs % factor / (factor + 0.0));
unit = "GB";
return;
}
result = MBs + KBs % factor / (factor + 0.0);
result = MBs + (KBs % factor / (factor + 0.0));
unit = "MB";
return;
}
result = KBs + amount % factor / (factor + 0.0);
result = KBs + (amount % factor / (factor + 0.0));
unit = "KB";
return;
}

View File

@@ -133,6 +133,7 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> CheckUpdateXrayCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateClashCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateClashMetaCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateSingBoxCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateGeoCmd { get; }
@@ -472,6 +473,10 @@ namespace v2rayN.ViewModels
{
CheckUpdateCore(ECoreType.clash_meta);
});
CheckUpdateSingBoxCoreCmd = ReactiveCommand.Create(() =>
{
CheckUpdateCore(ECoreType.sing_box);
});
CheckUpdateGeoCmd = ReactiveCommand.Create(() =>
{
CheckUpdateGeo();
@@ -718,10 +723,13 @@ namespace v2rayN.ViewModels
return;
}
_serverFilter = ServerFilter;
RefreshServers();
if (Utils.IsNullOrEmpty(_serverFilter))
{
RefreshServers();
}
}
private void RefreshServers()
public void RefreshServers()
{
List<ProfileItemModel> lstModel = LazyConfig.Instance.ProfileItems(_subId, _serverFilter);
@@ -917,8 +925,8 @@ namespace v2rayN.ViewModels
public void AddServerViaClipboard()
{
string clipboardData = Utils.GetClipboardData();
int ret = ConfigHandler.AddBatchServers(ref _config, clipboardData, _subId, false);
var clipboardData = Utils.GetClipboardData();
int ret = ConfigHandler.AddBatchServers(ref _config, clipboardData!, _subId, false);
if (ret > 0)
{
InitSubscriptionView();

View File

@@ -60,7 +60,6 @@ namespace v2rayN.ViewModels
[Reactive] public bool EnableDragDropSort { get; set; }
[Reactive] public bool DoubleClick2Activate { get; set; }
[Reactive] public int autoUpdateInterval { get; set; }
[Reactive] public int autoUpdateSubInterval { get; set; }
[Reactive] public int trayMenuServersLimit { get; set; }
[Reactive] public string currentFontFamily { get; set; }
[Reactive] public int SpeedTestTimeout { get; set; }
@@ -156,7 +155,6 @@ namespace v2rayN.ViewModels
EnableDragDropSort = _config.uiItem.enableDragDropSort;
DoubleClick2Activate = _config.uiItem.doubleClick2Activate;
autoUpdateInterval = _config.guiItem.autoUpdateInterval;
autoUpdateSubInterval = _config.guiItem.autoUpdateSubInterval;
trayMenuServersLimit = _config.guiItem.trayMenuServersLimit;
currentFontFamily = _config.uiItem.currentFontFamily;
SpeedTestTimeout = _config.speedTestItem.speedTestTimeout;
@@ -333,7 +331,6 @@ namespace v2rayN.ViewModels
_config.guiItem.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
_config.uiItem.autoHideStartup = AutoHideStartup;
_config.guiItem.autoUpdateInterval = autoUpdateInterval;
_config.guiItem.autoUpdateSubInterval = autoUpdateSubInterval;
_config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
_config.uiItem.enableDragDropSort = EnableDragDropSort;
_config.uiItem.doubleClick2Activate = DoubleClick2Activate;

View File

@@ -64,6 +64,7 @@ namespace v2rayN.ViewModels
item.url = SelectedSource.url;
item.moreUrl = SelectedSource.moreUrl;
item.enabled = SelectedSource.enabled;
item.autoUpdateInterval = SelectedSource.autoUpdateInterval;
item.userAgent = SelectedSource.userAgent;
item.sort = SelectedSource.sort;
item.filter = SelectedSource.filter;

View File

@@ -229,6 +229,11 @@
Height="{StaticResource MenuItemHeight}"
Header="Clash.Meta Core" />
<Separator Margin="-40,5" />
<MenuItem
x:Name="menuCheckUpdateSingBoxCore"
Height="{StaticResource MenuItemHeight}"
Header="SingBox Core" />
<Separator Margin="-40,5" />
<MenuItem
x:Name="menuCheckUpdateGeo"
Height="{StaticResource MenuItemHeight}"
@@ -499,6 +504,7 @@
GridLinesVisibility="All"
HeadersVisibility="All"
IsReadOnly="True"
RowHeaderWidth="40"
Style="{StaticResource DefDataGrid}">
<DataGrid.InputBindings>
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Ctrl+C" />
@@ -790,7 +796,7 @@
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator />
<Separator x:Name="sepRoutings" />
<MenuItem x:Name="menuRoutings" Height="Auto">
<MenuItem.Header>
<DockPanel>

View File

@@ -30,10 +30,10 @@ namespace v2rayN.Views
this.Closing += MainWindow_Closing;
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
lstProfiles.LoadingRow += LstProfiles_LoadingRow;
lstProfiles.RowHeaderWidth = 30;
if (_config.uiItem.enableDragDropSort)
{
lstProfiles.AllowDrop = true;
@@ -129,6 +129,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.CheckUpdateXrayCoreCmd, v => v.menuCheckUpdateXrayCore).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateClashCoreCmd, v => v.menuCheckUpdateClashCore).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateClashMetaCoreCmd, v => v.menuCheckUpdateClashMetaCore).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateSingBoxCoreCmd, v => v.menuCheckUpdateSingBoxCore).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateGeoCmd, v => v.menuCheckUpdateGeo).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
@@ -148,6 +149,7 @@ namespace v2rayN.Views
this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings.SelectedItem).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.menuRoutings.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.sepRoutings.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.Servers, v => v.cmbServers.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedServer, v => v.cmbServers.SelectedItem).DisposeWith(disposables);
@@ -408,6 +410,14 @@ namespace v2rayN.Views
it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
}
}
private void TxtServerFilter_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key is Key.Enter or Key.Return)
{
ViewModel?.RefreshServers();
}
}
#endregion
#region UI
@@ -439,7 +449,7 @@ namespace v2rayN.Views
var item2 = (MyDGTextColumn)lstProfiles.Columns[k];
if (item2.ExName == item.Name)
{
if (item.Width <= 0)
if (item.Width < 0)
{
item2.Visibility = Visibility.Hidden;
}
@@ -466,7 +476,7 @@ namespace v2rayN.Views
_config.uiItem.mainHeight = this.Height;
List<ColumnItem> lvColumnItem = new();
for (int k = 1; k < lstProfiles.Columns.Count; k++)
for (int k = 0; k < lstProfiles.Columns.Count; k++)
{
var item2 = (MyDGTextColumn)lstProfiles.Columns[k];
lvColumnItem.Add(new()

View File

@@ -216,7 +216,7 @@
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsLogEnabled}" />
Text="{x:Static resx:ResUI.TbSettingsLogEnabledToFile}" />
<ToggleButton
x:Name="toglogEnabled"
Grid.Row="9"
@@ -668,22 +668,6 @@
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="13"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsAutoUpdate}" />
<TextBox
x:Name="txtautoUpdateSubInterval"
Grid.Row="13"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="14"
Grid.Column="0"

View File

@@ -160,7 +160,6 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.autoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.autoUpdateSubInterval, v => v.txtautoUpdateSubInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.trayMenuServersLimit, v => v.txttrayMenuServersLimit.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.currentFontFamily, v => v.cmbcurrentFontFamily.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SpeedTestTimeout, v => v.cmbSpeedTestTimeout.Text).DisposeWith(disposables);

View File

@@ -187,18 +187,18 @@
Header="{x:Static resx:ResUI.menuRoutingAdvancedImportRules}" />
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Resources>
<Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding isActive}" Value="True">
<Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryHueLightBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border
Width="auto"
Height="auto"
Background="{DynamicResource PrimaryHueLightBrush}"
Visibility="{Binding Path=isActive, Converter={StaticResource BoolToVisConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Width="200"
Binding="{Binding remarks}"

View File

@@ -11,7 +11,7 @@
xmlns:vms="clr-namespace:v2rayN.ViewModels"
Title="{x:Static resx:ResUI.menuSubSetting}"
Width="700"
Height="550"
Height="600"
x:TypeArguments="vms:SubEditViewModel"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
@@ -49,6 +49,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -145,10 +146,28 @@
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.LvAutoUpdateInterval}" />
<TextBox
x:Name="txtAutoUpdateInterval"
Grid.Row="4"
Grid.Column="1"
Width="400"
Margin="4"
VerticalAlignment="Top"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
AcceptsReturn="True"
Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.LvUserAgent}" />
<TextBox
x:Name="txtUserAgent"
Grid.Row="4"
Grid.Row="5"
Grid.Column="1"
Width="400"
Margin="4"
@@ -159,7 +178,7 @@
TextWrapping="Wrap" />
<TextBlock
Grid.Row="5"
Grid.Row="6"
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
@@ -167,7 +186,7 @@
Text="{x:Static resx:ResUI.LvFilter}" />
<TextBox
x:Name="txtFilter"
Grid.Row="5"
Grid.Row="6"
Grid.Column="1"
Width="400"
Margin="4"
@@ -177,7 +196,7 @@
Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock
Grid.Row="6"
Grid.Row="7"
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
@@ -185,7 +204,7 @@
Text="{x:Static resx:ResUI.LvSort}" />
<TextBox
x:Name="txtSort"
Grid.Row="6"
Grid.Row="7"
Grid.Column="1"
Width="400"
Margin="4"

View File

@@ -22,6 +22,7 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.SelectedSource.url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.moreUrl, v => v.txtMoreUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnable.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.autoUpdateInterval, v => v.txtAutoUpdateInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.userAgent, v => v.txtUserAgent.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.sort, v => v.txtSort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.filter, v => v.txtFilter.Text).DisposeWith(disposables);

View File

@@ -10,7 +10,7 @@
xmlns:resx="clr-namespace:v2rayN.Resx"
xmlns:vms="clr-namespace:v2rayN.ViewModels"
Title="{x:Static resx:ResUI.menuSubSetting}"
Width="700"
Width="800"
Height="600"
x:TypeArguments="vms:SubSettingViewModel"
Background="{DynamicResource MaterialDesignPaper}"
@@ -104,7 +104,7 @@
Binding="{Binding remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn
Width="200"
Width="150"
Binding="{Binding url}"
Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridTextColumn
@@ -112,7 +112,11 @@
Binding="{Binding enabled}"
Header="{x:Static resx:ResUI.LvEnabled}" />
<DataGridTextColumn
Width="200"
Width="150"
Binding="{Binding autoUpdateInterval}"
Header="{x:Static resx:ResUI.LvAutoUpdateInterval}" />
<DataGridTextColumn
Width="150"
Binding="{Binding userAgent}"
Header="{x:Static resx:ResUI.LvUserAgent}" />
<DataGridTextColumn

View File

@@ -10,7 +10,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>v2rayN.ico</ApplicationIcon>
<Copyright>Copyright © 2017-2023 (GPLv3)</Copyright>
<FileVersion>6.21</FileVersion>
<FileVersion>6.22</FileVersion>
</PropertyGroup>
<ItemGroup>