public async Task InstallArchives() { var grouped = ModList.Directives .OfType <FromArchive>() .Select(a => new { VF = VFS.Index.FileForArchiveHashPath(a.ArchiveHashPath), Directive = a }) .GroupBy(a => a.VF) .ToDictionary(a => a.Key); if (grouped.Count == 0) { return; } await VFS.Extract(Queue, grouped.Keys.ToHashSet(), async (vf, sf) => { foreach (var directive in grouped[vf]) { var file = directive.Directive; switch (file) { case PatchedFromArchive pfa: { await using var s = await sf.GetStream(); s.Position = 0; var patchData = await LoadBytesFromPath(pfa.PatchID); var toFile = file.To.RelativeTo(OutputFolder); { await using var os = await toFile.Create(); Utils.ApplyPatch(s, () => new MemoryStream(patchData), os); } if (await VirusScanner.ShouldScan(toFile) && await ClientAPI.GetVirusScanResult(toFile) == VirusScanner.Result.Malware) { await toFile.DeleteAsync(); Utils.ErrorThrow(new Exception($"Virus scan of patched executable reported possible malware: {toFile.ToString()} ({(long)await toFile.FileHashCachedAsync()})")); } } break; case FromArchive _: if (grouped[vf].Count() == 1) { await sf.Move(directive.Directive.To.RelativeTo(OutputFolder)); } else { await using var s = await sf.GetStream(); await directive.Directive.To.RelativeTo(OutputFolder).WriteAllAsync(s, false); } break; default: throw new Exception($"No handler for {directive}"); } if (file is PatchedFromArchive) { await file.To.RelativeTo(OutputFolder).FileHashAsync(); } else { file.To.RelativeTo(OutputFolder).FileHashWriteCache(file.Hash); } if (UseCompression) { Utils.Status($"Compacting {file.To}"); await file.To.RelativeTo(OutputFolder).Compact(FileCompaction.Algorithm.XPRESS16K); } } }, tempFolder : OutputFolder, updateTracker : UpdateTracker); }