diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b62fe8b..d0a82b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ### Changelog +#### Version - 3.0.0.7 - 9/12/2022 +* Fix Dragons' Dogma MO2 archive names +* Add Modlist Report for CLI + #### Version - 3.0.0.6 - 8/23/2022 * Upgrade several dependency libraries * Provide a better error message when someone attempts to compile before logging into the Nexus (or installing a list) @@ -37,6 +41,9 @@ * Based on WebView2, .NET 6 * Probably lots of new bugs, please test +#### Version - 2.5.3.28 - 8/30/2022 +* Auto-inline `.compiler_settings` files during compilation + #### Version - 2.5.3.27 - 8/7/2022 * A few fixes for VectorPlexis and LL, you may need to log out and back in from these sites diff --git a/Wabbajack.App.Wpf/View Models/Compilers/CompilerVM.cs b/Wabbajack.App.Wpf/View Models/Compilers/CompilerVM.cs index cc4cbed5..26301311 100644 --- a/Wabbajack.App.Wpf/View Models/Compilers/CompilerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Compilers/CompilerVM.cs @@ -267,6 +267,11 @@ namespace Wabbajack NoMatchInclude = settings.NoMatchInclude; Include = settings.Include; Ignore = settings.Ignore; + if (path.FileName == "modlist.txt".ToRelativePath()) + { + await SaveSettingsFile(); + await LoadLastSavedSettings(); + } } diff --git a/Wabbajack.CLI/Program.cs b/Wabbajack.CLI/Program.cs index c74236bc..e86df3cb 100644 --- a/Wabbajack.CLI/Program.cs +++ b/Wabbajack.CLI/Program.cs @@ -80,6 +80,7 @@ internal class Program services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); }).Build(); diff --git a/Wabbajack.CLI/Resources/ModlistReport.html b/Wabbajack.CLI/Resources/ModlistReport.html new file mode 100644 index 00000000..000dd08c --- /dev/null +++ b/Wabbajack.CLI/Resources/ModlistReport.html @@ -0,0 +1,83 @@ + + + + + Modlist Report for {{$.Name}} + + + + + + + + + + +
+

Modlist Report ({{$.WabbajackSize}} compressed)

+ +

Inlined Data ({{$.TotalInlinedSize}})

+ + + + + + + + + + {{each $.InlinedData}} + + + + + + {{/each}} + +
ToIdSize
{{$.To}}{{$.Id}}{{$.Size}}
+ +

Patch Data ({{$.TotalPatchSize}})

+ + + + + + + + + + + + {{each $.PatchData}} + + + + + + + + {{/each}} + +
FromToIdPatch SizeFinal Size
{{$.From}}{{$.To}}{{$.Id}}{{$.PatchSize}}{{$.FinalSize}}
+
+ + + + \ No newline at end of file diff --git a/Wabbajack.CLI/Verbs/ModlistReport.cs b/Wabbajack.CLI/Verbs/ModlistReport.cs new file mode 100644 index 00000000..1ebc8488 --- /dev/null +++ b/Wabbajack.CLI/Verbs/ModlistReport.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Nettle; +using Wabbajack.Common; +using Wabbajack.DTOs.Directives; +using Wabbajack.DTOs.JsonConverters; +using Wabbajack.Installer; +using Wabbajack.Paths; +using Wabbajack.Paths.IO; + +namespace Wabbajack.CLI.Verbs; + +public class ModlistReport : IVerb +{ + private readonly ILogger _logger; + private readonly DTOSerializer _dtos; + + public ModlistReport(ILogger logger, DTOSerializer dtos) + { + _logger = logger; + _dtos = dtos; + } + public Command MakeCommand() + { + var command = new Command("modlist-report"); + command.Add(new Option(new[] {"-i", "-input"}, "Wabbajack file from which to generate a report")); + command.Description = "Generates a usage report for a Modlist file"; + command.Handler = CommandHandler.Create(Run); + return command; + } + + private static async Task ReportTemplate(object o) + { + var data = (typeof(ModlistReport).Assembly.GetManifestResourceStream("Wabbajack.CLI.Resources.ModlistReport.html")!).ReadAllText(); + var func = NettleEngine.GetCompiler().Compile(data); + return func(o); + } + + public async Task Run(AbsolutePath input) + { + + _logger.LogInformation("Loading Modlist"); + var modlist = await StandardInstaller.LoadFromFile(_dtos, input); + + Dictionary patchSizes; + using (var zip = new ZipArchive(input.Open(FileMode.Open, FileAccess.Read, FileShare.Read))) + { + patchSizes = zip.Entries.ToDictionary(e => e.Name, e => e.Length); + } + + var archives = modlist.Archives.ToDictionary(a => a.Hash, a => a.Name); + var bsas = modlist.Directives.OfType().ToDictionary(bsa => bsa.TempID.ToString()); + + var inlinedData = modlist.Directives.OfType() + .Select(e => new + { + To = e.To.ToString(), + Id = e.SourceDataID.ToString(), + SizeInt = e.Size, + Size = e.Size.ToFileSizeString() + }).ToArray(); + + string FixupTo(RelativePath path) + { + if (path.GetPart(0) != StandardInstaller.BSACreationDir.ToString()) return path.ToString(); + var bsaId = path.GetPart(1); + + if (!bsas.TryGetValue(bsaId, out var bsa)) + { + return path.ToString(); + } + + var relPath = RelativePath.FromParts(path.Parts[2..]); + return $" {bsa.To} | {relPath}"; + } + + var patchData = modlist.Directives.OfType() + .Select(e => new + { + From = $" {archives[e.ArchiveHashPath.Hash]} | {string.Join(" | ", e.ArchiveHashPath.Parts.Select(e => e.ToString()))}", + To = FixupTo(e.To), + Id = e.PatchID.ToString(), + PatchSize = patchSizes[e.PatchID.ToString()].ToFileSizeString(), + PatchSizeInt = patchSizes[e.PatchID.ToString()], + FinalSize = e.Size.ToFileSizeString(), + }).ToArray(); + + var data = await ReportTemplate(new + { + Name = modlist.Name, + TotalInlinedSize = inlinedData.Sum(i => i.SizeInt).ToFileSizeString(), + InlinedData = inlinedData, + TotalPatchSize = patchData.Sum(i => i.PatchSizeInt).ToFileSizeString(), + PatchData = patchData, + WabbajackSize = input.Size().ToFileSizeString() + }); + + await input.WithExtension(Ext.Html).WriteAllTextAsync(data); + + return 0; + } +} \ No newline at end of file diff --git a/Wabbajack.CLI/Wabbajack.CLI.csproj b/Wabbajack.CLI/Wabbajack.CLI.csproj index 86ca738f..4d414263 100644 --- a/Wabbajack.CLI/Wabbajack.CLI.csproj +++ b/Wabbajack.CLI/Wabbajack.CLI.csproj @@ -36,4 +36,9 @@ + + + + + diff --git a/Wabbajack.Compression.BSA/DDS.cs b/Wabbajack.Compression.BSA/DDS.cs index 8ca6e9ac..57366883 100644 --- a/Wabbajack.Compression.BSA/DDS.cs +++ b/Wabbajack.Compression.BSA/DDS.cs @@ -89,6 +89,7 @@ public struct DDS_HEADER return 9 * 4 + PixelFormat.GetSize() + 14 * 4; } + public void Write(BinaryWriter bw) { bw.Write(dwSize); diff --git a/Wabbajack.DTOs/Game/GameRegistry.cs b/Wabbajack.DTOs/Game/GameRegistry.cs index 30db2f2e..57e4f2ca 100644 --- a/Wabbajack.DTOs/Game/GameRegistry.cs +++ b/Wabbajack.DTOs/Game/GameRegistry.cs @@ -439,6 +439,7 @@ public static class GameRegistry Game = Game.DragonsDogma, SteamIDs = new[] {367500 }, MO2Name = "Dragon's Dogma: Dark Arisen", + MO2ArchiveName = "dragonsdogma", NexusName = "dragonsdogma", NexusGameId = 1249, IsGenericMO2Plugin = true, diff --git a/Wabbajack.Downloaders.Nexus/NexusDownloader.cs b/Wabbajack.Downloaders.Nexus/NexusDownloader.cs index f7aa5904..ef635b04 100644 --- a/Wabbajack.Downloaders.Nexus/NexusDownloader.cs +++ b/Wabbajack.Downloaders.Nexus/NexusDownloader.cs @@ -99,7 +99,10 @@ public class NexusDownloader : ADownloader, IUrlDownloader { if (iniData.TryGetValue("gameName", out var gameName) && iniData.TryGetValue("modID", out var modId) && - iniData.TryGetValue("fileID", out var fileId)) + iniData.TryGetValue("fileID", out var fileId) && + !string.IsNullOrWhiteSpace(gameName) && + !string.IsNullOrWhiteSpace(modId) && + !string.IsNullOrWhiteSpace(fileId)) return new Nexus { Game = GameRegistry.GetByMO2ArchiveName(gameName)!.Game, diff --git a/Wabbajack.Paths/RelativePath.cs b/Wabbajack.Paths/RelativePath.cs index 58d31eb9..3a480d9d 100644 --- a/Wabbajack.Paths/RelativePath.cs +++ b/Wabbajack.Paths/RelativePath.cs @@ -5,7 +5,7 @@ namespace Wabbajack.Paths; public struct RelativePath : IPath, IEquatable, IComparable { - internal readonly string[] Parts; + public readonly string[] Parts; private int _hashCode = 0; @@ -14,6 +14,11 @@ public struct RelativePath : IPath, IEquatable, IComparable