From f9fedae1a0d4f27aebeccaf09901431a58daa0cd Mon Sep 17 00:00:00 2001 From: SternI Date: Thu, 2 Apr 2026 20:20:06 +0200 Subject: [PATCH] HTTP request timeout configurable for all requests --- FModel/Framework/FRestRequest.cs | 3 ++- FModel/Settings/DirectorySettings.cs | 7 ------- FModel/Settings/UserSettings.cs | 7 +++++++ FModel/ViewModels/CUE4ParseViewModel.cs | 2 +- FModel/ViewModels/SettingsViewModel.cs | 12 ++---------- FModel/Views/SettingsView.xaml | 14 +++++++------- FModel/Views/SettingsView.xaml.cs | 20 ++++++++++++-------- 7 files changed, 31 insertions(+), 34 deletions(-) diff --git a/FModel/Framework/FRestRequest.cs b/FModel/Framework/FRestRequest.cs index b09cf30c..7d786dbc 100644 --- a/FModel/Framework/FRestRequest.cs +++ b/FModel/Framework/FRestRequest.cs @@ -1,11 +1,12 @@ using System; +using FModel.Settings; using RestSharp; namespace FModel.Framework; public class FRestRequest : RestRequest { - private const int TimeoutSeconds = 5; + private int TimeoutSeconds = UserSettings.Default.HttpRequestTimeout; public FRestRequest(string url, Method method = Method.Get) : base(url, method) { diff --git a/FModel/Settings/DirectorySettings.cs b/FModel/Settings/DirectorySettings.cs index 47d7c057..8cf126c7 100644 --- a/FModel/Settings/DirectorySettings.cs +++ b/FModel/Settings/DirectorySettings.cs @@ -106,13 +106,6 @@ public class DirectorySettings : ViewModel, ICloneable set => SetProperty(ref _criwareDecryptionKey, value); } - private uint _onDemandTimeout = 120; - public uint OnDemandTimeout - { - get => Math.Max(_onDemandTimeout, 60); - set => SetProperty(ref _onDemandTimeout, Math.Max(_onDemandTimeout, 60)); - } - private bool Equals(DirectorySettings other) { return GameDirectory == other.GameDirectory && UeVersion == other.UeVersion; diff --git a/FModel/Settings/UserSettings.cs b/FModel/Settings/UserSettings.cs index bca1427d..5f90cde3 100644 --- a/FModel/Settings/UserSettings.cs +++ b/FModel/Settings/UserSettings.cs @@ -544,5 +544,12 @@ namespace FModel.Settings get => _previewTexturesAssetExplorer; set => SetProperty(ref _previewTexturesAssetExplorer, value); } + + private int _httpRequestTimeout = 30; + public int HttpRequestTimeout + { + get => _httpRequestTimeout; + set => SetProperty(ref _httpRequestTimeout, Math.Max(value, 30)); + } } } diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 4c9212e9..4a715692 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -231,7 +231,7 @@ public class CUE4ParseViewModel : ViewModel { ChunkHostUri = new Uri("https://download.epicgames.com/", UriKind.Absolute), ChunkCacheDirectory = Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, ".data")), - Timeout = TimeSpan.FromSeconds(UserSettings.Default.CurrentDir.OnDemandTimeout) + Timeout = TimeSpan.FromSeconds(UserSettings.Default.HttpRequestTimeout) }; switch (Provider) diff --git a/FModel/ViewModels/SettingsViewModel.cs b/FModel/ViewModels/SettingsViewModel.cs index ca0c4897..0ea9e52d 100644 --- a/FModel/ViewModels/SettingsViewModel.cs +++ b/FModel/ViewModels/SettingsViewModel.cs @@ -172,13 +172,6 @@ public class SettingsViewModel : ViewModel set => SetProperty(ref _criwareDecryptionKey, value); } - private uint _onDemandTimeout = 120; - public uint OnDemandTimeout - { - get => Math.Max(_onDemandTimeout, 60); - set => SetProperty(ref _onDemandTimeout, Math.Max(_onDemandTimeout, 60)); - } - public bool SocketSettingsEnabled => SelectedMeshExportFormat == EMeshFormat.ActorX; public bool CompressionSettingsEnabled => SelectedMeshExportFormat == EMeshFormat.UEFormat; @@ -205,6 +198,7 @@ public class SettingsViewModel : ViewModel private string _codeSnapshot; private string _modelSnapshot; private string _gameSnapshot; + private int _httpRequestTimeout; private ETexturePlatform _uePlatformSnapshot; private EGame _ueGameSnapshot; private IList _customVersionsSnapshot; @@ -238,13 +232,13 @@ public class SettingsViewModel : ViewModel _codeSnapshot = UserSettings.Default.CodeDirectory; _modelSnapshot = UserSettings.Default.ModelDirectory; _gameSnapshot = UserSettings.Default.GameDirectory; + _httpRequestTimeout = UserSettings.Default.HttpRequestTimeout; _uePlatformSnapshot = UserSettings.Default.CurrentDir.TexturePlatform; _ueGameSnapshot = UserSettings.Default.CurrentDir.UeVersion; _customVersionsSnapshot = UserSettings.Default.CurrentDir.Versioning.CustomVersions; _optionsSnapshot = UserSettings.Default.CurrentDir.Versioning.Options; _mapStructTypesSnapshot = UserSettings.Default.CurrentDir.Versioning.MapStructTypes; _criwareDecryptionKey = UserSettings.Default.CurrentDir.CriwareDecryptionKey; - _onDemandTimeout = UserSettings.Default.CurrentDir.OnDemandTimeout; AesEndpoint = UserSettings.Default.CurrentDir.Endpoints[0]; MappingEndpoint = UserSettings.Default.CurrentDir.Endpoints[1]; @@ -281,7 +275,6 @@ public class SettingsViewModel : ViewModel SelectedMaterialExportFormat = _materialExportFormatSnapshot; SelectedTextureExportFormat = _textureExportFormatSnapshot; CriwareDecryptionKey = _criwareDecryptionKey; - OnDemandTimeout = _onDemandTimeout; SelectedAesReload = UserSettings.Default.AesReload; SelectedDiscordRpc = UserSettings.Default.DiscordRpc; @@ -323,7 +316,6 @@ public class SettingsViewModel : ViewModel UserSettings.Default.CurrentDir.Versioning.Options = SelectedOptions; UserSettings.Default.CurrentDir.Versioning.MapStructTypes = SelectedMapStructTypes; UserSettings.Default.CurrentDir.CriwareDecryptionKey = CriwareDecryptionKey; - UserSettings.Default.CurrentDir.OnDemandTimeout = OnDemandTimeout; UserSettings.Default.AssetLanguage = SelectedAssetLanguage; UserSettings.Default.CompressedAudioMode = SelectedCompressedAudio; diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index 115fe1af..e0382da8 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -272,11 +272,11 @@ - + PreviewTextInput="HttpRequestTimeoutBox_PreviewTextInput" + DataObject.Pasting="HttpRequestTimeoutBox_Pasting" + Loaded="HttpRequestTimeoutBox_Loaded" + TextChanged="HttpRequestTimeoutBox_TextChanged"/> diff --git a/FModel/Views/SettingsView.xaml.cs b/FModel/Views/SettingsView.xaml.cs index ce22e32d..4e95522c 100644 --- a/FModel/Views/SettingsView.xaml.cs +++ b/FModel/Views/SettingsView.xaml.cs @@ -62,6 +62,8 @@ public partial class SettingsView _applicationView.CUE4Parse.Provider.ReadScriptData = UserSettings.Default.ReadScriptData; _applicationView.CUE4Parse.Provider.ReadShaderMaps = UserSettings.Default.ReadShaderMaps; + + UserSettings.Save(); } private void OnBrowseOutput(object sender, RoutedEventArgs e) @@ -75,6 +77,7 @@ public partial class SettingsView UserSettings.Default.PropertiesDirectory = path; UserSettings.Default.TextureDirectory = path; UserSettings.Default.AudioDirectory = path; + UserSettings.Default.CodeDirectory = path; } private void OnBrowseDirectories(object sender, RoutedEventArgs e) @@ -273,34 +276,35 @@ public partial class SettingsView Process.Start(new ProcessStartInfo(hyperlink.NavigateUri.AbsoluteUri) { UseShellExecute = true }); } - private void OnDemandTimeout_Loaded(object sender, RoutedEventArgs e) + private void HttpRequestTimeoutBox_Loaded(object sender, RoutedEventArgs e) { if (sender is not TextBox textBox) return; - textBox.Text = _applicationView.SettingsView.OnDemandTimeout.ToString(); + textBox.Text = UserSettings.Default.HttpRequestTimeout.ToString(); } - private void OnDemandTimeout_TextChanged(object sender, TextChangedEventArgs e) + private void HttpRequestTimeoutBox_TextChanged(object sender, TextChangedEventArgs e) { if (sender is not TextBox textBox) return; string input = textBox.Text?.Trim() ?? string.Empty; + if (string.IsNullOrEmpty(input)) return; - if (uint.TryParse(input, out uint seconds)) - _applicationView.SettingsView.OnDemandTimeout = seconds; + if (int.TryParse(input, out int seconds)) + UserSettings.Default.HttpRequestTimeout = seconds; else - textBox.Text = uint.MaxValue.ToString(); + textBox.Text = int.MaxValue.ToString(); } - private void OnDemandTimeout_PreviewTextInput(object sender, TextCompositionEventArgs e) + private void HttpRequestTimeoutBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { e.Handled = !e.Text.All(char.IsDigit); } - private void OnDemandTimeout_Pasting(object sender, DataObjectPastingEventArgs e) + private void HttpRequestTimeoutBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(string))) {