Compare commits

..

104 Commits
6.1 ... 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
2dust
9dfd89c90d up 6.9 2023-02-06 19:28:43 +08:00
2dust
f6972125cd Update tun_singbox 2023-02-06 19:19:36 +08:00
2dust
6e366bf55a Improved enhanced tun mode 2023-02-06 15:29:10 +08:00
2dust
5e2e45c673 Merge branch 'master' of https://github.com/2dust/v2rayN 2023-02-05 20:17:07 +08:00
2dust
f879235564 fix get Win32FamilyNames 2023-02-05 20:17:03 +08:00
2dust
b00aee2ae7 Merge pull request #3187 from saphirique/patch-1
Add russian language
2023-02-05 19:57:08 +08:00
saphirique
28c2159ec3 add russian language 2023-02-05 17:55:24 +08:00
2dust
33dcef2285 Optimize Update Subscription 2023-02-04 18:52:17 +08:00
2dust
b9acd0ec28 Font size custom 2023-02-04 15:43:49 +08:00
2dust
7989d5180b adjust style 2023-02-04 14:25:21 +08:00
2dust
238086942e change fonts folder 2023-02-04 12:50:38 +08:00
2dust
a704a30242 up 6.8 2023-02-03 20:03:21 +08:00
2dust
26dd0d0ea5 add more PresetFingerprints 2023-02-03 09:45:21 +08:00
2dust
e31a4bcaa9 share link to add fingerprint 2023-02-03 09:39:39 +08:00
2dust
1722dc570b Modified the tun mode configuration template 2023-02-03 08:59:28 +08:00
2dust
3575e69b43 Tun mode can be auto turned on at startup 2023-02-02 16:27:35 +08:00
2dust
373d89874c Add custom font settings 2023-02-02 13:51:58 +08:00
2dust
976087ce97 Merge pull request #3165 from DanielBlackBeard/master
add more Farsi Translation
2023-02-02 10:51:21 +08:00
2dust
69a45788ee Merge pull request #3154 from mojpangr26/dev
增加自定义UA
2023-02-02 10:51:03 +08:00
mojpangr26
92e4de12fb 修改可编辑cmb
增加提示
2023-02-02 09:41:23 +08:00
Persian Prince
ea7fdb9b3d add more Farsi Translation 2023-02-01 21:40:26 +03:30
mojpangr26
fe1c043b8e 自定义UA 2023-02-01 17:07:36 +08:00
2dust
146f597a0b Fix the problem after clicking to sort and drag 2023-02-01 15:23:17 +08:00
2dust
d2bef312ce Add default fingerprint settings 2023-02-01 11:24:45 +08:00
2dust
61f297215d Optimize remove server 2023-02-01 11:08:05 +08:00
2dust
639a9fd540 Add test completion prompt 2023-02-01 10:06:19 +08:00
2dust
3d0428c518 add info filter the preset value 2023-02-01 09:53:37 +08:00
2dust
f40f926ce1 up 6.7 2023-01-31 19:24:55 +08:00
2dust
d6db4f0e4c Add double-click server as active parameter 2023-01-31 16:08:26 +08:00
2dust
fcbc9471aa add edit server menu 2023-01-31 14:33:17 +08:00
2dust
b147e05794 bug fix 2023-01-31 14:13:25 +08:00
2dust
47e6eb546d Optimize speed test info 2023-01-31 14:05:31 +08:00
2dust
8ba05cb4ed Replace the font with Source Han Sans CN 2023-01-31 13:34:32 +08:00
2dust
84b91e9649 Fix activity node display 2023-01-31 13:25:52 +08:00
2dust
703e17478d fix speed test url 2023-01-31 12:55:19 +08:00
2dust
8584e15c32 Optimize Sort as delay 2023-01-30 15:30:48 +08:00
2dust
46be7aadab Add refresh switch to information window 2023-01-30 14:44:49 +08:00
2dust
a5871f6cba memory log window size 2023-01-30 14:06:18 +08:00
2dust
917dc1803c Optimize custom configuration 2023-01-30 13:16:48 +08:00
2dust
c0c0961b2b Increase list line spacing 2023-01-30 12:30:04 +08:00
2dust
0995ac6f9a fix rules setting key 2023-01-30 12:27:41 +08:00
2dust
b7f40e4cbf Increase the Margin of qrcode 2023-01-30 11:18:01 +08:00
2dust
754cbb9eaa fix allowInsecure bug 2023-01-30 09:53:04 +08:00
2dust
7052b56069 Optimize font 2023-01-30 09:36:27 +08:00
2dust
decdee825b Merge pull request #3107 from buiawpkgew1/patch-1
修改hysteria 官网
2023-01-28 16:08:44 +08:00
菾凴
5f66afc399 修改hysteria 官网
https://github.com/2dust/v2rayN/issues/3094
2023-01-20 21:44:54 +08:00
2dust
5ceb638edf up 6.6 2023-01-09 20:04:24 +08:00
2dust
688b9ef5ee fix display 2023-01-09 20:03:39 +08:00
2dust
4909a557d5 Revert "Change the way to call the core in the speed test"
This reverts commit dd85ccd3f8.
2023-01-09 19:39:45 +08:00
2dust
75f63afadc bug fix 2023-01-08 09:24:09 +08:00
2dust
e90a624c9a up 6.5 2023-01-07 20:58:45 +08:00
2dust
dd85ccd3f8 Change the way to call the core in the speed test 2023-01-07 20:55:44 +08:00
2dust
fc54e19ce2 Add subscription failure log 2023-01-07 20:15:20 +08:00
2dust
118a920e57 Added drag and drop sorting option 2023-01-07 19:56:56 +08:00
2dust
975a335538 adjust timeout 2023-01-06 19:31:11 +08:00
2dust
c6ec4f38b0 Optimize speed test 2023-01-06 19:23:36 +08:00
2dust
5a5d686be1 up 6.4 2023-01-05 19:08:05 +08:00
2dust
8fc430d124 add tun mode custom config template 2023-01-05 19:05:16 +08:00
2dust
721eb40a8a bug fix 2023-01-05 19:03:29 +08:00
2dust
f18103751f Drag and Drop 2023-01-05 14:31:53 +08:00
2dust
9d30bb669e up 6.3 2023-01-04 17:18:29 +08:00
2dust
ab6f5c21c8 Auto Start via TaskService 2023-01-04 17:17:43 +08:00
2dust
4fc2ed32d2 bug fix 2023-01-04 15:47:08 +08:00
2dust
00ab4f2a7d delete temp file 2023-01-04 11:02:43 +08:00
2dust
cb5d8b405b fix bug 2023-01-04 11:02:26 +08:00
2dust
7b28aa8500 Optimize traffic statistics 2023-01-04 10:21:26 +08:00
2dust
97a369df0a Merge pull request #2962 from FrzMtrsprt/Fix_Window_Size
Fix window size on first launch
2023-01-04 09:07:23 +08:00
2dust
73a817c1cb remove tun Redirect Standard Error 2023-01-04 09:02:00 +08:00
FrzMtrsprt
c16053f0e5 Fix window size on first launch 2023-01-03 21:35:04 +08:00
2dust
3dfd108fc4 up 6.2 2023-01-03 16:32:49 +08:00
2dust
576696b25e add move to group 2023-01-03 16:32:33 +08:00
2dust
781fab5aab bug fix 2023-01-03 15:43:57 +08:00
2dust
0f099a19cd Improve traffic refresh 2023-01-03 15:11:34 +08:00
2dust
43b96ea4e5 bug fix 2023-01-03 10:52:44 +08:00
2dust
8cbf6bfffa Improve tun mode 2023-01-03 10:09:44 +08:00
2dust
52debcdcb3 Improved check for update v2rayN 2023-01-03 09:36:23 +08:00
2dust
9d38d89c25 Improve tun mode log 2023-01-02 20:22:00 +08:00
2dust
837f0ca393 Merge branch 'master' of https://github.com/2dust/v2rayN 2023-01-02 19:59:50 +08:00
2dust
42fd5b6eb2 fix bugs 2023-01-02 19:59:48 +08:00
2dust
7bdf76a665 Merge pull request #2928 from DanielBlackBeard/master
Update ResUI.fa-Ir.resx
2023-01-02 19:00:45 +08:00
Persian Prince
784ef278ea Update ResUI.fa-Ir.resx 2023-01-02 09:25:19 +03:30
55 changed files with 3918 additions and 962 deletions

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.App" x:Class="v2rayN.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:local="clr-namespace:v2rayN" xmlns:local="clr-namespace:v2rayN"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
ShutdownMode="OnExplicitShutdown" ShutdownMode="OnExplicitShutdown"
@@ -16,6 +17,10 @@
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<system:Double x:Key="MenuItemHeight">26</system:Double> <system:Double x:Key="MenuItemHeight">26</system:Double>
<system:Double x:Key="StdFontSize">12</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 <Thickness
x:Key="ServerItemMargin" x:Key="ServerItemMargin"
Bottom="4" Bottom="4"
@@ -32,19 +37,19 @@
x:Key="ModuleTitle" x:Key="ModuleTitle"
BasedOn="{StaticResource MaterialDesignTextBlock}" BasedOn="{StaticResource MaterialDesignTextBlock}"
TargetType="{x:Type TextBlock}"> TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="16" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize2}" />
</Style> </Style>
<Style <Style
x:Key="ToolbarTextBlock" x:Key="ToolbarTextBlock"
BasedOn="{StaticResource MaterialDesignTextBlock}" BasedOn="{StaticResource MaterialDesignTextBlock}"
TargetType="{x:Type TextBlock}"> TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="12" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
</Style> </Style>
<Style <Style
x:Key="StatusbarItem" x:Key="StatusbarItem"
BasedOn="{StaticResource MaterialDesignTextBlock}" BasedOn="{StaticResource MaterialDesignTextBlock}"
TargetType="{x:Type TextBlock}"> TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="12" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
<Setter Property="Padding" Value="0" /> <Setter Property="Padding" Value="0" />
</Style> </Style>
<Style TargetType="{x:Type TextElement}"> <Style TargetType="{x:Type TextElement}">
@@ -57,7 +62,7 @@
</Style> </Style>
<Style x:Key="lvItemSelected" TargetType="{x:Type ListViewItem}"> <Style x:Key="lvItemSelected" TargetType="{x:Type ListViewItem}">
<Setter Property="Height" Value="20" /> <Setter Property="Height" Value="20" />
<Setter Property="FontSize" Value="12" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsSelected" Value="true"> <Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" /> <Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
@@ -75,44 +80,69 @@
x:Key="ListItemCheckBox" x:Key="ListItemCheckBox"
BasedOn="{StaticResource MaterialDesignUserForegroundCheckBox}" BasedOn="{StaticResource MaterialDesignUserForegroundCheckBox}"
TargetType="{x:Type CheckBox}"> TargetType="{x:Type CheckBox}">
<Setter Property="FontSize" Value="12" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
</Style>
<Style x:Key="ListItemChip" TargetType="{x:Type materialDesign:Chip}">
<Setter Property="FontSize" Value="11" />
</Style> </Style>
<Style <Style
x:Key="DefButton" x:Key="DefButton"
BasedOn="{StaticResource MaterialDesignRaisedButton}" BasedOn="{StaticResource MaterialDesignRaisedButton}"
TargetType="{x:Type ButtonBase}"> TargetType="{x:Type ButtonBase}">
<Setter Property="FontSize" Value="14" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize1}" />
</Style> </Style>
<Style <Style
x:Key="DefContextMenu" x:Key="DefContextMenu"
BasedOn="{StaticResource MaterialDesignContextMenu}" BasedOn="{StaticResource MaterialDesignContextMenu}"
TargetType="{x:Type ContextMenu}"> TargetType="{x:Type ContextMenu}">
<Setter Property="FontSize" Value="13" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize1}" />
<Setter Property="FontFamily" Value="{x:Static conv:MaterialDesignFonts.MyFont}" />
</Style> </Style>
<Style <Style
x:Key="ToolbarMenu" x:Key="ToolbarMenu"
BasedOn="{StaticResource MaterialDesignMenu}" BasedOn="{StaticResource MaterialDesignMenu}"
TargetType="{x:Type Menu}"> TargetType="{x:Type Menu}">
<Setter Property="FontSize" Value="13" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize1}" />
<Setter Property="FontFamily" Value="{x:Static conv:MaterialDesignFonts.MyFont}" />
</Style> </Style>
<Style <Style
x:Key="DefComboBox" x:Key="DefComboBox"
BasedOn="{StaticResource MaterialDesignComboBox}" BasedOn="{StaticResource MaterialDesignComboBox}"
TargetType="{x:Type ComboBox}"> TargetType="{x:Type ComboBox}">
<Setter Property="FontSize" Value="12" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
<Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Left" />
</Style> </Style>
<Style <Style
x:Key="DefDataGrid" x:Key="DefDataGrid"
BasedOn="{StaticResource MaterialDesignDataGrid}" BasedOn="{StaticResource MaterialDesignDataGrid}"
TargetType="{x:Type DataGrid}"> TargetType="{x:Type DataGrid}">
<Setter Property="FontSize" Value="12" /> <Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
</Style> </Style>
<Style
x:Key="DefTextBox"
BasedOn="{StaticResource MaterialDesignTextBox}"
TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
</Style>
<Style
x:Key="MyOutlinedTextBox"
BasedOn="{StaticResource MaterialDesignOutlinedTextBox}"
TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="{DynamicResource StdFontSize}" />
</Style>
<Style
x:Key="MyGroupBox"
BasedOn="{StaticResource MaterialDesignGroupBox}"
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> </ResourceDictionary>
</Application.Resources> </Application.Resources>

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

@@ -0,0 +1,30 @@
using System.Windows.Media;
using v2rayN.Handler;
namespace v2rayN.Converters
{
public class MaterialDesignFonts
{
public static FontFamily MyFont { get; }
static MaterialDesignFonts()
{
try
{
var fontFamily = LazyConfig.Instance.GetConfig().uiItem.currentFontFamily;
if (!string.IsNullOrEmpty(fontFamily))
{
var fontPath = Utils.GetFontsPath();
MyFont = new FontFamily(new Uri(@$"file:///{fontPath}\"), $"./#{fontFamily}");
}
}
catch
{
}
if (MyFont is null)
{
MyFont = new FontFamily("Microsoft YaHei");
}
}
}
}

View File

@@ -3,6 +3,8 @@
class Global class Global
{ {
#region const #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 v2rayWebsiteUrl = @"https://www.v2fly.org/";
public const string AboutUrl = @"https://github.com/2dust/v2rayN"; public const string AboutUrl = @"https://github.com/2dust/v2rayN";
public const string UpdateUrl = AboutUrl + @"/releases"; public const string UpdateUrl = AboutUrl + @"/releases";
@@ -12,12 +14,11 @@
public const string NUrl = @"https://github.com/2dust/v2rayN/releases"; public const string NUrl = @"https://github.com/2dust/v2rayN/releases";
public const string clashCoreUrl = "https://github.com/Dreamacro/clash/releases"; public const string clashCoreUrl = "https://github.com/Dreamacro/clash/releases";
public const string clashMetaCoreUrl = "https://github.com/MetaCubeX/Clash.Meta/releases"; public const string clashMetaCoreUrl = "https://github.com/MetaCubeX/Clash.Meta/releases";
public const string hysteriaCoreUrl = "https://github.com/HyNetwork/hysteria/releases"; public const string hysteriaCoreUrl = "https://github.com/apernet/hysteria/releases";
public const string naiveproxyCoreUrl = "https://github.com/klzgrad/naiveproxy/releases"; public const string naiveproxyCoreUrl = "https://github.com/klzgrad/naiveproxy/releases";
public const string tuicCoreUrl = "https://github.com/EAimTY/tuic/releases"; public const string tuicCoreUrl = "https://github.com/EAimTY/tuic/releases";
public const string singboxCoreUrl = "https://github.com/SagerNet/sing-box/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 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 SpeedPingTestUrl = @"https://www.google.com/generate_204";
public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/"; public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
@@ -77,6 +78,7 @@
public const string CommandClearMsg = "CommandClearMsg"; public const string CommandClearMsg = "CommandClearMsg";
public const string DelayUnit = ""; public const string DelayUnit = "";
public const string SpeedUnit = ""; public const string SpeedUnit = "";
public const int MinFontSize = 10;
public static readonly List<string> IEProxyProtocols = new List<string> { public static readonly List<string> IEProxyProtocols = new List<string> {
"{ip}:{http_port}", "{ip}:{http_port}",
@@ -95,16 +97,27 @@
public static readonly List<string> coreTypes = new List<string> { "v2fly", "SagerNet", "Xray", "v2fly_v5" }; public static readonly List<string> coreTypes = new List<string> { "v2fly", "SagerNet", "Xray", "v2fly_v5" };
public static readonly List<string> domainStrategys = new List<string> { "AsIs", "IPIfNonMatch", "IPOnDemand" }; public static readonly List<string> domainStrategys = new List<string> { "AsIs", "IPIfNonMatch", "IPOnDemand" };
public static readonly List<string> domainMatchers = new List<string> { "linear", "mph", "" }; public static readonly List<string> domainMatchers = new List<string> { "linear", "mph", "" };
public static readonly List<string> fingerprints = new List<string> { "chrome", "firefox", "safari", "randomized", "" }; public static readonly List<string> fingerprints = new List<string> { "chrome", "firefox", "safari", "ios", "android", "edge", "360", "qq", "random", "randomized", "" };
public static readonly List<string> userAgent = new List<string> { "chrome", "firefox", "safari", "edge", "none" };
public static readonly Dictionary<string, string> userAgentTxt = new Dictionary<string, string>
{
{"chrome","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36" },
{"firefox","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0" },
{"safari","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" },
{"edge","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70" },
{"none",""}
};
public static readonly List<string> allowInsecures = new List<string> { "true", "false", "" }; public static readonly List<string> allowInsecures = new List<string> { "true", "false", "" };
public static readonly List<string> domainStrategy4Freedoms = new List<string> { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" }; public static readonly List<string> domainStrategy4Freedoms = new List<string> { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" };
public static readonly List<string> Languages = new List<string> { "zh-Hans", "en" ,"fa-Ir" }; public static readonly List<string> Languages = new List<string> { "zh-Hans", "en", "fa-Ir", "ru" };
public static readonly List<string> alpns = new List<string> { "h2", "http/1.1", "h2,http/1.1", "" }; public static readonly List<string> alpns = new List<string> { "h2", "http/1.1", "h2,http/1.1", "" };
public static readonly List<string> LogLevel = new List<string> { "debug", "info", "warning", "error", "none" }; public static readonly List<string> LogLevel = new List<string> { "debug", "info", "warning", "error", "none" };
public static readonly List<string> InboundTags = new List<string> { "socks", "http", "socks2", "http2" }; public static readonly List<string> InboundTags = new List<string> { "socks", "http", "socks2", "http2" };
public static readonly List<string> Protocols = new List<string> { "http", "tls", "bittorrent" }; 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> TunMtus = new List<string> { "9000", "1500" };
public static readonly List<string> TunStacks = new List<string> { "gvisor", "system" }; public static readonly List<string> TunStacks = new List<string> { "gvisor", "system" };
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 #endregion

View File

@@ -43,18 +43,17 @@ namespace v2rayN.Handler
if (config == null) if (config == null)
{ {
config = new Config config = new Config
{
};
}
if (config.coreBasicItem == null)
{
config.coreBasicItem = new()
{ {
logEnabled = false, logEnabled = false,
loglevel = "warning", loglevel = "warning",
//Mux
muxEnabled = false, muxEnabled = false,
enableStatistics = false,
statisticsFreshRate = 1,
enableRoutingAdvanced = true
}; };
} }
@@ -87,10 +86,17 @@ namespace v2rayN.Handler
config.inbound[0].protocol = Global.InboundSocks; config.inbound[0].protocol = Global.InboundSocks;
} }
} }
//路由规则 if (config.routingBasicItem == null)
if (Utils.IsNullOrEmpty(config.domainStrategy))
{ {
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)) //if (Utils.IsNullOrEmpty(config.domainMatcher))
//{ //{
@@ -130,6 +136,14 @@ namespace v2rayN.Handler
mtu = 9000, mtu = 9000,
}; };
} }
if (config.guiItem == null)
{
config.guiItem = new()
{
enableStatistics = false,
statisticsFreshRate = 1,
};
}
if (config.uiItem == null) if (config.uiItem == null)
{ {
config.uiItem = new UIItem() config.uiItem = new UIItem()
@@ -150,14 +164,6 @@ namespace v2rayN.Handler
{ {
config.constItem = new ConstItem(); 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)) if (Utils.IsNullOrEmpty(config.constItem.defIEProxyExceptions))
{ {
config.constItem.defIEProxyExceptions = Global.IEProxyExceptions; config.constItem.defIEProxyExceptions = Global.IEProxyExceptions;
@@ -167,9 +173,26 @@ namespace v2rayN.Handler
// config.remoteDNS = "1.1.1.1"; // 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) if (config == null)
@@ -288,20 +311,45 @@ namespace v2rayN.Handler
} }
config = Utils.FromJson<Config>(Utils.ToJson(configOld)); config = Utils.FromJson<Config>(Utils.ToJson(configOld));
if (config.tunModeItem == null)
if (config.coreBasicItem == null)
{ {
config.tunModeItem = new TunModeItem config.coreBasicItem = new()
{ {
enableTun = false, logEnabled = configOld.logEnabled,
showWindow = true, loglevel = configOld.loglevel,
mtu = 9000, 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); GetDefaultServer(ref config);
GetDefaultRouting(ref config); GetDefaultRouting(ref config);
SaveConfig(ref config); SaveConfig(ref config);
LazyConfig.Instance.SetConfig(ref config); LoadConfig(ref config);
return 0; return 0;
} }
@@ -638,7 +686,7 @@ namespace v2rayN.Handler
} }
if (Utils.IsNullOrEmpty(profileItem.allowInsecure)) if (Utils.IsNullOrEmpty(profileItem.allowInsecure))
{ {
profileItem.allowInsecure = config.defAllowInsecure.ToString(); profileItem.allowInsecure = config.coreBasicItem.defAllowInsecure.ToString().ToLower();
} }
AddServerCommon(ref config, profileItem); AddServerCommon(ref config, profileItem);
@@ -690,6 +738,28 @@ namespace v2rayN.Handler
{ {
lstProfile[i].sort = (i + 1) * 10; lstProfile[i].sort = (i + 1) * 10;
} }
if (name == EServerColName.delay)
{
var maxSort = lstProfile.Max(t => t.sort) + 10;
foreach (var item in lstProfile)
{
if (item.delay <= 0)
{
item.sort = maxSort;
}
}
}
if (name == EServerColName.speed)
{
var maxSort = lstProfile.Max(t => t.sort) + 10;
foreach (var item in lstProfile)
{
if (item.speed <= 0)
{
item.sort = maxSort;
}
}
}
SqliteHelper.Instance.UpdateAll(lstProfile); SqliteHelper.Instance.UpdateAll(lstProfile);
@@ -723,7 +793,7 @@ namespace v2rayN.Handler
public static int DedupServerList(ref Config config, ref List<ProfileItem> lstProfile) public static int DedupServerList(ref Config config, ref List<ProfileItem> lstProfile)
{ {
List<ProfileItem> source = lstProfile; List<ProfileItem> source = lstProfile;
bool keepOlder = config.keepOlderDedupl; bool keepOlder = config.guiItem.keepOlderDedupl;
List<ProfileItem> list = new List<ProfileItem>(); List<ProfileItem> list = new List<ProfileItem>();
if (!keepOlder) source.Reverse(); // Remove the early items first if (!keepOlder) source.Reverse(); // Remove the early items first
@@ -750,7 +820,7 @@ namespace v2rayN.Handler
profileItem.configVersion = 2; profileItem.configVersion = 2;
if (Utils.IsNullOrEmpty(profileItem.allowInsecure)) if (Utils.IsNullOrEmpty(profileItem.allowInsecure))
{ {
profileItem.allowInsecure = config.defAllowInsecure.ToString(); profileItem.allowInsecure = config.coreBasicItem.defAllowInsecure.ToString().ToLower();
} }
if (!Utils.IsNullOrEmpty(profileItem.network) && !Global.networks.Contains(profileItem.network)) if (!Utils.IsNullOrEmpty(profileItem.network) && !Global.networks.Contains(profileItem.network))
{ {
@@ -1194,11 +1264,11 @@ namespace v2rayN.Handler
} }
if (isSub) if (isSub)
{ {
SqliteHelper.Instance.Execute($"delete from ProfileItem where isSub = 1 and subid = {subid}"); SqliteHelper.Instance.Execute($"delete from ProfileItem where isSub = 1 and subid = '{subid}'");
} }
else else
{ {
SqliteHelper.Instance.Execute($"delete from ProfileItem where subid = {subid}"); SqliteHelper.Instance.Execute($"delete from ProfileItem where subid = '{subid}'");
} }
return 0; return 0;
@@ -1217,6 +1287,22 @@ namespace v2rayN.Handler
return 0; return 0;
} }
public static int MoveToGroup(Config config, List<ProfileItem> lstProfile, string subid)
{
foreach (var it in lstProfile)
{
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
if (item is null)
{
continue;
}
item.subid = subid;
SqliteHelper.Instance.Update(item);
}
return 0;
}
#endregion #endregion
#region UI #region UI
@@ -1399,7 +1485,7 @@ namespace v2rayN.Handler
{ {
if (SqliteHelper.Instance.Table<RoutingItem>().Where(t => t.id == routingItem.id).Count() > 0) 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; Global.reloadCore = true;
@@ -1410,7 +1496,7 @@ namespace v2rayN.Handler
} }
public static RoutingItem GetDefaultRouting(ref Config config) 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) if (item is null)
{ {
var item2 = SqliteHelper.Instance.Table<RoutingItem>().FirstOrDefault(t => t.locked == false); var item2 = SqliteHelper.Instance.Table<RoutingItem>().FirstOrDefault(t => t.locked == false);
@@ -1423,13 +1509,16 @@ namespace v2rayN.Handler
public static int InitBuiltinRouting(ref Config config, bool blImportAdvancedRules = false) 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 //Bypass the mainland
var item2 = new RoutingItem() var item2 = new RoutingItem()
{ {
remarks = "绕过大陆(Whitelist)", remarks = "绕过大陆(Whitelist)",
url = string.Empty, url = string.Empty,
sort = maxSort + 1,
}; };
AddBatchRoutingRules(ref item2, Utils.GetEmbedText(Global.CustomRoutingFileName + "white")); AddBatchRoutingRules(ref item2, Utils.GetEmbedText(Global.CustomRoutingFileName + "white"));
@@ -1438,6 +1527,7 @@ namespace v2rayN.Handler
{ {
remarks = "黑名单(Blacklist)", remarks = "黑名单(Blacklist)",
url = string.Empty, url = string.Empty,
sort = maxSort + 2,
}; };
AddBatchRoutingRules(ref item3, Utils.GetEmbedText(Global.CustomRoutingFileName + "black")); AddBatchRoutingRules(ref item3, Utils.GetEmbedText(Global.CustomRoutingFileName + "black"));
@@ -1446,6 +1536,7 @@ namespace v2rayN.Handler
{ {
remarks = "全局(Global)", remarks = "全局(Global)",
url = string.Empty, url = string.Empty,
sort = maxSort + 3,
}; };
AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "global")); AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "global"));

View File

@@ -73,28 +73,29 @@ namespace v2rayN.Handler
{ {
if (blExport) if (blExport)
{ {
if (config.logEnabled) if (config.coreBasicItem.logEnabled)
{ {
v2rayConfig.log.loglevel = config.loglevel; v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
} }
else else
{ {
v2rayConfig.log.loglevel = config.loglevel; v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
v2rayConfig.log.access = ""; v2rayConfig.log.access = "";
v2rayConfig.log.error = ""; v2rayConfig.log.error = "";
} }
} }
else else
{ {
if (config.logEnabled) if (config.coreBasicItem.logEnabled)
{ {
v2rayConfig.log.loglevel = config.loglevel; var dtNow = DateTime.Now;
v2rayConfig.log.access = Utils.GetLogPath(v2rayConfig.log.access); v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
v2rayConfig.log.error = Utils.GetLogPath(v2rayConfig.log.error); 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 else
{ {
v2rayConfig.log.loglevel = config.loglevel; v2rayConfig.log.loglevel = config.coreBasicItem.loglevel;
v2rayConfig.log.access = ""; v2rayConfig.log.access = "";
v2rayConfig.log.error = ""; v2rayConfig.log.error = "";
} }
@@ -186,10 +187,10 @@ namespace v2rayN.Handler
if (v2rayConfig.routing != null if (v2rayConfig.routing != null
&& v2rayConfig.routing.rules != null) && v2rayConfig.routing.rules != null)
{ {
v2rayConfig.routing.domainStrategy = config.domainStrategy; v2rayConfig.routing.domainStrategy = config.routingBasicItem.domainStrategy;
v2rayConfig.routing.domainMatcher = Utils.IsNullOrEmpty(config.domainMatcher) ? null : config.domainMatcher; 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); var routing = ConfigHandler.GetDefaultRouting(ref config);
if (routing != null) if (routing != null)
@@ -347,8 +348,8 @@ namespace v2rayN.Handler
} }
//Mux //Mux
outbound.mux.enabled = config.muxEnabled; outbound.mux.enabled = config.coreBasicItem.muxEnabled;
outbound.mux.concurrency = config.muxEnabled ? 8 : -1; outbound.mux.concurrency = config.coreBasicItem.muxEnabled ? 8 : -1;
boundStreamSettings(node, "out", outbound.streamSettings); boundStreamSettings(node, "out", outbound.streamSettings);
@@ -451,8 +452,8 @@ namespace v2rayN.Handler
usersItem.encryption = node.security; usersItem.encryption = node.security;
//Mux //Mux
outbound.mux.enabled = config.muxEnabled; outbound.mux.enabled = config.coreBasicItem.muxEnabled;
outbound.mux.concurrency = config.muxEnabled ? 8 : -1; outbound.mux.concurrency = config.coreBasicItem.muxEnabled ? 8 : -1;
boundStreamSettings(node, "out", outbound.streamSettings); boundStreamSettings(node, "out", outbound.streamSettings);
@@ -546,6 +547,18 @@ namespace v2rayN.Handler
streamSettings.network = node.GetNetwork(); streamSettings.network = node.GetNetwork();
string host = node.requestHost.TrimEx(); string host = node.requestHost.TrimEx();
string sni = node.sni; string sni = node.sni;
string useragent = "";
if (!config.coreBasicItem.defUserAgent.IsNullOrEmpty())
{
try
{
useragent = Global.userAgentTxt[config.coreBasicItem.defUserAgent];
}
catch (KeyNotFoundException)
{
useragent = config.coreBasicItem.defUserAgent;
}
}
//if tls //if tls
if (node.streamSecurity == Global.StreamSecurity) if (node.streamSecurity == Global.StreamSecurity)
@@ -554,9 +567,9 @@ namespace v2rayN.Handler
TlsSettings tlsSettings = new TlsSettings TlsSettings tlsSettings = new TlsSettings
{ {
allowInsecure = Utils.ToBool(node.allowInsecure), allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
alpn = node.GetAlpn(), alpn = node.GetAlpn(),
fingerprint = node.fingerprint fingerprint = node.fingerprint.IsNullOrEmpty() ? config.coreBasicItem.defFingerprint : node.fingerprint
}; };
if (!string.IsNullOrWhiteSpace(sni)) if (!string.IsNullOrWhiteSpace(sni))
{ {
@@ -576,9 +589,9 @@ namespace v2rayN.Handler
TlsSettings xtlsSettings = new TlsSettings TlsSettings xtlsSettings = new TlsSettings
{ {
allowInsecure = Utils.ToBool(node.allowInsecure), allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),
alpn = node.GetAlpn(), alpn = node.GetAlpn(),
fingerprint = node.fingerprint fingerprint = node.fingerprint.IsNullOrEmpty() ? config.coreBasicItem.defFingerprint : node.fingerprint
}; };
if (!string.IsNullOrWhiteSpace(sni)) if (!string.IsNullOrWhiteSpace(sni))
{ {
@@ -634,19 +647,22 @@ namespace v2rayN.Handler
WsSettings wsSettings = new WsSettings WsSettings wsSettings = new WsSettings
{ {
}; };
wsSettings.headers = new Headers
{
};
string path = node.path; string path = node.path;
if (!string.IsNullOrWhiteSpace(host)) if (!string.IsNullOrWhiteSpace(host))
{ {
wsSettings.headers = new Headers wsSettings.headers.Host = host;
{
Host = host
};
} }
if (!string.IsNullOrWhiteSpace(path)) if (!string.IsNullOrWhiteSpace(path))
{ {
wsSettings.path = path; wsSettings.path = path;
} }
if (!string.IsNullOrWhiteSpace(useragent))
{
wsSettings.headers.UserAgent = useragent;
}
streamSettings.wsSettings = wsSettings; streamSettings.wsSettings = wsSettings;
//TlsSettings tlsSettings = new TlsSettings(); //TlsSettings tlsSettings = new TlsSettings();
@@ -730,7 +746,7 @@ namespace v2rayN.Handler
string host2 = string.Join("\",\"", arrHost); string host2 = string.Join("\",\"", arrHost);
request = request.Replace("$requestHost$", $"\"{host2}\""); request = request.Replace("$requestHost$", $"\"{host2}\"");
//request = request.Replace("$requestHost$", string.Format("\"{0}\"", config.requestHost())); //request = request.Replace("$requestHost$", string.Format("\"{0}\"", config.requestHost()));
request = request.Replace("$requestUserAgent$", $"\"{useragent}\"");
//Path //Path
string pathHttp = @"/"; string pathHttp = @"/";
if (!Utils.IsNullOrEmpty(node.path)) if (!Utils.IsNullOrEmpty(node.path))
@@ -809,7 +825,7 @@ namespace v2rayN.Handler
private static int statistic(Config config, ref V2rayConfig v2rayConfig) private static int statistic(Config config, ref V2rayConfig v2rayConfig)
{ {
if (config.enableStatistics) if (config.guiItem.enableStatistics)
{ {
string tag = Global.InboundAPITagName; string tag = Global.InboundAPITagName;
API apiObj = new API(); API apiObj = new API();
@@ -1463,8 +1479,8 @@ namespace v2rayN.Handler
} }
if (it.configType == EConfigType.VMess || it.configType == EConfigType.VLESS) if (it.configType == EConfigType.VMess || it.configType == EConfigType.VLESS)
{ {
var item2 = LazyConfig.Instance.GetProfileItem(config.indexId); var item2 = LazyConfig.Instance.GetProfileItem(it.indexId);
if (item2 is null || !Utils.IsGuidByParse(item2.id)) if (item2 is null || Utils.IsNullOrEmpty(item2.id) || !Utils.IsGuidByParse(item2.id))
{ {
continue; continue;
} }

View File

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

View File

@@ -85,17 +85,20 @@ namespace v2rayN.Handler
public List<ProfileItemModel> ProfileItems(string subid, string filter) public List<ProfileItemModel> ProfileItems(string subid, string filter)
{ {
var sql = @$"select a.* var sql = @$"select a.*
,b.remarks subRemarks ,b.remarks subRemarks
,case when a.indexId = '{_config.indexId}' then true else false end isActive
from ProfileItem a from ProfileItem a
left join SubItem b on a.subid = b.id left join SubItem b on a.subid = b.id
where 1=1 "; where 1=1 ";
if (!Utils.IsNullOrEmpty(subid)) if (!Utils.IsNullOrEmpty(subid))
{ {
sql += $" and a.subid = {subid}"; sql += $" and a.subid = '{subid}'";
} }
if (!Utils.IsNullOrEmpty(filter)) if (!Utils.IsNullOrEmpty(filter))
{ {
if (filter.Contains("'"))
{
filter = filter.Replace("'", "");
}
sql += $" and a.remarks like '%{filter}%'"; sql += $" and a.remarks like '%{filter}%'";
} }
sql += " order by a.sort"; sql += " order by a.sort";
@@ -134,14 +137,9 @@ namespace v2rayN.Handler
return SqliteHelper.Instance.ExecuteAsync(sql); return SqliteHelper.Instance.ExecuteAsync(sql);
} }
public List<ServerStatItem> ServerStatItems()
{
return SqliteHelper.Instance.Table<ServerStatItem>().ToList();
}
public List<RoutingItem> RoutingItems() 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) public RoutingItem GetRoutingItem(string id)
{ {
@@ -211,7 +209,7 @@ namespace v2rayN.Handler
{ {
coreType = ECoreType.v2rayN, coreType = ECoreType.v2rayN,
coreUrl = Global.NUrl, 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", coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN.zip",
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip", coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip",
}); });
@@ -222,7 +220,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "wv2ray", "v2ray" }, coreExes = new List<string> { "wv2ray", "v2ray" },
arguments = "", arguments = "",
coreUrl = Global.v2flyCoreUrl, 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", coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray", match = "V2Ray",
@@ -236,7 +234,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "SagerNet", "v2ray" }, coreExes = new List<string> { "SagerNet", "v2ray" },
arguments = "run", arguments = "run",
coreUrl = Global.SagerNetCoreUrl, 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", coreDownloadUrl32 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl64 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray", match = "V2Ray",
@@ -250,7 +248,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "v2ray" }, coreExes = new List<string> { "v2ray" },
arguments = "run", arguments = "run",
coreUrl = Global.v2flyCoreUrl, 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", coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray", match = "V2Ray",
@@ -264,7 +262,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "xray", "wxray" }, coreExes = new List<string> { "xray", "wxray" },
arguments = "", arguments = "",
coreUrl = Global.xrayCoreUrl, 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", coreDownloadUrl32 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
coreDownloadUrl64 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip", coreDownloadUrl64 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
match = "Xray", match = "Xray",
@@ -278,7 +276,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" }, coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
arguments = "-f config.json", arguments = "-f config.json",
coreUrl = Global.clashCoreUrl, 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", coreDownloadUrl32 = Global.clashCoreUrl + "/download/{0}/clash-windows-386-{0}.zip",
coreDownloadUrl64 = Global.clashCoreUrl + "/download/{0}/clash-windows-amd64-{0}.zip", coreDownloadUrl64 = Global.clashCoreUrl + "/download/{0}/clash-windows-amd64-{0}.zip",
match = "v", match = "v",
@@ -292,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" }, coreExes = new List<string> { "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" },
arguments = "-f config.json", arguments = "-f config.json",
coreUrl = Global.clashMetaCoreUrl, 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", coreDownloadUrl32 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-386-{0}.zip",
coreDownloadUrl64 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-amd64-compatible-{0}.zip", coreDownloadUrl64 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-amd64-compatible-{0}.zip",
match = "v", match = "v",
@@ -306,7 +304,7 @@ namespace v2rayN.Handler
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" }, coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
arguments = "", arguments = "",
coreUrl = Global.hysteriaCoreUrl, 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", coreDownloadUrl32 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-386.exe",
coreDownloadUrl64 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-amd64.exe", coreDownloadUrl64 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-amd64.exe",
redirectInfo = true, redirectInfo = true,

View File

@@ -86,7 +86,7 @@ namespace v2rayN.Handler
{ {
try try
{ {
if (!config.enableRoutingAdvanced) if (!config.routingBasicItem.enableRoutingAdvanced)
{ {
return null; return null;
} }
@@ -309,9 +309,9 @@ namespace v2rayN.Handler
{ {
var dtNow = DateTime.Now; 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) => updateHandle.UpdateSubscriptionProcess(config, "", true, (bool success, string msg) =>
{ {
@@ -324,9 +324,9 @@ namespace v2rayN.Handler
Thread.Sleep(60000); 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) => updateHandle.UpdateGeoFile("geosite", config, (bool success, string msg) =>
{ {

View File

@@ -71,7 +71,8 @@ namespace v2rayN.Handler
path = item.path, path = item.path,
tls = item.streamSecurity, tls = item.streamSecurity,
sni = item.sni, sni = item.sni,
alpn = item.alpn alpn = item.alpn,
fp = item.fingerprint
}; };
url = Utils.ToJson(vmessQRCode); url = Utils.ToJson(vmessQRCode);
@@ -202,6 +203,10 @@ namespace v2rayN.Handler
{ {
dicQuery.Add("alpn", Utils.UrlEncode(item.alpn)); dicQuery.Add("alpn", Utils.UrlEncode(item.alpn));
} }
if (!Utils.IsNullOrEmpty(item.fingerprint))
{
dicQuery.Add("fp", Utils.UrlEncode(item.fingerprint));
}
dicQuery.Add("type", !Utils.IsNullOrEmpty(item.network) ? item.network : "tcp"); dicQuery.Add("type", !Utils.IsNullOrEmpty(item.network) ? item.network : "tcp");
@@ -408,6 +413,7 @@ namespace v2rayN.Handler
profileItem.streamSecurity = Utils.ToString(vmessQRCode.tls); profileItem.streamSecurity = Utils.ToString(vmessQRCode.tls);
profileItem.sni = Utils.ToString(vmessQRCode.sni); profileItem.sni = Utils.ToString(vmessQRCode.sni);
profileItem.alpn = Utils.ToString(vmessQRCode.alpn); profileItem.alpn = Utils.ToString(vmessQRCode.alpn);
profileItem.fingerprint = Utils.ToString(vmessQRCode.fp);
return profileItem; return profileItem;
} }
@@ -759,6 +765,7 @@ namespace v2rayN.Handler
item.streamSecurity = query["security"] ?? ""; item.streamSecurity = query["security"] ?? "";
item.sni = query["sni"] ?? ""; item.sni = query["sni"] ?? "";
item.alpn = Utils.UrlDecode(query["alpn"] ?? ""); item.alpn = Utils.UrlDecode(query["alpn"] ?? "");
item.fingerprint = Utils.UrlDecode(query["fp"] ?? "");
item.network = query["type"] ?? "tcp"; item.network = query["type"] ?? "tcp";
switch (item.network) switch (item.network)
{ {

View File

@@ -12,6 +12,7 @@ namespace v2rayN.Handler
private Config _config; private Config _config;
private CoreHandler _coreHandler; private CoreHandler _coreHandler;
private List<ServerTestItem> _selecteds; private List<ServerTestItem> _selecteds;
private ESpeedActionType _actionType;
Action<string, string, string> _updateFunc; Action<string, string, string> _updateFunc;
public SpeedtestHandler(Config config) public SpeedtestHandler(Config config)
@@ -23,12 +24,20 @@ namespace v2rayN.Handler
{ {
_config = config; _config = config;
_coreHandler = coreHandler; _coreHandler = coreHandler;
//_selecteds = Utils.DeepCopy(selecteds); _actionType = actionType;
_updateFunc = update; _updateFunc = update;
_selecteds = new List<ServerTestItem>(); _selecteds = new List<ServerTestItem>();
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (it.configType == EConfigType.Custom)
{
continue;
}
if (it.port <= 0)
{
continue;
}
_selecteds.Add(new ServerTestItem() _selecteds.Add(new ServerTestItem()
{ {
indexId = it.indexId, indexId = it.indexId,
@@ -37,6 +46,25 @@ namespace v2rayN.Handler
configType = it.configType configType = it.configType
}); });
} }
//clear test result
foreach (var it in _selecteds)
{
switch (actionType)
{
case ESpeedActionType.Ping:
case ESpeedActionType.Tcping:
case ESpeedActionType.Realping:
UpdateFunc(it.indexId, ResUI.Speedtesting, "");
break;
case ESpeedActionType.Speedtest:
UpdateFunc(it.indexId, "", ResUI.Speedtesting);
break;
case ESpeedActionType.Mixedtest:
UpdateFunc(it.indexId, ResUI.Speedtesting, ResUI.Speedtesting);
break;
}
}
switch (actionType) switch (actionType)
{ {
case ESpeedActionType.Ping: case ESpeedActionType.Ping:
@@ -106,7 +134,7 @@ namespace v2rayN.Handler
}); });
} }
private async Task RunRealPing() private Task RunRealPing()
{ {
int pid = -1; int pid = -1;
try try
@@ -117,7 +145,7 @@ namespace v2rayN.Handler
if (pid < 0) if (pid < 0)
{ {
UpdateFunc("", ResUI.FailedToRunCore); UpdateFunc("", ResUI.FailedToRunCore);
return; return Task.CompletedTask;
} }
DownloadHandle downloadHandle = new DownloadHandle(); DownloadHandle downloadHandle = new DownloadHandle();
@@ -144,6 +172,8 @@ namespace v2rayN.Handler
LazyConfig.Instance.SetTestResult(it.indexId, output, ""); LazyConfig.Instance.SetTestResult(it.indexId, output, "");
UpdateFunc(it.indexId, output); UpdateFunc(it.indexId, output);
int.TryParse(output, out int delay);
it.delay = delay;
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -162,11 +192,17 @@ namespace v2rayN.Handler
{ {
if (pid > 0) _coreHandler.CoreStopPid(pid); if (pid > 0) _coreHandler.CoreStopPid(pid);
} }
return Task.CompletedTask;
} }
private async Task RunSpeedTestAsync() private async Task RunSpeedTestAsync()
{ {
string testIndexId = string.Empty;
int pid = -1; int pid = -1;
//if (_actionType == ESpeedActionType.Mixedtest)
//{
// _selecteds = _selecteds.OrderBy(t => t.delay).ToList();
//}
pid = _coreHandler.LoadCoreConfigString(_config, _selecteds); pid = _coreHandler.LoadCoreConfigString(_config, _selecteds);
if (pid < 0) if (pid < 0)
@@ -175,14 +211,13 @@ namespace v2rayN.Handler
return; return;
} }
string url = _config.constItem.speedTestUrl; string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new DownloadHandle(); DownloadHandle downloadHandle = new DownloadHandle();
var timeout = 10;
foreach (var it in _selecteds) foreach (var it in _selecteds)
{ {
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
UpdateFunc(it.indexId, "", ResUI.Speedtesting);
if (!it.allowTest) if (!it.allowTest)
{ {
continue; continue;
@@ -191,7 +226,12 @@ namespace v2rayN.Handler
{ {
continue; continue;
} }
testIndexId = it.indexId; //if (it.delay < 0)
//{
// UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
// continue;
//}
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
var item = LazyConfig.Instance.GetProfileItem(it.indexId); var item = LazyConfig.Instance.GetProfileItem(it.indexId);
if (item is null) continue; if (item is null) continue;
@@ -213,17 +253,73 @@ namespace v2rayN.Handler
{ {
_coreHandler.CoreStopPid(pid); _coreHandler.CoreStopPid(pid);
} }
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() private async Task RunMixedtestAsync()
{ {
await RunRealPing(); await RunRealPing();
await RunSpeedTestAsync(); Thread.Sleep(1000);
await RunSpeedTestMulti();
} }
public string GetRealPingTime(DownloadHandle downloadHandle, WebProxy webProxy) 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; //string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
return FormatOut(Utils.IsNullOrEmpty(status) ? responseTime : -1, Global.DelayUnit); return FormatOut(Utils.IsNullOrEmpty(status) ? responseTime : -1, Global.DelayUnit);
} }

View File

@@ -14,6 +14,8 @@ namespace v2rayN.Handler
private StatsService.StatsServiceClient client_; private StatsService.StatsServiceClient client_;
private bool exitFlag_; private bool exitFlag_;
private ServerStatItem _serverStatItem; private ServerStatItem _serverStatItem;
private List<ServerStatItem> _lstServerStat;
public List<ServerStatItem> ServerStat => _lstServerStat;
Action<ServerSpeedItem> updateFunc_; Action<ServerSpeedItem> updateFunc_;
@@ -25,7 +27,7 @@ namespace v2rayN.Handler
public StatisticsHandler(Mode.Config config, Action<ServerSpeedItem> update) public StatisticsHandler(Mode.Config config, Action<ServerSpeedItem> update)
{ {
config_ = config; config_ = config;
Enable = config.enableStatistics; Enable = config.guiItem.enableStatistics;
updateFunc_ = update; updateFunc_ = update;
exitFlag_ = false; exitFlag_ = false;
@@ -83,24 +85,25 @@ namespace v2rayN.Handler
GetServerStatItem(config_.indexId); GetServerStatItem(config_.indexId);
ParseOutput(res.Stat, out ServerSpeedItem server); ParseOutput(res.Stat, out ServerSpeedItem server);
_serverStatItem.todayUp += server.proxyUp; if (server.proxyUp != 0 || server.proxyDown != 0)
_serverStatItem.todayDown += server.proxyDown; {
_serverStatItem.totalUp += server.proxyUp; _serverStatItem.todayUp += server.proxyUp;
_serverStatItem.totalDown += server.proxyDown; _serverStatItem.todayDown += server.proxyDown;
_serverStatItem.totalUp += server.proxyUp;
_serverStatItem.totalDown += server.proxyDown;
}
if (Global.ShowInTaskbar) if (Global.ShowInTaskbar)
{ {
server.indexId = config_.indexId; server.indexId = config_.indexId;
server.todayUp = _serverStatItem.todayUp;
server.todayDown = _serverStatItem.todayDown;
server.totalUp = _serverStatItem.totalUp;
server.totalDown = _serverStatItem.totalDown;
updateFunc_(server); updateFunc_(server);
} }
if (server.proxyUp != 0 || server.proxyDown != 0)
{
_ = SqliteHelper.Instance.UpdateAsync(_serverStatItem);
}
} }
} }
var sleep = config_.statisticsFreshRate < 1 ? 1 : config_.statisticsFreshRate; var sleep = config_.guiItem.statisticsFreshRate < 1 ? 1 : config_.guiItem.statisticsFreshRate;
Thread.Sleep(1000 * sleep); Thread.Sleep(1000 * sleep);
channel_.ConnectAsync(); channel_.ConnectAsync();
} }
@@ -114,12 +117,27 @@ namespace v2rayN.Handler
{ {
SqliteHelper.Instance.Execute($"delete from ServerStatItem "); SqliteHelper.Instance.Execute($"delete from ServerStatItem ");
_serverStatItem = null; _serverStatItem = null;
_lstServerStat = new();
}
public void SaveTo()
{
try
{
SqliteHelper.Instance.UpdateAll(_lstServerStat);
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
}
} }
private void Init() private void Init()
{ {
long ticks = DateTime.Now.Date.Ticks; long ticks = DateTime.Now.Date.Ticks;
SqliteHelper.Instance.Execute($"update ServerStatItem set todayUp = 0,todayDown=0,dateNow={ticks} where dateNow<>{ticks}"); SqliteHelper.Instance.Execute($"update ServerStatItem set todayUp = 0,todayDown=0,dateNow={ticks} where dateNow<>{ticks}");
_lstServerStat = SqliteHelper.Instance.Table<ServerStatItem>().ToList();
} }
private void GetServerStatItem(string indexId) private void GetServerStatItem(string indexId)
@@ -132,7 +150,7 @@ namespace v2rayN.Handler
if (_serverStatItem == null) if (_serverStatItem == null)
{ {
_serverStatItem = SqliteHelper.Instance.Table<ServerStatItem>().FirstOrDefault(t => t.indexId == indexId); _serverStatItem = _lstServerStat.FirstOrDefault(t => t.indexId == indexId);
if (_serverStatItem == null) if (_serverStatItem == null)
{ {
_serverStatItem = new ServerStatItem _serverStatItem = new ServerStatItem
@@ -145,6 +163,7 @@ namespace v2rayN.Handler
dateNow = ticks dateNow = ticks
}; };
_ = SqliteHelper.Instance.Replacesync(_serverStatItem); _ = SqliteHelper.Instance.Replacesync(_serverStatItem);
_lstServerStat.Add(_serverStatItem);
} }
} }

View File

@@ -72,7 +72,16 @@ namespace v2rayN.Base
private bool Init() private bool Init()
{ {
coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box); coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box);
//Template
string configStr = Utils.GetEmbedText(Global.TunSingboxFileName); string configStr = Utils.GetEmbedText(Global.TunSingboxFileName);
if (!Utils.IsNullOrEmpty(_config.tunModeItem.customTemplate) && File.Exists(_config.tunModeItem.customTemplate))
{
var customTemplate = File.ReadAllText(_config.tunModeItem.customTemplate);
if (!Utils.IsNullOrEmpty(customTemplate))
{
configStr = customTemplate;
}
}
if (Utils.IsNullOrEmpty(configStr)) if (Utils.IsNullOrEmpty(configStr))
{ {
return false; return false;
@@ -91,6 +100,17 @@ namespace v2rayN.Base
configStr = configStr.Replace("$strict_route$", $"{_config.tunModeItem.strictRoute.ToString().ToLower()}"); configStr = configStr.Replace("$strict_route$", $"{_config.tunModeItem.strictRoute.ToString().ToLower()}");
configStr = configStr.Replace("$stack$", $"{_config.tunModeItem.stack}"); configStr = configStr.Replace("$stack$", $"{_config.tunModeItem.stack}");
//logs
if (_config.tunModeItem.showWindow)
{
configStr = configStr.Replace("$log_output$", $"");
}
else
{
var dtNow = DateTime.Now;
var log_output = $"\"output\": \"{Utils.GetLogPath($"singbox_{dtNow.ToString("yyyy-MM-dd")}.txt")}\", ";
configStr = configStr.Replace("$log_output$", $"{log_output.Replace(@"\", @"\\")}");
}
//port //port
configStr = configStr.Replace("$socksPort$", $"{_socksPort}"); configStr = configStr.Replace("$socksPort$", $"{_socksPort}");
@@ -109,13 +129,13 @@ namespace v2rayN.Base
{ {
if (!lstDnsExe.Contains(it2) && it.coreType != ECoreType.sing_box) if (!lstDnsExe.Contains(it2) && it.coreType != ECoreType.sing_box)
{ {
lstDnsExe.Add(it2); //lstDnsExe.Add(it2);
lstDnsExe.Add($"{it2}.exe"); lstDnsExe.Add($"{it2}.exe");
} }
if (!lstDirectExe.Contains(it2)) if (!lstDirectExe.Contains(it2))
{ {
lstDirectExe.Add(it2); //lstDirectExe.Add(it2);
lstDirectExe.Add($"{it2}.exe"); lstDirectExe.Add($"{it2}.exe");
} }
} }
@@ -126,27 +146,45 @@ namespace v2rayN.Base
string strDirect = string.Join("\",\"", lstDirectExe.ToArray()); string strDirect = string.Join("\",\"", lstDirectExe.ToArray());
configStr = configStr.Replace("$directProcessName$", $"\"{strDirect}\""); configStr = configStr.Replace("$directProcessName$", $"\"{strDirect}\"");
if (_config.tunModeItem.bypassMode)
{
//direct ips
if (_config.tunModeItem.directIP != null && _config.tunModeItem.directIP.Count > 0)
{
var ips = new { outbound = "direct", ip_cidr = _config.tunModeItem.directIP };
configStr = configStr.Replace("$ruleDirectIPs$", "," + Utils.ToJson(ips));
}
//direct process
if (_config.tunModeItem.directProcess != null && _config.tunModeItem.directProcess.Count > 0)
{
var process = new { outbound = "direct", process_name = _config.tunModeItem.directProcess };
configStr = configStr.Replace("$ruleDirectProcess$", "," + Utils.ToJson(process));
}
}
else
{
//proxy ips
if (_config.tunModeItem.proxyIP != null && _config.tunModeItem.proxyIP.Count > 0)
{
var ips = new { outbound = "proxy", ip_cidr = _config.tunModeItem.proxyIP };
configStr = configStr.Replace("$ruleProxyIPs$", "," + Utils.ToJson(ips));
}
//proxy process
if (_config.tunModeItem.proxyProcess != null && _config.tunModeItem.proxyProcess.Count > 0)
{
var process = new { outbound = "proxy", process_name = _config.tunModeItem.proxyProcess };
configStr = configStr.Replace("$ruleProxyProcess$", "," + Utils.ToJson(process));
}
//ips var final = new { outbound = "direct", inbound = "tun-in" };
if (_config.tunModeItem.directIP != null && _config.tunModeItem.directIP.Count > 0) configStr = configStr.Replace("$ruleFinally$", "," + Utils.ToJson(final));
{
var ips = new { outbound = "direct", ip_cidr = _config.tunModeItem.directIP };
configStr = configStr.Replace("$ruleDirectIPs$", "," + Utils.ToJson(ips));
}
else
{
configStr = configStr.Replace("$ruleDirectIPs$", "");
}
//process
if (_config.tunModeItem.directProcess != null && _config.tunModeItem.directProcess.Count > 0)
{
var process = new { outbound = "direct", process_name = _config.tunModeItem.directProcess };
configStr = configStr.Replace("$ruleDirectProcess$", "," + Utils.ToJson(process));
}
else
{
configStr = configStr.Replace("$ruleDirectProcess$", "");
} }
configStr = configStr.Replace("$ruleDirectIPs$", "");
configStr = configStr.Replace("$ruleDirectProcess$", "");
configStr = configStr.Replace("$ruleProxyIPs$", "");
configStr = configStr.Replace("$ruleProxyProcess$", "");
configStr = configStr.Replace("$ruleFinally$", "");
File.WriteAllText(Utils.GetConfigPath(_tunConfigName), configStr); File.WriteAllText(Utils.GetConfigPath(_tunConfigName), configStr);
@@ -163,6 +201,7 @@ namespace v2rayN.Base
KillProcess(_process); KillProcess(_process);
_process.Dispose(); _process.Dispose();
_process = null; _process = null;
_needRestart = true;
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -200,15 +239,17 @@ namespace v2rayN.Base
{ {
return; return;
} }
var showWindow = _config.tunModeItem.showWindow;
Process p = new Process Process p = new Process
{ {
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
{ {
FileName = fileName, FileName = fileName,
Arguments = $"run -c {Utils.GetConfigPath(_tunConfigName)}", Arguments = $"run -c \"{Utils.GetConfigPath(_tunConfigName)}\"",
WorkingDirectory = Utils.GetConfigPath(), WorkingDirectory = Utils.GetConfigPath(),
UseShellExecute = _config.tunModeItem.showWindow, UseShellExecute = showWindow,
CreateNoWindow = !_config.tunModeItem.showWindow, CreateNoWindow = !showWindow,
//RedirectStandardError = !showWindow,
Verb = "runas", Verb = "runas",
} }
}; };
@@ -217,7 +258,14 @@ namespace v2rayN.Base
_isRunning = true; _isRunning = true;
if (p.WaitForExit(1000)) if (p.WaitForExit(1000))
{ {
//if (showWindow)
//{
throw new Exception("start tun mode fail"); throw new Exception("start tun mode fail");
//}
//else
//{
// throw new Exception(p.StandardError.ReadToEnd());
//}
} }
Global.processJob.AddProcess(p.Handle); Global.processJob.AddProcess(p.Handle);

View File

@@ -55,7 +55,7 @@ namespace v2rayN.Handler
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
{ {
FileName = "v2rayUpgrade.exe", FileName = "v2rayUpgrade.exe",
Arguments = "\"" + fileName + "\"", Arguments = $"\"{fileName}\"",
WorkingDirectory = Utils.StartupPath() WorkingDirectory = Utils.StartupPath()
} }
}; };
@@ -232,6 +232,11 @@ namespace v2rayN.Handler
} }
int ret = ConfigHandler.AddBatchServers(ref config, result, id, true); int ret = ConfigHandler.AddBatchServers(ref config, result, id, true);
if (ret <= 0)
{
Utils.SaveLog("FailedImportSubscription");
Utils.SaveLog(result);
}
_updateFunc(false, _updateFunc(false,
ret > 0 ret > 0
? $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}" ? $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}"
@@ -273,11 +278,15 @@ namespace v2rayN.Handler
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url)); string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
if (File.Exists(fileName)) if (File.Exists(fileName))
{ {
Global.coreTypes.ForEach(it => //Global.coreTypes.ForEach(it =>
{ //{
string targetPath = Utils.GetBinPath($"{geoName}.dat", (ECoreType)Enum.Parse(typeof(ECoreType), it)); // string targetPath = Utils.GetBinPath($"{geoName}.dat", (ECoreType)Enum.Parse(typeof(ECoreType), it));
File.Copy(fileName, targetPath, true); // File.Copy(fileName, targetPath, true);
}); //});
string targetPath = Utils.GetBinPath($"{geoName}.dat");
File.Copy(fileName, targetPath, true);
File.Delete(fileName);
//_updateFunc(true, ""); //_updateFunc(true, "");
} }
} }
@@ -319,7 +328,7 @@ namespace v2rayN.Handler
var coreInfo = LazyConfig.Instance.GetCoreInfo(type); var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
string url = coreInfo.coreReleaseApiUrl; string url = coreInfo.coreReleaseApiUrl;
var result = await (new DownloadHandle()).DownloadStringAsync(url, true, ""); var result = await (new DownloadHandle()).DownloadStringAsyncOri(url, true, "");
if (!Utils.IsNullOrEmpty(result)) if (!Utils.IsNullOrEmpty(result))
{ {
responseHandler(type, result, preRelease); responseHandler(type, result, preRelease);
@@ -457,6 +466,17 @@ namespace v2rayN.Handler
throw new ArgumentException("Type"); throw new ArgumentException("Type");
} }
if (type == ECoreType.v2rayN)
{
decimal.TryParse(curVersion, out decimal decCur);
decimal.TryParse(version, out decimal dec);
if (decCur >= dec)
{
AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message));
return;
}
}
if (curVersion == version) if (curVersion == version)
{ {
AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message)); AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message));

View File

@@ -8,148 +8,31 @@
{ {
#region property #region property
/// <summary> public string indexId { get; set; }
/// 允许日志
/// </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 remoteDNS { get; set; }
/// <summary> /// <summary>
/// Outbound Freedom domainStrategy /// Outbound Freedom domainStrategy
/// </summary> /// </summary>
public string domainStrategy4Freedom public string domainStrategy4Freedom { get; set; }
{
get; set;
}
/// <summary> public ESysProxyType sysProxyType { get; set; }
/// 是否允许不安全连接 public string systemProxyExceptions { get; set; }
/// </summary>
public bool defAllowInsecure
{
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 string systemProxyAdvancedProtocol { 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;
public bool autoHideStartup { get; set; }
#endregion #endregion
#region other entities #region other entities
public CoreBasicItem coreBasicItem { get; set; }
public TunModeItem tunModeItem { get; set; } public TunModeItem tunModeItem { get; set; }
public KcpItem kcpItem { get; set; } public KcpItem kcpItem { get; set; }
public GrpcItem grpcItem { get; set; } public GrpcItem grpcItem { get; set; }
public RoutingBasicItem routingBasicItem { get; set; }
public GUIItem guiItem { get; set; }
public UIItem uiItem { get; set; } public UIItem uiItem { get; set; }
public ConstItem constItem { get; set; } public ConstItem constItem { get; set; }
public SpeedTestItem speedTestItem { get; set; }
public List<InItem> inbound { get; set; } public List<InItem> inbound { get; set; }
public List<KeyEventItem> globalHotkeys { get; set; } public List<KeyEventItem> globalHotkeys { get; set; }
public List<CoreTypeItem> coreTypeItem { get; set; } public List<CoreTypeItem> coreTypeItem { get; set; }

View File

@@ -2,6 +2,37 @@
namespace v2rayN.Mode 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] [Serializable]
public class InItem public class InItem
{ {
@@ -51,23 +82,53 @@ namespace v2rayN.Mode
public int initial_windows_size { get; set; } 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] [Serializable]
public class UIItem public class UIItem
{ {
public bool enableAutoAdjustMainLvColWidth { get; set; } public bool enableAutoAdjustMainLvColWidth { get; set; }
public double mainWidth { get; set; } public double mainWidth { get; set; }
public double mainHeight { get; set; } public double mainHeight { get; set; }
public double mainGirdHeight1 { get; set; }
public double mainGirdHeight2 { get; set; }
public bool colorModeDark { get; set; } public bool colorModeDark { get; set; }
public string? colorPrimaryName { get; set; } public string? colorPrimaryName { get; set; }
public string currentLanguage { get; set; } public string currentLanguage { get; set; }
public string currentFontFamily { get; set; }
public int currentFontSize { get; set; }
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; } public Dictionary<string, int> mainLvColWidth { get; set; }
} }
[Serializable] [Serializable]
public class ConstItem public class ConstItem
{ {
public string speedTestUrl { get; set; }
public string speedPingTestUrl { get; set; }
public string defIEProxyExceptions { get; set; } public string defIEProxyExceptions { get; set; }
} }
@@ -102,8 +163,33 @@ namespace v2rayN.Mode
public bool strictRoute { get; set; } public bool strictRoute { get; set; }
public string stack { get; set; } public string stack { get; set; }
public int mtu { get; set; } public int mtu { get; set; }
public string customTemplate { get; set; }
public bool bypassMode { get; set; } = true;
public List<string> directIP { get; set; } public List<string> directIP { get; set; }
public List<string> directProcess { get; set; } public List<string> directProcess { get; set; }
public List<string> proxyIP { get; set; }
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 bool locked { get; set; }
public string customIcon { get; set; } public string customIcon { get; set; }
public string domainStrategy { get; set; } public string domainStrategy { get; set; }
public int sort { get; set; }
} }
} }

View File

@@ -1,12 +1,8 @@
namespace v2rayN.Mode namespace v2rayN.Mode
{ {
[Serializable] [Serializable]
class ServerSpeedItem class ServerSpeedItem : ServerStatItem
{ {
public string indexId
{
get; set;
}
public long proxyUp public long proxyUp
{ {
get; set; get; set;

View File

@@ -3,25 +3,11 @@
[Serializable] [Serializable]
class ServerTestItem class ServerTestItem
{ {
public string indexId public string indexId { get; set; }
{ public string address { get; set; }
get; set; public int port { get; set; }
} public EConfigType configType { get; set; }
public string address public bool allowTest { get; set; }
{ public int delay { get; set; }
get; set;
}
public int port
{
get; set;
}
public EConfigType configType
{
get; set;
}
public bool allowTest
{
get; set;
}
} }
} }

View File

@@ -1,4 +1,6 @@
namespace v2rayN.Mode using Newtonsoft.Json;
namespace v2rayN.Mode
{ {
/// <summary> /// <summary>
/// v2ray配置文件实体类 /// v2ray配置文件实体类
@@ -505,6 +507,12 @@
/// ///
/// </summary> /// </summary>
public string Host { get; set; } public string Host { get; set; }
/// <summary>
/// 用户代理
/// </summary>
[JsonProperty("User-Agent")]
public string UserAgent { get; set; }
} }
public class HttpSettings public class HttpSettings

View File

@@ -63,5 +63,10 @@
/// TLS alpn /// TLS alpn
/// </summary> /// </summary>
public string alpn { get; set; } = string.Empty; public string alpn { get; set; } = string.Empty;
/// <summary>
/// TLS fingerprint
/// </summary>
public string fp { get; set; } = string.Empty;
} }
} }

View File

@@ -70,7 +70,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 All servers 的本地化字符串。 /// 查找类似 All 的本地化字符串。
/// </summary> /// </summary>
public static string AllGroupServers { public static string AllGroupServers {
get { get {
@@ -681,6 +681,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Edit Server (Ctrl+D) 的本地化字符串。
/// </summary>
public static string menuEditServer {
get {
return ResourceManager.GetString("menuEditServer", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Exit 的本地化字符串。 /// 查找类似 Exit 的本地化字符串。
/// </summary> /// </summary>
@@ -781,7 +790,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 One-click test Latency and speed (Ctrl+E) 的本地化字符串。 /// 查找类似 One-click multi test Latency and speed (Ctrl+E) 的本地化字符串。
/// </summary> /// </summary>
public static string menuMixedTestServer { public static string menuMixedTestServer {
get { get {
@@ -807,6 +816,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Move to group 的本地化字符串。
/// </summary>
public static string menuMoveToGroup {
get {
return ResourceManager.GetString("menuMoveToGroup", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Move to top (T) 的本地化字符串。 /// 查找类似 Move to top (T) 的本地化字符串。
/// </summary> /// </summary>
@@ -1105,7 +1123,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Share Server (Ctrl+D) 的本地化字符串。 /// 查找类似 Share Server (Ctrl+F) 的本地化字符串。
/// </summary> /// </summary>
public static string menuShareServer { public static string menuShareServer {
get { get {
@@ -1743,6 +1761,24 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Test completed 的本地化字符串。
/// </summary>
public static string SpeedtestingCompleted {
get {
return ResourceManager.GetString("SpeedtestingCompleted", resourceCulture);
}
}
/// <summary>
/// 查找类似 Skip test 的本地化字符串。
/// </summary>
public static string SpeedtestingSkip {
get {
return ResourceManager.GetString("SpeedtestingSkip", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 PAC failed to start. Please run this program as Administrator. 的本地化字符串。 /// 查找类似 PAC failed to start. Please run this program as Administrator. 的本地化字符串。
/// </summary> /// </summary>
@@ -1852,6 +1888,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 AutoRefresh 的本地化字符串。
/// </summary>
public static string TbAutoRefresh {
get {
return ResourceManager.GetString("TbAutoRefresh", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Domain and ip are auto sorted when saving 的本地化字符串。 /// 查找类似 Domain and ip are auto sorted when saving 的本地化字符串。
/// </summary> /// </summary>
@@ -2347,6 +2392,24 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 FontFamily(Require restart) 的本地化字符串。
/// </summary>
public static string TbSettingsCurrentFontFamily {
get {
return ResourceManager.GetString("TbSettingsCurrentFontFamily", resourceCulture);
}
}
/// <summary>
/// 查找类似 Copy the font TTF file to the directory guiFonts, restart the settings 的本地化字符串。
/// </summary>
public static string TbSettingsCurrentFontFamilyTip {
get {
return ResourceManager.GetString("TbSettingsCurrentFontFamilyTip", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 AllowInsecure 的本地化字符串。 /// 查找类似 AllowInsecure 的本地化字符串。
/// </summary> /// </summary>
@@ -2356,6 +2419,33 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Default TLS fingerprint 的本地化字符串。
/// </summary>
public static string TbSettingsDefFingerprint {
get {
return ResourceManager.GetString("TbSettingsDefFingerprint", resourceCulture);
}
}
/// <summary>
/// 查找类似 User-Agent 的本地化字符串。
/// </summary>
public static string TbSettingsDefUserAgent {
get {
return ResourceManager.GetString("TbSettingsDefUserAgent", resourceCulture);
}
}
/// <summary>
/// 查找类似 This parameter is valid only for tcp/http and ws 的本地化字符串。
/// </summary>
public static string TbSettingsDefUserAgentTips {
get {
return ResourceManager.GetString("TbSettingsDefUserAgentTips", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Outbound Freedom domainStrategy 的本地化字符串。 /// 查找类似 Outbound Freedom domainStrategy 的本地化字符串。
/// </summary> /// </summary>
@@ -2365,6 +2455,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Double-click server make active 的本地化字符串。
/// </summary>
public static string TbSettingsDoubleClick2Activate {
get {
return ResourceManager.GetString("TbSettingsDoubleClick2Activate", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Automatically adjust column width after updating subscription 的本地化字符串。 /// 查找类似 Automatically adjust column width after updating subscription 的本地化字符串。
/// </summary> /// </summary>
@@ -2383,6 +2482,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Enable Server Drag Drop Sort(Require restart) 的本地化字符串。
/// </summary>
public static string TbSettingsEnableDragDropSort {
get {
return ResourceManager.GetString("TbSettingsEnableDragDropSort", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Exception 的本地化字符串。 /// 查找类似 Exception 的本地化字符串。
/// </summary> /// </summary>
@@ -2401,6 +2509,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 FontSize 的本地化字符串。
/// </summary>
public static string TbSettingsFontSize {
get {
return ResourceManager.GetString("TbSettingsFontSize", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Http Port 的本地化字符串。 /// 查找类似 Http Port 的本地化字符串。
/// </summary> /// </summary>
@@ -2438,7 +2555,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Language 的本地化字符串。 /// 查找类似 Language(Restart) 的本地化字符串。
/// </summary> /// </summary>
public static string TbSettingsLanguage { public static string TbSettingsLanguage {
get { get {
@@ -2563,6 +2680,33 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 http port=socks port+1 的本地化字符串。
/// </summary>
public static string TbSettingsSocksPortTip {
get {
return ResourceManager.GetString("TbSettingsSocksPortTip", resourceCulture);
}
}
/// <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> /// <summary>
/// 查找类似 Start on boot 的本地化字符串。 /// 查找类似 Start on boot 的本地化字符串。
/// </summary> /// </summary>
@@ -2572,6 +2716,15 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Set this with admin privileges, get admin privileges after startup 的本地化字符串。
/// </summary>
public static string TbSettingsStartBootTip {
get {
return ResourceManager.GetString("TbSettingsStartBootTip", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Enable Statistics (Require restart) 的本地化字符串。 /// 查找类似 Enable Statistics (Require restart) 的本地化字符串。
/// </summary> /// </summary>
@@ -2635,6 +2788,33 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Bypass Mode 的本地化字符串。
/// </summary>
public static string TbSettingsTunModeBypassMode {
get {
return ResourceManager.GetString("TbSettingsTunModeBypassMode", resourceCulture);
}
}
/// <summary>
/// 查找类似 Enable: If no route matches, the final proxy 的本地化字符串。
/// </summary>
public static string TbSettingsTunModeBypassModeTip {
get {
return ResourceManager.GetString("TbSettingsTunModeBypassModeTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Custom Template 的本地化字符串。
/// </summary>
public static string TbSettingsTunModeCustomTemplate {
get {
return ResourceManager.GetString("TbSettingsTunModeCustomTemplate", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Direct IP CIDR, separated by commas (,) 的本地化字符串。 /// 查找类似 Direct IP CIDR, separated by commas (,) 的本地化字符串。
/// </summary> /// </summary>
@@ -2653,6 +2833,24 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 Proxy IP CIDR, separated by commas (,) 的本地化字符串。
/// </summary>
public static string TbSettingsTunModeProxyIP {
get {
return ResourceManager.GetString("TbSettingsTunModeProxyIP", resourceCulture);
}
}
/// <summary>
/// 查找类似 Proxy Process name, separated by commas (,) 的本地化字符串。
/// </summary>
public static string TbSettingsTunModeProxyProcess {
get {
return ResourceManager.GetString("TbSettingsTunModeProxyProcess", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Show console 的本地化字符串。 /// 查找类似 Show console 的本地化字符串。
/// </summary> /// </summary>

View File

@@ -118,22 +118,22 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="BatchExportSubscriptionSuccessfully" xml:space="preserve"> <data name="BatchExportSubscriptionSuccessfully" xml:space="preserve">
<value>Batch export subscription to clipboard successfully</value> <value>صادرات دسته ای محتوای اشتراک به کلیپ بورد با موفقیت انجام شد</value>
</data> </data>
<data name="BatchExportURLSuccessfully" xml:space="preserve"> <data name="BatchExportURLSuccessfully" xml:space="preserve">
<value>Batch export share URL to clipboard successfully</value> <value>Batch export share URL to clipboard successfully</value>
</data> </data>
<data name="CheckServerSettings" xml:space="preserve"> <data name="CheckServerSettings" xml:space="preserve">
<value>Please check the server settings first</value> <value>لطفا ابتدا تنظیمات سرور را بررسی کنید</value>
</data> </data>
<data name="ConfigurationFormatIncorrect" xml:space="preserve"> <data name="ConfigurationFormatIncorrect" xml:space="preserve">
<value>Invalid configuration format</value> <value>فرمت پیکربندی نادرست است</value>
</data> </data>
<data name="CustomServerTips" xml:space="preserve"> <data name="CustomServerTips" xml:space="preserve">
<value>Note that custom configuration relies entirely on your own configuration and does not work with all settings. If you want to use the system proxy, please modify the listening port manually.</value> <value>توجه داشته باشید که پیکربندی سفارشی کاملاً به پیکربندی خود شما بستگی دارد و با همه تنظیمات کار نمی کند. اگر می خواهید از پروکسی سیستم استفاده کنید، لطفاً پورت درحال شنود را به صورت دستی تغییر دهید.</value>
</data> </data>
<data name="Downloading" xml:space="preserve"> <data name="Downloading" xml:space="preserve">
<value>Downloading...</value> <value>درحال دانلود...</value>
</data> </data>
<data name="downloadSpeed" xml:space="preserve"> <data name="downloadSpeed" xml:space="preserve">
<value>دانلود</value> <value>دانلود</value>
@@ -142,55 +142,55 @@
<value>Whether to download? {0}</value> <value>Whether to download? {0}</value>
</data> </data>
<data name="FailedConversionConfiguration" xml:space="preserve"> <data name="FailedConversionConfiguration" xml:space="preserve">
<value>Failed to convert configuration file</value> <value>تبدیل فایل پیکربندی انجام نشد</value>
</data> </data>
<data name="FailedGenDefaultConfiguration" xml:space="preserve"> <data name="FailedGenDefaultConfiguration" xml:space="preserve">
<value>Failed to generate default configuration file</value> <value>فایل پیکربندی پیش فرض ایجاد نشد</value>
</data> </data>
<data name="FailedGetDefaultConfiguration" xml:space="preserve"> <data name="FailedGetDefaultConfiguration" xml:space="preserve">
<value> Failed to get the default configuration</value> <value>پیکربندی پیش فرض دریافت نشد</value>
</data> </data>
<data name="FailedImportedCustomServer" xml:space="preserve"> <data name="FailedImportedCustomServer" xml:space="preserve">
<value>Failed to import custom configuration server</value> <value>سرور پیکربندی سفارشی وارد نشد</value>
</data> </data>
<data name="FailedReadConfiguration" xml:space="preserve"> <data name="FailedReadConfiguration" xml:space="preserve">
<value>Failed to read configuration file</value> <value>فایل پیکربندی خوانده نشد</value>
</data> </data>
<data name="FillCorrectServerPort" xml:space="preserve"> <data name="FillCorrectServerPort" xml:space="preserve">
<value>Please fill in the correct format server port</value> <value>لطفا فرمت صحیح پورت سرور را پر کنید</value>
</data> </data>
<data name="FillKcpParameters" xml:space="preserve"> <data name="FillKcpParameters" xml:space="preserve">
<value>Please fill in the KCP parameters correctly</value> <value>لطفاً پارامترهای KCP را به درستی پر کنید</value>
</data> </data>
<data name="FillLocalListeningPort" xml:space="preserve"> <data name="FillLocalListeningPort" xml:space="preserve">
<value>Please fill in the local listening port</value> <value>لطفاً پورت گوش دادن محلی را پر کنید</value>
</data> </data>
<data name="FillPassword" xml:space="preserve"> <data name="FillPassword" xml:space="preserve">
<value>Please fill in the password</value> <value>لطفا رمز عبور را وارد کنید</value>
</data> </data>
<data name="FillServerAddress" xml:space="preserve"> <data name="FillServerAddress" xml:space="preserve">
<value>Please fill in the server address</value> <value>لطفا آدرس سرور را وارد کنید</value>
</data> </data>
<data name="FillUUID" xml:space="preserve"> <data name="FillUUID" xml:space="preserve">
<value>Please fill in the user ID</value> <value>لطفا شناسه کاربری را وارد کنید</value>
</data> </data>
<data name="IncorrectClientConfiguration" xml:space="preserve"> <data name="IncorrectClientConfiguration" xml:space="preserve">
<value> is not the correct client configuration file, please check</value> <value>فایل پیکربندی مشتری صحیح نیست، لطفا بررسی کنید</value>
</data> </data>
<data name="Incorrectconfiguration" xml:space="preserve"> <data name="Incorrectconfiguration" xml:space="preserve">
<value> is not the correct configuration, please check</value> <value>پیکربندی درستی نیست، لطفا بررسی کنید</value>
</data> </data>
<data name="IncorrectServerConfiguration" xml:space="preserve"> <data name="IncorrectServerConfiguration" xml:space="preserve">
<value> is not the correct server configuration file, please check</value> <value>فایل پیکربندی سرور صحیح نیست، لطفا بررسی کنید</value>
</data> </data>
<data name="InitialConfiguration" xml:space="preserve"> <data name="InitialConfiguration" xml:space="preserve">
<value>Initial Configuration</value> <value>پیکربندی اولیه</value>
</data> </data>
<data name="IsLatestCore" xml:space="preserve"> <data name="IsLatestCore" xml:space="preserve">
<value>{0} already up to date.</value> <value>{0} در حال حاضر به روز است.</value>
</data> </data>
<data name="IsLatestN" xml:space="preserve"> <data name="IsLatestN" xml:space="preserve">
<value>{0} already up to date.</value> <value>{0} در حال حاضر به روز است.</value>
</data> </data>
<data name="LvAddress" xml:space="preserve"> <data name="LvAddress" xml:space="preserve">
<value>آدرس</value> <value>آدرس</value>
@@ -205,52 +205,52 @@
<value>پورت</value> <value>پورت</value>
</data> </data>
<data name="LvServiceType" xml:space="preserve"> <data name="LvServiceType" xml:space="preserve">
<value>Type</value> <value>نوع</value>
</data> </data>
<data name="LvSubscription" xml:space="preserve"> <data name="LvSubscription" xml:space="preserve">
<value>Subs group</value> <value>گروه فرعی</value>
</data> </data>
<data name="LvTestResults" xml:space="preserve"> <data name="LvTestResults" xml:space="preserve">
<value>Test Results</value> <value>نتایج تست</value>
</data> </data>
<data name="LvTodayDownloadDataAmount" xml:space="preserve"> <data name="LvTodayDownloadDataAmount" xml:space="preserve">
<value>Download traffic today</value> <value> ترافیک دانلود امروز</value>
</data> </data>
<data name="LvTodayUploadDataAmount" xml:space="preserve"> <data name="LvTodayUploadDataAmount" xml:space="preserve">
<value>Upload traffic today</value> <value> ترافیک اپلود امروز</value>
</data> </data>
<data name="LvTotalDownloadDataAmount" xml:space="preserve"> <data name="LvTotalDownloadDataAmount" xml:space="preserve">
<value>Total download traffic</value> <value>کل ترافیک دانلود</value>
</data> </data>
<data name="LvTotalUploadDataAmount" xml:space="preserve"> <data name="LvTotalUploadDataAmount" xml:space="preserve">
<value>Total upload traffic</value> <value>کل ترافیک آپلود</value>
</data> </data>
<data name="LvTransportProtocol" xml:space="preserve"> <data name="LvTransportProtocol" xml:space="preserve">
<value>Transport</value> <value>جابجایی</value>
</data> </data>
<data name="MediumFresh" xml:space="preserve"> <data name="MediumFresh" xml:space="preserve">
<value>Medium</value> <value>متوسط</value>
</data> </data>
<data name="MsgClearSubscription" xml:space="preserve"> <data name="MsgClearSubscription" xml:space="preserve">
<value>Clear original subscription content</value> <value>محتوای اشتراک اصلی را پاک کنید</value>
</data> </data>
<data name="MsgDownloadV2rayCoreSuccessfully" xml:space="preserve"> <data name="MsgDownloadV2rayCoreSuccessfully" xml:space="preserve">
<value>Download Core successfully</value> <value>دانلود Core با موفقیت</value>
</data> </data>
<data name="MsgFailedImportSubscription" xml:space="preserve"> <data name="MsgFailedImportSubscription" xml:space="preserve">
<value>Failed to import subscription content</value> <value>محتوای اشتراک وارد نشد</value>
</data> </data>
<data name="MsgGetSubscriptionSuccessfully" xml:space="preserve"> <data name="MsgGetSubscriptionSuccessfully" xml:space="preserve">
<value>Get subscription content successfully</value> <value>محتوای اشتراک با موفقیت دریافت شد</value>
</data> </data>
<data name="MsgNoValidSubscription" xml:space="preserve"> <data name="MsgNoValidSubscription" xml:space="preserve">
<value>No valid subscriptions set</value> <value>هیچ اشتراک معتبری تنظیم نشده است</value>
</data> </data>
<data name="MsgPACUpdateFailed" xml:space="preserve"> <data name="MsgPACUpdateFailed" xml:space="preserve">
<value>PAC update failed</value> <value>به روز رسانی PAC ناموفق بود</value>
</data> </data>
<data name="MsgPACUpdateSuccessfully" xml:space="preserve"> <data name="MsgPACUpdateSuccessfully" xml:space="preserve">
<value>PAC update succeeded</value> <value>به روز رسانی PAC با موفقیت انجام شد</value>
</data> </data>
<data name="MsgParsingSuccessfully" xml:space="preserve"> <data name="MsgParsingSuccessfully" xml:space="preserve">
<value>Resolve {0} successfully</value> <value>Resolve {0} successfully</value>
@@ -259,31 +259,31 @@
<value>Simplify PAC Success</value> <value>Simplify PAC Success</value>
</data> </data>
<data name="MsgStartGettingSubscriptions" xml:space="preserve"> <data name="MsgStartGettingSubscriptions" xml:space="preserve">
<value>Start getting subscriptions</value> <value>شروع به دریافت اشتراک شد</value>
</data> </data>
<data name="MsgStartUpdating" xml:space="preserve"> <data name="MsgStartUpdating" xml:space="preserve">
<value>Start updating {0}...</value> <value>شروع بروزرسانی {0}...</value>
</data> </data>
<data name="MsgStartUpdatingPAC" xml:space="preserve"> <data name="MsgStartUpdatingPAC" xml:space="preserve">
<value>Start updating PAC...</value> <value>شروع بروزرسانی PAC...</value>
</data> </data>
<data name="MsgSubscriptionDecodingFailed" xml:space="preserve"> <data name="MsgSubscriptionDecodingFailed" xml:space="preserve">
<value>Invalid subscription content</value> <value>محتوای اشتراک نامعتبر است</value>
</data> </data>
<data name="MsgUnpacking" xml:space="preserve"> <data name="MsgUnpacking" xml:space="preserve">
<value>is unpacking...</value> <value>در حال باز کردن بسته می باشد ...</value>
</data> </data>
<data name="MsgUpdateSubscriptionEnd" xml:space="preserve"> <data name="MsgUpdateSubscriptionEnd" xml:space="preserve">
<value>Update subscription end</value> <value>بروزرسانی اشتراک به پایان رسید</value>
</data> </data>
<data name="MsgUpdateSubscriptionStart" xml:space="preserve"> <data name="MsgUpdateSubscriptionStart" xml:space="preserve">
<value>Update subscription starts</value> <value>بروزرسانی اشتراک شروع شد</value>
</data> </data>
<data name="MsgUpdateV2rayCoreSuccessfully" xml:space="preserve"> <data name="MsgUpdateV2rayCoreSuccessfully" xml:space="preserve">
<value>Update Core successfully</value> <value>هسته با موفقیت بروزرسانی شد</value>
</data> </data>
<data name="MsgUpdateV2rayCoreSuccessfullyMore" xml:space="preserve"> <data name="MsgUpdateV2rayCoreSuccessfullyMore" xml:space="preserve">
<value>Update Core successfully! Restarting service...</value> <value>هسته با موفقیت بروزرسانی شد! راه اندازی مجدد سرویس...</value>
</data> </data>
<data name="NeedHttpGlobalProxy" xml:space="preserve"> <data name="NeedHttpGlobalProxy" xml:space="preserve">
<value> This feature relies on the Http global proxy, please set it correctly first.</value> <value> This feature relies on the Http global proxy, please set it correctly first.</value>
@@ -301,28 +301,28 @@
<value>Scan completed, no valid QR code found</value> <value>Scan completed, no valid QR code found</value>
</data> </data>
<data name="OperationFailed" xml:space="preserve"> <data name="OperationFailed" xml:space="preserve">
<value> operation failed, please check and retry</value> <value> عملیات انجام نشد، لطفا بررسی کنید و دوباره امتحان کنید</value>
</data> </data>
<data name="PleaseFillRemarks" xml:space="preserve"> <data name="PleaseFillRemarks" xml:space="preserve">
<value>Please Fill Remarks</value> <value>Please Fill Remarks</value>
</data> </data>
<data name="PleaseSelectEncryption" xml:space="preserve"> <data name="PleaseSelectEncryption" xml:space="preserve">
<value>Please select the encryption method</value> <value>لطفاً روش رمزگذاری را انتخاب کنید</value>
</data> </data>
<data name="PleaseSelectProtocol" xml:space="preserve"> <data name="PleaseSelectProtocol" xml:space="preserve">
<value>Please select a protocol</value> <value>لطفا یک پروتکل انتخاب کنید</value>
</data> </data>
<data name="PleaseSelectServer" xml:space="preserve"> <data name="PleaseSelectServer" xml:space="preserve">
<value>Please select the server first</value> <value>لطفا ابتدا سرور را انتخاب کنید</value>
</data> </data>
<data name="QuickFresh" xml:space="preserve"> <data name="QuickFresh" xml:space="preserve">
<value>Fast</value> <value>سریع</value>
</data> </data>
<data name="RemoveDuplicateServerResult" xml:space="preserve"> <data name="RemoveDuplicateServerResult" xml:space="preserve">
<value>Servers deduplication completed. Old: {0}, New: {1}.</value> <value>Servers deduplication completed. Old: {0}, New: {1}.</value>
</data> </data>
<data name="RemoveServer" xml:space="preserve"> <data name="RemoveServer" xml:space="preserve">
<value>Are you sure to remove the server?</value> <value>آیا مطمئن هستید که سرور را حذف می کنید؟</value>
</data> </data>
<data name="SaveClientConfigurationIn" xml:space="preserve"> <data name="SaveClientConfigurationIn" xml:space="preserve">
<value>The client configuration file is saved at: {0}</value> <value>The client configuration file is saved at: {0}</value>
@@ -331,44 +331,44 @@
<value>The server configuration file is saved at: {0}</value> <value>The server configuration file is saved at: {0}</value>
</data> </data>
<data name="SlowFresh" xml:space="preserve"> <data name="SlowFresh" xml:space="preserve">
<value>Slow</value> <value>آهسته. تدریجی</value>
</data> </data>
<data name="SpeedServerTips" xml:space="preserve"> <data name="SpeedServerTips" xml:space="preserve">
<value>Note: This feature relies on the Http global proxy. Please manually adjust the Http global proxy and active node after testing.</value> <value>توجه: این ویژگی به پروکسی جهانی Http متکی است. لطفاً پس از آزمایش، پراکسی جهانی Http و گره فعال را به صورت دستی تنظیم کنید.</value>
</data> </data>
<data name="StartPacFailed" xml:space="preserve"> <data name="StartPacFailed" xml:space="preserve">
<value>PAC failed to start. Please run this program as Administrator.</value> <value>PAC شروع نشد. لطفا این برنامه را به عنوان Administrator اجرا کنید.</value>
</data> </data>
<data name="StartService" xml:space="preserve"> <data name="StartService" xml:space="preserve">
<value>Start service ({0})...</value> <value>Start service ({0})...</value>
</data> </data>
<data name="SuccessfulConfiguration" xml:space="preserve"> <data name="SuccessfulConfiguration" xml:space="preserve">
<value>Configuration successful <value>پیکربندی با موفقیت انجام شد
{0}</value> {0}</value>
</data> </data>
<data name="SuccessfullyImportedCustomServer" xml:space="preserve"> <data name="SuccessfullyImportedCustomServer" xml:space="preserve">
<value>Custom configuration server imported successfully.</value> <value>سرور پیکربندی سفارشی با موفقیت وارد شد.</value>
</data> </data>
<data name="SuccessfullyImportedServerViaClipboard" xml:space="preserve"> <data name="SuccessfullyImportedServerViaClipboard" xml:space="preserve">
<value>{0} servers have been imported from clipboard.</value> <value>{0} سرورها از کلیپ بورد وارد شده اند.</value>
</data> </data>
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve"> <data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
<value>Scan import URL successfully</value> <value>اسکن URL وارد کردن با موفقیت</value>
</data> </data>
<data name="TestMeOutput" xml:space="preserve"> <data name="TestMeOutput" xml:space="preserve">
<value>The ping of current service: {0} ms</value> <value>پینگ سرویس فعلی: {0} ms</value>
</data> </data>
<data name="OperationSuccess" xml:space="preserve"> <data name="OperationSuccess" xml:space="preserve">
<value>Operation success</value> <value>موفقیت عملیات</value>
</data> </data>
<data name="PleaseSelectRules" xml:space="preserve"> <data name="PleaseSelectRules" xml:space="preserve">
<value>Please select rules</value> <value>لطفا قوانین را انتخاب کنید</value>
</data> </data>
<data name="RemoveRules" xml:space="preserve"> <data name="RemoveRules" xml:space="preserve">
<value>Are you sure to remove the rules?</value> <value>آیا مطمئن هستید که قوانین را حذف می کنید؟</value>
</data> </data>
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve"> <data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
<value>{0},One of the required.</value> <value>{0},یکی از مورد نیاز.</value>
</data> </data>
<data name="LvRemarks" xml:space="preserve"> <data name="LvRemarks" xml:space="preserve">
<value>Remarks</value> <value>Remarks</value>
@@ -386,16 +386,16 @@
<value>Do you want to append rules? Choose yes to append, choose otherwise to replace</value> <value>Do you want to append rules? Choose yes to append, choose otherwise to replace</value>
</data> </data>
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve"> <data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
<value>Download GeoFile: {0} successfully</value> <value>دانلود GeoFile: {0} با موفقیت</value>
</data> </data>
<data name="MsgInformationTitle" xml:space="preserve"> <data name="MsgInformationTitle" xml:space="preserve">
<value>Information</value> <value>اطلاعات</value>
</data> </data>
<data name="LvCustomIcon" xml:space="preserve"> <data name="LvCustomIcon" xml:space="preserve">
<value>Custom Icon</value> <value>نماد سفارشی</value>
</data> </data>
<data name="FillCorrectDNSText" xml:space="preserve"> <data name="FillCorrectDNSText" xml:space="preserve">
<value>Please fill in the correct custom DNS</value> <value>لطفاً DNS سفارشی صحیح را پر کنید</value>
</data> </data>
<data name="TransportPathTip1" xml:space="preserve"> <data name="TransportPathTip1" xml:space="preserve">
<value>*ws path</value> <value>*ws path</value>
@@ -446,34 +446,34 @@
<value>Global hotkey {0} registered successfully</value> <value>Global hotkey {0} registered successfully</value>
</data> </data>
<data name="UngroupedServers" xml:space="preserve"> <data name="UngroupedServers" xml:space="preserve">
<value>Ungrouped</value> <value>گروه بندی نشده</value>
</data> </data>
<data name="AllGroupServers" xml:space="preserve"> <data name="AllGroupServers" xml:space="preserve">
<value>All servers</value> <value>همه سرورها</value>
</data> </data>
<data name="FillServerAddressCustom" xml:space="preserve"> <data name="FillServerAddressCustom" xml:space="preserve">
<value>Please browse to import server configuration</value> <value>Please browse to import server configuration</value>
</data> </data>
<data name="SystemProxy" xml:space="preserve"> <data name="SystemProxy" xml:space="preserve">
<value>System proxy</value> <value>پروکسی سیستم</value>
</data> </data>
<data name="Speedtesting" xml:space="preserve"> <data name="Speedtesting" xml:space="preserve">
<value>Testing...</value> <value>درحال تست کردن...</value>
</data> </data>
<data name="TooManyServersTip" xml:space="preserve"> <data name="TooManyServersTip" xml:space="preserve">
<value>Too many servers, please open the main interface</value> <value>تعداد سرورها خیلی زیاد است، لطفا رابط اصلی را باز کنید</value>
</data> </data>
<data name="LabLAN" xml:space="preserve"> <data name="LabLAN" xml:space="preserve">
<value>LAN</value> <value>LAN</value>
</data> </data>
<data name="LabLocal" xml:space="preserve"> <data name="LabLocal" xml:space="preserve">
<value>Local</value> <value>محلی</value>
</data> </data>
<data name="MsgServerTitle" xml:space="preserve"> <data name="MsgServerTitle" xml:space="preserve">
<value>Servers Filter</value> <value>فیلتر سرورها</value>
</data> </data>
<data name="NetFrameworkRequirementsTip" xml:space="preserve"> <data name="NetFrameworkRequirementsTip" xml:space="preserve">
<value>Normal use of this version requires .NET Framework 4.8</value> <value>استفاده معمولی از این نسخه به .NET Framework 4.8 نیاز دارد</value>
</data> </data>
<data name="menuCheckUpdate" xml:space="preserve"> <data name="menuCheckUpdate" xml:space="preserve">
<value>بررسی بروزرسانی</value> <value>بررسی بروزرسانی</value>
@@ -491,10 +491,10 @@
<value>کمک</value> <value>کمک</value>
</data> </data>
<data name="menuOptionSetting" xml:space="preserve"> <data name="menuOptionSetting" xml:space="preserve">
<value>تنظیمات گزینه</value> <value>تنظیمات پارامتر</value>
</data> </data>
<data name="menuPromotion" xml:space="preserve"> <data name="menuPromotion" xml:space="preserve">
<value>Promotion</value> <value>ترفیع</value>
</data> </data>
<data name="menuReload" xml:space="preserve"> <data name="menuReload" xml:space="preserve">
<value>بارگذاری مجدد</value> <value>بارگذاری مجدد</value>
@@ -524,7 +524,7 @@
<value>اشتراک را بدون پروکسی به روز شود</value> <value>اشتراک را بدون پروکسی به روز شود</value>
</data> </data>
<data name="menuSubUpdateViaProxy" xml:space="preserve"> <data name="menuSubUpdateViaProxy" xml:space="preserve">
<value>Update subscription with proxy</value> <value>اشتراک را با پروکسی به روز شود</value>
</data> </data>
<data name="menuSystemproxy" xml:space="preserve"> <data name="menuSystemproxy" xml:space="preserve">
<value>پروکسی سیستم</value> <value>پروکسی سیستم</value>
@@ -536,7 +536,7 @@
<value>پروکسی سیستم تغییر نکند</value> <value>پروکسی سیستم تغییر نکند</value>
</data> </data>
<data name="menuSystemProxyPac" xml:space="preserve"> <data name="menuSystemProxyPac" xml:space="preserve">
<value>Pac Mode</value> <value>حالت Pac</value>
</data> </data>
<data name="menuSystemProxySet" xml:space="preserve"> <data name="menuSystemProxySet" xml:space="preserve">
<value>تنظیم پراکسی سیستم</value> <value>تنظیم پراکسی سیستم</value>
@@ -551,91 +551,91 @@
<value>زبان</value> <value>زبان</value>
</data> </data>
<data name="menuAddServerViaClipboard" xml:space="preserve"> <data name="menuAddServerViaClipboard" xml:space="preserve">
<value>Import bulk URL from clipboard (Ctrl+V)</value> <value>وارد کردن URL انبوه از کلیپ بورد (Ctrl+V)</value>
</data> </data>
<data name="menuAddServerViaScan" xml:space="preserve"> <data name="menuAddServerViaScan" xml:space="preserve">
<value>Scan QR code on the screen (Ctrl+S)</value> <value>اسکن کد QR روی صفحه (Ctrl+S)</value>
</data> </data>
<data name="menuCopyServer" xml:space="preserve"> <data name="menuCopyServer" xml:space="preserve">
<value>Clone selected server</value> <value>سرور انتخاب شده را شبیه سازی کنید</value>
</data> </data>
<data name="menuRemoveDuplicateServer" xml:space="preserve"> <data name="menuRemoveDuplicateServer" xml:space="preserve">
<value>Remove duplicate servers</value> <value>سرورهای تکراری را حذف کنید</value>
</data> </data>
<data name="menuRemoveServer" xml:space="preserve"> <data name="menuRemoveServer" xml:space="preserve">
<value>Remove selected servers (Delete)</value> <value>حذف سرورهای انتخابی (Delete)</value>
</data> </data>
<data name="menuSetDefaultServer" xml:space="preserve"> <data name="menuSetDefaultServer" xml:space="preserve">
<value>Set as active server (Enter)</value> <value>به عنوان سرور فعال تنظیم کنید (Enter)</value>
</data> </data>
<data name="menuClearServerStatistics" xml:space="preserve"> <data name="menuClearServerStatistics" xml:space="preserve">
<value>Clear all service statistics</value> <value>تمام آمار خدمات را پاک کنید</value>
</data> </data>
<data name="menuPingServer" xml:space="preserve"> <data name="menuPingServer" xml:space="preserve">
<value>Test servers ping (Ctrl+P)</value> <value>تست پینگ سرورها (Ctrl+P)</value>
</data> </data>
<data name="menuRealPingServer" xml:space="preserve"> <data name="menuRealPingServer" xml:space="preserve">
<value>Test servers real delay (Ctrl+R)</value> <value>آزمایش سرورها با تاخیر واقعی (Ctrl+R)</value>
</data> </data>
<data name="menuSortServerResult" xml:space="preserve"> <data name="menuSortServerResult" xml:space="preserve">
<value>Sort by test result</value> <value>مرتب سازی بر اساس نتیجه تست</value>
</data> </data>
<data name="menuSpeedServer" xml:space="preserve"> <data name="menuSpeedServer" xml:space="preserve">
<value>Test servers download speed (Ctrl+T)</value> <value>تست سرعت دانلود سرورها (Ctrl+T)</value>
</data> </data>
<data name="menuTcpingServer" xml:space="preserve"> <data name="menuTcpingServer" xml:space="preserve">
<value>Test servers with tcping (Ctrl+O)</value> <value>تست سرورها با tcping (Ctrl+O)</value>
</data> </data>
<data name="menuTestMe" xml:space="preserve"> <data name="menuTestMe" xml:space="preserve">
<value>Test current service status</value> <value>وضعیت سرویس فعلی را تست کنید</value>
</data> </data>
<data name="menuExport2ClientConfig" xml:space="preserve"> <data name="menuExport2ClientConfig" xml:space="preserve">
<value>سرور انتخابی را برای پیکربندی کلاینت صادر کنید</value> <value>سرور انتخابی را برای پیکربندی کلاینت صادر کنید</value>
</data> </data>
<data name="menuExport2ServerConfig" xml:space="preserve"> <data name="menuExport2ServerConfig" xml:space="preserve">
<value>Export selected server for server configuration</value> <value>سرور انتخاب شده را برای پیکربندی سرور صادر کنید</value>
</data> </data>
<data name="menuExport2ShareUrl" xml:space="preserve"> <data name="menuExport2ShareUrl" xml:space="preserve">
<value>Export share URLs to clipboard (Ctrl+C)</value> <value>URL های اشتراک گذاری را به کلیپ بورد صادر کنید (Ctrl+C)</value>
</data> </data>
<data name="menuExport2SubContent" xml:space="preserve"> <data name="menuExport2SubContent" xml:space="preserve">
<value>Export subscription (base64) share to clipboard</value> <value>اشتراک (base64) را به کلیپ بورد صادر کنید</value>
</data> </data>
<data name="menuAddCustomServer" xml:space="preserve"> <data name="menuAddCustomServer" xml:space="preserve">
<value>یک سرور پیکربندی سفارشی اضافه شود</value> <value>یک سرور پیکربندی سفارشی اضافه شود</value>
</data> </data>
<data name="menuAddShadowsocksServer" xml:space="preserve"> <data name="menuAddShadowsocksServer" xml:space="preserve">
<value>Add [Shadowsocks] server</value> <value>سرور [شادوساکس] را اضافه کنید</value>
</data> </data>
<data name="menuAddSocksServer" xml:space="preserve"> <data name="menuAddSocksServer" xml:space="preserve">
<value>Add [Socks] server</value> <value>سرور [ساکس] را اضافه کنید</value>
</data> </data>
<data name="menuAddTrojanServer" xml:space="preserve"> <data name="menuAddTrojanServer" xml:space="preserve">
<value>Add [Trojan] server</value> <value>سرور [تروجان] را اضافه کنید</value>
</data> </data>
<data name="menuAddVlessServer" xml:space="preserve"> <data name="menuAddVlessServer" xml:space="preserve">
<value>Add [VLESS] server</value> <value>سرور [VLESS] را اضافه کنید</value>
</data> </data>
<data name="menuAddVmessServer" xml:space="preserve"> <data name="menuAddVmessServer" xml:space="preserve">
<value>Add [VMess] server</value> <value>سرور [VMess] را اضافه کنید</value>
</data> </data>
<data name="menuSelectAll" xml:space="preserve"> <data name="menuSelectAll" xml:space="preserve">
<value>Select All (Ctrl+A)</value> <value>انتخاب همه (Ctrl+A)</value>
</data> </data>
<data name="menuMsgViewClear" xml:space="preserve"> <data name="menuMsgViewClear" xml:space="preserve">
<value>Clear All</value> <value>همه را پاک کن</value>
</data> </data>
<data name="menuMsgViewCopy" xml:space="preserve"> <data name="menuMsgViewCopy" xml:space="preserve">
<value>Copy (Ctrl+C)</value> <value>کپی (Ctrl+C)</value>
</data> </data>
<data name="menuMsgViewCopyAll" xml:space="preserve"> <data name="menuMsgViewCopyAll" xml:space="preserve">
<value>Copy All</value> <value>کپی همه</value>
</data> </data>
<data name="menuMsgViewFilter" xml:space="preserve"> <data name="menuMsgViewFilter" xml:space="preserve">
<value>Set message filters</value> <value>فیلترهای پیام را تنظیم کنید</value>
</data> </data>
<data name="menuMsgViewSelectAll" xml:space="preserve"> <data name="menuMsgViewSelectAll" xml:space="preserve">
<value>Select All (Ctrl+A)</value> <value>انتخاب همه (Ctrl+A)</value>
</data> </data>
<data name="menuSubAdd" xml:space="preserve"> <data name="menuSubAdd" xml:space="preserve">
<value>اضافه کردن</value> <value>اضافه کردن</value>
@@ -665,7 +665,7 @@
<value>تایید</value> <value>تایید</value>
</data> </data>
<data name="GbTransport" xml:space="preserve"> <data name="GbTransport" xml:space="preserve">
<value>Transport</value> <value>انتقال</value>
</data> </data>
<data name="TbAddress" xml:space="preserve"> <data name="TbAddress" xml:space="preserve">
<value>آدرس</value> <value>آدرس</value>
@@ -689,7 +689,7 @@
<value>UUID(id)</value> <value>UUID(id)</value>
</data> </data>
<data name="TbNetwork" xml:space="preserve"> <data name="TbNetwork" xml:space="preserve">
<value>Transport protocol(network)</value> <value>پروتکل جابجایی (شبکه)</value>
</data> </data>
<data name="TbPath" xml:space="preserve"> <data name="TbPath" xml:space="preserve">
<value>مسیر</value> <value>مسیر</value>
@@ -716,10 +716,10 @@
<value>*Default value tcp</value> <value>*Default value tcp</value>
</data> </data>
<data name="TbCoreType" xml:space="preserve"> <data name="TbCoreType" xml:space="preserve">
<value>Core Type</value> <value>نوع هسته</value>
</data> </data>
<data name="TbFlow5" xml:space="preserve"> <data name="TbFlow5" xml:space="preserve">
<value>Flow</value> <value>جریان</value>
</data> </data>
<data name="TbGUID" xml:space="preserve"> <data name="TbGUID" xml:space="preserve">
<value>Generate</value> <value>Generate</value>
@@ -728,19 +728,19 @@
<value>رمزعبور</value> <value>رمزعبور</value>
</data> </data>
<data name="TbId4" xml:space="preserve"> <data name="TbId4" xml:space="preserve">
<value>Password(Optional)</value> <value>رمز عبور (اختیاری)</value>
</data> </data>
<data name="TbId5" xml:space="preserve"> <data name="TbId5" xml:space="preserve">
<value>UUID(id)</value> <value>UUID(id)</value>
</data> </data>
<data name="TbSecurity3" xml:space="preserve"> <data name="TbSecurity3" xml:space="preserve">
<value>Encryption</value> <value>رمزگذاری</value>
</data> </data>
<data name="TbSecurity4" xml:space="preserve"> <data name="TbSecurity4" xml:space="preserve">
<value>User(Optional)</value> <value>کاربر (اختیاری)</value>
</data> </data>
<data name="TbSecurity5" xml:space="preserve"> <data name="TbSecurity5" xml:space="preserve">
<value>Encryption</value> <value>رمزگذاری</value>
</data> </data>
<data name="TbPreSocksPort" xml:space="preserve"> <data name="TbPreSocksPort" xml:space="preserve">
<value>txtPreSocksPort</value> <value>txtPreSocksPort</value>
@@ -755,46 +755,46 @@
<value>ویرایش</value> <value>ویرایش</value>
</data> </data>
<data name="TbSettingsAdvancedProtocol" xml:space="preserve"> <data name="TbSettingsAdvancedProtocol" xml:space="preserve">
<value>Advanced proxy settings, protocol selection (optional)</value> <value>تنظیمات پیشرفته پروکسی، انتخاب پروتکل (اختیاری)</value>
</data> </data>
<data name="TbSettingsAllowLAN" xml:space="preserve"> <data name="TbSettingsAllowLAN" xml:space="preserve">
<value>Allow connections from the LAN</value> <value>اتصالات از LAN را مجاز کنید</value>
</data> </data>
<data name="TbSettingsAutoHideStartup" xml:space="preserve"> <data name="TbSettingsAutoHideStartup" xml:space="preserve">
<value>Auto hide startup</value> <value>Auto hide startup</value>
</data> </data>
<data name="TbSettingsAutoTest" xml:space="preserve"> <data name="TbSettingsAutoTest" xml:space="preserve">
<value>Automatic latency test interval (minutes)</value> <value>فاصله تست تأخیر خودکار (دقیقه)</value>
</data> </data>
<data name="TbSettingsAutoUpdate" xml:space="preserve"> <data name="TbSettingsAutoUpdate" xml:space="preserve">
<value>Automatic update interval of subscriptions (hours)</value> <value>فاصله به روز رسانی خودکار اشتراک ها (ساعت)</value>
</data> </data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve"> <data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>Automatic update interval of and Geo (hours)</value> <value>فاصله به روز رسانی خودکار و Geo (ساعت)</value>
</data> </data>
<data name="TbSettingsCore" xml:space="preserve"> <data name="TbSettingsCore" xml:space="preserve">
<value>Core: basic settings</value> <value>هسته: تنظیمات اولیه</value>
</data> </data>
<data name="TbSettingsCoreDns" xml:space="preserve"> <data name="TbSettingsCoreDns" xml:space="preserve">
<value>Core: DNS settings</value> <value>هسته: تنظیمات DNS</value>
</data> </data>
<data name="TbSettingsCoreKcp" xml:space="preserve"> <data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Core: KCP settings</value> <value>هسته: تنظیمات KCP</value>
</data> </data>
<data name="TbSettingsCoreType" xml:space="preserve"> <data name="TbSettingsCoreType" xml:space="preserve">
<value>CoreType settings</value> <value>تنظیمات CoreType</value>
</data> </data>
<data name="TbSettingsDefAllowInsecure" xml:space="preserve"> <data name="TbSettingsDefAllowInsecure" xml:space="preserve">
<value>AllowInsecure</value> <value>اجازه ناامن</value>
</data> </data>
<data name="TbSettingsDomainStrategy4Freedom" xml:space="preserve"> <data name="TbSettingsDomainStrategy4Freedom" xml:space="preserve">
<value>Outbound Freedom domainStrategy</value> <value>Outbound Freedom domainStrategy</value>
</data> </data>
<data name="TbSettingsEnableAutoAdjustMainLvColWidth" xml:space="preserve"> <data name="TbSettingsEnableAutoAdjustMainLvColWidth" xml:space="preserve">
<value>Automatically adjust column width after updating subscription</value> <value>پس از به‌روزرسانی اشتراک، عرض ستون را به صورت خودکار تنظیم شود</value>
</data> </data>
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve"> <data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>Check for pre-release updates</value> <value>به روز رسانی های پیش از انتشار را بررسی شود</value>
</data> </data>
<data name="TbSettingsException" xml:space="preserve"> <data name="TbSettingsException" xml:space="preserve">
<value>استثنا</value> <value>استثنا</value>
@@ -803,37 +803,37 @@
<value>Exception. Do not use proxy server for addresses beginning with,Use semicolon (;)</value> <value>Exception. Do not use proxy server for addresses beginning with,Use semicolon (;)</value>
</data> </data>
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>Http Port</value> <value>پورت Http</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>Ignore Geo files when updating core</value> <value>هنگام به‌روزرسانی هسته، فایل‌های Geo را نادیده بگیرید</value>
</data> </data>
<data name="TbSettingsIpv6" xml:space="preserve"> <data name="TbSettingsIpv6" xml:space="preserve">
<value>Enable IPv6</value> <value>IPv6 را فعال کنید</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Keep older when deduplication</value> <value>Keep older when deduplication</value>
</data> </data>
<data name="TbSettingsLogEnabled" xml:space="preserve"> <data name="TbSettingsLogEnabled" xml:space="preserve">
<value>Record local logs</value> <value>ثبت گزارش های محلی</value>
</data> </data>
<data name="TbSettingsLogLevel" xml:space="preserve"> <data name="TbSettingsLogLevel" xml:space="preserve">
<value>Log Level</value> <value>سطح ثبت رویداد</value>
</data> </data>
<data name="TbSettingsMuxEnabled" xml:space="preserve"> <data name="TbSettingsMuxEnabled" xml:space="preserve">
<value>Turn on Mux Multiplexing</value> <value>Turn on Mux Multiplexing</value>
</data> </data>
<data name="TbSettingsN" xml:space="preserve"> <data name="TbSettingsN" xml:space="preserve">
<value>v2rayN settings</value> <value>تنظیمات v2rayN</value>
</data> </data>
<data name="TbSettingsPacListenPort" xml:space="preserve"> <data name="TbSettingsPacListenPort" xml:space="preserve">
<value>Pac listen port</value> <value>Pac پورت درحال شنود</value>
</data> </data>
<data name="TbSettingsPass" xml:space="preserve"> <data name="TbSettingsPass" xml:space="preserve">
<value>Auth pass</value> <value>Auth pass</value>
</data> </data>
<data name="TbSettingsRemoteDNS" xml:space="preserve"> <data name="TbSettingsRemoteDNS" xml:space="preserve">
<value>Custom DNS (multiple, separated by commas (,))</value> <value>سفارشی DNS (multiple, separated by commas (,))</value>
</data> </data>
<data name="TbSettingsSaveTip" xml:space="preserve"> <data name="TbSettingsSaveTip" xml:space="preserve">
<value>After modifying the following parameters, click Save to take effect</value> <value>After modifying the following parameters, click Save to take effect</value>
@@ -845,22 +845,22 @@
<value>Turn on Sniffing</value> <value>Turn on Sniffing</value>
</data> </data>
<data name="TbSettingsSocksPort" xml:space="preserve"> <data name="TbSettingsSocksPort" xml:space="preserve">
<value>Socks Port</value> <value>ساکس Port</value>
</data> </data>
<data name="TbSettingsStartBoot" xml:space="preserve"> <data name="TbSettingsStartBoot" xml:space="preserve">
<value>Start on boot</value> <value>درهنگام راه ائدازی شروع شود</value>
</data> </data>
<data name="TbSettingsStatistics" xml:space="preserve"> <data name="TbSettingsStatistics" xml:space="preserve">
<value>Enable Statistics (Require restart)</value> <value>فعال کردن آمار (نیاز به راه اندازی مجدد)</value>
</data> </data>
<data name="TbSettingsStatisticsFreshRate" xml:space="preserve"> <data name="TbSettingsStatisticsFreshRate" xml:space="preserve">
<value>Statistics freshrate (second)</value> <value>نرخ تازه سازی آمار (ثانیه)</value>
</data> </data>
<data name="TbSettingsSubConvert" xml:space="preserve"> <data name="TbSettingsSubConvert" xml:space="preserve">
<value>Subscription conversion Url</value> <value>Subscription conversion Url</value>
</data> </data>
<data name="TbSettingsSystemproxy" xml:space="preserve"> <data name="TbSettingsSystemproxy" xml:space="preserve">
<value>System proxy settings</value> <value>تنظیمات پراکسی سیستم</value>
</data> </data>
<data name="TbSettingsTLS13" xml:space="preserve"> <data name="TbSettingsTLS13" xml:space="preserve">
<value>Enable Security Protocol TLS v1.3 (subscription/update)</value> <value>Enable Security Protocol TLS v1.3 (subscription/update)</value>
@@ -875,19 +875,19 @@
<value>Auth user</value> <value>Auth user</value>
</data> </data>
<data name="TbClearSystemProxy" xml:space="preserve"> <data name="TbClearSystemProxy" xml:space="preserve">
<value>Clear system proxy</value> <value>پاک کردن پروکسی سیستم</value>
</data> </data>
<data name="TbDisplayGUI" xml:space="preserve"> <data name="TbDisplayGUI" xml:space="preserve">
<value>Display GUI</value> <value>نمایش رابط کاربری گرافیکی</value>
</data> </data>
<data name="TbGlobalHotkeySetting" xml:space="preserve"> <data name="TbGlobalHotkeySetting" xml:space="preserve">
<value>GlobalHotkey Setting</value> <value>تنظیم کلید میانبر جهانی</value>
</data> </data>
<data name="TbGlobalHotkeySettingTip" xml:space="preserve"> <data name="TbGlobalHotkeySettingTip" xml:space="preserve">
<value>Set directly by pressing the keyboard, Take effect after restart</value> <value>مستقیماً با فشار دادن صفحه کلید تنظیم کنید، بعد از راه اندازی مجدد اعمال شود</value>
</data> </data>
<data name="TbNotChangeSystemProxy" xml:space="preserve"> <data name="TbNotChangeSystemProxy" xml:space="preserve">
<value>Do not change system proxy</value> <value>پروکسی سیستم را تغییر ندهید</value>
</data> </data>
<data name="TbReset" xml:space="preserve"> <data name="TbReset" xml:space="preserve">
<value>بازنشانی</value> <value>بازنشانی</value>
@@ -896,10 +896,10 @@
<value>تنظیم پراکسی سیستم</value> <value>تنظیم پراکسی سیستم</value>
</data> </data>
<data name="TbSystemProxyPac" xml:space="preserve"> <data name="TbSystemProxyPac" xml:space="preserve">
<value>Pac Mode</value> <value>حالت Pac</value>
</data> </data>
<data name="menuShareServer" xml:space="preserve"> <data name="menuShareServer" xml:space="preserve">
<value>Share Server (Ctrl+D)</value> <value>اشتراک گذاری سرور(Ctrl+F)</value>
</data> </data>
<data name="menuRouting" xml:space="preserve"> <data name="menuRouting" xml:space="preserve">
<value>مسیریابی</value> <value>مسیریابی</value>
@@ -911,10 +911,10 @@
<value>اجرا به عنوان ادمین</value> <value>اجرا به عنوان ادمین</value>
</data> </data>
<data name="menuMoveBottom" xml:space="preserve"> <data name="menuMoveBottom" xml:space="preserve">
<value>Move to bottom (B)</value> <value>به پایین حرکت شود(B)</value>
</data> </data>
<data name="menuMoveDown" xml:space="preserve"> <data name="menuMoveDown" xml:space="preserve">
<value>Down (D)</value> <value>پایین (D)</value>
</data> </data>
<data name="menuMoveTop" xml:space="preserve"> <data name="menuMoveTop" xml:space="preserve">
<value>Move to top (T)</value> <value>Move to top (T)</value>
@@ -929,31 +929,31 @@
<value>{0} Website</value> <value>{0} Website</value>
</data> </data>
<data name="menuRoutingAdvanced" xml:space="preserve"> <data name="menuRoutingAdvanced" xml:space="preserve">
<value>Advanced Function</value> <value>عملکرد پیشرفته</value>
</data> </data>
<data name="menuRoutingAdvancedAdd" xml:space="preserve"> <data name="menuRoutingAdvancedAdd" xml:space="preserve">
<value>اضافه کردن</value> <value>اضافه کردن</value>
</data> </data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve"> <data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>Import Advanced Rules</value> <value>وارد کردن قوانین پیشرفته</value>
</data> </data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve"> <data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>Remove selected</value> <value>حذف انتخاب شده</value>
</data> </data>
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>Set as active rule</value> <value>Set as active rule</value>
</data> </data>
<data name="menuRoutingBasic" xml:space="preserve"> <data name="menuRoutingBasic" xml:space="preserve">
<value>Basic Function</value> <value>عملکرد پایه</value>
</data> </data>
<data name="menuRoutingBasicImportRules" xml:space="preserve"> <data name="menuRoutingBasicImportRules" xml:space="preserve">
<value>Import Basic Rules</value> <value>واردات قوانین اساسی</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve"> <data name="TbdomainMatcher" xml:space="preserve">
<value>Domain Matcher</value> <value>تطبیق دامنه</value>
</data> </data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Domain strategy</value> <value>استراتژی دامنه</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve"> <data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>فعال کردن عملکرد پیشرفته</value> <value>فعال کردن عملکرد پیشرفته</value>
@@ -968,58 +968,58 @@
<value>1.Proxy Domain or IP</value> <value>1.Proxy Domain or IP</value>
</data> </data>
<data name="TbRoutingTabRuleList" xml:space="preserve"> <data name="TbRoutingTabRuleList" xml:space="preserve">
<value>Pre-defined Rule Set List</value> <value>لیست مجموعه قوانین از پیش تعریف شده</value>
</data> </data>
<data name="TbRoutingTips" xml:space="preserve"> <data name="TbRoutingTips" xml:space="preserve">
<value>*Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt;</value> <value>*Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt;</value>
</data> </data>
<data name="menuImportRulesFromClipboard" xml:space="preserve"> <data name="menuImportRulesFromClipboard" xml:space="preserve">
<value>Import Rules From Clipboard</value> <value>وارد کردن قوانین از کلیپ بورد</value>
</data> </data>
<data name="menuImportRulesFromFile" xml:space="preserve"> <data name="menuImportRulesFromFile" xml:space="preserve">
<value>Import Rules From File</value> <value>وارد کردن قوانین از فایل</value>
</data> </data>
<data name="menuImportRulesFromUrl" xml:space="preserve"> <data name="menuImportRulesFromUrl" xml:space="preserve">
<value>Import Rules From Sub Url</value> <value>وارد کردن قوانین از Sub Url</value>
</data> </data>
<data name="menuRoutingRuleSetting" xml:space="preserve"> <data name="menuRoutingRuleSetting" xml:space="preserve">
<value>تنظیم قانون</value> <value>تنظیم قانون</value>
</data> </data>
<data name="menuRuleAdd" xml:space="preserve"> <data name="menuRuleAdd" xml:space="preserve">
<value>Rule Add</value> <value>اضافه کردن قانون</value>
</data> </data>
<data name="menuRuleExportSelected" xml:space="preserve"> <data name="menuRuleExportSelected" xml:space="preserve">
<value>Export Selected Rules</value> <value>صادر کردن قوانین انتخاب شده</value>
</data> </data>
<data name="menuRuleList" xml:space="preserve"> <data name="menuRuleList" xml:space="preserve">
<value>Rule List</value> <value>فهرست قوانین</value>
</data> </data>
<data name="menuRuleRemove" xml:space="preserve"> <data name="menuRuleRemove" xml:space="preserve">
<value>Remove Rules</value> <value>حذف قوانین</value>
</data> </data>
<data name="menuRoutingRuleDetailsSetting" xml:space="preserve"> <data name="menuRoutingRuleDetailsSetting" xml:space="preserve">
<value>RoutingRuleDetailsSetting</value> <value>تنظیم جزئیات قانون مسیریابی</value>
</data> </data>
<data name="TbAutoSort" xml:space="preserve"> <data name="TbAutoSort" xml:space="preserve">
<value>Domain and ip are auto sorted when saving</value> <value>دامنه و آی پی در هنگام ذخیره به طور خودکار مرتب می شوند</value>
</data> </data>
<data name="TbRuleobjectDoc" xml:space="preserve"> <data name="TbRuleobjectDoc" xml:space="preserve">
<value>Ruleobject Doc</value> <value>Ruleobject Doc</value>
</data> </data>
<data name="TbDnsObjectDoc" xml:space="preserve"> <data name="TbDnsObjectDoc" xml:space="preserve">
<value>Support DnsObject</value> <value>پشتیبانی از DnsObject</value>
</data> </data>
<data name="SubUrlTips" xml:space="preserve"> <data name="SubUrlTips" xml:space="preserve">
<value>Group please leave blank here</value> <value>گروه لطفا اینجا را خالی بگذارید</value>
</data> </data>
<data name="TipChangeRouting" xml:space="preserve"> <data name="TipChangeRouting" xml:space="preserve">
<value>Routing setting is changed</value> <value>تنظیمات مسیریابی تغییر کرده است</value>
</data> </data>
<data name="TipChangeSystemProxy" xml:space="preserve"> <data name="TipChangeSystemProxy" xml:space="preserve">
<value>System proxy setting is changed</value> <value>تنظیمات پراکسی سیستم تغییر کرده است</value>
</data> </data>
<data name="TbSettingsRouteOnly" xml:space="preserve"> <data name="TbSettingsRouteOnly" xml:space="preserve">
<value>RouteOnly</value> <value>فقط مسیر</value>
</data> </data>
<data name="menuMixedTestServer" xml:space="preserve"> <data name="menuMixedTestServer" xml:space="preserve">
<value>One-click test Latency and speed (Ctrl+E)</value> <value>One-click test Latency and speed (Ctrl+E)</value>
@@ -1031,25 +1031,25 @@
<value>Speed(M/s)</value> <value>Speed(M/s)</value>
</data> </data>
<data name="FailedToRunCore" xml:space="preserve"> <data name="FailedToRunCore" xml:space="preserve">
<value>Failed to run Core, please see the log</value> <value>Core اجرا نشد، لطفاً گزارش را ببینید</value>
</data> </data>
<data name="LvFilter" xml:space="preserve"> <data name="LvFilter" xml:space="preserve">
<value>Remarks regular filter</value> <value>Remarks regular filter</value>
</data> </data>
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>Display Log</value> <value>نمایش گزارش</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve"> <data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Import old config guiNConfig</value> <value>پیکربندی قدیمی guiNConfig را وارد شود</value>
</data> </data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>Enable Tun</value> <value>Tun را فعال شود</value>
</data> </data>
<data name="TbSettingsNewPort4LAN" xml:space="preserve"> <data name="TbSettingsNewPort4LAN" xml:space="preserve">
<value>New Port for LAN</value> <value>پورت جدید برای LAN</value>
</data> </data>
<data name="TbSettingsTunMode" xml:space="preserve"> <data name="TbSettingsTunMode" xml:space="preserve">
<value>TunMode settings</value> <value>تنظیمات TunMode</value>
</data> </data>
<data name="TbSettingsTunModeDirectIP" xml:space="preserve"> <data name="TbSettingsTunModeDirectIP" xml:space="preserve">
<value>Direct IP CIDR, separated by commas (,)</value> <value>Direct IP CIDR, separated by commas (,)</value>
@@ -1060,4 +1060,10 @@
<data name="TbSettingsTunModeShowWindow" xml:space="preserve"> <data name="TbSettingsTunModeShowWindow" xml:space="preserve">
<value>نمایش کنسول</value> <value>نمایش کنسول</value>
</data> </data>
<data name="TbSettingsDefUserAgent" xml:space="preserve">
<value>User-Agent</value>
</data>
<data name="TbSettingsDefUserAgentTips" xml:space="preserve">
<value>This parameter is valid only for tcp/http and ws</value>
</data>
</root> </root>

View File

@@ -449,7 +449,7 @@
<value>Ungrouped</value> <value>Ungrouped</value>
</data> </data>
<data name="AllGroupServers" xml:space="preserve"> <data name="AllGroupServers" xml:space="preserve">
<value>All servers</value> <value>All</value>
</data> </data>
<data name="FillServerAddressCustom" xml:space="preserve"> <data name="FillServerAddressCustom" xml:space="preserve">
<value>Please browse to import server configuration</value> <value>Please browse to import server configuration</value>
@@ -548,7 +548,7 @@
<value>Dark Mode</value> <value>Dark Mode</value>
</data> </data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>Language</value> <value>Language(Restart)</value>
</data> </data>
<data name="menuAddServerViaClipboard" xml:space="preserve"> <data name="menuAddServerViaClipboard" xml:space="preserve">
<value>Import bulk URL from clipboard (Ctrl+V)</value> <value>Import bulk URL from clipboard (Ctrl+V)</value>
@@ -899,7 +899,7 @@
<value>Pac Mode</value> <value>Pac Mode</value>
</data> </data>
<data name="menuShareServer" xml:space="preserve"> <data name="menuShareServer" xml:space="preserve">
<value>Share Server (Ctrl+D)</value> <value>Share Server (Ctrl+F)</value>
</data> </data>
<data name="menuRouting" xml:space="preserve"> <data name="menuRouting" xml:space="preserve">
<value>Routing</value> <value>Routing</value>
@@ -1022,7 +1022,7 @@
<value>RouteOnly</value> <value>RouteOnly</value>
</data> </data>
<data name="menuMixedTestServer" xml:space="preserve"> <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>
<data name="LvTestDelay" xml:space="preserve"> <data name="LvTestDelay" xml:space="preserve">
<value>Delay(ms)</value> <value>Delay(ms)</value>
@@ -1060,4 +1060,70 @@
<data name="TbSettingsTunModeShowWindow" xml:space="preserve"> <data name="TbSettingsTunModeShowWindow" xml:space="preserve">
<value>Show console</value> <value>Show console</value>
</data> </data>
<data name="menuMoveToGroup" xml:space="preserve">
<value>Move to group</value>
</data>
<data name="TbSettingsTunModeCustomTemplate" xml:space="preserve">
<value>Custom Template</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>Enable Server Drag Drop Sort(Require restart)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>AutoRefresh</value>
</data>
<data name="SpeedtestingSkip" xml:space="preserve">
<value>Skip test</value>
</data>
<data name="menuEditServer" xml:space="preserve">
<value>Edit Server (Ctrl+D)</value>
</data>
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
<value>Double-click server make active</value>
</data>
<data name="SpeedtestingCompleted" xml:space="preserve">
<value>Test completed</value>
</data>
<data name="TbSettingsDefFingerprint" xml:space="preserve">
<value>Default TLS fingerprint</value>
</data>
<data name="TbSettingsDefUserAgent" xml:space="preserve">
<value>User-Agent</value>
</data>
<data name="TbSettingsDefUserAgentTips" xml:space="preserve">
<value>This parameter is valid only for tcp/http and ws</value>
</data>
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
<value>FontFamily(Require restart)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>Copy the font TTF file to the directory guiFonts, restart the settings</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>http port=socks port+1</value>
</data>
<data name="TbSettingsStartBootTip" xml:space="preserve">
<value>Set this with admin privileges, get admin privileges after startup</value>
</data>
<data name="TbSettingsFontSize" xml:space="preserve">
<value>FontSize</value>
</data>
<data name="TbSettingsTunModeProxyIP" xml:space="preserve">
<value>Proxy IP CIDR, separated by commas (,)</value>
</data>
<data name="TbSettingsTunModeProxyProcess" xml:space="preserve">
<value>Proxy Process name, separated by commas (,)</value>
</data>
<data name="TbSettingsTunModeBypassMode" xml:space="preserve">
<value>Bypass Mode</value>
</data>
<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> </root>

File diff suppressed because it is too large Load Diff

View File

@@ -449,7 +449,7 @@
<value>未分组服务器</value> <value>未分组服务器</value>
</data> </data>
<data name="AllGroupServers" xml:space="preserve"> <data name="AllGroupServers" xml:space="preserve">
<value>所有服务器</value> <value>所有</value>
</data> </data>
<data name="FillServerAddressCustom" xml:space="preserve"> <data name="FillServerAddressCustom" xml:space="preserve">
<value>请浏览导入服务器配置</value> <value>请浏览导入服务器配置</value>
@@ -548,7 +548,7 @@
<value>暗黑模式</value> <value>暗黑模式</value>
</data> </data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>语言</value> <value>语言(重启)</value>
</data> </data>
<data name="menuAddServerViaClipboard" xml:space="preserve"> <data name="menuAddServerViaClipboard" xml:space="preserve">
<value>从剪贴板导入批量URL (Ctrl+V)</value> <value>从剪贴板导入批量URL (Ctrl+V)</value>
@@ -851,7 +851,7 @@
<value>开机启动(可能会不成功)</value> <value>开机启动(可能会不成功)</value>
</data> </data>
<data name="TbSettingsStatistics" xml:space="preserve"> <data name="TbSettingsStatistics" xml:space="preserve">
<value>启用统计(实时网速显示,需重启)</value> <value>启用统计(实时网速显示,需重启)</value>
</data> </data>
<data name="TbSettingsStatisticsFreshRate" xml:space="preserve"> <data name="TbSettingsStatisticsFreshRate" xml:space="preserve">
<value>统计刷新频率(单位秒)</value> <value>统计刷新频率(单位秒)</value>
@@ -899,7 +899,7 @@
<value>Pac模式</value> <value>Pac模式</value>
</data> </data>
<data name="menuShareServer" xml:space="preserve"> <data name="menuShareServer" xml:space="preserve">
<value>分享服务器 (Ctrl+D)</value> <value>分享服务器 (Ctrl+F)</value>
</data> </data>
<data name="menuRouting" xml:space="preserve"> <data name="menuRouting" xml:space="preserve">
<value>路由</value> <value>路由</value>
@@ -1022,7 +1022,7 @@
<value>RouteOnly</value> <value>RouteOnly</value>
</data> </data>
<data name="menuMixedTestServer" xml:space="preserve"> <data name="menuMixedTestServer" xml:space="preserve">
<value>一键测试延迟和速度 (Ctrl+E)</value> <value>一键多线程测试延迟和速度 (Ctrl+E)</value>
</data> </data>
<data name="LvTestDelay" xml:space="preserve"> <data name="LvTestDelay" xml:space="preserve">
<value>延迟(ms)</value> <value>延迟(ms)</value>
@@ -1060,4 +1060,70 @@
<data name="TbSettingsTunModeShowWindow" xml:space="preserve"> <data name="TbSettingsTunModeShowWindow" xml:space="preserve">
<value>显示控制台</value> <value>显示控制台</value>
</data> </data>
<data name="menuMoveToGroup" xml:space="preserve">
<value>移至订阅分组</value>
</data>
<data name="TbSettingsTunModeCustomTemplate" xml:space="preserve">
<value>自定义配置模板</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>启用服务器拖放排序(需重启)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>自动刷新</value>
</data>
<data name="SpeedtestingSkip" xml:space="preserve">
<value>跳过测试</value>
</data>
<data name="menuEditServer" xml:space="preserve">
<value>编辑服务器 (Ctrl+D)</value>
</data>
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
<value>主界面双击设为活动服务器</value>
</data>
<data name="SpeedtestingCompleted" xml:space="preserve">
<value>测试完成</value>
</data>
<data name="TbSettingsDefFingerprint" xml:space="preserve">
<value>默认TLS指纹(fingerprint)</value>
</data>
<data name="TbSettingsDefUserAgent" xml:space="preserve">
<value>用户代理(User-Agent)</value>
</data>
<data name="TbSettingsDefUserAgentTips" xml:space="preserve">
<value>仅对tcp/http、ws协议生效</value>
</data>
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
<value>当前字体(需重启)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>拷贝字体TTF文件到目录guiFonts重启设置</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>http端口=socks端口+1</value>
</data>
<data name="TbSettingsStartBootTip" xml:space="preserve">
<value>以管理员权限设置此项,在启动后获得管理员权限</value>
</data>
<data name="TbSettingsFontSize" xml:space="preserve">
<value>字体大小</value>
</data>
<data name="TbSettingsTunModeProxyIP" xml:space="preserve">
<value>代理的IP CIDR用逗号(,)分隔</value>
</data>
<data name="TbSettingsTunModeProxyProcess" xml:space="preserve">
<value>代理的进程名,用逗号(,)分隔</value>
</data>
<data name="TbSettingsTunModeBypassMode" xml:space="preserve">
<value>绕行模式</value>
</data>
<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> </root>

View File

@@ -1 +1 @@
{"version":"1.1","method":"GET","path":[$requestPath$],"headers":{"Host":[$requestHost$],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36","Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"],"Accept-Encoding":["gzip, deflate"],"Connection":["keep-alive"],"Pragma":"no-cache"}} {"version":"1.1","method":"GET","path":[$requestPath$],"headers":{"Host":[$requestHost$],"User-Agent":[$requestUserAgent$],"Accept-Encoding":["gzip, deflate"],"Connection":["keep-alive"],"Pragma":"no-cache"}}

View File

@@ -1,10 +1,12 @@
{ {
"log": {
"disabled": false,
"level": "debug",
$log_output$
"timestamp": true
},
"dns": { "dns": {
"servers": [ "servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{ {
"tag": "local", "tag": "local",
"address": "223.5.5.5", "address": "223.5.5.5",
@@ -27,6 +29,7 @@
"inbounds": [ "inbounds": [
{ {
"type": "tun", "type": "tun",
"tag": "tun-in",
"interface_name": "singbox_tun", "interface_name": "singbox_tun",
"inet4_address": "172.19.0.1/30", "inet4_address": "172.19.0.1/30",
@@ -106,6 +109,9 @@
} }
$ruleDirectIPs$ $ruleDirectIPs$
$ruleDirectProcess$ $ruleDirectProcess$
$ruleProxyIPs$
$ruleProxyProcess$
$ruleFinally$
] ]
} }
} }

View File

@@ -1,4 +1,5 @@
using Microsoft.Win32; using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
@@ -601,17 +602,28 @@ namespace v2rayN
//delete first //delete first
RegWriteValue(Global.AutoRunRegPath, autoRunName, ""); RegWriteValue(Global.AutoRunRegPath, autoRunName, "");
if (IsAdministrator())
{
AutoStart(autoRunName, "", "");
}
if (run) if (run)
{ {
string exePath = $"\"{GetExePath()}\""; string exePath = $"\"{GetExePath()}\"";
RegWriteValue(Global.AutoRunRegPath, autoRunName, exePath); if (IsAdministrator())
{
AutoStart(autoRunName, exePath, "");
}
else
{
RegWriteValue(Global.AutoRunRegPath, autoRunName, exePath);
}
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
SaveLog(ex.Message, ex); SaveLog(ex.Message, ex);
} }
} }
/// <summary> /// <summary>
@@ -741,6 +753,51 @@ namespace v2rayN
} }
} }
/// <summary>
/// Auto Start via TaskService
/// </summary>
/// <param name="taskName"></param>
/// <param name="fileName"></param>
/// <param name="description"></param>
/// <exception cref="ArgumentNullException"></exception>
public static void AutoStart(string taskName, string fileName, string description)
{
if (string.IsNullOrEmpty(taskName))
{
return;
}
string TaskName = taskName;
var logonUser = WindowsIdentity.GetCurrent().Name;
string taskDescription = description;
string deamonFileName = fileName;
using (var taskService = new TaskService())
{
var tasks = taskService.RootFolder.GetTasks(new Regex(TaskName));
foreach (var t in tasks)
{
taskService.RootFolder.DeleteTask(t.Name);
}
if (string.IsNullOrEmpty(fileName))
{
return;
}
var task = taskService.NewTask();
task.RegistrationInfo.Description = taskDescription;
task.Settings.DisallowStartIfOnBatteries = false;
task.Settings.StopIfGoingOnBatteries = false;
task.Settings.RunOnlyIfIdle = false;
task.Settings.IdleSettings.StopOnIdleEnd = false;
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
task.Triggers.Add(new LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromMinutes(1) });
task.Principal.RunLevel = TaskRunLevel.Highest;
task.Actions.Add(new ExecAction(deamonFileName));
taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
}
}
#endregion #endregion
#region #region
@@ -1064,7 +1121,14 @@ namespace v2rayN
Directory.CreateDirectory(_tempPath); 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 = "") public static string GetLogPath(string filename = "")
{ {
@@ -1082,6 +1146,22 @@ namespace v2rayN
return Path.Combine(_tempPath, filename); return Path.Combine(_tempPath, filename);
} }
} }
public static string GetFontsPath(string filename = "")
{
string _tempPath = Path.Combine(StartupPath(), "guiFonts");
if (!Directory.Exists(_tempPath))
{
Directory.CreateDirectory(_tempPath);
}
if (string.IsNullOrEmpty(filename))
{
return _tempPath;
}
else
{
return Path.Combine(_tempPath, filename);
}
}
#endregion #endregion

View File

@@ -26,6 +26,7 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> BrowseServerCmd { get; } public ReactiveCommand<Unit, Unit> BrowseServerCmd { get; }
public ReactiveCommand<Unit, Unit> EditServerCmd { get; } public ReactiveCommand<Unit, Unit> EditServerCmd { get; }
public ReactiveCommand<Unit, Unit> SaveServerCmd { get; } public ReactiveCommand<Unit, Unit> SaveServerCmd { get; }
public bool IsModified { get; set; }
public AddServer2ViewModel(ProfileItem profileItem, Window view) public AddServer2ViewModel(ProfileItem profileItem, Window view)
{ {
@@ -86,6 +87,7 @@ namespace v2rayN.ViewModels
item.remarks = SelectedSource.remarks; item.remarks = SelectedSource.remarks;
item.address = SelectedSource.address; item.address = SelectedSource.address;
item.coreType = SelectedSource.coreType; item.coreType = SelectedSource.coreType;
item.displayLog = SelectedSource.displayLog;
item.preSocksPort = SelectedSource.preSocksPort; item.preSocksPort = SelectedSource.preSocksPort;
} }
@@ -127,7 +129,11 @@ namespace v2rayN.ViewModels
if (ConfigHandler.AddCustomServer(ref _config, item, false) == 0) if (ConfigHandler.AddCustomServer(ref _config, item, false) == 0)
{ {
_noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomServer); _noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomServer);
_view.DialogResult = true; if (!Utils.IsNullOrEmpty(item.indexId))
{
SelectedSource = Utils.DeepCopy(item);
}
IsModified = true;
} }
else else
{ {

View File

@@ -8,6 +8,7 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Drawing; using System.Drawing;
using System.IO;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text; using System.Text;
@@ -62,6 +63,8 @@ namespace v2rayN.ViewModels
[Reactive] [Reactive]
public SubItem SelectedSub { get; set; } public SubItem SelectedSub { get; set; }
[Reactive] [Reactive]
public SubItem SelectedMoveToGroup { get; set; }
[Reactive]
public RoutingItem SelectedRouting { get; set; } public RoutingItem SelectedRouting { get; set; }
[Reactive] [Reactive]
public ComboItem SelectedServer { get; set; } public ComboItem SelectedServer { get; set; }
@@ -81,12 +84,13 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; } public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; } public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
//servers delete //servers delete
public ReactiveCommand<Unit, Unit> EditServerCmd { get; }
public ReactiveCommand<Unit, Unit> RemoveServerCmd { get; } public ReactiveCommand<Unit, Unit> RemoveServerCmd { get; }
public ReactiveCommand<Unit, Unit> RemoveDuplicateServerCmd { get; } public ReactiveCommand<Unit, Unit> RemoveDuplicateServerCmd { get; }
public ReactiveCommand<Unit, Unit> CopyServerCmd { get; } public ReactiveCommand<Unit, Unit> CopyServerCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultServerCmd { get; } public ReactiveCommand<Unit, Unit> SetDefaultServerCmd { get; }
public ReactiveCommand<Unit, Unit> ShareServerCmd { get; } public ReactiveCommand<Unit, Unit> ShareServerCmd { get; }
//servers move //servers move
public ReactiveCommand<Unit, Unit> MoveTopCmd { get; } public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }
public ReactiveCommand<Unit, Unit> MoveUpCmd { get; } public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }
public ReactiveCommand<Unit, Unit> MoveDownCmd { get; } public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }
@@ -109,8 +113,8 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SubSettingCmd { get; } public ReactiveCommand<Unit, Unit> SubSettingCmd { get; }
public ReactiveCommand<Unit, Unit> AddSubCmd { get; } public ReactiveCommand<Unit, Unit> AddSubCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; } public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> SubGroupUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; } public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }
public ReactiveCommand<Unit, Unit> SubGroupUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> SubGroupUpdateViaProxyCmd { get; } public ReactiveCommand<Unit, Unit> SubGroupUpdateViaProxyCmd { get; }
//Setting //Setting
@@ -185,6 +189,8 @@ namespace v2rayN.ViewModels
public IObservableCollection<Swatch> Swatches => _swatches; public IObservableCollection<Swatch> Swatches => _swatches;
[Reactive] [Reactive]
public Swatch SelectedSwatch { get; set; } public Swatch SelectedSwatch { get; set; }
[Reactive]
public int CurrentFontSize { get; set; }
[Reactive] [Reactive]
public string CurrentLanguage { get; set; } public string CurrentLanguage { get; set; }
@@ -205,8 +211,13 @@ namespace v2rayN.ViewModels
SelectedProfile = new(); SelectedProfile = new();
SelectedSub = new(); SelectedSub = new();
SelectedMoveToGroup = new();
SelectedRouting = new(); SelectedRouting = new();
SelectedServer = new(); SelectedServer = new();
if (_config.tunModeItem.enableTun && Utils.IsAdministrator())
{
EnableTun = true;
}
//RefreshServers(); //RefreshServers();
InitSubscriptionView(); InitSubscriptionView();
@@ -220,6 +231,10 @@ namespace v2rayN.ViewModels
x => x.SelectedSub, x => x.SelectedSub,
y => y != null && !y.remarks.IsNullOrEmpty() && _subId != y.id) y => y != null && !y.remarks.IsNullOrEmpty() && _subId != y.id)
.Subscribe(c => SubSelectedChanged(c)); .Subscribe(c => SubSelectedChanged(c));
this.WhenAnyValue(
x => x.SelectedMoveToGroup,
y => y != null && !y.remarks.IsNullOrEmpty())
.Subscribe(c => MoveToGroup(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedRouting, x => x.SelectedRouting,
@@ -285,6 +300,10 @@ namespace v2rayN.ViewModels
return ScanScreenTaskAsync(); return ScanScreenTaskAsync();
}); });
//servers delete //servers delete
EditServerCmd = ReactiveCommand.Create(() =>
{
EditServer(false, EConfigType.Custom);
}, canEditRemove);
RemoveServerCmd = ReactiveCommand.Create(() => RemoveServerCmd = ReactiveCommand.Create(() =>
{ {
RemoveServer(); RemoveServer();
@@ -305,7 +324,7 @@ namespace v2rayN.ViewModels
{ {
ShareServer(); ShareServer();
}, canEditRemove); }, canEditRemove);
//servers move //servers move
MoveTopCmd = ReactiveCommand.Create(() => MoveTopCmd = ReactiveCommand.Create(() =>
{ {
MoveServer(EMove.Top); MoveServer(EMove.Top);
@@ -380,13 +399,13 @@ namespace v2rayN.ViewModels
{ {
UpdateSubscriptionProcess("", false); UpdateSubscriptionProcess("", false);
}); });
SubGroupUpdateCmd = ReactiveCommand.Create(() =>
{
UpdateSubscriptionProcess(_subId, true);
});
SubUpdateViaProxyCmd = ReactiveCommand.Create(() => SubUpdateViaProxyCmd = ReactiveCommand.Create(() =>
{ {
UpdateSubscriptionProcess("", false); UpdateSubscriptionProcess("", true);
});
SubGroupUpdateCmd = ReactiveCommand.Create(() =>
{
UpdateSubscriptionProcess(_subId, false);
}); });
SubGroupUpdateViaProxyCmd = ReactiveCommand.Create(() => SubGroupUpdateViaProxyCmd = ReactiveCommand.Create(() =>
{ {
@@ -487,7 +506,7 @@ namespace v2rayN.ViewModels
//MainFormHandler.Instance.BackupGuiNConfig(_config, true); //MainFormHandler.Instance.BackupGuiNConfig(_config, true);
_coreHandler = new CoreHandler(UpdateHandler); _coreHandler = new CoreHandler(UpdateHandler);
if (_config.enableStatistics) if (_config.guiItem.enableStatistics)
{ {
_statistics = new StatisticsHandler(_config, UpdateStatisticsHandler); _statistics = new StatisticsHandler(_config, UpdateStatisticsHandler);
} }
@@ -518,7 +537,12 @@ namespace v2rayN.ViewModels
_noticeHandler?.SendMessage(msg); _noticeHandler?.SendMessage(msg);
if (success) if (success)
{ {
RefreshServers();
Reload(); Reload();
if (_config.uiItem.enableAutoAdjustMainLvColWidth)
{
_updateView("AdjustMainLvColWidth");
}
} }
} }
private void UpdateStatisticsHandler(ServerSpeedItem update) private void UpdateStatisticsHandler(ServerSpeedItem update)
@@ -533,6 +557,33 @@ namespace v2rayN.ViewModels
} }
SpeedProxyDisplay = string.Format("{0}:{1}/s<><73> | {2}/s<><73>", Global.agentTag, Utils.HumanFy(update.proxyUp), Utils.HumanFy(update.proxyDown)); SpeedProxyDisplay = string.Format("{0}:{1}/s<><73> | {2}/s<><73>", Global.agentTag, Utils.HumanFy(update.proxyUp), Utils.HumanFy(update.proxyDown));
SpeedDirectDisplay = string.Format("{0}:{1}/s<><73> | {2}/s<><73>", Global.directTag, Utils.HumanFy(update.directUp), Utils.HumanFy(update.directDown)); SpeedDirectDisplay = string.Format("{0}:{1}/s<><73> | {2}/s<><73>", Global.directTag, Utils.HumanFy(update.directUp), Utils.HumanFy(update.directDown));
if (update.proxyUp + update.proxyDown > 0)
{
var second = DateTime.Now.Second;
if (second % 3 == 0)
{
var item = _profileItems.Where(it => it.indexId == update.indexId).FirstOrDefault();
if (item != null)
{
item.todayDown = Utils.HumanFy(update.todayDown);
item.todayUp = Utils.HumanFy(update.todayUp);
item.totalDown = Utils.HumanFy(update.totalDown);
item.totalUp = Utils.HumanFy(update.totalUp);
if (SelectedProfile?.indexId == item.indexId)
{
var temp = Utils.DeepCopy(item);
_profileItems.Replace(item, temp);
SelectedProfile = temp;
}
else
{
_profileItems.Replace(item, Utils.DeepCopy(item));
}
}
}
}
})); }));
} }
catch (Exception ex) catch (Exception ex)
@@ -551,7 +602,8 @@ namespace v2rayN.ViewModels
{ {
if (Utils.IsNullOrEmpty(indexId)) if (Utils.IsNullOrEmpty(indexId))
{ {
_noticeHandler?.SendMessage(delay); _noticeHandler?.SendMessage(delay, true);
_noticeHandler?.Enqueue(delay);
return; return;
} }
var item = _profileItems.Where(it => it.indexId == indexId).FirstOrDefault(); var item = _profileItems.Where(it => it.indexId == indexId).FirstOrDefault();
@@ -612,6 +664,7 @@ namespace v2rayN.ViewModels
SysProxyHandle.UpdateSysProxy(_config, true); SysProxyHandle.UpdateSysProxy(_config, true);
} }
_statistics?.SaveTo();
_statistics?.Close(); _statistics?.Close();
_coreHandler.CoreStop(); _coreHandler.CoreStop();
@@ -638,6 +691,8 @@ namespace v2rayN.ViewModels
_subId = SelectedSub?.id; _subId = SelectedSub?.id;
RefreshServers(); RefreshServers();
_updateView("ProfilesFocus");
} }
private void ServerFilterChanged(bool c) private void ServerFilterChanged(bool c)
@@ -655,10 +710,12 @@ namespace v2rayN.ViewModels
List<ProfileItemModel> lstModel = LazyConfig.Instance.ProfileItems(_subId, _serverFilter); List<ProfileItemModel> lstModel = LazyConfig.Instance.ProfileItems(_subId, _serverFilter);
_lstProfile = Utils.FromJson<List<ProfileItem>>(Utils.ToJson(lstModel)); _lstProfile = Utils.FromJson<List<ProfileItem>>(Utils.ToJson(lstModel));
ConfigHandler.SetDefaultServer(_config, _lstProfile);
List<ServerStatItem> lstServerStat = new(); List<ServerStatItem> lstServerStat = new();
if (_statistics != null && _statistics.Enable) if (_statistics != null && _statistics.Enable)
{ {
lstServerStat = LazyConfig.Instance.ServerStatItems(); lstServerStat = _statistics.ServerStat;
} }
lstModel = (from t in lstModel lstModel = (from t in lstModel
join t2 in lstServerStat join t2 in lstServerStat
@@ -675,25 +732,31 @@ namespace v2rayN.ViewModels
network = t.network, network = t.network,
streamSecurity = t.streamSecurity, streamSecurity = t.streamSecurity,
subRemarks = t.subRemarks, subRemarks = t.subRemarks,
isActive = t.isActive, isActive = t.indexId == _config.indexId,
delay = t.delay, delay = t.delay,
delayVal = t.delay > 0 ? $"{t.delay} {Global.DelayUnit}" : string.Empty, delayVal = t.delay != 0 ? $"{t.delay} {Global.DelayUnit}" : string.Empty,
speedVal = t.speed > 0 ? $"{t.speed} {Global.SpeedUnit}" : string.Empty, speedVal = t.speed != 0 ? $"{t.speed} {Global.SpeedUnit}" : string.Empty,
todayDown = t22 == null ? "" : Utils.HumanFy(t22.todayDown), todayDown = t22 == null ? "" : Utils.HumanFy(t22.todayDown),
todayUp = t22 == null ? "" : Utils.HumanFy(t22.todayUp), todayUp = t22 == null ? "" : Utils.HumanFy(t22.todayUp),
totalDown = t22 == null ? "" : Utils.HumanFy(t22.totalDown), totalDown = t22 == null ? "" : Utils.HumanFy(t22.totalDown),
totalUp = t22 == null ? "" : Utils.HumanFy(t22.totalUp) totalUp = t22 == null ? "" : Utils.HumanFy(t22.totalUp)
}).ToList(); }).ToList();
ConfigHandler.SetDefaultServer(_config, _lstProfile);
Application.Current.Dispatcher.Invoke((Action)(() => Application.Current.Dispatcher.Invoke((Action)(() =>
{ {
_profileItems.Clear(); _profileItems.Clear();
_profileItems.AddRange(lstModel); _profileItems.AddRange(lstModel);
if (lstModel.Count > 0) if (lstModel.Count > 0)
{ {
SelectedProfile = lstModel[0]; var selected = lstModel.FirstOrDefault(t => t.indexId == _config.indexId);
if (selected != null)
{
SelectedProfile = selected;
}
else
{
SelectedProfile = lstModel[0];
}
} }
RefreshServersMenu(); RefreshServersMenu();
@@ -710,7 +773,7 @@ namespace v2rayN.ViewModels
private void RefreshServersMenu() private void RefreshServersMenu()
{ {
_servers.Clear(); _servers.Clear();
if (_lstProfile.Count > _config.trayMenuServersLimit) if (_lstProfile.Count > _config.guiItem.trayMenuServersLimit)
{ {
return; return;
} }
@@ -747,7 +810,7 @@ namespace v2rayN.ViewModels
private int GetProfileItems(out List<ProfileItem> lstSelecteds) private int GetProfileItems(out List<ProfileItem> lstSelecteds)
{ {
lstSelecteds = new List<ProfileItem>(); lstSelecteds = new List<ProfileItem>();
if (SelectedProfiles == null && SelectedProfiles.Count() <= 0) if (SelectedProfiles == null || SelectedProfiles.Count() <= 0)
{ {
return -1; return -1;
} }
@@ -771,6 +834,7 @@ namespace v2rayN.ViewModels
{ {
subid = _subId, subid = _subId,
configType = eConfigType, configType = eConfigType,
displayLog = false
}; };
} }
else else
@@ -852,12 +916,16 @@ namespace v2rayN.ViewModels
{ {
return; return;
} }
var exists = lstSelecteds.Exists(t => t.indexId == _config.indexId);
ConfigHandler.RemoveServer(_config, lstSelecteds); ConfigHandler.RemoveServer(_config, lstSelecteds);
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
RefreshServers(); RefreshServers();
Reload(); if (exists)
{
Reload();
}
} }
private void RemoveDuplicateServer() private void RemoveDuplicateServer()
@@ -883,7 +951,7 @@ namespace v2rayN.ViewModels
public void SetDefaultServer() public void SetDefaultServer()
{ {
if (Utils.IsNullOrEmpty(SelectedProfile.indexId)) if (Utils.IsNullOrEmpty(SelectedProfile?.indexId))
{ {
return; return;
} }
@@ -982,7 +1050,7 @@ namespace v2rayN.ViewModels
} }
(new UpdateHandle()).RunAvailabilityCheck((bool success, string msg) => (new UpdateHandle()).RunAvailabilityCheck((bool success, string msg) =>
{ {
_noticeHandler?.SendMessage(msg); _noticeHandler?.SendMessage(msg, true);
Application.Current.Dispatcher.Invoke((Action)(() => Application.Current.Dispatcher.Invoke((Action)(() =>
{ {
if (!Global.ShowInTaskbar) if (!Global.ShowInTaskbar)
@@ -995,6 +1063,26 @@ namespace v2rayN.ViewModels
} }
//move server //move server
private void MoveToGroup(bool c)
{
if (!c)
{
return;
}
if (GetProfileItems(out List<ProfileItem> lstSelecteds) < 0)
{
return;
}
ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.id);
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
RefreshServers();
SelectedMoveToGroup = new();
//Reload();
}
public void MoveServer(EMove eMove) public void MoveServer(EMove eMove)
{ {
var item = _lstProfile.FirstOrDefault(t => t.indexId == SelectedProfile.indexId); var item = _lstProfile.FirstOrDefault(t => t.indexId == SelectedProfile.indexId);
@@ -1015,6 +1103,17 @@ namespace v2rayN.ViewModels
} }
} }
public void MoveServerTo(int startIndex, ProfileItemModel targetItem)
{
var targetIndex = _profileItems.IndexOf(targetItem);
if (startIndex >= 0 && targetIndex >= 0 && startIndex != targetIndex)
{
if (ConfigHandler.MoveServer(ref _config, ref _lstProfile, startIndex, EMove.Position, targetIndex) == 0)
{
RefreshServers();
}
}
}
public void ServerSpeedtest(ESpeedActionType actionType) public void ServerSpeedtest(ESpeedActionType actionType)
{ {
@@ -1027,7 +1126,7 @@ namespace v2rayN.ViewModels
return; return;
} }
//ClearTestResult(); //ClearTestResult();
SpeedtestHandler statistics = new SpeedtestHandler(_config, _coreHandler, lstSelecteds, actionType, UpdateSpeedtestHandler); new SpeedtestHandler(_config, _coreHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);
} }
private void Export2ClientConfig() private void Export2ClientConfig()
@@ -1073,7 +1172,7 @@ namespace v2rayN.ViewModels
if (sb.Length > 0) if (sb.Length > 0)
{ {
Utils.SetClipboardData(sb.ToString()); Utils.SetClipboardData(sb.ToString());
_noticeHandler?.Enqueue(ResUI.BatchExportURLSuccessfully); _noticeHandler?.SendMessage(ResUI.BatchExportURLSuccessfully);
} }
} }
@@ -1098,7 +1197,7 @@ namespace v2rayN.ViewModels
if (sb.Length > 0) if (sb.Length > 0)
{ {
Utils.SetClipboardData(Utils.Base64Encode(sb.ToString())); Utils.SetClipboardData(Utils.Base64Encode(sb.ToString()));
_noticeHandler?.Enqueue(ResUI.BatchExportSubscriptionSuccessfully); _noticeHandler?.SendMessage(ResUI.BatchExportSubscriptionSuccessfully);
} }
} }
@@ -1127,20 +1226,7 @@ namespace v2rayN.ViewModels
private void UpdateSubscriptionProcess(string subId, bool blProxy) private void UpdateSubscriptionProcess(string subId, bool blProxy)
{ {
void _updateUI(bool success, string msg) (new UpdateHandle()).UpdateSubscriptionProcess(_config, subId, blProxy, UpdateTaskHandler);
{
_noticeHandler?.SendMessage(msg);
if (success)
{
RefreshServers();
if (_config.uiItem.enableAutoAdjustMainLvColWidth)
{
_updateView("AdjustMainLvColWidth");
}
}
};
(new UpdateHandle()).UpdateSubscriptionProcess(_config, subId, blProxy, _updateUI);
} }
#endregion #endregion
@@ -1215,7 +1301,7 @@ namespace v2rayN.ViewModels
MyAppExit(false); MyAppExit(false);
} }
}; };
(new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI, _config.checkPreReleaseUpdate); (new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI, _config.guiItem.checkPreReleaseUpdate);
} }
private void CheckUpdateCore(ECoreType type) private void CheckUpdateCore(ECoreType type)
@@ -1230,16 +1316,21 @@ namespace v2rayN.ViewModels
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(msg)); string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(msg));
string toPath = Utils.GetBinPath("", type); string toPath = Utils.GetBinPath("", type);
FileManager.ZipExtractToFile(fileName, toPath, _config.ignoreGeoUpdateCore ? "geo" : ""); FileManager.ZipExtractToFile(fileName, toPath, _config.guiItem.ignoreGeoUpdateCore ? "geo" : "");
_noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfullyMore); _noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
Reload(); Reload();
_noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfully); _noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfully);
if (File.Exists(fileName))
{
File.Delete(fileName);
}
} }
}; };
(new UpdateHandle()).CheckUpdateCore(type, _config, _updateUI, _config.checkPreReleaseUpdate); (new UpdateHandle()).CheckUpdateCore(type, _config, _updateUI, _config.guiItem.checkPreReleaseUpdate);
} }
private void CheckUpdateGeo() private void CheckUpdateGeo()
@@ -1343,7 +1434,7 @@ namespace v2rayN.ViewModels
private void RefreshRoutingsMenu() private void RefreshRoutingsMenu()
{ {
_routingItems.Clear(); _routingItems.Clear();
if (!_config.enableRoutingAdvanced) if (!_config.routingBasicItem.enableRoutingAdvanced)
{ {
BlRouting = false; BlRouting = false;
return; return;
@@ -1354,7 +1445,7 @@ namespace v2rayN.ViewModels
foreach (var item in routings) foreach (var item in routings)
{ {
_routingItems.Add(item); _routingItems.Add(item);
if (item.id.Equals(_config.routingIndexId)) if (item.id.Equals(_config.routingBasicItem.routingIndexId))
{ {
SelectedRouting = item; SelectedRouting = item;
} }
@@ -1378,7 +1469,7 @@ namespace v2rayN.ViewModels
{ {
return; return;
} }
if (_config.routingIndexId == item.id) if (_config.routingBasicItem.routingIndexId == item.id)
{ {
return; return;
} }
@@ -1479,6 +1570,7 @@ namespace v2rayN.ViewModels
{ {
SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.uiItem.colorPrimaryName); SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.uiItem.colorPrimaryName);
} }
CurrentFontSize = _config.uiItem.currentFontSize;
CurrentLanguage = _config.uiItem.currentLanguage; CurrentLanguage = _config.uiItem.currentLanguage;
this.WhenAnyValue( this.WhenAnyValue(
@@ -1514,6 +1606,24 @@ namespace v2rayN.ViewModels
} }
}); });
this.WhenAnyValue(
x => x.CurrentFontSize,
y => y > 0)
.Subscribe(c =>
{
if (CurrentFontSize >= Global.MinFontSize)
{
_config.uiItem.currentFontSize = CurrentFontSize;
double size = (long)CurrentFontSize;
Application.Current.Resources["StdFontSize"] = size;
Application.Current.Resources["StdFontSize1"] = size + 1;
Application.Current.Resources["StdFontSize2"] = size + 2;
Application.Current.Resources["StdFontSizeMsg"] = size - 1;
ConfigHandler.SaveConfig(ref _config);
}
});
this.WhenAnyValue( this.WhenAnyValue(
x => x.CurrentLanguage, x => x.CurrentLanguage,
y => y != null && !y.IsNullOrEmpty()) y => y != null && !y.IsNullOrEmpty())
@@ -1586,7 +1696,7 @@ namespace v2rayN.ViewModels
private void AutoHideStartup() private void AutoHideStartup()
{ {
if (_config.autoHideStartup) if (_config.uiItem.autoHideStartup)
{ {
Observable.Range(1, 1) Observable.Range(1, 1)
.Delay(TimeSpan.FromSeconds(1)) .Delay(TimeSpan.FromSeconds(1))

View File

@@ -28,6 +28,8 @@ namespace v2rayN.ViewModels
[Reactive] public bool logEnabled { get; set; } [Reactive] public bool logEnabled { get; set; }
[Reactive] public string loglevel { get; set; } [Reactive] public string loglevel { get; set; }
[Reactive] public bool defAllowInsecure { get; set; } [Reactive] public bool defAllowInsecure { get; set; }
[Reactive] public string defFingerprint { get; set; }
[Reactive] public string defUserAgent { get; set; }
#endregion #endregion
#region Core DNS #region Core DNS
@@ -55,9 +57,15 @@ namespace v2rayN.ViewModels
[Reactive] public bool EnableSecurityProtocolTls13 { get; set; } [Reactive] public bool EnableSecurityProtocolTls13 { get; set; }
[Reactive] public bool AutoHideStartup { get; set; } [Reactive] public bool AutoHideStartup { get; set; }
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; } [Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
[Reactive] public bool EnableDragDropSort { get; set; }
[Reactive] public bool DoubleClick2Activate { get; set; }
[Reactive] public int autoUpdateInterval { get; set; } [Reactive] public int autoUpdateInterval { get; set; }
[Reactive] public int autoUpdateSubInterval { get; set; } [Reactive] public int autoUpdateSubInterval { get; set; }
[Reactive] public int trayMenuServersLimit { 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 #endregion
#region System proxy #region System proxy
@@ -70,8 +78,13 @@ namespace v2rayN.ViewModels
[Reactive] public bool TunStrictRoute { get; set; } [Reactive] public bool TunStrictRoute { get; set; }
[Reactive] public string TunStack { get; set; } [Reactive] public string TunStack { get; set; }
[Reactive] public int TunMtu { get; set; } [Reactive] public int TunMtu { get; set; }
[Reactive] public string TunCustomTemplate { get; set; }
[Reactive] public bool TunBypassMode { get; set; }
[Reactive] public bool TunBypassMode2 { get; set; }
[Reactive] public string TunDirectIP { get; set; } [Reactive] public string TunDirectIP { get; set; }
[Reactive] public string TunDirectProcess { get; set; } [Reactive] public string TunDirectProcess { get; set; }
[Reactive] public string TunProxyIP { get; set; }
[Reactive] public string TunProxyProcess { get; set; }
#endregion #endregion
#region CoreType #region CoreType
@@ -103,10 +116,12 @@ namespace v2rayN.ViewModels
newPort4LAN = inbound.newPort4LAN; newPort4LAN = inbound.newPort4LAN;
user = inbound.user; user = inbound.user;
pass = inbound.pass; pass = inbound.pass;
muxEnabled = _config.muxEnabled; muxEnabled = _config.coreBasicItem.muxEnabled;
logEnabled = _config.logEnabled; logEnabled = _config.coreBasicItem.logEnabled;
loglevel = _config.loglevel; loglevel = _config.coreBasicItem.loglevel;
defAllowInsecure = _config.defAllowInsecure; defAllowInsecure = _config.coreBasicItem.defAllowInsecure;
defFingerprint = _config.coreBasicItem.defFingerprint;
defUserAgent = _config.coreBasicItem.defUserAgent;
#endregion #endregion
#region Core DNS #region Core DNS
@@ -125,18 +140,24 @@ namespace v2rayN.ViewModels
#endregion #endregion
#region UI #region UI
AutoRun = _config.autoRun; AutoRun = _config.guiItem.autoRun;
EnableStatistics = _config.enableStatistics; EnableStatistics = _config.guiItem.enableStatistics;
StatisticsFreshRate = _config.statisticsFreshRate; StatisticsFreshRate = _config.guiItem.statisticsFreshRate;
KeepOlderDedupl = _config.keepOlderDedupl; KeepOlderDedupl = _config.guiItem.keepOlderDedupl;
IgnoreGeoUpdateCore = _config.ignoreGeoUpdateCore; IgnoreGeoUpdateCore = _config.guiItem.ignoreGeoUpdateCore;
EnableAutoAdjustMainLvColWidth = _config.uiItem.enableAutoAdjustMainLvColWidth; EnableAutoAdjustMainLvColWidth = _config.uiItem.enableAutoAdjustMainLvColWidth;
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13; EnableSecurityProtocolTls13 = _config.guiItem.enableSecurityProtocolTls13;
AutoHideStartup = _config.autoHideStartup; AutoHideStartup = _config.uiItem.autoHideStartup;
EnableCheckPreReleaseUpdate = _config.checkPreReleaseUpdate; EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate;
autoUpdateInterval = _config.autoUpdateInterval; EnableDragDropSort = _config.uiItem.enableDragDropSort;
autoUpdateSubInterval = _config.autoUpdateSubInterval; DoubleClick2Activate = _config.uiItem.doubleClick2Activate;
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 #endregion
#region System proxy #region System proxy
@@ -150,8 +171,15 @@ namespace v2rayN.ViewModels
TunStrictRoute = _config.tunModeItem.strictRoute; TunStrictRoute = _config.tunModeItem.strictRoute;
TunStack = _config.tunModeItem.stack; TunStack = _config.tunModeItem.stack;
TunMtu = _config.tunModeItem.mtu; TunMtu = _config.tunModeItem.mtu;
TunCustomTemplate = _config.tunModeItem.customTemplate;
TunBypassMode = _config.tunModeItem.bypassMode;
TunDirectIP = Utils.List2String(_config.tunModeItem.directIP, true); TunDirectIP = Utils.List2String(_config.tunModeItem.directIP, true);
TunDirectProcess = Utils.List2String(_config.tunModeItem.directProcess, true); TunDirectProcess = Utils.List2String(_config.tunModeItem.directProcess, true);
TunProxyIP = Utils.List2String(_config.tunModeItem.proxyIP, true);
TunProxyProcess = Utils.List2String(_config.tunModeItem.proxyProcess, true);
this.WhenAnyValue(
x => x.TunBypassMode)
.Subscribe(c => TunBypassMode2 = !TunBypassMode);
#endregion #endregion
@@ -259,10 +287,12 @@ namespace v2rayN.ViewModels
{ {
_config.inbound.RemoveAt(1); _config.inbound.RemoveAt(1);
} }
_config.logEnabled = logEnabled; _config.coreBasicItem.logEnabled = logEnabled;
_config.loglevel = loglevel; _config.coreBasicItem.loglevel = loglevel;
_config.muxEnabled = muxEnabled; _config.coreBasicItem.muxEnabled = muxEnabled;
_config.defAllowInsecure = defAllowInsecure; _config.coreBasicItem.defAllowInsecure = defAllowInsecure;
_config.coreBasicItem.defFingerprint = defFingerprint;
_config.coreBasicItem.defUserAgent = defUserAgent;
//DNS //DNS
@@ -282,22 +312,27 @@ namespace v2rayN.ViewModels
//UI //UI
Utils.SetAutoRun(AutoRun); Utils.SetAutoRun(AutoRun);
_config.autoRun = AutoRun; _config.guiItem.autoRun = AutoRun;
_config.enableStatistics = EnableStatistics; _config.guiItem.enableStatistics = EnableStatistics;
_config.statisticsFreshRate = StatisticsFreshRate; _config.guiItem.statisticsFreshRate = StatisticsFreshRate;
if (_config.statisticsFreshRate > 100 || _config.statisticsFreshRate < 1) if (_config.guiItem.statisticsFreshRate > 100 || _config.guiItem.statisticsFreshRate < 1)
{ {
_config.statisticsFreshRate = 1; _config.guiItem.statisticsFreshRate = 1;
} }
_config.keepOlderDedupl = KeepOlderDedupl; _config.guiItem.keepOlderDedupl = KeepOlderDedupl;
_config.ignoreGeoUpdateCore = IgnoreGeoUpdateCore; _config.guiItem.ignoreGeoUpdateCore = IgnoreGeoUpdateCore;
_config.uiItem.enableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth; _config.uiItem.enableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth;
_config.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13; _config.guiItem.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
_config.autoHideStartup = AutoHideStartup; _config.uiItem.autoHideStartup = AutoHideStartup;
_config.autoUpdateInterval = autoUpdateInterval; _config.guiItem.autoUpdateInterval = autoUpdateInterval;
_config.autoUpdateSubInterval = autoUpdateSubInterval; _config.guiItem.autoUpdateSubInterval = autoUpdateSubInterval;
_config.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate; _config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
_config.trayMenuServersLimit = trayMenuServersLimit; _config.uiItem.enableDragDropSort = EnableDragDropSort;
_config.uiItem.doubleClick2Activate = DoubleClick2Activate;
_config.guiItem.trayMenuServersLimit = trayMenuServersLimit;
_config.uiItem.currentFontFamily = currentFontFamily;
_config.speedTestItem.speedTestTimeout = SpeedTestTimeout;
_config.speedTestItem.speedTestUrl = SpeedTestUrl;
//systemProxy //systemProxy
_config.systemProxyExceptions = systemProxyExceptions; _config.systemProxyExceptions = systemProxyExceptions;
@@ -308,8 +343,12 @@ namespace v2rayN.ViewModels
_config.tunModeItem.strictRoute = TunStrictRoute; _config.tunModeItem.strictRoute = TunStrictRoute;
_config.tunModeItem.stack = TunStack; _config.tunModeItem.stack = TunStack;
_config.tunModeItem.mtu = TunMtu; _config.tunModeItem.mtu = TunMtu;
_config.tunModeItem.customTemplate = TunCustomTemplate;
_config.tunModeItem.bypassMode = TunBypassMode;
_config.tunModeItem.directIP = Utils.String2List(TunDirectIP); _config.tunModeItem.directIP = Utils.String2List(TunDirectIP);
_config.tunModeItem.directProcess = Utils.String2List(TunDirectProcess); _config.tunModeItem.directProcess = Utils.String2List(TunDirectProcess);
_config.tunModeItem.proxyIP = Utils.String2List(TunProxyIP);
_config.tunModeItem.proxyProcess = Utils.String2List(TunProxyProcess);
//coreType //coreType
SaveCoreType(); SaveCoreType();

View File

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

View File

@@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Views="clr-namespace:v2rayN.Views" xmlns:Views="clr-namespace:v2rayN.Views"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:v2rayN" xmlns:local="clr-namespace:v2rayN"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
@@ -15,7 +16,9 @@
Height="500" Height="500"
x:TypeArguments="vms:AddServer2ViewModel" x:TypeArguments="vms:AddServer2ViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -70,7 +73,7 @@
Margin="4" Margin="4"
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -88,7 +91,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<StackPanel <StackPanel
Grid.Row="2" Grid.Row="2"
Grid.Column="2" Grid.Column="2"
@@ -122,6 +125,7 @@
Width="200" Width="200"
Margin="4" Margin="4"
HorizontalAlignment="Left" HorizontalAlignment="Left"
FontSize="{DynamicResource StdFontSize}"
MaxDropDownHeight="1000" MaxDropDownHeight="1000"
Style="{StaticResource MaterialDesignOutlinedComboBox}" /> Style="{StaticResource MaterialDesignOutlinedComboBox}" />
@@ -154,7 +158,7 @@
Margin="4" Margin="4"
HorizontalAlignment="Left" HorizontalAlignment="Left"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<StackPanel <StackPanel
Grid.Row="6" Grid.Row="6"
Grid.Column="1" Grid.Column="1"

View File

@@ -44,7 +44,14 @@ namespace v2rayN.Views
} }
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e) private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
{ {
this.Close(); if (ViewModel?.IsModified == true)
{
this.DialogResult = true;
}
else
{
this.Close();
}
} }
} }

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.AddServerWindow" x:Class="v2rayN.Views.AddServerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="800" Height="800"
x:TypeArguments="vms:AddServerViewModel" x:TypeArguments="vms:AddServerViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -80,7 +83,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -94,7 +98,8 @@
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
@@ -109,7 +114,8 @@
Grid.Column="1" Grid.Column="1"
Width="100" Width="100"
Margin="{StaticResource ServerItemMargin}" Margin="{StaticResource ServerItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
</Grid> </Grid>
<Separator <Separator
@@ -145,7 +151,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<Button <Button
x:Name="btnGUID" x:Name="btnGUID"
Grid.Row="1" Grid.Row="1"
@@ -168,7 +175,8 @@
Grid.Column="1" Grid.Column="1"
Width="100" Width="100"
Margin="{StaticResource ServerItemMargin}" Margin="{StaticResource ServerItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
@@ -213,7 +221,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -258,7 +267,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -272,7 +282,8 @@
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
</Grid> </Grid>
<Grid <Grid
@@ -303,7 +314,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<Button <Button
x:Name="btnGUID5" x:Name="btnGUID5"
Grid.Row="1" Grid.Row="1"
@@ -341,7 +353,8 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource ServerItemMargin}" Margin="{StaticResource ServerItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
</Grid> </Grid>
<Grid <Grid
x:Name="gridTrojan" x:Name="gridTrojan"
@@ -370,7 +383,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -475,7 +489,8 @@
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
x:Name="tipRequestHost" x:Name="tipRequestHost"
Grid.Row="3" Grid.Row="3"
@@ -497,7 +512,8 @@
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" /> Margin="{StaticResource ServerItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
x:Name="tipPath" x:Name="tipPath"
Grid.Row="4" Grid.Row="4"
@@ -569,7 +585,8 @@
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource ServerItemMargin}" Margin="{StaticResource ServerItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -599,6 +616,7 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource ServerItemMargin}" Margin="{StaticResource ServerItemMargin}"
IsEditable="True"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock

View File

@@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Views="clr-namespace:v2rayN.Views" xmlns:Views="clr-namespace:v2rayN.Views"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -14,8 +15,10 @@
Height="500" Height="500"
x:TypeArguments="vms:SubEditViewModel" x:TypeArguments="vms:SubEditViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
KeyDown="GlobalHotkeySettingWindow_KeyDown" KeyDown="GlobalHotkeySettingWindow_KeyDown"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -68,7 +71,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -85,7 +88,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
@@ -102,7 +105,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
Grid.Column="0" Grid.Column="0"
@@ -118,7 +121,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="5" Grid.Row="5"
Grid.Column="0" Grid.Column="0"
@@ -134,7 +137,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
</Grid> </Grid>
<TextBlock <TextBlock

View File

@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:v2rayN.Base" xmlns:base="clr-namespace:v2rayN.Base"
xmlns:converters="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:v2rayN.Views" xmlns:local="clr-namespace:v2rayN.Views"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
@@ -19,7 +19,9 @@
MinHeight="600" MinHeight="600"
x:TypeArguments="vms:MainWindowViewModel" x:TypeArguments="vms:MainWindowViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ShowInTaskbar="True" ShowInTaskbar="True"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -31,7 +33,7 @@
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
<converters:DelayColorConverter x:Key="DelayColorConverter" /> <conv:DelayColorConverter x:Key="DelayColorConverter" />
</ResourceDictionary> </ResourceDictionary>
</Window.Resources> </Window.Resources>
@@ -47,7 +49,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
ClipToBounds="True" ClipToBounds="True"
Style="{StaticResource MaterialDesignToolBar}"> Style="{StaticResource MaterialDesignToolBar}">
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0"> <MenuItem Padding="8,0">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -93,7 +95,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0"> <MenuItem Padding="8,0">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -125,7 +127,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0"> <MenuItem Padding="8,0">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -163,7 +165,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem x:Name="menuReload" Padding="8,0"> <MenuItem x:Name="menuReload" Padding="8,0">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -174,7 +176,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0"> <MenuItem Padding="8,0">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -215,7 +217,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem x:Name="menuHelp" Padding="8,0"> <MenuItem x:Name="menuHelp" Padding="8,0">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -226,7 +228,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem <MenuItem
x:Name="menuPromotion" x:Name="menuPromotion"
Padding="8,0" Padding="8,0"
@@ -240,7 +242,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<Menu Margin="0,8" Style="{StaticResource ToolbarMenu}"> <Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem <MenuItem
x:Name="menuClose" x:Name="menuClose"
Padding="8,0" Padding="8,0"
@@ -259,37 +261,74 @@
HorizontalAlignment="Right" HorizontalAlignment="Right"
Style="{StaticResource MaterialDesignToolForegroundPopupBox}"> Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
<StackPanel Margin="8"> <StackPanel Margin="8">
<StackPanel Orientation="Horizontal"> <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsColorMode}" /> Text="{x:Static resx:ResUI.TbSettingsColorMode}" />
<ToggleButton x:Name="togDarkMode" Margin="8" /> <ToggleButton
</StackPanel> x:Name="togDarkMode"
<StackPanel Orientation="Horizontal"> Grid.Row="0"
Grid.Column="1"
Margin="8" />
<TextBlock <TextBlock
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsColor}" /> Text="{x:Static resx:ResUI.TbSettingsColor}" />
<ComboBox <ComboBox
x:Name="cmbSwatches" x:Name="cmbSwatches"
Grid.Row="1"
Grid.Column="1"
Width="100" Width="100"
Margin="8" Margin="8"
DisplayMemberPath="Name" DisplayMemberPath="Name"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock <TextBlock
Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsFontSize}" />
<ComboBox
x:Name="cmbCurrentFontSize"
Grid.Row="2"
Grid.Column="1"
Width="100"
Margin="8"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsLanguage}" /> Text="{x:Static resx:ResUI.TbSettingsLanguage}" />
<ComboBox <ComboBox
x:Name="cmbCurrentLanguage" x:Name="cmbCurrentLanguage"
Grid.Row="3"
Grid.Column="1"
Width="100" Width="100"
Margin="8" Margin="8"
materialDesign:HintAssist.Hint="Language" materialDesign:HintAssist.Hint="Language"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
</StackPanel>
</Grid>
</StackPanel> </StackPanel>
</materialDesign:PopupBox> </materialDesign:PopupBox>
</ToolBar> </ToolBar>
@@ -300,7 +339,11 @@
VerticalAlignment="Center" VerticalAlignment="Center"
ClipToBounds="True" ClipToBounds="True"
Style="{StaticResource MaterialDesignToolBar}"> 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> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding remarks}" /> <TextBlock Text="{Binding remarks}" />
@@ -311,17 +354,18 @@
x:Name="btnAddSub" x:Name="btnAddSub"
Width="30" Width="30"
Height="30" Height="30"
Margin="8,0" Margin="4,0"
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"> Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}">
<materialDesign:PackIcon Kind="Plus" /> <materialDesign:PackIcon Kind="Plus" />
</Button> </Button>
<Separator /> <Separator />
<TextBox <TextBox
x:Name="txtServerFilter" x:Name="txtServerFilter"
Width="200" Width="100"
Margin="8,0" Margin="4,0"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
materialDesign:TextFieldAssist.HasClearButton="True" /> materialDesign:TextFieldAssist.HasClearButton="True"
Style="{StaticResource DefTextBox}" />
</ToolBar> </ToolBar>
</ToolBarTray> </ToolBarTray>
@@ -350,11 +394,12 @@
</StackPanel> </StackPanel>
<StackPanel <StackPanel
x:Name="spEnableTun"
Width="auto" Width="auto"
Margin="8,0" Margin="8,0"
VerticalAlignment="Center" VerticalAlignment="Center"
DockPanel.Dock="Left"> DockPanel.Dock="Left">
<TextBlock x:Name="txtEnableTun" Text="{x:Static resx:ResUI.TbEnableTunAs}" /> <TextBlock Text="{x:Static resx:ResUI.TbEnableTunAs}" />
<ToggleButton <ToggleButton
x:Name="togEnableTun" x:Name="togEnableTun"
Margin="4" Margin="4"
@@ -371,6 +416,7 @@
Width="120" Width="120"
Margin="8,0" Margin="8,0"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFloatingHintComboBox}"> Style="{StaticResource MaterialDesignFloatingHintComboBox}">
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" /> <ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" /> <ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
@@ -384,6 +430,7 @@
Margin="8,0" Margin="8,0"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="remarks" DisplayMemberPath="remarks"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFloatingHintComboBox}" /> Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
</StackPanel> </StackPanel>
@@ -401,7 +448,7 @@
</DockPanel> </DockPanel>
</materialDesign:ColorZone> </materialDesign:ColorZone>
<Grid> <Grid x:Name="gridMain">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="1*" /> <RowDefinition Height="1*" />
<RowDefinition Height="10" /> <RowDefinition Height="10" />
@@ -410,7 +457,7 @@
<DataGrid <DataGrid
x:Name="lstProfiles" x:Name="lstProfiles"
Grid.Row="0" Grid.Row="0"
materialDesign:DataGridAssist.CellPadding="1,0" materialDesign:DataGridAssist.CellPadding="2,2"
AutoGenerateColumns="False" AutoGenerateColumns="False"
BorderThickness="1" BorderThickness="1"
CanUserAddRows="False" CanUserAddRows="False"
@@ -430,6 +477,10 @@
</DataGrid.InputBindings> </DataGrid.InputBindings>
<DataGrid.ContextMenu> <DataGrid.ContextMenu>
<ContextMenu Style="{StaticResource DefContextMenu}"> <ContextMenu Style="{StaticResource DefContextMenu}">
<MenuItem
x:Name="menuEditServer"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuEditServer}" />
<MenuItem <MenuItem
x:Name="menuSetDefaultServer" x:Name="menuSetDefaultServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
@@ -451,28 +502,6 @@
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuShareServer}" /> Header="{x:Static resx:ResUI.menuShareServer}" />
<Separator /> <Separator />
<MenuItem
x:Name="menuMoveTop"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveTop}" />
<MenuItem
x:Name="menuMoveUp"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveUp}" />
<MenuItem
x:Name="menuMoveDown"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveDown}" />
<MenuItem
x:Name="menuMoveBottom"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveBottom}" />
<MenuItem
x:Name="menuSelectAll"
Height="{StaticResource MenuItemHeight}"
Click="menuSelectAll_Click"
Header="{x:Static resx:ResUI.menuSelectAll}" />
<Separator />
<MenuItem <MenuItem
x:Name="menuMixedTestServer" x:Name="menuMixedTestServer"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
@@ -498,6 +527,46 @@
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSortServerResult}" /> Header="{x:Static resx:ResUI.menuSortServerResult}" />
<Separator /> <Separator />
<MenuItem
x:Name="menuMoveToGroup"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveToGroup}">
<MenuItem Height="Auto">
<MenuItem.Header>
<DockPanel>
<ComboBox
x:Name="cmbMoveToGroup"
Width="200"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSubscription}"
DisplayMemberPath="remarks"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" />
</DockPanel>
</MenuItem.Header>
</MenuItem>
</MenuItem>
<MenuItem
x:Name="menuMoveTop"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveTop}" />
<MenuItem
x:Name="menuMoveUp"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveUp}" />
<MenuItem
x:Name="menuMoveDown"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveDown}" />
<MenuItem
x:Name="menuMoveBottom"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuMoveBottom}" />
<MenuItem
x:Name="menuSelectAll"
Height="{StaticResource MenuItemHeight}"
Click="menuSelectAll_Click"
Header="{x:Static resx:ResUI.menuSelectAll}" />
<Separator />
<MenuItem <MenuItem
x:Name="menuExport2ClientConfig" x:Name="menuExport2ClientConfig"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
@@ -679,6 +748,7 @@
MaxWidth="300" MaxWidth="300"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="remarks" DisplayMemberPath="remarks"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" /> Style="{StaticResource MaterialDesignFilledComboBox}" />
</DockPanel> </DockPanel>
</MenuItem.Header> </MenuItem.Header>
@@ -691,6 +761,7 @@
MaxWidth="300" MaxWidth="300"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}"
DisplayMemberPath="Text" DisplayMemberPath="Text"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" /> Style="{StaticResource MaterialDesignFilledComboBox}" />
</DockPanel> </DockPanel>
</MenuItem.Header> </MenuItem.Header>

View File

@@ -1,15 +1,19 @@
using ReactiveUI; using ReactiveUI;
using Splat; using Splat;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Resx; using v2rayN.Resx;
using v2rayN.ViewModels; using v2rayN.ViewModels;
using Point = System.Windows.Point;
using SystemInformation = System.Windows.Forms.SystemInformation; using SystemInformation = System.Windows.Forms.SystemInformation;
namespace v2rayN.Views namespace v2rayN.Views
@@ -29,10 +33,23 @@ namespace v2rayN.Views
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown; lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged; lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
lstProfiles.LoadingRow += LstProfiles_LoadingRow; lstProfiles.LoadingRow += LstProfiles_LoadingRow;
if (_config.uiItem.enableDragDropSort)
{
lstProfiles.AllowDrop = true;
lstProfiles.PreviewMouseLeftButtonDown += LstProfiles_PreviewMouseLeftButtonDown;
lstProfiles.MouseMove += LstProfiles_MouseMove;
lstProfiles.DragEnter += LstProfiles_DragEnter;
lstProfiles.Drop += LstProfiles_Drop;
}
ViewModel = new MainWindowViewModel(MainSnackbar.MessageQueue!, UpdateViewHandler); ViewModel = new MainWindowViewModel(MainSnackbar.MessageQueue!, UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 8; i++)
{
cmbCurrentFontSize.Items.Add(i.ToString());
}
Global.Languages.ForEach(it => Global.Languages.ForEach(it =>
{ {
cmbCurrentLanguage.Items.Add(it); cmbCurrentLanguage.Items.Add(it);
@@ -59,6 +76,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);
//servers delete //servers delete
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.menuEditServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RemoveServerCmd, v => v.menuRemoveServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RemoveServerCmd, v => v.menuRemoveServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RemoveDuplicateServerCmd, v => v.menuRemoveDuplicateServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RemoveDuplicateServerCmd, v => v.menuRemoveDuplicateServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CopyServerCmd, v => v.menuCopyServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CopyServerCmd, v => v.menuCopyServer).DisposeWith(disposables);
@@ -66,6 +84,9 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.ShareServerCmd, v => v.menuShareServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ShareServerCmd, v => v.menuShareServer).DisposeWith(disposables);
//servers move //servers move
this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.cmbMoveToGroup.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedMoveToGroup, v => v.cmbMoveToGroup.SelectedItem).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.MoveTopCmd, v => v.menuMoveTop).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.MoveTopCmd, v => v.menuMoveTop).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.MoveUpCmd, v => v.menuMoveUp).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.MoveUpCmd, v => v.menuMoveUp).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.MoveDownCmd, v => v.menuMoveDown).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.MoveDownCmd, v => v.menuMoveDown).DisposeWith(disposables);
@@ -88,8 +109,8 @@ namespace v2rayN.Views
//sub //sub
this.BindCommand(ViewModel, vm => vm.SubSettingCmd, v => v.menuSubSetting).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubSettingCmd, v => v.menuSubSetting).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubGroupUpdateCmd, v => v.menuSubGroupUpdate).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubGroupUpdateCmd, v => v.menuSubGroupUpdate).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubGroupUpdateViaProxyCmd, v => v.menuSubGroupUpdateViaProxy).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubGroupUpdateViaProxyCmd, v => v.menuSubGroupUpdateViaProxy).DisposeWith(disposables);
//setting //setting
@@ -157,6 +178,7 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.ColorModeDark, v => v.togDarkMode.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.ColorModeDark, v => v.togDarkMode.IsChecked).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.Swatches, v => v.cmbSwatches.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.Swatches, v => v.cmbSwatches.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables);
}); });
@@ -166,8 +188,7 @@ namespace v2rayN.Views
var IsAdministrator = Utils.IsAdministrator(); var IsAdministrator = Utils.IsAdministrator();
this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}"; this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
togEnableTun.Visibility = IsAdministrator ? Visibility.Visible : Visibility.Hidden; spEnableTun.Visibility = IsAdministrator ? Visibility.Visible : Visibility.Collapsed;
txtEnableTun.Visibility = IsAdministrator ? Visibility.Visible : Visibility.Hidden;
} }
#region Event #region Event
@@ -184,6 +205,10 @@ namespace v2rayN.Views
} }
})); }));
} }
else if (action == "ProfilesFocus")
{
lstProfiles.Focus();
}
} }
private void MainWindow_Closing(object? sender, CancelEventArgs e) private void MainWindow_Closing(object? sender, CancelEventArgs e)
@@ -212,27 +237,42 @@ namespace v2rayN.Views
} }
private void LstProfiles_LoadingRow(object? sender, DataGridRowEventArgs e) private void LstProfiles_LoadingRow(object? sender, DataGridRowEventArgs e)
{ {
if (e.Row.GetIndex() == 0) //if (e.Row.GetIndex() == 0)
{ //{
lstProfiles.Focus(); // lstProfiles.Focus();
} //}
e.Row.Header = e.Row.GetIndex() + 1; e.Row.Header = e.Row.GetIndex() + 1;
} }
private void LstProfiles_MouseDoubleClick(object sender, MouseButtonEventArgs e) private void LstProfiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{ {
ViewModel?.EditServer(false, EConfigType.Custom); if (_config.uiItem.doubleClick2Activate)
{
ViewModel?.SetDefaultServer();
}
else
{
ViewModel?.EditServer(false, EConfigType.Custom);
}
} }
private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e) private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e)
{ {
var colHeader = sender as DataGridColumnHeader; var colHeader = sender as DataGridColumnHeader;
if (colHeader == null || colHeader.TabIndex < 0) if (colHeader == null || colHeader.TabIndex < 0 || colHeader.Column == null)
{ {
return; return;
} }
if (colHeader.TabIndex == 0)
//find index
var index = lstProfiles.Columns.IndexOf(colHeader.Column);
if (index < 0)
{
index = colHeader.TabIndex;
}
if (index == 0)
{ {
foreach (var it in lstProfiles.Columns) foreach (var it in lstProfiles.Columns)
{ {
@@ -242,7 +282,7 @@ namespace v2rayN.Views
return; return;
} }
ViewModel?.SortServer(colHeader.TabIndex); ViewModel?.SortServer(index);
} }
private void menuSelectAll_Click(object sender, RoutedEventArgs e) private void menuSelectAll_Click(object sender, RoutedEventArgs e)
@@ -305,6 +345,10 @@ namespace v2rayN.Views
ViewModel?.Export2ShareUrl(); ViewModel?.Export2ShareUrl();
} }
else if (e.Key == Key.D) else if (e.Key == Key.D)
{
ViewModel?.EditServer(false, EConfigType.Custom);
}
else if (e.Key == Key.F)
{ {
ViewModel?.ShareServer(); ViewModel?.ShareServer();
} }
@@ -323,15 +367,15 @@ namespace v2rayN.Views
{ {
ViewModel?.MoveServer(EMove.Top); ViewModel?.MoveServer(EMove.Top);
} }
else if (e.Key == Key.B) else if (e.Key == Key.U)
{ {
ViewModel?.MoveServer(EMove.Up); ViewModel?.MoveServer(EMove.Up);
} }
else if (e.Key == Key.U) else if (e.Key == Key.D)
{ {
ViewModel?.MoveServer(EMove.Down); ViewModel?.MoveServer(EMove.Down);
} }
else if (e.Key == Key.D) else if (e.Key == Key.B)
{ {
ViewModel?.MoveServer(EMove.Bottom); ViewModel?.MoveServer(EMove.Bottom);
} }
@@ -365,24 +409,32 @@ namespace v2rayN.Views
{ {
if (_config.uiItem.mainWidth > 0 && _config.uiItem.mainHeight > 0) if (_config.uiItem.mainWidth > 0 && _config.uiItem.mainHeight > 0)
{ {
if (_config.uiItem.mainWidth > SystemInformation.WorkingArea.Width) Width = _config.uiItem.mainWidth;
{ Height = _config.uiItem.mainHeight;
_config.uiItem.mainWidth = SystemInformation.WorkingArea.Width * 2 / 3;
}
if (_config.uiItem.mainHeight > SystemInformation.WorkingArea.Height)
{
_config.uiItem.mainHeight = SystemInformation.WorkingArea.Height * 2 / 3;
}
this.Width = _config.uiItem.mainWidth;
this.Height = _config.uiItem.mainHeight;
} }
IntPtr hWnd = new WindowInteropHelper(this).EnsureHandle();
Graphics g = Graphics.FromHwnd(hWnd);
if (Width > SystemInformation.WorkingArea.Width * 96 / g.DpiX)
{
Width = SystemInformation.WorkingArea.Width * 96 / g.DpiX;
}
if (Height > SystemInformation.WorkingArea.Height * 96 / g.DpiY)
{
Height = SystemInformation.WorkingArea.Height * 96 / g.DpiY;
}
if (_config.uiItem.mainGirdHeight1 > 0 && _config.uiItem.mainGirdHeight2 > 0)
{
gridMain.RowDefinitions[0].Height = new GridLength(_config.uiItem.mainGirdHeight1, GridUnitType.Star);
gridMain.RowDefinitions[2].Height = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star);
}
for (int k = 0; k < lstProfiles.Columns.Count; k++) for (int k = 0; k < lstProfiles.Columns.Count; k++)
{ {
var width = ConfigHandler.GetformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].Width.Value)); var width = ConfigHandler.GetformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].Width.Value));
lstProfiles.Columns[k].Width = width; lstProfiles.Columns[k].Width = width;
} }
if (!_config.enableStatistics) if (!_config.guiItem.enableStatistics)
{ {
colTodayUp.Visibility = Visibility.Hidden; colTodayUp.Visibility = Visibility.Hidden;
colTodayDown.Visibility = Visibility.Hidden; colTodayDown.Visibility = Visibility.Hidden;
@@ -399,6 +451,8 @@ namespace v2rayN.Views
{ {
ConfigHandler.AddformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].ActualWidth)); ConfigHandler.AddformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].ActualWidth));
} }
_config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain.RowDefinitions[0].ActualHeight + 0.1);
_config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain.RowDefinitions[2].ActualHeight + 0.1);
} }
private void AddHelpMenuItem() private void AddHelpMenuItem()
@@ -426,6 +480,100 @@ namespace v2rayN.Views
#endregion #endregion
#region Drag and Drop
private Point startPoint = new Point();
private int startIndex = -1;
private string formatData = "ProfileItemModel";
/// <summary>
/// Helper to search up the VisualTree
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="current"></param>
/// <returns></returns>
private static T? FindAnchestor<T>(DependencyObject current) where T : DependencyObject
{
do
{
if (current is T)
{
return (T)current;
}
current = VisualTreeHelper.GetParent(current);
}
while (current != null);
return null;
}
private void LstProfiles_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Get current mouse position
startPoint = e.GetPosition(null);
}
private void LstProfiles_MouseMove(object sender, MouseEventArgs e)
{
// Get the current mouse position
Point mousePos = e.GetPosition(null);
Vector diff = startPoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
// Get the dragged Item
var listView = sender as DataGrid;
if (listView == null) return;
var listViewItem = FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);
if (listViewItem == null) return; // Abort
// Find the data behind the ListViewItem
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
if (item == null) return; // Abort
// Initialize the drag & drop operation
startIndex = lstProfiles.SelectedIndex;
DataObject dragData = new DataObject(formatData, item);
DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move);
}
}
private void LstProfiles_DragEnter(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(formatData) || sender != e.Source)
{
e.Effects = DragDropEffects.None;
}
}
private void LstProfiles_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(formatData) && sender == e.Source)
{
// Get the drop Item destination
var listView = sender as DataGrid;
if (listView == null) return;
var listViewItem = FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);
if (listViewItem == null)
{
// Abort
e.Effects = DragDropEffects.None;
return;
}
// Find the data behind the Item
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
if (item == null) return;
// Move item into observable collection
// (this will be automatically reflected to lstView.ItemsSource)
e.Effects = DragDropEffects.Move;
ViewModel?.MoveServerTo(startIndex, item);
startIndex = -1;
}
}
#endregion
} }
} }

View File

@@ -20,20 +20,35 @@
Margin="8,0" Margin="8,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{DynamicResource PrimaryHueLightBrush}" Foreground="{DynamicResource PrimaryHueLightBrush}"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.MsgInformationTitle}" /> Text="{x:Static resx:ResUI.MsgInformationTitle}" />
<TextBox <ComboBox
x:Name="txtMsgFilter" x:Name="cmbMsgFilter"
Width="200" Width="200"
Margin="8,0" Margin="8,0"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}"
materialDesign:TextFieldAssist.HasClearButton="True" /> materialDesign:TextFieldAssist.HasClearButton="True"
IsEditable="True"
Style="{StaticResource DefComboBox}"
TextBoxBase.TextChanged="cmbMsgFilter_TextChanged" />
<TextBlock
Margin="8,0"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbAutoRefresh}" />
<ToggleButton
x:Name="togAutoRefresh"
Margin="8,0"
HorizontalAlignment="Left"
IsChecked="True" />
</StackPanel> </StackPanel>
<TextBox <TextBox
Name="txtMsg" Name="txtMsg"
BorderThickness="0" BorderThickness="0"
FontSize="11" FontSize="{DynamicResource StdFontSizeMsg}"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
IsReadOnly="True" IsReadOnly="True"
TextAlignment="Left"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Visible"> VerticalScrollBarVisibility="Visible">
<TextBox.ContextMenu> <TextBox.ContextMenu>

View File

@@ -3,15 +3,27 @@ using System.Reactive.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Threading; using System.Windows.Threading;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Handler;
using v2rayN.Mode;
namespace v2rayN.Views namespace v2rayN.Views
{ {
public partial class MsgView public partial class MsgView
{ {
private static Config _config;
public MsgView() public MsgView()
{ {
InitializeComponent(); InitializeComponent();
_config = LazyConfig.Instance.GetConfig();
MessageBus.Current.Listen<string>("MsgView").Subscribe(x => DelegateAppendText(x)); 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) void DelegateAppendText(string msg)
@@ -26,7 +38,11 @@ namespace v2rayN.Views
ClearMsg(); ClearMsg();
return; return;
} }
var MsgFilter = txtMsgFilter.Text.TrimEx(); if (!togAutoRefresh.IsChecked.Value)
{
return;
}
var MsgFilter = cmbMsgFilter.Text.TrimEx();
if (!Utils.IsNullOrEmpty(MsgFilter)) if (!Utils.IsNullOrEmpty(MsgFilter))
{ {
if (!Regex.IsMatch(msg, MsgFilter)) if (!Regex.IsMatch(msg, MsgFilter))
@@ -79,6 +95,10 @@ namespace v2rayN.Views
{ {
ClearMsg(); ClearMsg();
} }
private void cmbMsgFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
_config.uiItem.mainMsgFilter = cmbMsgFilter.Text.TrimEx();
}
} }
} }

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.OptionSettingWindow" x:Class="v2rayN.Views.OptionSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="700" Height="700"
x:TypeArguments="vms:OptionSettingViewModel" x:TypeArguments="vms:OptionSettingViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -45,194 +48,250 @@
<TabControl> <TabControl>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCore}"> <TabItem Header="{x:Static resx:ResUI.TbSettingsCore}">
<Grid Margin="{StaticResource SettingItemMargin}"> <ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid.RowDefinitions> <Grid Margin="{StaticResource SettingItemMargin}">
<RowDefinition Height="Auto" /> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> <RowDefinition Height="Auto" />
<Grid.ColumnDefinitions> <RowDefinition Height="Auto" />
<ColumnDefinition Width="Auto" /> <RowDefinition Height="Auto" />
<ColumnDefinition Width="Auto" /> <RowDefinition Height="Auto" />
</Grid.ColumnDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Row="0" Grid.Row="0"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSocksPort}" /> Text="{x:Static resx:ResUI.TbSettingsSocksPort}" />
<TextBox <TextBox
x:Name="txtlocalPort" x:Name="txtlocalPort"
Grid.Row="0" Grid.Row="0"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="0"
Grid.Column="2"
Margin="{StaticResource ServerItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSocksPortTip}" />
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsUdpEnabled}" /> Text="{x:Static resx:ResUI.TbSettingsUdpEnabled}" />
<ToggleButton <ToggleButton
x:Name="togudpEnabled" x:Name="togudpEnabled"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSniffingEnabled}" /> Text="{x:Static resx:ResUI.TbSettingsSniffingEnabled}" />
<ToggleButton <ToggleButton
x:Name="togsniffingEnabled" x:Name="togsniffingEnabled"
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsRouteOnly}" /> Text="{x:Static resx:ResUI.TbSettingsRouteOnly}" />
<ToggleButton <ToggleButton
x:Name="togrouteOnly" x:Name="togrouteOnly"
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsAllowLAN}" /> Text="{x:Static resx:ResUI.TbSettingsAllowLAN}" />
<ToggleButton <ToggleButton
x:Name="togAllowLANConn" x:Name="togAllowLANConn"
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="5" Grid.Row="5"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsNewPort4LAN}" /> Text="{x:Static resx:ResUI.TbSettingsNewPort4LAN}" />
<ToggleButton <ToggleButton
x:Name="togNewPort4LAN" x:Name="togNewPort4LAN"
Grid.Row="5" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="6" Grid.Row="6"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsUser}" /> Text="{x:Static resx:ResUI.TbSettingsUser}" />
<TextBox <TextBox
x:Name="txtuser" x:Name="txtuser"
Grid.Row="6" Grid.Row="6"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="7" Grid.Row="7"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsPass}" /> Text="{x:Static resx:ResUI.TbSettingsPass}" />
<TextBox <TextBox
x:Name="txtpass" x:Name="txtpass"
Grid.Row="7" Grid.Row="7"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="8" Grid.Row="8"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsMuxEnabled}" /> Text="{x:Static resx:ResUI.TbSettingsMuxEnabled}" />
<ToggleButton <ToggleButton
x:Name="togmuxEnabled" x:Name="togmuxEnabled"
Grid.Row="8" Grid.Row="8"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="9" Grid.Row="9"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsLogEnabled}" /> Text="{x:Static resx:ResUI.TbSettingsLogEnabled}" />
<ToggleButton <ToggleButton
x:Name="toglogEnabled" x:Name="toglogEnabled"
Grid.Row="9" Grid.Row="9"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="10" Grid.Row="10"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsLogLevel}" /> Text="{x:Static resx:ResUI.TbSettingsLogLevel}" />
<ComboBox <ComboBox
x:Name="cmbloglevel" x:Name="cmbloglevel"
Grid.Row="10" Grid.Row="10"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Width="200"
materialDesign:HintAssist.Hint="Level" /> Margin="{StaticResource SettingItemMargin}"
materialDesign:HintAssist.Hint="Level"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="11" Grid.Row="11"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDefAllowInsecure}" /> Text="{x:Static resx:ResUI.TbSettingsDefAllowInsecure}" />
<ToggleButton <ToggleButton
x:Name="togdefAllowInsecure" x:Name="togdefAllowInsecure"
Grid.Row="11" Grid.Row="11"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
</Grid>
<TextBlock
Grid.Row="12"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDefFingerprint}" />
<ComboBox
x:Name="cmbdefFingerprint"
Grid.Row="12"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="13"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDefUserAgent}" />
<ComboBox
x:Name="cmbdefUserAgent"
Grid.Row="13"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="13"
Grid.Column="3"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDefUserAgentTips}" />
</Grid>
</ScrollViewer>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}"> <TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
@@ -246,7 +305,8 @@
<ComboBox <ComboBox
x:Name="cmbdomainStrategy4Freedom" x:Name="cmbdomainStrategy4Freedom"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
</StackPanel> </StackPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
@@ -270,6 +330,7 @@
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
AcceptsReturn="True" AcceptsReturn="True"
BorderThickness="1" BorderThickness="1"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</DockPanel> </DockPanel>
@@ -303,7 +364,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="mtu" /> Text="mtu" />
<TextBox <TextBox Style="{StaticResource DefTextBox}"
x:Name="txtKcpmtu" x:Name="txtKcpmtu"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
@@ -317,7 +378,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="tti" /> Text="tti" />
<TextBox <TextBox Style="{StaticResource DefTextBox}"
x:Name="txtKcptti" x:Name="txtKcptti"
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
@@ -331,7 +392,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="uplinkCapacity" /> Text="uplinkCapacity" />
<TextBox <TextBox Style="{StaticResource DefTextBox}"
x:Name="txtKcpuplinkCapacity" x:Name="txtKcpuplinkCapacity"
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
@@ -345,7 +406,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="downlinkCapacity" /> Text="downlinkCapacity" />
<TextBox <TextBox Style="{StaticResource DefTextBox}"
x:Name="txtKcpdownlinkCapacity" x:Name="txtKcpdownlinkCapacity"
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
@@ -359,7 +420,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="readBufferSize" /> Text="readBufferSize" />
<TextBox <TextBox Style="{StaticResource DefTextBox}"
x:Name="txtKcpreadBufferSize" x:Name="txtKcpreadBufferSize"
Grid.Row="5" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
@@ -373,7 +434,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="writeBufferSize" /> Text="writeBufferSize" />
<TextBox <TextBox Style="{StaticResource DefTextBox}"
x:Name="txtKcpwriteBufferSize" x:Name="txtKcpwriteBufferSize"
Grid.Row="6" Grid.Row="6"
Grid.Column="1" Grid.Column="1"
@@ -415,10 +476,15 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock <TextBlock
@@ -434,6 +500,13 @@
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
<TextBlock
Grid.Row="1"
Grid.Column="2"
Margin="{StaticResource ServerItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsStartBootTip}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -461,7 +534,8 @@
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
@@ -553,13 +627,13 @@
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsAutoUpdateInterval}" /> Text="{x:Static resx:ResUI.TbSettingsEnableDragDropSort}" />
<TextBox <ToggleButton
x:Name="txtautoUpdateInterval" x:Name="togEnableDragDropSort"
Grid.Row="10" Grid.Row="10"
Grid.Column="1" Grid.Column="1"
Width="200" Margin="{StaticResource SettingItemMargin}"
Margin="{StaticResource SettingItemMargin}" /> HorizontalAlignment="Left" />
<TextBlock <TextBlock
Grid.Row="11" Grid.Row="11"
@@ -567,16 +641,48 @@
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDoubleClick2Activate}" />
<ToggleButton
x:Name="togDoubleClick2Activate"
Grid.Row="11"
Grid.Column="1"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="12"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsAutoUpdateInterval}" />
<TextBox
x:Name="txtautoUpdateInterval"
Grid.Row="12"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
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}" /> Text="{x:Static resx:ResUI.TbSettingsAutoUpdate}" />
<TextBox <TextBox
x:Name="txtautoUpdateSubInterval" x:Name="txtautoUpdateSubInterval"
Grid.Row="11" Grid.Row="13"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="12" Grid.Row="14"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -584,10 +690,65 @@
Text="{x:Static resx:ResUI.TbSettingsTrayMenuServersLimit}" /> Text="{x:Static resx:ResUI.TbSettingsTrayMenuServersLimit}" />
<TextBox <TextBox
x:Name="txttrayMenuServersLimit" x:Name="txttrayMenuServersLimit"
Grid.Row="12" Grid.Row="14"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="15"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamily}" />
<ComboBox
x:Name="cmbcurrentFontFamily"
Grid.Row="15"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
MaxDropDownHeight="1000"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="15"
Grid.Column="2"
Margin="{StaticResource ServerItemMargin}"
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> </Grid>
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>
@@ -604,8 +765,10 @@
<ComboBox <ComboBox
x:Name="cmbsystemProxyAdvancedProtocol" x:Name="cmbsystemProxyAdvancedProtocol"
Grid.Row="4" Grid.Row="4"
MinWidth="200"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
materialDesign:HintAssist.Hint="Protocol" /> materialDesign:HintAssist.Hint="Protocol"
Style="{StaticResource DefComboBox}" />
</StackPanel> </StackPanel>
@@ -622,6 +785,7 @@
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
AcceptsReturn="True" AcceptsReturn="True"
BorderThickness="1" BorderThickness="1"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</DockPanel> </DockPanel>
@@ -642,10 +806,12 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock <TextBlock
@@ -688,7 +854,9 @@
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
@@ -702,10 +870,65 @@
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsTunModeCustomTemplate}" />
<TextBox
x:Name="txtCustomTemplate"
Grid.Row="5"
Grid.Column="1"
Width="400"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Top"
AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" />
<Button
x:Name="btnBrowse"
Grid.Row="5"
Grid.Column="2"
Width="100"
Margin="2,0,8,0"
Click="btnBrowse_Click"
Content="{x:Static resx:ResUI.TbBrowse}"
Style="{StaticResource DefButton}" />
<TextBlock
Grid.Row="6"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsTunModeBypassMode}" />
<ToggleButton
x:Name="togBypassMode"
Grid.Row="6"
Grid.Column="1"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="6"
Grid.Column="2"
Margin="{StaticResource ServerItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsTunModeBypassModeTip}" />
</Grid> </Grid>
<Grid Margin="{StaticResource SettingItemMargin}">
<Grid
x:Name="gridTunModeDirect"
Width="600"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" />
<ColumnDefinition Width="10" /> <ColumnDefinition Width="10" />
@@ -714,10 +937,11 @@
<GroupBox <GroupBox
Grid.Column="0" Grid.Column="0"
Header="{x:Static resx:ResUI.TbSettingsTunModeDirectIP}" Header="{x:Static resx:ResUI.TbSettingsTunModeDirectIP}"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtDirectIP" Name="txtDirectIP"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -725,14 +949,51 @@
<GroupBox <GroupBox
Grid.Column="2" Grid.Column="2"
Header="{x:Static resx:ResUI.TbSettingsTunModeDirectProcess}" Header="{x:Static resx:ResUI.TbSettingsTunModeDirectProcess}"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtDirectProcess" Name="txtDirectProcess"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
</Grid> </Grid>
<Grid
x:Name="gridTunModeProxy"
Width="600"
Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<GroupBox
Grid.Column="0"
Header="{x:Static resx:ResUI.TbSettingsTunModeProxyIP}"
Style="{StaticResource MyGroupBox}">
<TextBox
Name="txtProxyIP"
AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
</GroupBox>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<GroupBox
Grid.Column="2"
Header="{x:Static resx:ResUI.TbSettingsTunModeProxyProcess}"
Style="{StaticResource MyGroupBox}">
<TextBox
Name="txtProxyProcess"
AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
</GroupBox>
</Grid>
</DockPanel> </DockPanel>
</TabItem> </TabItem>
@@ -763,7 +1024,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -777,7 +1039,8 @@
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
@@ -791,7 +1054,8 @@
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
@@ -805,7 +1069,8 @@
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="5" Grid.Row="5"
@@ -819,7 +1084,8 @@
Grid.Row="5" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="6" Grid.Row="6"
@@ -833,7 +1099,8 @@
Grid.Row="6" Grid.Row="6"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" /> Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
</Grid> </Grid>
</TabItem> </TabItem>
</TabControl> </TabControl>

View File

@@ -1,15 +1,23 @@
using ReactiveUI; using ReactiveUI;
using System.Globalization;
using System.IO;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Media;
using v2rayN.Handler;
using v2rayN.Mode;
using v2rayN.ViewModels; using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
public partial class OptionSettingWindow public partial class OptionSettingWindow
{ {
private static Config _config;
public OptionSettingWindow() public OptionSettingWindow()
{ {
InitializeComponent(); InitializeComponent();
_config = LazyConfig.Instance.GetConfig();
ViewModel = new OptionSettingViewModel(this); ViewModel = new OptionSettingViewModel(this);
@@ -21,6 +29,14 @@ namespace v2rayN.Views
{ {
cmbloglevel.Items.Add(it); cmbloglevel.Items.Add(it);
}); });
Global.fingerprints.ForEach(it =>
{
cmbdefFingerprint.Items.Add(it);
});
Global.userAgent.ForEach(it =>
{
cmbdefUserAgent.Items.Add(it);
});
Global.domainStrategy4Freedoms.ForEach(it => Global.domainStrategy4Freedoms.ForEach(it =>
{ {
cmbdomainStrategy4Freedom.Items.Add(it); cmbdomainStrategy4Freedom.Items.Add(it);
@@ -47,6 +63,57 @@ namespace v2rayN.Views
cmbCoreType6.Items.Add(it); 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 culture2 = "en-us";
foreach (var it in files)
{
var families = Fonts.GetFontFamilies(Utils.GetFontsPath(it.Name));
foreach (FontFamily family in families)
{
var typefaces = family.GetTypefaces();
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 fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];
if (Utils.IsNullOrEmpty(fontFamily))
{
fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)];
if (Utils.IsNullOrEmpty(fontFamily))
{
continue;
}
}
cmbcurrentFontFamily.Items.Add(fontFamily);
break;
}
}
}
}
catch (Exception ex)
{
Utils.SaveLog("fill fonts error", ex);
}
cmbcurrentFontFamily.Items.Add(string.Empty);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
@@ -63,6 +130,8 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.logEnabled, v => v.toglogEnabled.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.logEnabled, v => v.toglogEnabled.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.loglevel, v => v.cmbloglevel.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.loglevel, v => v.cmbloglevel.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.defAllowInsecure, v => v.togdefAllowInsecure.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.defAllowInsecure, v => v.togdefAllowInsecure.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.defFingerprint, v => v.cmbdefFingerprint.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.defUserAgent, v => v.cmbdefUserAgent.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
@@ -87,9 +156,14 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
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.autoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.autoUpdateSubInterval, v => v.txtautoUpdateSubInterval.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.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); this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);
@@ -100,8 +174,14 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunCustomTemplate, v => v.txtCustomTemplate.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunBypassMode, v => v.togBypassMode.IsChecked).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.TunBypassMode, v => v.gridTunModeDirect.Visibility, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.TunBypassMode2, v => v.gridTunModeProxy.Visibility, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunDirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDirectProcess, v => v.txtDirectProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunDirectProcess, v => v.txtDirectProcess.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunProxyIP, v => v.txtProxyIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunProxyProcess, v => v.txtProxyProcess.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);
@@ -124,6 +204,13 @@ namespace v2rayN.Views
{ {
this.Close(); this.Close();
} }
private void btnBrowse_Click(object sender, System.Windows.RoutedEventArgs e)
{
var openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
openFileDialog1.Filter = "tunConfig|*.json|All|*.*";
openFileDialog1.ShowDialog();
txtCustomTemplate.Text = openFileDialog1.FileName;
}
} }
} }

View File

@@ -9,7 +9,7 @@
d:DesignHeight="300" d:DesignHeight="300"
d:DesignWidth="300" d:DesignWidth="300"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Margin="16"> <Grid Margin="30">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.RoutingRuleDetailsWindow" x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="700" Height="700"
x:TypeArguments="vms:RoutingRuleDetailsViewModel" x:TypeArguments="vms:RoutingRuleDetailsViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -62,7 +65,8 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="4" Margin="4"
HorizontalAlignment="Left" /> HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -77,6 +81,7 @@
Grid.Column="1" Grid.Column="1"
Margin="4" Margin="4"
HorizontalAlignment="Left" HorizontalAlignment="Left"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" /> Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" />
<TextBlock <TextBlock
@@ -91,6 +96,7 @@
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Margin="4" Margin="4"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" /> Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" />
<TextBlock <TextBlock
@@ -140,7 +146,7 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center"> VerticalAlignment="Center">
<CheckBox x:Name="chkAutoSort"> <CheckBox x:Name="chkAutoSort">
<TextBlock Text="{x:Static resx:ResUI.TbAutoSort}" /> <TextBlock Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.TbAutoSort}" />
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>
<Button <Button
@@ -169,10 +175,11 @@
<GroupBox <GroupBox
Grid.Column="0" Grid.Column="0"
Header="Domain" Header="Domain"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtDomain" Name="txtDomain"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -180,10 +187,11 @@
<GroupBox <GroupBox
Grid.Column="2" Grid.Column="2"
Header="IP" Header="IP"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtIP" Name="txtIP"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.RoutingRuleSettingWindow" x:Class="v2rayN.Views.RoutingRuleSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="700" Height="700"
x:TypeArguments="vms:RoutingRuleSettingViewModel" x:TypeArguments="vms:RoutingRuleSettingViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -89,6 +92,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
@@ -111,6 +115,7 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
@@ -143,6 +148,7 @@
Margin="4" Margin="4"
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
@@ -160,6 +166,7 @@
Margin="4" Margin="4"
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<Button <Button
x:Name="btnBrowse" x:Name="btnBrowse"
@@ -171,6 +178,23 @@
Content="{x:Static resx:ResUI.TbBrowse}" Content="{x:Static resx:ResUI.TbBrowse}"
Style="{StaticResource DefButton}" /> 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> </Grid>
<TabControl x:Name="tabAdvanced"> <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.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.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.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.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables);
@@ -75,15 +76,15 @@ namespace v2rayN.Views
{ {
ViewModel?.MoveRule(EMove.Top); ViewModel?.MoveRule(EMove.Top);
} }
else if (e.Key == Key.B) else if (e.Key == Key.U)
{ {
ViewModel?.MoveRule(EMove.Up); ViewModel?.MoveRule(EMove.Up);
} }
else if (e.Key == Key.U) else if (e.Key == Key.D)
{ {
ViewModel?.MoveRule(EMove.Down); ViewModel?.MoveRule(EMove.Down);
} }
else if (e.Key == Key.D) else if (e.Key == Key.B)
{ {
ViewModel?.MoveRule(EMove.Bottom); ViewModel?.MoveRule(EMove.Bottom);
} }

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.RoutingSettingWindow" x:Class="v2rayN.Views.RoutingSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="700" Height="700"
x:TypeArguments="vms:RoutingSettingViewModel" x:TypeArguments="vms:RoutingSettingViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -194,15 +197,19 @@
Binding="{Binding remarks}" Binding="{Binding remarks}"
Header="{x:Static resx:ResUI.LvAlias}" /> Header="{x:Static resx:ResUI.LvAlias}" />
<DataGridTextColumn <DataGridTextColumn
Width="70" Width="60"
Binding="{Binding ruleNum}" Binding="{Binding ruleNum}"
Header="{x:Static resx:ResUI.LvCount}" /> Header="{x:Static resx:ResUI.LvCount}" />
<DataGridTextColumn <DataGridTextColumn
Width="280" Width="60"
Binding="{Binding sort}"
Header="{x:Static resx:ResUI.LvSort}" />
<DataGridTextColumn
Width="260"
Binding="{Binding url}" Binding="{Binding url}"
Header="{x:Static resx:ResUI.LvUrl}" /> Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridTextColumn <DataGridTextColumn
Width="280" Width="260"
Binding="{Binding customIcon}" Binding="{Binding customIcon}"
Header="{x:Static resx:ResUI.LvCustomIcon}" /> Header="{x:Static resx:ResUI.LvCustomIcon}" />
</DataGrid.Columns> </DataGrid.Columns>
@@ -221,10 +228,11 @@
<GroupBox <GroupBox
Grid.Column="0" Grid.Column="0"
Header="Domain" Header="Domain"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtProxyDomain" Name="txtProxyDomain"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -232,10 +240,11 @@
<GroupBox <GroupBox
Grid.Column="2" Grid.Column="2"
Header="IP" Header="IP"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtProxyIP" Name="txtProxyIP"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -252,10 +261,11 @@
<GroupBox <GroupBox
Grid.Column="0" Grid.Column="0"
Header="Domain" Header="Domain"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtDirectDomain" Name="txtDirectDomain"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -263,10 +273,11 @@
<GroupBox <GroupBox
Grid.Column="2" Grid.Column="2"
Header="IP" Header="IP"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtDirectIP" Name="txtDirectIP"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -283,10 +294,11 @@
<GroupBox <GroupBox
Grid.Column="0" Grid.Column="0"
Header="Domain" Header="Domain"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtBlockDomain" Name="txtBlockDomain"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>
@@ -294,10 +306,11 @@
<GroupBox <GroupBox
Grid.Column="2" Grid.Column="2"
Header="IP" Header="IP"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MyGroupBox}">
<TextBox <TextBox
Name="txtBlockIP" Name="txtBlockIP"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource DefTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" />
</GroupBox> </GroupBox>

View File

@@ -11,6 +11,7 @@ namespace v2rayN.Views
public RoutingSettingWindow() public RoutingSettingWindow()
{ {
InitializeComponent(); InitializeComponent();
this.Closing += RoutingSettingWindow_Closing;
this.PreviewKeyDown += RoutingSettingWindow_PreviewKeyDown; this.PreviewKeyDown += RoutingSettingWindow_PreviewKeyDown;
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged; lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick; lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
@@ -61,6 +62,14 @@ namespace v2rayN.Views
}); });
} }
private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
{
if (ViewModel?.IsModified == true)
{
this.DialogResult = true;
}
}
private void RoutingSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e) private void RoutingSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{ {
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.SubEditWindow" x:Class="v2rayN.Views.SubEditWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="550" Height="550"
x:TypeArguments="vms:SubEditViewModel" x:TypeArguments="vms:SubEditViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"
@@ -66,7 +69,7 @@
Margin="4" Margin="4"
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" Style="{StaticResource MyOutlinedTextBox}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
@@ -85,7 +88,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" Style="{StaticResource MyOutlinedTextBox}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
@@ -117,7 +120,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" Style="{StaticResource MyOutlinedTextBox}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
@@ -136,7 +139,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="6" Grid.Row="6"
@@ -153,7 +156,7 @@
Margin="4" Margin="4"
VerticalAlignment="Top" VerticalAlignment="Top"
AcceptsReturn="True" AcceptsReturn="True"
Style="{StaticResource MaterialDesignOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
</Grid> </Grid>
<Grid <Grid

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Views.SubSettingWindow" x:Class="v2rayN.Views.SubSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -13,7 +14,9 @@
Height="600" Height="600"
x:TypeArguments="vms:SubSettingViewModel" x:TypeArguments="vms:SubSettingViewModel"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ResizeMode="NoResize" ResizeMode="NoResize"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="Auto" TextOptions.TextRenderingMode="Auto"

View File

@@ -1,4 +1,5 @@
using ReactiveUI; using ReactiveUI;
using System.ComponentModel;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.ViewModels; using v2rayN.ViewModels;
@@ -12,6 +13,7 @@ namespace v2rayN.Views
InitializeComponent(); InitializeComponent();
ViewModel = new SubSettingViewModel(this); ViewModel = new SubSettingViewModel(this);
this.Closing += SubSettingWindow_Closing;
lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick; lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;
this.WhenActivated(disposables => this.WhenActivated(disposables =>
@@ -27,6 +29,14 @@ namespace v2rayN.Views
}); });
} }
private void SubSettingWindow_Closing(object? sender, CancelEventArgs e)
{
if (ViewModel?.IsModified == true)
{
this.DialogResult = true;
}
}
private void LstSubscription_MouseDoubleClick(object sender, MouseButtonEventArgs e) private void LstSubscription_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{ {
ViewModel?.EditSub(false); ViewModel?.EditSub(false);

View File

@@ -9,11 +9,12 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>v2rayN.ico</ApplicationIcon> <ApplicationIcon>v2rayN.ico</ApplicationIcon>
<Copyright>Copyright © 2017-2023 (GPLv3)</Copyright> <Copyright>Copyright © 2017-2023 (GPLv3)</Copyright>
<FileVersion>6.1</FileVersion> <FileVersion>6.11</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MaterialDesignThemes" Version="4.6.1" /> <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="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NHotkey" Version="2.1.0" /> <PackageReference Include="NHotkey" Version="2.1.0" />
@@ -25,7 +26,7 @@
<PackageReference Include="ReactiveUI.Fody" Version="18.4.1" /> <PackageReference Include="ReactiveUI.Fody" Version="18.4.1" />
<PackageReference Include="ReactiveUI.Validation" Version="3.0.22" /> <PackageReference Include="ReactiveUI.Validation" Version="3.0.22" />
<PackageReference Include="ReactiveUI.WPF" Version="18.4.1" /> <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" /> <PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup> </ItemGroup>
@@ -99,6 +100,9 @@
<EmbeddedResource Update="Resx\ResUI.fa-Ir.resx"> <EmbeddedResource Update="Resx\ResUI.fa-Ir.resx">
<Generator>PublicResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="Resx\ResUI.ru.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup> </ItemGroup>
</Project> </Project>