Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9738f90970 | ||
|
|
6ed0741339 | ||
|
|
e6b1e22245 | ||
|
|
6b922be0c6 | ||
|
|
6e35a260e8 | ||
|
|
1106fd8cf1 | ||
|
|
fb92b90d5c | ||
|
|
5effbee50b | ||
|
|
9bc50a9f34 | ||
|
|
2a5a339c27 | ||
|
|
78d182fff3 | ||
|
|
0efb0b5e3e | ||
|
|
a2e8755730 | ||
|
|
06ddedbc4c | ||
|
|
fa148cdf42 |
@@ -1,6 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace AmazTool
|
||||
@@ -20,18 +19,15 @@ namespace AmazTool
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Try to end the process(尝试结束进程).");
|
||||
try
|
||||
{
|
||||
Process[] existing = Process.GetProcessesByName(V2rayN());
|
||||
foreach (Process p in existing)
|
||||
{
|
||||
var path = p.MainModule?.FileName ?? "";
|
||||
if (path.StartsWith(GetPath(V2rayN())))
|
||||
{
|
||||
p.Kill();
|
||||
p.WaitForExit(100);
|
||||
}
|
||||
}
|
||||
var path = GetPath(V2rayN);
|
||||
Console.WriteLine(path);
|
||||
var existing = Process.GetProcessesByName(V2rayN);
|
||||
var pp = existing.FirstOrDefault(p => p.MainModule?.FileName != null && p.MainModule?.FileName == path);
|
||||
pp?.Kill();
|
||||
pp?.WaitForExit(1000);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -40,6 +36,7 @@ namespace AmazTool
|
||||
"Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN,否则可能升级失败。\n\n" + ex.StackTrace);
|
||||
}
|
||||
|
||||
Console.WriteLine("Start extracting files(开始解压文件).");
|
||||
StringBuilder sb = new();
|
||||
try
|
||||
{
|
||||
@@ -85,18 +82,17 @@ namespace AmazTool
|
||||
}
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
Console.WriteLine("Upgrade Failed.\n" +
|
||||
"(升级失败)." + sb.ToString());
|
||||
Console.WriteLine("Upgrade Failed(升级失败)." + sb.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)");
|
||||
Thread.Sleep(3000);
|
||||
Thread.Sleep(9000);
|
||||
Process process = new()
|
||||
{
|
||||
StartInfo = new()
|
||||
{
|
||||
FileName = V2rayN(),
|
||||
FileName = V2rayN,
|
||||
WorkingDirectory = StartupPath()
|
||||
}
|
||||
};
|
||||
@@ -123,19 +119,6 @@ namespace AmazTool
|
||||
return Path.Combine(startupPath, fileName);
|
||||
}
|
||||
|
||||
private static string V2rayN()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
if (File.Exists(GetPath("v2rayN.exe")))
|
||||
return "v2rayN";
|
||||
else
|
||||
return "v2rayN.Desktop";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "v2rayN.Desktop";
|
||||
}
|
||||
}
|
||||
private static string V2rayN => "v2rayN";
|
||||
}
|
||||
}
|
||||
@@ -720,7 +720,7 @@ namespace ServiceLib.Common
|
||||
}
|
||||
if (coreType != null)
|
||||
{
|
||||
tempPath = Path.Combine(tempPath, coreType.ToString());
|
||||
tempPath = Path.Combine(tempPath, coreType.ToLower().ToString());
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
await ConfigHandler.SetDefaultServer(_config, lstModel);
|
||||
|
||||
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
|
||||
var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
|
||||
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
|
||||
lstModel = (from t in lstModel
|
||||
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
|
||||
from t22 in t2b.DefaultIfEmpty()
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ServiceLib.Handler
|
||||
return new Tuple<ClashProxies, ClashProviders>(clashProxies, clashProviders);
|
||||
}
|
||||
|
||||
await Task.Delay(5000);
|
||||
await Task.Delay(2000);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -746,7 +746,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
|
||||
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
|
||||
var lstProfile = (from t in lstModel
|
||||
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
|
||||
from t33 in t3b.DefaultIfEmpty()
|
||||
@@ -1340,7 +1340,9 @@ namespace ServiceLib.Handler
|
||||
//Do not allow http protocol
|
||||
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
|
||||
{
|
||||
return -1;
|
||||
//TODO Temporary reminder to be removed later
|
||||
NoticeHandler.Instance.Enqueue(ResUI.InsecureUrlProtocol);
|
||||
//return -1;
|
||||
}
|
||||
|
||||
var queryVars = Utils.ParseQueryString(uri.Query);
|
||||
|
||||
@@ -12,18 +12,12 @@
|
||||
|
||||
if (node.ConfigType == EConfigType.Custom)
|
||||
{
|
||||
if (node.CoreType is ECoreType.mihomo)
|
||||
result = node.CoreType switch
|
||||
{
|
||||
result = await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName);
|
||||
}
|
||||
if (node.CoreType is ECoreType.sing_box)
|
||||
{
|
||||
result = await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await GenerateClientCustomConfig(node, fileName);
|
||||
}
|
||||
ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName),
|
||||
ECoreType.sing_box => await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName),
|
||||
_ => await GenerateClientCustomConfig(node, fileName)
|
||||
};
|
||||
}
|
||||
else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
|
||||
{
|
||||
|
||||
@@ -15,13 +15,38 @@ namespace ServiceLib.Handler
|
||||
private Process? _processPre;
|
||||
private Action<bool, string>? _updateFunc;
|
||||
|
||||
public void Init(Config config, Action<bool, string> updateFunc)
|
||||
public async Task Init(Config config, Action<bool, string> updateFunc)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = updateFunc;
|
||||
|
||||
Environment.SetEnvironmentVariable("v2ray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||
Environment.SetEnvironmentVariable("xray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||
Environment.SetEnvironmentVariable("V2RAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||
Environment.SetEnvironmentVariable("XRAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||
|
||||
if (Utils.IsLinux())
|
||||
{
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||
foreach (var it in coreInfo)
|
||||
{
|
||||
if (it.CoreType == ECoreType.v2rayN)
|
||||
{
|
||||
if (Utils.UpgradeAppExists(out var fileName))
|
||||
{
|
||||
await Utils.SetLinuxChmod(fileName);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var vName in it.CoreExes)
|
||||
{
|
||||
var exe = Utils.GetExeName(Utils.GetBinPath(vName, it.CoreType.ToString()));
|
||||
if (File.Exists(exe))
|
||||
{
|
||||
await Utils.SetLinuxChmod(exe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadCore(ProfileItem? node)
|
||||
|
||||
@@ -9,27 +9,31 @@ namespace ServiceLib.Handler
|
||||
private static readonly Lazy<ProfileExHandler> _instance = new(() => new());
|
||||
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
||||
private Queue<string> _queIndexIds = new();
|
||||
public ConcurrentBag<ProfileExItem> ProfileExs => _lstProfileEx;
|
||||
public static ProfileExHandler Instance => _instance.Value;
|
||||
|
||||
public ProfileExHandler()
|
||||
{
|
||||
Init();
|
||||
//Init();
|
||||
}
|
||||
|
||||
private async Task Init()
|
||||
public async Task Init()
|
||||
{
|
||||
await InitData();
|
||||
await Task.Run(async () =>
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await SaveQueueIndexIds();
|
||||
await Task.Delay(1000 * 600);
|
||||
await SaveQueueIndexIds();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
|
||||
{
|
||||
return _lstProfileEx;
|
||||
}
|
||||
|
||||
private async Task InitData()
|
||||
{
|
||||
await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )");
|
||||
|
||||
18
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
18
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -294,6 +294,24 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Please do not use the insecure HTTP protocol subscription address 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string InsecureUrlProtocol {
|
||||
get {
|
||||
return ResourceManager.GetString("InsecureUrlProtocol", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Invalid address (Url) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string InvalidUrlTip {
|
||||
get {
|
||||
return ResourceManager.GetString("InvalidUrlTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 {0} {1} already up to date. 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1354,4 +1354,10 @@
|
||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||
<value>Scan QR code in the image</value>
|
||||
</data>
|
||||
<data name="InvalidUrlTip" xml:space="preserve">
|
||||
<value>Invalid address (Url)</value>
|
||||
</data>
|
||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||
<value>Please do not use the insecure HTTP protocol subscription address</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1351,4 +1351,10 @@
|
||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||
<value>扫描图片中的二维码</value>
|
||||
</data>
|
||||
<data name="InvalidUrlTip" xml:space="preserve">
|
||||
<value>地址(Url)无效</value>
|
||||
</data>
|
||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||
<value>请不要使用不安全的HTTP协议订阅地址</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1231,4 +1231,10 @@
|
||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||
<value>掃描圖片中的二維碼</value>
|
||||
</data>
|
||||
<data name="InvalidUrlTip" xml:space="preserve">
|
||||
<value>地址(Url)無效</value>
|
||||
</data>
|
||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||
<value>請不要使用不安全的HTTP協定訂閱位址</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>7.0.0</Version>
|
||||
<Version>7.0.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -45,12 +45,16 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
if (RuntimeInformation.ProcessArchitecture != Architecture.X86)
|
||||
{
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
IsSelected = false,
|
||||
CoreType = _v2rayN,
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
IsSelected = false,
|
||||
CoreType = _v2rayN,
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
}
|
||||
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
IsSelected = true,
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace ServiceLib.ViewModels
|
||||
private async Task Init()
|
||||
{
|
||||
await ProxiesReload();
|
||||
await DelayTestTask();
|
||||
DelayTestTask();
|
||||
}
|
||||
|
||||
private async Task DoRulemodeSelected(bool c)
|
||||
@@ -434,25 +434,29 @@ namespace ServiceLib.ViewModels
|
||||
public async Task DelayTestTask()
|
||||
{
|
||||
var lastTime = DateTime.Now;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await Task.Delay(1000 * 60);
|
||||
|
||||
Observable.Interval(TimeSpan.FromSeconds(60))
|
||||
.Subscribe(async x =>
|
||||
{
|
||||
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var dtNow = DateTime.Now;
|
||||
if (_config.ClashUIItem.ProxiesAutoDelayTestInterval > 0)
|
||||
{
|
||||
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval == 0)
|
||||
{
|
||||
await ProxiesDelayTest();
|
||||
lastTime = dtNow;
|
||||
}
|
||||
Task.Delay(1000).Wait();
|
||||
}
|
||||
});
|
||||
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (_config.ClashUIItem.ProxiesAutoDelayTestInterval <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var dtNow = DateTime.Now;
|
||||
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
await ProxiesDelayTest();
|
||||
lastTime = dtNow;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion task
|
||||
|
||||
@@ -208,7 +208,8 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
await ConfigHandler.InitBuiltinRouting(_config);
|
||||
await ConfigHandler.InitBuiltinDNS(_config);
|
||||
CoreHandler.Instance.Init(_config, UpdateHandler);
|
||||
await ProfileExHandler.Instance.Init();
|
||||
await CoreHandler.Instance.Init(_config, UpdateHandler);
|
||||
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
||||
|
||||
if (_config.GuiItem.EnableStatistics)
|
||||
@@ -389,6 +390,10 @@ namespace ServiceLib.ViewModels
|
||||
RefreshServers();
|
||||
NoticeHandler.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));
|
||||
}
|
||||
else
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AddServerViaScanAsync()
|
||||
@@ -433,6 +438,10 @@ namespace ServiceLib.ViewModels
|
||||
RefreshServers();
|
||||
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan);
|
||||
}
|
||||
else
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -176,13 +176,14 @@ namespace ServiceLib.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
var lst = new List<RulesItem4Ray>();
|
||||
var lst = new List<RulesItem>();
|
||||
foreach (var it in SelectedSources ?? [SelectedSource])
|
||||
{
|
||||
var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
|
||||
if (item != null)
|
||||
{
|
||||
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
||||
var item2 = JsonUtils.DeepCopy(item); //JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
||||
item2.Id = null;
|
||||
lst.Add(item2 ?? new());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,18 @@ namespace ServiceLib.ViewModels
|
||||
public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = AppHandler.Instance.Config;
|
||||
SelectedRouting = new();
|
||||
SelectedServer = new();
|
||||
RunningServerToolTipText = "-";
|
||||
|
||||
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
|
||||
{
|
||||
EnableTun = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.TunModeItem.EnableTun = EnableTun = false;
|
||||
}
|
||||
|
||||
#region WhenAnyValue && ReactiveCommand
|
||||
|
||||
@@ -179,19 +191,6 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
private async Task Init()
|
||||
{
|
||||
SelectedRouting = new();
|
||||
SelectedServer = new();
|
||||
RunningServerToolTipText = "-";
|
||||
|
||||
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
|
||||
{
|
||||
EnableTun = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.TunModeItem.EnableTun = EnableTun = false;
|
||||
}
|
||||
|
||||
await RefreshRoutingsMenu();
|
||||
await InboundDisplayStatus();
|
||||
await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, true);
|
||||
|
||||
@@ -39,14 +39,14 @@ namespace ServiceLib.ViewModels
|
||||
var uri = Utils.TryUri(url);
|
||||
if (uri == null)
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.LvUrl);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.InvalidUrlTip);
|
||||
return;
|
||||
}
|
||||
//Do not allow http protocol
|
||||
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.LvUrl);
|
||||
return;
|
||||
NoticeHandler.Instance.Enqueue(ResUI.InsecureUrlProtocol);
|
||||
//return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,10 +161,7 @@
|
||||
<RowDefinition Height="8" />
|
||||
<RowDefinition Height="1*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Text="{Binding Name}"
|
||||
TextWrapping="WrapWithOverflow" />
|
||||
<TextBlock Grid.Row="0" Text="{Binding Name}" />
|
||||
<DockPanel Grid.Row="2">
|
||||
<TextBlock
|
||||
DockPanel.Dock="Right"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
<AssemblyName>v2rayN</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -284,6 +284,8 @@ namespace v2rayN.Views
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.V:
|
||||
if (_backupAndRestoreView?.IsVisible == true) return;
|
||||
|
||||
var clipboardData = WindowsUtils.GetClipboardData();
|
||||
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user