diff --git a/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs b/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs index c5198d13..d09683fe 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs @@ -35,6 +35,8 @@ using Wabbajack.Paths.IO; using Wabbajack.Services.OSIntegrated; using Wabbajack.Util; using System.Windows.Forms; +using System.Web; +using System.Diagnostics; namespace Wabbajack; @@ -140,6 +142,7 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM // Command properties public ReactiveCommand ShowManifestCommand { get; } public ReactiveCommand OpenReadmeCommand { get; } + public ReactiveCommand OpenWikiCommand { get; } public ReactiveCommand OpenDiscordButton { get; } public ReactiveCommand VisitModListWebsiteCommand { get; } @@ -178,6 +181,11 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM UIUtils.OpenWebsite(new Uri(ModList!.Readme)); }, this.WhenAnyValue(vm => vm.LoadingLock.IsNotLoading, vm => vm.ModList.Readme, (isNotLoading, readme) => isNotLoading && !string.IsNullOrWhiteSpace(readme))); + OpenWikiCommand = ReactiveCommand.Create(() => + { + UIUtils.OpenWebsite(new Uri("https://wiki.wabbajack.org/index.html")); + }, this.WhenAnyValue(vm => vm.LoadingLock.IsNotLoading)); + VisitModListWebsiteCommand = ReactiveCommand.Create(() => { UIUtils.OpenWebsite(ModList!.Website); @@ -280,6 +288,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)) @@ -305,11 +317,12 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM } if (installPath.ToString().Length != 0 && installPath != LastInstallPath && - !Installer.AutomaticallyOverwrite && 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?"; + "There are files already in the chosen install path, if you are updating an existing modlist, this is fine. " + Environment.NewLine + + " Otherwise, please ensure you intend for the folder contents to be deleted during the modlist install." + Environment.NewLine + + " Continue? "; string title = "Files found in install folder"; MessageBoxButtons buttons = MessageBoxButtons.YesNo; DialogResult result = MessageBox.Show(message, title, buttons); @@ -325,10 +338,43 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM 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 a modlist into Windows protected locations - such as Downloads,Documents etc, please make a new folder for the modlist."); + } + + 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) diff --git a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs index 8e87a272..c4f2e93d 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs @@ -39,9 +39,6 @@ namespace Wabbajack public bool SupportsAfterInstallNavigation => true; - [Reactive] - public bool AutomaticallyOverwrite { get; set; } - public int ConfigVisualVerticalOffset => 25; public MO2InstallerVM(InstallerVM installerVM) @@ -166,7 +163,6 @@ namespace Wabbajack if (settings == null) return; settings.InstallationLocation = Location.TargetPath; settings.DownloadLocation = DownloadLocation.TargetPath; - settings.AutomaticallyOverrideExistingInstall = AutomaticallyOverwrite; } public void AfterInstallNavigation() diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml index 74284763..f76f9d15 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml @@ -12,7 +12,7 @@ x:TypeArguments="local:InstallerVM" mc:Ignorable="d"> - + @@ -23,6 +23,7 @@ + + Text="Modlist Readme" /> + + + + + + + + + Background="Transparent" Grid.ColumnSpan="2" Margin="0,0,10,0"> diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs index d2e70061..b4000b86 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs @@ -46,6 +46,9 @@ namespace Wabbajack this.WhenAny(x => x.ViewModel.OpenReadmeCommand) .BindToStrict(this, x => x.OpenReadmeButton.Command) .DisposeWith(dispose); + this.WhenAny(x => x.ViewModel.OpenWikiCommand) + .BindToStrict(this, x => x.OpenWikiButton.Command) + .DisposeWith(dispose); this.WhenAny(x => x.ViewModel.CloseWhenCompleteCommand) .BindToStrict(this, x => x.CloseButton.Command) .DisposeWith(dispose); diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml index 225346f0..5cd461c9 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml @@ -39,6 +39,13 @@ FontSize="14" Text="Target Modlist" TextAlignment="Center" /> + !v.Failed) .BindToStrict(this, view => view.BeginButton.IsEnabled) .DisposeWith(dispose); - + + this.WhenAnyValue(x => x.ViewModel.ErrorState) + .Select(v => v.Reason) + .BindToStrict(this, view => view.errorTextBox.Text) + .DisposeWith(dispose); + this.WhenAnyValue(x => x.ViewModel.ErrorState) .Select(v => v.Failed ? Visibility.Visible : Visibility.Hidden) .BindToStrict(this, view => view.ErrorSummaryIcon.Visibility) diff --git a/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml b/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml index 5561d7fd..f47095f3 100644 --- a/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml @@ -46,21 +46,5 @@ FontSize="14" PickerVM="{Binding DownloadLocation}" ToolTip="The directory where modlist archives will be downloaded to" /> - - - - - diff --git a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml b/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml index 60620f63..de4ff6b9 100644 --- a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml +++ b/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml @@ -33,13 +33,6 @@ -