fixes #14, fixes #17

This commit is contained in:
Timothy Baldridge 2019-09-02 16:36:57 -06:00
parent 50d2d95377
commit d21a11b005
5 changed files with 39 additions and 10 deletions

View File

@ -9,6 +9,8 @@
* Added support for non-archive files in downloads and installation. You can now provide a link directly to a file
that is copied directly into a modfile (commonly used for `SSE Terrain Tamriel.esm`)
* 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.
#### Version 0.8.1 - 8/29/2019
* Fixed a bug that was causing VFS temp folders not to be cleaned

View File

@ -135,6 +135,11 @@ Currently the Resolution stack looks like this:
So as you can see we handle a lot of possible install situations. See the section on [`Creating a Modpack`](README.md#Creating_a_ModList_Installer) for information on working with the installer
### Wabbajack Flags
The if the following words are found in a mod's notes or comments they trigger special behavior in Wabbajack.
* `WABBAJACK_INCLUDE` - All the files int he mod will be inlined into the installer
* `WABBAJAC_ALWAYS_ENABLE` - The mod's files will be considered by the compiler even if the mod is disabled in the profile
### Patches
Wabbajack can create binary patches for files that have been modified after installation. This could be `.esp` files that have been cleaned or patched. Or
it could be meshes and textures that have been optimized to work better in a given game. In any case a BSDiff file is generated. The output of this process

View File

@ -16,8 +16,8 @@ namespace Wabbajack.Common
public static string BSACreationDir = "TEMP_BSA_FILES";
public static string MegaPrefix = "https://mega.nz/#!";
public static HashSet<string> SupportedArchives = new HashSet<string>() { ".zip", ".rar", ".7z", ".7zip" };
public static HashSet<string> SupportedBSAs = new HashSet<string>() { ".bsa" };
public static HashSet<string> SupportedArchives = new HashSet<string> { ".zip", ".rar", ".7z", ".7zip" };
public static HashSet<string> SupportedBSAs = new HashSet<string> { ".bsa" };
public static String UserAgent {
get
@ -28,6 +28,8 @@ namespace Wabbajack.Common
}
}
public static HashSet<string> ConfigFileExtensions = new HashSet<string> {".json", ".ini", ".yml"};
public static string NexusCacheDirectory = "nexus_link_cache";
public static string WABBAJACK_INCLUDE = "WABBAJACK_INCLUDE";
@ -45,5 +47,6 @@ namespace Wabbajack.Common
public static string HashCacheName = "Wabbajack.hash_cache";
public static HashSet<string> GameESMs = new HashSet<string>() { "Skyrim.esm", "Update.esm", "Dawnguard.esm", "HearthFires.esm", "Dragonborn.esm" };
public static string WABBAJACK_ALWAYS_ENABLE = "WABBAJACK_ALWAYS_ENABLE";
}
}

View File

@ -534,7 +534,7 @@ namespace Wabbajack
IgnoreDisabledMods(),
IncludeThisProfile(),
// Ignore the ModOrganizer.ini file it contains info created by MO2 on startup
IncludeStubbedMO2Ini(),
IncludeStubbedConfigFiles(),
IncludeLootFiles(),
IgnoreStartsWith(Path.Combine(Consts.GameFolderFilesDir, "Data")),
IgnoreStartsWith(Path.Combine(Consts.GameFolderFilesDir, "Papyrus Compiler")),
@ -610,21 +610,22 @@ namespace Wabbajack
};
}
private Func<RawSourceFile, Directive> IncludeStubbedMO2Ini()
private Func<RawSourceFile, Directive> IncludeStubbedConfigFiles()
{
return source =>
{
if (source.Path == "ModOrganizer.ini")
if (Consts.ConfigFileExtensions.Contains(Path.GetExtension(source.Path)))
{
return RemapIni(source, GamePath);
return RemapFile(source, GamePath);
}
return null;
};
}
private Directive RemapIni(RawSourceFile source, string gamePath)
private Directive RemapFile(RawSourceFile source, string gamePath)
{
var data = File.ReadAllText(source.AbsolutePath);
var original_data = data;
data = data.Replace(GamePath, Consts.GAME_PATH_MAGIC_BACK);
data = data.Replace(GamePath.Replace("\\", "\\\\"), Consts.GAME_PATH_MAGIC_DOUBLE_BACK);
@ -633,6 +634,8 @@ namespace Wabbajack
data = data.Replace(MO2Folder, Consts.MO2_PATH_MAGIC_BACK);
data = data.Replace(MO2Folder.Replace("\\", "\\\\"), Consts.MO2_PATH_MAGIC_DOUBLE_BACK);
data = data.Replace(MO2Folder.Replace("\\", "/"), Consts.MO2_PATH_MAGIC_FORWARD);
if (data == original_data)
return null;
var result = source.EvolveTo<RemappedInlineFile>();
result.SourceData = Encoding.UTF8.GetBytes(data).ToBase64();
return result;
@ -823,9 +826,12 @@ namespace Wabbajack
private Func<RawSourceFile, Directive> 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 => Path.Combine("mods", line.Substring(1)) + "\\")
.Select(line => line.Substring(1))
.Where(line => !always_enabled.Contains(line))
.Select(line => Path.Combine("mods", line + "\\"))
.ToList();
return source =>
{
@ -839,6 +845,19 @@ namespace Wabbajack
};
}
private static bool IsAlwaysEnabled(dynamic data)
{
if (data == null)
return false;
if (data.General != null && data.General.notes != null &&
data.General.notes.Contains(Consts.WABBAJACK_ALWAYS_ENABLE))
return true;
if (data.General != null && data.General.comments != null &&
data.General.notes.Contains(Consts.WABBAJACK_ALWAYS_ENABLE))
return true;
return false;
}
private Func<RawSourceFile, Directive> IncludePatches()
{
var indexed = IndexedFiles.Values

View File

@ -76,7 +76,7 @@ namespace Wabbajack
var files = lst.Directives.OrderBy(d => d.To).ToList();
Text($"\n\n### Install Plan of ({files.Count}) files");
Text($"(ignoring files that are directly copied from archives or listed in the patches section above)");
foreach (var directive in files)
foreach (var directive in files.OrderBy(f => f.GetType().Name).ThenByDescending(f => f.To))
{
switch (directive)
{
@ -87,7 +87,7 @@ namespace Wabbajack
NoWrapText($"* `{i.To}` by applying a patch to a game ESM ({i.SourceESMHash})");
break;
case RemappedInlineFile i:
NoWrapText($"* `{i.To}` by remapping the contents of a inline file");
NoWrapText($"* `{i.To}` by remapping the contents of an inline file");
break;
case InlineFile i:
NoWrapText($"* `{i.To}` from `{i.SourceData.Length}` byte file included in modlist");