Compare commits

...

23 Commits
6.9 ... 6.11

Author SHA1 Message Date
2dust
007a250f55 up 6.11 2023-02-12 08:54:23 +08:00
2dust
e9bb6a9951 bug fixes 2023-02-12 08:53:28 +08:00
2dust
82f236e07b up 6.10 2023-02-11 20:03:54 +08:00
2dust
17bfe74ecf Add routing sort 2023-02-11 19:34:15 +08:00
2dust
b77827df90 Update v2rayN.csproj 2023-02-10 21:02:41 +08:00
2dust
a359a508ae fix Import old config 2023-02-10 21:02:29 +08:00
2dust
3a740118f0 Adjust task service settings 2023-02-10 18:58:20 +08:00
2dust
58d9bcbd14 tidy code github 2023-02-10 16:25:16 +08:00
2dust
24be7b2180 store msg filter 2023-02-10 16:01:47 +08:00
2dust
f4c9ca8dff Refactor routing basic settings 2023-02-10 14:51:00 +08:00
2dust
9b8181b72b Refactor gui settings 2023-02-10 14:36:37 +08:00
2dust
1ff1962425 Refactor basic settings 2023-02-10 14:16:59 +08:00
2dust
9b05736746 Add environment variables to geo files 2023-02-10 11:22:03 +08:00
2dust
dec722e693 Update UpdateHandle.cs 2023-02-10 11:05:11 +08:00
2dust
49fa0a4c67 DownloadStringAsyncOri 2023-02-10 11:04:57 +08:00
2dust
0cdc69e1e8 Update MsgView.xaml 2023-02-10 09:39:18 +08:00
2dust
0494cc4ce7 adjust group style 2023-02-09 16:43:50 +08:00
2dust
30d82947d6 fix 2023-02-09 15:17:52 +08:00
2dust
ec59249d79 Optimize file download 2023-02-09 14:54:54 +08:00
2dust
7eb869ab1d Optimize file download 2023-02-09 10:54:31 +08:00
2dust
d014724a2d Optimize speed test 2023-02-08 19:20:44 +08:00
2dust
dfb6cef364 Update OptionSettingWindow.xaml.cs 2023-02-08 15:07:23 +08:00
2dust
0ebf8c9349 Optimize Font size 2023-02-07 19:05:49 +08:00
34 changed files with 768 additions and 334 deletions

View File

@@ -18,8 +18,9 @@
</ResourceDictionary.MergedDictionaries>
<system:Double x:Key="MenuItemHeight">26</system:Double>
<system:Double x:Key="StdFontSize">12</system:Double>
<system:Double x:Key="StdFontSize1">14</system:Double>
<system:Double x:Key="StdFontSize2">16</system:Double>
<system:Double x:Key="StdFontSize1">13</system:Double>
<system:Double x:Key="StdFontSize2">14</system:Double>
<system:Double x:Key="StdFontSizeMsg">11</system:Double>
<Thickness
x:Key="ServerItemMargin"
Bottom="4"
@@ -134,6 +135,12 @@
TargetType="{x:Type GroupBox}">
<Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
</Style>
<Style
x:Key="MyChipListBoxItem"
BasedOn="{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBoxItem}"
TargetType="{x:Type ListBoxItem}">
<Setter Property="Margin" Value="-4,0" />
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,206 @@
using Downloader;
using System.IO;
using System.Net;
namespace v2rayN.Base
{
internal class DownloaderHelper
{
private static readonly Lazy<DownloaderHelper> _instance = new Lazy<DownloaderHelper>(() => new());
public static DownloaderHelper Instance => _instance.Value;
public DownloaderHelper()
{
}
public async Task<string> DownloadStringAsync(IWebProxy webProxy, string url, string? userAgent, int timeout)
{
if (string.IsNullOrEmpty(url))
{
return null;
}
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(timeout * 1000);
Uri uri = new Uri(url);
//Authorization Header
var headers = new WebHeaderCollection();
if (!Utils.IsNullOrEmpty(uri.UserInfo))
{
headers.Add(HttpRequestHeader.Authorization, "Basic " + Utils.Base64Encode(uri.UserInfo));
}
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Headers = headers,
UserAgent = userAgent,
Timeout = timeout * 1000,
Proxy = webProxy
}
};
string text = string.Empty;
using (var downloader = new DownloadService(downloadOpt))
{
downloader.DownloadFileCompleted += (sender, value) =>
{
if (value.Error != null)
{
throw new Exception(string.Format("{0}", value.Error.Message));
}
};
using (var stream = await downloader.DownloadFileTaskAsync(address: url, cancellationToken: cancellationToken.Token))
{
using (StreamReader reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
}
}
downloadOpt = null;
return text;
}
public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress<string> progress, int timeout)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(timeout * 1000);
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,
Proxy = webProxy
}
};
DateTime totalDatetime = DateTime.Now;
int totalSecond = 0;
var hasValue = false;
double maxSpeed = 0;
using (var downloader = new DownloadService(downloadOpt))
{
//downloader.DownloadStarted += (sender, value) =>
//{
// if (progress != null)
// {
// progress.Report("Start download data...");
// }
//};
downloader.DownloadProgressChanged += (sender, value) =>
{
TimeSpan ts = (DateTime.Now - totalDatetime);
if (progress != null && ts.Seconds > totalSecond)
{
hasValue = true;
totalSecond = ts.Seconds;
if (value.BytesPerSecondSpeed > maxSpeed)
{
maxSpeed = value.BytesPerSecondSpeed;
var speed = (maxSpeed / 1000 / 1000).ToString("#0.0");
progress.Report(speed);
}
}
};
downloader.DownloadFileCompleted += (sender, value) =>
{
if (progress != null)
{
if (!hasValue && value.Error != null)
{
progress.Report(value.Error?.Message);
}
}
};
progress.Report("......");
await downloader.DownloadFileTaskAsync(address: url, cancellationToken: cancellationToken.Token);
}
downloadOpt = null;
}
public async Task DownloadFileAsync(IWebProxy webProxy, string url, string fileName, IProgress<double> progress, int timeout)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException("fileName");
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(timeout * 1000);
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,
Proxy = webProxy
}
};
var progressPercentage = 0;
var hasValue = false;
using (var downloader = new DownloadService(downloadOpt))
{
downloader.DownloadStarted += (sender, value) =>
{
if (progress != null)
{
progress.Report(0);
}
};
downloader.DownloadProgressChanged += (sender, value) =>
{
hasValue = true;
var percent = (int)value.ProgressPercentage;// Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);
if (progressPercentage != percent && percent % 10 == 0)
{
progressPercentage = percent;
progress.Report(percent);
}
};
downloader.DownloadFileCompleted += (sender, value) =>
{
if (progress != null)
{
if (hasValue && value.Error == null)
{
progress.Report(101);
}
}
};
await downloader.DownloadFileTaskAsync(url, fileName, cancellationToken: cancellationToken.Token);
}
downloadOpt = null;
}
}
}

View File

@@ -3,6 +3,8 @@
class Global
{
#region const
public const string githubUrl = "https://github.com";
public const string githubApiUrl = "https://api.github.com/repos";
public const string v2rayWebsiteUrl = @"https://www.v2fly.org/";
public const string AboutUrl = @"https://github.com/2dust/v2rayN";
public const string UpdateUrl = AboutUrl + @"/releases";
@@ -17,7 +19,6 @@
public const string tuicCoreUrl = "https://github.com/EAimTY/tuic/releases";
public const string singboxCoreUrl = "https://github.com/SagerNet/sing-box/releases";
public const string geoUrl = "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/{0}.dat";
public const string SpeedTestUrl = @"http://cachefly.cachefly.net/10mb.test";
public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
@@ -115,7 +116,8 @@
public static readonly List<string> Protocols = new List<string> { "http", "tls", "bittorrent" };
public static readonly List<string> TunMtus = new List<string> { "9000", "1500" };
public static readonly List<string> TunStacks = new List<string> { "gvisor", "system" };
public static readonly List<string> PresetMsgFilters = new List<string> { "^(?!.*proxy).*$", "^(?!.*direct).*$", "" };
public static readonly List<string> PresetMsgFilters = new List<string> { "proxy", "direct", "block", "" };
public static readonly List<string> SpeedTestUrls = new List<string> { @"http://cachefly.cachefly.net/100mb.test", @"http://cachefly.cachefly.net/10mb.test" };
#endregion

View File

@@ -43,18 +43,17 @@ namespace v2rayN.Handler
if (config == null)
{
config = new Config
{
};
}
if (config.coreBasicItem == null)
{
config.coreBasicItem = new()
{
logEnabled = false,
loglevel = "warning",
//Mux
muxEnabled = false,
enableStatistics = false,
statisticsFreshRate = 1,
enableRoutingAdvanced = true
};
}
@@ -87,10 +86,17 @@ namespace v2rayN.Handler
config.inbound[0].protocol = Global.InboundSocks;
}
}
//路由规则
if (Utils.IsNullOrEmpty(config.domainStrategy))
if (config.routingBasicItem == null)
{
config.domainStrategy = Global.domainStrategys[0];//"IPIfNonMatch";
config.routingBasicItem = new()
{
enableRoutingAdvanced = true
};
}
//路由规则
if (Utils.IsNullOrEmpty(config.routingBasicItem.domainStrategy))
{
config.routingBasicItem.domainStrategy = Global.domainStrategys[0];//"IPIfNonMatch";
}
//if (Utils.IsNullOrEmpty(config.domainMatcher))
//{
@@ -130,6 +136,14 @@ namespace v2rayN.Handler
mtu = 9000,
};
}
if (config.guiItem == null)
{
config.guiItem = new()
{
enableStatistics = false,
statisticsFreshRate = 1,
};
}
if (config.uiItem == null)
{
config.uiItem = new UIItem()
@@ -150,14 +164,6 @@ namespace v2rayN.Handler
{
config.constItem = new ConstItem();
}
if (Utils.IsNullOrEmpty(config.constItem.speedTestUrl))
{
config.constItem.speedTestUrl = Global.SpeedTestUrl;
}
if (Utils.IsNullOrEmpty(config.constItem.speedPingTestUrl))
{
config.constItem.speedPingTestUrl = Global.SpeedPingTestUrl;
}
if (Utils.IsNullOrEmpty(config.constItem.defIEProxyExceptions))
{
config.constItem.defIEProxyExceptions = Global.IEProxyExceptions;
@@ -167,9 +173,26 @@ namespace v2rayN.Handler
// config.remoteDNS = "1.1.1.1";
//}
if (config.statisticsFreshRate > 100 || config.statisticsFreshRate < 1)
if (config.speedTestItem == null)
{
config.statisticsFreshRate = 1;
config.speedTestItem = new();
}
if (config.speedTestItem.speedTestTimeout < 10)
{
config.speedTestItem.speedTestTimeout = 10;
}
if (Utils.IsNullOrEmpty(config.speedTestItem.speedTestUrl))
{
config.speedTestItem.speedTestUrl = Global.SpeedTestUrls[0];
}
if (Utils.IsNullOrEmpty(config.speedTestItem.speedPingTestUrl))
{
config.speedTestItem.speedPingTestUrl = Global.SpeedPingTestUrl;
}
if (config.guiItem.statisticsFreshRate > 100 || config.guiItem.statisticsFreshRate < 1)
{
config.guiItem.statisticsFreshRate = 1;
}
if (config == null)
@@ -288,20 +311,45 @@ namespace v2rayN.Handler
}
config = Utils.FromJson<Config>(Utils.ToJson(configOld));
if (config.tunModeItem == null)
if (config.coreBasicItem == null)
{
config.tunModeItem = new TunModeItem
config.coreBasicItem = new()
{
enableTun = false,
showWindow = true,
mtu = 9000,
logEnabled = configOld.logEnabled,
loglevel = configOld.loglevel,
muxEnabled = configOld.muxEnabled,
};
}
if (config.routingBasicItem == null)
{
config.routingBasicItem = new()
{
enableRoutingAdvanced = configOld.enableRoutingAdvanced,
domainStrategy = configOld.domainStrategy
};
}
if (config.guiItem == null)
{
config.guiItem = new()
{
enableStatistics = configOld.enableStatistics,
statisticsFreshRate = configOld.statisticsFreshRate,
keepOlderDedupl = configOld.keepOlderDedupl,
ignoreGeoUpdateCore = configOld.ignoreGeoUpdateCore,
autoUpdateInterval = configOld.autoUpdateInterval,
checkPreReleaseUpdate = configOld.checkPreReleaseUpdate,
enableSecurityProtocolTls13 = configOld.enableSecurityProtocolTls13,
trayMenuServersLimit = configOld.trayMenuServersLimit,
};
}
GetDefaultServer(ref config);
GetDefaultRouting(ref config);
SaveConfig(ref config);
LazyConfig.Instance.SetConfig(ref config);
LoadConfig(ref config);
return 0;
}
@@ -638,7 +686,7 @@ namespace v2rayN.Handler
}
if (Utils.IsNullOrEmpty(profileItem.allowInsecure))
{
profileItem.allowInsecure = config.defAllowInsecure.ToString().ToLower();
profileItem.allowInsecure = config.coreBasicItem.defAllowInsecure.ToString().ToLower();
}
AddServerCommon(ref config, profileItem);
@@ -745,7 +793,7 @@ namespace v2rayN.Handler
public static int DedupServerList(ref Config config, ref List<ProfileItem> lstProfile)
{
List<ProfileItem> source = lstProfile;
bool keepOlder = config.keepOlderDedupl;
bool keepOlder = config.guiItem.keepOlderDedupl;
List<ProfileItem> list = new List<ProfileItem>();
if (!keepOlder) source.Reverse(); // Remove the early items first
@@ -772,7 +820,7 @@ namespace v2rayN.Handler
profileItem.configVersion = 2;
if (Utils.IsNullOrEmpty(profileItem.allowInsecure))
{
profileItem.allowInsecure = config.defAllowInsecure.ToString().ToLower();
profileItem.allowInsecure = config.coreBasicItem.defAllowInsecure.ToString().ToLower();
}
if (!Utils.IsNullOrEmpty(profileItem.network) && !Global.networks.Contains(profileItem.network))
{
@@ -1437,7 +1485,7 @@ namespace v2rayN.Handler
{
if (SqliteHelper.Instance.Table<RoutingItem>().Where(t => t.id == routingItem.id).Count() > 0)
{
config.routingIndexId = routingItem.id;
config.routingBasicItem.routingIndexId = routingItem.id;
}
Global.reloadCore = true;
@@ -1448,7 +1496,7 @@ namespace v2rayN.Handler
}
public static RoutingItem GetDefaultRouting(ref Config config)
{
var item = LazyConfig.Instance.GetRoutingItem(config.routingIndexId);
var item = LazyConfig.Instance.GetRoutingItem(config.routingBasicItem.routingIndexId);
if (item is null)
{
var item2 = SqliteHelper.Instance.Table<RoutingItem>().FirstOrDefault(t => t.locked == false);
@@ -1461,13 +1509,16 @@ namespace v2rayN.Handler
public static int InitBuiltinRouting(ref Config config, bool blImportAdvancedRules = false)
{
if (blImportAdvancedRules || LazyConfig.Instance.RoutingItems().Count <= 0)
var items = LazyConfig.Instance.RoutingItems();
if (blImportAdvancedRules || items.Count <= 0)
{
var maxSort = items.Count;
//Bypass the mainland
var item2 = new RoutingItem()
{
remarks = "绕过大陆(Whitelist)",
url = string.Empty,
sort = maxSort + 1,
};
AddBatchRoutingRules(ref item2, Utils.GetEmbedText(Global.CustomRoutingFileName + "white"));
@@ -1476,6 +1527,7 @@ namespace v2rayN.Handler
{
remarks = "黑名单(Blacklist)",
url = string.Empty,
sort = maxSort + 2,
};
AddBatchRoutingRules(ref item3, Utils.GetEmbedText(Global.CustomRoutingFileName + "black"));
@@ -1484,6 +1536,7 @@ namespace v2rayN.Handler
{
remarks = "全局(Global)",
url = string.Empty,
sort = maxSort + 3,
};
AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "global"));

View File

@@ -73,29 +73,29 @@ namespace v2rayN.Handler
{
if (blExport)
{
if (config.logEnabled)
if (config.coreBasicItem.logEnabled)
{
v2rayConfig.log.loglevel = config.loglevel;
v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
}
else
{
v2rayConfig.log.loglevel = config.loglevel;
v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
v2rayConfig.log.access = "";
v2rayConfig.log.error = "";
}
}
else
{
if (config.logEnabled)
if (config.coreBasicItem.logEnabled)
{
var dtNow = DateTime.Now;
v2rayConfig.log.loglevel = config.loglevel;
v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
v2rayConfig.log.access = Utils.GetLogPath($"Vaccess_{dtNow.ToString("yyyy-MM-dd")}.txt");
v2rayConfig.log.error = Utils.GetLogPath($"Verror_{dtNow.ToString("yyyy-MM-dd")}.txt");
}
else
{
v2rayConfig.log.loglevel = config.loglevel;
v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
v2rayConfig.log.access = "";
v2rayConfig.log.error = "";
}
@@ -187,10 +187,10 @@ namespace v2rayN.Handler
if (v2rayConfig.routing != null
&& v2rayConfig.routing.rules != null)
{
v2rayConfig.routing.domainStrategy = config.domainStrategy;
v2rayConfig.routing.domainMatcher = Utils.IsNullOrEmpty(config.domainMatcher) ? null : config.domainMatcher;
v2rayConfig.routing.domainStrategy = config.routingBasicItem.domainStrategy;
v2rayConfig.routing.domainMatcher = Utils.IsNullOrEmpty(config.routingBasicItem.domainMatcher) ? null : config.routingBasicItem.domainMatcher;
if (config.enableRoutingAdvanced)
if (config.routingBasicItem.enableRoutingAdvanced)
{
var routing = ConfigHandler.GetDefaultRouting(ref config);
if (routing != null)
@@ -348,8 +348,8 @@ namespace v2rayN.Handler
}
//Mux
outbound.mux.enabled = config.muxEnabled;
outbound.mux.concurrency = config.muxEnabled ? 8 : -1;
outbound.mux.enabled = config.coreBasicItem.muxEnabled;
outbound.mux.concurrency = config.coreBasicItem.muxEnabled ? 8 : -1;
boundStreamSettings(node, "out", outbound.streamSettings);
@@ -452,8 +452,8 @@ namespace v2rayN.Handler
usersItem.encryption = node.security;
//Mux
outbound.mux.enabled = config.muxEnabled;
outbound.mux.concurrency = config.muxEnabled ? 8 : -1;
outbound.mux.enabled = config.coreBasicItem.muxEnabled;
outbound.mux.concurrency = config.coreBasicItem.muxEnabled ? 8 : -1;
boundStreamSettings(node, "out", outbound.streamSettings);
@@ -548,15 +548,15 @@ namespace v2rayN.Handler
string host = node.requestHost.TrimEx();
string sni = node.sni;
string useragent = "";
if (!config.defUserAgent.IsNullOrEmpty())
if (!config.coreBasicItem.defUserAgent.IsNullOrEmpty())
{
try
{
useragent = Global.userAgentTxt[config.defUserAgent];
useragent = Global.userAgentTxt[config.coreBasicItem.defUserAgent];
}
catch (KeyNotFoundException)
{
useragent = config.defUserAgent;
useragent = config.coreBasicItem.defUserAgent;
}
}
@@ -567,9 +567,9 @@ namespace v2rayN.Handler
TlsSettings tlsSettings = new TlsSettings
{
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? config.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
alpn = node.GetAlpn(),
fingerprint = node.fingerprint.IsNullOrEmpty() ? config.defFingerprint : node.fingerprint
fingerprint = node.fingerprint.IsNullOrEmpty() ? config.coreBasicItem.defFingerprint : node.fingerprint
};
if (!string.IsNullOrWhiteSpace(sni))
{
@@ -589,9 +589,9 @@ namespace v2rayN.Handler
TlsSettings xtlsSettings = new TlsSettings
{
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? config.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
alpn = node.GetAlpn(),
fingerprint = node.fingerprint.IsNullOrEmpty() ? config.defFingerprint : node.fingerprint
fingerprint = node.fingerprint.IsNullOrEmpty() ? config.coreBasicItem.defFingerprint : node.fingerprint
};
if (!string.IsNullOrWhiteSpace(sni))
{
@@ -825,7 +825,7 @@ namespace v2rayN.Handler
private static int statistic(Config config, ref V2rayConfig v2rayConfig)
{
if (config.enableStatistics)
if (config.guiItem.enableStatistics)
{
string tag = Global.InboundAPITagName;
API apiObj = new API();

View File

@@ -20,6 +20,9 @@ namespace v2rayN.Handler
public CoreHandler(Action<bool, string> update)
{
_updateFunc = update;
Environment.SetEnvironmentVariable("v2ray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("xray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
}
public void LoadCore(Config config)

View File

@@ -33,20 +33,13 @@ namespace v2rayN.Handler
public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> update)
{
var hasValue = false;
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
var client = new HttpClient(new SocketsHttpHandler()
{
Proxy = webProxy
});
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
var progress = new Progress<string>();
progress.ProgressChanged += (sender, value) =>
{
hasValue = true;
if (update != null)
{
string msg = $"{value}";
@@ -54,22 +47,17 @@ namespace v2rayN.Handler
}
};
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(downloadTimeout * 1000);
await HttpClientHelper.GetInstance().DownloadDataAsync4Speed(client,
await DownloaderHelper.Instance.DownloadDataAsync4Speed(webProxy,
url,
progress,
cancellationToken.Token);
downloadTimeout);
}
catch (Exception ex)
{
if (!hasValue)
update(false, ex.Message);
if (ex.InnerException != null)
{
update(false, ex.Message);
if (ex.InnerException != null)
{
update(false, ex.InnerException.Message);
}
update(false, ex.InnerException.Message);
}
}
return 0;
@@ -79,14 +67,9 @@ namespace v2rayN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
var client = new HttpClient(new SocketsHttpHandler()
{
Proxy = GetWebProxy(blProxy)
});
var progress = new Progress<double>();
progress.ProgressChanged += (sender, value) =>
{
@@ -97,12 +80,12 @@ namespace v2rayN.Handler
}
};
var cancellationToken = new CancellationTokenSource();
_ = HttpClientHelper.GetInstance().DownloadFileAsync(client,
url,
Utils.GetTempPath(Utils.GetDownloadFileName(url)),
progress,
cancellationToken.Token);
var webProxy = GetWebProxy(blProxy);
_ = DownloaderHelper.Instance.DownloadFileAsync(webProxy,
url,
Utils.GetTempPath(Utils.GetDownloadFileName(url)),
progress,
downloadTimeout);
}
catch (Exception ex)
{
@@ -118,7 +101,7 @@ namespace v2rayN.Handler
public async Task<string> UrlRedirectAsync(string url, bool blProxy)
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
var webRequestHandler = new SocketsHttpHandler
{
AllowAutoRedirect = false,
@@ -146,7 +129,33 @@ namespace v2rayN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
var webProxy = GetWebProxy(blProxy);
var result = await DownloaderHelper.Instance.DownloadStringAsync(webProxy, url, userAgent, 30);
return result;
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
Error?.Invoke(this, new ErrorEventArgs(ex));
if (ex.InnerException != null)
{
Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));
}
}
return null;
}
/// <summary>
/// DownloadString
/// </summary>
/// <param name="url"></param>
public async Task<string> DownloadStringAsyncOri(string url, bool blProxy, string userAgent)
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);
var client = new HttpClient(new SocketsHttpHandler()
{
Proxy = GetWebProxy(blProxy)
@@ -196,7 +205,7 @@ namespace v2rayN.Handler
try
{
var config = LazyConfig.Instance.GetConfig();
string status = GetRealPingTime(config.constItem.speedPingTestUrl, webProxy, 10, out int responseTime);
string status = GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10, out int responseTime);
bool noError = Utils.IsNullOrEmpty(status);
return noError ? responseTime : -1;
}

View File

@@ -139,7 +139,7 @@ namespace v2rayN.Handler
public List<RoutingItem> RoutingItems()
{
return SqliteHelper.Instance.Table<RoutingItem>().Where(it => it.locked == false).ToList();
return SqliteHelper.Instance.Table<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToList();
}
public RoutingItem GetRoutingItem(string id)
{
@@ -209,7 +209,7 @@ namespace v2rayN.Handler
{
coreType = ECoreType.v2rayN,
coreUrl = Global.NUrl,
coreReleaseApiUrl = Global.NUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreReleaseApiUrl = Global.NUrl.Replace(Global.githubUrl, Global.githubApiUrl),
coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN.zip",
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip",
});
@@ -220,7 +220,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "wv2ray", "v2ray" },
arguments = "",
coreUrl = Global.v2flyCoreUrl,
coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
match = "V2Ray",
@@ -234,7 +234,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "SagerNet", "v2ray" },
arguments = "run",
coreUrl = Global.SagerNetCoreUrl,
coreReleaseApiUrl = Global.SagerNetCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
match = "V2Ray",
@@ -248,7 +248,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "v2ray" },
arguments = "run",
coreUrl = Global.v2flyCoreUrl,
coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
match = "V2Ray",
@@ -262,7 +262,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "xray", "wxray" },
arguments = "",
coreUrl = Global.xrayCoreUrl,
coreReleaseApiUrl = Global.xrayCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
match = "Xray",
@@ -276,7 +276,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
arguments = "-f config.json",
coreUrl = Global.clashCoreUrl,
coreReleaseApiUrl = Global.clashCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
match = "v",
@@ -290,7 +290,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" },
arguments = "-f config.json",
coreUrl = Global.clashMetaCoreUrl,
coreReleaseApiUrl = Global.clashMetaCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
match = "v",
@@ -304,7 +304,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
arguments = "",
coreUrl = Global.hysteriaCoreUrl,
coreReleaseApiUrl = Global.hysteriaCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
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",
redirectInfo = true,

View File

@@ -86,7 +86,7 @@ namespace v2rayN.Handler
{
try
{
if (!config.enableRoutingAdvanced)
if (!config.routingBasicItem.enableRoutingAdvanced)
{
return null;
}
@@ -309,9 +309,9 @@ namespace v2rayN.Handler
{
var dtNow = DateTime.Now;
if (config.autoUpdateSubInterval > 0)
if (config.guiItem.autoUpdateSubInterval > 0)
{
if ((dtNow - autoUpdateSubTime).Hours % config.autoUpdateSubInterval == 0)
if ((dtNow - autoUpdateSubTime).Hours % config.guiItem.autoUpdateSubInterval == 0)
{
updateHandle.UpdateSubscriptionProcess(config, "", true, (bool success, string msg) =>
{
@@ -324,9 +324,9 @@ namespace v2rayN.Handler
Thread.Sleep(60000);
}
if (config.autoUpdateInterval > 0)
if (config.guiItem.autoUpdateInterval > 0)
{
if ((dtNow - autoUpdateGeoTime).Hours % config.autoUpdateInterval == 0)
if ((dtNow - autoUpdateGeoTime).Hours % config.guiItem.autoUpdateInterval == 0)
{
updateHandle.UpdateGeoFile("geosite", config, (bool success, string msg) =>
{

View File

@@ -34,6 +34,10 @@ namespace v2rayN.Handler
{
continue;
}
if (it.port <= 0)
{
continue;
}
_selecteds.Add(new ServerTestItem()
{
indexId = it.indexId,
@@ -195,10 +199,10 @@ namespace v2rayN.Handler
private async Task RunSpeedTestAsync()
{
int pid = -1;
if (_actionType == ESpeedActionType.Mixedtest)
{
_selecteds = _selecteds.OrderBy(t => t.delay).ToList();
}
//if (_actionType == ESpeedActionType.Mixedtest)
//{
// _selecteds = _selecteds.OrderBy(t => t.delay).ToList();
//}
pid = _coreHandler.LoadCoreConfigString(_config, _selecteds);
if (pid < 0)
@@ -207,10 +211,11 @@ namespace v2rayN.Handler
return;
}
string url = _config.constItem.speedTestUrl;
string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new DownloadHandle();
var timeout = 8;
foreach (var it in _selecteds)
{
if (!it.allowTest)
@@ -221,11 +226,11 @@ namespace v2rayN.Handler
{
continue;
}
if (it.delay < 0)
{
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
continue;
}
//if (it.delay < 0)
//{
// UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
// continue;
//}
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
@@ -250,18 +255,71 @@ namespace v2rayN.Handler
}
UpdateFunc("", ResUI.SpeedtestingCompleted);
}
private async Task RunSpeedTestMulti()
{
int pid = -1;
pid = _coreHandler.LoadCoreConfigString(_config, _selecteds);
if (pid < 0)
{
UpdateFunc("", ResUI.FailedToRunCore);
return;
}
string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new DownloadHandle();
foreach (var it in _selecteds)
{
if (!it.allowTest)
{
continue;
}
if (it.configType == EConfigType.Custom)
{
continue;
}
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
if (item is null) continue;
WebProxy webProxy = new WebProxy(Global.Loopback, it.port);
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>
{
decimal.TryParse(msg, out decimal dec);
if (dec > 0)
{
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", msg);
}
UpdateFunc(it.indexId, "", msg);
});
Thread.Sleep(2000);
}
Thread.Sleep((timeout + 2) * 1000);
if (pid > 0)
{
_coreHandler.CoreStopPid(pid);
}
UpdateFunc("", ResUI.SpeedtestingCompleted);
}
private async Task RunMixedtestAsync()
{
await RunRealPing();
Thread.Sleep(1000);
await RunSpeedTestAsync();
await RunSpeedTestMulti();
}
public string GetRealPingTime(DownloadHandle downloadHandle, WebProxy webProxy)
{
string status = downloadHandle.GetRealPingTime(_config.constItem.speedPingTestUrl, webProxy, 10, out int responseTime);
string status = downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10, out int responseTime);
//string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
return FormatOut(Utils.IsNullOrEmpty(status) ? responseTime : -1, Global.DelayUnit);
}

View File

@@ -27,7 +27,7 @@ namespace v2rayN.Handler
public StatisticsHandler(Mode.Config config, Action<ServerSpeedItem> update)
{
config_ = config;
Enable = config.enableStatistics;
Enable = config.guiItem.enableStatistics;
updateFunc_ = update;
exitFlag_ = false;
@@ -103,7 +103,7 @@ namespace v2rayN.Handler
}
}
}
var sleep = config_.statisticsFreshRate < 1 ? 1 : config_.statisticsFreshRate;
var sleep = config_.guiItem.statisticsFreshRate < 1 ? 1 : config_.guiItem.statisticsFreshRate;
Thread.Sleep(1000 * sleep);
channel_.ConnectAsync();
}

View File

@@ -184,12 +184,12 @@ namespace v2rayN.Base
configStr = configStr.Replace("$ruleProxyIPs$", "");
configStr = configStr.Replace("$ruleProxyProcess$", "");
configStr = configStr.Replace("$ruleFinally$", "");
File.WriteAllText(Utils.GetConfigPath(_tunConfigName), configStr);
return true;
}
}
private void CoreStop()
{

View File

@@ -278,11 +278,13 @@ namespace v2rayN.Handler
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
if (File.Exists(fileName))
{
Global.coreTypes.ForEach(it =>
{
string targetPath = Utils.GetBinPath($"{geoName}.dat", (ECoreType)Enum.Parse(typeof(ECoreType), it));
File.Copy(fileName, targetPath, true);
});
//Global.coreTypes.ForEach(it =>
//{
// string targetPath = Utils.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);
File.Delete(fileName);
//_updateFunc(true, "");
@@ -326,7 +328,7 @@ namespace v2rayN.Handler
var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
string url = coreInfo.coreReleaseApiUrl;
var result = await (new DownloadHandle()).DownloadStringAsync(url, true, "");
var result = await (new DownloadHandle()).DownloadStringAsyncOri(url, true, "");
if (!Utils.IsNullOrEmpty(result))
{
responseHandler(type, result, preRelease);

View File

@@ -8,150 +8,31 @@
{
#region property
/// <summary>
/// 允许日志
/// </summary>
public bool logEnabled
{
get; set;
}
/// <summary>
/// 日志等级
/// </summary>
public string loglevel
{
get; set;
}
public string indexId
{
get; set;
}
/// <summary>
/// 允许Mux多路复用
/// </summary>
public bool muxEnabled
{
get; set;
}
/// <summary>
///
/// </summary>
public ESysProxyType sysProxyType
{
get; set;
}
public bool autoRun { get; set; }
/// <summary>
/// 启用实时网速和流量统计
/// </summary>
public bool enableStatistics
{
get; set;
}
/// <summary>
/// 去重时优先保留较旧(顶部)节点
/// </summary>
public bool keepOlderDedupl
{
get; set;
}
/// <summary>
/// 视图刷新率
/// </summary>
public int statisticsFreshRate
{
get; set;
}
/// <summary>
/// 自定义远程DNS
/// </summary>
public string remoteDNS
{
get; set;
}
public string indexId { get; set; }
public string remoteDNS { get; set; }
/// <summary>
/// Outbound Freedom domainStrategy
/// </summary>
public string domainStrategy4Freedom
{
get; set;
}
public string domainStrategy4Freedom { get; set; }
/// <summary>
/// 是否允许不安全连接
/// </summary>
public bool defAllowInsecure { get; set; }
public string defFingerprint { get; set; }
/// <summary>
/// 默认用户代理
/// </summary>
public string defUserAgent { get; set; }
/// <summary>
/// 域名解析策略
/// </summary>
public string domainStrategy
{
get; set;
}
public string domainMatcher
{
get; set;
}
public string routingIndexId { get; set; }
public bool enableRoutingAdvanced
{
get; set;
}
public bool ignoreGeoUpdateCore
{
get; set;
}
/// <summary>
/// systemProxyExceptions
/// </summary>
public string systemProxyExceptions
{
get; set;
}
public ESysProxyType sysProxyType { get; set; }
public string systemProxyExceptions { get; set; }
public string systemProxyAdvancedProtocol { get; set; }
public int autoUpdateInterval { get; set; } = 10;
public int autoUpdateSubInterval { get; set; } = 10;
public bool checkPreReleaseUpdate { get; set; } = false;
public bool enableSecurityProtocolTls13
{
get; set;
}
public int trayMenuServersLimit { get; set; } = 20;
#endregion
#region other entities
public CoreBasicItem coreBasicItem { get; set; }
public TunModeItem tunModeItem { get; set; }
public KcpItem kcpItem { get; set; }
public GrpcItem grpcItem { get; set; }
public RoutingBasicItem routingBasicItem { get; set; }
public GUIItem guiItem { get; set; }
public UIItem uiItem { get; set; }
public ConstItem constItem { get; set; }
public SpeedTestItem speedTestItem { get; set; }
public List<InItem> inbound { get; set; }
public List<KeyEventItem> globalHotkeys { get; set; }
public List<CoreTypeItem> coreTypeItem { get; set; }

View File

@@ -2,6 +2,37 @@
namespace v2rayN.Mode
{
[Serializable]
public class CoreBasicItem
{
/// <summary>
/// 允许日志
/// </summary>
public bool logEnabled { get; set; }
/// <summary>
/// 日志等级
/// </summary>
public string loglevel { get; set; }
/// <summary>
/// 允许Mux多路复用
/// </summary>
public bool muxEnabled { get; set; }
/// <summary>
/// 是否允许不安全连接
/// </summary>
public bool defAllowInsecure { get; set; }
public string defFingerprint { get; set; }
/// <summary>
/// 默认用户代理
/// </summary>
public string defUserAgent { get; set; }
}
[Serializable]
public class InItem
{
@@ -51,6 +82,30 @@ namespace v2rayN.Mode
public int initial_windows_size { get; set; }
}
[Serializable]
public class GUIItem
{
public bool autoRun { get; set; }
public bool enableStatistics { get; set; }
public int statisticsFreshRate { get; set; }
public bool keepOlderDedupl { get; set; }
public bool ignoreGeoUpdateCore { get; set; } = true;
public int autoUpdateInterval { get; set; } = 10;
public int autoUpdateSubInterval { get; set; } = 10;
public bool checkPreReleaseUpdate { get; set; } = false;
public bool enableSecurityProtocolTls13 { get; set; }
public int trayMenuServersLimit { get; set; } = 20;
}
[Serializable]
public class UIItem
{
@@ -67,14 +122,13 @@ namespace v2rayN.Mode
public bool enableDragDropSort { get; set; }
public bool doubleClick2Activate { get; set; }
public bool autoHideStartup { get; set; } = true;
public string mainMsgFilter { get; set; }
public Dictionary<string, int> mainLvColWidth { get; set; }
}
[Serializable]
public class ConstItem
{
public string speedTestUrl { get; set; }
public string speedPingTestUrl { get; set; }
public string defIEProxyExceptions { get; set; }
}
@@ -117,4 +171,25 @@ namespace v2rayN.Mode
public List<string> proxyProcess { get; set; }
}
[Serializable]
public class SpeedTestItem
{
public int speedTestTimeout { get; set; }
public string speedTestUrl { get; set; }
public string speedPingTestUrl { get; set; }
}
[Serializable]
public class RoutingBasicItem
{
/// <summary>
/// 域名解析策略
/// </summary>
public string domainStrategy { get; set; }
public string domainMatcher { get; set; }
public string routingIndexId { get; set; }
public bool enableRoutingAdvanced { get; set; }
}
}

View File

@@ -15,6 +15,7 @@ namespace v2rayN.Mode
public bool locked { get; set; }
public string customIcon { get; set; }
public string domainStrategy { get; set; }
public int sort { get; set; }
}
}

View File

@@ -70,7 +70,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 All servers 的本地化字符串。
/// 查找类似 All 的本地化字符串。
/// </summary>
public static string AllGroupServers {
get {
@@ -790,7 +790,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 One-click test Latency and speed (Ctrl+E) 的本地化字符串。
/// 查找类似 One-click multi test Latency and speed (Ctrl+E) 的本地化字符串。
/// </summary>
public static string menuMixedTestServer {
get {
@@ -2689,6 +2689,24 @@ namespace v2rayN.Resx {
}
}
/// <summary>
/// 查找类似 SpeedTest Single Timeout Value 的本地化字符串。
/// </summary>
public static string TbSettingsSpeedTestTimeout {
get {
return ResourceManager.GetString("TbSettingsSpeedTestTimeout", resourceCulture);
}
}
/// <summary>
/// 查找类似 SpeedTest Url 的本地化字符串。
/// </summary>
public static string TbSettingsSpeedTestUrl {
get {
return ResourceManager.GetString("TbSettingsSpeedTestUrl", resourceCulture);
}
}
/// <summary>
/// 查找类似 Start on boot 的本地化字符串。
/// </summary>

View File

@@ -449,7 +449,7 @@
<value>Ungrouped</value>
</data>
<data name="AllGroupServers" xml:space="preserve">
<value>All servers</value>
<value>All</value>
</data>
<data name="FillServerAddressCustom" xml:space="preserve">
<value>Please browse to import server configuration</value>
@@ -1022,7 +1022,7 @@
<value>RouteOnly</value>
</data>
<data name="menuMixedTestServer" xml:space="preserve">
<value>One-click test Latency and speed (Ctrl+E)</value>
<value>One-click multi test Latency and speed (Ctrl+E)</value>
</data>
<data name="LvTestDelay" xml:space="preserve">
<value>Delay(ms)</value>
@@ -1120,4 +1120,10 @@
<data name="TbSettingsTunModeBypassModeTip" xml:space="preserve">
<value>Enable: If no route matches, the final proxy</value>
</data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>SpeedTest Single Timeout Value</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>SpeedTest Url</value>
</data>
</root>

View File

@@ -449,7 +449,7 @@
<value>未分组服务器</value>
</data>
<data name="AllGroupServers" xml:space="preserve">
<value>所有服务器</value>
<value>所有</value>
</data>
<data name="FillServerAddressCustom" xml:space="preserve">
<value>请浏览导入服务器配置</value>
@@ -1022,7 +1022,7 @@
<value>RouteOnly</value>
</data>
<data name="menuMixedTestServer" xml:space="preserve">
<value>一键测试延迟和速度 (Ctrl+E)</value>
<value>一键多线程测试延迟和速度 (Ctrl+E)</value>
</data>
<data name="LvTestDelay" xml:space="preserve">
<value>延迟(ms)</value>
@@ -1120,4 +1120,10 @@
<data name="TbSettingsTunModeBypassModeTip" xml:space="preserve">
<value>启用:路由无匹配则最终代理</value>
</data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>测速单个超时值</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>测速文件地址</value>
</data>
</root>

View File

@@ -786,6 +786,10 @@ namespace v2rayN
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.FromMinutes(1) });
task.Principal.RunLevel = TaskRunLevel.Highest;
task.Actions.Add(new ExecAction(deamonFileName));
@@ -1117,7 +1121,14 @@ namespace v2rayN
Directory.CreateDirectory(_tempPath);
}
}
return Path.Combine(_tempPath, filename);
if (string.IsNullOrEmpty(filename))
{
return _tempPath;
}
else
{
return Path.Combine(_tempPath, filename);
}
}
public static string GetLogPath(string filename = "")
{

View File

@@ -506,7 +506,7 @@ namespace v2rayN.ViewModels
//MainFormHandler.Instance.BackupGuiNConfig(_config, true);
_coreHandler = new CoreHandler(UpdateHandler);
if (_config.enableStatistics)
if (_config.guiItem.enableStatistics)
{
_statistics = new StatisticsHandler(_config, UpdateStatisticsHandler);
}
@@ -773,7 +773,7 @@ namespace v2rayN.ViewModels
private void RefreshServersMenu()
{
_servers.Clear();
if (_lstProfile.Count > _config.trayMenuServersLimit)
if (_lstProfile.Count > _config.guiItem.trayMenuServersLimit)
{
return;
}
@@ -1225,7 +1225,7 @@ namespace v2rayN.ViewModels
}
private void UpdateSubscriptionProcess(string subId, bool blProxy)
{
{
(new UpdateHandle()).UpdateSubscriptionProcess(_config, subId, blProxy, UpdateTaskHandler);
}
@@ -1301,7 +1301,7 @@ namespace v2rayN.ViewModels
MyAppExit(false);
}
};
(new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI, _config.checkPreReleaseUpdate);
(new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI, _config.guiItem.checkPreReleaseUpdate);
}
private void CheckUpdateCore(ECoreType type)
@@ -1316,7 +1316,7 @@ namespace v2rayN.ViewModels
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(msg));
string toPath = Utils.GetBinPath("", type);
FileManager.ZipExtractToFile(fileName, toPath, _config.ignoreGeoUpdateCore ? "geo" : "");
FileManager.ZipExtractToFile(fileName, toPath, _config.guiItem.ignoreGeoUpdateCore ? "geo" : "");
_noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
@@ -1330,7 +1330,7 @@ namespace v2rayN.ViewModels
}
}
};
(new UpdateHandle()).CheckUpdateCore(type, _config, _updateUI, _config.checkPreReleaseUpdate);
(new UpdateHandle()).CheckUpdateCore(type, _config, _updateUI, _config.guiItem.checkPreReleaseUpdate);
}
private void CheckUpdateGeo()
@@ -1434,7 +1434,7 @@ namespace v2rayN.ViewModels
private void RefreshRoutingsMenu()
{
_routingItems.Clear();
if (!_config.enableRoutingAdvanced)
if (!_config.routingBasicItem.enableRoutingAdvanced)
{
BlRouting = false;
return;
@@ -1445,7 +1445,7 @@ namespace v2rayN.ViewModels
foreach (var item in routings)
{
_routingItems.Add(item);
if (item.id.Equals(_config.routingIndexId))
if (item.id.Equals(_config.routingBasicItem.routingIndexId))
{
SelectedRouting = item;
}
@@ -1469,7 +1469,7 @@ namespace v2rayN.ViewModels
{
return;
}
if (_config.routingIndexId == item.id)
if (_config.routingBasicItem.routingIndexId == item.id)
{
return;
}
@@ -1616,8 +1616,9 @@ namespace v2rayN.ViewModels
_config.uiItem.currentFontSize = CurrentFontSize;
double size = (long)CurrentFontSize;
Application.Current.Resources["StdFontSize"] = size;
Application.Current.Resources["StdFontSize1"] = size + 2;
Application.Current.Resources["StdFontSize2"] = size + 4;
Application.Current.Resources["StdFontSize1"] = size + 1;
Application.Current.Resources["StdFontSize2"] = size + 2;
Application.Current.Resources["StdFontSizeMsg"] = size - 1;
ConfigHandler.SaveConfig(ref _config);
}

View File

@@ -63,6 +63,8 @@ namespace v2rayN.ViewModels
[Reactive] public int autoUpdateSubInterval { get; set; }
[Reactive] public int trayMenuServersLimit { get; set; }
[Reactive] public string currentFontFamily { get; set; }
[Reactive] public int SpeedTestTimeout { get; set; }
[Reactive] public string SpeedTestUrl { get; set; }
#endregion
@@ -114,12 +116,12 @@ namespace v2rayN.ViewModels
newPort4LAN = inbound.newPort4LAN;
user = inbound.user;
pass = inbound.pass;
muxEnabled = _config.muxEnabled;
logEnabled = _config.logEnabled;
loglevel = _config.loglevel;
defAllowInsecure = _config.defAllowInsecure;
defFingerprint = _config.defFingerprint;
defUserAgent = _config.defUserAgent;
muxEnabled = _config.coreBasicItem.muxEnabled;
logEnabled = _config.coreBasicItem.logEnabled;
loglevel = _config.coreBasicItem.loglevel;
defAllowInsecure = _config.coreBasicItem.defAllowInsecure;
defFingerprint = _config.coreBasicItem.defFingerprint;
defUserAgent = _config.coreBasicItem.defUserAgent;
#endregion
#region Core DNS
@@ -138,21 +140,23 @@ namespace v2rayN.ViewModels
#endregion
#region UI
AutoRun = _config.autoRun;
EnableStatistics = _config.enableStatistics;
StatisticsFreshRate = _config.statisticsFreshRate;
KeepOlderDedupl = _config.keepOlderDedupl;
IgnoreGeoUpdateCore = _config.ignoreGeoUpdateCore;
AutoRun = _config.guiItem.autoRun;
EnableStatistics = _config.guiItem.enableStatistics;
StatisticsFreshRate = _config.guiItem.statisticsFreshRate;
KeepOlderDedupl = _config.guiItem.keepOlderDedupl;
IgnoreGeoUpdateCore = _config.guiItem.ignoreGeoUpdateCore;
EnableAutoAdjustMainLvColWidth = _config.uiItem.enableAutoAdjustMainLvColWidth;
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13;
EnableSecurityProtocolTls13 = _config.guiItem.enableSecurityProtocolTls13;
AutoHideStartup = _config.uiItem.autoHideStartup;
EnableCheckPreReleaseUpdate = _config.checkPreReleaseUpdate;
EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate;
EnableDragDropSort = _config.uiItem.enableDragDropSort;
DoubleClick2Activate = _config.uiItem.doubleClick2Activate;
autoUpdateInterval = _config.autoUpdateInterval;
autoUpdateSubInterval = _config.autoUpdateSubInterval;
trayMenuServersLimit = _config.trayMenuServersLimit;
autoUpdateInterval = _config.guiItem.autoUpdateInterval;
autoUpdateSubInterval = _config.guiItem.autoUpdateSubInterval;
trayMenuServersLimit = _config.guiItem.trayMenuServersLimit;
currentFontFamily = _config.uiItem.currentFontFamily;
SpeedTestTimeout = _config.speedTestItem.speedTestTimeout;
SpeedTestUrl = _config.speedTestItem.speedTestUrl;
#endregion
@@ -283,12 +287,12 @@ namespace v2rayN.ViewModels
{
_config.inbound.RemoveAt(1);
}
_config.logEnabled = logEnabled;
_config.loglevel = loglevel;
_config.muxEnabled = muxEnabled;
_config.defAllowInsecure = defAllowInsecure;
_config.defFingerprint = defFingerprint;
_config.defUserAgent = defUserAgent;
_config.coreBasicItem.logEnabled = logEnabled;
_config.coreBasicItem.loglevel = loglevel;
_config.coreBasicItem.muxEnabled = muxEnabled;
_config.coreBasicItem.defAllowInsecure = defAllowInsecure;
_config.coreBasicItem.defFingerprint = defFingerprint;
_config.coreBasicItem.defUserAgent = defUserAgent;
//DNS
@@ -308,25 +312,27 @@ namespace v2rayN.ViewModels
//UI
Utils.SetAutoRun(AutoRun);
_config.autoRun = AutoRun;
_config.enableStatistics = EnableStatistics;
_config.statisticsFreshRate = StatisticsFreshRate;
if (_config.statisticsFreshRate > 100 || _config.statisticsFreshRate < 1)
_config.guiItem.autoRun = AutoRun;
_config.guiItem.enableStatistics = EnableStatistics;
_config.guiItem.statisticsFreshRate = StatisticsFreshRate;
if (_config.guiItem.statisticsFreshRate > 100 || _config.guiItem.statisticsFreshRate < 1)
{
_config.statisticsFreshRate = 1;
_config.guiItem.statisticsFreshRate = 1;
}
_config.keepOlderDedupl = KeepOlderDedupl;
_config.ignoreGeoUpdateCore = IgnoreGeoUpdateCore;
_config.guiItem.keepOlderDedupl = KeepOlderDedupl;
_config.guiItem.ignoreGeoUpdateCore = IgnoreGeoUpdateCore;
_config.uiItem.enableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth;
_config.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
_config.guiItem.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
_config.uiItem.autoHideStartup = AutoHideStartup;
_config.autoUpdateInterval = autoUpdateInterval;
_config.autoUpdateSubInterval = autoUpdateSubInterval;
_config.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
_config.guiItem.autoUpdateInterval = autoUpdateInterval;
_config.guiItem.autoUpdateSubInterval = autoUpdateSubInterval;
_config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
_config.uiItem.enableDragDropSort = EnableDragDropSort;
_config.uiItem.doubleClick2Activate = DoubleClick2Activate;
_config.trayMenuServersLimit = trayMenuServersLimit;
_config.guiItem.trayMenuServersLimit = trayMenuServersLimit;
_config.uiItem.currentFontFamily = currentFontFamily;
_config.speedTestItem.speedTestTimeout = SpeedTestTimeout;
_config.speedTestItem.speedTestUrl = SpeedTestUrl;
//systemProxy
_config.systemProxyExceptions = systemProxyExceptions;

View File

@@ -71,9 +71,9 @@ namespace v2rayN.ViewModels
ConfigHandler.InitBuiltinRouting(ref _config);
enableRoutingAdvanced = _config.enableRoutingAdvanced;
domainStrategy = _config.domainStrategy;
domainMatcher = _config.domainMatcher;
enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced;
domainStrategy = _config.routingBasicItem.domainStrategy;
domainMatcher = _config.routingBasicItem.domainMatcher;
RefreshRoutingItems();
@@ -163,7 +163,7 @@ namespace v2rayN.ViewModels
foreach (var item in routings)
{
bool def = false;
if (item.id.Equals(_config.routingIndexId))
if (item.id.Equals(_config.routingBasicItem.routingIndexId))
{
def = true;
}
@@ -176,15 +176,16 @@ namespace v2rayN.ViewModels
remarks = item.remarks,
url = item.url,
customIcon = item.customIcon,
sort = item.sort,
};
_routingItems.Add(it);
}
}
private void SaveRouting()
{
_config.domainStrategy = domainStrategy;
_config.enableRoutingAdvanced = enableRoutingAdvanced;
_config.domainMatcher = domainMatcher;
_config.routingBasicItem.domainStrategy = domainStrategy;
_config.routingBasicItem.enableRoutingAdvanced = enableRoutingAdvanced;
_config.routingBasicItem.domainMatcher = domainMatcher;
EndBindingLockedData();

View File

@@ -339,7 +339,11 @@
VerticalAlignment="Center"
ClipToBounds="True"
Style="{StaticResource MaterialDesignToolBar}">
<ListBox x:Name="lstGroup" Style="{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBox}">
<ListBox
x:Name="lstGroup"
FontSize="{DynamicResource StdFontSize}"
ItemContainerStyle="{StaticResource MyChipListBoxItem}"
Style="{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBox}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding remarks}" />
@@ -350,15 +354,15 @@
x:Name="btnAddSub"
Width="30"
Height="30"
Margin="8,0"
Margin="4,0"
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}">
<materialDesign:PackIcon Kind="Plus" />
</Button>
<Separator />
<TextBox
x:Name="txtServerFilter"
Width="200"
Margin="8,0"
Width="100"
Margin="4,0"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
materialDesign:TextFieldAssist.HasClearButton="True"
Style="{StaticResource DefTextBox}" />

View File

@@ -434,7 +434,7 @@ namespace v2rayN.Views
var width = ConfigHandler.GetformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].Width.Value));
lstProfiles.Columns[k].Width = width;
}
if (!_config.enableStatistics)
if (!_config.guiItem.enableStatistics)
{
colTodayUp.Visibility = Visibility.Hidden;
colTodayDown.Visibility = Visibility.Hidden;

View File

@@ -29,7 +29,8 @@
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}"
materialDesign:TextFieldAssist.HasClearButton="True"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
Style="{StaticResource DefComboBox}"
TextBoxBase.TextChanged="cmbMsgFilter_TextChanged" />
<TextBlock
Margin="8,0"
VerticalAlignment="Center"
@@ -44,9 +45,10 @@
<TextBox
Name="txtMsg"
BorderThickness="0"
FontSize="{DynamicResource StdFontSize}"
FontSize="{DynamicResource StdFontSizeMsg}"
HorizontalScrollBarVisibility="Auto"
IsReadOnly="True"
TextAlignment="Left"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Visible">
<TextBox.ContextMenu>

View File

@@ -3,19 +3,27 @@ using System.Reactive.Linq;
using System.Text.RegularExpressions;
using System.Windows.Threading;
using v2rayN.Base;
using v2rayN.Handler;
using v2rayN.Mode;
namespace v2rayN.Views
{
public partial class MsgView
{
private static Config _config;
public MsgView()
{
InitializeComponent();
_config = LazyConfig.Instance.GetConfig();
MessageBus.Current.Listen<string>("MsgView").Subscribe(x => DelegateAppendText(x));
Global.PresetMsgFilters.ForEach(it =>
{
cmbMsgFilter.Items.Add(it);
});
if (!_config.uiItem.mainMsgFilter.IsNullOrEmpty())
{
cmbMsgFilter.Text = _config.uiItem.mainMsgFilter;
}
}
void DelegateAppendText(string msg)
@@ -87,6 +95,10 @@ namespace v2rayN.Views
{
ClearMsg();
}
private void cmbMsgFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
_config.uiItem.mainMsgFilter = cmbMsgFilter.Text.TrimEx();
}
}
}

View File

@@ -478,6 +478,8 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -660,6 +662,7 @@
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
@@ -675,6 +678,7 @@
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
@@ -690,6 +694,7 @@
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
@@ -714,6 +719,36 @@
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyTip}" />
<TextBlock
Grid.Row="16"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSpeedTestTimeout}" />
<ComboBox
x:Name="cmbSpeedTestTimeout"
Grid.Row="16"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="17"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSpeedTestUrl}" />
<ComboBox
x:Name="cmbSpeedTestUrl"
Grid.Row="17"
Grid.Column="1"
Width="300"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
</Grid>
</ScrollViewer>
</TabItem>

View File

@@ -63,12 +63,21 @@ namespace v2rayN.Views
cmbCoreType6.Items.Add(it);
});
for (int i = 2; i <= 6; i++)
{
cmbSpeedTestTimeout.Items.Add(i * 5);
}
Global.SpeedTestUrls.ForEach(it =>
{
cmbSpeedTestUrl.Items.Add(it);
});
//fill fonts
try
{
var dir = new DirectoryInfo(Utils.GetFontsPath());
var files = dir.GetFiles("*.ttf");
var culture = _config.uiItem.currentLanguage.Equals(Global.Languages[0]) ? "zh-cn" : "en-us";
var culture = _config.uiItem.currentLanguage.Equals(Global.Languages[0]) ? "zh-cn" : "en-us";
var culture2 = "en-us";
foreach (var it in files)
{
@@ -79,11 +88,11 @@ namespace v2rayN.Views
foreach (Typeface typeface in typefaces)
{
typeface.TryGetGlyphTypeface(out GlyphTypeface glyph);
var fontFace = glyph.Win32FaceNames[new CultureInfo("en-us")];
if (!fontFace.Equals("Regular") && !fontFace.Equals("Normal"))
{
continue;
}
//var fontFace = glyph.Win32FaceNames[new CultureInfo("en-us")];
//if (!fontFace.Equals("Regular") && !fontFace.Equals("Normal"))
//{
// continue;
//}
var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];
if (Utils.IsNullOrEmpty(fontFamily))
{
@@ -153,6 +162,8 @@ namespace v2rayN.Views
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);
this.Bind(ViewModel, vm => vm.SpeedTestUrl, v => v.cmbSpeedTestUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);

View File

@@ -92,6 +92,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -177,6 +178,23 @@
Content="{x:Static resx:ResUI.TbBrowse}"
Style="{StaticResource DefButton}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.LvSort}" />
<TextBox
x:Name="txtSort"
Grid.Row="4"
Grid.Column="1"
Width="200"
Margin="4"
HorizontalAlignment="Left"
AcceptsReturn="True"
Style="{StaticResource DefTextBox}" />
</Grid>
<TabControl x:Name="tabAdvanced">

View File

@@ -33,6 +33,7 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.customIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.sort, v => v.txtSort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables);

View File

@@ -197,15 +197,19 @@
Binding="{Binding remarks}"
Header="{x:Static resx:ResUI.LvAlias}" />
<DataGridTextColumn
Width="70"
Width="60"
Binding="{Binding ruleNum}"
Header="{x:Static resx:ResUI.LvCount}" />
<DataGridTextColumn
Width="280"
Width="60"
Binding="{Binding sort}"
Header="{x:Static resx:ResUI.LvSort}" />
<DataGridTextColumn
Width="260"
Binding="{Binding url}"
Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridTextColumn
Width="280"
Width="260"
Binding="{Binding customIcon}"
Header="{x:Static resx:ResUI.LvCustomIcon}" />
</DataGrid.Columns>

View File

@@ -9,10 +9,11 @@
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>v2rayN.ico</ApplicationIcon>
<Copyright>Copyright © 2017-2023 (GPLv3)</Copyright>
<FileVersion>6.9</FileVersion>
<FileVersion>6.11</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Downloader" Version="3.0.3" />
<PackageReference Include="MaterialDesignThemes" Version="4.7.1" />
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
@@ -25,7 +26,7 @@
<PackageReference Include="ReactiveUI.Fody" Version="18.4.1" />
<PackageReference Include="ReactiveUI.Validation" Version="3.0.22" />
<PackageReference Include="ReactiveUI.WPF" Version="18.4.1" />
<PackageReference Include="Splat.NLog" Version="14.6.1" />
<PackageReference Include="Splat.NLog" Version="14.6.8" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup>