From fab17a6ae0c9cc85969d231f4b6ad21a8700b54e Mon Sep 17 00:00:00 2001 From: Luca <52624146+EzioTheDeadPoet@users.noreply.github.com> Date: Thu, 12 Oct 2023 20:33:06 +0200 Subject: [PATCH] Wabbajack 3.3.0.0 Update (#2416) * added more visible error messages to avoid user confusion added hard drive free space detection, added red error message text, removed overwrite checkbox, added wiki button link extended the error text for starting wabbajack in protected location removed debug code shortened error message to fit in text box * restored warning removed in error, updated changelog, removed debug includes * Update InstallerVM.cs * Update InstallerVM.cs * Update MainWindowViewModel.cs * added json optional flag to only show version number over modlist image in installer view, if the modlist image already contains the title removed debug code change to pascal case and match existing code style update changelog * Fix manual downloads sometimes launching in browser * Fix manual downloads from secure servers * Remove duplicate user agent code * Create configuration project and performance settings * Bind new performance settings to UI * Use performance settings to limit maximum memory per download * Remove unused settings and related classes * Updated CHANGELOG.md * update CHANGELOG.md * moved the existing files popup to an error message , heralding the return of the overwrite install checkbox * added newline * reverted erroneous edit * gogID for fallout4 added * update CHANGELOG.md * Fix deadlock when loading new settings * change folder/directory check logic * update CHANGELOG.md * revert unnecessary change * update CHANGELOG.md * Bump Wabbajack to .NET 7 * Bump ReactiveUI packages & deps * Update GameFinder to 4.0.0 * Update CHANGELOG.md * Update CHANGELOG.md --------- Co-authored-by: JanuarySnow Co-authored-by: JanuarySnow <85711747+JanuarySnow@users.noreply.github.com> Co-authored-by: UrbanCMC Co-authored-by: trawzified <55751269+tr4wzified@users.noreply.github.com> --- CHANGELOG.md | 35 ++-- Wabbajack.App.Wpf/App.xaml.cs | 4 +- Wabbajack.App.Wpf/LauncherUpdater.cs | 19 +- Wabbajack.App.Wpf/Settings.cs | 183 +++--------------- .../UserIntervention/ManualDownloadHandler.cs | 15 +- .../UserIntervention/OAuth2LoginHandler.cs | 10 +- .../View Models/BrowserWindowViewModel.cs | 27 ++- .../Compilers/ModlistSettingsEditorVM.cs | 109 ----------- .../View Models/Gallery/ModListGalleryVM.cs | 1 - .../View Models/Gallery/ModListMetadataVM.cs | 9 + .../View Models/Installers/InstallerVM.cs | 89 +++++++-- .../View Models/Installers/MO2InstallerVM.cs | 104 +--------- Wabbajack.App.Wpf/View Models/MainWindowVM.cs | 8 +- .../View Models/Settings/SettingsVM.cs | 36 +++- .../Views/Common/CpuView.xaml.cs | 32 +-- .../Installers/InstallationCompleteView.xaml | 30 ++- .../InstallationCompleteView.xaml.cs | 3 + .../InstallationConfigurationView.xaml | 29 ++- .../InstallationConfigurationView.xaml.cs | 13 +- .../Views/Installers/InstallationView.xaml | 14 -- .../Installers/MO2InstallerConfigView.xaml | 16 -- .../ConfirmUpdateOfExistingInstallView.xaml | 50 ----- ...ConfirmUpdateOfExistingInstallView.xaml.cs | 51 ----- Wabbajack.App.Wpf/Views/MainWindow.xaml.cs | 67 +------ .../Views/Settings/MiscSettingsView.xaml | 40 +--- .../Views/Settings/MiscSettingsView.xaml.cs | 4 - .../Settings/PerformanceSettingsView.xaml | 33 +++- .../Settings/PerformanceSettingsView.xaml.cs | 10 + Wabbajack.App.Wpf/Wabbajack.App.Wpf.csproj | 14 +- .../Wabbajack.CLI.Builder.csproj | 4 +- Wabbajack.CLI/Wabbajack.CLI.csproj | 5 +- Wabbajack.Common/HttpExtensions.cs | 20 +- Wabbajack.Common/Wabbajack.Common.csproj | 4 +- .../Wabbajack.Compiler.Test.csproj | 2 +- Wabbajack.Compiler/Wabbajack.Compiler.csproj | 2 +- .../Wabbajack.Compression.BSA.Test.csproj | 2 +- .../Wabbajack.Compression.BSA.csproj | 2 +- .../Wabbajack.Compression.Zip.Test.csproj | 2 +- .../Wabbajack.Compression.Zip.csproj | 2 +- Wabbajack.Configuration/MainSettings.cs | 27 +++ .../PerformanceSettings.cs | 6 + .../Wabbajack.Configuration.csproj | 9 + .../Wabbajack.DTOs.ConverterGenerators.csproj | 2 +- .../Wabbajack.DTOs.Test.csproj | 2 +- Wabbajack.DTOs/Game/GameMetaData.cs | 2 +- Wabbajack.DTOs/Game/GameRegistry.cs | 37 ++-- .../Interventions/ManualDownload.cs | 6 +- Wabbajack.DTOs/ModList/ModListMetadata.cs | 2 + Wabbajack.DTOs/Wabbajack.DTOs.csproj | 2 +- .../Wabbajack.Downloaders.Bethesda.csproj | 2 +- ...bbajack.Downloaders.Dispatcher.Test.csproj | 4 +- .../Wabbajack.Downloaders.Dispatcher.csproj | 2 +- Wabbajack.Downloaders.GameFile/GameLocator.cs | 44 +++-- .../Wabbajack.Downloaders.GameFile.csproj | 10 +- .../GoogleDriveDownloader.cs | 22 +-- .../Wabbajack.Downloaders.GoogleDrive.csproj | 2 +- .../Wabbajack.Downloaders.Http.csproj | 2 +- ...ck.Downloaders.IPS4OAuth2Downloader.csproj | 2 +- .../Wabbajack.Downloaders.Interfaces.csproj | 2 +- .../Wabbajack.Downloaders.Manual.csproj | 2 +- .../Wabbajack.Downloaders.MediaFire.csproj | 4 +- .../Wabbajack.Downloaders.Mega.csproj | 2 +- .../Wabbajack.Downloaders.ModDB.csproj | 2 +- .../Wabbajack.Downloaders.Nexus.csproj | 2 +- ...ajack.Downloaders.VerificationCache.csproj | 2 +- .../Wabbajack.Downloaders.WabbajackCDN.csproj | 2 +- .../Wabbajack.FileExtractor.Test.csproj | 4 +- .../Wabbajack.FileExtractor.csproj | 2 +- .../Wabbajack.Hashing.PHash.Test.csproj | 2 +- .../Wabbajack.Hashing.PHash.csproj | 2 +- ...abbajack.Hashing.xxHash64.Benchmark.csproj | 2 +- .../Wabbajack.Hashing.xxHash64.Test.csproj | 2 +- .../Wabbajack.Hashing.xxHash64.csproj | 2 +- Wabbajack.IO.Async/Wabbajack.IO.Async.csproj | 2 +- .../Wabbajack.Installer.Test.csproj | 4 +- .../Wabbajack.Installer.csproj | 2 +- .../ViewModels/MainWindowViewModel.cs | 2 +- Wabbajack.Launcher/Wabbajack.Launcher.csproj | 3 +- .../Wabbajack.Networking.BethesdaNet.csproj | 2 +- .../Wabbajack.Networking.Discord.csproj | 2 +- .../Wabbajack.Networking.GitHub.csproj | 2 +- ...abbajack.Networking.Http.Interfaces.csproj | 2 +- .../Wabbajack.Networking.Http.Test.csproj | 2 +- Wabbajack.Networking.Http/Extensions.cs | 7 - .../ResumableDownloader.cs | 7 +- .../SingleThreadedDownloader.cs | 7 +- .../Wabbajack.Networking.Http.csproj | 5 +- .../Wabbajack.Networking.NexusApi.Test.csproj | 2 +- .../ProxiedNexusApi.cs | 6 +- .../Wabbajack.Networking.NexusApi.csproj | 4 +- .../Wabbajack.Networking.Steam.Test.csproj | 4 +- .../Wabbajack.Networking.Steam.csproj | 2 +- ...ajack.Networking.WabbajackClientApi.csproj | 2 +- .../Wabbajack.Paths.IO.Test.csproj | 2 +- Wabbajack.Paths.IO/Wabbajack.Paths.IO.csproj | 2 +- .../Wabbajack.Paths.Test.csproj | 2 +- Wabbajack.Paths/Wabbajack.Paths.csproj | 2 +- .../Wabbajack.RateLimiter.Test.csproj | 2 +- .../Wabbajack.RateLimiter.csproj | 2 +- .../Wabbajack.Server.Lib.csproj | 2 +- Wabbajack.Server/Wabbajack.Server.csproj | 2 +- .../ServiceExtensions.cs | 61 +++--- .../Wabbajack.Services.OSIntegrated.csproj | 4 +- .../Wabbajack.VFS.Interfaces.csproj | 2 +- Wabbajack.VFS.Test/Wabbajack.VFS.Test.csproj | 4 +- Wabbajack.VFS/Wabbajack.VFS.csproj | 2 +- Wabbajack.sln | 6 + 107 files changed, 580 insertions(+), 903 deletions(-) delete mode 100644 Wabbajack.App.Wpf/View Models/Compilers/ModlistSettingsEditorVM.cs delete mode 100644 Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml delete mode 100644 Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml.cs create mode 100644 Wabbajack.Configuration/MainSettings.cs create mode 100644 Wabbajack.Configuration/PerformanceSettings.cs create mode 100644 Wabbajack.Configuration/Wabbajack.Configuration.csproj diff --git a/CHANGELOG.md b/CHANGELOG.md index 247c9e6f..f6a08e81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,32 @@ ### Changelog +#### Version - 3.3.0.0 - TBA +* Fixed some UI issues arising from 3.2.0.0 changes - more informative error text, wiki link button +* Added optional JSON flag for `DisplayVersionOnlyInInstallerView` to enable the installer image to only show version number. +* Fixed manual downloader downloading in the OS's "Downloads" folder +* Added RAM Limit setting for downloads + * This fixes the High RAM usage (and sometimes app crashes) on some Hardware + Very High Speed Internet Connection Systems +* Added Fallout 4 (GOG) to the index +* Updated App to .NET 7.0 + * Should fix random crashes on some systems +* Updated GameFinder to 4.0.0 + #### Version - 3.2.0.1 - 7/23/2023 * Code cleanup: re-added some network and diagnostic code missing since 2.5 #### Version - 3.2.0.0 - 7/16/2023 - * Fixed issues related to high RAM usage - * The resumable downloads now reserve drive space to write to in advance instead of being managed in system RAM - * remove LoversLab from the "Logins" Setting because it is deprecated for ages now and only causes confusion, - just for the unlikely probability that LL will fix their proper API. - * Added safety to install path selection, to ensure that no files are deleted that are not intended to be. - * Fixed allowing back button during install which can result in multiple install processes - * fixed search filter not applying when pressing back button and reaccessing gallery - * Added more robust checking for protected location paths and subfolders for the launcher exe and install and download paths - * Fixed readme double opening when modlist details are prepoulated - * Added a check if Downloadpath is alongside Wabbajack.exe location, to match the install path check that already exists - * Added check for identical download and install paths - * Fixed No Delete and NoDelete being handled by stripping whitespace before the regex, to idiotproof things a bit +* Fixed issues related to high RAM usage +* The resumable downloads now reserve drive space to write to in advance instead of being managed in system RAM +* remove LoversLab from the "Logins" Setting because it is deprecated for ages now and only causes confusion, + just for the unlikely probability that LL will fix their proper API. +* Added safety to install path selection, to ensure that no files are deleted that are not intended to be. +* Fixed allowing back button during install which can result in multiple install processes +* fixed search filter not applying when pressing back button and reaccessing gallery +* Added more robust checking for protected location paths and subfolders for the launcher exe and install and download paths +* Fixed readme double opening when modlist details are prepoulated +* Added a check if Downloadpath is alongside Wabbajack.exe location, to match the install path check that already exists +* Added check for identical download and install paths +* Fixed No Delete and NoDelete being handled by stripping whitespace before the regex, to idiotproof things a bit #### Version - 3.1.0.0 - 5/7/2023 * Fixed Readme opening twice diff --git a/Wabbajack.App.Wpf/App.xaml.cs b/Wabbajack.App.Wpf/App.xaml.cs index 4fd29c41..dc9d2cd0 100644 --- a/Wabbajack.App.Wpf/App.xaml.cs +++ b/Wabbajack.App.Wpf/App.xaml.cs @@ -3,7 +3,6 @@ using System.Reactive.Concurrency; using System.Reactive.Disposables; using System.Runtime.InteropServices; using System.Security.Principal; -using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using Microsoft.Extensions.DependencyInjection; @@ -166,7 +165,6 @@ namespace Wabbajack services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -182,7 +180,7 @@ namespace Wabbajack services.AddTransient(); // Login Managers - + //Disabled LL because it is currently not used and broken due to the way LL butchers their API //services.AddAllSingleton(); services.AddAllSingleton(); diff --git a/Wabbajack.App.Wpf/LauncherUpdater.cs b/Wabbajack.App.Wpf/LauncherUpdater.cs index 94e7031e..96d3fd6b 100644 --- a/Wabbajack.App.Wpf/LauncherUpdater.cs +++ b/Wabbajack.App.Wpf/LauncherUpdater.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.VisualBasic.CompilerServices; using Newtonsoft.Json; +using Wabbajack.Common; using Wabbajack.Downloaders; using Wabbajack.DTOs; using Wabbajack.DTOs.DownloadStates; @@ -27,9 +28,9 @@ namespace Wabbajack private readonly HttpClient _client; private readonly Client _wjclient; private readonly DTOSerializer _dtos; - + private readonly DownloadDispatcher _downloader; - + private static Uri GITHUB_REPO_RELEASES = new("https://api.github.com/repos/wabbajack-tools/wabbajack/releases"); public LauncherUpdater(ILogger logger, HttpClient client, Client wjclient, DTOSerializer dtos, @@ -41,8 +42,8 @@ namespace Wabbajack _dtos = dtos; _downloader = downloader; } - - + + public static Lazy CommonFolder = new (() => { var entryPoint = KnownFolders.EntryPoint; @@ -105,7 +106,7 @@ namespace Wabbajack var launcherFolder = KnownFolders.EntryPoint.Parent; var exePath = launcherFolder.Combine("Wabbajack.exe"); - + var launcherVersion = FileVersionInfo.GetVersionInfo(exePath.ToString()); if (release != default && release.version > Version.Parse(launcherVersion.FileVersion!)) @@ -119,7 +120,7 @@ namespace Wabbajack Name = release.asset.Name, Size = release.asset.Size }, tempPath, CancellationToken.None); - + if (tempPath.Size() != release.asset.Size) { _logger.LogInformation( @@ -130,12 +131,12 @@ namespace Wabbajack if (exePath.FileExists()) exePath.Delete(); await tempPath.MoveToAsync(exePath, true, CancellationToken.None); - + _logger.LogInformation("Finished updating wabbajack"); await _wjclient.SendMetric("updated_launcher", $"{launcherVersion.FileVersion} -> {release.version}"); } } - + private async Task GetReleases() { _logger.LogInformation("Getting new Wabbajack version list"); @@ -146,7 +147,7 @@ namespace Wabbajack private HttpRequestMessage MakeMessage(Uri uri) { var msg = new HttpRequestMessage(HttpMethod.Get, uri); - msg.UseChromeUserAgent(); + msg.AddChromeAgent(); return msg; } diff --git a/Wabbajack.App.Wpf/Settings.cs b/Wabbajack.App.Wpf/Settings.cs index 4a65f6d7..4ad1517c 100644 --- a/Wabbajack.App.Wpf/Settings.cs +++ b/Wabbajack.App.Wpf/Settings.cs @@ -1,84 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Reactive; -using System.Reactive.Subjects; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Wabbajack.Compiler; +using Wabbajack.Downloaders; using Wabbajack.DTOs.JsonConverters; -using Wabbajack; using Wabbajack.Paths; -using Consts = Wabbajack.Consts; +using Wabbajack.RateLimiter; +using Wabbajack.Util; namespace Wabbajack { - [JsonName("MainSettings")] - [JsonObject(MemberSerialization.OptOut)] - public class MainSettings - { - public byte Version { get; set; } = Consts.SettingsVersion; - public double PosX { get; set; } - public double PosY { get; set; } - public double Height { get; set; } - public double Width { get; set; } - public InstallerSettings Installer { get; set; } = new(); - public FiltersSettings Filters { get; set; } = new(); - public CompilerSettings Compiler { get; set; } = new(); - public PerformanceSettings Performance { get; set; } = new(); - - private Subject _saveSignal = new(); - [JsonIgnore] - public IObservable SaveSignal => _saveSignal; - - public static async ValueTask<(MainSettings settings, bool loaded)> TryLoadTypicalSettings() - { - /* - if (!Consts.SettingsFile.Exists) - { - return default; - } - - // Version check - try - { - var settings = Consts.SettingsFile.FromJson(); - if (settings.Version == Consts.SettingsVersion) - return (settings, true); - } - catch (Exception ex) - { - Utils.Error(ex, "Error loading settings"); - } - - var backup = Consts.SettingsFile.AppendToName("-backup"); - await backup.DeleteAsync(); - - await Consts.SettingsFile.CopyToAsync(backup); - await Consts.SettingsFile.DeleteAsync(); -*/ - return default; - } - - public static async ValueTask SaveSettings(MainSettings settings) - { - settings._saveSignal.OnNext(Unit.Default); - - // Might add this if people are putting save work on other threads or other - // things that delay the operation. - //settings._saveSignal.OnCompleted(); - //await settings._saveSignal; - - //await settings.ToJsonAsync(Consts.SettingsFile); - } - } - - [JsonName("InstallerSettings")] - public class InstallerSettings - { - public AbsolutePath LastInstalledListLocation { get; set; } - public Dictionary Mo2ModlistSettings { get; } = new Dictionary(); - } - [JsonName("Mo2ModListInstallerSettings")] public class Mo2ModlistInstallationSettings { @@ -87,105 +14,41 @@ namespace Wabbajack public bool AutomaticallyOverrideExistingInstall { get; set; } } - [JsonName("FiltersSettings")] - [JsonObject(MemberSerialization.OptOut)] - public class FiltersSettings : ViewModel - { - public bool ShowNSFW { get; set; } - public bool OnlyInstalled { get; set; } - public string Game { get; set; } - public string Search { get; set; } - private bool _isPersistent = true; - public bool IsPersistent { get => _isPersistent; set => RaiseAndSetIfChanged(ref _isPersistent, value); } - - private bool _useCompression = false; - public bool UseCompression { get => _useCompression; set => RaiseAndSetIfChanged(ref _useCompression, value); } - public bool ShowUtilityLists { get; set; } - } - - [JsonName("PerformanceSettings")] - [JsonObject(MemberSerialization.OptOut)] public class PerformanceSettings : ViewModel { - public PerformanceSettings() + private readonly Configuration.MainSettings _settings; + private readonly int _defaultMaximumMemoryPerDownloadThreadMb; + + public PerformanceSettings(Configuration.MainSettings settings, IResource downloadResources, SystemParametersConstructor systemParams) { - _reduceHDDThreads = true; - _favorPerfOverRam = false; - _diskThreads = Environment.ProcessorCount; - _downloadThreads = Environment.ProcessorCount <= 8 ? Environment.ProcessorCount : 8; - } + var p = systemParams.Create(); - private int _downloadThreads; - public int DownloadThreads { get => _downloadThreads; set => RaiseAndSetIfChanged(ref _downloadThreads, value); } - - private int _diskThreads; - public int DiskThreads { get => _diskThreads; set => RaiseAndSetIfChanged(ref _diskThreads, value); } + _settings = settings; + // Split half of available memory among download threads + _defaultMaximumMemoryPerDownloadThreadMb = (int)(p.SystemMemorySize / downloadResources.MaxTasks / 1024 / 1024) / 2; + _maximumMemoryPerDownloadThreadMb = settings.PerformanceSettings.MaximumMemoryPerDownloadThreadMb; - private bool _reduceHDDThreads; - public bool ReduceHDDThreads { get => _reduceHDDThreads; set => RaiseAndSetIfChanged(ref _reduceHDDThreads, value); } - - private bool _favorPerfOverRam; - public bool FavorPerfOverRam { get => _favorPerfOverRam; set => RaiseAndSetIfChanged(ref _favorPerfOverRam, value); } - - private bool _networkWorkaroundMode; - public bool NetworkWorkaroundMode - { - get => _networkWorkaroundMode; - set + if (MaximumMemoryPerDownloadThreadMb < 0) { - Consts.UseNetworkWorkaroundMode = value; - RaiseAndSetIfChanged(ref _networkWorkaroundMode, value); + ResetMaximumMemoryPerDownloadThreadMb(); } } - - private bool _disableTextureResizing; - public bool DisableTextureResizing + private int _maximumMemoryPerDownloadThreadMb; + + public int MaximumMemoryPerDownloadThreadMb { - get => _disableTextureResizing; + get => _maximumMemoryPerDownloadThreadMb; set { - RaiseAndSetIfChanged(ref _disableTextureResizing, value); + RaiseAndSetIfChanged(ref _maximumMemoryPerDownloadThreadMb, value); + _settings.PerformanceSettings.MaximumMemoryPerDownloadThreadMb = value; } } - - - /* - public void SetProcessorSettings(ABatchProcessor processor) + public void ResetMaximumMemoryPerDownloadThreadMb() { - processor.DownloadThreads = DownloadThreads; - processor.DiskThreads = DiskThreads; - processor.ReduceHDDThreads = ReduceHDDThreads; - processor.FavorPerfOverRam = FavorPerfOverRam; - - if (processor is MO2Compiler mo2c) - mo2c.DisableTextureResizing = DisableTextureResizing; - }*/ + MaximumMemoryPerDownloadThreadMb = _defaultMaximumMemoryPerDownloadThreadMb; + } } - - [JsonName("CompilationModlistSettings")] - public class CompilationModlistSettings - { - public string ModListName { get; set; } - public string Version { get; set; } - public string Author { get; set; } - public string Description { get; set; } - public string Website { get; set; } - public string Readme { get; set; } - public bool IsNSFW { get; set; } - - public string MachineUrl { get; set; } - public AbsolutePath SplashScreen { get; set; } - public bool Publish { get; set; } - } - - [JsonName("MO2CompilationSettings")] - public class MO2CompilationSettings - { - public AbsolutePath DownloadLocation { get; set; } - public AbsolutePath LastCompiledProfileLocation { get; set; } - public Dictionary ModlistSettings { get; } = new Dictionary(); - } - } diff --git a/Wabbajack.App.Wpf/UserIntervention/ManualDownloadHandler.cs b/Wabbajack.App.Wpf/UserIntervention/ManualDownloadHandler.cs index 6bf219c1..003099bf 100644 --- a/Wabbajack.App.Wpf/UserIntervention/ManualDownloadHandler.cs +++ b/Wabbajack.App.Wpf/UserIntervention/ManualDownloadHandler.cs @@ -1,10 +1,7 @@ -using System.Security.Policy; using System.Threading; using System.Threading.Tasks; -using Wabbajack.DTOs; using Wabbajack.DTOs.DownloadStates; using Wabbajack.DTOs.Interventions; -using Wabbajack.Paths; namespace Wabbajack.UserIntervention; @@ -17,18 +14,18 @@ public class ManualDownloadHandler : BrowserWindowViewModel //await WaitForReady(); var archive = Intervention.Archive; var md = Intervention.Archive.State as Manual; - + HeaderText = $"Manual download ({md.Url.Host})"; - + Instructions = string.IsNullOrWhiteSpace(md.Prompt) ? $"Please download {archive.Name}" : md.Prompt; - await NavigateTo(md.Url); - - var uri = await WaitForDownloadUri(token, async () => + var task = WaitForDownloadUri(token, async () => { await RunJavaScript("Array.from(document.getElementsByTagName(\"iframe\")).forEach(f => f.remove())"); }); - + await NavigateTo(md.Url); + var uri = await task; + Intervention.Finish(uri); } } \ No newline at end of file diff --git a/Wabbajack.App.Wpf/UserIntervention/OAuth2LoginHandler.cs b/Wabbajack.App.Wpf/UserIntervention/OAuth2LoginHandler.cs index 1d287022..51f45c7b 100644 --- a/Wabbajack.App.Wpf/UserIntervention/OAuth2LoginHandler.cs +++ b/Wabbajack.App.Wpf/UserIntervention/OAuth2LoginHandler.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Web; using Microsoft.Extensions.Logging; using ReactiveUI; +using Wabbajack.Common; using Wabbajack.DTOs.Interventions; using Wabbajack.DTOs.Logins; using Wabbajack.Messages; @@ -40,7 +41,7 @@ public abstract class OAuth2LoginHandler : BrowserWindowViewModel var tcs = new TaskCompletionSource(); await NavigateTo(tlogin.AuthorizationEndpoint); - + Browser!.Browser.CoreWebView2.Settings.UserAgent = "Wabbajack"; Browser!.Browser.NavigationStarting += (sender, args) => { @@ -50,7 +51,7 @@ public abstract class OAuth2LoginHandler : BrowserWindowViewModel tcs.TrySetResult(uri); } }; - + Instructions = $"Please log in and allow Wabbajack to access your {tlogin.SiteName} account"; var scopes = string.Join(" ", tlogin.Scopes); @@ -88,8 +89,7 @@ public abstract class OAuth2LoginHandler : BrowserWindowViewModel var msg = new HttpRequestMessage(); msg.Method = HttpMethod.Post; msg.RequestUri = tlogin.TokenEndpoint; - msg.Headers.Add("User-Agent", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"); + msg.AddChromeAgent(); msg.Headers.Add("Cookie", string.Join(";", cookies.Select(c => $"{c.Name}={c.Value}"))); msg.Content = new FormUrlEncodedContent(formData.ToList()); @@ -101,6 +101,6 @@ public abstract class OAuth2LoginHandler : BrowserWindowViewModel Cookies = cookies, ResultState = data! }); - + } } \ No newline at end of file diff --git a/Wabbajack.App.Wpf/View Models/BrowserWindowViewModel.cs b/Wabbajack.App.Wpf/View Models/BrowserWindowViewModel.cs index b74cdd99..d0aa4a4c 100644 --- a/Wabbajack.App.Wpf/View Models/BrowserWindowViewModel.cs +++ b/Wabbajack.App.Wpf/View Models/BrowserWindowViewModel.cs @@ -23,7 +23,7 @@ public abstract class BrowserWindowViewModel : ViewModel [Reactive] public string HeaderText { get; set; } [Reactive] public string Instructions { get; set; } - + [Reactive] public string Address { get; set; } public BrowserWindow? Browser { get; set; } @@ -83,6 +83,11 @@ public abstract class BrowserWindowViewModel : ViewModel public async Task GetCookies(string domainEnding, CancellationToken token) { + // Strip www. before searching for cookies on a domain to handle websites saving their cookies like .example.org + if (domainEnding.StartsWith("www.")) + { + domainEnding = domainEnding[4..]; + } var cookies = (await _browser.CoreWebView2.CookieManager.GetCookiesAsync("")) .Where(c => c.Domain.EndsWith(domainEnding)); return cookies.Select(c => new Cookie @@ -112,18 +117,20 @@ public abstract class BrowserWindowViewModel : ViewModel { var source = new TaskCompletionSource(); var referer = _browser.Source; + while (_browser.CoreWebView2 == null) + await Task.Delay(10, token); + _browser.CoreWebView2.DownloadStarting += (sender, args) => { try { - source.SetResult(new Uri(args.DownloadOperation.Uri)); } catch (Exception) { source.SetCanceled(); } - + args.Cancel = true; args.Handled = true; }; @@ -144,12 +151,16 @@ public abstract class BrowserWindowViewModel : ViewModel } var cookies = await GetCookies(uri.Host, token); - return new ManualDownload.BrowserDownloadState(uri, cookies, new[] - { - ("Referer", referer.ToString()) - }); + return new ManualDownload.BrowserDownloadState( + uri, + cookies, + new[] + { + ("Referer", referer?.ToString() ?? uri.ToString()) + }, + _browser.CoreWebView2.Settings.UserAgent); } - + public async Task WaitForDownload(AbsolutePath path, CancellationToken token) { var source = new TaskCompletionSource(); diff --git a/Wabbajack.App.Wpf/View Models/Compilers/ModlistSettingsEditorVM.cs b/Wabbajack.App.Wpf/View Models/Compilers/ModlistSettingsEditorVM.cs deleted file mode 100644 index 1552b98e..00000000 --- a/Wabbajack.App.Wpf/View Models/Compilers/ModlistSettingsEditorVM.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Reactive.Linq; -using System.Windows.Input; -using DynamicData; -using Microsoft.WindowsAPICodePack.Dialogs; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; -using Wabbajack.Common; -using Wabbajack; - -namespace Wabbajack -{ - public class ModlistSettingsEditorVM : ViewModel - { - private readonly CompilationModlistSettings _settings; - - [Reactive] - public string ModListName { get; set; } - - [Reactive] - public string VersionText { get; set; } - - private readonly ObservableAsPropertyHelper _version; - public Version Version => _version.Value; - - [Reactive] - public string AuthorText { get; set; } - - [Reactive] - public string Description { get; set; } - - public FilePickerVM ImagePath { get; } - - [Reactive] - public string Readme { get; set; } - - [Reactive] public string MachineUrl { get; set; } = ""; - [Reactive] public bool Publish { get; set; } = false; - - [Reactive] - public string Website { get; set; } - - [Reactive] - public bool IsNSFW { get; set; } - - public IObservable InError { get; } - - public ModlistSettingsEditorVM(CompilationModlistSettings settings) - { - _settings = settings; - ImagePath = new FilePickerVM - { - ExistCheckOption = FilePickerVM.CheckOptions.IfPathNotEmpty, - PathType = FilePickerVM.PathTypeOptions.File, - }; - ImagePath.Filters.Add(new CommonFileDialogFilter("Banner image", "*.png")); - - _version = this.WhenAny(x => x.VersionText) - .Select(x => - { - if (string.IsNullOrWhiteSpace(x)) - return new Version(0, 0); - - return !Version.TryParse(x, out var version) ? new Version(0, 0) : version; - }).ObserveOnGuiThread() - .ToProperty(this, x => x.Version); - - InError = this.WhenAny(x => x.ImagePath.ErrorState) - .Select(err => err.Failed) - .CombineLatest( - this.WhenAny(x => x.VersionText) - .Select(x => Version.TryParse(x, out _)), - (image, version) => !image && !version) - .Publish() - .RefCount(); - } - - public void Init() - { - AuthorText = _settings.Author; - if (!string.IsNullOrWhiteSpace(_settings.ModListName)) - { - ModListName = _settings.ModListName; - } - Description = _settings.Description; - Readme = _settings.Readme; - ImagePath.TargetPath = _settings.SplashScreen; - Website = _settings.Website; - VersionText = _settings.Version; - IsNSFW = _settings.IsNSFW; - MachineUrl = _settings.MachineUrl; - Publish = _settings.Publish; - } - - public void Save() - { - _settings.Version = VersionText; - _settings.Author = AuthorText; - _settings.ModListName = ModListName; - _settings.Description = Description; - _settings.Readme = Readme; - _settings.SplashScreen = ImagePath.TargetPath; - _settings.Website = Website; - _settings.IsNSFW = IsNSFW; - _settings.MachineUrl = MachineUrl; - _settings.Publish = Publish; - } - } -} diff --git a/Wabbajack.App.Wpf/View Models/Gallery/ModListGalleryVM.cs b/Wabbajack.App.Wpf/View Models/Gallery/ModListGalleryVM.cs index e91b3ce7..c87dfde5 100644 --- a/Wabbajack.App.Wpf/View Models/Gallery/ModListGalleryVM.cs +++ b/Wabbajack.App.Wpf/View Models/Gallery/ModListGalleryVM.cs @@ -80,7 +80,6 @@ namespace Wabbajack private readonly SettingsManager _settingsManager; private readonly CancellationToken _cancellationToken; - private FiltersSettings settings { get; set; } = new(); public ICommand ClearFiltersCommand { get; set; } public ModListGalleryVM(ILogger logger, Client wjClient, GameLocator locator, diff --git a/Wabbajack.App.Wpf/View Models/Gallery/ModListMetadataVM.cs b/Wabbajack.App.Wpf/View Models/Gallery/ModListMetadataVM.cs index 3bd14e44..93cce20c 100644 --- a/Wabbajack.App.Wpf/View Models/Gallery/ModListMetadataVM.cs +++ b/Wabbajack.App.Wpf/View Models/Gallery/ModListMetadataVM.cs @@ -82,6 +82,13 @@ namespace Wabbajack [Reactive] public string VersionText { get; private set; } + [Reactive] + public bool ImageContainsTitle { get; private set; } + + [Reactive] + + public bool DisplayVersionOnlyInInstallerView { get; private set; } + [Reactive] public IErrorResponse Error { get; private set; } @@ -123,6 +130,8 @@ namespace Wabbajack Metadata.DownloadMetadata.SizeOfArchives + Metadata.DownloadMetadata.SizeOfInstalledFiles ); VersionText = "Modlist version : " + Metadata.Version; + ImageContainsTitle = Metadata.ImageContainsTitle; + DisplayVersionOnlyInInstallerView = Metadata.DisplayVersionOnlyInInstallerView; IsBroken = metadata.ValidationSummary.HasFailures || metadata.ForceDown; // https://www.wabbajack.org/modlist/wj-featured/aldrnari OpenWebsiteCommand = ReactiveCommand.Create(() => UIUtils.OpenWebsite(new Uri($"https://www.wabbajack.org/modlist/{Metadata.NamespacedName}"))); diff --git a/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs b/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs index c5198d13..e5c16540 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs @@ -135,11 +135,14 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM public LogStream LoggerProvider { get; } private AbsolutePath LastInstallPath { get; set; } + + [Reactive] public bool OverwriteFiles { get; set; } // Command properties public ReactiveCommand ShowManifestCommand { get; } public ReactiveCommand OpenReadmeCommand { get; } + public ReactiveCommand OpenWikiCommand { get; } public ReactiveCommand OpenDiscordButton { get; } public ReactiveCommand VisitModListWebsiteCommand { get; } @@ -178,6 +181,11 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM UIUtils.OpenWebsite(new Uri(ModList!.Readme)); }, this.WhenAnyValue(vm => vm.LoadingLock.IsNotLoading, vm => vm.ModList.Readme, (isNotLoading, readme) => isNotLoading && !string.IsNullOrWhiteSpace(readme))); + OpenWikiCommand = ReactiveCommand.Create(() => + { + UIUtils.OpenWebsite(new Uri("https://wiki.wabbajack.org/index.html")); + }, this.WhenAnyValue(vm => vm.LoadingLock.IsNotLoading)); + VisitModListWebsiteCommand = ReactiveCommand.Create(() => { UIUtils.OpenWebsite(ModList!.Website); @@ -219,7 +227,10 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM { UIUtils.OpenFolder(Installer.Location.TargetPath); }); - + + this.WhenAnyValue(x => x.OverwriteFiles) + .Subscribe(x => ConfirmOverwrite()); + MessageBus.Current.Listen() .Subscribe(msg => LoadModlistFromGallery(msg.Path, msg.Metadata).FireAndForget()) .DisposeWith(CompositeDisposable); @@ -280,6 +291,10 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM { yield return ErrorResponse.Fail("Can't have identical install and download folders"); } + if (installPath.ToString().Length > 0 && downloadPath.ToString().Length > 0 && KnownFolders.IsSubDirectoryOf(installPath.ToString(), downloadPath.ToString())) + { + yield return ErrorResponse.Fail("Can't put the install folder inside the download folder"); + } foreach (var game in GameRegistry.Games) { if (!_gameLocator.TryFindLocation(game.Key, out var location)) @@ -304,31 +319,53 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM yield return ErrorResponse.Fail("Installing in this folder may overwrite Wabbajack"); } - if (installPath.ToString().Length != 0 && installPath != LastInstallPath && - !Installer.AutomaticallyOverwrite && + if (installPath.ToString().Length != 0 && installPath != LastInstallPath && !OverwriteFiles && Directory.EnumerateFileSystemEntries(installPath.ToString()).Any()) { - string message = - "There are existing files in the chosen install path, they will be deleted or overwritten (if updating existing modlist), continue?"; - string title = "Files found in install folder"; - MessageBoxButtons buttons = MessageBoxButtons.YesNo; - DialogResult result = MessageBox.Show(message, title, buttons); - if (result == DialogResult.Yes) - { - // everythings fine - } - else - { - Installer.Location.TargetPath = "".ToAbsolutePath(); - } + yield return ErrorResponse.Fail("There are files in the install folder, please tick 'Overwrite Installation' to confirm you want to install to this folder " + Environment.NewLine + + "if you are updating an existing modlist, then this is expected and can be overwritten."); } if (KnownFolders.IsInSpecialFolder(installPath) || KnownFolders.IsInSpecialFolder(downloadPath)) { - yield return ErrorResponse.Fail("Can't install a modlist into Windows protected locations - such as Downloads, Documents etc"); + yield return ErrorResponse.Fail("Can't install into Windows locations such as Documents etc, please make a new folder for the modlist - C:\\ModList\\ for example."); } + // Disabled Because it was causing issues for people trying to update lists. + //if (installPath.ToString().Length > 0 && downloadPath.ToString().Length > 0 && !HasEnoughSpace(installPath, downloadPath)){ + // yield return ErrorResponse.Fail("Can't install modlist due to lack of free hard drive space, please read the modlist Readme to learn more."); + //} } + /* + private bool HasEnoughSpace(AbsolutePath inpath, AbsolutePath downpath) + { + string driveLetterInPath = inpath.ToString().Substring(0,1); + string driveLetterDownPath = inpath.ToString().Substring(0,1); + DriveInfo driveUsedInPath = new DriveInfo(driveLetterInPath); + DriveInfo driveUsedDownPath = new DriveInfo(driveLetterDownPath); + long spaceRequiredforInstall = ModlistMetadata.DownloadMetadata.SizeOfInstalledFiles; + long spaceRequiredforDownload = ModlistMetadata.DownloadMetadata.SizeOfArchives; + long spaceInstRemaining = driveUsedInPath.AvailableFreeSpace; + long spaceDownRemaining = driveUsedDownPath.AvailableFreeSpace; + if ( driveLetterInPath == driveLetterDownPath) + { + long totalSpaceRequired = spaceRequiredforInstall + spaceRequiredforDownload; + if (spaceInstRemaining < totalSpaceRequired) + { + return false; + } + + } else + { + if( spaceInstRemaining < spaceRequiredforInstall || spaceDownRemaining < spaceRequiredforDownload) + { + return false; + } + } + return true; + + }*/ + private async Task BeginSlideShow(CancellationToken token) { while (!token.IsCancellationRequested) @@ -411,6 +448,13 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM } } + private void ConfirmOverwrite() + { + AbsolutePath prev = Installer.Location.TargetPath; + Installer.Location.TargetPath = "".ToAbsolutePath(); + Installer.Location.TargetPath = prev; + } + private async Task BeginInstall() { await Task.Run(async () => @@ -521,7 +565,14 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM private void PopulateSlideShow(ModList modList) { - SlideShowTitle = modList.Name; + if (ModlistMetadata.ImageContainsTitle && ModlistMetadata.DisplayVersionOnlyInInstallerView) + { + SlideShowTitle = "v" + ModlistMetadata.Version.ToString(); + } + else + { + SlideShowTitle = modList.Name; + } SlideShowAuthor = modList.Author; SlideShowDescription = modList.Description; SlideShowImage = ModListImage; @@ -551,4 +602,4 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM } } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs index 8e87a272..f9bc25a4 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs @@ -1,37 +1,27 @@ using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Reactive.Disposables; -using System.Reactive.Linq; -using System.Text; using System.Threading.Tasks; using ReactiveUI; using ReactiveUI.Fody.Helpers; -using Wabbajack.Common; using Wabbajack.Installer; -using Wabbajack; -using Wabbajack.DTOs; using Wabbajack.DTOs.Interventions; -using Wabbajack.Interventions; using Wabbajack.Paths; -using Wabbajack.Util; namespace Wabbajack { public class MO2InstallerVM : ViewModel, ISubInstallerVM { public InstallerVM Parent { get; } - + [Reactive] public ErrorResponse CanInstall { get; set; } [Reactive] public IInstaller ActiveInstallation { get; private set; } - - [Reactive] public Mo2ModlistInstallationSettings CurrentSettings { get; set; } + [Reactive] + public Mo2ModlistInstallationSettings CurrentSettings { get; set; } public FilePickerVM Location { get; } @@ -62,97 +52,13 @@ namespace Wabbajack DownloadLocation.TargetPath = newPath.Combine("downloads"); } }).DisposeWith(CompositeDisposable); - + DownloadLocation = new FilePickerVM() { ExistCheckOption = FilePickerVM.CheckOptions.Off, PathType = FilePickerVM.PathTypeOptions.Folder, PromptTitle = "Select a location for MO2 downloads", }; - /* TODO - DownloadLocation.AdditionalError = this.WhenAny(x => x.DownloadLocation.TargetPath) - .Select(x => Utils.IsDirectoryPathValid(x)); - Location.AdditionalError = Observable.CombineLatest( - this.WhenAny(x => x.Location.TargetPath), - this.WhenAny(x => x.DownloadLocation.TargetPath), - resultSelector: (target, download) => (target, download)) - .ObserveOn(RxApp.TaskpoolScheduler) - .Select(i => MO2Installer.CheckValidInstallPath(i.target, i.download, Parent.ModList?.SourceModList?.GameType.MetaData())) - .ObserveOnGuiThread(); - - _CanInstall = Observable.CombineLatest( - this.WhenAny(x => x.Location.ErrorState), - this.WhenAny(x => x.DownloadLocation.ErrorState), - installerVM.WhenAny(x => x.ModListLocation.ErrorState), - resultSelector: (loc, modlist, download) => - { - return ErrorResponse.FirstFail(loc, modlist, download); - }) - .ToProperty(this, nameof(CanInstall)); - - // Have Installation location updates modify the downloads location if empty or the same path - this.WhenAny(x => x.Location.TargetPath) - .Skip(1) // Don't do it initially - .Subscribe(installPath => - { - if (DownloadLocation.TargetPath == default || DownloadLocation.TargetPath == installPath) - { - if (installPath.Exists) DownloadLocation.TargetPath = installPath.Combine("downloads"); - } - }) - .DisposeWith(CompositeDisposable); - - // Have Download location updates change if the same as the install path - this.WhenAny(x => x.DownloadLocation.TargetPath) - .Skip(1) // Don't do it initially - .Subscribe(downloadPath => - { - if (downloadPath != default && downloadPath == Location.TargetPath) - { - DownloadLocation.TargetPath = Location.TargetPath.Combine("downloads"); - } - }) - .DisposeWith(CompositeDisposable); - - // Load settings - _CurrentSettings = installerVM.WhenAny(x => x.ModListLocation.TargetPath) - .Select(path => path == default ? null : installerVM.MWVM.Settings.Installer.Mo2ModlistSettings.TryCreate(path)) - .ToGuiProperty(this, nameof(CurrentSettings)); - this.WhenAny(x => x.CurrentSettings) - .Pairwise() - .Subscribe(settingsPair => - { - SaveSettings(settingsPair.Previous); - if (settingsPair.Current == null) return; - Location.TargetPath = settingsPair.Current.InstallationLocation; - DownloadLocation.TargetPath = settingsPair.Current.DownloadLocation; - AutomaticallyOverwrite = settingsPair.Current.AutomaticallyOverrideExistingInstall; - }) - .DisposeWith(CompositeDisposable); - installerVM.MWVM.Settings.SaveSignal - .Subscribe(_ => SaveSettings(CurrentSettings)) - .DisposeWith(CompositeDisposable); - - // Hook onto user interventions, and intercept MO2 specific ones for customization - this.WhenAny(x => x.ActiveInstallation) - .Select(x => x?.LogMessages ?? Observable.Empty()) - .Switch() - .Subscribe(x => - { - switch (x) - { - case ConfirmUpdateOfExistingInstall c: - if (AutomaticallyOverwrite) - { - c.Confirm(); - } - break; - default: - break; - } - }) - .DisposeWith(CompositeDisposable); - */ } public void Unload() @@ -205,7 +111,7 @@ namespace Wabbajack */ return true; } - + public IUserIntervention InterventionConverter(IUserIntervention intervention) { switch (intervention) diff --git a/Wabbajack.App.Wpf/View Models/MainWindowVM.cs b/Wabbajack.App.Wpf/View Models/MainWindowVM.cs index 804a14d6..cd1430ed 100644 --- a/Wabbajack.App.Wpf/View Models/MainWindowVM.cs +++ b/Wabbajack.App.Wpf/View Models/MainWindowVM.cs @@ -16,11 +16,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Orc.FileAssociation; using Wabbajack.Common; -using Wabbajack.Downloaders.GameFile; -using Wabbajack; using Wabbajack.DTOs.Interventions; using Wabbajack.Interventions; -using Wabbajack.LoginManagers; using Wabbajack.Messages; using Wabbajack.Models; using Wabbajack.Networking.WabbajackClientApi; @@ -39,8 +36,6 @@ namespace Wabbajack { public MainWindow MainWindow { get; } - public MainSettings Settings { get; } - [Reactive] public ViewModel ActivePane { get; private set; } @@ -76,7 +71,7 @@ namespace Wabbajack [Reactive] public bool UpdateAvailable { get; private set; } - public MainWindowVM(ILogger logger, MainSettings settings, Client wjClient, + public MainWindowVM(ILogger logger, Client wjClient, IServiceProvider serviceProvider, ModeSelectionVM modeSelectionVM, ModListGalleryVM modListGalleryVM, ResourceMonitor resourceMonitor, InstallerVM installer, CompilerVM compilerVM, SettingsVM settingsVM, WebBrowserVM webBrowserVM) { @@ -85,7 +80,6 @@ namespace Wabbajack _resourceMonitor = resourceMonitor; _serviceProvider = serviceProvider; ConverterRegistration.Register(); - Settings = settings; Installer = installer; Compiler = compilerVM; SettingsPane = settingsVM; diff --git a/Wabbajack.App.Wpf/View Models/Settings/SettingsVM.cs b/Wabbajack.App.Wpf/View Models/Settings/SettingsVM.cs index 44ced940..a32855ce 100644 --- a/Wabbajack.App.Wpf/View Models/Settings/SettingsVM.cs +++ b/Wabbajack.App.Wpf/View Models/Settings/SettingsVM.cs @@ -2,28 +2,32 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Reflection; -using System.Text; using System.Threading.Tasks; using System.Windows.Input; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using ReactiveUI; -using Wabbajack; +using Wabbajack.Common; +using Wabbajack.Downloaders; using Wabbajack.LoginManagers; using Wabbajack.Messages; using Wabbajack.Networking.WabbajackClientApi; +using Wabbajack.RateLimiter; +using Wabbajack.Services.OSIntegrated; using Wabbajack.Services.OSIntegrated.TokenProviders; +using Wabbajack.Util; using Wabbajack.View_Models.Settings; namespace Wabbajack { public class SettingsVM : BackNavigatingVM { + private readonly Configuration.MainSettings _settings; + private readonly SettingsManager _settingsManager; + public LoginManagerVM Login { get; } public PerformanceSettings Performance { get; } - public FiltersSettings Filters { get; } public AuthorFilesVM AuthorFile { get; } public ICommand OpenTerminalCommand { get; } @@ -31,12 +35,30 @@ namespace Wabbajack public SettingsVM(ILogger logger, IServiceProvider provider) : base(logger) { - Login = new LoginManagerVM(provider.GetRequiredService>(), this, + _settings = provider.GetRequiredService(); + _settingsManager = provider.GetRequiredService(); + + Login = new LoginManagerVM(provider.GetRequiredService>(), this, provider.GetRequiredService>()); - AuthorFile = new AuthorFilesVM(provider.GetRequiredService>()!, + AuthorFile = new AuthorFilesVM(provider.GetRequiredService>()!, provider.GetRequiredService()!, provider.GetRequiredService()!, this); OpenTerminalCommand = ReactiveCommand.CreateFromTask(OpenTerminal); - BackCommand = ReactiveCommand.Create(NavigateBack.Send); + Performance = new PerformanceSettings( + _settings, + provider.GetRequiredService>(), + provider.GetRequiredService()); + BackCommand = ReactiveCommand.Create(() => + { + NavigateBack.Send(); + Unload(); + }); + } + + public override void Unload() + { + _settingsManager.Save(Configuration.MainSettings.SettingsFileName, _settings).FireAndForget(); + + base.Unload(); } private async Task OpenTerminal() diff --git a/Wabbajack.App.Wpf/Views/Common/CpuView.xaml.cs b/Wabbajack.App.Wpf/Views/Common/CpuView.xaml.cs index d56efa07..4541b3c4 100644 --- a/Wabbajack.App.Wpf/Views/Common/CpuView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Common/CpuView.xaml.cs @@ -1,24 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reactive.Disposables; -using System.Text; -using System.Threading.Tasks; +using System.Reactive.Disposables; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using ReactiveUI; -using ReactiveUI.Fody.Helpers; -using Wabbajack; -using System.Windows.Controls.Primitives; using System.Reactive.Linq; -using Wabbajack.Common; using Wabbajack.RateLimiter; namespace Wabbajack @@ -36,23 +19,12 @@ namespace Wabbajack public static readonly DependencyProperty ProgressPercentProperty = DependencyProperty.Register(nameof(ProgressPercent), typeof(Percent), typeof(CpuView), new FrameworkPropertyMetadata(default(Percent), WireNotifyPropertyChanged)); - public MainSettings SettingsHook - { - get => (MainSettings)GetValue(SettingsHookProperty); - set => SetValue(SettingsHookProperty, value); - } - public static readonly DependencyProperty SettingsHookProperty = DependencyProperty.Register(nameof(SettingsHook), typeof(MainSettings), typeof(CpuView), - new FrameworkPropertyMetadata(default(SettingsVM), WireNotifyPropertyChanged)); - - private bool _ShowingSettings; - public bool ShowingSettings { get => _ShowingSettings; set => this.RaiseAndSetIfChanged(ref _ShowingSettings, value); } - public CpuView() { InitializeComponent(); this.WhenActivated(disposable => { - + this.WhenAny(x => x.ViewModel.StatusList) .BindToStrict(this, x => x.CpuListControl.ItemsSource) .DisposeWith(disposable); diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml index 74284763..f76f9d15 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml @@ -12,7 +12,7 @@ x:TypeArguments="local:InstallerVM" mc:Ignorable="d"> - + @@ -23,6 +23,7 @@ + + Text="Modlist Readme" /> + + + + + + + + + Background="Transparent" Grid.ColumnSpan="2" Margin="0,0,10,0"> diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs index d2e70061..b4000b86 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs @@ -46,6 +46,9 @@ namespace Wabbajack this.WhenAny(x => x.ViewModel.OpenReadmeCommand) .BindToStrict(this, x => x.OpenReadmeButton.Command) .DisposeWith(dispose); + this.WhenAny(x => x.ViewModel.OpenWikiCommand) + .BindToStrict(this, x => x.OpenWikiButton.Command) + .DisposeWith(dispose); this.WhenAny(x => x.ViewModel.CloseWhenCompleteCommand) .BindToStrict(this, x => x.CloseButton.Command) .DisposeWith(dispose); diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml index 225346f0..6580df93 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml @@ -39,6 +39,13 @@ FontSize="14" Text="Target Modlist" TextAlignment="Center" /> + + + + + + + diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml.cs b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml.cs index 121da58f..178780e7 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml.cs @@ -39,14 +39,21 @@ namespace Wabbajack this.WhenAny(x => x.ViewModel.BeginCommand) .BindToStrict(this, x => x.BeginButton.Command) .DisposeWith(dispose); - + this.BindStrict(ViewModel, vm => vm.OverwriteFiles, x => x.OverwriteCheckBox.IsChecked) + .DisposeWith(dispose); + // Error handling - + this.WhenAnyValue(x => x.ViewModel.ErrorState) .Select(v => !v.Failed) .BindToStrict(this, view => view.BeginButton.IsEnabled) .DisposeWith(dispose); - + + this.WhenAnyValue(x => x.ViewModel.ErrorState) + .Select(v => v.Reason) + .BindToStrict(this, view => view.errorTextBox.Text) + .DisposeWith(dispose); + this.WhenAnyValue(x => x.ViewModel.ErrorState) .Select(v => v.Failed ? Visibility.Visible : Visibility.Hidden) .BindToStrict(this, view => view.ErrorSummaryIcon.Visibility) diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationView.xaml index 9dc049e9..39fc63ee 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationView.xaml @@ -324,20 +324,6 @@ - diff --git a/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml b/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml index 5561d7fd..f47095f3 100644 --- a/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml @@ -46,21 +46,5 @@ FontSize="14" PickerVM="{Binding DownloadLocation}" ToolTip="The directory where modlist archives will be downloaded to" /> - - - - - diff --git a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml b/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml deleted file mode 100644 index 60620f63..00000000 --- a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - + + + diff --git a/Wabbajack.App.Wpf/Views/Settings/PerformanceSettingsView.xaml.cs b/Wabbajack.App.Wpf/Views/Settings/PerformanceSettingsView.xaml.cs index efed2027..d2a0ee5c 100644 --- a/Wabbajack.App.Wpf/Views/Settings/PerformanceSettingsView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Settings/PerformanceSettingsView.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.Reactive.Disposables; using ReactiveUI; using Wabbajack.Paths.IO; @@ -15,12 +16,21 @@ namespace Wabbajack this.WhenActivated(disposable => { + this.BindStrict( + ViewModel, + x => x.MaximumMemoryPerDownloadThreadMb, + x => x.MaximumMemoryPerDownloadThreadIntegerUpDown.Value) + .DisposeWith(disposable); this.EditResourceSettings.Command = ReactiveCommand.Create(() => { UIUtils.OpenFile( KnownFolders.WabbajackAppLocal.Combine("saved_settings", "resource_settings.json")); Environment.Exit(0); }); + ResetMaximumMemoryPerDownloadThread.Command = ReactiveCommand.Create(() => + { + ViewModel.ResetMaximumMemoryPerDownloadThreadMb(); + }); }); } } diff --git a/Wabbajack.App.Wpf/Wabbajack.App.Wpf.csproj b/Wabbajack.App.Wpf/Wabbajack.App.Wpf.csproj index 6cec0311..af71c310 100644 --- a/Wabbajack.App.Wpf/Wabbajack.App.Wpf.csproj +++ b/Wabbajack.App.Wpf/Wabbajack.App.Wpf.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows + net7.0-windows true x64 win10-x64 @@ -73,12 +73,12 @@ - + NU1701 - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -95,11 +95,11 @@ - - - + + + - + diff --git a/Wabbajack.CLI.Builder/Wabbajack.CLI.Builder.csproj b/Wabbajack.CLI.Builder/Wabbajack.CLI.Builder.csproj index 28ed9b4e..87e50f36 100644 --- a/Wabbajack.CLI.Builder/Wabbajack.CLI.Builder.csproj +++ b/Wabbajack.CLI.Builder/Wabbajack.CLI.Builder.csproj @@ -1,14 +1,14 @@ - net6.0 + net7.0 enable enable - + diff --git a/Wabbajack.CLI/Wabbajack.CLI.csproj b/Wabbajack.CLI/Wabbajack.CLI.csproj index c9edf2b7..fe9ebfc9 100644 --- a/Wabbajack.CLI/Wabbajack.CLI.csproj +++ b/Wabbajack.CLI/Wabbajack.CLI.csproj @@ -1,4 +1,4 @@ - + Exe @@ -13,11 +13,12 @@ CS8600 CS8601 CS8618 + net7.0 - + diff --git a/Wabbajack.Common/HttpExtensions.cs b/Wabbajack.Common/HttpExtensions.cs index a0900120..b2ca8d39 100644 --- a/Wabbajack.Common/HttpExtensions.cs +++ b/Wabbajack.Common/HttpExtensions.cs @@ -14,12 +14,21 @@ namespace Wabbajack.Common; public static class HttpExtensions { + private const string ChromeUserAgent = + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"; public static HttpRequestMessage AddCookies(this HttpRequestMessage msg, Cookie[] cookies) { msg.Headers.Add("Cookie", string.Join(";", cookies.Select(c => $"{c.Name}={c.Value}"))); return msg; } - + + public static HttpRequestMessage AddChromeAgent(this HttpRequestMessage msg, string? overrideUserAgent = null) + { + msg.Headers.UserAgent.Clear(); + msg.Headers.Add("User-Agent", overrideUserAgent ?? ChromeUserAgent); + return msg; + } + public static HttpRequestMessage AddHeaders(this HttpRequestMessage msg, IEnumerable<(string Key, string Value)> headers) { foreach (var header in headers) @@ -29,17 +38,10 @@ public static class HttpExtensions return msg; } - public static HttpRequestMessage AddChromeAgent(this HttpRequestMessage msg) - { - msg.Headers.Add("User-Agent", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"); - return msg; - } - public static HttpRequestMessage ToHttpRequestMessage(this ManualDownload.BrowserDownloadState browserState) { var msg = new HttpRequestMessage(HttpMethod.Get, browserState.Uri); - msg.AddChromeAgent(); + msg.AddChromeAgent(browserState.UserAgent); msg.AddCookies(browserState.Cookies); msg.AddHeaders(browserState.Headers); return msg; diff --git a/Wabbajack.Common/Wabbajack.Common.csproj b/Wabbajack.Common/Wabbajack.Common.csproj index 35b829e3..a382ae26 100644 --- a/Wabbajack.Common/Wabbajack.Common.csproj +++ b/Wabbajack.Common/Wabbajack.Common.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) @@ -34,7 +34,7 @@ - + diff --git a/Wabbajack.Compiler.Test/Wabbajack.Compiler.Test.csproj b/Wabbajack.Compiler.Test/Wabbajack.Compiler.Test.csproj index 019ec030..b9b77692 100644 --- a/Wabbajack.Compiler.Test/Wabbajack.Compiler.Test.csproj +++ b/Wabbajack.Compiler.Test/Wabbajack.Compiler.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Compiler/Wabbajack.Compiler.csproj b/Wabbajack.Compiler/Wabbajack.Compiler.csproj index 62584356..9ca4cf58 100644 --- a/Wabbajack.Compiler/Wabbajack.Compiler.csproj +++ b/Wabbajack.Compiler/Wabbajack.Compiler.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Compression.BSA.Test/Wabbajack.Compression.BSA.Test.csproj b/Wabbajack.Compression.BSA.Test/Wabbajack.Compression.BSA.Test.csproj index c9ee6010..270a509f 100644 --- a/Wabbajack.Compression.BSA.Test/Wabbajack.Compression.BSA.Test.csproj +++ b/Wabbajack.Compression.BSA.Test/Wabbajack.Compression.BSA.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Compression.BSA/Wabbajack.Compression.BSA.csproj b/Wabbajack.Compression.BSA/Wabbajack.Compression.BSA.csproj index ae648ab2..d9d11284 100644 --- a/Wabbajack.Compression.BSA/Wabbajack.Compression.BSA.csproj +++ b/Wabbajack.Compression.BSA/Wabbajack.Compression.BSA.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable true GPL-3.0-or-later diff --git a/Wabbajack.Compression.Zip.Test/Wabbajack.Compression.Zip.Test.csproj b/Wabbajack.Compression.Zip.Test/Wabbajack.Compression.Zip.Test.csproj index 3d04da28..6d15e005 100644 --- a/Wabbajack.Compression.Zip.Test/Wabbajack.Compression.Zip.Test.csproj +++ b/Wabbajack.Compression.Zip.Test/Wabbajack.Compression.Zip.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable false diff --git a/Wabbajack.Compression.Zip/Wabbajack.Compression.Zip.csproj b/Wabbajack.Compression.Zip/Wabbajack.Compression.Zip.csproj index bad41454..01178a67 100644 --- a/Wabbajack.Compression.Zip/Wabbajack.Compression.Zip.csproj +++ b/Wabbajack.Compression.Zip/Wabbajack.Compression.Zip.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Configuration/MainSettings.cs b/Wabbajack.Configuration/MainSettings.cs new file mode 100644 index 00000000..5b8bf4eb --- /dev/null +++ b/Wabbajack.Configuration/MainSettings.cs @@ -0,0 +1,27 @@ +namespace Wabbajack.Configuration; + +public class MainSettings +{ + public const string SettingsFileName = "app_settings"; + private const int SettingsVersion = 1; + + public int CurrentSettingsVersion { get; set; } + + public PerformanceSettings PerformanceSettings { get; set; } = new(); + + public bool Upgrade() + { + if (CurrentSettingsVersion == SettingsVersion) + { + return false; + } + + if (CurrentSettingsVersion < 1) + { + PerformanceSettings.MaximumMemoryPerDownloadThreadMb = -1; + } + + CurrentSettingsVersion = SettingsVersion; + return true; + } +} \ No newline at end of file diff --git a/Wabbajack.Configuration/PerformanceSettings.cs b/Wabbajack.Configuration/PerformanceSettings.cs new file mode 100644 index 00000000..93dff240 --- /dev/null +++ b/Wabbajack.Configuration/PerformanceSettings.cs @@ -0,0 +1,6 @@ +namespace Wabbajack.Configuration; + +public class PerformanceSettings +{ + public int MaximumMemoryPerDownloadThreadMb { get; set; } +} \ No newline at end of file diff --git a/Wabbajack.Configuration/Wabbajack.Configuration.csproj b/Wabbajack.Configuration/Wabbajack.Configuration.csproj new file mode 100644 index 00000000..cfadb03d --- /dev/null +++ b/Wabbajack.Configuration/Wabbajack.Configuration.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + diff --git a/Wabbajack.DTOs.ConverterGenerators/Wabbajack.DTOs.ConverterGenerators.csproj b/Wabbajack.DTOs.ConverterGenerators/Wabbajack.DTOs.ConverterGenerators.csproj index f549991b..3831f9b2 100644 --- a/Wabbajack.DTOs.ConverterGenerators/Wabbajack.DTOs.ConverterGenerators.csproj +++ b/Wabbajack.DTOs.ConverterGenerators/Wabbajack.DTOs.ConverterGenerators.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 GPL-3.0-or-later $(VERSION) CS8600 diff --git a/Wabbajack.DTOs.Test/Wabbajack.DTOs.Test.csproj b/Wabbajack.DTOs.Test/Wabbajack.DTOs.Test.csproj index eb42bd83..6bc36413 100644 --- a/Wabbajack.DTOs.Test/Wabbajack.DTOs.Test.csproj +++ b/Wabbajack.DTOs.Test/Wabbajack.DTOs.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.DTOs/Game/GameMetaData.cs b/Wabbajack.DTOs/Game/GameMetaData.cs index 36dc7c9f..1b4a4061 100644 --- a/Wabbajack.DTOs/Game/GameMetaData.cs +++ b/Wabbajack.DTOs/Game/GameMetaData.cs @@ -21,7 +21,7 @@ public class GameMetaData public int[] SteamIDs { get; internal init; } = Array.Empty(); // to get gog ids: https://www.gogdb.org - public int[] GOGIDs { get; internal init; } = Array.Empty(); + public long[] GOGIDs { get; internal init; } = Array.Empty(); // to get these ids, split the numbers from the letters in file names found in // C:\ProgramData\Origin\LocalContent\{game name)\*.mfst diff --git a/Wabbajack.DTOs/Game/GameRegistry.cs b/Wabbajack.DTOs/Game/GameRegistry.cs index 95bec0e6..4bf839a3 100644 --- a/Wabbajack.DTOs/Game/GameRegistry.cs +++ b/Wabbajack.DTOs/Game/GameRegistry.cs @@ -14,7 +14,7 @@ public static class GameRegistry { Game = Game.Morrowind, SteamIDs = new[] {22320}, - GOGIDs = new[] {1440163901, 1435828767}, + GOGIDs = new long[] {1440163901, 1435828767}, NexusName = "morrowind", NexusGameId = 100, MO2Name = "Morrowind", @@ -38,7 +38,7 @@ public static class GameRegistry MO2Name = "Oblivion", MO2ArchiveName = "oblivion", SteamIDs = new[] {22330}, - GOGIDs = new[] {1458058109}, + GOGIDs = new long[] {1458058109}, RequiredFiles = new[] { "oblivion.exe".ToRelativePath() @@ -56,7 +56,7 @@ public static class GameRegistry MO2Name = "Fallout 3", MO2ArchiveName = "fallout3", SteamIDs = new[] {22300, 22370}, // base game and GotY - GOGIDs = new[] {1454315831}, // GotY edition + GOGIDs = new long[] {1454315831}, // GotY edition RequiredFiles = new[] { "Fallout3.exe".ToRelativePath() @@ -73,7 +73,7 @@ public static class GameRegistry MO2Name = "New Vegas", MO2ArchiveName = "falloutnv", SteamIDs = new[] {22380, 22490}, // normal and RU version - GOGIDs = new[] {1454587428}, + GOGIDs = new long[] {1454587428}, RequiredFiles = new[] { "FalloutNV.exe".ToRelativePath() @@ -107,7 +107,7 @@ public static class GameRegistry MO2Name = "Skyrim Special Edition", MO2ArchiveName = "skyrimse", SteamIDs = new[] {489830}, - GOGIDs = new[] + GOGIDs = new long[] { 1711230643,// The Elder Scrolls V: Skyrim Special Edition AKA Base Game 1801825368,// The Elder Scrolls V: Skyrim Anniversary Edition AKA The Store Bundle @@ -130,6 +130,7 @@ public static class GameRegistry MO2Name = "Fallout 4", MO2ArchiveName = "fallout4", SteamIDs = new[] {377160}, + GOGIDs = new long[]{1998527297}, RequiredFiles = new[] { "Fallout4.exe".ToRelativePath() @@ -182,7 +183,7 @@ public static class GameRegistry MO2Name = "Enderal Special Edition", MO2ArchiveName = "enderalse", SteamIDs = new[] {976620}, - GOGIDs = new [] {1708684988}, + GOGIDs = new long[] {1708684988}, RequiredFiles = new[] { "SkyrimSE.exe".ToRelativePath() @@ -216,7 +217,7 @@ public static class GameRegistry MO2Name = "Darkest Dungeon", NexusGameId = 804, SteamIDs = new[] {262060}, - GOGIDs = new[] {1450711444}, + GOGIDs = new long[] {1450711444}, EpicGameStoreIDs = new[] {"b4eecf70e3fe4e928b78df7855a3fc2d"}, IsGenericMO2Plugin = true, RequiredFiles = new[] @@ -235,7 +236,7 @@ public static class GameRegistry MO2ArchiveName = "dishonored", NexusGameId = 802, SteamIDs = new[] {205100}, - GOGIDs = new[] {1701063787}, + GOGIDs = new long[] {1701063787}, RequiredFiles = new[] { @"Binaries\Win32\Dishonored.exe".ToRelativePath() @@ -252,7 +253,7 @@ public static class GameRegistry MO2Name = "The Witcher: Enhanced Edition", MO2ArchiveName = "witcher", SteamIDs = new[] {20900}, // normal and GotY - GOGIDs = new[] {1207658924}, // normal, GotY and both in packages + GOGIDs = new long[] {1207658924}, // normal, GotY and both in packages RequiredFiles = new[] { @"System\witcher.exe".ToRelativePath() @@ -269,7 +270,7 @@ public static class GameRegistry MO2Name = "The Witcher 3: Wild Hunt", MO2ArchiveName = "witcher3", SteamIDs = new[] {292030, 499450}, // normal and GotY - GOGIDs = new[] + GOGIDs = new long[] {1207664643, 1495134320, 1207664663, 1640424747}, // normal, GotY and both in packages RequiredFiles = new[] { @@ -287,7 +288,7 @@ public static class GameRegistry MO2ArchiveName = "stardewvalley", NexusGameId = 1303, SteamIDs = new[] {413150}, - GOGIDs = new[] {1453375253}, + GOGIDs = new long[] {1453375253}, IsGenericMO2Plugin = true, RequiredFiles = new[] { @@ -305,7 +306,7 @@ public static class GameRegistry MO2ArchiveName = "kingdomcomedeliverance", NexusGameId = 2298, SteamIDs = new[] {379430}, - GOGIDs = new[] {1719198803}, + GOGIDs = new long[] {1719198803}, IsGenericMO2Plugin = true, RequiredFiles = new[] { @@ -339,7 +340,7 @@ public static class GameRegistry NexusGameId = 1634, MO2Name = "No Man's Sky", SteamIDs = new[] {275850}, - GOGIDs = new[] {1446213994}, + GOGIDs = new long[] {1446213994}, RequiredFiles = new[] { @"Binaries\NMS.exe".ToRelativePath() @@ -356,7 +357,7 @@ public static class GameRegistry MO2Name = "Dragon Age: Origins", SteamIDs = new[] {47810}, OriginIDs = new[] {"DR:169789300", "DR:208591800"}, - GOGIDs = new[] {1949616134}, + GOGIDs = new long[] {1949616134}, RequiredFiles = new[] { @"bin_ship\daorigins.exe".ToRelativePath() @@ -404,7 +405,7 @@ public static class GameRegistry MO2Name = "Kerbal Space Program", NexusGameId = 272, SteamIDs = new[] {220200}, - GOGIDs = new[] {1429864849}, + GOGIDs = new long[] {1429864849}, IsGenericMO2Plugin = true, RequiredFiles = new[] { @@ -432,7 +433,7 @@ public static class GameRegistry { Game = Game.Cyberpunk2077, SteamIDs = new[] {1091500}, - GOGIDs = new [] {2093619782, 1423049311}, + GOGIDs = new long[] {2093619782, 1423049311}, EpicGameStoreIDs = new[] {"5beededaad9743df90e8f07d92df153f"}, MO2Name = "Cyberpunk 2077", NexusName = "cyberpunk2077", @@ -466,7 +467,7 @@ public static class GameRegistry { Game = Game.DragonsDogma, SteamIDs = new[] {367500 }, - GOGIDs = new []{1242384383}, + GOGIDs = new long[]{1242384383}, MO2Name = "Dragon's Dogma: Dark Arisen", MO2ArchiveName = "dragonsdogma", NexusName = "dragonsdogma", @@ -520,7 +521,7 @@ public static class GameRegistry MO2Name = "Mount & Blade II: Bannerlord", MO2ArchiveName = "mountandblade2bannerlord", SteamIDs = new[] { 261550 }, - GOGIDs = new [] { + GOGIDs = new long[] { 1564781494, //Mount & Blade II: Bannerlord : Game 1681929523, //Mount & Blade II: Bannerlord - Digital Deluxe : Package 1802539526, //Mount & Blade II: Bannerlord : Package diff --git a/Wabbajack.DTOs/Interventions/ManualDownload.cs b/Wabbajack.DTOs/Interventions/ManualDownload.cs index 15a3be24..84dda1dd 100644 --- a/Wabbajack.DTOs/Interventions/ManualDownload.cs +++ b/Wabbajack.DTOs/Interventions/ManualDownload.cs @@ -10,14 +10,14 @@ namespace Wabbajack.DTOs.Interventions; public class ManualDownload : AUserIntervention { public Archive Archive { get; } - + public ManualDownload(Archive archive) { Archive = archive; } - public record BrowserDownloadState(Uri Uri, Cookie[] Cookies, (string Key, string Value)[] Headers) + public record BrowserDownloadState(Uri Uri, Cookie[] Cookies, (string Key, string Value)[] Headers, string UserAgent) { - + } } \ No newline at end of file diff --git a/Wabbajack.DTOs/ModList/ModListMetadata.cs b/Wabbajack.DTOs/ModList/ModListMetadata.cs index fbb27dab..df3bfd50 100644 --- a/Wabbajack.DTOs/ModList/ModListMetadata.cs +++ b/Wabbajack.DTOs/ModList/ModListMetadata.cs @@ -30,6 +30,8 @@ public class ModlistMetadata [JsonPropertyName("image_contains_title")] public bool ImageContainsTitle { get; set; } + [JsonPropertyName("DisplayVersionOnlyInInstallerView")] public bool DisplayVersionOnlyInInstallerView { get; set; } + [JsonPropertyName("force_down")] public bool ForceDown { get; set; } [JsonPropertyName("links")] public LinksObject Links { get; set; } = new(); diff --git a/Wabbajack.DTOs/Wabbajack.DTOs.csproj b/Wabbajack.DTOs/Wabbajack.DTOs.csproj index 4e232d26..04b1cc65 100644 --- a/Wabbajack.DTOs/Wabbajack.DTOs.csproj +++ b/Wabbajack.DTOs/Wabbajack.DTOs.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Downloaders.Bethesda/Wabbajack.Downloaders.Bethesda.csproj b/Wabbajack.Downloaders.Bethesda/Wabbajack.Downloaders.Bethesda.csproj index 7544d14c..02afa7a1 100644 --- a/Wabbajack.Downloaders.Bethesda/Wabbajack.Downloaders.Bethesda.csproj +++ b/Wabbajack.Downloaders.Bethesda/Wabbajack.Downloaders.Bethesda.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Downloaders.Dispatcher.Test/Wabbajack.Downloaders.Dispatcher.Test.csproj b/Wabbajack.Downloaders.Dispatcher.Test/Wabbajack.Downloaders.Dispatcher.Test.csproj index 901a70cc..9070839d 100644 --- a/Wabbajack.Downloaders.Dispatcher.Test/Wabbajack.Downloaders.Dispatcher.Test.csproj +++ b/Wabbajack.Downloaders.Dispatcher.Test/Wabbajack.Downloaders.Dispatcher.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/Wabbajack.Downloaders.Dispatcher/Wabbajack.Downloaders.Dispatcher.csproj b/Wabbajack.Downloaders.Dispatcher/Wabbajack.Downloaders.Dispatcher.csproj index 0db2bd81..7cebb553 100644 --- a/Wabbajack.Downloaders.Dispatcher/Wabbajack.Downloaders.Dispatcher.csproj +++ b/Wabbajack.Downloaders.Dispatcher/Wabbajack.Downloaders.Dispatcher.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Downloaders.GameFile/GameLocator.cs b/Wabbajack.Downloaders.GameFile/GameLocator.cs index 2cf9aef9..8c2a9d94 100644 --- a/Wabbajack.Downloaders.GameFile/GameLocator.cs +++ b/Wabbajack.Downloaders.GameFile/GameLocator.cs @@ -5,6 +5,8 @@ using GameFinder.StoreHandlers.EGS; using GameFinder.StoreHandlers.GOG; using GameFinder.StoreHandlers.Origin; using GameFinder.StoreHandlers.Steam; +using GameFinder.StoreHandlers.Steam.Models; +using GameFinder.StoreHandlers.Steam.Models.ValueTypes; using Microsoft.Extensions.Logging; using Wabbajack.DTOs; using Wabbajack.Paths; @@ -19,10 +21,10 @@ public class GameLocator : IGameLocator private readonly EGSHandler? _egs; private readonly OriginHandler? _origin; - private readonly Dictionary _steamGames = new(); - private readonly Dictionary _gogGames = new(); - private readonly Dictionary _egsGames = new(StringComparer.OrdinalIgnoreCase); - private readonly Dictionary _originGames = new(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _steamGames = new(); + private readonly Dictionary _gogGames = new(); + private readonly Dictionary _egsGames = new(); + private readonly Dictionary _originGames = new(); private readonly Dictionary _locationCache; private readonly ILogger _logger; @@ -30,19 +32,20 @@ public class GameLocator : IGameLocator public GameLocator(ILogger logger) { _logger = logger; + var fileSystem = NexusMods.Paths.FileSystem.Shared; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var windowsRegistry = new WindowsRegistry(); - _steam = new SteamHandler(windowsRegistry); - _gog = new GOGHandler(windowsRegistry); - _egs = new EGSHandler(windowsRegistry); - _origin = new OriginHandler(); + _steam = new SteamHandler(fileSystem, windowsRegistry); + _gog = new GOGHandler(windowsRegistry, fileSystem); + _egs = new EGSHandler(windowsRegistry, fileSystem); + _origin = new OriginHandler(fileSystem); } else { - _steam = new SteamHandler(null); + _steam = new SteamHandler(fileSystem, null); } _locationCache = new Dictionary(); @@ -54,7 +57,7 @@ public class GameLocator : IGameLocator { try { - FindStoreGames(_steam, _steamGames, game => game.Path); + FindStoreGames(_steam, _steamGames, game => (AbsolutePath)game.Path.GetFullPath()); } catch (Exception e) { @@ -63,7 +66,7 @@ public class GameLocator : IGameLocator try { - FindStoreGames(_gog, _gogGames, game => game.Path); + FindStoreGames(_gog, _gogGames, game => (AbsolutePath)game.Path.GetFullPath()); } catch (Exception e) { @@ -72,7 +75,7 @@ public class GameLocator : IGameLocator try { - FindStoreGames(_egs, _egsGames, game => game.InstallLocation); + FindStoreGames(_egs, _egsGames, game => (AbsolutePath)game.InstallLocation.GetFullPath()); } catch (Exception e) { @@ -81,7 +84,7 @@ public class GameLocator : IGameLocator try { - FindStoreGames(_origin, _originGames, game => game.InstallPath); + FindStoreGames(_origin, _originGames, game => (AbsolutePath)game.InstallPath.GetFullPath()); } catch (Exception e) { @@ -92,8 +95,9 @@ public class GameLocator : IGameLocator private void FindStoreGames( AHandler? handler, Dictionary paths, - Func getPath) - where TGame : class + Func getPath) + where TGame : class, IGame + where TId : notnull { if (handler is null) return; @@ -103,7 +107,7 @@ public class GameLocator : IGameLocator { try { - var path = getPath(game).ToAbsolutePath(); + var path = getPath(game); if (!path.DirectoryExists()) { _logger.LogError("Game does not exist: {Game}", game); @@ -160,28 +164,28 @@ public class GameLocator : IGameLocator foreach (var id in metaData.SteamIDs) { - if (!_steamGames.TryGetValue(id, out var found)) continue; + if (!_steamGames.TryGetValue(AppId.From((uint)id), out var found)) continue; path = found; return true; } foreach (var id in metaData.GOGIDs) { - if (!_gogGames.TryGetValue(id, out var found)) continue; + if (!_gogGames.TryGetValue(GOGGameId.From(id), out var found)) continue; path = found; return true; } foreach (var id in metaData.EpicGameStoreIDs) { - if (!_egsGames.TryGetValue(id, out var found)) continue; + if (!_egsGames.TryGetValue(EGSGameId.From(id), out var found)) continue; path = found; return true; } foreach (var id in metaData.OriginIDs) { - if (!_originGames.TryGetValue(id, out var found)) continue; + if (!_originGames.TryGetValue(OriginGameId.From(id), out var found)) continue; path = found; return true; } diff --git a/Wabbajack.Downloaders.GameFile/Wabbajack.Downloaders.GameFile.csproj b/Wabbajack.Downloaders.GameFile/Wabbajack.Downloaders.GameFile.csproj index 26f0e1ca..598216a2 100644 --- a/Wabbajack.Downloaders.GameFile/Wabbajack.Downloaders.GameFile.csproj +++ b/Wabbajack.Downloaders.GameFile/Wabbajack.Downloaders.GameFile.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable @@ -18,10 +18,10 @@ - - - - + + + + diff --git a/Wabbajack.Downloaders.GoogleDrive/GoogleDriveDownloader.cs b/Wabbajack.Downloaders.GoogleDrive/GoogleDriveDownloader.cs index 2dede342..c4906694 100644 --- a/Wabbajack.Downloaders.GoogleDrive/GoogleDriveDownloader.cs +++ b/Wabbajack.Downloaders.GoogleDrive/GoogleDriveDownloader.cs @@ -65,7 +65,7 @@ public class GoogleDriveDownloader : ADownloader iniData) { if (iniData.ContainsKey("directURL") && Uri.TryCreate(iniData["directURL"].CleanIniString(), UriKind.Absolute, out var uri)) @@ -74,8 +74,8 @@ public class GoogleDriveDownloader : ADownloader Priority.Normal; - - + + public async Task DownloadStream(Archive archive, Func> fn, CancellationToken token) { var state = archive.State as DTOs.DownloadStates.GoogleDrive; @@ -112,8 +112,8 @@ public class GoogleDriveDownloader : ADownloader c.Key.StartsWith("download_warning_")); @@ -124,7 +124,7 @@ public class GoogleDriveDownloader : ADownloaderGoogle Drive - Quota exceeded")) throw new Exception("Google Drive - Quota Exceeded"); - + doc.LoadHtml(txt); var action = doc.DocumentNode.DescendantsAndSelf() @@ -133,7 +133,7 @@ public class GoogleDriveDownloader : ADownloader d.GetAttributeValue("action", "")) .FirstOrDefault(); - if (action != null) + if (action != null) warning = ("download_warning_", "t"); } @@ -145,18 +145,18 @@ public class GoogleDriveDownloader : ADownloader - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Downloaders.Http/Wabbajack.Downloaders.Http.csproj b/Wabbajack.Downloaders.Http/Wabbajack.Downloaders.Http.csproj index f0190d2e..e0fbecdb 100644 --- a/Wabbajack.Downloaders.Http/Wabbajack.Downloaders.Http.csproj +++ b/Wabbajack.Downloaders.Http/Wabbajack.Downloaders.Http.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Downloaders.IPS4OAuth2Downloader/Wabbajack.Downloaders.IPS4OAuth2Downloader.csproj b/Wabbajack.Downloaders.IPS4OAuth2Downloader/Wabbajack.Downloaders.IPS4OAuth2Downloader.csproj index ae2488eb..6fdce2ea 100644 --- a/Wabbajack.Downloaders.IPS4OAuth2Downloader/Wabbajack.Downloaders.IPS4OAuth2Downloader.csproj +++ b/Wabbajack.Downloaders.IPS4OAuth2Downloader/Wabbajack.Downloaders.IPS4OAuth2Downloader.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable diff --git a/Wabbajack.Downloaders.Interfaces/Wabbajack.Downloaders.Interfaces.csproj b/Wabbajack.Downloaders.Interfaces/Wabbajack.Downloaders.Interfaces.csproj index 88869b1c..d3acee8e 100644 --- a/Wabbajack.Downloaders.Interfaces/Wabbajack.Downloaders.Interfaces.csproj +++ b/Wabbajack.Downloaders.Interfaces/Wabbajack.Downloaders.Interfaces.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) diff --git a/Wabbajack.Downloaders.Manual/Wabbajack.Downloaders.Manual.csproj b/Wabbajack.Downloaders.Manual/Wabbajack.Downloaders.Manual.csproj index efbf5c33..575e7e12 100644 --- a/Wabbajack.Downloaders.Manual/Wabbajack.Downloaders.Manual.csproj +++ b/Wabbajack.Downloaders.Manual/Wabbajack.Downloaders.Manual.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Downloaders.MediaFire/Wabbajack.Downloaders.MediaFire.csproj b/Wabbajack.Downloaders.MediaFire/Wabbajack.Downloaders.MediaFire.csproj index 7c3378e9..883ad2d0 100644 --- a/Wabbajack.Downloaders.MediaFire/Wabbajack.Downloaders.MediaFire.csproj +++ b/Wabbajack.Downloaders.MediaFire/Wabbajack.Downloaders.MediaFire.csproj @@ -1,13 +1,13 @@ - net6.0 + net7.0 enable - + diff --git a/Wabbajack.Downloaders.Mega/Wabbajack.Downloaders.Mega.csproj b/Wabbajack.Downloaders.Mega/Wabbajack.Downloaders.Mega.csproj index 300a2784..2c58d3a0 100644 --- a/Wabbajack.Downloaders.Mega/Wabbajack.Downloaders.Mega.csproj +++ b/Wabbajack.Downloaders.Mega/Wabbajack.Downloaders.Mega.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable diff --git a/Wabbajack.Downloaders.ModDB/Wabbajack.Downloaders.ModDB.csproj b/Wabbajack.Downloaders.ModDB/Wabbajack.Downloaders.ModDB.csproj index ed35adc1..d32eb433 100644 --- a/Wabbajack.Downloaders.ModDB/Wabbajack.Downloaders.ModDB.csproj +++ b/Wabbajack.Downloaders.ModDB/Wabbajack.Downloaders.ModDB.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable diff --git a/Wabbajack.Downloaders.Nexus/Wabbajack.Downloaders.Nexus.csproj b/Wabbajack.Downloaders.Nexus/Wabbajack.Downloaders.Nexus.csproj index 96c12049..6fc137e1 100644 --- a/Wabbajack.Downloaders.Nexus/Wabbajack.Downloaders.Nexus.csproj +++ b/Wabbajack.Downloaders.Nexus/Wabbajack.Downloaders.Nexus.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) diff --git a/Wabbajack.Downloaders.VerificationCache/Wabbajack.Downloaders.VerificationCache.csproj b/Wabbajack.Downloaders.VerificationCache/Wabbajack.Downloaders.VerificationCache.csproj index 775a9597..864b1a37 100644 --- a/Wabbajack.Downloaders.VerificationCache/Wabbajack.Downloaders.VerificationCache.csproj +++ b/Wabbajack.Downloaders.VerificationCache/Wabbajack.Downloaders.VerificationCache.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Downloaders.WabbajackCDN/Wabbajack.Downloaders.WabbajackCDN.csproj b/Wabbajack.Downloaders.WabbajackCDN/Wabbajack.Downloaders.WabbajackCDN.csproj index c04a827f..c9a9c634 100644 --- a/Wabbajack.Downloaders.WabbajackCDN/Wabbajack.Downloaders.WabbajackCDN.csproj +++ b/Wabbajack.Downloaders.WabbajackCDN/Wabbajack.Downloaders.WabbajackCDN.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.FileExtractor.Test/Wabbajack.FileExtractor.Test.csproj b/Wabbajack.FileExtractor.Test/Wabbajack.FileExtractor.Test.csproj index 6e070afe..40378dd9 100644 --- a/Wabbajack.FileExtractor.Test/Wabbajack.FileExtractor.Test.csproj +++ b/Wabbajack.FileExtractor.Test/Wabbajack.FileExtractor.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/Wabbajack.FileExtractor/Wabbajack.FileExtractor.csproj b/Wabbajack.FileExtractor/Wabbajack.FileExtractor.csproj index 356afd7d..358a3e0a 100644 --- a/Wabbajack.FileExtractor/Wabbajack.FileExtractor.csproj +++ b/Wabbajack.FileExtractor/Wabbajack.FileExtractor.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Hashing.PHash.Test/Wabbajack.Hashing.PHash.Test.csproj b/Wabbajack.Hashing.PHash.Test/Wabbajack.Hashing.PHash.Test.csproj index 2f5f8283..7119afd0 100644 --- a/Wabbajack.Hashing.PHash.Test/Wabbajack.Hashing.PHash.Test.csproj +++ b/Wabbajack.Hashing.PHash.Test/Wabbajack.Hashing.PHash.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Hashing.PHash/Wabbajack.Hashing.PHash.csproj b/Wabbajack.Hashing.PHash/Wabbajack.Hashing.PHash.csproj index 0d66a3e1..78d738ce 100644 --- a/Wabbajack.Hashing.PHash/Wabbajack.Hashing.PHash.csproj +++ b/Wabbajack.Hashing.PHash/Wabbajack.Hashing.PHash.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Hashing.xxHash64.Benchmark/Wabbajack.Hashing.xxHash64.Benchmark.csproj b/Wabbajack.Hashing.xxHash64.Benchmark/Wabbajack.Hashing.xxHash64.Benchmark.csproj index 4e9b1f49..03dff657 100644 --- a/Wabbajack.Hashing.xxHash64.Benchmark/Wabbajack.Hashing.xxHash64.Benchmark.csproj +++ b/Wabbajack.Hashing.xxHash64.Benchmark/Wabbajack.Hashing.xxHash64.Benchmark.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 Wabbajac.Hash.xxHash64.Benchmark true diff --git a/Wabbajack.Hashing.xxHash64.Test/Wabbajack.Hashing.xxHash64.Test.csproj b/Wabbajack.Hashing.xxHash64.Test/Wabbajack.Hashing.xxHash64.Test.csproj index d4523c52..204f9d5f 100644 --- a/Wabbajack.Hashing.xxHash64.Test/Wabbajack.Hashing.xxHash64.Test.csproj +++ b/Wabbajack.Hashing.xxHash64.Test/Wabbajack.Hashing.xxHash64.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Hashing.xxHash64/Wabbajack.Hashing.xxHash64.csproj b/Wabbajack.Hashing.xxHash64/Wabbajack.Hashing.xxHash64.csproj index f6edd4e1..f26d307e 100644 --- a/Wabbajack.Hashing.xxHash64/Wabbajack.Hashing.xxHash64.csproj +++ b/Wabbajack.Hashing.xxHash64/Wabbajack.Hashing.xxHash64.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.IO.Async/Wabbajack.IO.Async.csproj b/Wabbajack.IO.Async/Wabbajack.IO.Async.csproj index eb2460e9..6836c680 100644 --- a/Wabbajack.IO.Async/Wabbajack.IO.Async.csproj +++ b/Wabbajack.IO.Async/Wabbajack.IO.Async.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Installer.Test/Wabbajack.Installer.Test.csproj b/Wabbajack.Installer.Test/Wabbajack.Installer.Test.csproj index c1dbcbe2..590be299 100644 --- a/Wabbajack.Installer.Test/Wabbajack.Installer.Test.csproj +++ b/Wabbajack.Installer.Test/Wabbajack.Installer.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/Wabbajack.Installer/Wabbajack.Installer.csproj b/Wabbajack.Installer/Wabbajack.Installer.csproj index 845d9ca3..28277612 100644 --- a/Wabbajack.Installer/Wabbajack.Installer.csproj +++ b/Wabbajack.Installer/Wabbajack.Installer.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Launcher/ViewModels/MainWindowViewModel.cs b/Wabbajack.Launcher/ViewModels/MainWindowViewModel.cs index 5b2c514b..75472aa3 100644 --- a/Wabbajack.Launcher/ViewModels/MainWindowViewModel.cs +++ b/Wabbajack.Launcher/ViewModels/MainWindowViewModel.cs @@ -231,7 +231,7 @@ public class MainWindowViewModel : ViewModelBase ShowInCenter = true, ContentTitle = "Wabbajack Launcher: Bad startup path", ContentMessage = - "Cannot start in the root of a drive, or protected folder locations such as Downloads, Desktop etc.\nPlease move Wabbajack to another folder." + "Cannot start in the root of a drive, or protected folder locations such as Downloads, Desktop etc.\nPlease move Wabbajack to another folder, creating a new folder if necessary ( example : C:\\Wabbajack\\), outside of these locations." }); var result = await msg.Show(); Environment.Exit(1); diff --git a/Wabbajack.Launcher/Wabbajack.Launcher.csproj b/Wabbajack.Launcher/Wabbajack.Launcher.csproj index a188ab0b..a47fefab 100644 --- a/Wabbajack.Launcher/Wabbajack.Launcher.csproj +++ b/Wabbajack.Launcher/Wabbajack.Launcher.csproj @@ -16,6 +16,7 @@ Resources\Icons\wabbajack.ico + net7.0-windows @@ -30,7 +31,7 @@ - + diff --git a/Wabbajack.Networking.BethesdaNet/Wabbajack.Networking.BethesdaNet.csproj b/Wabbajack.Networking.BethesdaNet/Wabbajack.Networking.BethesdaNet.csproj index 0267a74f..68bb36ab 100644 --- a/Wabbajack.Networking.BethesdaNet/Wabbajack.Networking.BethesdaNet.csproj +++ b/Wabbajack.Networking.BethesdaNet/Wabbajack.Networking.BethesdaNet.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Networking.Discord/Wabbajack.Networking.Discord.csproj b/Wabbajack.Networking.Discord/Wabbajack.Networking.Discord.csproj index 1061d857..c9ab6aab 100644 --- a/Wabbajack.Networking.Discord/Wabbajack.Networking.Discord.csproj +++ b/Wabbajack.Networking.Discord/Wabbajack.Networking.Discord.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) diff --git a/Wabbajack.Networking.GitHub/Wabbajack.Networking.GitHub.csproj b/Wabbajack.Networking.GitHub/Wabbajack.Networking.GitHub.csproj index d75d9f31..40e65542 100644 --- a/Wabbajack.Networking.GitHub/Wabbajack.Networking.GitHub.csproj +++ b/Wabbajack.Networking.GitHub/Wabbajack.Networking.GitHub.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) diff --git a/Wabbajack.Networking.Http.Interfaces/Wabbajack.Networking.Http.Interfaces.csproj b/Wabbajack.Networking.Http.Interfaces/Wabbajack.Networking.Http.Interfaces.csproj index e9ee3e62..5037943c 100644 --- a/Wabbajack.Networking.Http.Interfaces/Wabbajack.Networking.Http.Interfaces.csproj +++ b/Wabbajack.Networking.Http.Interfaces/Wabbajack.Networking.Http.Interfaces.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Networking.Http.Test/Wabbajack.Networking.Http.Test.csproj b/Wabbajack.Networking.Http.Test/Wabbajack.Networking.Http.Test.csproj index 0aecc8b7..a20f6ab2 100644 --- a/Wabbajack.Networking.Http.Test/Wabbajack.Networking.Http.Test.csproj +++ b/Wabbajack.Networking.Http.Test/Wabbajack.Networking.Http.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable false diff --git a/Wabbajack.Networking.Http/Extensions.cs b/Wabbajack.Networking.Http/Extensions.cs index 81b751e6..eed4666b 100644 --- a/Wabbajack.Networking.Http/Extensions.cs +++ b/Wabbajack.Networking.Http/Extensions.cs @@ -10,13 +10,6 @@ namespace Wabbajack.Networking.Http; public static class Extensions { - public static HttpRequestMessage UseChromeUserAgent(this HttpRequestMessage msg) - { - msg.Headers.UserAgent.Clear(); - msg.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"); - return msg; - } - public static async Task GetJsonFromSendAsync(this HttpClient client, HttpRequestMessage msg, JsonSerializerOptions opts, CancellationToken? token = null) { diff --git a/Wabbajack.Networking.Http/ResumableDownloader.cs b/Wabbajack.Networking.Http/ResumableDownloader.cs index ca07712c..025715e4 100644 --- a/Wabbajack.Networking.Http/ResumableDownloader.cs +++ b/Wabbajack.Networking.Http/ResumableDownloader.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Downloader; using Microsoft.Extensions.Logging; +using Wabbajack.Configuration; using Wabbajack.Hashing.xxHash64; using Wabbajack.Paths; using Wabbajack.Paths.IO; @@ -20,17 +21,19 @@ internal class ResumableDownloader private readonly HttpRequestMessage _msg; private readonly AbsolutePath _outputPath; private readonly AbsolutePath _packagePath; + private readonly PerformanceSettings _performanceSettings; private readonly ILogger _logger; private CancellationToken _token; private Exception? _error; - public ResumableDownloader(HttpRequestMessage msg, AbsolutePath outputPath, IJob job, ILogger logger) + public ResumableDownloader(HttpRequestMessage msg, AbsolutePath outputPath, IJob job, PerformanceSettings performanceSettings, ILogger logger) { _job = job; _msg = msg; _outputPath = outputPath; _packagePath = outputPath.WithExtension(Extension.FromPath(".download_package")); + _performanceSettings = performanceSettings; _logger = logger; } @@ -99,8 +102,10 @@ internal class ResumableDownloader private DownloadConfiguration CreateConfiguration(HttpRequestMessage message) { + var maximumMemoryPerDownloadThreadMb = Math.Max(0, _performanceSettings.MaximumMemoryPerDownloadThreadMb); var configuration = new DownloadConfiguration { + MaximumMemoryBufferBytes = maximumMemoryPerDownloadThreadMb * 1024 * 1024, Timeout = (int)TimeSpan.FromSeconds(120).TotalMilliseconds, ReserveStorageSpaceBeforeStartingDownload = true, RequestConfiguration = new RequestConfiguration diff --git a/Wabbajack.Networking.Http/SingleThreadedDownloader.cs b/Wabbajack.Networking.Http/SingleThreadedDownloader.cs index 4790d4ac..ed88e3bb 100644 --- a/Wabbajack.Networking.Http/SingleThreadedDownloader.cs +++ b/Wabbajack.Networking.Http/SingleThreadedDownloader.cs @@ -7,6 +7,7 @@ using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Wabbajack.Configuration; using Wabbajack.Hashing.xxHash64; using Wabbajack.Networking.Http.Interfaces; using Wabbajack.Paths; @@ -19,18 +20,20 @@ public class SingleThreadedDownloader : IHttpDownloader { private readonly HttpClient _client; private readonly ILogger _logger; + private readonly PerformanceSettings _settings; - public SingleThreadedDownloader(ILogger logger, HttpClient client) + public SingleThreadedDownloader(ILogger logger, HttpClient client, MainSettings settings) { _logger = logger; _client = client; + _settings = settings.PerformanceSettings; } public async Task Download(HttpRequestMessage message, AbsolutePath outputPath, IJob job, CancellationToken token) { Exception downloadError = null!; - var downloader = new ResumableDownloader(message, outputPath, job, _logger); + var downloader = new ResumableDownloader(message, outputPath, job, _settings, _logger); for (var i = 0; i < 3; i++) { try diff --git a/Wabbajack.Networking.Http/Wabbajack.Networking.Http.csproj b/Wabbajack.Networking.Http/Wabbajack.Networking.Http.csproj index d285e4f4..2cf94a56 100644 --- a/Wabbajack.Networking.Http/Wabbajack.Networking.Http.csproj +++ b/Wabbajack.Networking.Http/Wabbajack.Networking.Http.csproj @@ -1,18 +1,19 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) - + + diff --git a/Wabbajack.Networking.NexusApi.Test/Wabbajack.Networking.NexusApi.Test.csproj b/Wabbajack.Networking.NexusApi.Test/Wabbajack.Networking.NexusApi.Test.csproj index 552f015c..fac1ed50 100644 --- a/Wabbajack.Networking.NexusApi.Test/Wabbajack.Networking.NexusApi.Test.csproj +++ b/Wabbajack.Networking.NexusApi.Test/Wabbajack.Networking.NexusApi.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Networking.NexusApi/ProxiedNexusApi.cs b/Wabbajack.Networking.NexusApi/ProxiedNexusApi.cs index 21397c0d..703dc241 100644 --- a/Wabbajack.Networking.NexusApi/ProxiedNexusApi.cs +++ b/Wabbajack.Networking.NexusApi/ProxiedNexusApi.cs @@ -8,15 +8,15 @@ using Wabbajack.DTOs; using Wabbajack.DTOs.Logins; using Wabbajack.Networking.Http.Interfaces; using Wabbajack.Networking.NexusApi.DTOs; -using Wabbajack.Networking.WabbajackClientApi; using Wabbajack.RateLimiter; +using ClientConfiguration = Wabbajack.Networking.WabbajackClientApi.Configuration; namespace Wabbajack.Networking.NexusApi; public class ProxiedNexusApi : NexusApi { private readonly ITokenProvider _apiState; - private readonly Configuration _wabbajackClientConfiguration; + private readonly ClientConfiguration _wabbajackClientConfiguration; public HashSet ProxiedEndpoints = new() { @@ -28,7 +28,7 @@ public class ProxiedNexusApi : NexusApi public ProxiedNexusApi(ITokenProvider apiKey, ILogger logger, HttpClient client, IResource limiter, ApplicationInfo appInfo, JsonSerializerOptions jsonOptions, ITokenProvider apiState, - Configuration wabbajackClientConfiguration) + ClientConfiguration wabbajackClientConfiguration) : base(apiKey, logger, client, limiter, appInfo, jsonOptions) { _apiState = apiState; diff --git a/Wabbajack.Networking.NexusApi/Wabbajack.Networking.NexusApi.csproj b/Wabbajack.Networking.NexusApi/Wabbajack.Networking.NexusApi.csproj index 05977cf3..500ad9fa 100644 --- a/Wabbajack.Networking.NexusApi/Wabbajack.Networking.NexusApi.csproj +++ b/Wabbajack.Networking.NexusApi/Wabbajack.Networking.NexusApi.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) @@ -12,7 +12,7 @@ - + diff --git a/Wabbajack.Networking.Steam.Test/Wabbajack.Networking.Steam.Test.csproj b/Wabbajack.Networking.Steam.Test/Wabbajack.Networking.Steam.Test.csproj index b8f20c0b..c7e6d73b 100644 --- a/Wabbajack.Networking.Steam.Test/Wabbajack.Networking.Steam.Test.csproj +++ b/Wabbajack.Networking.Steam.Test/Wabbajack.Networking.Steam.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable false @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/Wabbajack.Networking.Steam/Wabbajack.Networking.Steam.csproj b/Wabbajack.Networking.Steam/Wabbajack.Networking.Steam.csproj index d9364b70..ee840362 100644 --- a/Wabbajack.Networking.Steam/Wabbajack.Networking.Steam.csproj +++ b/Wabbajack.Networking.Steam/Wabbajack.Networking.Steam.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.Networking.WabbajackClientApi/Wabbajack.Networking.WabbajackClientApi.csproj b/Wabbajack.Networking.WabbajackClientApi/Wabbajack.Networking.WabbajackClientApi.csproj index 7aeb859b..55712888 100644 --- a/Wabbajack.Networking.WabbajackClientApi/Wabbajack.Networking.WabbajackClientApi.csproj +++ b/Wabbajack.Networking.WabbajackClientApi/Wabbajack.Networking.WabbajackClientApi.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.Paths.IO.Test/Wabbajack.Paths.IO.Test.csproj b/Wabbajack.Paths.IO.Test/Wabbajack.Paths.IO.Test.csproj index bbd2b0ea..3948bc11 100644 --- a/Wabbajack.Paths.IO.Test/Wabbajack.Paths.IO.Test.csproj +++ b/Wabbajack.Paths.IO.Test/Wabbajack.Paths.IO.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Paths.IO/Wabbajack.Paths.IO.csproj b/Wabbajack.Paths.IO/Wabbajack.Paths.IO.csproj index 2494c58e..0cd88c4d 100644 --- a/Wabbajack.Paths.IO/Wabbajack.Paths.IO.csproj +++ b/Wabbajack.Paths.IO/Wabbajack.Paths.IO.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) diff --git a/Wabbajack.Paths.Test/Wabbajack.Paths.Test.csproj b/Wabbajack.Paths.Test/Wabbajack.Paths.Test.csproj index 1415da3d..a5d4fe49 100644 --- a/Wabbajack.Paths.Test/Wabbajack.Paths.Test.csproj +++ b/Wabbajack.Paths.Test/Wabbajack.Paths.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false diff --git a/Wabbajack.Paths/Wabbajack.Paths.csproj b/Wabbajack.Paths/Wabbajack.Paths.csproj index 2502d56d..1ffbca14 100644 --- a/Wabbajack.Paths/Wabbajack.Paths.csproj +++ b/Wabbajack.Paths/Wabbajack.Paths.csproj @@ -1,6 +1,6 @@ - net6.0 + net7.0 enable GPL-3.0-or-later $(VERSION) diff --git a/Wabbajack.RateLimiter.Test/Wabbajack.RateLimiter.Test.csproj b/Wabbajack.RateLimiter.Test/Wabbajack.RateLimiter.Test.csproj index 8b16f12f..3db11fcf 100644 --- a/Wabbajack.RateLimiter.Test/Wabbajack.RateLimiter.Test.csproj +++ b/Wabbajack.RateLimiter.Test/Wabbajack.RateLimiter.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable false diff --git a/Wabbajack.RateLimiter/Wabbajack.RateLimiter.csproj b/Wabbajack.RateLimiter/Wabbajack.RateLimiter.csproj index 72d6b4a4..444af79a 100644 --- a/Wabbajack.RateLimiter/Wabbajack.RateLimiter.csproj +++ b/Wabbajack.RateLimiter/Wabbajack.RateLimiter.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable diff --git a/Wabbajack.Server.Lib/Wabbajack.Server.Lib.csproj b/Wabbajack.Server.Lib/Wabbajack.Server.Lib.csproj index d69e3e3c..03942d81 100644 --- a/Wabbajack.Server.Lib/Wabbajack.Server.Lib.csproj +++ b/Wabbajack.Server.Lib/Wabbajack.Server.Lib.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable diff --git a/Wabbajack.Server/Wabbajack.Server.csproj b/Wabbajack.Server/Wabbajack.Server.csproj index 9abb308e..c31158e1 100644 --- a/Wabbajack.Server/Wabbajack.Server.csproj +++ b/Wabbajack.Server/Wabbajack.Server.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable Exe diff --git a/Wabbajack.Services.OSIntegrated/ServiceExtensions.cs b/Wabbajack.Services.OSIntegrated/ServiceExtensions.cs index 3a2b41e7..d89cf4e2 100644 --- a/Wabbajack.Services.OSIntegrated/ServiceExtensions.cs +++ b/Wabbajack.Services.OSIntegrated/ServiceExtensions.cs @@ -8,7 +8,9 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Wabbajack.Common; using Wabbajack.Compiler; +using Wabbajack.Configuration; using Wabbajack.Downloaders; using Wabbajack.Downloaders.GameFile; using Wabbajack.Downloaders.VerificationCache; @@ -79,24 +81,36 @@ public static class ServiceExtensions ? new BinaryPatchCache(s.GetRequiredService>(), s.GetService()!.CreateFolder().Path) : new BinaryPatchCache(s.GetRequiredService>(),KnownFolders.WabbajackAppLocal.Combine("PatchCache"))); - + service.AddSingleton(s => { var dtos = s.GetRequiredService(); return options.UseLocalCache ? new VerificationCache(s.GetRequiredService>(), - s.GetService()!.CreateFile().Path, + s.GetService()!.CreateFile().Path, TimeSpan.FromDays(1), dtos) : new VerificationCache(s.GetRequiredService>(), - KnownFolders.WabbajackAppLocal.Combine("VerificationCacheV2.sqlite"), + KnownFolders.WabbajackAppLocal.Combine("VerificationCacheV2.sqlite"), TimeSpan.FromDays(1), dtos); }); service.AddSingleton(new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount}); - Func> GetSettings(IServiceProvider provider, string name) + MainSettings GetAppSettings(IServiceProvider provider, string name) + { + var settingsManager = provider.GetRequiredService(); + var settings = Task.Run(() => settingsManager.Load(name)).Result; + if (settings.Upgrade()) + { + settingsManager.Save(MainSettings.SettingsFileName, settings).FireAndForget(); + } + + return settings; + } + + Func> GetResourceSettings(IServiceProvider provider, string name) { return async () => { @@ -104,9 +118,9 @@ public static class ServiceExtensions return ((int) s.MaxTasks, s.MaxThroughput); }; } - + // Settings - + service.AddSingleton(s => new Configuration { EncryptedDataLocation = KnownFolders.WabbajackAppLocal.Combine("encrypted"), @@ -118,26 +132,27 @@ public static class ServiceExtensions service.AddSingleton(); service.AddSingleton(); - + service.AddSingleton(s => GetAppSettings(s, MainSettings.SettingsFileName)); + // Resources service.AddAllSingleton>(s => - new Resource("Downloads", GetSettings(s, "Downloads"), s.GetRequiredService())); + new Resource("Downloads", GetResourceSettings(s, "Downloads"), s.GetRequiredService())); - service.AddAllSingleton>(s => new Resource("Web Requests", GetSettings(s, "Web Requests"), s.GetRequiredService())); - service.AddAllSingleton>(s => new Resource("VFS", GetSettings(s, "VFS"), s.GetRequiredService())); + service.AddAllSingleton>(s => new Resource("Web Requests", GetResourceSettings(s, "Web Requests"), s.GetRequiredService())); + service.AddAllSingleton>(s => new Resource("VFS", GetResourceSettings(s, "VFS"), s.GetRequiredService())); service.AddAllSingleton>(s => - new Resource("File Hashing", GetSettings(s, "File Hashing"), s.GetRequiredService())); + new Resource("File Hashing", GetResourceSettings(s, "File Hashing"), s.GetRequiredService())); service.AddAllSingleton>(s => - new Resource("Wabbajack Client", GetSettings(s, "Wabbajack Client"), s.GetRequiredService())); + new Resource("Wabbajack Client", GetResourceSettings(s, "Wabbajack Client"), s.GetRequiredService())); service.AddAllSingleton>(s => - new Resource("File Extractor", GetSettings(s, "File Extractor"), s.GetRequiredService())); + new Resource("File Extractor", GetResourceSettings(s, "File Extractor"), s.GetRequiredService())); service.AddAllSingleton>(s => - new Resource("Compiler", GetSettings(s, "Compiler"), s.GetRequiredService())); + new Resource("Compiler", GetResourceSettings(s, "Compiler"), s.GetRequiredService())); service.AddAllSingleton>(s => - new Resource("Installer", GetSettings(s, "Installer"), s.GetRequiredService())); + new Resource("Installer", GetResourceSettings(s, "Installer"), s.GetRequiredService())); service.AddAllSingleton>(s => new Resource("User Intervention", 1, token: s.GetRequiredService())); @@ -154,7 +169,7 @@ public static class ServiceExtensions service.AddAllSingleton(); service.AddSteam(); - + service.AddSingleton(); service.AddSingleton(); service.AddBethesdaNet(); @@ -186,11 +201,11 @@ public static class ServiceExtensions service.AddAllSingleton(); else service.AddAllSingleton(); - + // ImageLoader if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) service.AddSingleton(); - else + else service.AddSingleton(); // Installer/Compiler Configuration @@ -214,9 +229,9 @@ public static class ServiceExtensions OSVersion = Environment.OSVersion.VersionString, Version = version }); - - + + return service; } @@ -224,7 +239,7 @@ public static class ServiceExtensions { // Get directories first and cache them, this freezes the directories were looking at // so any new ones don't show up in the middle of our deletes. - + var dirs = path.EnumerateDirectories().ToList(); var processIds = Process.GetProcesses().Select(p => p.Id).ToHashSet(); foreach (var dir in dirs) @@ -232,7 +247,7 @@ public static class ServiceExtensions var name = dir.FileName.ToString().Split("_"); if (!int.TryParse(name[0], out var processId)) continue; if (processIds.Contains(processId)) continue; - + try { dir.DeleteDirectory(); @@ -242,7 +257,7 @@ public static class ServiceExtensions // ignored } } - + } public class OSIntegratedOptions diff --git a/Wabbajack.Services.OSIntegrated/Wabbajack.Services.OSIntegrated.csproj b/Wabbajack.Services.OSIntegrated/Wabbajack.Services.OSIntegrated.csproj index b2cfce82..2223ea6d 100644 --- a/Wabbajack.Services.OSIntegrated/Wabbajack.Services.OSIntegrated.csproj +++ b/Wabbajack.Services.OSIntegrated/Wabbajack.Services.OSIntegrated.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Wabbajack.VFS.Interfaces/Wabbajack.VFS.Interfaces.csproj b/Wabbajack.VFS.Interfaces/Wabbajack.VFS.Interfaces.csproj index bf68d60e..5b854cb5 100644 --- a/Wabbajack.VFS.Interfaces/Wabbajack.VFS.Interfaces.csproj +++ b/Wabbajack.VFS.Interfaces/Wabbajack.VFS.Interfaces.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/Wabbajack.VFS.Test/Wabbajack.VFS.Test.csproj b/Wabbajack.VFS.Test/Wabbajack.VFS.Test.csproj index ebcd2790..29e3421c 100644 --- a/Wabbajack.VFS.Test/Wabbajack.VFS.Test.csproj +++ b/Wabbajack.VFS.Test/Wabbajack.VFS.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/Wabbajack.VFS/Wabbajack.VFS.csproj b/Wabbajack.VFS/Wabbajack.VFS.csproj index 07ec317f..a4501f7c 100644 --- a/Wabbajack.VFS/Wabbajack.VFS.csproj +++ b/Wabbajack.VFS/Wabbajack.VFS.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable $(VERSION) GPL-3.0-or-later diff --git a/Wabbajack.sln b/Wabbajack.sln index 33a2724b..1800043e 100644 --- a/Wabbajack.sln +++ b/Wabbajack.sln @@ -147,6 +147,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.CLI.Builder", "Wa EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.Downloaders.VerificationCache", "Wabbajack.Downloaders.VerificationCache\Wabbajack.Downloaders.VerificationCache.csproj", "{D9560C73-4E58-4463-9DB9-D06491E0E1C8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.Configuration", "Wabbajack.Configuration\Wabbajack.Configuration.csproj", "{E7CDACA6-D3FF-4CF6-8EF8-05FCD27F6FBE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -401,6 +403,10 @@ Global {D9560C73-4E58-4463-9DB9-D06491E0E1C8}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9560C73-4E58-4463-9DB9-D06491E0E1C8}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9560C73-4E58-4463-9DB9-D06491E0E1C8}.Release|Any CPU.Build.0 = Release|Any CPU + {E7CDACA6-D3FF-4CF6-8EF8-05FCD27F6FBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7CDACA6-D3FF-4CF6-8EF8-05FCD27F6FBE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7CDACA6-D3FF-4CF6-8EF8-05FCD27F6FBE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7CDACA6-D3FF-4CF6-8EF8-05FCD27F6FBE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE