public Action Stage(IEnumerable <VirtualFile> files) { var grouped = files.SelectMany(f => f.FilesInPath) .Distinct() .Where(f => f.ParentArchive != null) .GroupBy(f => f.ParentArchive) .OrderBy(f => f.Key == null ? 0 : f.Key.Paths.Length) .ToList(); List <string> Paths = new List <string>(); foreach (var group in grouped) { var tmp_path = Path.Combine(_stagedRoot, Guid.NewGuid().ToString()); FileExtractor.ExtractAll(group.Key.StagedPath, tmp_path); Paths.Add(tmp_path); foreach (var file in group) { file._stagedPath = Path.Combine(tmp_path, file.Paths[group.Key.Paths.Length]); } } return(() => { Paths.Do(p => { if (Directory.Exists(p)) { DeleteDirectory(p); } }); }); }
private void DownloadAndInstall(string url, string filename, string mod_name = null) { var src = Path.Combine(DOWNLOAD_FOLDER, filename); if (!File.Exists(src)) { var state = DownloadDispatcher.ResolveArchive(url); state.Download(new Archive() { Name = "Unknown" }, src); } if (!Directory.Exists(utils.DownloadsFolder)) { Directory.CreateDirectory(utils.DownloadsFolder); } File.Copy(src, Path.Combine(utils.DownloadsFolder, filename)); if (mod_name == null) { FileExtractor.ExtractAll(src, utils.MO2Folder); } else { FileExtractor.ExtractAll(src, Path.Combine(utils.ModsFolder, mod_name)); } }
private void DownloadAndInstall(Game game, int modid, string mod_name) { utils.AddMod(mod_name); var client = new NexusApiClient(); var file = client.GetModFiles(game, modid).First(f => f.is_primary); var src = Path.Combine(DOWNLOAD_FOLDER, file.file_name); var ini = string.Join("\n", new List <string> { "[General]", $"gameName={GameRegistry.Games[game].MO2ArchiveName}", $"modID={modid}", $"fileID={file.file_id}" }); if (!File.Exists(file.file_name)) { var state = DownloadDispatcher.ResolveArchive(ini.LoadIniString()); state.Download(src); } if (!Directory.Exists(utils.DownloadsFolder)) { Directory.CreateDirectory(utils.DownloadsFolder); } var dest = Path.Combine(utils.DownloadsFolder, file.file_name); File.Copy(src, dest); FileExtractor.ExtractAll(src, Path.Combine(utils.ModsFolder, mod_name)); File.WriteAllText(dest + ".meta", ini); }
private void UpdateArchive(VirtualFile f) { if (!f.IsStaged) { throw new InvalidDataException("Can't analyze an unstaged file"); } var tmp_dir = Path.Combine(_stagedRoot, Guid.NewGuid().ToString()); Utils.Status($"Extracting Archive {Path.GetFileName(f.StagedPath)}"); FileExtractor.ExtractAll(f.StagedPath, tmp_dir); Utils.Status($"Updating Archive {Path.GetFileName(f.StagedPath)}"); var entries = Directory.EnumerateFiles(tmp_dir, "*", SearchOption.AllDirectories) .Select(path => path.RelativeTo(tmp_dir)); var new_files = entries.Select(e => { var new_path = new string[f.Paths.Length + 1]; f.Paths.CopyTo(new_path, 0); new_path[f.Paths.Length] = e; var nf = new VirtualFile { Paths = new_path }; nf._stagedPath = Path.Combine(tmp_dir, e); Add(nf); return(nf); }).ToList(); // Analyze them new_files.PMap(file => { Utils.Status($"Analyzing {Path.GetFileName(file.StagedPath)}"); file.Analyze(); }); // Recurse into any archives in this archive new_files.Where(file => file.IsArchive).Do(file => UpdateArchive(file)); f.FinishedIndexing = true; if (!_isSyncing) { SyncToDisk(); } Utils.Status("Cleaning Directory"); DeleteDirectory(tmp_dir); }
/// <summary> /// We bundle the cef libs inside the .exe, we need to extract them before loading any wpf code that requires them /// </summary> private static void ExtractLibs() { if (File.Exists("cefsharp.7z") && File.Exists("libcef.dll")) { return; } using (var fs = File.Open("cefsharp.7z", System.IO.FileMode.Create)) using (var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream("Wabbajack.Lib.LibCefHelpers.cefsharp.7z")) { rs.CopyTo(fs); Utils.Log("Extracting libCef files"); } using (var wq = new WorkQueue(1)) { FileExtractor.ExtractAll(wq, "cefsharp.7z", ".").Wait(); } }
/// <summary> /// We bundle the cef libs inside the .exe, we need to extract them before loading any wpf code that requires them /// </summary> private static async Task ExtractLibs() { if (File.Exists("cefglue.7z") && File.Exists("libcef.dll")) { return; } using (var fs = File.OpenWrite("cefglue.7z")) using (var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream("Wabbajack.Lib.LibCefHelpers.cefglue.7z")) { rs.CopyTo(fs); Utils.Log("Extracting libCef files"); } using (var wq = new WorkQueue(1)) { await FileExtractor.ExtractAll(wq, "cefglue.7z", "."); } }
private async Task DownloadAndInstall(string url, string filename, string mod_name = null) { var src = Path.Combine(DOWNLOAD_FOLDER, filename); if (!File.Exists(src)) { var state = DownloadDispatcher.ResolveArchive(url); await state.Download(new Archive { Name = "Unknown" }, src); } if (!Directory.Exists(utils.DownloadsFolder)) { Directory.CreateDirectory(utils.DownloadsFolder); } await Utils.CopyFileAsync(src, Path.Combine(utils.DownloadsFolder, filename)); await FileExtractor.ExtractAll(Queue, src, mod_name == null?utils.MO2Folder : Path.Combine(utils.ModsFolder, mod_name)); }
private async Task <(string Download, string ModFolder)> DownloadAndInstall(Game game, int modid, string mod_name) { utils.AddMod(mod_name); var client = await NexusApiClient.Get(); var resp = await client.GetModFiles(game, modid); var file = resp.files.FirstOrDefault(f => f.is_primary) ?? resp.files.FirstOrDefault(f => !string.IsNullOrEmpty(f.category_name)); var src = Path.Combine(DOWNLOAD_FOLDER, file.file_name); var ini = string.Join("\n", new List <string> { "[General]", $"gameName={game.MetaData().MO2ArchiveName}", $"modID={modid}", $"fileID={file.file_id}" }); if (!File.Exists(src)) { var state = (AbstractDownloadState)await DownloadDispatcher.ResolveArchive(ini.LoadIniString()); await state.Download(src); } if (!Directory.Exists(utils.DownloadsFolder)) { Directory.CreateDirectory(utils.DownloadsFolder); } var dest = Path.Combine(utils.DownloadsFolder, file.file_name); await Utils.CopyFileAsync(src, dest); var modFolder = Path.Combine(utils.ModsFolder, mod_name); await FileExtractor.ExtractAll(Queue, src, modFolder); File.WriteAllText(dest + Consts.MetaFileExtension, ini); return(dest, modFolder); }
[InlineData(Game.Fallout4, 43474)] // EM 2 Rifle public async Task BSACompressionRecompression(Game game, int modid) { var filename = await DownloadMod(game, modid); var folder = _bsaFolder.Combine(game.ToString(), modid.ToString()); await folder.DeleteDirectory(); folder.CreateDirectory(); await using var files = await FileExtractor.ExtractAll(Queue, filename); await files.MoveAllTo(folder); foreach (var bsa in folder.EnumerateFiles().Where(f => Consts.SupportedBSAs.Contains(f.Extension))) { TestContext.WriteLine($"From {bsa}"); TestContext.WriteLine("Cleaning Output Dir"); await _tempDir.DeleteDirectory(); _tempDir.CreateDirectory(); TestContext.WriteLine($"Reading {bsa}"); var tempFile = ((RelativePath)"tmp.bsa").RelativeToEntryPoint(); var size = bsa.Size; await using var a = BSADispatch.OpenRead(bsa); await a.Files.PMap(Queue, file => { var absName = _tempDir.Combine(file.Path); ViaJson(file.State); absName.Parent.CreateDirectory(); using (var fs = absName.Create()) { file.CopyDataTo(fs); } Assert.Equal(file.Size, absName.Size); }); // Check Files should be case insensitive Assert.Equal(a.Files.Count(), a.Files.Select(f => f.Path).ToHashSet().Count); Assert.Equal(a.Files.Count(), a.Files.Select(f => f.Path.ToString().ToLowerInvariant()).ToHashSet().Count); TestContext.WriteLine($"Building {bsa}"); await using (var w = ViaJson(a.State).MakeBuilder(size)) { var streams = await a.Files.PMap(Queue, async file => { var absPath = _tempDir.Combine(file.Path); var str = absPath.OpenRead(); await w.AddFile(ViaJson(file.State), str); return(str); }); await w.Build(tempFile); streams.Do(s => s.Dispose()); } TestContext.WriteLine($"Verifying {bsa}"); await using var b = BSADispatch.OpenRead(tempFile); TestContext.WriteLine($"Performing A/B tests on {bsa}"); Assert.Equal(a.State.ToJson(), b.State.ToJson()); // Check same number of files Assert.Equal(a.Files.Count(), b.Files.Count()); await a.Files.Zip(b.Files, (ai, bi) => (ai, bi)) .PMap(Queue, pair => { Assert.Equal(pair.ai.State.ToJson(), pair.bi.State.ToJson()); //Console.WriteLine($" - {pair.ai.Path}"); Assert.Equal(pair.ai.Path, pair.bi.Path); //Equal(pair.ai.Compressed, pair.bi.Compressed); Assert.Equal(pair.ai.Size, pair.bi.Size); Assert.Equal(GetData(pair.ai), GetData(pair.bi)); }); } }
public async Task ExtractModlist() { ExtractedModListFiles = await FileExtractor.ExtractAll(Queue, ModListArchive); }