MO2 proper install folder logic now ignores files in downloads

This commit is contained in:
Justin Swanson 2019-12-21 19:30:01 -06:00
parent eed71e1c24
commit b392b667cf
4 changed files with 48 additions and 14 deletions

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Data.HashFunction.xxHash;
using System.Diagnostics;
@ -978,6 +978,11 @@ namespace Wabbajack.Common
p.WaitForExit();
}
public static bool IsUnderneathDirectory(string path, string dirPath)
{
return path.StartsWith(dirPath, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Writes a file to JSON but in an encrypted format in the user's app local directory.
/// The data will be encrypted so that it can only be read by this machine and this user.

View File

@ -319,7 +319,7 @@ namespace Wabbajack.Lib
File.WriteAllText(Path.Combine(OutputFolder, directive.To), data);
}
public static IErrorResponse CheckValidInstallPath(string path)
public static IErrorResponse CheckValidInstallPath(string path, string downloadFolder)
{
var ret = Utils.IsDirectoryPathValid(path);
if (!ret.Succeeded) return ret;
@ -339,8 +339,8 @@ namespace Wabbajack.Lib
// Check folder is either empty, or a likely valid previous install
if (!Directory.IsEmpty(path))
{
// Some probably naive check, but should be a good starting point to improve later
if (!Directory.EnumerateFiles(path).Any(file =>
// If we have a MO2 install, assume good to go
if (Directory.EnumerateFiles(path).Any(file =>
{
var fileName = Path.GetFileName(file);
if (fileName.Equals("ModOrganizer.exe", StringComparison.OrdinalIgnoreCase)) return true;
@ -348,7 +348,19 @@ namespace Wabbajack.Lib
return false;
}))
{
return ErrorResponse.Fail($"Cannot install into a non-empty folder that does not look like a previous WJ installation.");
return ErrorResponse.Success;
}
// If we don't have a MO2 install, and there's any file that's not in the downloads folder, mark failure
if (Directory.EnumerateFiles(path).Any(file =>
{
var fileName = Path.GetFileName(file);
if (string.IsNullOrWhiteSpace(downloadFolder)) return true;
return !Utils.IsUnderneathDirectory(file, downloadFolder);
}))
{
return ErrorResponse.Fail($"Cannot install into a non-empty folder that does not look like a previous WJ installation.\n" +
$"To override, delete all installed files from your target installation folder. Any files in your download folder are okay to keep.");
}
}

View File

@ -19,7 +19,7 @@ namespace Wabbajack.Test
{
using (var tempDir = new TempFolder())
{
Assert.IsTrue(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName).Succeeded);
Assert.IsTrue(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName, downloadFolder: null).Succeeded);
}
}
@ -28,7 +28,7 @@ namespace Wabbajack.Test
{
using (var tempDir = new TempFolder())
{
Assert.IsTrue(MO2Installer.CheckValidInstallPath(Path.Combine(tempDir.Dir.FullName, "Subfolder")).Succeeded);
Assert.IsTrue(MO2Installer.CheckValidInstallPath(Path.Combine(tempDir.Dir.FullName, "Subfolder"), downloadFolder: null).Succeeded);
}
}
@ -37,7 +37,7 @@ namespace Wabbajack.Test
{
using (var tempDir = new TempFolder())
{
Assert.IsFalse(MO2Installer.CheckValidInstallPath($"{tempDir.Dir.FullName}/*").Succeeded);
Assert.IsFalse(MO2Installer.CheckValidInstallPath($"{tempDir.Dir.FullName}/*", downloadFolder: null).Succeeded);
}
}
@ -48,7 +48,7 @@ namespace Wabbajack.Test
{
File.Create(Path.Combine(tempDir.Dir.FullName, $"ModOrganizer.exe"));
File.Create(Path.Combine(tempDir.Dir.FullName, $"modlist{ExtensionManager.Extension}"));
Assert.IsFalse(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName).Succeeded);
Assert.IsFalse(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName, downloadFolder: null).Succeeded);
}
}
@ -58,7 +58,7 @@ namespace Wabbajack.Test
using (var tempDir = new TempFolder())
{
File.Create(Path.Combine(tempDir.Dir.FullName, $"ModOrganizer.exe"));
Assert.IsTrue(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName).Succeeded);
Assert.IsTrue(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName, downloadFolder: null).Succeeded);
}
}
@ -68,7 +68,19 @@ namespace Wabbajack.Test
using (var tempDir = new TempFolder())
{
File.Create(Path.Combine(tempDir.Dir.FullName, $"someFile.txt"));
Assert.IsFalse(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName).Succeeded);
Assert.IsFalse(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName, downloadFolder: null).Succeeded);
}
}
[TestMethod]
public void CheckValidInstallPath_OverwriteFilesInDownloads()
{
using (var tempDir = new TempFolder())
{
var downloadsFolder = Path.Combine(tempDir.Dir.FullName, "downloads");
Directory.CreateDirectory(downloadsFolder);
File.Create(Path.Combine(tempDir.Dir.FullName, $"downloads/someFile.txt"));
Assert.IsFalse(MO2Installer.CheckValidInstallPath(tempDir.Dir.FullName, downloadFolder: downloadsFolder).Succeeded);
}
}
#endregion

View File

@ -47,8 +47,6 @@ namespace Wabbajack
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Installation Directory",
};
Location.AdditionalError = this.WhenAny(x => x.Location.TargetPath)
.Select(x => MO2Installer.CheckValidInstallPath(x));
DownloadLocation = new FilePickerVM()
{
ExistCheckOption = FilePickerVM.CheckOptions.Off,
@ -57,6 +55,13 @@ namespace Wabbajack
};
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) =>
{
return MO2Installer.CheckValidInstallPath(target, download);
});
CanInstall = Observable.CombineLatest(
this.WhenAny(x => x.Location.InError),
@ -83,7 +88,7 @@ namespace Wabbajack
_CurrentSettings = installerVM.WhenAny(x => x.ModListLocation.TargetPath)
.Select(path => path == null ? null : installerVM.MWVM.Settings.Installer.Mo2ModlistSettings.TryCreate(path))
.ToProperty(this, nameof(CurrentSettings));
(this).WhenAny(x => x.CurrentSettings)
this.WhenAny(x => x.CurrentSettings)
.Pairwise()
.Subscribe(settingsPair =>
{