diff --git a/Wabbajack.Lib/ACompiler.cs b/Wabbajack.Lib/ACompiler.cs index 6667f101..4345c17b 100644 --- a/Wabbajack.Lib/ACompiler.cs +++ b/Wabbajack.Lib/ACompiler.cs @@ -101,12 +101,18 @@ namespace Wabbajack.Lib return id; } - internal async Task IncludeFile(AbsolutePath data) + internal async Task IncludeFile(Stream data) { var id = IncludeId(); - await data.CopyToAsync(ModListOutputFolder.Combine(id)); + await ModListOutputFolder.Combine(id).WriteAllAsync(data); return id; } + + internal async Task IncludeFile(AbsolutePath data) + { + await using var stream = await data.OpenRead(); + return await IncludeFile(stream); + } internal async Task<(RelativePath, AbsolutePath)> IncludeString(string str) @@ -302,6 +308,27 @@ namespace Wabbajack.Lib } } + protected async Task InlineFiles() + { + var grouped = ModList.Directives.OfType() + .Where(f => f.SourceDataID == default) + .GroupBy(f => f.SourceDataFile) + .ToDictionary(f => f.Key); + + await VFS.Extract(Queue, grouped.Keys.ToHashSet(), async (vf, sfn) => + { + await using var stream = await sfn.GetStream(); + var id = await IncludeFile(stream); + foreach (var file in grouped[vf]) + { + file.SourceDataID = id; + file.SourceDataFile = null; + } + + }); + } + + public bool CheckForNoMatchExit(ICollection noMatches) { if (noMatches.Count > 0) diff --git a/Wabbajack.Lib/AInstaller.cs b/Wabbajack.Lib/AInstaller.cs index ed41a416..be65cf8e 100644 --- a/Wabbajack.Lib/AInstaller.cs +++ b/Wabbajack.Lib/AInstaller.cs @@ -87,7 +87,11 @@ namespace Wabbajack.Lib public async Task LoadBytesFromPath(RelativePath path) { - return await ExtractedModlistFolder!.Dir.Combine(path).ReadAllBytesAsync(); + var fullPath = ExtractedModlistFolder!.Dir.Combine(path); + if (!fullPath.IsFile) + throw new Exception($"Cannot load inlined data {path} file does not exist"); + + return await fullPath.ReadAllBytesAsync(); } public static ModList LoadFromFile(AbsolutePath path) @@ -140,7 +144,27 @@ namespace Wabbajack.Lib foreach (var directive in grouped[vf]) { s.Position = 0; - await directive.Directive.To.RelativeTo(OutputFolder).WriteAllAsync(s, false); + + switch (directive.Directive) + { + case PatchedFromArchive pfa: + { + var patchData = await LoadBytesFromPath(pfa.PatchID); + await using var os = await directive.Directive.To.RelativeTo(OutputFolder).Create(); + Utils.ApplyPatch(s, () => new MemoryStream(patchData), os); + } + break; + + + + case FromArchive _: + await directive.Directive.To.RelativeTo(OutputFolder).WriteAllAsync(s, false); + break; + default: + throw new Exception($"No handler for {directive}"); + + + } } }); } diff --git a/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs b/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs index ee6600ae..e873c4cf 100644 --- a/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs +++ b/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs @@ -76,7 +76,7 @@ namespace Wabbajack.Lib.CompilationSteps Func? _cleanup = null; if (defaultInclude) { - _cleanup = await source.File.Context.Stage(source.File.Children); + //_cleanup = await source.File.Context.Stage(source.File.Children); } var matches = await sourceFiles.PMap(_mo2Compiler.Queue, e => _mo2Compiler.RunStack(stack, new RawSourceFile(e, Consts.BSACreationDir.Combine((RelativePath)id, (RelativePath)e.Name)))); diff --git a/Wabbajack.Lib/CompilationSteps/IncludeAll.cs b/Wabbajack.Lib/CompilationSteps/IncludeAll.cs index 3b4c8b5b..8138181d 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeAll.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeAll.cs @@ -14,8 +14,7 @@ namespace Wabbajack.Lib.CompilationSteps public override async ValueTask Run(RawSourceFile source) { var inline = source.EvolveTo(); - await using var file = await source.File.StagedFile.OpenRead(); - inline.SourceDataID = await _compiler.IncludeFile(await file.ReadAllAsync()); + inline.SourceDataFile = source.File; return inline; } } diff --git a/Wabbajack.Lib/Data.cs b/Wabbajack.Lib/Data.cs index c5552621..8da342e3 100644 --- a/Wabbajack.Lib/Data.cs +++ b/Wabbajack.Lib/Data.cs @@ -161,6 +161,9 @@ namespace Wabbajack.Lib /// Data that will be written as-is to the destination location; /// public RelativePath SourceDataID { get; set; } + + [JsonIgnore] + public VirtualFile? SourceDataFile { get; set; } } [JsonName("ArchiveMeta")] diff --git a/Wabbajack.Lib/MO2Compiler.cs b/Wabbajack.Lib/MO2Compiler.cs index 9c980fc6..7b935812 100644 --- a/Wabbajack.Lib/MO2Compiler.cs +++ b/Wabbajack.Lib/MO2Compiler.cs @@ -57,7 +57,7 @@ namespace Wabbajack.Lib public HashSet SelectedProfiles { get; set; } = new HashSet(); public MO2Compiler(AbsolutePath mo2Folder, string mo2Profile, AbsolutePath outputFile) - : base(steps: 20) + : base(steps: 21) { MO2Folder = mo2Folder; MO2Profile = mo2Profile; @@ -352,6 +352,9 @@ namespace Wabbajack.Lib Version = ModlistVersion ?? new Version(1,0,0,0), IsNSFW = ModlistIsNSFW }; + + UpdateTracker.NextStep("Including required files"); + await InlineFiles(); UpdateTracker.NextStep("Running Validation"); @@ -370,7 +373,6 @@ namespace Wabbajack.Lib return true; } - public Dictionary> GameHashes { get; set; } = new Dictionary>(); public Dictionary GamesWithHashes { get; set; } = new Dictionary();