Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ceb638edf | ||
|
|
688b9ef5ee | ||
|
|
4909a557d5 | ||
|
|
75f63afadc | ||
|
|
e90a624c9a | ||
|
|
dd85ccd3f8 | ||
|
|
fc54e19ce2 | ||
|
|
118a920e57 | ||
|
|
975a335538 | ||
|
|
c6ec4f38b0 | ||
|
|
5a5d686be1 | ||
|
|
8fc430d124 | ||
|
|
721eb40a8a | ||
|
|
f18103751f | ||
|
|
9d30bb669e | ||
|
|
ab6f5c21c8 | ||
|
|
4fc2ed32d2 | ||
|
|
00ab4f2a7d | ||
|
|
cb5d8b405b | ||
|
|
7b28aa8500 | ||
|
|
97a369df0a | ||
|
|
73a817c1cb | ||
|
|
c16053f0e5 |
@@ -1194,11 +1194,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;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace v2rayN.Handler
|
|||||||
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))
|
||||||
{
|
{
|
||||||
@@ -134,11 +134,6 @@ 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).ToList();
|
||||||
|
|||||||
@@ -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,7 +24,7 @@ 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>();
|
||||||
@@ -106,7 +107,7 @@ namespace v2rayN.Handler
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RunRealPing()
|
private Task RunRealPing()
|
||||||
{
|
{
|
||||||
int pid = -1;
|
int pid = -1;
|
||||||
try
|
try
|
||||||
@@ -117,7 +118,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 +145,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 +165,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)
|
||||||
@@ -178,11 +187,9 @@ namespace v2rayN.Handler
|
|||||||
string url = _config.constItem.speedTestUrl;
|
string url = _config.constItem.speedTestUrl;
|
||||||
DownloadHandle downloadHandle = new DownloadHandle();
|
DownloadHandle downloadHandle = new DownloadHandle();
|
||||||
|
|
||||||
var timeout = 10;
|
var timeout = 8;
|
||||||
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 +198,12 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
testIndexId = it.indexId;
|
if (it.delay < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
|
||||||
|
UpdateFunc(it.indexId, "", ResUI.Speedtesting);
|
||||||
|
|
||||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||||
if (item is null) continue;
|
if (item is null) continue;
|
||||||
@@ -218,6 +230,8 @@ namespace v2rayN.Handler
|
|||||||
{
|
{
|
||||||
await RunRealPing();
|
await RunRealPing();
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
await RunSpeedTestAsync();
|
await RunSpeedTestAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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_;
|
||||||
|
|
||||||
@@ -83,11 +85,13 @@ 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;
|
||||||
@@ -97,11 +101,6 @@ namespace v2rayN.Handler
|
|||||||
server.totalDown = _serverStatItem.totalDown;
|
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_.statisticsFreshRate < 1 ? 1 : config_.statisticsFreshRate;
|
||||||
@@ -118,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)
|
||||||
@@ -136,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
|
||||||
@@ -149,6 +163,7 @@ namespace v2rayN.Handler
|
|||||||
dateNow = ticks
|
dateNow = ticks
|
||||||
};
|
};
|
||||||
_ = SqliteHelper.Instance.Replacesync(_serverStatItem);
|
_ = SqliteHelper.Instance.Replacesync(_serverStatItem);
|
||||||
|
_lstServerStat.Add(_serverStatItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -210,7 +219,7 @@ namespace v2rayN.Base
|
|||||||
WorkingDirectory = Utils.GetConfigPath(),
|
WorkingDirectory = Utils.GetConfigPath(),
|
||||||
UseShellExecute = showWindow,
|
UseShellExecute = showWindow,
|
||||||
CreateNoWindow = !showWindow,
|
CreateNoWindow = !showWindow,
|
||||||
RedirectStandardError = !showWindow,
|
//RedirectStandardError = !showWindow,
|
||||||
Verb = "runas",
|
Verb = "runas",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -219,14 +228,14 @@ namespace v2rayN.Base
|
|||||||
_isRunning = true;
|
_isRunning = true;
|
||||||
if (p.WaitForExit(1000))
|
if (p.WaitForExit(1000))
|
||||||
{
|
{
|
||||||
if (showWindow)
|
//if (showWindow)
|
||||||
{
|
//{
|
||||||
throw new Exception("start tun mode fail");
|
throw new Exception("start tun mode fail");
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
throw new Exception(p.StandardError.ReadToEnd());
|
// throw new Exception(p.StandardError.ReadToEnd());
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
Global.processJob.AddProcess(p.Handle);
|
Global.processJob.AddProcess(p.Handle);
|
||||||
|
|||||||
@@ -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}"
|
||||||
@@ -278,6 +283,8 @@ namespace v2rayN.Handler
|
|||||||
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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File.Delete(fileName);
|
||||||
//_updateFunc(true, "");
|
//_updateFunc(true, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ namespace v2rayN.Mode
|
|||||||
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 bool enableDragDropSort { get; set; }
|
||||||
public Dictionary<string, int> mainLvColWidth { get; set; }
|
public Dictionary<string, int> mainLvColWidth { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +103,7 @@ 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 List<string> directIP { get; set; }
|
public List<string> directIP { get; set; }
|
||||||
public List<string> directProcess { get; set; }
|
public List<string> directProcess { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
18
v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
@@ -2392,6 +2392,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>
|
||||||
@@ -2644,6 +2653,15 @@ namespace v2rayN.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
|||||||
@@ -1063,4 +1063,10 @@
|
|||||||
<data name="menuMoveToGroup" xml:space="preserve">
|
<data name="menuMoveToGroup" xml:space="preserve">
|
||||||
<value>Move to group</value>
|
<value>Move to group</value>
|
||||||
</data>
|
</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>
|
||||||
</root>
|
</root>
|
||||||
@@ -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>
|
||||||
@@ -1063,4 +1063,10 @@
|
|||||||
<data name="menuMoveToGroup" xml:space="preserve">
|
<data name="menuMoveToGroup" xml:space="preserve">
|
||||||
<value>移至订阅分组</value>
|
<value>移至订阅分组</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSettingsTunModeCustomTemplate" xml:space="preserve">
|
||||||
|
<value>自定义配置模板</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
|
||||||
|
<value>启用服务器拖放排序(需重启)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -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,11 +602,22 @@ 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)
|
||||||
@@ -741,6 +753,47 @@ 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.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 测速
|
||||||
|
|||||||
@@ -86,6 +86,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -111,8 +112,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
|
||||||
@@ -226,7 +227,7 @@ namespace v2rayN.ViewModels
|
|||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SelectedMoveToGroup,
|
x => x.SelectedMoveToGroup,
|
||||||
y => y != null && !y.remarks.IsNullOrEmpty())
|
y => y != null && !y.remarks.IsNullOrEmpty())
|
||||||
.Subscribe(c => MoveToGroup(c));
|
.Subscribe(c => MoveToGroup(c));
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SelectedRouting,
|
x => x.SelectedRouting,
|
||||||
@@ -387,13 +388,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(() =>
|
||||||
{
|
{
|
||||||
@@ -637,6 +638,7 @@ namespace v2rayN.ViewModels
|
|||||||
SysProxyHandle.UpdateSysProxy(_config, true);
|
SysProxyHandle.UpdateSysProxy(_config, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_statistics?.SaveTo();
|
||||||
_statistics?.Close();
|
_statistics?.Close();
|
||||||
|
|
||||||
_coreHandler.CoreStop();
|
_coreHandler.CoreStop();
|
||||||
@@ -685,7 +687,7 @@ namespace v2rayN.ViewModels
|
|||||||
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
|
||||||
@@ -704,8 +706,8 @@ namespace v2rayN.ViewModels
|
|||||||
subRemarks = t.subRemarks,
|
subRemarks = t.subRemarks,
|
||||||
isActive = t.isActive,
|
isActive = t.isActive,
|
||||||
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),
|
||||||
@@ -1062,6 +1064,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)
|
||||||
{
|
{
|
||||||
@@ -1074,7 +1087,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()
|
||||||
@@ -1284,6 +1297,11 @@ namespace v2rayN.ViewModels
|
|||||||
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.checkPreReleaseUpdate);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ 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 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; }
|
||||||
@@ -70,6 +71,7 @@ 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 string TunDirectIP { get; set; }
|
[Reactive] public string TunDirectIP { get; set; }
|
||||||
[Reactive] public string TunDirectProcess { get; set; }
|
[Reactive] public string TunDirectProcess { get; set; }
|
||||||
#endregion
|
#endregion
|
||||||
@@ -134,6 +136,7 @@ namespace v2rayN.ViewModels
|
|||||||
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13;
|
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13;
|
||||||
AutoHideStartup = _config.autoHideStartup;
|
AutoHideStartup = _config.autoHideStartup;
|
||||||
EnableCheckPreReleaseUpdate = _config.checkPreReleaseUpdate;
|
EnableCheckPreReleaseUpdate = _config.checkPreReleaseUpdate;
|
||||||
|
EnableDragDropSort = _config.uiItem.enableDragDropSort;
|
||||||
autoUpdateInterval = _config.autoUpdateInterval;
|
autoUpdateInterval = _config.autoUpdateInterval;
|
||||||
autoUpdateSubInterval = _config.autoUpdateSubInterval;
|
autoUpdateSubInterval = _config.autoUpdateSubInterval;
|
||||||
trayMenuServersLimit = _config.trayMenuServersLimit;
|
trayMenuServersLimit = _config.trayMenuServersLimit;
|
||||||
@@ -150,6 +153,7 @@ 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;
|
||||||
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);
|
||||||
|
|
||||||
@@ -297,6 +301,7 @@ namespace v2rayN.ViewModels
|
|||||||
_config.autoUpdateInterval = autoUpdateInterval;
|
_config.autoUpdateInterval = autoUpdateInterval;
|
||||||
_config.autoUpdateSubInterval = autoUpdateSubInterval;
|
_config.autoUpdateSubInterval = autoUpdateSubInterval;
|
||||||
_config.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
|
_config.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
|
||||||
|
_config.uiItem.enableDragDropSort = EnableDragDropSort;
|
||||||
_config.trayMenuServersLimit = trayMenuServersLimit;
|
_config.trayMenuServersLimit = trayMenuServersLimit;
|
||||||
|
|
||||||
//systemProxy
|
//systemProxy
|
||||||
@@ -308,6 +313,7 @@ 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.directIP = Utils.String2List(TunDirectIP);
|
_config.tunModeItem.directIP = Utils.String2List(TunDirectIP);
|
||||||
_config.tunModeItem.directProcess = Utils.String2List(TunDirectProcess);
|
_config.tunModeItem.directProcess = Utils.String2List(TunDirectProcess);
|
||||||
|
|
||||||
|
|||||||
@@ -350,11 +350,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"
|
||||||
|
|||||||
@@ -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,6 +33,14 @@ 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));
|
||||||
@@ -91,8 +103,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
|
||||||
@@ -169,8 +181,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
|
||||||
@@ -372,18 +383,21 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
@@ -433,6 +447,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
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -415,6 +415,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" />
|
||||||
@@ -553,16 +554,30 @@
|
|||||||
Margin="{StaticResource SettingItemMargin}"
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbSettingsEnableDragDropSort}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togEnableDragDropSort"
|
||||||
|
Grid.Row="10"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="11"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsAutoUpdateInterval}" />
|
Text="{x:Static resx:ResUI.TbSettingsAutoUpdateInterval}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtautoUpdateInterval"
|
x:Name="txtautoUpdateInterval"
|
||||||
Grid.Row="10"
|
Grid.Row="11"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource SettingItemMargin}" />
|
Margin="{StaticResource SettingItemMargin}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="11"
|
Grid.Row="12"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@@ -570,13 +585,13 @@
|
|||||||
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="12"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource SettingItemMargin}" />
|
Margin="{StaticResource SettingItemMargin}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="12"
|
Grid.Row="13"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="{StaticResource SettingItemMargin}"
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@@ -584,7 +599,7 @@
|
|||||||
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="13"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource SettingItemMargin}" />
|
Margin="{StaticResource SettingItemMargin}" />
|
||||||
@@ -646,6 +661,7 @@
|
|||||||
<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 +704,8 @@
|
|||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource SettingItemMargin}" />
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
@@ -702,7 +719,34 @@
|
|||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Margin="{StaticResource SettingItemMargin}" />
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
|
<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="600"
|
||||||
|
Margin="{StaticResource SettingItemMargin}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
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}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid Margin="{StaticResource SettingItemMargin}">
|
<Grid Margin="{StaticResource SettingItemMargin}">
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ 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.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);
|
||||||
@@ -100,6 +101,7 @@ 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.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);
|
||||||
|
|
||||||
@@ -124,6 +126,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace v2rayN.Views
|
|||||||
private void LstSubscription_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
private void LstSubscription_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
ViewModel?.EditSub(false);
|
ViewModel?.EditSub(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuClose_Click(object sender, System.Windows.RoutedEventArgs e)
|
private void menuClose_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<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.2</FileVersion>
|
<FileVersion>6.6</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user