예제 #1
0
        public static int DumpTask(string path /*, bool all, bool strings*/, bool imports /*, bool buffers, bool chunks*/)
        {
            // initial checks
            var isDirectory   = false;
            var inputFileInfo = new FileInfo(path);
            var inputDirInfo  = new DirectoryInfo(path);

            if (!inputFileInfo.Exists)
            {
                if (!inputDirInfo.Exists)
                {
                    return(0);
                }
                else
                {
                    isDirectory = true;
                }
            }

            var archives = new List <Archive>();

            if (isDirectory)
            {
                archives.AddRange(inputDirInfo
                                  .GetFiles("*.archive", SearchOption.AllDirectories)
                                  .Select(_ => new Archive(_.FullName)));
            }
            else
            {
                archives.Add(new Archive(inputFileInfo.FullName));
            }

            if (imports /*|| strings || buffers || chunks || all*/)
            {
                foreach (var ar in archives)
                {
                    using var mmf = MemoryMappedFile.CreateFromFile(ar._filepath, FileMode.Open, ar._filepath.GetHashMD5(), 0,
                                                                    MemoryMappedFileAccess.Read);
                    var fileDictionary = new ConcurrentDictionary <ulong, Cr2wDumpObject>();
                    foreach (var(key, value) in ar.HashDictionary)
                    {
                        fileDictionary[key] = new Cr2wDumpObject();
                    }

                    using var pb = new ProgressBar();
                    using var p1 = pb.Progress.Fork();

                    int progress = 0;

                    var count = ar.HashDictionary.Count;
                    Parallel.For(0, count, new ParallelOptions {
                        MaxDegreeOfParallelism = 8
                    }, i =>
                    {
                        var key = ar.GetHashFromIndex(i);

                        var f = ar.GetFileData((int)i, mmf);

                        // check if cr2w file
                        if (f.Length < 4)
                        {
                            return;
                        }

                        var id = f.Take(4);
                        if (!id.SequenceEqual(MAGIC))
                        {
                            return;
                        }
                        else
                        {
                        }

                        try
                        {
                            var cr2w = new CR2WFile();

                            using var ms = new MemoryStream(f);
                            using var br = new BinaryReader(ms);
                            cr2w.ReadImportsAndBuffers(br);

                            var obj = new Cr2wDumpObject {
                                Filename = key.ToString()
                            };

                            //if (strings || all)
                            //    obj.Stringdict = cr2w.StringDictionary;
                            if (imports /*|| all*/)
                            {
                                obj.Imports = cr2w.Imports;
                            }
                            //if (buffers || all)
                            //    obj.Buffers = cr2w.Buffers;
                            //if (chunks || all)
                            //    obj.Chunks = cr2w.Chunks;

                            //fileDictionary[key] = obj;
                            fileDictionary.AddOrUpdate(key, obj, (arg1, o) => obj);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"Could not read file {key}.");
                            //throw;
                            return;
                        }
                        finally
                        {
                            progress += 1;
                            var perc  = progress / (double)count;
                            p1.Report(perc, $"Loading bundle entries: {progress}/{count}");
                        }
                    });


                    var arobj = new ArchiveDumpObject()
                    {
                        Filename       = ar._filepath,
                        FileDictionary = fileDictionary
                    };


                    // write
                    using var writer  = File.CreateText($"{ar._filepath}.imports.txt");
                    using var hwriter = File.CreateText($"{ar._filepath}.hashes.csv");
                    hwriter.WriteLine("String,Hash");
                    List <string> allimports = new List <string>();

                    foreach (var(key, value) in arobj.FileDictionary)
                    {
                        if (value.Imports == null)
                        {
                            continue;
                        }
                        foreach (var import in value.Imports)
                        {
                            allimports.Add(import.DepotPathStr);
                        }
                    }

                    foreach (var str in allimports.Distinct())
                    {
                        writer.WriteLine(str);
                        var hash = FNV1A64HashAlgorithm.HashString(str);
                        hwriter.WriteLine($"{str},{hash}");
                    }



                    Console.WriteLine($"Finished. Dump file written to {ar._filepath}.");
                }
            }

            return(1);
        }
예제 #2
0
        public static int DumpTask(string path, bool imports, bool missinghashes)
        {
            #region checks

            var isDirectory   = false;
            var inputFileInfo = new FileInfo(path);
            var inputDirInfo  = new DirectoryInfo(path);
            if (!inputFileInfo.Exists)
            {
                if (!inputDirInfo.Exists)
                {
                    return(0);
                }
                else
                {
                    isDirectory = true;
                }
            }

            var archives = new List <Archive>();

            if (isDirectory)
            {
                archives.AddRange(inputDirInfo
                                  .GetFiles("*.archive", SearchOption.AllDirectories)
                                  .Select(_ => new Archive(_.FullName)));
            }
            else
            {
                archives.Add(new Archive(inputFileInfo.FullName));
            }

            #endregion


            var missinghashtxt = isDirectory
                ? Path.Combine(inputDirInfo.FullName, "missinghashes.txt")
                : $"{inputFileInfo.FullName}.missinghashes.txt";
            using var mwriter = File.CreateText(missinghashtxt);

            foreach (var ar in archives)
            {
                using var pb = new ProgressBar();
                if (imports)
                {
                    using var mmf = MemoryMappedFile.CreateFromFile(ar.Filepath, FileMode.Open,
                                                                    ar.Filepath.GetHashMD5(), 0,
                                                                    MemoryMappedFileAccess.Read);
                    using var p1 = pb.Progress.Fork();
                    int progress = 0;

                    var fileDictionary = new ConcurrentDictionary <ulong, Cr2wDumpObject>();
                    foreach (var(hash, value) in ar.Files)
                    {
                        fileDictionary[hash] = new Cr2wDumpObject();
                    }

                    // get info
                    var count = ar.FileCount;
                    Parallel.For(0, count, new ParallelOptions {
                        MaxDegreeOfParallelism = 8
                    }, i =>
                    {
                        var entry       = ar.Files.ToList()[i];
                        var hash        = entry.Key;
                        var(f, buffers) = ar.GetFileData(hash, mmf);

                        // check if cr2w file
                        if (f.Length < 4)
                        {
                            return;
                        }
                        var id = f.Take(4);
                        if (!id.SequenceEqual(MAGIC))
                        {
                            return;
                        }

                        var cr2w = new CR2WFile();

                        using var ms = new MemoryStream(f);
                        using var br = new BinaryReader(ms);
                        cr2w.ReadImportsAndBuffers(br);

                        var obj = new Cr2wDumpObject
                        {
                            Filename = hash.ToString(),
                            Imports  = cr2w.Imports
                        };


                        fileDictionary.AddOrUpdate(hash, obj, (arg1, o) => obj);

                        progress += 1;
                        var perc  = progress / (double)count;
                        p1.Report(perc, $"Loading bundle entries: {progress}/{count}");
                    });

                    // write
                    var arobj = new ArchiveDumpObject()
                    {
                        Filename       = ar.Filepath,
                        FileDictionary = fileDictionary
                    };

                    using var writer  = File.CreateText($"{ar.Filepath}.imports.txt");
                    using var hwriter = File.CreateText($"{ar.Filepath}.hashes.csv");
                    hwriter.WriteLine("String,Hash");
                    List <string> allimports = new List <string>();

                    foreach (var(key, value) in arobj.FileDictionary)
                    {
                        if (value.Imports == null)
                        {
                            continue;
                        }
                        allimports.AddRange(value.Imports.Select(import => import.DepotPathStr));
                    }
                    foreach (var str in allimports.Distinct())
                    {
                        writer.WriteLine(str);
                        var hash = FNV1A64HashAlgorithm.HashString(str);
                        hwriter.WriteLine($"{str},{hash}");
                    }

                    Console.WriteLine($"Finished. Dump file written to {ar.Filepath}.");
                }

                if (missinghashes)
                {
                    foreach (var(hash, fileInfoEntry) in ar.Files)
                    {
                        if (fileInfoEntry.NameStr == hash.ToString())
                        {
                            mwriter.WriteLine(hash);
                        }
                    }
                }
            }


            return(1);
        }