mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
#### Version - 3.0.0.7 - 9/12/2022
* Few compiler fixes for non Bethesda game compiling * Fix Dragons' Dogma MO2 archive names * Add Modlist Report for CLI
This commit is contained in:
parent
0f361a3f62
commit
de9ddd62e1
@ -1,5 +1,9 @@
|
|||||||
### Changelog
|
### 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
|
#### Version - 3.0.0.6 - 8/23/2022
|
||||||
* Upgrade several dependency libraries
|
* Upgrade several dependency libraries
|
||||||
* Provide a better error message when someone attempts to compile before logging into the Nexus (or installing a list)
|
* 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
|
* Based on WebView2, .NET 6
|
||||||
* Probably lots of new bugs, please test
|
* 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
|
#### 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
|
* A few fixes for VectorPlexis and LL, you may need to log out and back in from these sites
|
||||||
|
|
||||||
|
@ -267,6 +267,11 @@ namespace Wabbajack
|
|||||||
NoMatchInclude = settings.NoMatchInclude;
|
NoMatchInclude = settings.NoMatchInclude;
|
||||||
Include = settings.Include;
|
Include = settings.Include;
|
||||||
Ignore = settings.Ignore;
|
Ignore = settings.Ignore;
|
||||||
|
if (path.FileName == "modlist.txt".ToRelativePath())
|
||||||
|
{
|
||||||
|
await SaveSettingsFile();
|
||||||
|
await LoadLastSavedSettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ internal class Program
|
|||||||
services.AddSingleton<IVerb, InstallCompileInstallVerify>();
|
services.AddSingleton<IVerb, InstallCompileInstallVerify>();
|
||||||
services.AddSingleton<IVerb, HashUrlString>();
|
services.AddSingleton<IVerb, HashUrlString>();
|
||||||
services.AddSingleton<IVerb, DownloadAll>();
|
services.AddSingleton<IVerb, DownloadAll>();
|
||||||
|
services.AddSingleton<IVerb, ModlistReport>();
|
||||||
|
|
||||||
services.AddSingleton<IUserInterventionHandler, UserInterventionHandler>();
|
services.AddSingleton<IUserInterventionHandler, UserInterventionHandler>();
|
||||||
}).Build();
|
}).Build();
|
||||||
|
83
Wabbajack.CLI/Resources/ModlistReport.html
Normal file
83
Wabbajack.CLI/Resources/ModlistReport.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Modlist Report for {{$.Name}}</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.css">
|
||||||
|
<script type="text/javascript" charset="utf8" src="https://code.jquery.com/jquery-3.5.1.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/dataTables.bootstrap4.min.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/plug-ins/1.12.1/sorting/file-size.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="ml-2" style="width: 90%">
|
||||||
|
<h2>Modlist Report ({{$.WabbajackSize}} compressed)</h2>
|
||||||
|
|
||||||
|
<h3>Inlined Data ({{$.TotalInlinedSize}}) </h3>
|
||||||
|
<table id="inlined-data" class="table table-striped table-bordered" style="width:100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>To</th>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Size</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{each $.InlinedData}}
|
||||||
|
<tr>
|
||||||
|
<td>{{$.To}}</td>
|
||||||
|
<td>{{$.Id}}</td>
|
||||||
|
<td>{{$.Size}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>Patch Data ({{$.TotalPatchSize}}) </h3>
|
||||||
|
<table id="patch-data" class="table table-striped table-bordered" style="width:100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>From</th>
|
||||||
|
<th>To</th>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Patch Size</th>
|
||||||
|
<th>Final Size</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{each $.PatchData}}
|
||||||
|
<tr>
|
||||||
|
<td>{{$.From}}</td>
|
||||||
|
<td>{{$.To}}</td>
|
||||||
|
<td>{{$.Id}}</td>
|
||||||
|
<td>{{$.PatchSize}}</td>
|
||||||
|
<td>{{$.FinalSize}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready( function () {
|
||||||
|
$("#inlined-data").DataTable({
|
||||||
|
columnDefs: [
|
||||||
|
{ type: 'file-size', targets: 2},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
|
||||||
|
$(document).ready( function () {
|
||||||
|
$("#patch-data").DataTable({
|
||||||
|
columnDefs: [
|
||||||
|
{ type: 'file-size', targets: 3},
|
||||||
|
{ type: 'file-size', targets: 4},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
109
Wabbajack.CLI/Verbs/ModlistReport.cs
Normal file
109
Wabbajack.CLI/Verbs/ModlistReport.cs
Normal file
@ -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<ModlistReport> _logger;
|
||||||
|
private readonly DTOSerializer _dtos;
|
||||||
|
|
||||||
|
public ModlistReport(ILogger<ModlistReport> logger, DTOSerializer dtos)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_dtos = dtos;
|
||||||
|
}
|
||||||
|
public Command MakeCommand()
|
||||||
|
{
|
||||||
|
var command = new Command("modlist-report");
|
||||||
|
command.Add(new Option<AbsolutePath>(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<string> 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<int> Run(AbsolutePath input)
|
||||||
|
{
|
||||||
|
|
||||||
|
_logger.LogInformation("Loading Modlist");
|
||||||
|
var modlist = await StandardInstaller.LoadFromFile(_dtos, input);
|
||||||
|
|
||||||
|
Dictionary<string, long> 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<CreateBSA>().ToDictionary(bsa => bsa.TempID.ToString());
|
||||||
|
|
||||||
|
var inlinedData = modlist.Directives.OfType<InlineFile>()
|
||||||
|
.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 $"<i> {bsa.To} </i> | {relPath}";
|
||||||
|
}
|
||||||
|
|
||||||
|
var patchData = modlist.Directives.OfType<PatchedFromArchive>()
|
||||||
|
.Select(e => new
|
||||||
|
{
|
||||||
|
From = $"<i> {archives[e.ArchiveHashPath.Hash]} </i> | {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;
|
||||||
|
}
|
||||||
|
}
|
@ -36,4 +36,9 @@
|
|||||||
<ProjectReference Include="..\Wabbajack.VFS\Wabbajack.VFS.csproj" />
|
<ProjectReference Include="..\Wabbajack.VFS\Wabbajack.VFS.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Resources\ModlistReport.html" />
|
||||||
|
<EmbeddedResource Include="Resources\ModlistReport.html" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -89,6 +89,7 @@ public struct DDS_HEADER
|
|||||||
return 9 * 4 + PixelFormat.GetSize() + 14 * 4;
|
return 9 * 4 + PixelFormat.GetSize() + 14 * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Write(BinaryWriter bw)
|
public void Write(BinaryWriter bw)
|
||||||
{
|
{
|
||||||
bw.Write(dwSize);
|
bw.Write(dwSize);
|
||||||
|
@ -439,6 +439,7 @@ public static class GameRegistry
|
|||||||
Game = Game.DragonsDogma,
|
Game = Game.DragonsDogma,
|
||||||
SteamIDs = new[] {367500 },
|
SteamIDs = new[] {367500 },
|
||||||
MO2Name = "Dragon's Dogma: Dark Arisen",
|
MO2Name = "Dragon's Dogma: Dark Arisen",
|
||||||
|
MO2ArchiveName = "dragonsdogma",
|
||||||
NexusName = "dragonsdogma",
|
NexusName = "dragonsdogma",
|
||||||
NexusGameId = 1249,
|
NexusGameId = 1249,
|
||||||
IsGenericMO2Plugin = true,
|
IsGenericMO2Plugin = true,
|
||||||
|
@ -99,7 +99,10 @@ public class NexusDownloader : ADownloader<Nexus>, IUrlDownloader
|
|||||||
{
|
{
|
||||||
if (iniData.TryGetValue("gameName", out var gameName) &&
|
if (iniData.TryGetValue("gameName", out var gameName) &&
|
||||||
iniData.TryGetValue("modID", out var modId) &&
|
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
|
return new Nexus
|
||||||
{
|
{
|
||||||
Game = GameRegistry.GetByMO2ArchiveName(gameName)!.Game,
|
Game = GameRegistry.GetByMO2ArchiveName(gameName)!.Game,
|
||||||
|
@ -5,7 +5,7 @@ namespace Wabbajack.Paths;
|
|||||||
|
|
||||||
public struct RelativePath : IPath, IEquatable<RelativePath>, IComparable<RelativePath>
|
public struct RelativePath : IPath, IEquatable<RelativePath>, IComparable<RelativePath>
|
||||||
{
|
{
|
||||||
internal readonly string[] Parts;
|
public readonly string[] Parts;
|
||||||
|
|
||||||
private int _hashCode = 0;
|
private int _hashCode = 0;
|
||||||
|
|
||||||
@ -14,6 +14,11 @@ public struct RelativePath : IPath, IEquatable<RelativePath>, IComparable<Relati
|
|||||||
Parts = parts;
|
Parts = parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RelativePath FromParts(string[] parts)
|
||||||
|
{
|
||||||
|
return new RelativePath(parts);
|
||||||
|
}
|
||||||
|
|
||||||
public static explicit operator RelativePath(string i)
|
public static explicit operator RelativePath(string i)
|
||||||
{
|
{
|
||||||
var splits = i.Split(AbsolutePath.StringSplits, StringSplitOptions.RemoveEmptyEntries);
|
var splits = i.Split(AbsolutePath.StringSplits, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
Loading…
Reference in New Issue
Block a user