Esempio n. 1
0
 public static async Task ExtractAll(WorkQueue queue, string source, string dest)
 {
     try
     {
         if (Consts.SupportedBSAs.Any(b => source.ToLower().EndsWith(b)))
         {
             await ExtractAllWithBSA(queue, source, dest);
         }
         else if (source.EndsWith(".omod"))
         {
             ExtractAllWithOMOD(source, dest);
         }
         else if (source.EndsWith(".exe"))
         {
             ExtractAllWithInno(source, dest);
         }
         else
         {
             ExtractAllWith7Zip(source, dest);
         }
     }
     catch (Exception ex)
     {
         Utils.ErrorThrow(ex, $"Error while extracting {source}");
     }
 }
Esempio n. 2
0
 public static async Task <ExtractedFiles> ExtractAll(WorkQueue queue, AbsolutePath source, IEnumerable <RelativePath> OnlyFiles = null)
 {
     try
     {
         if (Consts.SupportedBSAs.Contains(source.Extension))
         {
             return(await ExtractAllWithBSA(queue, source));
         }
         else if (source.Extension == Consts.OMOD)
         {
             return(await ExtractAllWithOMOD(source));
         }
         else if (source.Extension == Consts.EXE)
         {
             return(await ExtractAllExe(source));
         }
         else
         {
             return(await ExtractAllWith7Zip(source, OnlyFiles));
         }
     }
     catch (Exception ex)
     {
         Utils.ErrorThrow(ex, $"Error while extracting {source}");
         throw new Exception();
     }
 }
Esempio n. 3
0
        private static async Task ExtractAllWithBSA(WorkQueue queue, string source, string dest)
        {
            try
            {
                using (var arch = BSADispatch.OpenRead(source))
                {
                    await arch.Files
                    .PMap(queue, f =>
                    {
                        var path = f.Path;
                        if (f.Path.StartsWith("\\"))
                        {
                            path = f.Path.Substring(1);
                        }
                        Utils.Status($"Extracting {path}");
                        var outPath = Path.Combine(dest, path);
                        var parent  = Path.GetDirectoryName(outPath);

                        if (!Directory.Exists(parent))
                        {
                            Directory.CreateDirectory(parent);
                        }

                        using (var fs = File.Open(outPath, System.IO.FileMode.Create))
                        {
                            f.CopyDataTo(fs);
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                Utils.ErrorThrow(ex, $"While Extracting {source}");
            }
        }
Esempio n. 4
0
 public static async Task ExtractAll(WorkQueue queue, AbsolutePath source, AbsolutePath dest)
 {
     try
     {
         if (Consts.SupportedBSAs.Contains(source.Extension))
         {
             await ExtractAllWithBSA(queue, source, dest);
         }
         else if (source.Extension == Consts.OMOD)
         {
             ExtractAllWithOMOD(source, dest);
         }
         else if (source.Extension == Consts.EXE)
         {
             await ExtractAllExe(source, dest);
         }
         else
         {
             await ExtractAllWith7Zip(source, dest);
         }
     }
     catch (Exception ex)
     {
         Utils.ErrorThrow(ex, $"Error while extracting {source}");
     }
 }
Esempio n. 5
0
        private static async Task ExtractAllWithBSA(WorkQueue queue, AbsolutePath source, AbsolutePath dest)
        {
            try
            {
                using var arch = BSADispatch.OpenRead(source);
                await arch.Files
                .PMap(queue, f =>
                {
                    Utils.Status($"Extracting {(string)f.Path}");
                    var outPath = f.Path.RelativeTo(dest);
                    var parent  = outPath.Parent;

                    if (!parent.IsDirectory)
                    {
                        parent.CreateDirectory();
                    }

                    using var fs = outPath.Create();
                    f.CopyDataTo(fs);
                });
            }
            catch (Exception ex)
            {
                Utils.ErrorThrow(ex, $"While Extracting {source}");
            }
        }
Esempio n. 6
0
 private static async Task <ExtractedFiles> ExtractAllWithBSA(WorkQueue queue, AbsolutePath source)
 {
     try
     {
         await using var arch = BSADispatch.OpenRead(source);
         var files = arch.Files.ToDictionary(f => f.Path, f => (IExtractedFile) new ExtractedBSAFile(f));
         return(new ExtractedFiles(files, arch));
     }
     catch (Exception ex)
     {
         Utils.ErrorThrow(ex, $"While Extracting {source}");
         throw new Exception();
     }
 }
Esempio n. 7
0
        private static async Task <Dictionary <RelativePath, T> > GatheringExtractWith7Zip <T>(WorkQueue queue, IStreamFactory sf, Definitions.FileType sig, Predicate <RelativePath> shouldExtract, Func <RelativePath, IExtractedFile, ValueTask <T> > mapfn,
                                                                                               AbsolutePath tempPath, HashSet <RelativePath> onlyFiles)
        {
            TempFile tmpFile = null;
            var      dest    = tempPath.Combine(Guid.NewGuid().ToString());

            dest.CreateDirectory();

            TempFile     spoolFile = null;
            AbsolutePath source;

            try
            {
                if (sf.Name is AbsolutePath abs)
                {
                    source = abs;
                }
                else
                {
                    spoolFile = new TempFile(tempPath.Combine(Guid.NewGuid().ToString())
                                             .WithExtension(source.Extension));
                    await using var s = await sf.GetStream();

                    await spoolFile.Path.WriteAllAsync(s);

                    source = spoolFile.Path;
                }

                Utils.Log(new GenericInfo($"Extracting {(string)source.FileName}",
                                          $"The contents of {(string)source.FileName} are being extracted to {(string)source.FileName} using 7zip.exe"));

                var process = new ProcessHelper {
                    Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint),
                };

                if (onlyFiles != null)
                {
                    //It's stupid that we have to do this, but 7zip's file pattern matching isn't very fuzzy
                    IEnumerable <string> AllVariants(string input)
                    {
                        yield return($"\"{input}\"");

                        yield return($"\"\\{input}\"");
                    }

                    tmpFile = new TempFile();
                    await tmpFile.Path.WriteAllLinesAsync(onlyFiles.SelectMany(f => AllVariants((string)f)).ToArray());

                    process.Arguments = new object[]
                    {
                        "x", "-bsp1", "-y", $"-o\"{dest}\"", source, $"@\"{tmpFile.Path}\"", "-mmt=off"
                    };
                }
                else
                {
                    process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest}\"", source, "-mmt=off" };
                }


                var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output)
                             .ForEachAsync(p =>
                {
                    var(_, line) = p;
                    if (line == null)
                    {
                        return;
                    }

                    if (line.Length <= 4 || line[3] != '%')
                    {
                        return;
                    }

                    int.TryParse(line.Substring(0, 3), out var percentInt);
                    Utils.Status($"Extracting {(string)source.FileName} - {line.Trim()}",
                                 Percent.FactoryPutInRange(percentInt / 100d));
                });

                var exitCode = await process.Start();


                if (exitCode != 0)
                {
                    Utils.ErrorThrow(new _7zipReturnError(exitCode, source, dest, ""));
                }
                else
                {
                    Utils.Status($"Extracting {source.FileName} - done", Percent.One, alsoLog: true);
                }

                var results = await dest.EnumerateFiles()
                              .PMap(queue, async f =>
                {
                    var path = f.RelativeTo(dest);
                    if (!shouldExtract(path))
                    {
                        return(((RelativePath, T)) default);