mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Optimize modlists before installation. Also fixed an async bug in VFS.
This commit is contained in:
parent
50bbd0eb1f
commit
13de3913da
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Windows.Navigation;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
using Wabbajack.VirtualFileSystem;
|
||||
@ -160,6 +161,9 @@ namespace Wabbajack.Lib
|
||||
File.Move(from, to);
|
||||
else
|
||||
File.Copy(from, to);
|
||||
// If we don't do this, the file will use the last-modified date of the file when it was compressed
|
||||
// into an archive, which isn't really what we want in the case of files installed archives
|
||||
File.SetLastWriteTime(to, DateTime.Now);
|
||||
}
|
||||
|
||||
vFiles.GroupBy(f => f.FromFile)
|
||||
@ -285,5 +289,40 @@ namespace Wabbajack.Lib
|
||||
File.WriteAllText(cache, e.FileHash());
|
||||
return HashArchive(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The user may already have some files in the OutputFolder. If so we can go through these and
|
||||
/// figure out which need to be updated, deleted, or left alone
|
||||
/// </summary>
|
||||
public void OptimizeModlist()
|
||||
{
|
||||
Utils.Log("Optimizing Modlist directives");
|
||||
var indexed = ModList.Directives.ToDictionary(d => d.To);
|
||||
|
||||
indexed.Values.PMap(Queue, d =>
|
||||
{
|
||||
// Bit backwards, but we want to return null for
|
||||
// all files we *want* installed. We return the files
|
||||
// to remove from the install list.
|
||||
var path = Path.Combine(OutputFolder, d.To);
|
||||
if (!File.Exists(path)) return null;
|
||||
|
||||
var fi = new FileInfo(path);
|
||||
if (fi.Length != d.Size) return null;
|
||||
|
||||
return path.FileHash() == d.Hash ? d : null;
|
||||
}).Where(d => d != null)
|
||||
.Do(d => indexed.Remove(d.To));
|
||||
|
||||
Utils.Log($"Optimized {ModList.Directives.Count} directives to {indexed.Count} required");
|
||||
var requiredArchives = indexed.Values.OfType<FromArchive>()
|
||||
.GroupBy(d => d.ArchiveHashPath[0])
|
||||
.Select(d => d.Key)
|
||||
.ToHashSet();
|
||||
|
||||
ModList.Archives = ModList.Archives.Where(a => requiredArchives.Contains(a.Hash)).ToList();
|
||||
ModList.Directives = indexed.Values.ToList();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ namespace Wabbajack.Lib
|
||||
private void BuildArchivePatches(string archive_sha, IEnumerable<PatchedFromArchive> group,
|
||||
Dictionary<string, string> absolute_paths)
|
||||
{
|
||||
using (var files = VFS.StageWith(group.Select(g => VFS.Index.FileForArchiveHashPath(g.ArchiveHashPath))).Result)
|
||||
using (var files = VFS.StageWith(group.Select(g => VFS.Index.FileForArchiveHashPath(g.ArchiveHashPath))))
|
||||
{
|
||||
var by_path = files.GroupBy(f => string.Join("|", f.FilesInFullPath.Skip(1).Select(i => i.Name)))
|
||||
.ToDictionary(f => f.Key, f => f.First());
|
||||
|
@ -3,6 +3,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
using Wabbajack.Lib.NexusApi;
|
||||
@ -17,6 +18,8 @@ namespace Wabbajack.Lib
|
||||
{
|
||||
public class MO2Installer : AInstaller
|
||||
{
|
||||
public bool WarnOnOverwrite { get; set; } = true;
|
||||
|
||||
public MO2Installer(string archive, ModList mod_list, string output_folder)
|
||||
{
|
||||
ModManager = ModManager.MO2;
|
||||
@ -52,7 +55,7 @@ namespace Wabbajack.Lib
|
||||
Directory.CreateDirectory(OutputFolder);
|
||||
Directory.CreateDirectory(DownloadFolder);
|
||||
|
||||
if (Directory.Exists(Path.Combine(OutputFolder, "mods")))
|
||||
if (Directory.Exists(Path.Combine(OutputFolder, "mods")) && WarnOnOverwrite)
|
||||
{
|
||||
if (MessageBox.Show(
|
||||
"There already appears to be a Mod Organizer 2 install in this folder, are you sure you wish to continue" +
|
||||
@ -66,6 +69,7 @@ namespace Wabbajack.Lib
|
||||
}
|
||||
}
|
||||
|
||||
OptimizeModlist();
|
||||
|
||||
HashArchives();
|
||||
DownloadArchives();
|
||||
@ -99,6 +103,7 @@ namespace Wabbajack.Lib
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void InstallIncludedDownloadMetas()
|
||||
{
|
||||
ModList.Directives
|
||||
|
@ -57,6 +57,7 @@ namespace Wabbajack.Test
|
||||
{
|
||||
var modlist = MO2Installer.LoadFromFile(compiler.ModListOutputFile);
|
||||
var installer = new MO2Installer(compiler.ModListOutputFile, modlist, utils.InstallFolder);
|
||||
installer.WarnOnOverwrite = false;
|
||||
installer.DownloadFolder = utils.DownloadsFolder;
|
||||
installer.GameFolder = utils.GameFolder;
|
||||
installer.Begin().Wait();
|
||||
|
@ -55,6 +55,55 @@ namespace Wabbajack.Test
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex.copy");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestUpdating()
|
||||
{
|
||||
|
||||
var profile = utils.AddProfile();
|
||||
var mod = utils.AddMod();
|
||||
var unchanged = utils.AddModFile(mod, @"Data\scripts\unchanged.pex", 10);
|
||||
var deleted = utils.AddModFile(mod, @"Data\scripts\deleted.pex", 10);
|
||||
var modified = utils.AddModFile(mod, @"Data\scripts\modified.pex", 10);
|
||||
|
||||
utils.Configure();
|
||||
|
||||
utils.AddManualDownload(
|
||||
new Dictionary<string, byte[]>
|
||||
{
|
||||
{ "/baz/unchanged.pex", File.ReadAllBytes(unchanged) },
|
||||
{ "/baz/deleted.pex", File.ReadAllBytes(deleted) },
|
||||
{ "/baz/modified.pex", File.ReadAllBytes(modified) },
|
||||
});
|
||||
|
||||
CompileAndInstall(profile);
|
||||
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex");
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex");
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\modified.pex");
|
||||
|
||||
var unchanged_path = utils.PathOfInstalledFile(mod, @"Data\scripts\unchanged.pex");
|
||||
var deleted_path = utils.PathOfInstalledFile(mod, @"Data\scripts\deleted.pex");
|
||||
var modified_path = utils.PathOfInstalledFile(mod, @"Data\scripts\modified.pex");
|
||||
|
||||
|
||||
var unchanged_modified = File.GetLastWriteTime(unchanged_path);
|
||||
var modified_modified = File.GetLastWriteTime(modified_path);
|
||||
|
||||
File.WriteAllText(modified_path, "random data");
|
||||
File.Delete(deleted_path);
|
||||
|
||||
CompileAndInstall(profile);
|
||||
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex");
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex");
|
||||
utils.VerifyInstalledFile(mod, @"Data\scripts\modified.pex");
|
||||
|
||||
Assert.AreEqual(unchanged_modified, File.GetLastWriteTime(unchanged_path));
|
||||
Assert.AreNotEqual(modified_modified, File.GetLastWriteTime(modified_path));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CleanedESMTest()
|
||||
|
@ -182,6 +182,11 @@ namespace Wabbajack.Test
|
||||
}
|
||||
}
|
||||
|
||||
public string PathOfInstalledFile(string mod, string file)
|
||||
{
|
||||
return Path.Combine(InstallFolder, "mods", mod, file);
|
||||
}
|
||||
|
||||
public void VerifyAllFiles()
|
||||
{
|
||||
foreach (var dest_file in Directory.EnumerateFiles(InstallFolder, "*", DirectoryEnumerationOptions.Recursive))
|
||||
|
@ -139,7 +139,7 @@ namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
var magic = Encoding.ASCII.GetString(br.ReadBytes(Encoding.ASCII.GetBytes(Magic).Length));
|
||||
var fileVersion = br.ReadUInt64();
|
||||
if (fileVersion != FileVersion || magic != magic)
|
||||
if (fileVersion != FileVersion || magic != Magic)
|
||||
throw new InvalidDataException("Bad Data Format");
|
||||
|
||||
var numFiles = br.ReadUInt64();
|
||||
@ -223,7 +223,7 @@ namespace Wabbajack.VirtualFileSystem
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<DisposableList<VirtualFile>> StageWith(IEnumerable<VirtualFile> files)
|
||||
public DisposableList<VirtualFile> StageWith(IEnumerable<VirtualFile> files)
|
||||
{
|
||||
return new DisposableList<VirtualFile>(Stage(files), files);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user