Ejemplo n.º 1
0
        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);
                    }
                });
            });
        }
Ejemplo n.º 2
0
        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));
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        /// <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();
            }
        }
Ejemplo n.º 6
0
        /// <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", ".");
            }
        }
Ejemplo n.º 7
0
        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));
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        [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));
                });
            }
        }
Ejemplo n.º 10
0
 public async Task ExtractModlist()
 {
     ExtractedModListFiles = await FileExtractor.ExtractAll(Queue, ModListArchive);
 }