From dae96640d8191dc37fb5d8af595ec818d6aa932b Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 3 Nov 2019 14:54:49 +0100 Subject: [PATCH 01/72] Created ModManager enum, moved enums to Wabbajack.Common --- Wabbajack.Common/Enums/ModManager.cs | 14 ++++++++++++++ {Wabbajack => Wabbajack.Common}/Enums/RunMode.cs | 0 Wabbajack.Common/Wabbajack.Common.csproj | 2 ++ Wabbajack.Lib/Data.cs | 5 +++++ Wabbajack/Wabbajack.csproj | 1 - 5 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Wabbajack.Common/Enums/ModManager.cs rename {Wabbajack => Wabbajack.Common}/Enums/RunMode.cs (100%) diff --git a/Wabbajack.Common/Enums/ModManager.cs b/Wabbajack.Common/Enums/ModManager.cs new file mode 100644 index 00000000..cd25ee9e --- /dev/null +++ b/Wabbajack.Common/Enums/ModManager.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Wabbajack.Common +{ + public enum ModManager + { + MO2, + Vortex + } +} diff --git a/Wabbajack/Enums/RunMode.cs b/Wabbajack.Common/Enums/RunMode.cs similarity index 100% rename from Wabbajack/Enums/RunMode.cs rename to Wabbajack.Common/Enums/RunMode.cs diff --git a/Wabbajack.Common/Wabbajack.Common.csproj b/Wabbajack.Common/Wabbajack.Common.csproj index 213dc82b..4469b164 100644 --- a/Wabbajack.Common/Wabbajack.Common.csproj +++ b/Wabbajack.Common/Wabbajack.Common.csproj @@ -91,6 +91,8 @@ + + diff --git a/Wabbajack.Lib/Data.cs b/Wabbajack.Lib/Data.cs index 7208c4e1..01720eb0 100644 --- a/Wabbajack.Lib/Data.cs +++ b/Wabbajack.Lib/Data.cs @@ -40,6 +40,11 @@ namespace Wabbajack.Lib /// public List Archives; + /// + /// The Mod Manager used to create the modlist + /// + public ModManager ModManager; + /// /// The game variant to which this game applies /// diff --git a/Wabbajack/Wabbajack.csproj b/Wabbajack/Wabbajack.csproj index 29e01834..7249e020 100644 --- a/Wabbajack/Wabbajack.csproj +++ b/Wabbajack/Wabbajack.csproj @@ -185,7 +185,6 @@ CompilerView.xaml - DownloadWindow.xaml From f9b0976ef1d941081f4e50c703f9e5534813f094 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 3 Nov 2019 16:26:51 +0100 Subject: [PATCH 02/72] Created abstract Compiler class --- Wabbajack.Lib/ACompiler.cs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Wabbajack.Lib/ACompiler.cs diff --git a/Wabbajack.Lib/ACompiler.cs b/Wabbajack.Lib/ACompiler.cs new file mode 100644 index 00000000..ce5c1e3e --- /dev/null +++ b/Wabbajack.Lib/ACompiler.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VFS; +using Wabbajack.Lib.CompilationSteps; + +namespace Wabbajack.Lib +{ + public abstract class ACompiler + { + protected string GamePath; + + protected string ModListOutputFolder; + protected string ModListOutputFile; + + protected List InstallDirectives; + protected List AllFiles; + protected ModList ModList; + protected VirtualFileSystem VFS; + protected List IndexedArchives; + protected Dictionary> IndexedFiles; + + public abstract void Info(string msg); + public abstract void Status(string msg); + public abstract void Error(string msg); + + internal abstract string IncludeFile(byte[] data); + internal abstract string IncludeFile(string data); + + public abstract bool Compile(); + + public abstract Directive RunStack(IEnumerable stack, RawSourceFile source); + public abstract IEnumerable GetStack(); + public abstract IEnumerable MakeStack(); + } +} From dcf91c07377e23a8a91b42450d3154a5120a3022 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 3 Nov 2019 17:43:43 +0100 Subject: [PATCH 03/72] Created VortexCompiler and updated MO2 Compiler --- Wabbajack.Lib/ACompiler.cs | 24 ++- Wabbajack.Lib/Compiler.cs | 49 ++--- Wabbajack.Lib/VortexCompiler.cs | 308 +++++++++++++++++++++++++++++ Wabbajack.Lib/Wabbajack.Lib.csproj | 2 + 4 files changed, 352 insertions(+), 31 deletions(-) create mode 100644 Wabbajack.Lib/VortexCompiler.cs diff --git a/Wabbajack.Lib/ACompiler.cs b/Wabbajack.Lib/ACompiler.cs index ce5c1e3e..1d9deda2 100644 --- a/Wabbajack.Lib/ACompiler.cs +++ b/Wabbajack.Lib/ACompiler.cs @@ -4,23 +4,29 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using VFS; +using Wabbajack.Common; using Wabbajack.Lib.CompilationSteps; namespace Wabbajack.Lib { public abstract class ACompiler { - protected string GamePath; + public ModManager ModManager; + public Compiler _mo2Compiler; + public VortexCompiler _vortexCompiler; - protected string ModListOutputFolder; - protected string ModListOutputFile; + public string GamePath; - protected List InstallDirectives; - protected List AllFiles; - protected ModList ModList; - protected VirtualFileSystem VFS; - protected List IndexedArchives; - protected Dictionary> IndexedFiles; + public string ModListOutputFolder; + public string ModListOutputFile; + + public List SelectedArchives; + public List InstallDirectives; + public List AllFiles; + public ModList ModList; + public VirtualFileSystem VFS; + public List IndexedArchives; + public Dictionary> IndexedFiles; public abstract void Info(string msg); public abstract void Status(string msg); diff --git a/Wabbajack.Lib/Compiler.cs b/Wabbajack.Lib/Compiler.cs index bf343416..3cf047e0 100644 --- a/Wabbajack.Lib/Compiler.cs +++ b/Wabbajack.Lib/Compiler.cs @@ -26,7 +26,7 @@ using Path = Alphaleonis.Win32.Filesystem.Path; namespace Wabbajack.Lib { - public class Compiler + public class Compiler : ACompiler { private string _mo2DownloadsFolder; @@ -42,9 +42,25 @@ namespace Wabbajack.Lib public Compiler(string mo2_folder) { + _vortexCompiler = null; + _mo2Compiler = this; + ModManager = ModManager.MO2; + MO2Folder = mo2_folder; MO2Ini = Path.Combine(MO2Folder, "ModOrganizer.ini").LoadIniFile(); GamePath = ((string)MO2Ini.General.gamePath).Replace("\\\\", "\\"); + + ModListOutputFolder = "output_folder"; + ModListOutputFile = MO2Profile + ExtensionManager.Extension; + + SelectedArchives = new List(); + InstallDirectives = new List(); + AllFiles = new List(); + ModList = new ModList(); + + VFS = VirtualFileSystem.VFS; + IndexedArchives = new List(); + IndexedFiles = new Dictionary>(); } public dynamic MO2Ini { get; } @@ -70,55 +86,43 @@ namespace Wabbajack.Lib public string MO2ProfileDir => Path.Combine(MO2Folder, "profiles", MO2Profile); - public string ModListOutputFolder => "output_folder"; - public string ModListOutputFile => MO2Profile + ExtensionManager.Extension; - - public List InstallDirectives { get; private set; } internal UserStatus User { get; private set; } - public List SelectedArchives { get; private set; } - public List AllFiles { get; private set; } - public ModList ModList { get; private set; } public ConcurrentBag ExtraFiles { get; private set; } public Dictionary ModInis { get; private set; } - public VirtualFileSystem VFS => VirtualFileSystem.VFS; - - public List IndexedArchives { get; private set; } - public Dictionary> IndexedFiles { get; private set; } - public HashSet SelectedProfiles { get; set; } = new HashSet(); - public void Info(string msg) + public override void Info(string msg) { Utils.Log(msg); } - public void Status(string msg) + public override void Status(string msg) { WorkQueue.Report(msg, 0); } - private void Error(string msg) + public override void Error(string msg) { Utils.Log(msg); throw new Exception(msg); } - internal string IncludeFile(byte[] data) + internal override string IncludeFile(byte[] data) { var id = Guid.NewGuid().ToString(); File.WriteAllBytes(Path.Combine(ModListOutputFolder, id), data); return id; } - internal string IncludeFile(string data) + internal override string IncludeFile(string data) { var id = Guid.NewGuid().ToString(); File.WriteAllText(Path.Combine(ModListOutputFolder, id), data); return id; } - public bool Compile() + public override bool Compile() { VirtualFileSystem.Clean(); Info("Looking for other profiles"); @@ -283,6 +287,7 @@ namespace Wabbajack.Lib GameType = GameRegistry.Games.Values.First(f => f.MO2Name == MO2Ini.General.gameName).Game, WabbajackVersion = WabbajackVersion, Archives = SelectedArchives, + ModManager = ModManager.MO2, Directives = InstallDirectives, Name = ModListName ?? MO2Profile, Author = ModListAuthor ?? "", @@ -533,7 +538,7 @@ namespace Wabbajack.Lib } - public static Directive RunStack(IEnumerable stack, RawSourceFile source) + public override Directive RunStack(IEnumerable stack, RawSourceFile source) { Utils.Status($"Compiling {source.Path}"); foreach (var step in stack) @@ -545,7 +550,7 @@ namespace Wabbajack.Lib throw new InvalidDataException("Data fell out of the compilation stack"); } - public IEnumerable GetStack() + public override IEnumerable GetStack() { var user_config = Path.Combine(MO2ProfileDir, "compilation_stack.yml"); if (File.Exists(user_config)) @@ -566,7 +571,7 @@ namespace Wabbajack.Lib /// result included into the pack /// /// - public IEnumerable MakeStack() + public override IEnumerable MakeStack() { Utils.Log("Generating compilation stack"); return new List diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs new file mode 100644 index 00000000..c1293974 --- /dev/null +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VFS; +using Wabbajack.Common; +using Wabbajack.Lib.CompilationSteps; + +namespace Wabbajack.Lib +{ + public class VortexCompiler : ACompiler + { + public string GameName { get; } + + public string VortexFolder { get; } + public string StagingFolder { get; } + public string DownloadsFolder { get; } + + public bool IgnoreMissingFiles { get; set; } + + public VortexCompiler(string gameName, string gamePath) + { + _vortexCompiler = this; + _mo2Compiler = null; + ModManager = ModManager.Vortex; + + // TODO: only for testing + IgnoreMissingFiles = true; + + GamePath = gamePath; + GameName = gameName; + + // currently only works if staging and downloads folder is in the standard directory + // aka %APPDATADA%\Vortex\ + VortexFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Vortex"); + StagingFolder = Path.Combine(VortexFolder, gameName, "mods"); + DownloadsFolder = Path.Combine(VortexFolder, "downloads", gameName); + + ModListOutputFolder = "output_folder"; + + // TODO: add custom modlist name + ModListOutputFile = $"VORTEX_TEST_MODLIST{ExtensionManager.Extension}"; + + VFS = VirtualFileSystem.VFS; + + SelectedArchives = new List(); + AllFiles = new List(); + IndexedArchives = new List(); + IndexedFiles = new Dictionary>(); + } + + public override void Info(string msg) + { + Utils.Log(msg); + } + + public override void Status(string msg) + { + WorkQueue.Report(msg, 0); + } + + public override void Error(string msg) + { + Utils.Log(msg); + throw new Exception(msg); + } + + internal override string IncludeFile(byte[] data) + { + var id = Guid.NewGuid().ToString(); + File.WriteAllBytes(Path.Combine(ModListOutputFolder, id), data); + return id; + } + + internal override string IncludeFile(string data) + { + var id = Guid.NewGuid().ToString(); + File.WriteAllText(Path.Combine(ModListOutputFolder, id), data); + return id; + } + + public override bool Compile() + { + VirtualFileSystem.Clean(); + Info($"Starting Vortex compilation for {GameName} at {GamePath} with staging folder at {StagingFolder} and downloads folder at {DownloadsFolder}."); + + Info($"Indexing {GamePath}"); + VFS.AddRoot(GamePath); + + Info($"Indexing {DownloadsFolder}"); + VFS.AddRoot(DownloadsFolder); + + Info("Cleaning output folder"); + if (Directory.Exists(ModListOutputFolder)) Directory.Delete(ModListOutputFolder, true); + Directory.CreateDirectory(ModListOutputFolder); + + IEnumerable game_files = Directory.EnumerateFiles(GamePath, "*", SearchOption.AllDirectories) + .Where(p => p.FileExists()) + .Select(p => new RawSourceFile(VFS.Lookup(p)) + { Path = Alphaleonis.Win32.Filesystem.Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)) }); + + Info("Indexing Archives"); + IndexedArchives = Directory.EnumerateFiles(DownloadsFolder) + .Where(File.Exists) + .Select(f => new IndexedArchive + { + File = VFS.Lookup(f), + Name = Path.GetFileName(f) + }) + .ToList(); + + Info("Indexing Files"); + IDictionary> grouped = VFS.GroupedByArchive(); + IndexedFiles = IndexedArchives.Select(f => grouped.TryGetValue(f.File, out var result) ? result : new List()) + .SelectMany(fs => fs) + .Concat(IndexedArchives.Select(f => f.File)) + .OrderByDescending(f => f.TopLevelArchive.LastModified) + .GroupBy(f => f.Hash) + .ToDictionary(f => f.Key, f => f.AsEnumerable()); + + Info("Searching for mod files"); + AllFiles = game_files.DistinctBy(f => f.Path).ToList(); + + Info($"Found {AllFiles.Count} files to build into mod list"); + + Info("Verifying destinations"); + List> 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"); + } + + IEnumerable stack = MakeStack(); + + Info("Running Compilation Stack"); + List results = AllFiles.PMap(f => RunStack(stack, f)).ToList(); + + IEnumerable noMatch = results.OfType().ToList(); + Info($"No match for {noMatch.Count()} files"); + foreach (var file in noMatch) + Info($" {file.To}"); + if (noMatch.Any()) + { + if (IgnoreMissingFiles) + { + Info("Continuing even though files were missing at the request of the user."); + } + else + { + Info("Exiting due to no way to compile these files"); + return false; + } + } + + InstallDirectives = results.Where(i => !(i is IgnoredDirectly)).ToList(); + + // TODO: nexus stuff + /*Info("Getting Nexus api_key, please click authorize if a browser window appears"); + if (IndexedArchives.Any(a => a.IniData?.General?.gameName != null)) + { + var nexusClient = new NexusApiClient(); + if (!nexusClient.IsPremium) Error($"User {nexusClient.Username} is not a premium Nexus user, so we cannot access the necessary API calls, cannot continue"); + + } + */ + + GatherArchives(); + + ModList = new ModList + { + Archives = SelectedArchives, + ModManager = ModManager.Vortex, + Directives = InstallDirectives + }; + + ExportModList(); + + Info("Done Building ModList"); + return true; + } + + private void ExportModList() + { + Utils.Log($"Exporting ModList to: {ModListOutputFolder}"); + + // using JSON for better debugging + ModList.ToJSON(Path.Combine(ModListOutputFolder, "modlist.json")); + //ModList.ToCERAS(Path.Combine(ModListOutputFolder, "modlist"), ref CerasConfig.Config); + + if(File.Exists(ModListOutputFile)) + File.Delete(ModListOutputFile); + + using (var fs = new FileStream(ModListOutputFile, FileMode.Create)) + { + using (var za = new ZipArchive(fs, ZipArchiveMode.Create)) + { + Directory.EnumerateFiles(ModListOutputFolder, "*.*") + .DoProgress("Compressing Modlist", + f => + { + var ze = za.CreateEntry(Path.GetFileName(f)); + using (var os = ze.Open()) + using (var ins = File.OpenRead(f)) + { + ins.CopyTo(os); + } + }); + } + } + Utils.Log("Removing ModList staging folder"); + Directory.Delete(ModListOutputFolder, true); + } + + private void GatherArchives() + { + Info("Building a list of archives based on the files required"); + + var shas = InstallDirectives.OfType() + .Select(a => a.ArchiveHashPath[0]) + .Distinct(); + + var archives = IndexedArchives.OrderByDescending(f => f.File.LastModified) + .GroupBy(f => f.File.Hash) + .ToDictionary(f => f.Key, f => f.First()); + + SelectedArchives = shas.PMap(sha => ResolveArchive(sha, archives)); + } + + // TODO: this whole thing + private Archive ResolveArchive(string sha, IDictionary archives) + { + if (archives.TryGetValue(sha, out var found)) + { + var result = new Archive(); + + result.Name = found.Name; + result.Hash = found.File.Hash; + result.Size = found.File.Size; + + return result; + } + + Error($"No match found for Archive sha: {sha} this shouldn't happen"); + return null; + } + + public override Directive RunStack(IEnumerable stack, RawSourceFile source) + { + Utils.Status($"Compiling {source.Path}"); + foreach (var step in stack) + { + var result = step.Run(source); + if (result != null) return result; + } + + throw new InvalidDataException("Data fell out of the compilation stack"); + + } + + public override IEnumerable GetStack() + { + var userConfig = Path.Combine(VortexFolder, "compilation_stack.yml"); + if (File.Exists(userConfig)) + return Serialization.Deserialize(File.ReadAllText(userConfig), this); + + IEnumerable stack = MakeStack(); + + File.WriteAllText(Path.Combine(VortexFolder, "_current_compilation_stack.yml"), + Serialization.Serialize(stack)); + + return stack; + } + + public override IEnumerable MakeStack() + { + Utils.Log("Generating compilation stack"); + return new List + { + //new IncludePropertyFiles(this), + + new IgnoreGameFiles(this), + + new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Data")), + new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Papyrus Compiler")), + new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Skyrim")), + new IgnoreRegex(this, Consts.GameFolderFilesDir + "\\\\.*\\.bsa"), + + new DirectMatch(this), + + new IgnoreGameFiles(this), + + new IgnoreWabbajackInstallCruft(this), + + new DropAll(this) + }; + } + } +} diff --git a/Wabbajack.Lib/Wabbajack.Lib.csproj b/Wabbajack.Lib/Wabbajack.Lib.csproj index 36c710cc..4620a8ff 100644 --- a/Wabbajack.Lib/Wabbajack.Lib.csproj +++ b/Wabbajack.Lib/Wabbajack.Lib.csproj @@ -77,6 +77,7 @@ + @@ -131,6 +132,7 @@ + WebAutomationWindow.xaml From 917a9e296c237c061140c221a86dfa33774e54aa Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 3 Nov 2019 17:44:49 +0100 Subject: [PATCH 04/72] Updated ACompilationStep and IStackStep to use new ACompiler --- Wabbajack.Lib/CompilationSteps/ACompilationStep.cs | 4 ++-- Wabbajack.Lib/CompilationSteps/IStackStep.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Wabbajack.Lib/CompilationSteps/ACompilationStep.cs b/Wabbajack.Lib/CompilationSteps/ACompilationStep.cs index a27e41ed..257e41fb 100644 --- a/Wabbajack.Lib/CompilationSteps/ACompilationStep.cs +++ b/Wabbajack.Lib/CompilationSteps/ACompilationStep.cs @@ -2,9 +2,9 @@ { public abstract class ACompilationStep : ICompilationStep { - protected Compiler _compiler; + protected ACompiler _compiler; - public ACompilationStep(Compiler compiler) + public ACompilationStep(ACompiler compiler) { _compiler = compiler; } diff --git a/Wabbajack.Lib/CompilationSteps/IStackStep.cs b/Wabbajack.Lib/CompilationSteps/IStackStep.cs index 9ea53d4c..107bab97 100644 --- a/Wabbajack.Lib/CompilationSteps/IStackStep.cs +++ b/Wabbajack.Lib/CompilationSteps/IStackStep.cs @@ -8,6 +8,6 @@ public interface IState { - ICompilationStep CreateStep(Compiler compiler); + ICompilationStep CreateStep(ACompiler compiler); } } \ No newline at end of file From 8eb2f34faae31e3fe4f5379b390e421115b39757 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 3 Nov 2019 17:45:49 +0100 Subject: [PATCH 05/72] Updated all CompilationSteps to use the new ACompiler --- .../CompilationSteps/DeconstructBSAs.cs | 22 +++++++++---------- Wabbajack.Lib/CompilationSteps/DirectMatch.cs | 4 ++-- Wabbajack.Lib/CompilationSteps/DropAll.cs | 4 ++-- .../CompilationSteps/IgnoreDisabledMods.cs | 10 ++++----- .../CompilationSteps/IgnoreEndsWith.cs | 4 ++-- .../CompilationSteps/IgnoreGameFiles.cs | 4 ++-- .../CompilationSteps/IgnorePathContains.cs | 4 ++-- Wabbajack.Lib/CompilationSteps/IgnoreRegex.cs | 4 ++-- .../CompilationSteps/IgnoreStartsWith.cs | 4 ++-- .../IgnoreWabbajackInstallCruft.cs | 4 ++-- Wabbajack.Lib/CompilationSteps/IncludeAll.cs | 4 ++-- .../CompilationSteps/IncludeAllConfigs.cs | 4 ++-- .../CompilationSteps/IncludeDummyESPs.cs | 4 ++-- .../CompilationSteps/IncludeLOOTFiles.cs | 4 ++-- .../CompilationSteps/IncludeModIniData.cs | 4 ++-- .../CompilationSteps/IncludeOtherProfiles.cs | 6 ++--- .../CompilationSteps/IncludePatches.cs | 4 ++-- .../CompilationSteps/IncludePropertyFiles.cs | 12 +++++----- .../CompilationSteps/IncludeRegex.cs | 4 ++-- .../IncludeStubbedConfigfiles.cs | 16 +++++++------- .../CompilationSteps/IncludeTaggedMods.cs | 6 ++--- .../CompilationSteps/IncludeThisProfile.cs | 6 ++--- .../CompilationSteps/PatchStockESMs.cs | 4 ++-- .../CompilationSteps/Serialization.cs | 2 +- 24 files changed, 72 insertions(+), 72 deletions(-) diff --git a/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs b/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs index bc8a8e03..142fd413 100644 --- a/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs +++ b/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs @@ -14,9 +14,9 @@ namespace Wabbajack.Lib.CompilationSteps private readonly List _microstack; private readonly List _microstackWithInclude; - public DeconstructBSAs(Compiler compiler) : base(compiler) + public DeconstructBSAs(ACompiler compiler) : base(compiler) { - _include_directly = _compiler.ModInis.Where(kv => + _include_directly = compiler._mo2Compiler.ModInis.Where(kv => { var general = kv.Value.General; if (general.notes != null && general.notes.Contains(Consts.WABBAJACK_INCLUDE)) return true; @@ -28,16 +28,16 @@ namespace Wabbajack.Lib.CompilationSteps _microstack = new List { - new DirectMatch(_compiler), - new IncludePatches(_compiler), - new DropAll(_compiler) + new DirectMatch(compiler), + new IncludePatches(compiler._mo2Compiler), + new DropAll(compiler) }; _microstackWithInclude = new List { - new DirectMatch(_compiler), - new IncludePatches(_compiler), - new IncludeAll(_compiler) + new DirectMatch(compiler), + new IncludePatches(compiler._mo2Compiler), + new IncludeAll(compiler._mo2Compiler) }; } @@ -61,7 +61,7 @@ namespace Wabbajack.Lib.CompilationSteps var id = Guid.NewGuid().ToString(); - var matches = source_files.PMap(e => Compiler.RunStack(stack, new RawSourceFile(e) + var matches = source_files.PMap(e => _compiler.RunStack(stack, new RawSourceFile(e) { Path = Path.Combine(Consts.BSACreationDir, id, e.Paths.Last()) })); @@ -71,7 +71,7 @@ namespace Wabbajack.Lib.CompilationSteps { if (match is IgnoredDirectly) Utils.Error($"File required for BSA {source.Path} creation doesn't exist: {match.To}"); - _compiler.ExtraFiles.Add(match); + _compiler._mo2Compiler.ExtraFiles.Add(match); } CreateBSA directive; @@ -92,7 +92,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("DeconstructBSAs")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new DeconstructBSAs(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/DirectMatch.cs b/Wabbajack.Lib/CompilationSteps/DirectMatch.cs index 0b840082..289625f6 100644 --- a/Wabbajack.Lib/CompilationSteps/DirectMatch.cs +++ b/Wabbajack.Lib/CompilationSteps/DirectMatch.cs @@ -6,7 +6,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class DirectMatch : ACompilationStep { - public DirectMatch(Compiler compiler) : base(compiler) + public DirectMatch(ACompiler compiler) : base(compiler) { } @@ -34,7 +34,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("DirectMatch")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new DirectMatch(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/DropAll.cs b/Wabbajack.Lib/CompilationSteps/DropAll.cs index d818be90..33ed357f 100644 --- a/Wabbajack.Lib/CompilationSteps/DropAll.cs +++ b/Wabbajack.Lib/CompilationSteps/DropAll.cs @@ -5,7 +5,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class DropAll : ACompilationStep { - public DropAll(Compiler compiler) : base(compiler) + public DropAll(ACompiler compiler) : base(compiler) { } @@ -25,7 +25,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("DropAll")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new DropAll(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs b/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs index bea34d6d..c7513665 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs @@ -10,12 +10,12 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly IEnumerable _allEnabledMods; - public IgnoreDisabledMods(Compiler compiler) : base(compiler) + public IgnoreDisabledMods(ACompiler compiler) : base(compiler) { - var alwaysEnabled = _compiler.ModInis.Where(f => IsAlwaysEnabled(f.Value)).Select(f => f.Key).ToHashSet(); + var alwaysEnabled = compiler._mo2Compiler.ModInis.Where(f => IsAlwaysEnabled(f.Value)).Select(f => f.Key).ToHashSet(); - _allEnabledMods = _compiler.SelectedProfiles - .SelectMany(p => File.ReadAllLines(Path.Combine(_compiler.MO2Folder, "profiles", p, "modlist.txt"))) + _allEnabledMods = compiler._mo2Compiler.SelectedProfiles + .SelectMany(p => File.ReadAllLines(Path.Combine(compiler._mo2Compiler.MO2Folder, "profiles", p, "modlist.txt"))) .Where(line => line.StartsWith("+") || line.EndsWith("_separator")) .Select(line => line.Substring(1)) .Concat(alwaysEnabled) @@ -55,7 +55,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IgnoreDisabledMods")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreDisabledMods(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreEndsWith.cs b/Wabbajack.Lib/CompilationSteps/IgnoreEndsWith.cs index 501c4b8c..966d019d 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreEndsWith.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreEndsWith.cs @@ -7,7 +7,7 @@ namespace Wabbajack.Lib.CompilationSteps private readonly string _postfix; private readonly string _reason; - public IgnoreEndsWith(Compiler compiler, string postfix) : base(compiler) + public IgnoreEndsWith(ACompiler compiler, string postfix) : base(compiler) { _postfix = postfix; _reason = $"Ignored because path ends with {postfix}"; @@ -40,7 +40,7 @@ namespace Wabbajack.Lib.CompilationSteps public string Postfix { get; set; } - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreEndsWith(compiler, Postfix); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreGameFiles.cs b/Wabbajack.Lib/CompilationSteps/IgnoreGameFiles.cs index 829403fe..26e25db6 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreGameFiles.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreGameFiles.cs @@ -7,7 +7,7 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly string _startDir; - public IgnoreGameFiles(Compiler compiler) : base(compiler) + public IgnoreGameFiles(ACompiler compiler) : base(compiler) { _startDir = Consts.GameFolderFilesDir + "\\"; } @@ -28,7 +28,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IgnoreGameFiles")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreGameFiles(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnorePathContains.cs b/Wabbajack.Lib/CompilationSteps/IgnorePathContains.cs index ac34717a..9b37faca 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnorePathContains.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnorePathContains.cs @@ -7,7 +7,7 @@ namespace Wabbajack.Lib.CompilationSteps private readonly string _pattern; private readonly string _reason; - public IgnorePathContains(Compiler compiler, string pattern) : base(compiler) + public IgnorePathContains(ACompiler compiler, string pattern) : base(compiler) { _pattern = $"\\{pattern.Trim('\\')}\\"; _reason = $"Ignored because path contains {_pattern}"; @@ -40,7 +40,7 @@ namespace Wabbajack.Lib.CompilationSteps public string Pattern { get; set; } - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnorePathContains(compiler, Pattern); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreRegex.cs b/Wabbajack.Lib/CompilationSteps/IgnoreRegex.cs index 04d76386..8c4bf0f0 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreRegex.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreRegex.cs @@ -9,7 +9,7 @@ namespace Wabbajack.Lib.CompilationSteps private readonly Regex _regex; private readonly string _pattern; - public IgnoreRegex(Compiler compiler, string pattern) : base(compiler) + public IgnoreRegex(ACompiler compiler, string pattern) : base(compiler) { _pattern = pattern; _reason = $"Ignored because path matches regex {pattern}"; @@ -43,7 +43,7 @@ namespace Wabbajack.Lib.CompilationSteps public string Pattern { get; set; } - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreRegex(compiler, Pattern); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreStartsWith.cs b/Wabbajack.Lib/CompilationSteps/IgnoreStartsWith.cs index a551627f..61070bc1 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreStartsWith.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreStartsWith.cs @@ -7,7 +7,7 @@ namespace Wabbajack.Lib.CompilationSteps private readonly string _prefix; private readonly string _reason; - public IgnoreStartsWith(Compiler compiler, string prefix) : base(compiler) + public IgnoreStartsWith(ACompiler compiler, string prefix) : base(compiler) { _prefix = prefix; _reason = string.Format("Ignored because path starts with {0}", _prefix); @@ -44,7 +44,7 @@ namespace Wabbajack.Lib.CompilationSteps public string Prefix { get; set; } - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreStartsWith(compiler, Prefix); } diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreWabbajackInstallCruft.cs b/Wabbajack.Lib/CompilationSteps/IgnoreWabbajackInstallCruft.cs index 73cb13dc..d772f179 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreWabbajackInstallCruft.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreWabbajackInstallCruft.cs @@ -9,7 +9,7 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly HashSet _cruftFiles; - public IgnoreWabbajackInstallCruft(Compiler compiler) : base(compiler) + public IgnoreWabbajackInstallCruft(ACompiler compiler) : base(compiler) { _cruftFiles = new HashSet { @@ -34,7 +34,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IgnoreWabbajackInstallCruft")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreWabbajackInstallCruft(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeAll.cs b/Wabbajack.Lib/CompilationSteps/IncludeAll.cs index 8903d448..980ad796 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeAll.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeAll.cs @@ -5,7 +5,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IncludeAll : ACompilationStep { - public IncludeAll(Compiler compiler) : base(compiler) + public IncludeAll(ACompiler compiler) : base(compiler) { } @@ -24,7 +24,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeAll")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeAll(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeAllConfigs.cs b/Wabbajack.Lib/CompilationSteps/IncludeAllConfigs.cs index 1f669666..41fe7adb 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeAllConfigs.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeAllConfigs.cs @@ -6,7 +6,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IncludeAllConfigs : ACompilationStep { - public IncludeAllConfigs(Compiler compiler) : base(compiler) + public IncludeAllConfigs(ACompiler compiler) : base(compiler) { } @@ -26,7 +26,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeAllConfigs")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeAllConfigs(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeDummyESPs.cs b/Wabbajack.Lib/CompilationSteps/IncludeDummyESPs.cs index 63b0c1e8..d8fa4d0c 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeDummyESPs.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeDummyESPs.cs @@ -5,7 +5,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IncludeDummyESPs : ACompilationStep { - public IncludeDummyESPs(Compiler compiler) : base(compiler) + public IncludeDummyESPs(ACompiler compiler) : base(compiler) { } @@ -36,7 +36,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeDummyESPs")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeDummyESPs(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeLOOTFiles.cs b/Wabbajack.Lib/CompilationSteps/IncludeLOOTFiles.cs index 567af7f1..342ed413 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeLOOTFiles.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeLOOTFiles.cs @@ -8,7 +8,7 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly string _prefix; - public IncludeLootFiles(Compiler compiler) : base(compiler) + public IncludeLootFiles(ACompiler compiler) : base(compiler) { _prefix = Consts.LOOTFolderFilesDir + "\\"; } @@ -29,7 +29,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeLootFiles")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeLootFiles(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeModIniData.cs b/Wabbajack.Lib/CompilationSteps/IncludeModIniData.cs index 101205ed..c9dbc4b3 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeModIniData.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeModIniData.cs @@ -5,7 +5,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IncludeModIniData : ACompilationStep { - public IncludeModIniData(Compiler compiler) : base(compiler) + public IncludeModIniData(ACompiler compiler) : base(compiler) { } @@ -25,7 +25,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeModIniData")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeModIniData(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeOtherProfiles.cs b/Wabbajack.Lib/CompilationSteps/IncludeOtherProfiles.cs index 82442db7..f9dec58c 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeOtherProfiles.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeOtherProfiles.cs @@ -9,9 +9,9 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly IEnumerable _profiles; - public IgnoreOtherProfiles(Compiler compiler) : base(compiler) + public IgnoreOtherProfiles(ACompiler compiler) : base(compiler) { - _profiles = _compiler.SelectedProfiles + _profiles = compiler._mo2Compiler.SelectedProfiles .Select(p => Path.Combine("profiles", p) + "\\") .ToList(); } @@ -33,7 +33,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IgnoreOtherProfiles")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IgnoreOtherProfiles(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludePatches.cs b/Wabbajack.Lib/CompilationSteps/IncludePatches.cs index 71c4fd44..a4a6e9c4 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludePatches.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludePatches.cs @@ -11,7 +11,7 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly Dictionary> _indexed; - public IncludePatches(Compiler compiler) : base(compiler) + public IncludePatches(ACompiler compiler) : base(compiler) { _indexed = _compiler.IndexedFiles.Values .SelectMany(f => f) @@ -47,7 +47,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludePatches")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludePatches(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludePropertyFiles.cs b/Wabbajack.Lib/CompilationSteps/IncludePropertyFiles.cs index dfa7f607..ce7bedd9 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludePropertyFiles.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludePropertyFiles.cs @@ -7,7 +7,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IncludePropertyFiles : ACompilationStep { - public IncludePropertyFiles(Compiler compiler) : base(compiler) + public IncludePropertyFiles(ACompiler compiler) : base(compiler) { } @@ -15,23 +15,23 @@ namespace Wabbajack.Lib.CompilationSteps { var files = new HashSet { - _compiler.ModListImage, _compiler.ModListReadme + _compiler._mo2Compiler.ModListImage, _compiler._mo2Compiler.ModListReadme }; if (!files.Any(f => source.AbsolutePath.Equals(f))) return null; if (!File.Exists(source.AbsolutePath)) return null; - var isBanner = source.AbsolutePath == _compiler.ModListImage; + var isBanner = source.AbsolutePath == _compiler._mo2Compiler.ModListImage; //var isReadme = source.AbsolutePath == ModListReadme; var result = source.EvolveTo(); result.SourceDataID = _compiler.IncludeFile(File.ReadAllBytes(source.AbsolutePath)); if (isBanner) { result.Type = PropertyType.Banner; - _compiler.ModListImage = result.SourceDataID; + _compiler._mo2Compiler.ModListImage = result.SourceDataID; } else { result.Type = PropertyType.Readme; - _compiler.ModListReadme = result.SourceDataID; + _compiler._mo2Compiler.ModListReadme = result.SourceDataID; } return result; @@ -45,7 +45,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludePropertyFiles")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludePropertyFiles(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeRegex.cs b/Wabbajack.Lib/CompilationSteps/IncludeRegex.cs index e53c4875..7f806981 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeRegex.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeRegex.cs @@ -9,7 +9,7 @@ namespace Wabbajack.Lib.CompilationSteps private readonly string _pattern; private readonly Regex _regex; - public IncludeRegex(Compiler compiler, string pattern) : base(compiler) + public IncludeRegex(ACompiler compiler, string pattern) : base(compiler) { _pattern = pattern; _regex = new Regex(pattern); @@ -43,7 +43,7 @@ namespace Wabbajack.Lib.CompilationSteps public string Pattern { get; set; } - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeRegex(compiler, Pattern); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs b/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs index a5cede88..b75c5b95 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs @@ -7,7 +7,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class IncludeStubbedConfigFiles : ACompilationStep { - public IncludeStubbedConfigFiles(Compiler compiler) : base(compiler) + public IncludeStubbedConfigFiles(ACompiler compiler) : base(compiler) { } @@ -30,14 +30,14 @@ namespace Wabbajack.Lib.CompilationSteps data = data.Replace(_compiler.GamePath.Replace("\\", "\\\\"), Consts.GAME_PATH_MAGIC_DOUBLE_BACK); data = data.Replace(_compiler.GamePath.Replace("\\", "/"), Consts.GAME_PATH_MAGIC_FORWARD); - data = data.Replace(_compiler.MO2Folder, Consts.MO2_PATH_MAGIC_BACK); - data = data.Replace(_compiler.MO2Folder.Replace("\\", "\\\\"), Consts.MO2_PATH_MAGIC_DOUBLE_BACK); - data = data.Replace(_compiler.MO2Folder.Replace("\\", "/"), Consts.MO2_PATH_MAGIC_FORWARD); + data = data.Replace(_compiler._mo2Compiler.MO2Folder, Consts.MO2_PATH_MAGIC_BACK); + data = data.Replace(_compiler._mo2Compiler.MO2Folder.Replace("\\", "\\\\"), Consts.MO2_PATH_MAGIC_DOUBLE_BACK); + data = data.Replace(_compiler._mo2Compiler.MO2Folder.Replace("\\", "/"), Consts.MO2_PATH_MAGIC_FORWARD); - data = data.Replace(_compiler.MO2DownloadsFolder, Consts.DOWNLOAD_PATH_MAGIC_BACK); - data = data.Replace(_compiler.MO2DownloadsFolder.Replace("\\", "\\\\"), + data = data.Replace(_compiler._mo2Compiler.MO2DownloadsFolder, Consts.DOWNLOAD_PATH_MAGIC_BACK); + data = data.Replace(_compiler._mo2Compiler.MO2DownloadsFolder.Replace("\\", "\\\\"), Consts.DOWNLOAD_PATH_MAGIC_DOUBLE_BACK); - data = data.Replace(_compiler.MO2DownloadsFolder.Replace("\\", "/"), Consts.DOWNLOAD_PATH_MAGIC_FORWARD); + data = data.Replace(_compiler._mo2Compiler.MO2DownloadsFolder.Replace("\\", "/"), Consts.DOWNLOAD_PATH_MAGIC_FORWARD); if (data == originalData) return null; @@ -49,7 +49,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeStubbedConfigFiles")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeStubbedConfigFiles(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs b/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs index ea1a8cd6..f6304f56 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs @@ -11,10 +11,10 @@ namespace Wabbajack.Lib.CompilationSteps private readonly string _tag; - public IncludeTaggedMods(Compiler compiler, string tag) : base(compiler) + public IncludeTaggedMods(ACompiler compiler, string tag) : base(compiler) { _tag = tag; - _includeDirectly = _compiler.ModInis.Where(kv => + _includeDirectly = compiler._mo2Compiler.ModInis.Where(kv => { var general = kv.Value.General; if (general.notes != null && general.notes.Contains(_tag)) @@ -56,7 +56,7 @@ namespace Wabbajack.Lib.CompilationSteps public string Tag { get; set; } - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeTaggedMods(compiler, Tag); } diff --git a/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs b/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs index d1c97e39..f5ca2515 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs @@ -10,9 +10,9 @@ namespace Wabbajack.Lib.CompilationSteps { private readonly IEnumerable _correctProfiles; - public IncludeThisProfile(Compiler compiler) : base(compiler) + public IncludeThisProfile(ACompiler compiler) : base(compiler) { - _correctProfiles = _compiler.SelectedProfiles.Select(p => Path.Combine("profiles", p) + "\\").ToList(); + _correctProfiles = compiler._mo2Compiler.SelectedProfiles.Select(p => Path.Combine("profiles", p) + "\\").ToList(); } public override Directive Run(RawSourceFile source) @@ -48,7 +48,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("IncludeThisProfile")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeThisProfile(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/PatchStockESMs.cs b/Wabbajack.Lib/CompilationSteps/PatchStockESMs.cs index 521ff6d4..58338899 100644 --- a/Wabbajack.Lib/CompilationSteps/PatchStockESMs.cs +++ b/Wabbajack.Lib/CompilationSteps/PatchStockESMs.cs @@ -8,7 +8,7 @@ namespace Wabbajack.Lib.CompilationSteps { public class PatchStockESMs : ACompilationStep { - public PatchStockESMs(Compiler compiler) : base(compiler) + public PatchStockESMs(ACompiler compiler) : base(compiler) { } @@ -44,7 +44,7 @@ namespace Wabbajack.Lib.CompilationSteps [JsonObject("PatchStockESMs")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new PatchStockESMs(compiler); } diff --git a/Wabbajack.Lib/CompilationSteps/Serialization.cs b/Wabbajack.Lib/CompilationSteps/Serialization.cs index e601cf5d..2aff7668 100644 --- a/Wabbajack.Lib/CompilationSteps/Serialization.cs +++ b/Wabbajack.Lib/CompilationSteps/Serialization.cs @@ -13,7 +13,7 @@ namespace Wabbajack.Lib.CompilationSteps .ToJSON(TypeNameHandling.Auto, TypeNameAssemblyFormatHandling.Simple); } - public static List Deserialize(string stack, Compiler compiler) + public static List Deserialize(string stack, ACompiler compiler) { return stack.FromJSONString>(TypeNameHandling.Auto, TypeNameAssemblyFormatHandling.Simple) .Select(s => s.CreateStep(compiler)).ToList(); From 45ba7d4bce2212b123f1dbe21164cac9d55b8ea4 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 3 Nov 2019 17:46:26 +0100 Subject: [PATCH 06/72] Updated zEditIntegration to use the new ACompiler --- Wabbajack.Lib/zEditIntegration.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Wabbajack.Lib/zEditIntegration.cs b/Wabbajack.Lib/zEditIntegration.cs index fa1216ee..d8560cd2 100644 --- a/Wabbajack.Lib/zEditIntegration.cs +++ b/Wabbajack.Lib/zEditIntegration.cs @@ -14,9 +14,9 @@ namespace Wabbajack.Lib { public class zEditIntegration { - public static string FindzEditPath(Compiler compiler) + public static string FindzEditPath(ACompiler compiler) { - var executables = compiler.MO2Ini.customExecutables; + var executables = compiler._mo2Compiler.MO2Ini.customExecutables; if (executables.size == null) return null; foreach (var idx in Enumerable.Range(1, int.Parse(executables.size))) @@ -35,7 +35,7 @@ namespace Wabbajack.Lib { private Dictionary _mergesIndexed; - public IncludeZEditPatches(Compiler compiler) : base(compiler) + public IncludeZEditPatches(ACompiler compiler) : base(compiler) { var zEditPath = FindzEditPath(compiler); var havezEdit = zEditPath != null; @@ -63,7 +63,7 @@ namespace Wabbajack.Lib _mergesIndexed = merges.ToDictionary( - m => Path.Combine(compiler.MO2Folder, "mods", m.Key.name, m.Key.filename), + m => Path.Combine(compiler._mo2Compiler.MO2Folder, "mods", m.Key.name, m.Key.filename), m => m.First()); } @@ -89,12 +89,12 @@ namespace Wabbajack.Lib return new SourcePatch { - RelativePath = abs_path.RelativeTo(_compiler.MO2Folder), + RelativePath = abs_path.RelativeTo(_compiler._mo2Compiler.MO2Folder), Hash = _compiler.VFS[abs_path].Hash }; }).ToList(); - var src_data = result.Sources.Select(f => File.ReadAllBytes(Path.Combine(_compiler.MO2Folder, f.RelativePath))) + var src_data = result.Sources.Select(f => File.ReadAllBytes(Path.Combine(_compiler._mo2Compiler.MO2Folder, f.RelativePath))) .ConcatArrays(); var dst_data = File.ReadAllBytes(source.AbsolutePath); @@ -117,7 +117,7 @@ namespace Wabbajack.Lib [JsonObject("IncludeZEditPatches")] public class State : IState { - public ICompilationStep CreateStep(Compiler compiler) + public ICompilationStep CreateStep(ACompiler compiler) { return new IncludeZEditPatches(compiler); } From 8d650fcbd93d11a2100a1207e602f7f2230b151d Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 13:30:02 +0100 Subject: [PATCH 07/72] Fixed some stuff --- Wabbajack.Lib/VortexCompiler.cs | 26 ++++---- Wabbajack/View Models/CompilerVM.cs | 94 ++++++++++++++++++----------- 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index c1293974..8042a6e3 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -100,15 +100,18 @@ namespace Wabbajack.Lib IEnumerable game_files = Directory.EnumerateFiles(GamePath, "*", SearchOption.AllDirectories) .Where(p => p.FileExists()) .Select(p => new RawSourceFile(VFS.Lookup(p)) - { Path = Alphaleonis.Win32.Filesystem.Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)) }); + { Path = Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)) }); Info("Indexing Archives"); IndexedArchives = Directory.EnumerateFiles(DownloadsFolder) + //.Where(f => File.Exists(f+".meta")) .Where(File.Exists) .Select(f => new IndexedArchive { File = VFS.Lookup(f), - Name = Path.GetFileName(f) + Name = Path.GetFileName(f), + //IniData = (f+"meta").LoadIniFile(), + //Meta = File.ReadAllText(f+".meta") }) .ToList(); @@ -131,7 +134,7 @@ namespace Wabbajack.Lib .Where(fs => fs.Count() > 1) .Select(fs => { - Utils.Log($"Duplicate files installed to {fs.Key} from : {String.Join(", ", fs.Select(f => f.AbsolutePath))}"); + Utils.Log($"Duplicate files installed to {fs.Key} from : {string.Join(", ", fs.Select(f => f.AbsolutePath))}"); return fs; }).ToList(); @@ -205,7 +208,7 @@ namespace Wabbajack.Lib using (var za = new ZipArchive(fs, ZipArchiveMode.Create)) { Directory.EnumerateFiles(ModListOutputFolder, "*.*") - .DoProgress("Compressing Modlist", + .DoProgress("Compressing ModList", f => { var ze = za.CreateEntry(Path.GetFileName(f)); @@ -218,7 +221,7 @@ namespace Wabbajack.Lib } } Utils.Log("Removing ModList staging folder"); - Directory.Delete(ModListOutputFolder, true); + //Directory.Delete(ModListOutputFolder, true); } private void GatherArchives() @@ -288,12 +291,13 @@ namespace Wabbajack.Lib { //new IncludePropertyFiles(this), - new IgnoreGameFiles(this), - - new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Data")), - new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Papyrus Compiler")), - new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Skyrim")), - new IgnoreRegex(this, Consts.GameFolderFilesDir + "\\\\.*\\.bsa"), + new IgnoreGameFiles(this), + new IncludeRegex(this, @".*\.zip?$"), + //new IncludeRegex(this, "*.zip"), + //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Data")), + //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Papyrus Compiler")), + //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Skyrim")), + //new IgnoreRegex(this, Consts.GameFolderFilesDir + "\\\\.*\\.bsa"), new DirectMatch(this), diff --git a/Wabbajack/View Models/CompilerVM.cs b/Wabbajack/View Models/CompilerVM.cs index 3362eb0b..b58c4d18 100644 --- a/Wabbajack/View Models/CompilerVM.cs +++ b/Wabbajack/View Models/CompilerVM.cs @@ -196,47 +196,71 @@ namespace Wabbajack private async Task ExecuteBegin() { - Compiler compiler; - try + if (true) { - compiler = new Compiler(this.Mo2Folder) + var compiler = new VortexCompiler("darkestdungeon", "S:\\SteamLibrary\\steamapps\\common\\DarkestDungeon"); + await Task.Run(() => { - MO2Profile = this.MOProfile, - ModListName = this.ModListName, - ModListAuthor = this.AuthorText, - ModListDescription = this.Description, - ModListImage = this.ImagePath.TargetPath, - ModListWebsite = this.Website, - ModListReadme = this.ReadMeText.TargetPath, - }; - } - catch (Exception ex) - { - while (ex.InnerException != null) ex = ex.InnerException; - Utils.Log($"Compiler error: {ex.ExceptionToString()}"); - return; - } - await Task.Run(() => - { - Compiling = true; - try - { - compiler.Compile(); - if (compiler.ModList?.ReportHTML != null) + UIReady = false; + try { - this.HTMLReport = compiler.ModList.ReportHTML; + compiler.Compile(); } - } - catch (Exception ex) + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + this.Log().Warn(ex, "Can't continue"); + } + finally + { + UIReady = true; + } + }); + }else{ + if (this.Mo2Folder != null) { - while (ex.InnerException != null) ex = ex.InnerException; - Utils.Log($"Compiler error: {ex.ExceptionToString()}"); + Compiler compiler; + try { + compiler = new Compiler(this.Mo2Folder) + { + MO2Profile = this.MOProfile, + ModListName = this.ModListName, + ModListAuthor = this.AuthorText, + ModListDescription = this.Description, + ModListImage = this.ImagePath.TargetPath, + ModListWebsite = this.Website, + ModListReadme = this.ReadMeText.TargetPath, + }; + } + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + Utils.Log($"Compiler error: {ex.ExceptionToString()}"); + return; + } + await Task.Run(() => + { + Compiling = true; + try + { + compiler.Compile(); + if (compiler.ModList?.ReportHTML != null) + { + this.HTMLReport = compiler.ModList.ReportHTML; + } + } + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + Utils.Log($"Compiler error: {ex.ExceptionToString()}"); + } + finally + { + Compiling = false; + } + }); } - finally - { - Compiling = false; - } - }); + } } } } From bd3d7531389a94f07f3509599307b9957797f1a7 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 13:47:41 +0100 Subject: [PATCH 08/72] Created IncludeVortexDeployment Compilation Step --- .../IncludeVortexDeployment.cs | 38 +++++++++++++++++++ Wabbajack.Lib/VortexCompiler.cs | 7 ++-- Wabbajack.Lib/Wabbajack.Lib.csproj | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs diff --git a/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs b/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs new file mode 100644 index 00000000..249edf66 --- /dev/null +++ b/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Wabbajack.Lib.CompilationSteps +{ + public class IncludeVortexDeployment : ACompilationStep + { + public IncludeVortexDeployment(ACompiler compiler) : base(compiler) + { + } + + public override Directive Run(RawSourceFile source) + { + if (!source.Path.EndsWith("\\vortex.deployment.msgpack") && + !source.Path.EndsWith("\\vortex.deployment.json")) return null; + var inline = source.EvolveTo(); + inline.SourceDataID = _compiler.IncludeFile(File.ReadAllBytes(source.AbsolutePath)); + return inline; + } + + public override IState GetState() + { + return new State(); + } + + public class State : IState + { + public ICompilationStep CreateStep(ACompiler compiler) + { + return new IncludeVortexDeployment(compiler); + } + } + } +} diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 8042a6e3..667e36b3 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -290,15 +290,16 @@ namespace Wabbajack.Lib return new List { //new IncludePropertyFiles(this), - - new IgnoreGameFiles(this), - new IncludeRegex(this, @".*\.zip?$"), + //new IncludeRegex(this, "^.*\\.zip"), + new IncludeVortexDeployment(this), //new IncludeRegex(this, "*.zip"), //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Data")), //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Papyrus Compiler")), //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Skyrim")), //new IgnoreRegex(this, Consts.GameFolderFilesDir + "\\\\.*\\.bsa"), + new IgnoreGameFiles(this), + new DirectMatch(this), new IgnoreGameFiles(this), diff --git a/Wabbajack.Lib/Wabbajack.Lib.csproj b/Wabbajack.Lib/Wabbajack.Lib.csproj index 4620a8ff..c5248d75 100644 --- a/Wabbajack.Lib/Wabbajack.Lib.csproj +++ b/Wabbajack.Lib/Wabbajack.Lib.csproj @@ -102,6 +102,7 @@ + From f3b7b44d246df9e204e2f1891f1762d46b553a53 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 13:53:02 +0100 Subject: [PATCH 09/72] Fixed bad comment --- Wabbajack.Lib/Data.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Wabbajack.Lib/Data.cs b/Wabbajack.Lib/Data.cs index 01720eb0..7366ba19 100644 --- a/Wabbajack.Lib/Data.cs +++ b/Wabbajack.Lib/Data.cs @@ -209,6 +209,7 @@ namespace Wabbajack.Lib /// public string Hash; + /// /// Meta INI for the downloaded archive /// public string Meta; From 1c9f96025214b37e86486e749f3c5c294743f6f6 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 15:32:28 +0100 Subject: [PATCH 10/72] Created NexusFile class --- Wabbajack.Lib/NexusApi/Dtos.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Wabbajack.Lib/NexusApi/Dtos.cs b/Wabbajack.Lib/NexusApi/Dtos.cs index d1f66a82..106f5a50 100644 --- a/Wabbajack.Lib/NexusApi/Dtos.cs +++ b/Wabbajack.Lib/NexusApi/Dtos.cs @@ -46,6 +46,18 @@ namespace Wabbajack.Lib.NexusApi public bool contains_adult_content; } + public class NexusFile + { + public ulong file_id; + public string name; + public string version; + public string file_name; + public string description; + public string mod_version; + public ulong category_id; + public string category_name; + } + public class EndorsementResponse { public string message; From 609c5d309b2518029c1a0b5b36b79207746c8f80 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 15:32:57 +0100 Subject: [PATCH 11/72] Game name will not be converted if it already is --- Wabbajack.Lib/NexusApi/NexusApiUtils.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Lib/NexusApi/NexusApiUtils.cs b/Wabbajack.Lib/NexusApi/NexusApiUtils.cs index 3446f39c..29915564 100644 --- a/Wabbajack.Lib/NexusApi/NexusApiUtils.cs +++ b/Wabbajack.Lib/NexusApi/NexusApiUtils.cs @@ -1,4 +1,5 @@ -using Wabbajack.Common; +using System.Text.RegularExpressions; +using Wabbajack.Common; namespace Wabbajack.Lib.NexusApi { @@ -6,6 +7,8 @@ namespace Wabbajack.Lib.NexusApi { public static string ConvertGameName(string gameName) { + if (Regex.IsMatch(gameName, @"^[^a-z\s]+\.[^a-z\s]+$")) + return gameName; return GameRegistry.GetByMO2ArchiveName(gameName)?.NexusName ?? gameName.ToLower(); } From 68f800e783aa7068f9c72949a0688e6d8067d931 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 15:33:17 +0100 Subject: [PATCH 12/72] Created GetModFiles NexusApi function --- Wabbajack.Lib/NexusApi/NexusApi.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Wabbajack.Lib/NexusApi/NexusApi.cs b/Wabbajack.Lib/NexusApi/NexusApi.cs index b5e7967e..ef067954 100644 --- a/Wabbajack.Lib/NexusApi/NexusApi.cs +++ b/Wabbajack.Lib/NexusApi/NexusApi.cs @@ -222,7 +222,6 @@ namespace Wabbajack.Lib.NexusApi } - public string GetNexusDownloadLink(NexusDownloader.State archive, bool cache = false) { if (cache && TryGetCachedLink(archive, out var result)) @@ -269,7 +268,13 @@ namespace Wabbajack.Lib.NexusApi return GetCached(url).files; } - public ModInfo GetModInfo(Game game, string modId) + public List GetModFiles(string gameName, string modID) + { + var url = $"https://api.nexusmods.com/v1/games/{gameName}/mods/{modID}/files.json"; + return Get>(url); + } + + public ModInfo GetModInfo(string gameName, string modId) { var url = $"https://api.nexusmods.com/v1/games/{GameRegistry.Games[game].NexusName}/mods/{modId}.json"; return GetCached(url); From 1041f1ecde17424024f79655837ce599820265dc Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 16:11:58 +0100 Subject: [PATCH 13/72] Using MD5 hash for getting mod info --- Wabbajack.Lib/NexusApi/Dtos.cs | 12 +++--------- Wabbajack.Lib/NexusApi/NexusApi.cs | 6 +++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Wabbajack.Lib/NexusApi/Dtos.cs b/Wabbajack.Lib/NexusApi/Dtos.cs index 106f5a50..bd948390 100644 --- a/Wabbajack.Lib/NexusApi/Dtos.cs +++ b/Wabbajack.Lib/NexusApi/Dtos.cs @@ -46,16 +46,10 @@ namespace Wabbajack.Lib.NexusApi public bool contains_adult_content; } - public class NexusFile + public class MD5Response { - public ulong file_id; - public string name; - public string version; - public string file_name; - public string description; - public string mod_version; - public ulong category_id; - public string category_name; + public ModInfo mod; + public NexusFileInfo file_details; } public class EndorsementResponse diff --git a/Wabbajack.Lib/NexusApi/NexusApi.cs b/Wabbajack.Lib/NexusApi/NexusApi.cs index ef067954..b8568319 100644 --- a/Wabbajack.Lib/NexusApi/NexusApi.cs +++ b/Wabbajack.Lib/NexusApi/NexusApi.cs @@ -268,10 +268,10 @@ namespace Wabbajack.Lib.NexusApi return GetCached(url).files; } - public List GetModFiles(string gameName, string modID) + public List GetModInfoFromMD5(string gameName, string md5Hash) { - var url = $"https://api.nexusmods.com/v1/games/{gameName}/mods/{modID}/files.json"; - return Get>(url); + var url = $"https://api.nexusmods.com/v1/games/{gameName}/mods/md5_search/{md5Hash}.json"; + return Get>(url); } public ModInfo GetModInfo(string gameName, string modId) From 0fa2be2c1d65808447223e129fad458c01513002 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 16:12:28 +0100 Subject: [PATCH 14/72] Fixed typo --- Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs b/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs index 249edf66..774acc50 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeVortexDeployment.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Wabbajack.Common; namespace Wabbajack.Lib.CompilationSteps { @@ -15,7 +16,7 @@ namespace Wabbajack.Lib.CompilationSteps public override Directive Run(RawSourceFile source) { - if (!source.Path.EndsWith("\\vortex.deployment.msgpack") && + if (!source.Path.EndsWith("vortex.deployment.msgpack") && !source.Path.EndsWith("\\vortex.deployment.json")) return null; var inline = source.EvolveTo(); inline.SourceDataID = _compiler.IncludeFile(File.ReadAllBytes(source.AbsolutePath)); From 3fb698789c63968aefa49516765dc2b0ccc8b4c3 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 17:04:37 +0100 Subject: [PATCH 15/72] Working VortexCompiler --- Wabbajack.Lib/VortexCompiler.cs | 90 ++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 14 deletions(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 667e36b3..b1fe6b21 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -3,11 +3,14 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using VFS; using Wabbajack.Common; using Wabbajack.Lib.CompilationSteps; +using Wabbajack.Lib.Downloaders; +using Wabbajack.Lib.NexusApi; namespace Wabbajack.Lib { @@ -44,7 +47,7 @@ namespace Wabbajack.Lib // TODO: add custom modlist name ModListOutputFile = $"VORTEX_TEST_MODLIST{ExtensionManager.Extension}"; - VFS = VirtualFileSystem.VFS; + //VFS = VirtualFileSystem.VFS; SelectedArchives = new List(); AllFiles = new List(); @@ -87,6 +90,12 @@ namespace Wabbajack.Lib VirtualFileSystem.Clean(); Info($"Starting Vortex compilation for {GameName} at {GamePath} with staging folder at {StagingFolder} and downloads folder at {DownloadsFolder}."); + Info("Starting pre-compilation steps"); + CreateMetaFiles(); + + Info($"Indexing {StagingFolder}"); + VFS.AddRoot(StagingFolder); + Info($"Indexing {GamePath}"); VFS.AddRoot(GamePath); @@ -96,22 +105,31 @@ namespace Wabbajack.Lib Info("Cleaning output folder"); if (Directory.Exists(ModListOutputFolder)) Directory.Delete(ModListOutputFolder, true); Directory.CreateDirectory(ModListOutputFolder); + + IEnumerable vortexStagingFiles = Directory.EnumerateFiles(StagingFolder, "*", SearchOption.AllDirectories) + .Where(p => p.FileExists() && p != "__vortex_staging_folder") + .Select(p => new RawSourceFile(VFS.Lookup(p)) + {Path = p.RelativeTo(StagingFolder)}); + + IEnumerable vortexDownloads = Directory.EnumerateFiles(DownloadsFolder, "*", SearchOption.AllDirectories) + .Where(p => p.FileExists()) + .Select(p => new RawSourceFile(VFS.Lookup(p)) + {Path = p.RelativeTo(DownloadsFolder)}); - IEnumerable game_files = Directory.EnumerateFiles(GamePath, "*", SearchOption.AllDirectories) + IEnumerable gameFiles = Directory.EnumerateFiles(GamePath, "*", SearchOption.AllDirectories) .Where(p => p.FileExists()) .Select(p => new RawSourceFile(VFS.Lookup(p)) { Path = Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)) }); Info("Indexing Archives"); IndexedArchives = Directory.EnumerateFiles(DownloadsFolder) - //.Where(f => File.Exists(f+".meta")) - .Where(File.Exists) + .Where(f => File.Exists(f+".meta")) .Select(f => new IndexedArchive { File = VFS.Lookup(f), Name = Path.GetFileName(f), - //IniData = (f+"meta").LoadIniFile(), - //Meta = File.ReadAllText(f+".meta") + IniData = (f+".meta").LoadIniFile(), + Meta = File.ReadAllText(f+".meta") }) .ToList(); @@ -125,7 +143,10 @@ namespace Wabbajack.Lib .ToDictionary(f => f.Key, f => f.AsEnumerable()); Info("Searching for mod files"); - AllFiles = game_files.DistinctBy(f => f.Path).ToList(); + AllFiles = vortexStagingFiles.Concat(vortexDownloads) + .Concat(gameFiles) + .DistinctBy(f => f.Path) + .ToList(); Info($"Found {AllFiles.Count} files to build into mod list"); @@ -224,6 +245,36 @@ namespace Wabbajack.Lib //Directory.Delete(ModListOutputFolder, true); } + private void CreateMetaFiles() + { + Directory.EnumerateFiles(DownloadsFolder, "*", SearchOption.TopDirectoryOnly) + .Where(f => File.Exists(f) && (Path.GetExtension(f) == ".zip" || Path.GetExtension(f) == ".rar") && !File.Exists(f+".meta")) + .Do(f => + { + var metaString = $"[General]\n" + + $"repository=Nexus\n" + + $"installed=true\n" + + $"uninstalled=false\n" + + $"paused=false\n" + + $"removed=false\n" + + $"gameName={GameName}\n"; + var nexusClient = new NexusApiClient(); + var hash = ""; + using(var md5 = MD5.Create()) + using (var stream = File.OpenRead(f)) + { + byte[] cH = md5.ComputeHash(stream); + hash = BitConverter.ToString(cH).Replace("-", "").ToLowerInvariant(); + } + + var md5Response = nexusClient.GetModInfoFromMD5(GameName, hash); + var modInfo = md5Response[0].mod; + metaString += $"modID={modInfo.mod_id}\ndescription={NexusApiUtils.FixupSummary(modInfo.summary)}\n" + + $"modName={modInfo.name}\nfileID={md5Response[0].file_details.file_id}"; + File.WriteAllText(f+".meta",metaString, Encoding.UTF8); + }); + } + private void GatherArchives() { Info("Building a list of archives based on the files required"); @@ -239,17 +290,30 @@ namespace Wabbajack.Lib SelectedArchives = shas.PMap(sha => ResolveArchive(sha, archives)); } - // TODO: this whole thing private Archive ResolveArchive(string sha, IDictionary archives) { if (archives.TryGetValue(sha, out var found)) { + if(found.IniData == null) + Error($"No download metadata found for {found.Name}, please use MO2 to query info or add a .meta file and try again."); + var result = new Archive(); + result.State = (AbstractDownloadState) DownloadDispatcher.ResolveArchive(found.IniData); + + if (result.State == null) + Error($"{found.Name} could not be handled by any of the downloaders"); result.Name = found.Name; result.Hash = found.File.Hash; + result.Meta = found.Meta; result.Size = found.File.Size; + Info($"Checking link for {found.Name}"); + + if (!result.State.Verify()) + Error( + $"Unable to resolve link for {found.Name}. If this is hosted on the Nexus the file may have been removed."); + return result; } @@ -290,13 +354,11 @@ namespace Wabbajack.Lib return new List { //new IncludePropertyFiles(this), - //new IncludeRegex(this, "^.*\\.zip"), new IncludeVortexDeployment(this), - //new IncludeRegex(this, "*.zip"), - //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Data")), - //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Papyrus Compiler")), - //new IgnoreStartsWith(this, Path.Combine(Consts.GameFolderFilesDir, "Skyrim")), - //new IgnoreRegex(this, Consts.GameFolderFilesDir + "\\\\.*\\.bsa"), + new IncludeRegex(this, "^*\\.meta"), + new IgnoreStartsWith(this, " __vortex_staging_folder"), + new IgnoreEndsWith(this, "__vortex_staging_folder"), + new IgnoreEndsWith(this, "project.xml"), new IgnoreGameFiles(this), From 22dbc7cab3ef3675c63cd82ec2fa45c3b022789f Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 17:05:01 +0100 Subject: [PATCH 16/72] Rerolled a commit --- Wabbajack.Lib/VortexCompiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index b1fe6b21..f3a4d9a9 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -47,7 +47,7 @@ namespace Wabbajack.Lib // TODO: add custom modlist name ModListOutputFile = $"VORTEX_TEST_MODLIST{ExtensionManager.Extension}"; - //VFS = VirtualFileSystem.VFS; + VFS = VirtualFileSystem.VFS; SelectedArchives = new List(); AllFiles = new List(); From 6a4600dcc13491e018998b30a6676ad9b2b46f89 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 4 Nov 2019 18:08:49 +0100 Subject: [PATCH 17/72] Only for testing: game name and location will come from command line arguments --- Wabbajack/View Models/CompilerVM.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Wabbajack/View Models/CompilerVM.cs b/Wabbajack/View Models/CompilerVM.cs index b58c4d18..a1ec8d89 100644 --- a/Wabbajack/View Models/CompilerVM.cs +++ b/Wabbajack/View Models/CompilerVM.cs @@ -198,7 +198,8 @@ namespace Wabbajack { if (true) { - var compiler = new VortexCompiler("darkestdungeon", "S:\\SteamLibrary\\steamapps\\common\\DarkestDungeon"); + string[] args = Environment.GetCommandLineArgs(); + var compiler = new VortexCompiler(args[1], args[2]); await Task.Run(() => { UIReady = false; From ece05901c26a76b6ccb85c4db68071841b13096a Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 13:48:03 +0100 Subject: [PATCH 18/72] Fixed stack compilation endless loop --- .../CompilationSteps/DeconstructBSAs.cs | 16 ++++++++-------- .../CompilationSteps/IgnoreDisabledMods.cs | 6 +++--- .../IncludeStubbedConfigfiles.cs | 6 +++--- .../CompilationSteps/IncludeTaggedMods.cs | 2 +- .../CompilationSteps/IncludeThisProfile.cs | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs b/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs index 142fd413..440b8813 100644 --- a/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs +++ b/Wabbajack.Lib/CompilationSteps/DeconstructBSAs.cs @@ -16,7 +16,7 @@ namespace Wabbajack.Lib.CompilationSteps public DeconstructBSAs(ACompiler compiler) : base(compiler) { - _include_directly = compiler._mo2Compiler.ModInis.Where(kv => + _include_directly = _compiler._mo2Compiler.ModInis.Where(kv => { var general = kv.Value.General; if (general.notes != null && general.notes.Contains(Consts.WABBAJACK_INCLUDE)) return true; @@ -28,16 +28,16 @@ namespace Wabbajack.Lib.CompilationSteps _microstack = new List { - new DirectMatch(compiler), - new IncludePatches(compiler._mo2Compiler), - new DropAll(compiler) + new DirectMatch(_compiler._mo2Compiler), + new IncludePatches(_compiler._mo2Compiler), + new DropAll(_compiler._mo2Compiler) }; _microstackWithInclude = new List { - new DirectMatch(compiler), - new IncludePatches(compiler._mo2Compiler), - new IncludeAll(compiler._mo2Compiler) + new DirectMatch(_compiler._mo2Compiler), + new IncludePatches(_compiler._mo2Compiler), + new IncludeAll(_compiler._mo2Compiler) }; } @@ -61,7 +61,7 @@ namespace Wabbajack.Lib.CompilationSteps var id = Guid.NewGuid().ToString(); - var matches = source_files.PMap(e => _compiler.RunStack(stack, new RawSourceFile(e) + var matches = source_files.PMap(e => _compiler._mo2Compiler.RunStack(stack, new RawSourceFile(e) { Path = Path.Combine(Consts.BSACreationDir, id, e.Paths.Last()) })); diff --git a/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs b/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs index c7513665..cde06c36 100644 --- a/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs +++ b/Wabbajack.Lib/CompilationSteps/IgnoreDisabledMods.cs @@ -12,10 +12,10 @@ namespace Wabbajack.Lib.CompilationSteps public IgnoreDisabledMods(ACompiler compiler) : base(compiler) { - var alwaysEnabled = compiler._mo2Compiler.ModInis.Where(f => IsAlwaysEnabled(f.Value)).Select(f => f.Key).ToHashSet(); + var alwaysEnabled = _compiler._mo2Compiler.ModInis.Where(f => IsAlwaysEnabled(f.Value)).Select(f => f.Key).ToHashSet(); - _allEnabledMods = compiler._mo2Compiler.SelectedProfiles - .SelectMany(p => File.ReadAllLines(Path.Combine(compiler._mo2Compiler.MO2Folder, "profiles", p, "modlist.txt"))) + _allEnabledMods = _compiler._mo2Compiler.SelectedProfiles + .SelectMany(p => File.ReadAllLines(Path.Combine(_compiler._mo2Compiler.MO2Folder, "profiles", p, "modlist.txt"))) .Where(line => line.StartsWith("+") || line.EndsWith("_separator")) .Select(line => line.Substring(1)) .Concat(alwaysEnabled) diff --git a/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs b/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs index b75c5b95..19019e18 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeStubbedConfigfiles.cs @@ -26,9 +26,9 @@ namespace Wabbajack.Lib.CompilationSteps var data = File.ReadAllText(source.AbsolutePath); var originalData = data; - data = data.Replace(_compiler.GamePath, Consts.GAME_PATH_MAGIC_BACK); - data = data.Replace(_compiler.GamePath.Replace("\\", "\\\\"), Consts.GAME_PATH_MAGIC_DOUBLE_BACK); - data = data.Replace(_compiler.GamePath.Replace("\\", "/"), Consts.GAME_PATH_MAGIC_FORWARD); + data = data.Replace(_compiler._mo2Compiler.GamePath, Consts.GAME_PATH_MAGIC_BACK); + data = data.Replace(_compiler._mo2Compiler.GamePath.Replace("\\", "\\\\"), Consts.GAME_PATH_MAGIC_DOUBLE_BACK); + data = data.Replace(_compiler._mo2Compiler.GamePath.Replace("\\", "/"), Consts.GAME_PATH_MAGIC_FORWARD); data = data.Replace(_compiler._mo2Compiler.MO2Folder, Consts.MO2_PATH_MAGIC_BACK); data = data.Replace(_compiler._mo2Compiler.MO2Folder.Replace("\\", "\\\\"), Consts.MO2_PATH_MAGIC_DOUBLE_BACK); diff --git a/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs b/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs index f6304f56..dbbf3242 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeTaggedMods.cs @@ -14,7 +14,7 @@ namespace Wabbajack.Lib.CompilationSteps public IncludeTaggedMods(ACompiler compiler, string tag) : base(compiler) { _tag = tag; - _includeDirectly = compiler._mo2Compiler.ModInis.Where(kv => + _includeDirectly = _compiler._mo2Compiler.ModInis.Where(kv => { var general = kv.Value.General; if (general.notes != null && general.notes.Contains(_tag)) diff --git a/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs b/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs index f5ca2515..580f64a8 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludeThisProfile.cs @@ -12,7 +12,7 @@ namespace Wabbajack.Lib.CompilationSteps public IncludeThisProfile(ACompiler compiler) : base(compiler) { - _correctProfiles = compiler._mo2Compiler.SelectedProfiles.Select(p => Path.Combine("profiles", p) + "\\").ToList(); + _correctProfiles = _compiler._mo2Compiler.SelectedProfiles.Select(p => Path.Combine("profiles", p) + "\\").ToList(); } public override Directive Run(RawSourceFile source) From 18a36437bc680eaf611281bd4e24e2e58dd36488 Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 14:03:56 +0100 Subject: [PATCH 19/72] Added supported mod manager and Darkest Dungeon --- Wabbajack.Common/GameMetaData.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index 34b3cf13..b1bbdfeb 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -11,6 +11,7 @@ using Microsoft.Win32; namespace Wabbajack.Common { public enum Game { + //MO2 GAMES Morrowind, Oblivion, Fallout3, @@ -18,11 +19,14 @@ namespace Wabbajack.Common Skyrim, SkyrimSpecialEdition, Fallout4, - SkyrimVR + SkyrimVR, + //VORTEX GAMES + DarkestDungeon } public class GameMetaData { + public ModManager SupportedModManager { get; internal set; } public string MO2ArchiveName { get; internal set; } public Game Game { get; internal set; } public string NexusName { get; internal set; } @@ -62,6 +66,7 @@ namespace Wabbajack.Common { Game.Oblivion, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.Oblivion, NexusName = "oblivion", MO2Name = "Oblivion", @@ -73,6 +78,7 @@ namespace Wabbajack.Common { Game.Fallout3, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.Fallout3, NexusName = "fallout3", MO2Name = "fallout3", @@ -83,6 +89,7 @@ namespace Wabbajack.Common { Game.FalloutNewVegas, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.FalloutNewVegas, NexusName = "newvegas", MO2Name = "New Vegas", @@ -93,6 +100,7 @@ namespace Wabbajack.Common { Game.Skyrim, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.Skyrim, NexusName = "skyrim", MO2Name = "Skyrim", @@ -103,6 +111,7 @@ namespace Wabbajack.Common { Game.SkyrimSpecialEdition, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.SkyrimSpecialEdition, NexusName = "skyrimspecialedition", MO2Name = "Skyrim Special Edition", @@ -113,6 +122,7 @@ namespace Wabbajack.Common { Game.Fallout4, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.Fallout4, NexusName = "fallout4", MO2Name = "Fallout 4", @@ -123,12 +133,21 @@ namespace Wabbajack.Common { Game.SkyrimVR, new GameMetaData { + SupportedModManager = ModManager.MO2, Game = Game.SkyrimVR, NexusName = "skyrimspecialedition", MO2Name = "Skyrim VR", MO2ArchiveName = "skyrimse", GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Skyrim VR" } + }, + { + Game.DarkestDungeon, new GameMetaData() + { + SupportedModManager = ModManager.Vortex, + Game = Game.DarkestDungeon, + NexusName = "darkestdungeon" + } } }; } From 2497d5ba888b9d578a5283ddc19d080bd6f92120 Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 14:10:42 +0100 Subject: [PATCH 20/72] Added Steam ids --- Wabbajack.Common/GameMetaData.cs | 36 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index b1bbdfeb..6bf144ef 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -32,6 +32,7 @@ namespace Wabbajack.Common public string NexusName { get; internal set; } public string MO2Name { get; internal set; } public string GameLocationRegistryKey { get; internal set; } + public List SteamIDs { get; internal set; } public string GameLocation { @@ -71,7 +72,8 @@ namespace Wabbajack.Common NexusName = "oblivion", MO2Name = "Oblivion", MO2ArchiveName = "oblivion", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Oblivion" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Oblivion", + SteamIDs = new List{22330} } }, @@ -83,7 +85,8 @@ namespace Wabbajack.Common NexusName = "fallout3", MO2Name = "fallout3", MO2ArchiveName = "fallout3", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Fallout3" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Fallout3", + SteamIDs = new List{22300, 22370} // base game and GotY } }, { @@ -94,7 +97,8 @@ namespace Wabbajack.Common NexusName = "newvegas", MO2Name = "New Vegas", MO2ArchiveName = "falloutnv", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\falloutnv" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\falloutnv", + SteamIDs = new List{22380} } }, { @@ -105,7 +109,8 @@ namespace Wabbajack.Common NexusName = "skyrim", MO2Name = "Skyrim", MO2ArchiveName = "skyrim", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\skyrim" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\skyrim", + SteamIDs = new List{72850} } }, { @@ -116,7 +121,8 @@ namespace Wabbajack.Common NexusName = "skyrimspecialedition", MO2Name = "Skyrim Special Edition", MO2ArchiveName = "skyrimse", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Skyrim Special Edition" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Skyrim Special Edition", + SteamIDs = new List{489830} } }, { @@ -127,9 +133,21 @@ namespace Wabbajack.Common NexusName = "fallout4", MO2Name = "Fallout 4", MO2ArchiveName = "fallout4", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Fallout4" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Fallout4", + SteamIDs = new List{377160} } }, + /*{ + Game.Fallout4VR, new GameMetaData + { + SupportedModManager = ModManager.MO2, + Game = Game.Fallout4VR, + NexusName = "fallout4", + MO2Name = "Fallout 4", + MO2ArchiveName = "fallout4", + SteamIDs = new List{611660} + } + },*/ { Game.SkyrimVR, new GameMetaData { @@ -138,7 +156,8 @@ namespace Wabbajack.Common NexusName = "skyrimspecialedition", MO2Name = "Skyrim VR", MO2ArchiveName = "skyrimse", - GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Skyrim VR" + GameLocationRegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Bethesda Softworks\Skyrim VR", + SteamIDs = new List{611670} } }, { @@ -146,7 +165,8 @@ namespace Wabbajack.Common { SupportedModManager = ModManager.Vortex, Game = Game.DarkestDungeon, - NexusName = "darkestdungeon" + NexusName = "darkestdungeon", + SteamIDs = new List{262060} } } }; From 2044a6728ad4d107800ab73526ed051cad9294af Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 15:20:12 +0100 Subject: [PATCH 21/72] Created SteamHandler --- Wabbajack.Common/SteamHandler.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Common/SteamHandler.cs b/Wabbajack.Common/SteamHandler.cs index cf542ca9..d403ce14 100644 --- a/Wabbajack.Common/SteamHandler.cs +++ b/Wabbajack.Common/SteamHandler.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -35,6 +35,7 @@ namespace Wabbajack.Common private string SteamConfig => Path.Combine(SteamPath, "config", "config.vdf"); +<<<<<<< HEAD public SteamHandler(bool init) { var steamKey = Registry.CurrentUser.OpenSubKey(SteamRegKey); @@ -42,6 +43,12 @@ namespace Wabbajack.Common if(!init) return; LoadInstallFolders(); LoadAllSteamGames(); +======= + public SteamHandler() + { + var steamKey = Registry.CurrentUser.OpenSubKey(SteamRegKey); + SteamPath = steamKey?.GetValue("SteamPath").ToString(); +>>>>>>> Created SteamHandler } /// @@ -64,9 +71,13 @@ namespace Wabbajack.Common File.ReadLines(SteamConfig, Encoding.UTF8).Do(l => { if (!l.Contains("BaseInstallFolder_")) return; +<<<<<<< HEAD var s = GetVdfValue(l); s = Path.Combine(s, "steamapps"); paths.Add(s); +======= + paths.Add(GetVdfValue(l)); +>>>>>>> Created SteamHandler }); InstallFolders = paths; From 8de6c9d23920b4129bbfa2577d9a1c5507456ebc Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 15:30:46 +0100 Subject: [PATCH 22/72] Fixed bad steam lib paths --- Wabbajack.Common/SteamHandler.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Wabbajack.Common/SteamHandler.cs b/Wabbajack.Common/SteamHandler.cs index d403ce14..541ba286 100644 --- a/Wabbajack.Common/SteamHandler.cs +++ b/Wabbajack.Common/SteamHandler.cs @@ -35,7 +35,6 @@ namespace Wabbajack.Common private string SteamConfig => Path.Combine(SteamPath, "config", "config.vdf"); -<<<<<<< HEAD public SteamHandler(bool init) { var steamKey = Registry.CurrentUser.OpenSubKey(SteamRegKey); @@ -43,12 +42,6 @@ namespace Wabbajack.Common if(!init) return; LoadInstallFolders(); LoadAllSteamGames(); -======= - public SteamHandler() - { - var steamKey = Registry.CurrentUser.OpenSubKey(SteamRegKey); - SteamPath = steamKey?.GetValue("SteamPath").ToString(); ->>>>>>> Created SteamHandler } /// @@ -71,13 +64,9 @@ namespace Wabbajack.Common File.ReadLines(SteamConfig, Encoding.UTF8).Do(l => { if (!l.Contains("BaseInstallFolder_")) return; -<<<<<<< HEAD var s = GetVdfValue(l); s = Path.Combine(s, "steamapps"); paths.Add(s); -======= - paths.Add(GetVdfValue(l)); ->>>>>>> Created SteamHandler }); InstallFolders = paths; From ccafda79b2dd7bc6880c15f9532c3f46164cab03 Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 15:49:29 +0100 Subject: [PATCH 23/72] Created GOG Handler --- Wabbajack.Common/GOGHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack.Common/GOGHandler.cs b/Wabbajack.Common/GOGHandler.cs index 3012e625..72ae196b 100644 --- a/Wabbajack.Common/GOGHandler.cs +++ b/Wabbajack.Common/GOGHandler.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Microsoft.Win32; From de40b8ce324312c6cd95804586aef88c53b0d567 Mon Sep 17 00:00:00 2001 From: erri120 Date: Tue, 5 Nov 2019 15:51:52 +0100 Subject: [PATCH 24/72] Added GOGID property --- Wabbajack.Common/GameMetaData.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index 6bf144ef..5d99321b 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -33,6 +33,7 @@ namespace Wabbajack.Common public string MO2Name { get; internal set; } public string GameLocationRegistryKey { get; internal set; } public List SteamIDs { get; internal set; } + public int GOGID { get; internal set; } public string GameLocation { @@ -161,12 +162,13 @@ namespace Wabbajack.Common } }, { - Game.DarkestDungeon, new GameMetaData() + Game.DarkestDungeon, new GameMetaData { SupportedModManager = ModManager.Vortex, Game = Game.DarkestDungeon, NexusName = "darkestdungeon", - SteamIDs = new List{262060} + SteamIDs = new List{262060}, + GOGID = 1450711444 } } }; From 60620886817e3efc934dd3921b7f49a58c712f53 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 14:51:51 +0100 Subject: [PATCH 25/72] Removed unused imports --- Wabbajack.Common/GameMetaData.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index 5d99321b..a0c35d70 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading.Tasks; using Alphaleonis.Win32.Filesystem; using Microsoft.Win32; From 263581e50ee3e4e915885da2e31fea024827fb5e Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 14:53:39 +0100 Subject: [PATCH 26/72] Fixed typo --- Wabbajack/View Models/CompilerVM.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack/View Models/CompilerVM.cs b/Wabbajack/View Models/CompilerVM.cs index a1ec8d89..719adeb2 100644 --- a/Wabbajack/View Models/CompilerVM.cs +++ b/Wabbajack/View Models/CompilerVM.cs @@ -210,7 +210,7 @@ namespace Wabbajack catch (Exception ex) { while (ex.InnerException != null) ex = ex.InnerException; - this.Log().Warn(ex, "Can't continue"); + Utils.Log($"Can't continue: {ex.ExceptionToString()}"); } finally { From 4900423f70645578fea89932716769c80972dedd Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 14:55:54 +0100 Subject: [PATCH 27/72] Fixed rebase issues --- Wabbajack.Lib/NexusApi/NexusApi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack.Lib/NexusApi/NexusApi.cs b/Wabbajack.Lib/NexusApi/NexusApi.cs index b8568319..dab9e696 100644 --- a/Wabbajack.Lib/NexusApi/NexusApi.cs +++ b/Wabbajack.Lib/NexusApi/NexusApi.cs @@ -274,7 +274,7 @@ namespace Wabbajack.Lib.NexusApi return Get>(url); } - public ModInfo GetModInfo(string gameName, string modId) + public ModInfo GetModInfo(Game game, string modId) { var url = $"https://api.nexusmods.com/v1/games/{GameRegistry.Games[game].NexusName}/mods/{modId}.json"; return GetCached(url); From 233c85b36de99a57eebc62227a04e45bab73f1b4 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 15:07:16 +0100 Subject: [PATCH 28/72] Implemented new caching system with GetModInfoFromMD5 --- Wabbajack.Lib/NexusApi/NexusApi.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Wabbajack.Lib/NexusApi/NexusApi.cs b/Wabbajack.Lib/NexusApi/NexusApi.cs index dab9e696..11243729 100644 --- a/Wabbajack.Lib/NexusApi/NexusApi.cs +++ b/Wabbajack.Lib/NexusApi/NexusApi.cs @@ -268,10 +268,10 @@ namespace Wabbajack.Lib.NexusApi return GetCached(url).files; } - public List GetModInfoFromMD5(string gameName, string md5Hash) + public List GetModInfoFromMD5(Game game, string md5Hash) { - var url = $"https://api.nexusmods.com/v1/games/{gameName}/mods/md5_search/{md5Hash}.json"; - return Get>(url); + var url = $"https://api.nexusmods.com/v1/games/{GameRegistry.Games[game].NexusName}/mods/md5_search/{md5Hash}.json"; + return GetCached>(url); } public ModInfo GetModInfo(Game game, string modId) From 2a9213102584f0e5667528b44b690634faddd166 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 15:10:28 +0100 Subject: [PATCH 29/72] Created GetByNexusName function for the GameRegistry --- Wabbajack.Common/GameMetaData.cs | 5 +++++ Wabbajack.Lib/VortexCompiler.cs | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index a0c35d70..9e6bcb25 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -54,6 +54,11 @@ namespace Wabbajack.Common return Games.Values.FirstOrDefault(g => g.MO2ArchiveName?.ToLower() == gamename); } + public static GameMetaData GetByNexusName(string gameName) + { + return Games.Values.FirstOrDefault(g => g.NexusName == gameName.ToLower()); + } + public static Dictionary Games = new Dictionary { diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index f3a4d9a9..f5237bb0 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -16,6 +16,7 @@ namespace Wabbajack.Lib { public class VortexCompiler : ACompiler { + public Game Game { get; } public string GameName { get; } public string VortexFolder { get; } @@ -35,6 +36,7 @@ namespace Wabbajack.Lib GamePath = gamePath; GameName = gameName; + Game = GameRegistry.GetByNexusName(GameName).Game; // currently only works if staging and downloads folder is in the standard directory // aka %APPDATADA%\Vortex\ @@ -267,7 +269,7 @@ namespace Wabbajack.Lib hash = BitConverter.ToString(cH).Replace("-", "").ToLowerInvariant(); } - var md5Response = nexusClient.GetModInfoFromMD5(GameName, hash); + var md5Response = nexusClient.GetModInfoFromMD5(game, hash); var modInfo = md5Response[0].mod; metaString += $"modID={modInfo.mod_id}\ndescription={NexusApiUtils.FixupSummary(modInfo.summary)}\n" + $"modName={modInfo.name}\nfileID={md5Response[0].file_details.file_id}"; From 6c1177d8e1b546c9b8313f509531300225c61c7a Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 15:11:19 +0100 Subject: [PATCH 30/72] Fixed typo --- Wabbajack.Lib/VortexCompiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index f5237bb0..2dd94f2c 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -269,7 +269,7 @@ namespace Wabbajack.Lib hash = BitConverter.ToString(cH).Replace("-", "").ToLowerInvariant(); } - var md5Response = nexusClient.GetModInfoFromMD5(game, hash); + var md5Response = nexusClient.GetModInfoFromMD5(Game, hash); var modInfo = md5Response[0].mod; metaString += $"modID={modInfo.mod_id}\ndescription={NexusApiUtils.FixupSummary(modInfo.summary)}\n" + $"modName={modInfo.name}\nfileID={md5Response[0].file_details.file_id}"; From 5b1ea3d448c656922f677b8b819e59b7054386a1 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 15:57:35 +0100 Subject: [PATCH 31/72] Added null check to NexusDownloader:GetDownloaderState --- Wabbajack.Lib/Downloaders/NexusDownloader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Lib/Downloaders/NexusDownloader.cs b/Wabbajack.Lib/Downloaders/NexusDownloader.cs index 44747048..4f66d984 100644 --- a/Wabbajack.Lib/Downloaders/NexusDownloader.cs +++ b/Wabbajack.Lib/Downloaders/NexusDownloader.cs @@ -19,7 +19,8 @@ namespace Wabbajack.Lib.Downloaders if (general.modID != null && general.fileID != null && general.gameName != null) { var name = (string)general.gameName; - var game = GameRegistry.GetByMO2ArchiveName(name).Game; + var gameMeta = GameRegistry.GetByMO2ArchiveName(name); + var game = gameMeta != null ? GameRegistry.GetByMO2ArchiveName(name).Game : GameRegistry.GetByNexusName(name).Game; var info = new NexusApiClient().GetModInfo(game, general.modID); return new State { From e23ca453a560585c37ad848a0ba9a3aca6809fc1 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 16:10:31 +0100 Subject: [PATCH 32/72] VortexCompiler: Added ModList metadata --- Wabbajack.Lib/VortexCompiler.cs | 38 +++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 2dd94f2c..1f9492be 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -5,12 +5,13 @@ using System.IO.Compression; using System.Linq; using System.Security.Cryptography; using System.Text; -using System.Threading.Tasks; using VFS; using Wabbajack.Common; using Wabbajack.Lib.CompilationSteps; using Wabbajack.Lib.Downloaders; +using Wabbajack.Lib.ModListRegistry; using Wabbajack.Lib.NexusApi; +using File = Alphaleonis.Win32.Filesystem.File; namespace Wabbajack.Lib { @@ -206,7 +207,8 @@ namespace Wabbajack.Lib { Archives = SelectedArchives, ModManager = ModManager.Vortex, - Directives = InstallDirectives + Directives = InstallDirectives, + GameType = Game }; ExportModList(); @@ -243,10 +245,42 @@ namespace Wabbajack.Lib }); } } + + Utils.Log("Exporting ModList metadata"); + var metadata = new ModlistMetadata.DownloadMetadata + { + Size = File.GetSize(ModListOutputFile), + Hash = ModListOutputFile.FileHash(), + NumberOfArchives = ModList.Archives.Count, + SizeOfArchives = ModList.Archives.Sum(a => a.Size), + NumberOfInstalledFiles = ModList.Directives.Count, + SizeOfInstalledFiles = ModList.Directives.Sum(a => a.Size) + }; + metadata.ToJSON(ModListOutputFile + ".meta.json"); + Utils.Log("Removing ModList staging folder"); //Directory.Delete(ModListOutputFolder, true); } + /*private void GenerateReport() + { + string css; + using (var cssStream = Utils.GetResourceStream("Wabbajack.Lib.css-min.css")) + using (var reader = new StreamReader(cssStream)) + { + css = reader.ReadToEnd(); + } + + using (var fs = File.OpenWrite($"{ModList.Name}.md")) + { + fs.SetLength(0); + using (var reporter = new ReportBuilder(fs, ModListOutputFolder)) + { + reporter.Build(this, ModList); + } + } + }*/ + private void CreateMetaFiles() { Directory.EnumerateFiles(DownloadsFolder, "*", SearchOption.TopDirectoryOnly) From 00cacfd01feda404a867a3cac8a0866a1848ea37 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 16:19:08 +0100 Subject: [PATCH 33/72] VortexCompiler: Added more logging --- Wabbajack.Lib/VortexCompiler.cs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 1f9492be..f8789ecd 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -287,6 +287,7 @@ namespace Wabbajack.Lib .Where(f => File.Exists(f) && (Path.GetExtension(f) == ".zip" || Path.GetExtension(f) == ".rar") && !File.Exists(f+".meta")) .Do(f => { + Utils.Log($"Trying to create meta file for {Path.GetFileName(f)}"); var metaString = $"[General]\n" + $"repository=Nexus\n" + $"installed=true\n" + @@ -294,20 +295,31 @@ namespace Wabbajack.Lib $"paused=false\n" + $"removed=false\n" + $"gameName={GameName}\n"; + Utils.Log("Getting Nexus api_key, please click authorize if a browser window appears"); var nexusClient = new NexusApiClient(); - var hash = ""; + string hash; using(var md5 = MD5.Create()) using (var stream = File.OpenRead(f)) { + Utils.Log($"Calculating hash for {Path.GetFileName(f)}"); byte[] cH = md5.ComputeHash(stream); hash = BitConverter.ToString(cH).Replace("-", "").ToLowerInvariant(); + Utils.Log($"Hash is {hash}"); } - var md5Response = nexusClient.GetModInfoFromMD5(Game, hash); - var modInfo = md5Response[0].mod; - metaString += $"modID={modInfo.mod_id}\ndescription={NexusApiUtils.FixupSummary(modInfo.summary)}\n" + - $"modName={modInfo.name}\nfileID={md5Response[0].file_details.file_id}"; - File.WriteAllText(f+".meta",metaString, Encoding.UTF8); + List md5Response = nexusClient.GetModInfoFromMD5(Game, hash); + if (md5Response.Count >= 1) + { + var modInfo = md5Response[0].mod; + metaString += $"modID={modInfo.mod_id}\ndescription={NexusApiUtils.FixupSummary(modInfo.summary)}\n" + + $"modName={modInfo.name}\nfileID={md5Response[0].file_details.file_id}"; + File.WriteAllText(f+".meta",metaString, Encoding.UTF8); + } + else + { + Error("Error while getting information from nexusmods via MD5 hash!"); + } + }); } From 061e46572dc582115e65bee7624ade91a676f1f5 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 16:24:23 +0100 Subject: [PATCH 34/72] VortexCompiler: Added support for different staging/downloads folder --- Wabbajack.Lib/VortexCompiler.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index f8789ecd..6ea1b2ce 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -28,23 +28,29 @@ namespace Wabbajack.Lib public VortexCompiler(string gameName, string gamePath) { + _vortexCompiler = this; _mo2Compiler = null; ModManager = ModManager.Vortex; // TODO: only for testing IgnoreMissingFiles = true; + string[] args = Environment.GetCommandLineArgs(); GamePath = gamePath; GameName = gameName; Game = GameRegistry.GetByNexusName(GameName).Game; - // currently only works if staging and downloads folder is in the standard directory - // aka %APPDATADA%\Vortex\ + //args: wabbajacke.exe gameName gamePath vortexfolder stagingfolder downloadsfolder VortexFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Vortex"); StagingFolder = Path.Combine(VortexFolder, gameName, "mods"); DownloadsFolder = Path.Combine(VortexFolder, "downloads", gameName); + if (args.Length >= 4) + StagingFolder = args[3]; + if (args.Length == 5) + DownloadsFolder = args[4]; + ModListOutputFolder = "output_folder"; // TODO: add custom modlist name From a6016813f0e923986270f5238f88188f2f55034f Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 19:12:36 +0100 Subject: [PATCH 35/72] Added a comment --- Wabbajack.Lib/VortexCompiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 6ea1b2ce..3df4076a 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -412,7 +412,7 @@ namespace Wabbajack.Lib new IncludeRegex(this, "^*\\.meta"), new IgnoreStartsWith(this, " __vortex_staging_folder"), new IgnoreEndsWith(this, "__vortex_staging_folder"), - new IgnoreEndsWith(this, "project.xml"), + new IgnoreEndsWith(this, "project.xml"), // darkest dungeon specific new IgnoreGameFiles(this), From 791438eea605cdf645e39243651187d66a5de4f4 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 19:27:35 +0100 Subject: [PATCH 36/72] Created RunIfGame CompilationStep --- Wabbajack.Lib/CompilationSteps/RunIfGame.cs | 46 +++++++++++++++++++++ Wabbajack.Lib/Wabbajack.Lib.csproj | 1 + 2 files changed, 47 insertions(+) create mode 100644 Wabbajack.Lib/CompilationSteps/RunIfGame.cs diff --git a/Wabbajack.Lib/CompilationSteps/RunIfGame.cs b/Wabbajack.Lib/CompilationSteps/RunIfGame.cs new file mode 100644 index 00000000..8cfadaca --- /dev/null +++ b/Wabbajack.Lib/CompilationSteps/RunIfGame.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using Wabbajack.Common; + +namespace Wabbajack.Lib.CompilationSteps +{ + public class RunIfGame : ACompilationStep + { + private readonly Game _game; + private readonly List _microStack; + + public RunIfGame(ACompiler compiler, Game game, List microStack) : base(compiler) + { + _game = game; + _microStack = microStack; + } + + public override Directive Run(RawSourceFile source) + { + return _compiler._vortexCompiler?.Game != _game ? null : _compiler._vortexCompiler.RunStack(_microStack, source); + } + + public override IState GetState() + { + return new State(_game, _microStack); + } + + [JsonArray("RunIfGame")] + public class State : IState + { + public State(Game game, List microStack) + { + Game = game; + MicroStack = microStack; + } + + public Game Game { get; set; } + public List MicroStack { get; set; } + + public ICompilationStep CreateStep(ACompiler compiler) + { + return new RunIfGame(compiler, Game, MicroStack); + } + } + } +} diff --git a/Wabbajack.Lib/Wabbajack.Lib.csproj b/Wabbajack.Lib/Wabbajack.Lib.csproj index c5248d75..d252cb62 100644 --- a/Wabbajack.Lib/Wabbajack.Lib.csproj +++ b/Wabbajack.Lib/Wabbajack.Lib.csproj @@ -93,6 +93,7 @@ + From 9feed217ef812226d8a59b17d7cd382eadc516a4 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 19:57:29 +0100 Subject: [PATCH 37/72] Removed RunIfGame Step in favor of inline conditional statements --- Wabbajack.Lib/CompilationSteps/RunIfGame.cs | 46 --------------------- Wabbajack.Lib/VortexCompiler.cs | 6 ++- Wabbajack.Lib/Wabbajack.Lib.csproj | 1 - 3 files changed, 4 insertions(+), 49 deletions(-) delete mode 100644 Wabbajack.Lib/CompilationSteps/RunIfGame.cs diff --git a/Wabbajack.Lib/CompilationSteps/RunIfGame.cs b/Wabbajack.Lib/CompilationSteps/RunIfGame.cs deleted file mode 100644 index 8cfadaca..00000000 --- a/Wabbajack.Lib/CompilationSteps/RunIfGame.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; -using Wabbajack.Common; - -namespace Wabbajack.Lib.CompilationSteps -{ - public class RunIfGame : ACompilationStep - { - private readonly Game _game; - private readonly List _microStack; - - public RunIfGame(ACompiler compiler, Game game, List microStack) : base(compiler) - { - _game = game; - _microStack = microStack; - } - - public override Directive Run(RawSourceFile source) - { - return _compiler._vortexCompiler?.Game != _game ? null : _compiler._vortexCompiler.RunStack(_microStack, source); - } - - public override IState GetState() - { - return new State(_game, _microStack); - } - - [JsonArray("RunIfGame")] - public class State : IState - { - public State(Game game, List microStack) - { - Game = game; - MicroStack = microStack; - } - - public Game Game { get; set; } - public List MicroStack { get; set; } - - public ICompilationStep CreateStep(ACompiler compiler) - { - return new RunIfGame(compiler, Game, MicroStack); - } - } - } -} diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 3df4076a..0b0c8653 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -176,7 +176,7 @@ namespace Wabbajack.Lib IEnumerable stack = MakeStack(); Info("Running Compilation Stack"); - List results = AllFiles.PMap(f => RunStack(stack, f)).ToList(); + List results = AllFiles.PMap(f => RunStack(stack.Where(s => s != null), f)).ToList(); IEnumerable noMatch = results.OfType().ToList(); Info($"No match for {noMatch.Count()} files"); @@ -410,9 +410,11 @@ namespace Wabbajack.Lib //new IncludePropertyFiles(this), new IncludeVortexDeployment(this), new IncludeRegex(this, "^*\\.meta"), + + Game == Game.DarkestDungeon ? new IncludeRegex(this, "project\\.xml$") : null, + new IgnoreStartsWith(this, " __vortex_staging_folder"), new IgnoreEndsWith(this, "__vortex_staging_folder"), - new IgnoreEndsWith(this, "project.xml"), // darkest dungeon specific new IgnoreGameFiles(this), diff --git a/Wabbajack.Lib/Wabbajack.Lib.csproj b/Wabbajack.Lib/Wabbajack.Lib.csproj index d252cb62..c5248d75 100644 --- a/Wabbajack.Lib/Wabbajack.Lib.csproj +++ b/Wabbajack.Lib/Wabbajack.Lib.csproj @@ -93,7 +93,6 @@ - From b02d9b50a22072cd584f9d875b27e794472693ba Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 21:26:33 +0100 Subject: [PATCH 38/72] Added Divinity Original Sins 2 to the Games list --- Wabbajack.Common/GameMetaData.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index 9e6bcb25..5c6c702a 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -16,7 +16,8 @@ namespace Wabbajack.Common Fallout4, SkyrimVR, //VORTEX GAMES - DarkestDungeon + DarkestDungeon, + DivinityOriginalSins2 } public class GameMetaData @@ -170,6 +171,16 @@ namespace Wabbajack.Common SteamIDs = new List{262060}, GOGID = 1450711444 } + }, + { + Game.DivinityOriginalSins2, new GameMetaData + { + SupportedModManager = ModManager.Vortex, + Game = Game.DivinityOriginalSins2, + NexusName = "divinityoriginalsins2", + SteamIDs = new List{435150}, + GOGID = 1584823040 + } } }; } From 1d35bf5ed1dcbfa480e86200c52865ca19fa8683 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 21:34:44 +0100 Subject: [PATCH 39/72] Created AdditionalFolders property --- Wabbajack.Common/GameMetaData.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Wabbajack.Common/GameMetaData.cs b/Wabbajack.Common/GameMetaData.cs index 5c6c702a..64aaac29 100644 --- a/Wabbajack.Common/GameMetaData.cs +++ b/Wabbajack.Common/GameMetaData.cs @@ -30,6 +30,7 @@ namespace Wabbajack.Common public string GameLocationRegistryKey { get; internal set; } public List SteamIDs { get; internal set; } public int GOGID { get; internal set; } + public List AdditionalFolders { get; internal set; } public string GameLocation { @@ -179,7 +180,12 @@ namespace Wabbajack.Common Game = Game.DivinityOriginalSins2, NexusName = "divinityoriginalsins2", SteamIDs = new List{435150}, - GOGID = 1584823040 + GOGID = 1584823040, + AdditionalFolders = new List + { + "%documents%\\Larian Studios\\Divinity Original Sin 2\\Mods\\", + "%documents%\\Larian Studios\\Divinity Original Sin 2 Definitive Edition\\Mods\\" + } } } }; From 80068fdd7dfe7d879736867f70cc52fff0138a4a Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 21:35:08 +0100 Subject: [PATCH 40/72] Created AddExternalFolder function to index the AdditionalFolders for the game --- Wabbajack.Lib/VortexCompiler.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 0b0c8653..0bb8d99e 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -5,6 +5,7 @@ using System.IO.Compression; using System.Linq; using System.Security.Cryptography; using System.Text; +using Microsoft.WindowsAPICodePack.Shell; using VFS; using Wabbajack.Common; using Wabbajack.Lib.CompilationSteps; @@ -111,6 +112,8 @@ namespace Wabbajack.Lib Info($"Indexing {DownloadsFolder}"); VFS.AddRoot(DownloadsFolder); + AddExternalFolder(); + Info("Cleaning output folder"); if (Directory.Exists(ModListOutputFolder)) Directory.Delete(ModListOutputFolder, true); Directory.CreateDirectory(ModListOutputFolder); @@ -223,6 +226,22 @@ namespace Wabbajack.Lib return true; } + /// + /// Some have mods outside their game folder located + /// + private void AddExternalFolder() + { + var currentGame = GameRegistry.Games[Game]; + if (currentGame.AdditionalFolders == null || currentGame.AdditionalFolders.Count == 0) return; + currentGame.AdditionalFolders.Do(f => + { + var path = f.Replace("%documents%", KnownFolders.Documents.Path); + if (!Directory.Exists(path)) return; + Info($"Indexing {path}"); + VFS.AddRoot(path); + }); + } + private void ExportModList() { Utils.Log($"Exporting ModList to: {ModListOutputFolder}"); From 3ad63bda39430e441d4efebed19fa48f81791389 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 21:40:25 +0100 Subject: [PATCH 41/72] Created VortexInstaller --- Wabbajack.Lib/VortexInstaller.cs | 72 ++++++++++++++++++++++++++++++ Wabbajack.Lib/Wabbajack.Lib.csproj | 1 + 2 files changed, 73 insertions(+) create mode 100644 Wabbajack.Lib/VortexInstaller.cs diff --git a/Wabbajack.Lib/VortexInstaller.cs b/Wabbajack.Lib/VortexInstaller.cs new file mode 100644 index 00000000..e59ba878 --- /dev/null +++ b/Wabbajack.Lib/VortexInstaller.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VFS; +using Wabbajack.Common; + +namespace Wabbajack.Lib +{ + public class VortexInstaller + { + public string ModListArchive { get; } + public ModList ModList { get; } + + public VirtualFileSystem VFS => VirtualFileSystem.VFS; + + public VortexInstaller(string archive, ModList modList) + { + ModListArchive = archive; + ModList = modList; + } + + public void Info(string msg) + { + Utils.Log(msg); + } + + public void Status(string msg) + { + WorkQueue.Report(msg, 0); + } + + private void Error(string msg) + { + Utils.Log(msg); + throw new Exception(msg); + } + + public byte[] LoadBytesFromPath(string path) + { + using (var fs = new FileStream(ModListArchive, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var ar = new ZipArchive(fs, ZipArchiveMode.Read)) + using (var ms = new MemoryStream()) + { + var entry = ar.GetEntry(path); + using (var e = entry.Open()) + e.CopyTo(ms); + return ms.ToArray(); + } + } + + public static ModList LoadFromFile(string path) + { + using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var ar = new ZipArchive(fs, ZipArchiveMode.Read)) + { + var entry = ar.GetEntry("modlist"); + if (entry == null) + { + entry = ar.GetEntry("modlist.json"); + using (var e = entry.Open()) + return e.FromJSON(); + } + using (var e = entry.Open()) + return e.FromCERAS(ref CerasConfig.Config); + } + } + } +} diff --git a/Wabbajack.Lib/Wabbajack.Lib.csproj b/Wabbajack.Lib/Wabbajack.Lib.csproj index c5248d75..a3be6fac 100644 --- a/Wabbajack.Lib/Wabbajack.Lib.csproj +++ b/Wabbajack.Lib/Wabbajack.Lib.csproj @@ -134,6 +134,7 @@ + WebAutomationWindow.xaml From 60f9b3326590285f0e8fc368067070fa3901b826 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sat, 9 Nov 2019 22:45:10 +0100 Subject: [PATCH 42/72] Working VortexInstaller --- Wabbajack.Lib/VortexInstaller.cs | 244 ++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 2 deletions(-) diff --git a/Wabbajack.Lib/VortexInstaller.cs b/Wabbajack.Lib/VortexInstaller.cs index e59ba878..a0a94cf3 100644 --- a/Wabbajack.Lib/VortexInstaller.cs +++ b/Wabbajack.Lib/VortexInstaller.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; -using System.Text; -using System.Threading.Tasks; using VFS; using Wabbajack.Common; +using Wabbajack.Lib.Downloaders; +using Directory = Alphaleonis.Win32.Filesystem.Directory; +using File = Alphaleonis.Win32.Filesystem.File; +using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo; +using Path = Alphaleonis.Win32.Filesystem.Path; namespace Wabbajack.Lib { @@ -14,13 +17,31 @@ namespace Wabbajack.Lib { public string ModListArchive { get; } public ModList ModList { get; } + public Dictionary HashedArchives { get; private set; } + + public GameMetaData GameInfo { get; internal set; } + + public string VortexFolder { get; set; } + public string StagingFolder { get; set; } + public string DownloadFolder { get; set; } public VirtualFileSystem VFS => VirtualFileSystem.VFS; + public bool IgnoreMissingFiles { get; internal set; } + public VortexInstaller(string archive, ModList modList) { ModListArchive = archive; ModList = modList; + + // TODO: only for testing + IgnoreMissingFiles = true; + + GameInfo = GameRegistry.Games[ModList.GameType]; + + VortexFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Vortex"); + StagingFolder = Path.Combine(VortexFolder, GameInfo.NexusName, "mods"); + DownloadFolder = Path.Combine(VortexFolder, "downloads", GameInfo.NexusName); } public void Info(string msg) @@ -68,5 +89,224 @@ namespace Wabbajack.Lib return e.FromCERAS(ref CerasConfig.Config); } } + + public void Install() + { + Directory.CreateDirectory(DownloadFolder); + + VirtualFileSystem.Clean(); + + HashArchives(); + DownloadArchives(); + HashArchives(); + + var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList(); + if (missing.Count > 0) + { + foreach (var a in missing) + Info($"Unable to download {a.Name}"); + if (IgnoreMissingFiles) + Info("Missing some archives, but continuing anyways at the request of the user"); + else + Error("Cannot continue, was unable to download one or more archives"); + } + + PrimeVFS(); + + BuildFolderStructure(); + InstallArchives(); + InstallIncludedFiles(); + //InctallIncludedDownloadMetas(); + + Info("Installation complete! You may exit the program."); + } + + private void BuildFolderStructure() + { + Info("Building Folder Structure"); + ModList.Directives + .OfType() + .Select(d => Path.Combine(StagingFolder, Path.GetDirectoryName(d.To))) + .ToHashSet() + .Do(f => + { + if (Directory.Exists(f)) return; + Directory.CreateDirectory(f); + }); + } + + private void InstallArchives() + { + Info("Installing Archives"); + Info("Grouping Install Files"); + var grouped = ModList.Directives + .OfType() + .GroupBy(e => e.ArchiveHashPath[0]) + .ToDictionary(k => k.Key); + var archives = ModList.Archives + .Select(a => new { Archive = a, AbsolutePath = HashedArchives.GetOrDefault(a.Hash) }) + .Where(a => a.AbsolutePath != null) + .ToList(); + + Info("Installing Archives"); + archives.PMap(a => InstallArchive(a.Archive, a.AbsolutePath, grouped[a.Archive.Hash])); + } + + private void InstallArchive(Archive archive, string absolutePath, IGrouping grouping) + { + Status($"Extracting {archive.Name}"); + + var vFiles = grouping.Select(g => + { + var file = VFS.FileForArchiveHashPath(g.ArchiveHashPath); + g.FromFile = file; + return g; + }).ToList(); + + var onFinish = VFS.Stage(vFiles.Select(f => f.FromFile).Distinct()); + + Status($"Copying files for {archive.Name}"); + + void CopyFile(string from, string to, bool useMove) + { + if(File.Exists(to)) + File.Delete(to); + if (useMove) + File.Move(from, to); + else + File.Copy(from, to); + } + + vFiles.GroupBy(f => f.FromFile) + .DoIndexed((idx, group) => + { + Utils.Status("Installing files", idx * 100 / vFiles.Count); + var firstDest = Path.Combine(StagingFolder, group.First().To); + CopyFile(group.Key.StagedPath, firstDest, true); + + foreach (var copy in group.Skip(1)) + { + var nextDest = Path.Combine(StagingFolder, copy.To); + CopyFile(firstDest, nextDest, false); + } + }); + + Status("Unstaging files"); + onFinish(); + } + + private void InstallIncludedFiles() + { + Info("Writing inline files"); + ModList.Directives.OfType() + .PMap(directive => + { + Status($"Writing included file {directive.To}"); + var outPath = Path.Combine(StagingFolder, directive.To); + if(File.Exists(outPath)) File.Delete(outPath); + File.WriteAllBytes(outPath, LoadBytesFromPath(directive.SourceDataID)); + }); + } + + private void PrimeVFS() + { + HashedArchives.Do(a => VFS.AddKnown(new VirtualFile + { + Paths = new[] { a.Value }, + Hash = a.Key + })); + VFS.RefreshIndexes(); + + + ModList.Directives + .OfType() + .Do(f => + { + var updated_path = new string[f.ArchiveHashPath.Length]; + f.ArchiveHashPath.CopyTo(updated_path, 0); + updated_path[0] = VFS.HashIndex[updated_path[0]].Where(e => e.IsConcrete).First().FullPath; + VFS.AddKnown(new VirtualFile { Paths = updated_path }); + }); + + VFS.BackfillMissing(); + } + + private void DownloadArchives() + { + var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList(); + Info($"Missing {missing.Count} archives"); + + Info("Getting Nexus API Key, if a browser appears, please accept"); + + var dispatchers = missing.Select(m => m.State.GetDownloader()).Distinct(); + + foreach (var dispatcher in dispatchers) + dispatcher.Prepare(); + + DownloadMissingArchives(missing); + } + + private void DownloadMissingArchives(List missing, bool download = true) + { + if (download) + { + foreach (var a in missing.Where(a => a.State.GetType() == typeof(ManualDownloader.State))) + { + var output_path = Path.Combine(DownloadFolder, a.Name); + a.State.Download(a, output_path); + } + } + + missing.Where(a => a.State.GetType() != typeof(ManualDownloader.State)) + .PMap(archive => + { + Info($"Downloading {archive.Name}"); + var output_path = Path.Combine(DownloadFolder, archive.Name); + + if (!download) return DownloadArchive(archive, download); + if (output_path.FileExists()) + File.Delete(output_path); + + return DownloadArchive(archive, download); + }); + } + + public bool DownloadArchive(Archive archive, bool download) + { + try + { + archive.State.Download(archive, Path.Combine(DownloadFolder, archive.Name)); + } + catch (Exception ex) + { + Utils.Log($"Download error for file {archive.Name}"); + Utils.Log(ex.ToString()); + return false; + } + + return false; + } + + private void HashArchives() + { + HashedArchives = Directory.EnumerateFiles(DownloadFolder) + .Where(e => !e.EndsWith(".sha")) + .PMap(e => (HashArchive(e), e)) + .OrderByDescending(e => File.GetLastWriteTime(e.Item2)) + .GroupBy(e => e.Item1) + .Select(e => e.First()) + .ToDictionary(e => e.Item1, e => e.Item2); + } + + private string HashArchive(string e) + { + var cache = e + ".sha"; + if (cache.FileExists() && new FileInfo(cache).LastWriteTime >= new FileInfo(e).LastWriteTime) + return File.ReadAllText(cache); + + Status($"Hashing {Path.GetFileName(e)}"); + File.WriteAllText(cache, e.FileHash()); + return HashArchive(e); + } } } From d1563c6bf4a68c03b93aadd88597f252e3027f99 Mon Sep 17 00:00:00 2001 From: erri120 Date: Sun, 10 Nov 2019 17:44:56 +0100 Subject: [PATCH 43/72] InstallerVM will not set Download folder for vortex installation --- Wabbajack/View Models/InstallerVM.cs | 77 +++++++++++++++++++--------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/Wabbajack/View Models/InstallerVM.cs b/Wabbajack/View Models/InstallerVM.cs index 0506b307..37439bd1 100644 --- a/Wabbajack/View Models/InstallerVM.cs +++ b/Wabbajack/View Models/InstallerVM.cs @@ -289,35 +289,64 @@ namespace Wabbajack private void ExecuteBegin() { - this.Installing = true; - this.InstallingMode = true; - var installer = new Installer(this.ModListPath, this.ModList.SourceModList, Location.TargetPath) + Installing = true; + InstallingMode = true; + if (true) { - DownloadFolder = DownloadLocation.TargetPath - }; - var th = new Thread(() => + var installer = new VortexInstaller(ModListPath, ModList.SourceModList); + var th = new Thread(() => + { + try + { + installer.Install(); + } + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + Utils.Log(ex.StackTrace); + Utils.Log(ex.ToString()); + Utils.Log($"{ex.Message} - Can't continue"); + } + finally + { + Installing = false; + } + }) + { + Priority = ThreadPriority.BelowNormal + }; + th.Start(); + } + else { - try + var installer = new Installer(this.ModListPath, this.ModList.SourceModList, Location.TargetPath) { - installer.Install(); - } - catch (Exception ex) - { - while (ex.InnerException != null) ex = ex.InnerException; - Utils.Log(ex.StackTrace); - Utils.Log(ex.ToString()); - Utils.Log($"{ex.Message} - Can't continue"); - } - finally + DownloadFolder = DownloadLocation.TargetPath + }; + var th = new Thread(() => { + try + { + installer.Install(); + } + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + Utils.Log(ex.StackTrace); + Utils.Log(ex.ToString()); + Utils.Log($"{ex.Message} - Can't continue"); + } + finally + { - this.Installing = false; - } - }) - { - Priority = ThreadPriority.BelowNormal - }; - th.Start(); + this.Installing = false; + } + }) + { + Priority = ThreadPriority.BelowNormal + }; + th.Start(); + } } } } \ No newline at end of file From 263802c304f1c5d841ab11c54376f91729fccc7a Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 11 Nov 2019 12:38:45 +0100 Subject: [PATCH 44/72] Added ModManager property to ModListVM --- Wabbajack/View Models/ModListVM.cs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/Wabbajack/View Models/ModListVM.cs b/Wabbajack/View Models/ModListVM.cs index 95768222..c2bd6056 100644 --- a/Wabbajack/View Models/ModListVM.cs +++ b/Wabbajack/View Models/ModListVM.cs @@ -1,13 +1,8 @@ using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Collections.Generic; using System.IO; using System.IO.Compression; -using System.Linq; using System.Reactive.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Media.Imaging; using Wabbajack.Common; using Wabbajack.Lib; @@ -18,13 +13,14 @@ namespace Wabbajack { public ModList SourceModList { get; } public string ModListPath { get; } - public string Name => this.SourceModList.Name; - public string ReportHTML => this.SourceModList.ReportHTML; - public string Readme => this.SourceModList.Readme; - public string ImageURL => this.SourceModList.Image; - public string Author => this.SourceModList.Author; - public string Description => this.SourceModList.Description; - public string Website => this.SourceModList.Website; + public string Name => SourceModList.Name; + public string ReportHTML => SourceModList.ReportHTML; + public string Readme => SourceModList.Readme; + public string ImageURL => SourceModList.Image; + public string Author => SourceModList.Author; + public string Description => SourceModList.Description; + public string Website => SourceModList.Website; + public ModManager ModManager => SourceModList.ModManager; // Image isn't exposed as a direct property, but as an observable. // This acts as a caching mechanism, as interested parties will trigger it to be created, @@ -33,10 +29,10 @@ namespace Wabbajack public ModListVM(ModList sourceModList, string modListPath) { - this.ModListPath = modListPath; - this.SourceModList = sourceModList; + ModListPath = modListPath; + SourceModList = sourceModList; - this.ImageObservable = Observable.Return(this.ImageURL) + ImageObservable = Observable.Return(this.ImageURL) .ObserveOn(RxApp.TaskpoolScheduler) .Select(url => { From d65085e1aba24168bd6f081af7a9d2bb4efbbae7 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 11 Nov 2019 12:40:05 +0100 Subject: [PATCH 45/72] InstallerVM will switch between ModList.ModManager --- Wabbajack/View Models/InstallerVM.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wabbajack/View Models/InstallerVM.cs b/Wabbajack/View Models/InstallerVM.cs index 37439bd1..d91d87df 100644 --- a/Wabbajack/View Models/InstallerVM.cs +++ b/Wabbajack/View Models/InstallerVM.cs @@ -291,7 +291,7 @@ namespace Wabbajack { Installing = true; InstallingMode = true; - if (true) + if (ModList.ModManager == ModManager.Vortex) { var installer = new VortexInstaller(ModListPath, ModList.SourceModList); var th = new Thread(() => From 1024d4a2e28fd2a009684101569a769193987995 Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 11 Nov 2019 12:50:16 +0100 Subject: [PATCH 46/72] Warning message will appear if you try to install a Vortex ModList --- Wabbajack/View Models/InstallerVM.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Wabbajack/View Models/InstallerVM.cs b/Wabbajack/View Models/InstallerVM.cs index d91d87df..00710085 100644 --- a/Wabbajack/View Models/InstallerVM.cs +++ b/Wabbajack/View Models/InstallerVM.cs @@ -147,6 +147,13 @@ namespace Wabbajack this.MWVM.MainWindow.Close(); }); return default(ModListVM); + }else if (modList.ModManager == ModManager.Vortex) + { + MessageBox.Show( + "The ModList you are about to install was compiled from a Vortex installation. " + + "Vortex support is still very bleeding edge and installing this ModList WILL OVERRIDE your existing mods. " + + "If you encounter any errors during installation go to our discord and ping erri120#2285 with your error and a log file.", + "Important information regarding Vortex support", MessageBoxButton.OK, MessageBoxImage.Stop); } return new ModListVM(modList, modListPath); }) From a423e33cef14dd331379a208068d894d91af64ec Mon Sep 17 00:00:00 2001 From: erri120 Date: Mon, 11 Nov 2019 13:03:46 +0100 Subject: [PATCH 47/72] InstallerView will show different settings depending on ModManager used during ModList compilation --- Wabbajack/View Models/InstallerVM.cs | 24 ++++- Wabbajack/Views/InstallationView.xaml | 144 +++++++++++++++++++++----- 2 files changed, 139 insertions(+), 29 deletions(-) diff --git a/Wabbajack/View Models/InstallerVM.cs b/Wabbajack/View Models/InstallerVM.cs index 00710085..b3b6e9f0 100644 --- a/Wabbajack/View Models/InstallerVM.cs +++ b/Wabbajack/View Models/InstallerVM.cs @@ -52,8 +52,20 @@ namespace Wabbajack public FilePickerVM Location { get; } + [Reactive] + public bool IsMO2ModList { get; set; } + + [Reactive] + public string DownloadLocation { get; set; } + public FilePickerVM DownloadLocation { get; } + [Reactive] + public string StagingLocation { get; set; } + + private readonly ObservableAsPropertyHelper _stagingLocationError; + public IErrorResponse StagingLocationError => _stagingLocationError.Value; + private readonly ObservableAsPropertyHelper _ProgressPercent; public float ProgressPercent => _ProgressPercent.Value; @@ -147,14 +159,20 @@ namespace Wabbajack this.MWVM.MainWindow.Close(); }); return default(ModListVM); - }else if (modList.ModManager == ModManager.Vortex) + } + if (modList.ModManager == ModManager.Vortex) { + IsMO2ModList = false; MessageBox.Show( "The ModList you are about to install was compiled from a Vortex installation. " + "Vortex support is still very bleeding edge and installing this ModList WILL OVERRIDE your existing mods. " + "If you encounter any errors during installation go to our discord and ping erri120#2285 with your error and a log file.", "Important information regarding Vortex support", MessageBoxButton.OK, MessageBoxImage.Stop); } + else + { + IsMO2ModList = true; + } return new ModListVM(modList, modListPath); }) .ObserveOnGuiThread() @@ -213,6 +231,10 @@ namespace Wabbajack .Select(x => x?.Name) .ToProperty(this, nameof(this.ModListName)); + _stagingLocationError = this.WhenAny(x => x.StagingLocation) + .Select(Utils.IsDirectoryPathValid) + .ToProperty(this, nameof(StagingLocationError)); + // Define commands this.ShowReportCommand = ReactiveCommand.Create(ShowReport); this.OpenReadmeCommand = ReactiveCommand.Create( diff --git a/Wabbajack/Views/InstallationView.xaml b/Wabbajack/Views/InstallationView.xaml index b537fe0c..1d895518 100644 --- a/Wabbajack/Views/InstallationView.xaml +++ b/Wabbajack/Views/InstallationView.xaml @@ -281,37 +281,125 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +