/// <summary> /// If a user includes WABBAJACK_INCLUDE directly in the notes or comments of a mod, the contents of that /// mod will be inlined into the installer. USE WISELY. /// </summary> /// <returns></returns> private Func <RawSourceFile, Directive> IncludeTaggedFiles() { var include_directly = ModInis.Where(kv => { var general = kv.Value.General; if (general.notes != null && general.notes.Contains(Consts.WABBAJACK_INCLUDE)) { return(true); } if (general.comments != null && general.comments.Contains(Consts.WABBAJACK_INCLUDE)) { return(true); } return(false); }).Select(kv => $"mods\\{kv.Key}\\"); return(source => { if (source.Path.StartsWith("mods")) { foreach (var modpath in include_directly) { if (source.Path.StartsWith(modpath)) { var result = source.EvolveTo <InlineFile>(); result.SourceData = File.ReadAllBytes(source.AbsolutePath).ToBase64(); return result; } } } return null; }); }
/// <summary> /// This function will search for a way to create a BSA in the installed mod list by assembling it from files /// found in archives. To do this we hash all the files in side the BSA then try to find matches and patches for /// all of the files. /// </summary> /// <returns></returns> private Func <RawSourceFile, Directive> DeconstructBSAs() { var include_directly = ModInis.Where(kv => { var general = kv.Value.General; if (general.notes != null && general.notes.Contains(Consts.WABBAJACK_INCLUDE)) { return(true); } if (general.comments != null && general.comments.Contains(Consts.WABBAJACK_INCLUDE)) { return(true); } return(false); }).Select(kv => $"mods\\{kv.Key}\\"); var microstack = new List <Func <RawSourceFile, Directive> >() { DirectMatch(), IncludePatches(), DropAll() }; var microstack_with_include = new List <Func <RawSourceFile, Directive> >() { DirectMatch(), IncludePatches(), IncludeALL() }; return(source => { if (!Consts.SupportedBSAs.Contains(Path.GetExtension(source.Path))) { return null; } bool default_include = false; if (source.Path.StartsWith("mods")) { foreach (var modpath in include_directly) { if (source.Path.StartsWith(modpath)) { default_include = true; break; } } } var source_files = source.File.FileInArchive; var stack = default_include ? microstack_with_include : microstack; var id = Guid.NewGuid().ToString(); var matches = source_files.PMap(e => RunStack(stack, new RawSourceFile(e) { Path = Path.Combine(Consts.BSACreationDir, id, e.Paths.Last()) })); foreach (var match in matches) { if (match is IgnoredDirectly) { Error($"File required for BSA creation doesn't exist: {match.To}"); } ExtraFiles.Add(match); } ; CreateBSA directive; using (var bsa = new BSAReader(source.AbsolutePath)) { directive = new CreateBSA() { To = source.Path, TempID = id, Type = (uint)bsa.HeaderType, FileFlags = (uint)bsa.FileFlags, ArchiveFlags = (uint)bsa.ArchiveFlags, }; }; return directive; }); }