mirror of
https://github.com/2dust/v2rayN.git
synced 2026-09-14 02:12:06 +03:00
Add an option to check for update without proxy (#10090)
Checking for updates always dialed through the local proxy, which fails exactly when an update may be needed most - when no working server is available. Like the subscription-update menu, updating without the proxy is now possible: the Check Update window gets an "Update via proxy" toggle (persisted, on by default so existing behavior is unchanged), honored by the check-only, update and geo-file flows, and by the scheduled update check. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -136,7 +136,7 @@ public class TaskManager
|
||||
|
||||
var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask);
|
||||
|
||||
var msgs = await updateService.CheckHasUpdateOnlyAll(_config.CheckUpdateItem.CheckPreReleaseUpdate);
|
||||
var msgs = await updateService.CheckHasUpdateOnlyAll(_config.CheckUpdateItem.CheckPreReleaseUpdate, _config.CheckUpdateItem.UpdateViaProxy);
|
||||
foreach (var msg in msgs)
|
||||
{
|
||||
await _updateFunc?.Invoke(false, msg);
|
||||
|
||||
@@ -243,6 +243,7 @@ public class WebDavItem
|
||||
public class CheckUpdateItem
|
||||
{
|
||||
public bool CheckPreReleaseUpdate { get; set; }
|
||||
public bool UpdateViaProxy { get; set; } = true;
|
||||
public List<string>? SelectedCoreTypes { get; set; }
|
||||
}
|
||||
|
||||
|
||||
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -4238,6 +4238,15 @@ namespace ServiceLib.Resx {
|
||||
return ResourceManager.GetString("TbSettingsEnableCheckPreReleaseUpdate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Update via proxy 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsEnableUpdateViaProxy {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsEnableUpdateViaProxy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Enable sorting Configurations by drag-n-drop (requires restart) 的本地化字符串。
|
||||
|
||||
@@ -693,6 +693,9 @@
|
||||
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
|
||||
<value>به روز رسانی های پیش از انتشار را بررسی شود</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
|
||||
<value>بهروزرسانی از طریق پروکسی</value>
|
||||
</data>
|
||||
<data name="TbSettingsException" xml:space="preserve">
|
||||
<value>استثنا</value>
|
||||
</data>
|
||||
|
||||
@@ -693,6 +693,9 @@
|
||||
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
|
||||
<value>Check for pre-release</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
|
||||
<value>Update via proxy</value>
|
||||
</data>
|
||||
<data name="TbSettingsException" xml:space="preserve">
|
||||
<value>Exception</value>
|
||||
</data>
|
||||
|
||||
@@ -693,6 +693,9 @@
|
||||
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
|
||||
<value>检查 Pre-Release</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
|
||||
<value>通过代理更新</value>
|
||||
</data>
|
||||
<data name="TbSettingsException" xml:space="preserve">
|
||||
<value>例外</value>
|
||||
</data>
|
||||
|
||||
@@ -693,6 +693,9 @@
|
||||
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
|
||||
<value>檢查 Pre-Release</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
|
||||
<value>透過代理更新</value>
|
||||
</data>
|
||||
<data name="TbSettingsException" xml:space="preserve">
|
||||
<value>例外</value>
|
||||
</data>
|
||||
|
||||
@@ -7,7 +7,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
private readonly int _timeout = 30;
|
||||
private static readonly string _tag = "UpdateService";
|
||||
|
||||
public async Task CheckUpdateGuiN(bool preRelease)
|
||||
public async Task CheckUpdateGuiN(bool preRelease, bool blProxy = true)
|
||||
{
|
||||
var url = string.Empty;
|
||||
var fileName = string.Empty;
|
||||
@@ -31,7 +31,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
};
|
||||
|
||||
await UpdateFunc(false, string.Format(ResUI.MsgStartUpdating, ECoreType.v2rayN));
|
||||
var result = await CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease);
|
||||
var result = await CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease, blProxy);
|
||||
if (result.Success)
|
||||
{
|
||||
await UpdateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN));
|
||||
@@ -39,7 +39,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
|
||||
url = result.Url!;
|
||||
fileName = Utils.GetTempPath(Utils.GetGuid());
|
||||
await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, true, TimeSpan.FromSeconds(_timeout));
|
||||
await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, blProxy, TimeSpan.FromSeconds(_timeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -47,7 +47,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CheckUpdateCore(ECoreType type, bool preRelease)
|
||||
public async Task CheckUpdateCore(ECoreType type, bool preRelease, bool blProxy = true)
|
||||
{
|
||||
var url = string.Empty;
|
||||
var fileName = string.Empty;
|
||||
@@ -80,7 +80,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
};
|
||||
|
||||
await UpdateFunc(false, string.Format(ResUI.MsgStartUpdating, type));
|
||||
var result = await CheckUpdateAsync(downloadHandle, type, preRelease);
|
||||
var result = await CheckUpdateAsync(downloadHandle, type, preRelease, blProxy);
|
||||
if (result.Success)
|
||||
{
|
||||
await UpdateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type));
|
||||
@@ -89,7 +89,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
url = result.Url!;
|
||||
var ext = url.Contains(".tar.gz") ? ".tar.gz" : Path.GetExtension(url);
|
||||
fileName = Utils.GetTempPath(Utils.GetGuid() + ext);
|
||||
await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, true, TimeSpan.FromSeconds(_timeout));
|
||||
await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, blProxy, TimeSpan.FromSeconds(_timeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -100,7 +100,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<UpdateResult> CheckHasUpdateOnly(ECoreType type, bool preRelease)
|
||||
public async Task<UpdateResult> CheckHasUpdateOnly(ECoreType type, bool preRelease, bool blProxy = true)
|
||||
{
|
||||
if (!CoreInfoManager.Instance.IsCheckUpdateSupported(type))
|
||||
{
|
||||
@@ -109,10 +109,10 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
|
||||
var downloadHandle = new DownloadService();
|
||||
var checkPreRelease = CoreInfoManager.Instance.GetCheckPreRelease(type, preRelease);
|
||||
return await CheckUpdateAsync(downloadHandle, type, checkPreRelease);
|
||||
return await CheckUpdateAsync(downloadHandle, type, checkPreRelease, blProxy);
|
||||
}
|
||||
|
||||
public async Task<List<string>> CheckHasUpdateOnlyAll(bool preRelease)
|
||||
public async Task<List<string>> CheckHasUpdateOnlyAll(bool preRelease, bool blProxy = true)
|
||||
{
|
||||
var msgs = new List<string>();
|
||||
foreach (var type in CoreInfoManager.Instance.GetCheckUpdateCoreTypes())
|
||||
@@ -122,7 +122,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
continue;
|
||||
}
|
||||
|
||||
var result = await CheckHasUpdateOnly(type, preRelease);
|
||||
var result = await CheckHasUpdateOnly(type, preRelease, blProxy);
|
||||
if (result.Success && result.Version != null)
|
||||
{
|
||||
var msg = string.Format(ResUI.MsgCheckUpdateHasNewVersion, type, result.Version);
|
||||
@@ -137,7 +137,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
return msgs;
|
||||
}
|
||||
|
||||
public async Task UpdateGeoFileAll()
|
||||
public async Task UpdateGeoFileAll(bool blProxy = true)
|
||||
{
|
||||
var requests = new List<FileDownloadRequest>();
|
||||
requests.AddRange(GetGeoFilesRequest());
|
||||
@@ -145,17 +145,17 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
requests.AddRange(await GetSrsFileAllRequest());
|
||||
// NOTE: srs files are more small, so we reverse the order to ensure a good download experience for the user.
|
||||
requests.Reverse();
|
||||
await DownloadGeoFiles(requests);
|
||||
await DownloadGeoFiles(requests, blProxy);
|
||||
await UpdateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
|
||||
}
|
||||
|
||||
#region CheckUpdate private
|
||||
|
||||
private async Task<UpdateResult> CheckUpdateAsync(DownloadService downloadHandle, ECoreType type, bool preRelease)
|
||||
private async Task<UpdateResult> CheckUpdateAsync(DownloadService downloadHandle, ECoreType type, bool preRelease, bool blProxy)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await GetRemoteVersion(downloadHandle, type, preRelease);
|
||||
var result = await GetRemoteVersion(downloadHandle, type, preRelease, blProxy);
|
||||
if (!result.Success || result.Version is null)
|
||||
{
|
||||
return result;
|
||||
@@ -170,14 +170,14 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<UpdateResult> GetRemoteVersion(DownloadService downloadHandle, ECoreType type, bool preRelease)
|
||||
private async Task<UpdateResult> GetRemoteVersion(DownloadService downloadHandle, ECoreType type, bool preRelease, bool blProxy)
|
||||
{
|
||||
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(type);
|
||||
var tagName = string.Empty;
|
||||
if (preRelease || coreInfo?.LockedMaxVersion != null)
|
||||
{
|
||||
var url = coreInfo?.ReleaseApiUrl;
|
||||
var result = await downloadHandle.TryDownloadString(url, true, Global.AppName);
|
||||
var result = await downloadHandle.TryDownloadString(url, blProxy, Global.AppName);
|
||||
if (result.IsNullOrEmpty())
|
||||
{
|
||||
return new UpdateResult(false, "");
|
||||
@@ -209,7 +209,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
else
|
||||
{
|
||||
var url = Path.Combine(coreInfo.Url, "latest");
|
||||
var lastUrl = await downloadHandle.UrlRedirectAsync(url, true);
|
||||
var lastUrl = await downloadHandle.UrlRedirectAsync(url, blProxy);
|
||||
if (lastUrl == null)
|
||||
{
|
||||
return new UpdateResult(false, "");
|
||||
@@ -531,7 +531,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
};
|
||||
}
|
||||
|
||||
private async Task DownloadGeoFiles(List<FileDownloadRequest> requests)
|
||||
private async Task DownloadGeoFiles(List<FileDownloadRequest> requests, bool blProxy)
|
||||
{
|
||||
var tmpFilePathDict = new Dictionary<string, string>();
|
||||
var tmpFileRequests = new List<FileDownloadRequest>();
|
||||
@@ -586,7 +586,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
|
||||
_ = UpdateFunc(false, args.GetException().Message);
|
||||
};
|
||||
|
||||
await downloadHandle.DownloadSmallFilesAsync(tmpFileRequests, true, TimeSpan.FromSeconds(_timeout));
|
||||
await downloadHandle.DownloadSmallFilesAsync(tmpFileRequests, blProxy, TimeSpan.FromSeconds(_timeout));
|
||||
}
|
||||
|
||||
#endregion Geo private
|
||||
|
||||
@@ -13,6 +13,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
public ReactiveCommand<RxVoid, RxVoid> CheckUpdateCmd { get; }
|
||||
public ReactiveCommand<RxVoid, RxVoid> CheckOnlyCmd { get; }
|
||||
[Reactive] public partial bool EnableCheckPreReleaseUpdate { get; set; }
|
||||
[Reactive] public partial bool EnableUpdateViaProxy { get; set; }
|
||||
|
||||
public CheckUpdateViewModel()
|
||||
{
|
||||
@@ -33,12 +34,18 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
});
|
||||
|
||||
EnableCheckPreReleaseUpdate = _config.CheckUpdateItem.CheckPreReleaseUpdate;
|
||||
EnableUpdateViaProxy = _config.CheckUpdateItem.UpdateViaProxy;
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.EnableCheckPreReleaseUpdate,
|
||||
y => y == true)
|
||||
.Subscribe(c => _ = OnCheckPreReleaseUpdateChanged());
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.EnableUpdateViaProxy,
|
||||
y => y == true)
|
||||
.Subscribe(c => _ = OnUpdateViaProxyChanged());
|
||||
|
||||
RefreshCheckUpdateItems();
|
||||
}
|
||||
|
||||
@@ -98,6 +105,16 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
await SaveSelectedCoreTypes();
|
||||
}
|
||||
|
||||
private async Task OnUpdateViaProxyChanged()
|
||||
{
|
||||
if (_config.CheckUpdateItem.UpdateViaProxy == EnableUpdateViaProxy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_config.CheckUpdateItem.UpdateViaProxy = EnableUpdateViaProxy;
|
||||
await SaveSelectedCoreTypes();
|
||||
}
|
||||
|
||||
private async Task SaveSelectedCoreTypes()
|
||||
{
|
||||
_config.CheckUpdateItem.SelectedCoreTypes =
|
||||
@@ -145,7 +162,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
}
|
||||
|
||||
var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask);
|
||||
var result = await updateService.CheckHasUpdateOnly(item.CoreType.Value, EnableCheckPreReleaseUpdate);
|
||||
var result = await updateService.CheckHasUpdateOnly(item.CoreType.Value, EnableCheckPreReleaseUpdate, EnableUpdateViaProxy);
|
||||
if (result.Success && result.Version != null)
|
||||
{
|
||||
await UpdateView(item.CoreType, string.Format(ResUI.MsgCheckUpdateHasNewVersion, item.CoreType, result.Version));
|
||||
@@ -230,7 +247,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
UpdatedPlusPlus(null, "");
|
||||
}
|
||||
}
|
||||
await new UpdateService(_config, _updateUI).UpdateGeoFileAll()
|
||||
await new UpdateService(_config, _updateUI).UpdateGeoFileAll(EnableUpdateViaProxy)
|
||||
.ContinueWith(t => UpdatedPlusPlus(null, ""));
|
||||
}
|
||||
|
||||
@@ -245,7 +262,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
UpdatedPlusPlus(_v2rayN, msg);
|
||||
}
|
||||
}
|
||||
await new UpdateService(_config, _updateUI).CheckUpdateGuiN(preRelease)
|
||||
await new UpdateService(_config, _updateUI).CheckUpdateGuiN(preRelease, EnableUpdateViaProxy)
|
||||
.ContinueWith(t => UpdatedPlusPlus(_v2rayN, ""));
|
||||
}
|
||||
|
||||
@@ -263,7 +280,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
|
||||
|
||||
if (model.CoreType.HasValue)
|
||||
{
|
||||
await new UpdateService(_config, _updateUI).CheckUpdateCore(model.CoreType.Value, preRelease)
|
||||
await new UpdateService(_config, _updateUI).CheckUpdateCore(model.CoreType.Value, preRelease, EnableUpdateViaProxy)
|
||||
.ContinueWith(t => UpdatedPlusPlus(model.CoreType, ""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@
|
||||
HorizontalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsEnableUpdateViaProxy}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togEnableUpdateViaProxy"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
|
||||
@@ -11,6 +11,7 @@ public partial class CheckUpdateView : ReactiveUserControl<CheckUpdateViewModel>
|
||||
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableUpdateViaProxy, v => v.togEnableUpdateViaProxy.IsChecked).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
@@ -22,6 +22,16 @@
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsEnableUpdateViaProxy}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnableUpdateViaProxy"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
|
||||
@@ -11,6 +11,7 @@ public partial class CheckUpdateView
|
||||
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableUpdateViaProxy, v => v.togEnableUpdateViaProxy.IsChecked).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user