mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
7a706fdd64
35
CHANGELOG.md
35
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
|
||||
|
@ -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<LauncherUpdater>();
|
||||
services.AddSingleton<ResourceMonitor>();
|
||||
|
||||
services.AddSingleton<MainSettings>();
|
||||
services.AddTransient<CompilerVM>();
|
||||
services.AddTransient<InstallerVM>();
|
||||
services.AddTransient<ModeSelectionVM>();
|
||||
@ -182,7 +180,7 @@ namespace Wabbajack
|
||||
services.AddTransient<LoversLabLoginHandler>();
|
||||
|
||||
// Login Managers
|
||||
|
||||
|
||||
//Disabled LL because it is currently not used and broken due to the way LL butchers their API
|
||||
//services.AddAllSingleton<INeedsLogin, LoversLabLoginManager>();
|
||||
services.AddAllSingleton<INeedsLogin, NexusLoginManager>();
|
||||
|
@ -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<LauncherUpdater> logger, HttpClient client, Client wjclient, DTOSerializer dtos,
|
||||
@ -41,8 +42,8 @@ namespace Wabbajack
|
||||
_dtos = dtos;
|
||||
_downloader = downloader;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static Lazy<AbsolutePath> 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<Release[]> 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;
|
||||
}
|
||||
|
||||
|
@ -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<Unit> _saveSignal = new();
|
||||
[JsonIgnore]
|
||||
public IObservable<Unit> 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<MainSettings>();
|
||||
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<AbsolutePath, Mo2ModlistInstallationSettings> Mo2ModlistSettings { get; } = new Dictionary<AbsolutePath, Mo2ModlistInstallationSettings>();
|
||||
}
|
||||
|
||||
[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<DownloadDispatcher> 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<AbsolutePath, CompilationModlistSettings> ModlistSettings { get; } = new Dictionary<AbsolutePath, CompilationModlistSettings>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<TLoginType> : BrowserWindowViewModel
|
||||
|
||||
var tcs = new TaskCompletionSource<Uri>();
|
||||
await NavigateTo(tlogin.AuthorizationEndpoint);
|
||||
|
||||
|
||||
Browser!.Browser.CoreWebView2.Settings.UserAgent = "Wabbajack";
|
||||
Browser!.Browser.NavigationStarting += (sender, args) =>
|
||||
{
|
||||
@ -50,7 +51,7 @@ public abstract class OAuth2LoginHandler<TLoginType> : 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<TLoginType> : 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<TLoginType> : BrowserWindowViewModel
|
||||
Cookies = cookies,
|
||||
ResultState = data!
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -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<Cookie[]> 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<Uri>();
|
||||
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<Hash> WaitForDownload(AbsolutePath path, CancellationToken token)
|
||||
{
|
||||
var source = new TaskCompletionSource();
|
||||
|
@ -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> _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<bool> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<ModListGalleryVM> logger, Client wjClient, GameLocator locator,
|
||||
|
@ -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}")));
|
||||
|
@ -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<Unit, Unit> ShowManifestCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenReadmeCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenWikiCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenDiscordButton { get; }
|
||||
public ReactiveCommand<Unit, Unit> 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<LoadModlistForInstalling>()
|
||||
.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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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<IStatusMessage>())
|
||||
.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)
|
||||
|
@ -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<MainWindowVM> logger, MainSettings settings, Client wjClient,
|
||||
public MainWindowVM(ILogger<MainWindowVM> 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;
|
||||
|
@ -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<SettingsVM> logger, IServiceProvider provider)
|
||||
: base(logger)
|
||||
{
|
||||
Login = new LoginManagerVM(provider.GetRequiredService<ILogger<LoginManagerVM>>(), this,
|
||||
_settings = provider.GetRequiredService<Configuration.MainSettings>();
|
||||
_settingsManager = provider.GetRequiredService<SettingsManager>();
|
||||
|
||||
Login = new LoginManagerVM(provider.GetRequiredService<ILogger<LoginManagerVM>>(), this,
|
||||
provider.GetRequiredService<IEnumerable<INeedsLogin>>());
|
||||
AuthorFile = new AuthorFilesVM(provider.GetRequiredService<ILogger<AuthorFilesVM>>()!,
|
||||
AuthorFile = new AuthorFilesVM(provider.GetRequiredService<ILogger<AuthorFilesVM>>()!,
|
||||
provider.GetRequiredService<WabbajackApiTokenProvider>()!, provider.GetRequiredService<Client>()!, this);
|
||||
OpenTerminalCommand = ReactiveCommand.CreateFromTask(OpenTerminal);
|
||||
BackCommand = ReactiveCommand.Create(NavigateBack.Send);
|
||||
Performance = new PerformanceSettings(
|
||||
_settings,
|
||||
provider.GetRequiredService<IResource<DownloadDispatcher>>(),
|
||||
provider.GetRequiredService<SystemParametersConstructor>());
|
||||
BackCommand = ReactiveCommand.Create(() =>
|
||||
{
|
||||
NavigateBack.Send();
|
||||
Unload();
|
||||
});
|
||||
}
|
||||
|
||||
public override void Unload()
|
||||
{
|
||||
_settingsManager.Save(Configuration.MainSettings.SettingsFileName, _settings).FireAndForget();
|
||||
|
||||
base.Unload();
|
||||
}
|
||||
|
||||
private async Task OpenTerminal()
|
||||
|
@ -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);
|
||||
|
@ -12,7 +12,7 @@
|
||||
x:TypeArguments="local:InstallerVM"
|
||||
mc:Ignorable="d">
|
||||
<local:AttentionBorder x:Name="AttentionBorder" ClipToBounds="True">
|
||||
<Grid Margin="5">
|
||||
<Grid Margin="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="3*" />
|
||||
@ -23,6 +23,7 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="5"
|
||||
x:Name="TitleText"
|
||||
@ -124,11 +125,34 @@
|
||||
<TextBlock Grid.Row="1"
|
||||
Margin="0,10,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Text="Readme" />
|
||||
Text="Modlist Readme" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Grid.Column="4"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Button
|
||||
x:Name="OpenWikiButton"
|
||||
Width="50"
|
||||
Height="50"
|
||||
Style="{StaticResource CircleButtonStyle}">
|
||||
<icon:PackIconFontAwesome
|
||||
Width="25"
|
||||
Height="25"
|
||||
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
|
||||
Kind="QuestionSolid" />
|
||||
</Button>
|
||||
<TextBlock Grid.Row="1"
|
||||
Margin="0,10,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Text="Help and Wiki" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Grid.Column="5"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent">
|
||||
Background="Transparent" Grid.ColumnSpan="2" Margin="0,0,10,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
|
@ -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);
|
||||
|
@ -39,6 +39,13 @@
|
||||
FontSize="14"
|
||||
Text="Target Modlist"
|
||||
TextAlignment="Center" />
|
||||
<TextBlock x:Name="errorTextBox"
|
||||
Grid.Row="3"
|
||||
FontFamily="Verdana" FontSize="10" FontWeight="ExtraBold"
|
||||
Background="{StaticResource WindowBackgroundBrush}"
|
||||
Foreground="Red"
|
||||
Text=""
|
||||
TextAlignment="Left" Margin="0,79,0,-45" Grid.ColumnSpan="3" />
|
||||
<local:FilePicker Grid.Row="1" Grid.Column="2"
|
||||
x:Name="ModListLocationPicker"
|
||||
Height="30"
|
||||
@ -74,10 +81,11 @@
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<local:BeginButton Grid.Row="1"
|
||||
x:Name="BeginButton"
|
||||
HorizontalAlignment="Right"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
<icon:PackIconFontAwesome Grid.Row="2"
|
||||
x:Name="ErrorSummaryIconGlow"
|
||||
@ -92,8 +100,27 @@
|
||||
<icon:PackIconFontAwesome Grid.Row="2"
|
||||
x:Name="ErrorSummaryIcon"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Foreground="{StaticResource WarningBrush}"
|
||||
Kind="ExclamationTriangleSolid" />
|
||||
<CheckBox Grid.Row="2" Grid.Column="2"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
x:Name="OverwriteCheckBox"
|
||||
Content="Overwrite Installation"
|
||||
IsChecked="False"
|
||||
ToolTip="Confirm to overwrite files in install folder.">
|
||||
<CheckBox.Style>
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Opacity" Value="0.6" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</CheckBox.Style>
|
||||
</CheckBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</rxui:ReactiveUserControl>
|
||||
|
@ -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)
|
||||
|
@ -324,20 +324,6 @@
|
||||
<local:CpuView Grid.Column="2"
|
||||
x:Name="CpuView"
|
||||
ViewModel="{Binding}" />
|
||||
<!--
|
||||
<local:AttentionBorder Grid.Column="2"
|
||||
x:Name="UserInterventionsControl"
|
||||
Content="{Binding ActiveGlobalUserIntervention}">
|
||||
<local:AttentionBorder.Resources>
|
||||
<DataTemplate DataType="{x:Type lib1:ConfirmationIntervention}">
|
||||
<local:ConfirmationInterventionView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:ConfirmUpdateOfExistingInstallVM}">
|
||||
<local:ConfirmUpdateOfExistingInstallView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
</local:AttentionBorder.Resources>
|
||||
</local:AttentionBorder>
|
||||
-->
|
||||
<local:InstallationCompleteView Grid.Column="2"
|
||||
x:Name="InstallComplete"
|
||||
ViewModel="{Binding}" />
|
||||
|
@ -46,21 +46,5 @@
|
||||
FontSize="14"
|
||||
PickerVM="{Binding DownloadLocation}"
|
||||
ToolTip="The directory where modlist archives will be downloaded to" />
|
||||
<CheckBox Grid.Row="2" Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
Content="Overwrite Installation"
|
||||
IsChecked="{Binding AutomaticallyOverwrite}"
|
||||
ToolTip="If installing over an existing installation, automatically replace it without asking permission.">
|
||||
<CheckBox.Style>
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Opacity" Value="0.6" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</CheckBox.Style>
|
||||
</CheckBox>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
@ -1,50 +0,0 @@
|
||||
<rxui:ReactiveUserControl
|
||||
x:Class="Wabbajack.ConfirmUpdateOfExistingInstallView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:lib="clr-namespace:Wabbajack;assembly=Wabbajack"
|
||||
xmlns:local="clr-namespace:Wabbajack"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:rxui="http://reactiveui.net"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:TypeArguments="local:ConfirmUpdateOfExistingInstallVM"
|
||||
mc:Ignorable="d">
|
||||
<Grid Margin="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="5*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="2*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
|
||||
x:Name="ShortDescription"
|
||||
Margin="0,0,0,5"
|
||||
FontFamily="Lucida Sans"
|
||||
FontSize="14"
|
||||
FontWeight="Bold"
|
||||
TextWrapping="WrapWithOverflow" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
|
||||
x:Name="ExtendedDescription"
|
||||
TextWrapping="WrapWithOverflow" />
|
||||
<CheckBox Grid.Row="2" Grid.Column="2"
|
||||
x:Name="AutoOverwriteCheckbox"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Right"
|
||||
Content="Remember"
|
||||
IsChecked="{Binding Installer.AutomaticallyOverwrite}"
|
||||
ToolTip="If installing over an existing installation next time, automatically replace it without asking permission." />
|
||||
<Button Grid.Row="3" Grid.Column="0"
|
||||
x:Name="CancelButton"
|
||||
Content="Cancel" />
|
||||
<Button Grid.Row="3" Grid.Column="2"
|
||||
x:Name="ConfirmButton"
|
||||
Content="Confirm" />
|
||||
</Grid>
|
||||
</rxui:ReactiveUserControl>
|
@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
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 Wabbajack;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ConfirmUpdateOfExistingInstallView.xaml
|
||||
/// </summary>
|
||||
public partial class ConfirmUpdateOfExistingInstallView : ReactiveUserControl<ConfirmUpdateOfExistingInstallVM>
|
||||
{
|
||||
public ConfirmUpdateOfExistingInstallView()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.WhenActivated(dispose =>
|
||||
{
|
||||
this.WhenAny(x => x.ViewModel.ShortDescription)
|
||||
.BindToStrict(this, x => x.ShortDescription.Text)
|
||||
.DisposeWith(dispose);
|
||||
this.WhenAny(x => x.ViewModel.ExtendedDescription)
|
||||
.BindToStrict(this, x => x.ExtendedDescription.Text)
|
||||
.DisposeWith(dispose);
|
||||
this.WhenAny(x => x.ViewModel.Source.ConfirmCommand)
|
||||
.BindToStrict(this, x => x.ConfirmButton.Command)
|
||||
.DisposeWith(dispose);
|
||||
this.WhenAny(x => x.ViewModel.Source.CancelCommand)
|
||||
.BindToStrict(this, x => x.CancelButton.Command)
|
||||
.DisposeWith(dispose);
|
||||
|
||||
this.BindStrict(this.ViewModel, x => x.Installer.AutomaticallyOverwrite, x => x.AutoOverwriteCheckbox.IsChecked,
|
||||
vmToViewConverter: x => x,
|
||||
viewToVmConverter: x => x ?? false)
|
||||
.DisposeWith(dispose);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using MahApps.Metro.Controls;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.DTOs;
|
||||
using Wabbajack.DTOs.DownloadStates;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.Messages;
|
||||
using Wabbajack.Paths.IO;
|
||||
using Wabbajack.UserIntervention;
|
||||
using Wabbajack.Util;
|
||||
using Wabbajack.Views;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
@ -30,7 +21,6 @@ namespace Wabbajack
|
||||
public partial class MainWindow : MetroWindow
|
||||
{
|
||||
private MainWindowVM _mwvm;
|
||||
private MainSettings _settings;
|
||||
private readonly ILogger<MainWindow> _logger;
|
||||
private readonly SystemParametersConstructor _systemParams;
|
||||
|
||||
@ -75,7 +65,7 @@ namespace Wabbajack
|
||||
var p = _systemParams.Create();
|
||||
|
||||
_logger.LogInformation("Detected Windows Version: {Version}", Environment.OSVersion.VersionString);
|
||||
|
||||
|
||||
_logger.LogInformation(
|
||||
"System settings - ({MemorySize} RAM) ({PageSize} Page), Display: {ScreenWidth} x {ScreenHeight} ({Vram} VRAM - VideoMemorySizeMb={ENBVRam})",
|
||||
p.SystemMemorySize.ToFileSizeString(), p.SystemPageSize.ToFileSizeString(), p.ScreenWidth, p.ScreenHeight, p.VideoMemorySize.ToFileSizeString(), p.EnbLEVRAMSize);
|
||||
@ -85,25 +75,8 @@ namespace Wabbajack
|
||||
else if (p.SystemPageSize < 2e+10)
|
||||
_logger.LogInformation("Pagefile below recommended! Consider increasing to 20000MB. A suboptimal pagefile can cause crashes and poor in-game performance");
|
||||
|
||||
//Warmup();
|
||||
|
||||
var _ = updater.Run();
|
||||
|
||||
var (settings, loadedSettings) = MainSettings.TryLoadTypicalSettings().AsTask().Result;
|
||||
// Load settings
|
||||
/*
|
||||
if (CLIArguments.NoSettings || !loadedSettings)
|
||||
{
|
||||
_settings = new MainSettings {Version = Consts.SettingsVersion};
|
||||
RunWhenLoaded(DefaultSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
_settings = settings;
|
||||
RunWhenLoaded(LoadSettings);
|
||||
}*/
|
||||
|
||||
|
||||
// Bring window to the front if it isn't already
|
||||
this.Initialized += (s, e) =>
|
||||
{
|
||||
@ -135,45 +108,7 @@ namespace Wabbajack
|
||||
.BindToStrict(this, view => view.ResourceUsage.Text);
|
||||
vm.WhenAnyValue(vm => vm.AppName)
|
||||
.BindToStrict(this, view => view.AppName.Text);
|
||||
|
||||
}
|
||||
|
||||
public void Init(MainWindowVM vm, MainSettings settings)
|
||||
{
|
||||
DataContext = vm;
|
||||
_mwvm = vm;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
private void RunWhenLoaded(Action a)
|
||||
{
|
||||
if (IsLoaded)
|
||||
{
|
||||
a();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Loaded += (sender, e) =>
|
||||
{
|
||||
a();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
Width = _settings.Width;
|
||||
Height = _settings.Height;
|
||||
Left = _settings.PosX;
|
||||
Top = _settings.PosY;
|
||||
}
|
||||
|
||||
private void DefaultSettings()
|
||||
{
|
||||
Width = 1300;
|
||||
Height = 960;
|
||||
Left = 15;
|
||||
Top = 15;
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, CancelEventArgs e)
|
||||
|
@ -6,7 +6,6 @@
|
||||
xmlns:local="clr-namespace:Wabbajack"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:rxui="http://reactiveui.net"
|
||||
xmlns:xwpf="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:TypeArguments="local:SettingsVM"
|
||||
@ -32,17 +31,19 @@
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2"
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
FontFamily="Lucida Sans"
|
||||
FontSize="20"
|
||||
FontWeight="Bold"
|
||||
Text="Misc Settings" />
|
||||
<Grid Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3">
|
||||
<Grid
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.Resources>
|
||||
<Style BasedOn="{StaticResource MainButtonStyle}" TargetType="Button">
|
||||
@ -55,32 +56,9 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<CheckBox Grid.Row="0"
|
||||
Name="FilterPersistCheckBox"
|
||||
Margin="0,5,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Gallery filters are saved on exit">
|
||||
<CheckBox.LayoutTransform>
|
||||
<ScaleTransform ScaleX="1.2" ScaleY="1.2" />
|
||||
</CheckBox.LayoutTransform>
|
||||
</CheckBox>
|
||||
<CheckBox Grid.Row="1"
|
||||
Name="UseCompressionCheckBox"
|
||||
Margin="0,5,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Use NTFS LZS compression during install">
|
||||
<CheckBox.LayoutTransform>
|
||||
<ScaleTransform ScaleX="1.2" ScaleY="1.2" />
|
||||
</CheckBox.LayoutTransform>
|
||||
</CheckBox>
|
||||
<Button Grid.Row="2"
|
||||
Name="ClearCefCache"
|
||||
Margin="0,5,0,0"
|
||||
Content="Clear In-App Browser Cache" />
|
||||
<Button Grid.Row="3"
|
||||
<Button
|
||||
Name="OpenTerminal"
|
||||
Grid.Row="0"
|
||||
Margin="0,5,0,0"
|
||||
Content="Launch Wabbajack CLI" />
|
||||
</Grid>
|
||||
|
@ -15,10 +15,6 @@ namespace Wabbajack
|
||||
this.WhenActivated(disposable =>
|
||||
{
|
||||
// Bind Values
|
||||
this.BindStrict(this.ViewModel, x => x.Filters.IsPersistent, x => x.FilterPersistCheckBox.IsChecked)
|
||||
.DisposeWith(disposable);
|
||||
this.BindStrict(this.ViewModel, x => x.Filters.UseCompression, x => x.UseCompressionCheckBox.IsChecked)
|
||||
.DisposeWith(disposable);
|
||||
this.WhenAnyValue(x => x.ViewModel.OpenTerminalCommand)
|
||||
.BindToStrict(this, x => x.OpenTerminal.Command)
|
||||
.DisposeWith(disposable);
|
||||
|
@ -24,7 +24,7 @@
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="25" />
|
||||
<RowDefinition Height="25" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="25" />
|
||||
<RowDefinition Height="25" />
|
||||
<RowDefinition Height="25" />
|
||||
@ -34,16 +34,43 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2"
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
FontFamily="Lucida Sans"
|
||||
FontSize="20"
|
||||
FontWeight="Bold"
|
||||
Text="Performance" />
|
||||
<Button Grid.Row="2" x:Name="EditResourceSettings">
|
||||
<Button x:Name="EditResourceSettings" Grid.Row="2">
|
||||
<TextBlock FontSize="14" FontWeight="Bold">Edit Resource Usage Settings and Close Wabbajack</TextBlock>
|
||||
</Button>
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
FontSize="14"
|
||||
Foreground="{StaticResource ForegroundBrush}"
|
||||
Text="Maximum RAM per download thread (MB)"
|
||||
ToolTip="Defines the maximum amount of RAM each download thread can use for buffering. Set to 0 to disable this limit completely." />
|
||||
<xwpf:IntegerUpDown
|
||||
x:Name="MaximumMemoryPerDownloadThreadIntegerUpDown"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Width="80"
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="{StaticResource ForegroundBrush}"
|
||||
Maximum="10000"
|
||||
Minimum="0" />
|
||||
<Button
|
||||
x:Name="ResetMaximumMemoryPerDownloadThread"
|
||||
Grid.Row="4"
|
||||
Grid.Column="3"
|
||||
Margin="20,0,0,0"
|
||||
Padding="10,0"
|
||||
HorizontalAlignment="Left">
|
||||
<TextBlock FontSize="14">Reset</TextBlock>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</rxui:ReactiveUserControl>
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
@ -73,12 +73,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DynamicData" Version="7.12.1" />
|
||||
<PackageReference Include="DynamicData" Version="8.0.2" />
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.4.0">
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Fizzler.Systems.HtmlAgilityPack" Version="1.2.1" />
|
||||
<PackageReference Include="Fody" Version="6.6.4">
|
||||
<PackageReference Include="Fody" Version="6.8.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
@ -95,11 +95,11 @@
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.1.0" />
|
||||
<PackageReference Include="Orc.FileAssociation" Version="5.0.0-alpha0061" />
|
||||
<PackageReference Include="PInvoke.User32" Version="0.7.124" />
|
||||
<PackageReference Include="ReactiveUI" Version="18.3.1" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="18.3.1" />
|
||||
<PackageReference Include="ReactiveUI.WPF" Version="18.3.1" />
|
||||
<PackageReference Include="ReactiveUI" Version="19.5.1" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.1" />
|
||||
<PackageReference Include="ReactiveUI.WPF" Version="19.5.1" />
|
||||
<PackageReference Include="Silk.NET.DXGI" Version="2.16.0" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1-preview.1" />
|
||||
<PackageReference Include="WPFThemes.DarkBlend" Version="1.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.3" />
|
||||
|
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
@ -13,11 +13,12 @@
|
||||
<NoWarn>CS8600</NoWarn>
|
||||
<NoWarn>CS8601</NoWarn>
|
||||
<NoWarn>CS8618</NoWarn>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.3" />
|
||||
|
@ -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;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.3" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1-preview.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
27
Wabbajack.Configuration/MainSettings.cs
Normal file
27
Wabbajack.Configuration/MainSettings.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
6
Wabbajack.Configuration/PerformanceSettings.cs
Normal file
6
Wabbajack.Configuration/PerformanceSettings.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace Wabbajack.Configuration;
|
||||
|
||||
public class PerformanceSettings
|
||||
{
|
||||
public int MaximumMemoryPerDownloadThreadMb { get; set; }
|
||||
}
|
9
Wabbajack.Configuration/Wabbajack.Configuration.csproj
Normal file
9
Wabbajack.Configuration/Wabbajack.Configuration.csproj
Normal file
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
<NoWarn>CS8600</NoWarn>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -21,7 +21,7 @@ public class GameMetaData
|
||||
public int[] SteamIDs { get; internal init; } = Array.Empty<int>();
|
||||
|
||||
// to get gog ids: https://www.gogdb.org
|
||||
public int[] GOGIDs { get; internal init; } = Array.Empty<int>();
|
||||
public long[] GOGIDs { get; internal init; } = Array.Empty<long>();
|
||||
|
||||
// to get these ids, split the numbers from the letters in file names found in
|
||||
// C:\ProgramData\Origin\LocalContent\{game name)\*.mfst
|
||||
|
@ -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
|
||||
|
@ -10,14 +10,14 @@ namespace Wabbajack.DTOs.Interventions;
|
||||
public class ManualDownload : AUserIntervention<ManualDownload.BrowserDownloadState>
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
@ -11,7 +11,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="Xunit.DependencyInjection.Logging" Version="8.0.1" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -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<int, AbsolutePath> _steamGames = new();
|
||||
private readonly Dictionary<long, AbsolutePath> _gogGames = new();
|
||||
private readonly Dictionary<string, AbsolutePath> _egsGames = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, AbsolutePath> _originGames = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<AppId, AbsolutePath> _steamGames = new();
|
||||
private readonly Dictionary<GOGGameId, AbsolutePath> _gogGames = new();
|
||||
private readonly Dictionary<EGSGameId, AbsolutePath> _egsGames = new();
|
||||
private readonly Dictionary<OriginGameId, AbsolutePath> _originGames = new();
|
||||
|
||||
private readonly Dictionary<Game, AbsolutePath> _locationCache;
|
||||
private readonly ILogger<GameLocator> _logger;
|
||||
@ -30,19 +32,20 @@ public class GameLocator : IGameLocator
|
||||
public GameLocator(ILogger<GameLocator> 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<Game, AbsolutePath>();
|
||||
@ -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<TGame, TId>(
|
||||
AHandler<TGame, TId>? handler,
|
||||
Dictionary<TId, AbsolutePath> paths,
|
||||
Func<TGame, string> getPath)
|
||||
where TGame : class
|
||||
Func<TGame, AbsolutePath> 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;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
@ -18,10 +18,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="GameFinder.StoreHandlers.EGS" Version="2.2.2" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.GOG" Version="2.2.2" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.Origin" Version="2.2.2" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.Steam" Version="2.2.2" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.EGS" Version="4.0.0" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.GOG" Version="4.0.0" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.Origin" Version="4.0.0" />
|
||||
<PackageReference Include="GameFinder.StoreHandlers.Steam" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -65,7 +65,7 @@ public class GoogleDriveDownloader : ADownloader<DTOs.DownloadStates.GoogleDrive
|
||||
return new Uri(
|
||||
$"https://drive.google.com/uc?id={(state as DTOs.DownloadStates.GoogleDrive)?.Id}&export=download");
|
||||
}
|
||||
|
||||
|
||||
public override IDownloadState? Resolve(IReadOnlyDictionary<string, string> iniData)
|
||||
{
|
||||
if (iniData.ContainsKey("directURL") && Uri.TryCreate(iniData["directURL"].CleanIniString(), UriKind.Absolute, out var uri))
|
||||
@ -74,8 +74,8 @@ public class GoogleDriveDownloader : ADownloader<DTOs.DownloadStates.GoogleDrive
|
||||
}
|
||||
|
||||
public override Priority Priority => Priority.Normal;
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task<T> DownloadStream<T>(Archive archive, Func<Stream, Task<T>> fn, CancellationToken token)
|
||||
{
|
||||
var state = archive.State as DTOs.DownloadStates.GoogleDrive;
|
||||
@ -112,8 +112,8 @@ public class GoogleDriveDownloader : ADownloader<DTOs.DownloadStates.GoogleDrive
|
||||
{
|
||||
var initialUrl = $"https://drive.google.com/uc?id={state.Id}&export=download";
|
||||
var msg = new HttpRequestMessage(HttpMethod.Get, initialUrl);
|
||||
msg.UseChromeUserAgent();
|
||||
|
||||
msg.AddChromeAgent();
|
||||
|
||||
using var response = await _client.SendAsync(msg, token);
|
||||
var cookies = response.GetSetCookies();
|
||||
var warning = cookies.FirstOrDefault(c => c.Key.StartsWith("download_warning_"));
|
||||
@ -124,7 +124,7 @@ public class GoogleDriveDownloader : ADownloader<DTOs.DownloadStates.GoogleDrive
|
||||
var txt = await response.Content.ReadAsStringAsync(token);
|
||||
if (txt.Contains("<title>Google Drive - Quota exceeded</title>"))
|
||||
throw new Exception("Google Drive - Quota Exceeded");
|
||||
|
||||
|
||||
doc.LoadHtml(txt);
|
||||
|
||||
var action = doc.DocumentNode.DescendantsAndSelf()
|
||||
@ -133,7 +133,7 @@ public class GoogleDriveDownloader : ADownloader<DTOs.DownloadStates.GoogleDrive
|
||||
.Select(d => d.GetAttributeValue("action", ""))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (action != null)
|
||||
if (action != null)
|
||||
warning = ("download_warning_", "t");
|
||||
|
||||
}
|
||||
@ -145,18 +145,18 @@ public class GoogleDriveDownloader : ADownloader<DTOs.DownloadStates.GoogleDrive
|
||||
|
||||
var url = $"https://drive.google.com/uc?export=download&confirm={warning.Value}&id={state.Id}";
|
||||
var httpState = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
httpState.UseChromeUserAgent();
|
||||
httpState.AddChromeAgent();
|
||||
return httpState;
|
||||
}
|
||||
else
|
||||
{
|
||||
var url = $"https://drive.google.com/file/d/{state.Id}/edit";
|
||||
var msg = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
msg.UseChromeUserAgent();
|
||||
|
||||
msg.AddChromeAgent();
|
||||
|
||||
using var response = await _client.SendAsync(msg, token);
|
||||
msg = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
msg.UseChromeUserAgent();
|
||||
msg.AddChromeAgent();
|
||||
return !response.IsSuccessStatusCode ? null : msg;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
@ -11,7 +11,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.3" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Wabbajac.Hash.xxHash64.Benchmark</RootNamespace>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
@ -11,7 +11,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -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);
|
||||
|
@ -16,6 +16,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\Icons\wabbajack.ico</ApplicationIcon>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview4" />
|
||||
@ -30,7 +31,7 @@
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="2.3.1-prev2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="18.3.1" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.1" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="6.0.2-mauipre.1.22102.15" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
@ -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<T> GetJsonFromSendAsync<T>(this HttpClient client, HttpRequestMessage msg,
|
||||
JsonSerializerOptions opts, CancellationToken? token = null)
|
||||
{
|
||||
|
@ -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<SingleThreadedDownloader> _logger;
|
||||
private CancellationToken _token;
|
||||
private Exception? _error;
|
||||
|
||||
|
||||
public ResumableDownloader(HttpRequestMessage msg, AbsolutePath outputPath, IJob job, ILogger<SingleThreadedDownloader> logger)
|
||||
public ResumableDownloader(HttpRequestMessage msg, AbsolutePath outputPath, IJob job, PerformanceSettings performanceSettings, ILogger<SingleThreadedDownloader> 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
|
||||
|
@ -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<SingleThreadedDownloader> _logger;
|
||||
private readonly PerformanceSettings _settings;
|
||||
|
||||
public SingleThreadedDownloader(ILogger<SingleThreadedDownloader> logger, HttpClient client)
|
||||
public SingleThreadedDownloader(ILogger<SingleThreadedDownloader> logger, HttpClient client, MainSettings settings)
|
||||
{
|
||||
_logger = logger;
|
||||
_client = client;
|
||||
_settings = settings.PerformanceSettings;
|
||||
}
|
||||
|
||||
public async Task<Hash> 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
|
||||
|
@ -1,18 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Downloader" Version="3.0.4" />
|
||||
<PackageReference Include="Downloader" Version="3.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.2-mauipre.1.22102.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Wabbajack.Configuration\Wabbajack.Configuration.csproj" />
|
||||
<ProjectReference Include="..\Wabbajack.Downloaders.Interfaces\Wabbajack.Downloaders.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\Wabbajack.Hashing.xxHash64\Wabbajack.Hashing.xxHash64.csproj" />
|
||||
<ProjectReference Include="..\Wabbajack.Networking.Http.Interfaces\Wabbajack.Networking.Http.Interfaces.csproj" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -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<WabbajackApiState> _apiState;
|
||||
private readonly Configuration _wabbajackClientConfiguration;
|
||||
private readonly ClientConfiguration _wabbajackClientConfiguration;
|
||||
|
||||
public HashSet<string> ProxiedEndpoints = new()
|
||||
{
|
||||
@ -28,7 +28,7 @@ public class ProxiedNexusApi : NexusApi
|
||||
public ProxiedNexusApi(ITokenProvider<NexusApiState> apiKey, ILogger<ProxiedNexusApi> logger, HttpClient client,
|
||||
IResource<HttpClient> limiter,
|
||||
ApplicationInfo appInfo, JsonSerializerOptions jsonOptions, ITokenProvider<WabbajackApiState> apiState,
|
||||
Configuration wabbajackClientConfiguration)
|
||||
ClientConfiguration wabbajackClientConfiguration)
|
||||
: base(apiKey, logger, client, limiter, appInfo, jsonOptions)
|
||||
{
|
||||
_apiState = apiState;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
@ -12,7 +12,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
@ -12,7 +12,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.2-mauipre.1.22102.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="Xunit.DependencyInjection" Version="8.6.1" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>$(VERSION)</Version>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<Version>$(VERSION)</Version>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user