Merge pull request #1045 from wabbajack-tools/rework-patch-selection

Rework how we select patches (use non-primary games as a last resort)
This commit is contained in:
Timothy Baldridge 2020-08-18 19:31:26 -07:00 committed by GitHub
commit 77d586f131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 2 deletions

View File

@ -6,6 +6,7 @@ using Alphaleonis.Win32.Filesystem;
using F23.StringSimilarity;
using Newtonsoft.Json;
using Wabbajack.Common;
using Wabbajack.Lib.Downloaders;
using Wabbajack.VirtualFileSystem;
namespace Wabbajack.Lib.CompilationSteps
@ -104,7 +105,7 @@ namespace Wabbajack.Lib.CompilationSteps
if (patches.All(p => p.Item1))
{
var (_, bytes, file) = patches.OrderBy(f => f.data!.Length).First();
var (_, bytes, file) = PickPatch(_mo2Compiler, patches);
e.FromHash = file.Hash;
e.ArchiveHashPath = file.MakeRelativePaths();
e.PatchID = await _compiler.IncludeFile(bytes!);
@ -125,6 +126,29 @@ namespace Wabbajack.Lib.CompilationSteps
return e;
}
public static (bool, byte[], VirtualFile) PickPatch(MO2Compiler mo2Compiler, IEnumerable<(bool foundHash, byte[]? data, VirtualFile file)> patches)
{
var ordered = patches
.Select(f => (f.foundHash, f.data!, f.file))
.OrderBy(f => f.Item2.Length)
.ToArray();
var primaryChoice = ordered.FirstOrDefault(itm =>
{
var baseHash = itm.file.TopParent.Hash;
// If this file doesn't come from a game use it
if (!mo2Compiler.GamesWithHashes.TryGetValue(baseHash, out var games))
return true;
// Otherwise skip files that are not from the primary game
return games.Contains(mo2Compiler.CompilingGame.Game);
});
// If we didn't find a file from an archive or the primary game, use a secondary game file.
return primaryChoice != default ? primaryChoice : ordered.FirstOrDefault();
}
private AbsolutePath ModForFile(AbsolutePath file)
{
return file.RelativeTo(((MO2Compiler)_compiler).MO2ModsFolder).TopParent

View File

@ -210,6 +210,7 @@ namespace Wabbajack.Lib
{
var files = await ClientAPI.GetExistingGameFiles(Queue, ag);
Utils.Log($"Including {files.Length} stock game files from {ag} as download sources");
GameHashes[ag] = files.Select(f => f.Hash).ToHashSet();
IndexedArchives.AddRange(files.Select(f =>
{
@ -228,6 +229,10 @@ namespace Wabbajack.Lib
Utils.Error(e, "Unable to find existing game files, skipping.");
}
}
GamesWithHashes = GameHashes.SelectMany(g => g.Value.Select(h => (g, h)))
.GroupBy(gh => gh.h)
.ToDictionary(gh => gh.Key, gh => gh.Select(p => p.g.Key).ToArray());
}
IndexedArchives = IndexedArchives.DistinctBy(a => a.File.AbsoluteName).ToList();
@ -364,6 +369,9 @@ namespace Wabbajack.Lib
}
public Dictionary<Game, HashSet<Hash>> GameHashes { get; set; } = new Dictionary<Game, HashSet<Hash>>();
public Dictionary<Hash, Game[]> GamesWithHashes { get; set; } = new Dictionary<Hash, Game[]>();
public bool UseGamePaths { get; set; } = true;
private async Task CleanInvalidArchivesAndFillState()
@ -508,7 +516,7 @@ namespace Wabbajack.Lib
if (patches.All(p => p.Item1))
{
var (_, bytes, file) = patches.OrderBy(f => f.data!.Length).First();
var (_, bytes, file) = IncludePatches.PickPatch(this, patches);
pfa.FromFile = file;
pfa.FromHash = file.Hash;
pfa.ArchiveHashPath = file.MakeRelativePaths();