diff --git a/Wabbajack.Compiler/ACompiler.cs b/Wabbajack.Compiler/ACompiler.cs index b6121d6d..3feb744e 100644 --- a/Wabbajack.Compiler/ACompiler.cs +++ b/Wabbajack.Compiler/ACompiler.cs @@ -51,6 +51,7 @@ public abstract class ACompiler public ConcurrentDictionary _sourceFileLinks; private string _statusText; + private string _statusCategory; public List IndexedArchives = new(); public Dictionary> IndexedFiles = new(); @@ -106,16 +107,17 @@ public abstract class ACompiler public event EventHandler OnStatusUpdate; - public void NextStep(string statusText, long maxStepProgress = 1) + public void NextStep(string statusCategory, string statusText, long maxStepProgress = 1) { _updateStopWatch.Restart(); _maxStepProgress = maxStepProgress; _currentStep += 1; _statusText = statusText; + _statusCategory = statusCategory; _logger.LogInformation("Compiler Step: {Step}", statusText); if (OnStatusUpdate != null) - OnStatusUpdate(this, new StatusUpdate($"[{_currentStep}/{MaxSteps}] " + statusText, + OnStatusUpdate(this, new StatusUpdate(statusCategory, $"[{_currentStep}/{MaxSteps}] " + statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps), Percent.Zero)); } @@ -131,7 +133,7 @@ public abstract class ACompiler } if (OnStatusUpdate != null) - OnStatusUpdate(this, new StatusUpdate(_statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps), + OnStatusUpdate(this, new StatusUpdate(_statusCategory, _statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps), Percent.FactoryPutInRange(_currentStepProgress, _maxStepProgress))); } @@ -195,7 +197,7 @@ public abstract class ACompiler public async Task GatherMetaData() { _logger.LogInformation("Getting meta data for {count} archives", SelectedArchives.Count); - NextStep("Gathering Metadata", SelectedArchives.Count); + NextStep("Building", "Gathering Metadata", SelectedArchives.Count); await SelectedArchives.PDoAll(CompilerLimiter, async a => { UpdateProgress(1); @@ -208,7 +210,7 @@ public abstract class ACompiler protected async Task IndexGameFileHashes() { - NextStep("Indexing Game Files"); + NextStep("Compiling", "Indexing Game Files"); if (_settings.UseGamePaths) { //taking the games in Settings.IncludedGames + currently compiling game so you can eg @@ -258,7 +260,7 @@ public abstract class ACompiler protected async Task CleanInvalidArchivesAndFillState() { - NextStep("Cleaning Invalid Archives"); + NextStep("Compiling", "Cleaning Invalid Archives"); var remove = await IndexedArchives.PMapAll(CompilerLimiter, async a => { try @@ -313,7 +315,7 @@ public abstract class ACompiler .Where(f => f.FileExists()) .ToList(); - NextStep("InferMetas", toFind.Count); + NextStep("Initializing", "InferMetas", toFind.Count); if (toFind.Count == 0) return; _logger.LogInformation("Attempting to infer {count} metas from the server.", toFind.Count); @@ -353,7 +355,7 @@ public abstract class ACompiler protected async Task ExportModList(CancellationToken token) { - NextStep("Exporting Modlist"); + NextStep("Finalizing", "Exporting Modlist"); _logger.LogInformation("Exporting ModList to {location}", _settings.OutputFile); // Modify readme and ModList image to relative paths if they exist @@ -431,7 +433,7 @@ public abstract class ACompiler })) .ToArray(); - NextStep("Generating Patches", toBuild.Length); + NextStep("Compiling","Generating Patches", toBuild.Length); if (toBuild.Length == 0) return; // Extract all the source files @@ -512,7 +514,7 @@ public abstract class ACompiler public async Task GenerateManifest() { - NextStep("Generating Manifest"); + NextStep("Finalizing", "Generating Manifest"); var manifest = new Manifest(ModList); await using var of = _settings.OutputFile.Open(FileMode.Create, FileAccess.Write); await _dtos.Serialize(manifest, of); @@ -520,7 +522,7 @@ public abstract class ACompiler public async Task GatherArchives() { - NextStep("Gathering Archives"); + NextStep("Building", "Gathering Archives"); _logger.LogInformation("Building a list of archives based on the files required"); var hashes = InstallDirectives.OfType() @@ -621,7 +623,7 @@ public abstract class ACompiler .GroupBy(f => _sourceFileLinks[f].File) .ToDictionary(k => k.Key); - NextStep("Inlining Files"); + NextStep("Building", "Inlining Files"); if (grouped.Count == 0) return; await _vfs.Extract(grouped.Keys.ToHashSet(), async (vf, sfn) => { diff --git a/Wabbajack.Compiler/MO2Compiler.cs b/Wabbajack.Compiler/MO2Compiler.cs index e03f80e6..c72a515d 100644 --- a/Wabbajack.Compiler/MO2Compiler.cs +++ b/Wabbajack.Compiler/MO2Compiler.cs @@ -59,12 +59,12 @@ public class MO2Compiler : ACompiler var roots = new List {Settings.Source, Settings.Downloads}; roots.AddRange(Settings.OtherGames.Append(Settings.Game).Select(g => _locator.GameLocation(g))); - NextStep("Add Roots"); + NextStep("Initializing", "Add Roots"); await _vfs.AddRoots(roots, token); // Step 1 await InferMetas(token); // Step 2 - NextStep("Add Download Roots"); + NextStep("Initializing", "Add Download Roots"); await _vfs.AddRoot(Settings.Downloads, token); // Step 3 // Find all Downloads @@ -125,14 +125,14 @@ public class MO2Compiler : ACompiler var stack = MakeStack(); - NextStep("Running Compilation Stack", AllFiles.Count); + NextStep("Compiling", "Running Compilation Stack", AllFiles.Count); var results = await AllFiles.PMapAll(CompilerLimiter, f => { UpdateProgress(1); return RunStack(stack, f); }).ToList(); - NextStep("Updating Extra files"); + NextStep("Compiling", "Updating Extra files"); // Add the extra files that were generated by the stack results = results.Concat(ExtraFiles).ToList(); @@ -184,7 +184,7 @@ public class MO2Compiler : ACompiler private async Task RunValidation(ModList modList) { - NextStep("Validating Archives", modList.Archives.Length); + NextStep("Finalizing", "Validating Archives", modList.Archives.Length); var allowList = await _wjClient.LoadDownloadAllowList(); foreach (var archive in modList.Archives) { diff --git a/Wabbajack.Installer/AInstaller.cs b/Wabbajack.Installer/AInstaller.cs index 7b926d48..bc962a22 100644 --- a/Wabbajack.Installer/AInstaller.cs +++ b/Wabbajack.Installer/AInstaller.cs @@ -26,7 +26,7 @@ using Wabbajack.VFS; namespace Wabbajack.Installer; -public record StatusUpdate(string StatusText, Percent StepsProgress, Percent StepProgress) +public record StatusUpdate(string StatusCategory, string StatusText, Percent StepsProgress, Percent StepProgress) { } @@ -57,6 +57,7 @@ public abstract class AInstaller protected long MaxStepProgress { get; set; } + private string _statusCategory; private string _statusText; private readonly Stopwatch _updateStopWatch = new(); @@ -92,15 +93,16 @@ public abstract class AInstaller public ModList ModList => _configuration.ModList; - public void NextStep(string statusText, long maxStepProgress) + public void NextStep(string statusCategory, string statusText, long maxStepProgress) { _updateStopWatch.Restart(); MaxStepProgress = maxStepProgress; _currentStep += 1; _statusText = statusText; + _statusCategory = statusCategory; _logger.LogInformation("Next Step: {Step}", statusText); - OnStatusUpdate?.Invoke(new StatusUpdate($"[{_currentStep}/{MaxSteps}] " + statusText, + OnStatusUpdate?.Invoke(new StatusUpdate(statusCategory, statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps), Percent.Zero)); } @@ -108,8 +110,7 @@ public abstract class AInstaller { Interlocked.Add(ref _currentStepProgress, stepProgress); - OnStatusUpdate?.Invoke(new StatusUpdate($"[{_currentStep}/{MaxSteps}] " + _statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps), - Percent.FactoryPutInRange(_currentStepProgress, MaxStepProgress))); + OnStatusUpdate?.Invoke(new StatusUpdate(_statusCategory, _statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps), Percent.FactoryPutInRange(_currentStepProgress, MaxStepProgress))); } public abstract Task Begin(CancellationToken token); @@ -119,7 +120,7 @@ public abstract class AInstaller ExtractedModlistFolder = _manager.CreateFolder(); await using var stream = _configuration.ModlistArchive.Open(FileMode.Open, FileAccess.Read, FileShare.Read); using var archive = new ZipArchive(stream, ZipArchiveMode.Read); - NextStep("Extracting Modlist", archive.Entries.Count); + NextStep("Preparing","Extracting Modlist", archive.Entries.Count); foreach (var entry in archive.Entries) { var path = entry.FullName.ToRelativePath().RelativeTo(ExtractedModlistFolder); @@ -181,7 +182,7 @@ public abstract class AInstaller /// protected async Task PrimeVFS() { - NextStep("Priming VFS", 0); + NextStep("Preparing","Priming VFS", 0); _vfs.AddKnown(_configuration.ModList.Directives.OfType().Select(d => d.ArchiveHashPath), HashedArchives); await _vfs.BackfillMissing(); @@ -189,7 +190,7 @@ public abstract class AInstaller public async Task BuildFolderStructure() { - NextStep("Building Folder Structure", 0); + NextStep("Preparing", "Building Folder Structure", 0); _logger.LogInformation("Building Folder Structure"); ModList.Directives .Where(d => d.To.Depth > 1) @@ -200,7 +201,7 @@ public abstract class AInstaller public async Task InstallArchives(CancellationToken token) { - NextStep("Installing files", ModList.Directives.Sum(d => d.Size)); + NextStep("Installing", "Installing files", ModList.Directives.Sum(d => d.Size)); var grouped = ModList.Directives .OfType() .Select(a => new {VF = _vfs.Index.FileForArchiveHashPath(a.ArchiveHashPath), Directive = a}) @@ -302,7 +303,7 @@ public abstract class AInstaller } _logger.LogInformation("Downloading {count} archives", missing.Count); - NextStep("Downloading files", missing.Count); + NextStep("Downloading", "Downloading files", missing.Count); await missing .OrderBy(a => a.Size) @@ -363,7 +364,7 @@ public abstract class AInstaller public async Task HashArchives(CancellationToken token) { - NextStep("Hashing Archives", 0); + NextStep("Hashing", "Hashing Archives", 0); _logger.LogInformation("Looking for files to hash"); var allFiles = _configuration.Downloads.EnumerateFiles() @@ -414,7 +415,7 @@ public abstract class AInstaller var savePath = (RelativePath) "saves"; var existingFiles = _configuration.Install.EnumerateFiles().ToList(); - NextStep("Optimizing Modlist: Looking for files to delete", existingFiles.Count); + NextStep("Preparing", "Looking for files to delete", existingFiles.Count); await existingFiles .PDoAll(async f => { @@ -428,12 +429,12 @@ public abstract class AInstaller if (NoDeleteRegex.IsMatch(f.ToString())) return; - _logger.LogInformation("Deleting {relativeTo} it's not part of this ModList", relativeTo); + _logger.LogTrace("Deleting {relativeTo} it's not part of this ModList", relativeTo); f.Delete(); }); _logger.LogInformation("Cleaning empty folders"); - NextStep("Optimizing Modlist: Cleaning empty folders", indexed.Keys.Count); + NextStep("Preparing", "Cleaning empty folders", indexed.Keys.Count); var expectedFolders = (indexed.Keys .Select(f => f.RelativeTo(_configuration.Install)) // We ignore the last part of the path, so we need a dummy file name @@ -468,7 +469,7 @@ public abstract class AInstaller var existingfiles = _configuration.Install.EnumerateFiles().ToHashSet(); - NextStep("Optimizing Modlist: Removing redundant directives", indexed.Count); + NextStep("Preparing", "Removing redundant directives", indexed.Count); await indexed.Values.PMapAll(async d => { // Bit backwards, but we want to return null for @@ -487,7 +488,7 @@ public abstract class AInstaller _logger.LogInformation("Optimized {optimized} directives to {indexed} required", ModList.Directives.Length, indexed.Count); - NextStep("Finalizing modlist optimization", 0); + NextStep("Preparing", "Finalizing modlist optimization", 0); var requiredArchives = indexed.Values.OfType() .GroupBy(d => d.ArchiveHashPath.Hash) .Select(d => d.Key) diff --git a/Wabbajack.Installer/StandardInstaller.cs b/Wabbajack.Installer/StandardInstaller.cs index dfedc4bc..13de952a 100644 --- a/Wabbajack.Installer/StandardInstaller.cs +++ b/Wabbajack.Installer/StandardInstaller.cs @@ -61,7 +61,7 @@ public class StandardInstaller : AInstaller { if (token.IsCancellationRequested) return false; await _wjClient.SendMetric(MetricNames.BeginInstall, ModList.Name); - NextStep("Configuring Installer", 0); + NextStep("Preparing", "Configuring Installer", 0); _logger.LogInformation("Configuring Processor"); if (_configuration.GameFolder == default) @@ -145,7 +145,7 @@ public class StandardInstaller : AInstaller await ExtractedModlistFolder!.DisposeAsync(); await _wjClient.SendMetric(MetricNames.FinishInstall, ModList.Name); - NextStep("Finished", 1); + NextStep("Finished", "Finished", 1); _logger.LogInformation("Finished Installation"); return true; } @@ -275,7 +275,7 @@ public class StandardInstaller : AInstaller private async Task InstallIncludedFiles(CancellationToken token) { _logger.LogInformation("Writing inline files"); - NextStep("Installing Included Files", ModList.Directives.OfType().Count()); + NextStep("Installing", "Installing Included Files", ModList.Directives.OfType().Count()); await ModList.Directives .OfType() .PDoAll(async directive =>