Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c22b57927c | ||
|
|
81b84d235c | ||
|
|
488e8aab00 | ||
|
|
fc43a9a726 | ||
|
|
31947fdcb3 | ||
|
|
34c7963d28 | ||
|
|
d91b0afb9a | ||
|
|
82eb3fd6bd | ||
|
|
3d3d3f83df | ||
|
|
6879c75bc8 |
File diff suppressed because it is too large
Load Diff
@@ -176,7 +176,7 @@ namespace ServiceLib.Common
|
||||
};
|
||||
|
||||
using var cts = new CancellationTokenSource();
|
||||
await downloader.DownloadFileTaskAsync(url, fileName, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);
|
||||
await downloader.DownloadFileTaskAsync(url, fileName, cts.Token);
|
||||
|
||||
downloadOpt = null;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,5 @@ namespace ServiceLib.Common
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
this.minor = int.Parse(parts[1]);
|
||||
this.patch = 0;
|
||||
}
|
||||
else if (parts.Length == 3)
|
||||
else if (parts.Length == 3 || parts.Length == 4)
|
||||
{
|
||||
this.major = int.Parse(parts[0]);
|
||||
this.minor = int.Parse(parts[1]);
|
||||
|
||||
@@ -593,8 +593,7 @@ namespace ServiceLib.Common
|
||||
{
|
||||
try
|
||||
{
|
||||
string location = GetExePath();
|
||||
return FileVersionInfo.GetVersionInfo(location)?.FileVersion ?? "0.0";
|
||||
return Assembly.GetExecutingAssembly()?.GetName()?.Version?.ToString() ?? "0.0";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
DispatcherRefreshServersBiz,
|
||||
DispatcherRefreshIcon,
|
||||
DispatcherCheckUpdate,
|
||||
DispatcherCheckUpdateFinished,
|
||||
DispatcherCheckUpdateFinished,
|
||||
DispatcherShowMsg,
|
||||
}
|
||||
}
|
||||
@@ -124,20 +124,16 @@ namespace ServiceLib.Handler
|
||||
mtu = 9000,
|
||||
};
|
||||
}
|
||||
if (config.guiItem == null)
|
||||
config.guiItem ??= new()
|
||||
{
|
||||
config.guiItem = new()
|
||||
{
|
||||
enableStatistics = false,
|
||||
};
|
||||
}
|
||||
if (config.uiItem == null)
|
||||
enableStatistics = false,
|
||||
};
|
||||
config.msgUIItem ??= new();
|
||||
|
||||
config.uiItem ??= new UIItem()
|
||||
{
|
||||
config.uiItem = new UIItem()
|
||||
{
|
||||
enableAutoAdjustMainLvColWidth = true
|
||||
};
|
||||
}
|
||||
enableAutoAdjustMainLvColWidth = true
|
||||
};
|
||||
if (config.uiItem.mainColumnItem == null)
|
||||
{
|
||||
config.uiItem.mainColumnItem = new();
|
||||
@@ -174,11 +170,11 @@ namespace ServiceLib.Handler
|
||||
}
|
||||
|
||||
config.mux4RayItem ??= new()
|
||||
{
|
||||
concurrency = 8,
|
||||
xudpConcurrency = 16,
|
||||
xudpProxyUDP443 = "reject"
|
||||
};
|
||||
{
|
||||
concurrency = 8,
|
||||
xudpConcurrency = 16,
|
||||
xudpProxyUDP443 = "reject"
|
||||
};
|
||||
|
||||
if (config.mux4SboxItem == null)
|
||||
{
|
||||
@@ -1510,6 +1506,7 @@ namespace ServiceLib.Handler
|
||||
item.userAgent = subItem.userAgent;
|
||||
item.sort = subItem.sort;
|
||||
item.filter = subItem.filter;
|
||||
item.updateTime = subItem.updateTime;
|
||||
item.convertTarget = subItem.convertTarget;
|
||||
item.prevProfile = subItem.prevProfile;
|
||||
item.nextProfile = subItem.nextProfile;
|
||||
|
||||
@@ -1097,7 +1097,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
address = Utils.IsNullOrEmpty(dNSItem?.domainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.domainDNSAddress,
|
||||
domains = [node.address]
|
||||
};
|
||||
servers.AsArray().Insert(0, JsonUtils.SerializeToNode(dnsServer));
|
||||
servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace ServiceLib.Handler
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async Task DownloadFileAsync(string url, bool blProxy, int downloadTimeout)
|
||||
public async Task DownloadFileAsync(string url, string fileName, bool blProxy, int downloadTimeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace ServiceLib.Handler
|
||||
var webProxy = GetWebProxy(blProxy);
|
||||
await DownloaderHelper.Instance.DownloadFileAsync(webProxy,
|
||||
url,
|
||||
Utils.GetTempPath(Utils.GetDownloadFileName(url)),
|
||||
fileName,
|
||||
progress,
|
||||
downloadTimeout);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ServiceLib.Handler
|
||||
namespace ServiceLib.Handler
|
||||
{
|
||||
public sealed class LazyConfig
|
||||
{
|
||||
|
||||
@@ -9,10 +9,9 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
private Action<bool, string> _updateFunc;
|
||||
private Config _config;
|
||||
private int _timeout = 30;
|
||||
|
||||
public event EventHandler<ResultEventArgs> AbsoluteCompleted;
|
||||
|
||||
public class ResultEventArgs : EventArgs
|
||||
private class ResultEventArgs
|
||||
{
|
||||
public bool Success;
|
||||
public string Msg;
|
||||
@@ -26,11 +25,12 @@ namespace ServiceLib.Handler
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckUpdateGuiN(Config config, Action<bool, string> update, bool preRelease)
|
||||
public async Task CheckUpdateGuiN(Config config, Action<bool, string> update, bool preRelease)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = update;
|
||||
var url = string.Empty;
|
||||
var fileName = string.Empty;
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
@@ -38,9 +38,7 @@ namespace ServiceLib.Handler
|
||||
if (args.Success)
|
||||
{
|
||||
_updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);
|
||||
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
|
||||
fileName = Utils.UrlEncode(fileName);
|
||||
_updateFunc(true, fileName);
|
||||
_updateFunc(true, Utils.UrlEncode(fileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -50,36 +48,31 @@ namespace ServiceLib.Handler
|
||||
downloadHandle.Error += (sender2, args) =>
|
||||
{
|
||||
_updateFunc(false, args.GetException().Message);
|
||||
_updateFunc(false, "");
|
||||
};
|
||||
AbsoluteCompleted += (sender2, args) =>
|
||||
{
|
||||
if (args.Success)
|
||||
{
|
||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN));
|
||||
_updateFunc(false, args.Msg);
|
||||
|
||||
url = args.Url;
|
||||
AskToDownload(downloadHandle, url, true).ContinueWith(task =>
|
||||
{
|
||||
_updateFunc(false, "");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_updateFunc(false, args.Msg);
|
||||
_updateFunc(false, "");
|
||||
}
|
||||
};
|
||||
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, ECoreType.v2rayN));
|
||||
CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease);
|
||||
var args = await CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease);
|
||||
if (args.Success)
|
||||
{
|
||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN));
|
||||
_updateFunc(false, args.Msg);
|
||||
|
||||
url = args.Url;
|
||||
fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
_updateFunc(false, args.Msg);
|
||||
}
|
||||
}
|
||||
|
||||
public async void CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)
|
||||
public async Task CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = update;
|
||||
var url = string.Empty;
|
||||
var fileName = string.Empty;
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
@@ -91,7 +84,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
try
|
||||
{
|
||||
_updateFunc(true, url);
|
||||
_updateFunc(true, fileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -105,31 +98,27 @@ namespace ServiceLib.Handler
|
||||
};
|
||||
downloadHandle.Error += (sender2, args) =>
|
||||
{
|
||||
_updateFunc(false, args.GetException().Message);
|
||||
_updateFunc(false, "");
|
||||
_updateFunc(false, args.GetException().Message);
|
||||
};
|
||||
|
||||
AbsoluteCompleted += (sender2, args) =>
|
||||
{
|
||||
if (args.Success)
|
||||
{
|
||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type));
|
||||
_updateFunc(false, args.Msg);
|
||||
|
||||
url = args.Url;
|
||||
AskToDownload(downloadHandle, url, true).ContinueWith(task =>
|
||||
{
|
||||
_updateFunc(false, "");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_updateFunc(false, args.Msg);
|
||||
_updateFunc(false, "");
|
||||
}
|
||||
};
|
||||
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, type));
|
||||
CheckUpdateAsync(downloadHandle, type, preRelease);
|
||||
var args = await CheckUpdateAsync(downloadHandle, type, preRelease);
|
||||
if (args.Success)
|
||||
{
|
||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type));
|
||||
_updateFunc(false, args.Msg);
|
||||
|
||||
url = args.Url;
|
||||
fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!args.Msg.IsNullOrEmpty())
|
||||
{
|
||||
_updateFunc(false, args.Msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> update)
|
||||
@@ -265,14 +254,11 @@ namespace ServiceLib.Handler
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateGeoFileAll(Config config, Action<bool, string> update)
|
||||
public async Task UpdateGeoFileAll(Config config, Action<bool, string> update)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await UpdateGeoFile("geosite", _config, update);
|
||||
await UpdateGeoFile("geoip", _config, update);
|
||||
_updateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
|
||||
});
|
||||
await UpdateGeoFile("geosite", _config, update);
|
||||
await UpdateGeoFile("geoip", _config, update);
|
||||
_updateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
|
||||
}
|
||||
|
||||
public void RunAvailabilityCheck(Action<bool, string> update)
|
||||
@@ -287,28 +273,28 @@ namespace ServiceLib.Handler
|
||||
|
||||
#region private
|
||||
|
||||
private async void CheckUpdateAsync(DownloadHandler downloadHandle, ECoreType type, bool preRelease)
|
||||
private async Task<ResultEventArgs> CheckUpdateAsync(DownloadHandler downloadHandle, ECoreType type, bool preRelease)
|
||||
{
|
||||
try
|
||||
{
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||
string url = coreInfo.coreReleaseApiUrl;
|
||||
var url = coreInfo?.coreReleaseApiUrl;
|
||||
|
||||
var result = await downloadHandle.DownloadStringAsync(url, true, Global.AppName);
|
||||
if (!Utils.IsNullOrEmpty(result))
|
||||
{
|
||||
ResponseHandler(type, result, preRelease);
|
||||
return await ParseDownloadUrl(type, result, preRelease);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.SaveLog("StatusCode error: " + url);
|
||||
return;
|
||||
return new ResultEventArgs(false, "");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
_updateFunc(false, ex.Message);
|
||||
return new ResultEventArgs(false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,7 +366,7 @@ namespace ServiceLib.Handler
|
||||
}
|
||||
}
|
||||
|
||||
private void ResponseHandler(ECoreType type, string gitHubReleaseApi, bool preRelease)
|
||||
private async Task<ResultEventArgs> ParseDownloadUrl(ECoreType type, string gitHubReleaseApi, bool preRelease)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -434,16 +420,16 @@ namespace ServiceLib.Handler
|
||||
|
||||
if (curVersion >= version && version != new SemanticVersion(0, 0, 0))
|
||||
{
|
||||
AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message));
|
||||
return;
|
||||
return new ResultEventArgs(false, message);
|
||||
}
|
||||
|
||||
AbsoluteCompleted?.Invoke(this, new ResultEventArgs(true, body, url));
|
||||
return new ResultEventArgs(true, body, url);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
_updateFunc(false, ex.Message);
|
||||
return new ResultEventArgs(false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,31 +458,12 @@ namespace ServiceLib.Handler
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task AskToDownload(DownloadHandler downloadHandle, string url, bool blAsk)
|
||||
{
|
||||
//bool blDownload = false;
|
||||
//if (blAsk)
|
||||
//{
|
||||
// if (UI.ShowYesNo(string.Format(ResUI.DownloadYesNo, url)) == MessageBoxResult.Yes)
|
||||
// {
|
||||
// blDownload = true;
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// blDownload = true;
|
||||
//}
|
||||
//if (blDownload)
|
||||
//{
|
||||
await downloadHandle.DownloadFileAsync(url, true, 60);
|
||||
//}
|
||||
}
|
||||
|
||||
private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> update)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = update;
|
||||
var url = string.Format(Global.GeoUrl, geoName);
|
||||
var fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
@@ -507,7 +474,6 @@ namespace ServiceLib.Handler
|
||||
|
||||
try
|
||||
{
|
||||
string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
string targetPath = Utils.GetBinPath($"{geoName}.dat");
|
||||
@@ -531,7 +497,8 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
_updateFunc(false, args.GetException().Message);
|
||||
};
|
||||
await AskToDownload(downloadHandle, url, false);
|
||||
|
||||
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||
}
|
||||
|
||||
#endregion private
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceLib.Models
|
||||
namespace ServiceLib.Models
|
||||
{
|
||||
public class CheckUpdateItem
|
||||
{
|
||||
@@ -14,4 +8,4 @@ namespace ServiceLib.Models
|
||||
public string? fileName { get; set; }
|
||||
public bool? isFinished { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
public GrpcItem grpcItem { get; set; }
|
||||
public RoutingBasicItem routingBasicItem { get; set; }
|
||||
public GUIItem guiItem { get; set; }
|
||||
public MsgUIItem msgUIItem { get; set; }
|
||||
public UIItem uiItem { get; set; }
|
||||
public ConstItem constItem { get; set; }
|
||||
public SpeedTestItem speedTestItem { get; set; }
|
||||
|
||||
@@ -107,6 +107,13 @@
|
||||
public bool enableLog { get; set; } = true;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MsgUIItem
|
||||
{
|
||||
public string? mainMsgFilter { get; set; }
|
||||
public bool? autoRefresh { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class UIItem
|
||||
{
|
||||
@@ -126,7 +133,6 @@
|
||||
public bool enableDragDropSort { get; set; }
|
||||
public bool doubleClick2Activate { get; set; }
|
||||
public bool autoHideStartup { get; set; }
|
||||
public string mainMsgFilter { get; set; }
|
||||
public List<ColumnItem> mainColumnItem { get; set; }
|
||||
public bool showInTaskbar { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>6.57</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -12,7 +13,7 @@
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||
<PackageReference Include="Splat.NLog" Version="15.1.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.0.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.1.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
[Reactive]
|
||||
public ProfileItem SelectedSource { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string? CoreType { get; set; }
|
||||
|
||||
|
||||
@@ -28,9 +28,13 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
RefreshSubItems();
|
||||
|
||||
CheckUpdateCmd = ReactiveCommand.Create(() =>
|
||||
CheckUpdateCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
CheckUpdate();
|
||||
await CheckUpdate()
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdateFinished();
|
||||
});
|
||||
});
|
||||
EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate;
|
||||
IsCheckUpdate = true;
|
||||
@@ -77,9 +81,11 @@ namespace ServiceLib.ViewModels
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckUpdate()
|
||||
private async Task CheckUpdate()
|
||||
{
|
||||
_lstUpdated.Clear();
|
||||
_lstUpdated = _checkUpdateItem.Where(x => x.isSelected == true)
|
||||
.Select(x => new CheckUpdateItem() { coreType = x.coreType }).ToList();
|
||||
|
||||
for (int k = _checkUpdateItem.Count - 1; k >= 0; k--)
|
||||
{
|
||||
@@ -87,23 +93,22 @@ namespace ServiceLib.ViewModels
|
||||
if (item.isSelected == true)
|
||||
{
|
||||
IsCheckUpdate = false;
|
||||
_lstUpdated.Add(new CheckUpdateItem() { coreType = item.coreType });
|
||||
UpdateView(item.coreType, "...");
|
||||
if (item.coreType == _geo)
|
||||
{
|
||||
CheckUpdateGeo();
|
||||
await CheckUpdateGeo();
|
||||
}
|
||||
else if (item.coreType == ECoreType.v2rayN.ToString())
|
||||
{
|
||||
CheckUpdateN(EnableCheckPreReleaseUpdate);
|
||||
await CheckUpdateN(EnableCheckPreReleaseUpdate);
|
||||
}
|
||||
else if (item.coreType == ECoreType.mihomo.ToString())
|
||||
{
|
||||
CheckUpdateCore(item, false);
|
||||
await CheckUpdateCore(item, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
|
||||
await CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +128,7 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckUpdateGeo()
|
||||
private async Task CheckUpdateGeo()
|
||||
{
|
||||
void _updateUI(bool success, string msg)
|
||||
{
|
||||
@@ -131,13 +136,16 @@ namespace ServiceLib.ViewModels
|
||||
if (success)
|
||||
{
|
||||
UpdatedPlusPlus(_geo, "");
|
||||
UpdateFinished();
|
||||
}
|
||||
}
|
||||
(new UpdateHandler()).UpdateGeoFileAll(_config, _updateUI);
|
||||
await (new UpdateHandler()).UpdateGeoFileAll(_config, _updateUI)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdatedPlusPlus(_geo, "");
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckUpdateN(bool preRelease)
|
||||
private async Task CheckUpdateN(bool preRelease)
|
||||
{
|
||||
//Check for standalone windows .Net version
|
||||
if (Utils.IsWindows()
|
||||
@@ -151,54 +159,38 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
void _updateUI(bool success, string msg)
|
||||
{
|
||||
UpdateView(ECoreType.v2rayN.ToString(), msg);
|
||||
if (success)
|
||||
{
|
||||
UpdateView(ECoreType.v2rayN.ToString(), ResUI.OperationSuccess);
|
||||
UpdatedPlusPlus(ECoreType.v2rayN.ToString(), msg);
|
||||
UpdateFinished();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg.IsNullOrEmpty())
|
||||
{
|
||||
UpdatedPlusPlus(ECoreType.v2rayN.ToString(), "");
|
||||
UpdateFinished();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateView(ECoreType.v2rayN.ToString(), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
(new UpdateHandler()).CheckUpdateGuiN(_config, _updateUI, preRelease);
|
||||
await (new UpdateHandler()).CheckUpdateGuiN(_config, _updateUI, preRelease)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdatedPlusPlus(ECoreType.v2rayN.ToString(), "");
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckUpdateCore(CheckUpdateItem item, bool preRelease)
|
||||
private async Task CheckUpdateCore(CheckUpdateItem item, bool preRelease)
|
||||
{
|
||||
void _updateUI(bool success, string msg)
|
||||
{
|
||||
UpdateView(item.coreType, msg);
|
||||
if (success)
|
||||
{
|
||||
UpdateView(item.coreType, ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
|
||||
|
||||
UpdatedPlusPlus(item.coreType, msg);
|
||||
UpdateFinished();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg.IsNullOrEmpty())
|
||||
{
|
||||
UpdatedPlusPlus(item.coreType, "");
|
||||
UpdateFinished();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateView(item.coreType, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
var type = (ECoreType)Enum.Parse(typeof(ECoreType), item.coreType);
|
||||
(new UpdateHandler()).CheckUpdateCore(type, _config, _updateUI, preRelease);
|
||||
await (new UpdateHandler()).CheckUpdateCore(type, _config, _updateUI, preRelease)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdatedPlusPlus(item.coreType, "");
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateFinished()
|
||||
@@ -206,13 +198,15 @@ namespace ServiceLib.ViewModels
|
||||
if (_lstUpdated.Count > 0 && _lstUpdated.Count(x => x.isFinished == true) == _lstUpdated.Count)
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.DispatcherCheckUpdateFinished, false);
|
||||
|
||||
Task.Delay(1000);
|
||||
UpgradeCore();
|
||||
|
||||
if (_lstUpdated.Any(x => x.coreType == ECoreType.v2rayN.ToString() && x.isFinished == true))
|
||||
{
|
||||
Task.Delay(1000);
|
||||
UpgradeN();
|
||||
}
|
||||
Task.Delay(1000);
|
||||
_updateView?.Invoke(EViewAction.DispatcherCheckUpdateFinished, true);
|
||||
}
|
||||
}
|
||||
@@ -270,7 +264,7 @@ namespace ServiceLib.ViewModels
|
||||
continue;
|
||||
}
|
||||
|
||||
var fileName = Utils.GetTempPath(Utils.GetDownloadFileName(item.fileName));
|
||||
var fileName = item.fileName;
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
continue;
|
||||
|
||||
111
v2rayN/ServiceLib/ViewModels/MsgViewModel.cs
Normal file
111
v2rayN/ServiceLib/ViewModels/MsgViewModel.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ServiceLib.ViewModels
|
||||
{
|
||||
public class MsgViewModel : MyReactiveObject
|
||||
{
|
||||
private ConcurrentQueue<string> _queueMsg = new();
|
||||
private int _numMaxMsg = 500;
|
||||
private string _lastMsgFilter = string.Empty;
|
||||
private bool _lastMsgFilterNotAvailable;
|
||||
private bool _blLockShow = false;
|
||||
|
||||
[Reactive]
|
||||
public string MsgFilter { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool AutoRefresh { get; set; }
|
||||
|
||||
public MsgViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_updateView = updateView;
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
|
||||
MessageBus.Current.Listen<string>(Global.CommandSendMsgView).Subscribe(async x => await AppendQueueMsg(x));
|
||||
|
||||
MsgFilter = _config.msgUIItem.mainMsgFilter ?? string.Empty;
|
||||
AutoRefresh = _config.msgUIItem.autoRefresh ?? true;
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.MsgFilter)
|
||||
.Subscribe(c => _config.msgUIItem.mainMsgFilter = MsgFilter);
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.AutoRefresh,
|
||||
y => y == true)
|
||||
.Subscribe(c => { _config.msgUIItem.autoRefresh = AutoRefresh; });
|
||||
}
|
||||
|
||||
private async Task AppendQueueMsg(string msg)
|
||||
{
|
||||
//if (msg == Global.CommandClearMsg)
|
||||
//{
|
||||
// ClearMsg();
|
||||
// return;
|
||||
//}
|
||||
if (AutoRefresh == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_ = EnqueueQueueMsg(msg);
|
||||
|
||||
if (_blLockShow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_blLockShow = true;
|
||||
|
||||
await Task.Delay(100);
|
||||
var txt = string.Join("", _queueMsg.ToArray());
|
||||
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, txt);
|
||||
|
||||
_blLockShow = false;
|
||||
}
|
||||
|
||||
private async Task EnqueueQueueMsg(string msg)
|
||||
{
|
||||
//filter msg
|
||||
if (MsgFilter != _lastMsgFilter) _lastMsgFilterNotAvailable = false;
|
||||
if (!Utils.IsNullOrEmpty(MsgFilter) && !_lastMsgFilterNotAvailable)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Regex.IsMatch(msg, MsgFilter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_lastMsgFilterNotAvailable = true;
|
||||
}
|
||||
}
|
||||
_lastMsgFilter = MsgFilter;
|
||||
|
||||
//Enqueue
|
||||
if (_queueMsg.Count > _numMaxMsg)
|
||||
{
|
||||
for (int k = 0; k < _queueMsg.Count - _numMaxMsg; k++)
|
||||
{
|
||||
_queueMsg.TryDequeue(out _);
|
||||
}
|
||||
}
|
||||
_queueMsg.Enqueue(msg);
|
||||
if (!msg.EndsWith(Environment.NewLine))
|
||||
{
|
||||
_queueMsg.Enqueue(Environment.NewLine);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearMsg()
|
||||
{
|
||||
_queueMsg.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,6 +279,7 @@ namespace v2rayN.Desktop.Views
|
||||
var clipboardData = await AvaUtils.GetClipboardData(this);
|
||||
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
||||
break;
|
||||
|
||||
case EViewAction.AdjustMainLvColWidth:
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
Locator.Current.GetService<ProfilesViewModel>()?.AutofitColumnWidthAsync(),
|
||||
|
||||
@@ -66,14 +66,12 @@
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
IsVisible="False"
|
||||
Text="{x:Static resx:ResUI.TbAutoScrollToEnd}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togScrollToEnd"
|
||||
Margin="8,0"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="True"
|
||||
IsVisible="False" />
|
||||
IsChecked="True" />
|
||||
</WrapPanel>
|
||||
<TextBox
|
||||
Name="txtMsg"
|
||||
|
||||
@@ -1,103 +1,54 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Reactive.Disposables;
|
||||
using v2rayN.Desktop.Common;
|
||||
|
||||
namespace v2rayN.Desktop.Views
|
||||
{
|
||||
public partial class MsgView : UserControl
|
||||
public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
||||
{
|
||||
private static Config? _config;
|
||||
|
||||
private string lastMsgFilter = string.Empty;
|
||||
private bool lastMsgFilterNotAvailable;
|
||||
private ConcurrentBag<string> _lstMsg = [];
|
||||
|
||||
public MsgView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_config = LazyConfig.Instance.Config;
|
||||
MessageBus.Current.Listen<string>(Global.CommandSendMsgView).Subscribe(x => DelegateAppendText(x));
|
||||
//Global.PresetMsgFilters.ForEach(it =>
|
||||
//{
|
||||
// cmbMsgFilter.Items.Add(it);
|
||||
//});
|
||||
if (!_config.uiItem.mainMsgFilter.IsNullOrEmpty())
|
||||
|
||||
ViewModel = new MsgViewModel(UpdateViewHandler);
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
cmbMsgFilter.Text = _config.uiItem.mainMsgFilter;
|
||||
}
|
||||
cmbMsgFilter.TextChanged += (s, e) =>
|
||||
{
|
||||
_config.uiItem.mainMsgFilter = cmbMsgFilter.Text?.ToString();
|
||||
};
|
||||
this.Bind(ViewModel, vm => vm.MsgFilter, v => v.cmbMsgFilter.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.AutoRefresh, v => v.togAutoRefresh.IsChecked).DisposeWith(disposables);
|
||||
});
|
||||
}
|
||||
|
||||
private void DelegateAppendText(string msg)
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => AppendText(msg), DispatcherPriority.ApplicationIdle);
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.DispatcherShowMsg:
|
||||
if (obj is null) return false;
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
ShowMsg(obj),
|
||||
DispatcherPriority.ApplicationIdle);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
|
||||
public void AppendText(string msg)
|
||||
private void ShowMsg(object msg)
|
||||
{
|
||||
if (msg == Global.CommandClearMsg)
|
||||
{
|
||||
ClearMsg();
|
||||
return;
|
||||
}
|
||||
if (togAutoRefresh.IsChecked == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var MsgFilter = cmbMsgFilter.Text?.ToString();
|
||||
if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;
|
||||
if (!Utils.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Regex.IsMatch(msg, MsgFilter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
lastMsgFilterNotAvailable = true;
|
||||
}
|
||||
}
|
||||
lastMsgFilter = MsgFilter;
|
||||
|
||||
ShowMsg(msg);
|
||||
|
||||
txtMsg.Text = msg.ToString();
|
||||
if (togScrollToEnd.IsChecked ?? true)
|
||||
{
|
||||
txtMsg.CaretIndex = int.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowMsg(string msg)
|
||||
{
|
||||
if (_lstMsg.Count > 999)
|
||||
{
|
||||
ClearMsg();
|
||||
}
|
||||
if (!msg.EndsWith(Environment.NewLine))
|
||||
{
|
||||
_lstMsg.Add(Environment.NewLine);
|
||||
}
|
||||
_lstMsg.Add(msg);
|
||||
// if (!msg.EndsWith(Environment.NewLine))
|
||||
// {
|
||||
// _lstMsg.Add(Environment.NewLine);
|
||||
// }
|
||||
this.txtMsg.Text = string.Join("", _lstMsg);
|
||||
}
|
||||
|
||||
public void ClearMsg()
|
||||
{
|
||||
_lstMsg.Clear();
|
||||
ViewModel?.ClearMsg();
|
||||
txtMsg.Clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<ApplicationIcon>v2rayN.ico</ApplicationIcon>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
<FileVersion>6.55</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -26,8 +25,8 @@
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.3" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="3.1.6" />
|
||||
<PackageReference Include="Semi.Avalonia" Version="11.1.0.2" />
|
||||
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.1.0.2" />
|
||||
<PackageReference Include="Semi.Avalonia" Version="11.1.0.3" />
|
||||
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.1.0.3" />
|
||||
<PackageReference Include="ReactiveUI" Version="20.1.1" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Application
|
||||
x:Class="v2rayN.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
ShutdownMode="OnExplicitShutdown"
|
||||
StartupUri="Views/MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
IsCancel="True"
|
||||
IsDefault="True"
|
||||
Style="{StaticResource MaterialDesignFlatButton}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
@@ -106,7 +105,6 @@
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</reactiveui:ReactiveUserControl>
|
||||
@@ -34,6 +34,7 @@ namespace v2rayN.Views
|
||||
ViewModel?.UpdateViewResult((CheckUpdateItem)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherCheckUpdateFinished:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
@@ -41,7 +42,6 @@ namespace v2rayN.Views
|
||||
ViewModel?.UpdateFinishedResult((bool)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace v2rayN.Views
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config.globalHotkeys ??= new List<KeyEventItem>();
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace v2rayN.Views
|
||||
{
|
||||
public partial class MainWindow
|
||||
{
|
||||
private static Config _config;
|
||||
private static Config _config;
|
||||
private CheckUpdateView? _checkUpdateView;
|
||||
|
||||
public MainWindow()
|
||||
@@ -206,7 +206,10 @@ namespace v2rayN.Views
|
||||
|
||||
private void OnProgramStarted(object state, bool timeout)
|
||||
{
|
||||
ShowHideWindow(true);
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
ShowHideWindow(true);
|
||||
}));
|
||||
}
|
||||
|
||||
private void DelegateSnackMsg(string content)
|
||||
@@ -290,7 +293,10 @@ namespace v2rayN.Views
|
||||
break;
|
||||
|
||||
case EViewAction.Shutdown:
|
||||
Application.Current.Shutdown();
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.ScanScreenTask:
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<UserControl
|
||||
<reactiveui:ReactiveUserControl
|
||||
x:Class="v2rayN.Views.MsgView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:TypeArguments="vms:MsgViewModel"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="2">
|
||||
<WrapPanel
|
||||
@@ -23,8 +26,7 @@
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}"
|
||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||
IsEditable="True"
|
||||
Style="{StaticResource DefComboBox}"
|
||||
TextBoxBase.TextChanged="cmbMsgFilter_TextChanged" />
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
<Button
|
||||
x:Name="btnCopy"
|
||||
Width="24"
|
||||
@@ -96,4 +98,4 @@
|
||||
</TextBox.ContextMenu>
|
||||
</TextBox>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
</reactiveui:ReactiveUserControl>
|
||||
@@ -1,22 +1,23 @@
|
||||
using ReactiveUI;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace v2rayN.Views
|
||||
{
|
||||
public partial class MsgView
|
||||
{
|
||||
private static Config? _config;
|
||||
|
||||
private string lastMsgFilter = string.Empty;
|
||||
private bool lastMsgFilterNotAvailable;
|
||||
|
||||
public MsgView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_config = LazyConfig.Instance.Config;
|
||||
MessageBus.Current.Listen<string>(Global.CommandSendMsgView).Subscribe(x => DelegateAppendText(x));
|
||||
|
||||
ViewModel = new MsgViewModel(UpdateViewHandler);
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.MsgFilter, v => v.cmbMsgFilter.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.AutoRefresh, v => v.togAutoRefresh.IsChecked).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
btnCopy.Click += menuMsgViewCopyAll_Click;
|
||||
btnClear.Click += menuMsgViewClear_Click;
|
||||
@@ -29,70 +30,37 @@ namespace v2rayN.Views
|
||||
{
|
||||
cmbMsgFilter.Items.Add(it);
|
||||
});
|
||||
if (!_config.uiItem.mainMsgFilter.IsNullOrEmpty())
|
||||
{
|
||||
cmbMsgFilter.Text = _config.uiItem.mainMsgFilter;
|
||||
}
|
||||
}
|
||||
|
||||
private void DelegateAppendText(string msg)
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
Dispatcher.BeginInvoke(AppendText, DispatcherPriority.ApplicationIdle, msg);
|
||||
}
|
||||
|
||||
public void AppendText(string msg)
|
||||
{
|
||||
if (msg == Global.CommandClearMsg)
|
||||
switch (action)
|
||||
{
|
||||
ClearMsg();
|
||||
return;
|
||||
}
|
||||
if (togAutoRefresh.IsChecked == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var MsgFilter = cmbMsgFilter.Text.TrimEx();
|
||||
if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;
|
||||
if (!Utils.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Regex.IsMatch(msg, MsgFilter)) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>쳣
|
||||
case EViewAction.DispatcherShowMsg:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
lastMsgFilterNotAvailable = true;
|
||||
}
|
||||
ShowMsg(obj);
|
||||
}), DispatcherPriority.ApplicationIdle);
|
||||
break;
|
||||
}
|
||||
lastMsgFilter = MsgFilter;
|
||||
|
||||
ShowMsg(msg);
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
|
||||
private void ShowMsg(object msg)
|
||||
{
|
||||
txtMsg.BeginChange();
|
||||
txtMsg.Text = msg.ToString();
|
||||
if (togScrollToEnd.IsChecked ?? true)
|
||||
{
|
||||
txtMsg.ScrollToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowMsg(string msg)
|
||||
{
|
||||
if (txtMsg.LineCount > 999)
|
||||
{
|
||||
ClearMsg();
|
||||
}
|
||||
this.txtMsg.AppendText(msg);
|
||||
if (!msg.EndsWith(Environment.NewLine))
|
||||
{
|
||||
this.txtMsg.AppendText(Environment.NewLine);
|
||||
}
|
||||
txtMsg.EndChange();
|
||||
}
|
||||
|
||||
public void ClearMsg()
|
||||
{
|
||||
ViewModel?.ClearMsg();
|
||||
txtMsg.Clear();
|
||||
}
|
||||
|
||||
@@ -118,10 +86,5 @@ namespace v2rayN.Views
|
||||
{
|
||||
ClearMsg();
|
||||
}
|
||||
|
||||
private void cmbMsgFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
_config.uiItem.mainMsgFilter = cmbMsgFilter.Text.TrimEx();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
<reactiveui:ReactiveWindow
|
||||
x:Class="v2rayN.Views.RoutingRuleSettingWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
||||
Width="960"
|
||||
Height="700"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<reactiveui:ReactiveWindow
|
||||
x:Class="v2rayN.Views.SubEditWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||
Title="{x:Static resx:ResUI.menuSubSetting}"
|
||||
Width="700"
|
||||
Height="600"
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<reactiveui:ReactiveUserControl
|
||||
x:Class="v2rayN.Views.ThemeSettingView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="clr-namespace:v2rayN.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||
d:DesignHeight="450"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<ApplicationIcon>v2rayN.ico</ApplicationIcon>
|
||||
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
|
||||
<FileVersion>6.56</FileVersion>
|
||||
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user