diff --git a/CHANGELOG.md b/CHANGELOG.md index ab8c3477..e7a2c348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ that is copied directly into a modfile (commonly used for `SSE Terrain Tamriel.e * Fix crash caused by multiple downloads with the same SHA256 * Putting `WABBAJACK_ALWAYS_INCLUDE` on a mod's notes/comments will cause it to always be included in the modlist, even if disabled * All `.json`, `.ini`, and `.yaml` files that contain remappable paths are now inlined and remapped. +* If Wabbajack finds a file called `otherprofiles.txt` inside the compile'd profile's folder. Then that file is assumed +to be a list of other profiles to be included in the install. This list should be the name of a profile, one name per line. #### Version 0.8.1 - 8/29/2019 * Fixed a bug that was causing VFS temp folders not to be cleaned diff --git a/VirtualFileSystem/VirtualFileSystem.cs b/VirtualFileSystem/VirtualFileSystem.cs index 954bd4b7..4e8bb78a 100644 --- a/VirtualFileSystem/VirtualFileSystem.cs +++ b/VirtualFileSystem/VirtualFileSystem.cs @@ -624,6 +624,7 @@ namespace VFS Size = fio.Length; Hash = Utils.FileSHA256(StagedPath); LastModified = fio.LastWriteTime.ToMilliseconds(); + } diff --git a/Wabbajack.Common/Utils.cs b/Wabbajack.Common/Utils.cs index d392a3fe..b69dde9e 100644 --- a/Wabbajack.Common/Utils.cs +++ b/Wabbajack.Common/Utils.cs @@ -56,7 +56,7 @@ namespace Wabbajack.Common using (var o = new CryptoStream(Stream.Null, sha, CryptoStreamMode.Write)) { using (var i = File.OpenRead(file)) - i.CopyToWithStatus(new FileInfo(file).Length, o, $"Hashing {Path.GetFileName(file)}"); + i.CopyToWithStatus(new FileInfo(file).Length, o, $"Hashing {Path.GetFileName(file)}"); } return sha.Hash.ToBase64(); diff --git a/Wabbajack/Compiler.cs b/Wabbajack/Compiler.cs index 76d445b6..f2c5dc70 100644 --- a/Wabbajack/Compiler.cs +++ b/Wabbajack/Compiler.cs @@ -113,6 +113,8 @@ namespace Wabbajack GamePath = ((string)MO2Ini.General.gamePath).Replace("\\\\", "\\"); } + public HashSet SelectedProfiles { get; set; } = new HashSet(); + private IndexedArchive LoadArchive(string file) { var info = new IndexedArchive(); @@ -140,6 +142,16 @@ namespace Wabbajack public void Compile() { + Info($"Looking for other profiles"); + var other_profiles_path = Path.Combine(MO2ProfileDir, "otherprofiles.txt"); + if (File.Exists(other_profiles_path)) + { + SelectedProfiles = File.ReadAllLines(other_profiles_path).ToHashSet(); + SelectedProfiles.Add(MO2Profile); + } + + Info($"Using Profiles: " + string.Join(", ", SelectedProfiles.OrderBy(p => p))); + Info($"Indexing {MO2Folder}"); VFS.AddRoot(MO2Folder); Info($"Indexing {GamePath}"); @@ -827,21 +839,21 @@ namespace Wabbajack private Func IgnoreDisabledMods() { var always_enabled = ModInis.Where(f => IsAlwaysEnabled(f.Value)).Select(f => f.Key).ToHashSet(); - var disabled_mods = File.ReadAllLines(Path.Combine(MO2ProfileDir, "modlist.txt")) - .Where(line => line.StartsWith("-") && !line.EndsWith("_separator")) - .Select(line => line.Substring(1)) - .Where(line => !always_enabled.Contains(line)) - .Select(line => Path.Combine("mods", line + "\\")) - .ToList(); + + var all_enabled_mods = SelectedProfiles + .SelectMany(p => File.ReadAllLines(Path.Combine(MO2Folder, "profiles", p, "modlist.txt"))) + .Where(line => line.StartsWith("+") || line.EndsWith("_separator")) + .Select(line => line.Substring(1)) + .Concat(always_enabled) + .Select(line => Path.Combine("mods", line) + "\\") + .ToList(); + return source => { - if (disabled_mods.FirstOrDefault(mod => source.Path.StartsWith(mod)) != null) - { - var r = source.EvolveTo(); - r.Reason = "Disabled Mod"; - return r; - } - return null; + if (!source.Path.StartsWith("mods") || all_enabled_mods.Any(mod => source.Path.StartsWith(mod))) return null; + var r = source.EvolveTo(); + r.Reason = "Disabled Mod"; + return r; }; } @@ -912,10 +924,11 @@ namespace Wabbajack private Func IncludeThisProfile() { - var correct_profile = Path.Combine("profiles", MO2Profile) + "\\"; + var correct_profiles = SelectedProfiles.Select(p => Path.Combine("profiles", p) + "\\").ToList(); + return source => { - if (source.Path.StartsWith(correct_profile)) + if (correct_profiles.Any(p => source.Path.StartsWith(p))) { byte[] data; if (source.Path.EndsWith("\\modlist.txt")) @@ -942,13 +955,20 @@ namespace Wabbajack private Func IgnoreOtherProfiles() { - var correct_profile = Path.Combine("profiles", MO2Profile) + "\\"; + var profiles = SelectedProfiles + .Select(p => Path.Combine("profiles", p) + "\\") + .ToList(); + return source => { - if (source.Path.StartsWith("profiles\\") && !source.Path.StartsWith(correct_profile)) + if (source.Path.StartsWith("profiles\\")) { + if (profiles.Any(profile => !source.Path.StartsWith(profile))) + { + return null; + } var c = source.EvolveTo(); - c.Reason = "File not for this profile"; + c.Reason = "File not for selected profiles"; return c; } return null;