From ea95c78b2681ebbfcfa3ae62ad851a4b71ef4bd6 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Mon, 30 Sep 2019 17:39:41 -0600 Subject: [PATCH] updated the README fixed validation and game folder path detection --- CHANGELOG.md | 2 + NexusPage.html | 278 ++++++++++++++++++++++++ README.md | 25 ++- Wabbajack.Common/GameMetaData.cs | 2 +- Wabbajack.sln | 1 + Wabbajack/Compiler.cs | 17 +- Wabbajack/Installer.cs | 18 +- Wabbajack/Validation/ValidateModlist.cs | 6 +- 8 files changed, 325 insertions(+), 24 deletions(-) create mode 100644 NexusPage.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 49f0c53d..2447ae8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ * Added support for `.omod` files * Stop emitting `.exe` modlist installers * Reworked Nexus HTTP API - Thanks Cyclonit +* Added permissions system +* Auto detect game folders #### Version 0.9.2 - 9/18/2013 * Fixed a bug with BSA string encoding diff --git a/NexusPage.html b/NexusPage.html new file mode 100644 index 00000000..29e62bea --- /dev/null +++ b/NexusPage.html @@ -0,0 +1,278 @@ +

Wabbajack - An automated modlist installer for TES/Fallout games

+ +

Build Status

+ +

+ The general idea behind this program is fairly simple. Given a Mod Organizer 2 folder and profile, generate list of instructions that will allow + a program to automatically recreate the contents of the folder on another machine. Think of it as replication, but without ever distributing copyrighted + files or syncing data between the source and destination machine. The end result is a program that recreate a modlist on a computer while respecting the + rights of the game publisher and the mod authors. +

+ +

Installing a Modlist

+ +

Please visit our Discord link below for information on how to obtain and install a modlist.

+ + + + + +

What Wabbajack can do

+ +

+ At this point you may be wondering how much of a complex modlist Wabbajack can handle. At this point it's more about what Wabbajack can't handle, but + let's do a rundown of all the supported features: +

+ + + +

That being said, there are some cases where we would need to do a bit more work to develop:

+ + + +

The Wabbajack Permissions System

+ +

+ While Wabbajack can perform a large variety of operations on mod files, we recognize that some authors don't want to deal with + the support requests that come from some users performing operations on these files. Therefore we worked together with several + authors to create a permissions system Wabbajack will follow during installation and creation of a modlist. This permissions file + can be found on Github. Feel free to contact + us via discord about any questions you may have. +

+ +

Creating a ModList Installer

+ +

Overview video https://www.youtube.com/watch?v=5Fwr0Chtcuc

+ +

+ 1) Download Wabbajack and install it somewhere outside of your normal Mod Organizer 2 folder + (otherwise Wabbajack will try to figure out how to install itself and that might cause a collapse in the time-space + continuum). + 2) Make sure every archive you used in your MO2 profile has some sort of download information attached. +

+ + + +

Installing a ModList

+ +

+ 1) Get a modlist installer, it's a .exe file that was created by Wabbajack + 2) Run the .exe, the install folder defaults to the same folder as the executable, change it if you want. + 3) Click Begin to start installation. At some point you will be prompted for SSO authorization on the Nexus, files + will be auto installed and downloaded + 4) After installation has completed, run Mod Organizer 2.exe, select Portable and your game type. +

+ +

How it works

+ +

At a technical level the process is as follows.

+ +

+ 1) Hash and cache the contents of every archive in the \downloads folder. This lets Wabbajack know of all the possible locations where you could have installed mods + 2) Apply the resolution stack to every file in both the game's root folder and in the MO2 folder. + 3) Take the install directives and required archives and write their metadata to a JSON file. + 4) Attach the JSON file to Wabbajack itself, creating a new Auto-installer for the profile +

+ +

The Resolution Stack

+ +

Every file analyzed by Wabbajack is passed through a stack of rules. The first rule to match the file creates a Install Directive or a instruction on how to install that specific file.

+ +

Currently the Resolution stack looks like this:

+ +

+ 1) Ignore the contents of logs\ + 2) Directly include .meta files int the downloads\ folder + 3) Ignore the contents of downloads\ + 4) Ignore the contents of webcache\ + 5) Ignore the contents of overwrite\ + 6) Ignore any files with temporary_logs as a folder in the path + 7) Ignore .pyc files + 8) Ignore .log files + 9) Ignore any files in profiles that are not for the selected MO2 profile + 10) Ignore any disabled mods + 11) Include any profile settings for the selected profile by including them directly in the modlist + 12) Ignore "ModOrganizer.ini", it will be re-created when MO2 starts on the new machine + 13) Ignore "Data" in the Game directly (in your Steam folder) + 14) Ignore "Papyrus Compiler" in the game folder + 15) Ignore the "Skyrim" folder in the game folder + 16) Ignore any BSAs in the game folder + 17) Include all meta.ini files from all (selected) mods + 18) Include archive and file meta information for any file that matches a file in an archive directly via a SHA256 comparison + 19) Rip apart any .bsa files and run a mini resolution stack on the contents to figure out how to build the .bsa from the input files + 20) Generate patches for files that may have been modified after being installed from an archive (see section on Patching for more info) + 21) Include dummy ESPs directly into the modlist + 22) Ignore files in the game directory + 23) Ignore .ini files + 24) Ignore .html files (normally these are logs) + 25) Ignore .txt files + 26) Ignore HavockBehaviourPostProcess.exe this seems to get copied around by tools for some reason + 27) Ignore splash.png it's created for some games (like FO4) by MO2 + 28) Error for any file that survives to this point. +

+ +

So as you can see we handle a lot of possible install situations. See the section on Creating a Modpack 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.

+ + + +

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 + is copied directly into the modlist instructions. However! It is important to note that the patch file is 100% useless without the source file. So original + patch = final_file. Without the original file, the final file cannot be recrated. This allows us to distribute arbitrary changes without violating copyrights as we do not copy + copyrighted material. Instead we copy instructions on how to modify the copyrighted material. +

+ +

FAQ

+ +

How do I get Wabbjack to handle mods from X

\ No newline at end of file diff --git a/README.md b/README.md index 77403df6..1f928289 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ a program to automatically recreate the contents of the folder on another machin files or syncing data between the source and destination machine. The end result is a program that recreate a modlist on a computer while respecting the rights of the game publisher and the mod authors. +### Installing a Modlist +Please visit our Discord link below for information on how to obtain and install a modlist. + ### Social Links - [Discord](https://discord.gg/zgbrkmA) @@ -65,6 +68,13 @@ That being said, there are some cases where we would need to do a bit more work - esp to esm conversion (there are hacks for this) - binary patching of non-bsa huge files. 256MB is the largest size Wabbajack can currently handle with the binary patcher +### The Wabbajack Permissions System +While Wabbajack can perform a large variety of operations on mod files, we recognize that some authors don't want to deal with +the support requests that come from some users performing operations on these files. Therefore we worked together with several +authors to create a permissions system Wabbajack will follow during installation and creation of a modlist. This permissions file +can be found on [Github](https://github.com/wabbajack-tools/opt-out-lists/blob/master/NexusModPermissions.yml). Feel free to contact +us via discord about any questions you may have. + ### Creating a ModList Installer Overview video [`https://www.youtube.com/watch?v=5Fwr0Chtcuc`](https://www.youtube.com/watch?v=5Fwr0Chtcuc) @@ -184,18 +194,6 @@ I wouldn't throw away the code, but it would have to be done in a way that was r it doesn't know what mod manager a user is using. This means that if the modlist creator used Vortex all users of the modlist would have to use Vortex. This doesn't seem optimal. It's possible perhaps, but it's at the bottom of the priority list. -**Where is the modlist? Why am I just given an .exe?** - -When Wabbajack creates a modlist, as a final step it copies itself (the wabbajack.exe) and tacks onto the end of the file the modlist data, and a few bits -of magic text. When Wabbajack starts it looks at itself to see if it has this extra data tacked on to the end of the executable. If the data is found the app kicks -into installation mode. This means that Wabbajack acts a lot like a self-extracting installer. - -**Do you know that some mod authors don't like their mods being automatically installed?** - -Yes, I've heard this, but they chose to host their data on a public site. And no, they don't have the right to dictate what HTTP client is used to download a file. -We're using official Nexus APIs for nexus downloads, so any downloads Wabbajack performs are correctly tracked, and MO2 encourages users to endorse mods. It's 2019, we can -have better tools than manually clicking links. - **How does Wabbajack differ from Automaton?** I (halgari) used to be a developer working on Automaton. Sadly development was moving a bit too slowly for my liking, and I realized that a complete rewrite would allow the @@ -215,6 +213,9 @@ Our tester and Discord members who encourage development and help test the build #### Patreon Supporters - Druwski +- Soothsayre +- krageon +- Scumbag ### License & Copyright diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index 890249e0..7677da15 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -28,7 +28,7 @@ namespace Wabbajack.Common public string GameLocation => (string)Registry.GetValue(GameLocationRegistryKey, "installed path", null) ?? - (string)Registry.GetValue(GameLocationRegistryKey.Replace(@"HKEY_LOCAL_MACHINE\SOFTWARE\", @"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432"), "installed path", null); + (string)Registry.GetValue(GameLocationRegistryKey.Replace(@"HKEY_LOCAL_MACHINE\SOFTWARE\", @"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\"), "installed path", null); } public class GameRegistry diff --git a/Wabbajack.sln b/Wabbajack.sln index edc10232..ef9a1871 100644 --- a/Wabbajack.sln +++ b/Wabbajack.sln @@ -15,6 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject CHANGELOG.md = CHANGELOG.md LICENSE.txt = LICENSE.txt + NexusPage.html = NexusPage.html README.md = README.md RECIPES.md = RECIPES.md EndProjectSection diff --git a/Wabbajack/Compiler.cs b/Wabbajack/Compiler.cs index 48e4dd5b..18297947 100644 --- a/Wabbajack/Compiler.cs +++ b/Wabbajack/Compiler.cs @@ -180,6 +180,20 @@ namespace Wabbajack Info($"Found {AllFiles.Count} files to build into mod list"); + Info("Verifying destinations"); + var dups = AllFiles.GroupBy(f => f.Path) + .Where(fs => fs.Count() > 1) + .Select(fs => + { + Utils.Log($"Duplicate files installed to {fs.Key} from : {String.Join(", ", fs.Select(f => f.AbsolutePath))}"); + return fs; + }).ToList(); + + if (dups.Count > 0) + { + Error($"Found {dups.Count} duplicates, exiting"); + } + ExtraFiles = new ConcurrentBag(); ModInis = Directory.EnumerateDirectories(Path.Combine(MO2Folder, "mods")) @@ -245,11 +259,12 @@ namespace Wabbajack Name = MO2Profile }; + ValidateModlist.RunValidation(ModList); + GenerateReport(); ExportModlist(); ResetMembers(); - ValidateModlist.RunValidation(ModList); ShowReport(); diff --git a/Wabbajack/Installer.cs b/Wabbajack/Installer.cs index 3f41b108..fe61a430 100644 --- a/Wabbajack/Installer.cs +++ b/Wabbajack/Installer.cs @@ -93,18 +93,18 @@ namespace Wabbajack } } + var game = GameRegistry.Games[ModList.GameType]; + + GameFolder = game.GameLocation; + if (GameFolder == null) { MessageBox.Show( - "In order to do a proper install Wabbajack needs to know where your game folder resides. This is most likely " + - "somewhere in one of your Steam folders. Please select this folder on the next screen." + - "Note: This is not the install location where Mod Organizer 2 will be installed. ", - "Select your Game Folder", MessageBoxButton.OK); - if (!LocateGameFolder()) - { - Info("Stopping installation because game folder was not selected"); - return; - } + $"In order to do a proper install Wabbajack needs to know where your {game.MO2Name} folder resides. We tried looking the" + + "game location up in the windows registry but were unable to find it, please make sure you launch the game once before running this installer. ", + "Could not find game location", MessageBoxButton.OK); + Utils.Log("Exiting because we couldn't find the game folder."); + return; } HashArchives(); diff --git a/Wabbajack/Validation/ValidateModlist.cs b/Wabbajack/Validation/ValidateModlist.cs index 201c50d9..c53ef764 100644 --- a/Wabbajack/Validation/ValidateModlist.cs +++ b/Wabbajack/Validation/ValidateModlist.cs @@ -65,7 +65,11 @@ namespace Wabbajack.Validation var errors = validator.Validate(modlist); errors.Do(e => Utils.Log(e)); - Utils.Log($"{errors.Count()} validation errors found, cannot continue."); + if (errors.Count() > 0) + { + Utils.Log($"{errors.Count()} validation errors found, cannot continue."); + throw new AccessViolationException(); + } } ///