Пример #1
0
        public UnpackedRenamedFileMapping LoadMappingData()
        {
            if (!fileInfo.Exists)
            {
                throw new Exception("Can't read from null file!");
            }

            log.Info("Loading renamed file mapping from file: " + fileInfo.FullName);

            UnpackedRenamedFileMapping mapping = new UnpackedRenamedFileMapping();

            using (FileStream fs = File.OpenRead(fileInfo.FullName))
            {
                int sig = fs.ReadByte();
                while (sig != -1)
                {
                    UnpackedRenamedFileMapping.RenamedFileMappingData data = new UnpackedRenamedFileMapping.RenamedFileMappingData();

                    data.ReadFromStream(fs, tempBuffer);

                    mapping[data.Key] = data;

                    sig = fs.ReadByte();
                }
            }

            return(mapping);
        }
Пример #2
0
        public override void LoadFromDisk()
        {
            status.stopwatch.Reset();
            status.stopwatch.Start();
            status.UpdateProgress(0f);
            log.Info("Loading unpacked bigfile from disk...");

            UnpackedFileKeyMappingFile mappingFile = new UnpackedFileKeyMappingFile(new DirectoryInfo(fileOrDirectory));

            renamedMapping = mappingFile.LoadMappingData();

            status.UpdateProgress(0.2f);

            SegmentHeader = segment.ReadSegmentHeader();
            FileHeader    = header.ReadHeader(ref SegmentHeader);

            log.Info(string.Format("Count info offset: {0:X8}", SegmentHeader.InfoOffset));
            version = BigFileVersions.GetVersion(FileHeader.BigFileVersion);
            fileUtil.BigFileVersion = version;
            filesAndFolders.Version = version;
            log.Info(string.Format("Version: {0:X4}", FileHeader.BigFileVersion));

            rawFolderInfos = filesAndFolders.ReadFolderInfos(ref SegmentHeader, ref FileHeader);
            rawFileInfos   = filesAndFolders.ReadFileInfos(ref SegmentHeader, ref FileHeader);

            fileUtil.BigFileVersion = version;
            filesAndFolders.Version = version;

            status.UpdateProgress(0.4f);

            rootFolder = fileUtil.CreateRootFolderTree(rawFolderInfos);
            fileMap    = fileUtil.CreateFileMappingData(rootFolder, rawFileInfos);
            fileUtil.MapFilesToFolders(rootFolder, fileMap);

            UnpackedFolderMapAndFilesList folderAndFiles = fileUtil.CreateFolderTreeAndFilesListFromDirectory(new DirectoryInfo(directory.FullName + "\\" + BigFileConst.UNPACK_DIR), renamedMapping, fileMap);

            rootFolder = folderAndFiles.folderMap[0];

            rawFileInfos   = folderAndFiles.filesList;
            rawFolderInfos = folderAndFiles.foldersList;

            status.UpdateProgress(0.6f);

            fileMap = fileUtil.CreateFileMappingData(folderAndFiles.folderMap[0], folderAndFiles.filesList);

            status.UpdateProgress(0.8f);

            fileUtil.MapFilesToFolders(rootFolder, fileMap);

            status.UpdateProgress(1.0f);

            status.stopwatch.Stop();
            log.Info("Unpacked bigfile loaded!");
            log.Info("  Time taken: " + status.TimeTaken + "ms");
        }
Пример #3
0
        public void SaveMappingData(UnpackedRenamedFileMapping mapping)
        {
            log.Info("Saving renamed mapping to file: " + fileInfo.FullName);

            using (FileStream fs = File.Create(fileInfo.FullName))
            {
                foreach (KeyValuePair <int, UnpackedRenamedFileMapping.RenamedFileMappingData> kvp in mapping.KeyMap)
                {
                    fs.WriteByte(0x1C);

                    kvp.Value.WriteToStream(fs, tempBuffer);
                }
            }
        }
Пример #4
0
        public UnpackedRenamedFileMapping CreateRenamedFileMapping(BigFileFolder folder, UnpackedRenamedFileMapping mapping = null, Dictionary <string, int> fileRenameCounts = null)
        {
            bool isFirst = mapping == null;

            if (isFirst)
            {
                mapping          = new UnpackedRenamedFileMapping();
                fileRenameCounts = new Dictionary <string, int>();
                stopwatch.Reset();
                stopwatch.Start();
            }

            foreach (BigFileFile file in folder.Files)
            {
                string fullName = file.FullFolderPath + file.Name;

                //if (extensionsList != null && extensionsList.ContainsKey(file.FileInfo.FileType))
                //{
                //    fullName += "." + extensionsList[file.FileInfo.FileType];
                //}
                //else
                //{
                fullName += string.Format(".{0}", file.FileInfo.FileType);
                //}

                string fullNameLower = fullName.ToLowerInvariant();

                if (fileRenameCounts.ContainsKey(fullNameLower))
                {
                    fileRenameCounts[fullNameLower]++;
                    fullName += "_" + fileRenameCounts[fullNameLower];
                }
                else
                {
                    fileRenameCounts.Add(fullNameLower, 1);
                }

                log.Debug(file.Name + " remapped to " + fullName);

                UnpackedRenamedFileMapping.RenamedFileMappingData data = new UnpackedRenamedFileMapping.RenamedFileMappingData()
                {
                    Key          = file.FileInfo.Key,
                    OriginalName = file.Name,
                    FileName     = fullName
                };

                mapping[file.FileInfo.Key] = data;
            }

            foreach (BigFileFolder childFolder in folder.SubFolders)
            {
                CreateRenamedFileMapping(childFolder, mapping, fileRenameCounts);
            }

            if (isFirst)
            {
                stopwatch.Stop();
                diagData.CreateRenamedFileMapping = stopwatch.ElapsedMilliseconds;
            }

            return(mapping);
        }
Пример #5
0
        public BigFileUnpackOperationStatus UnpackBigfile(BigFileUnpackOptions options)
        {
            if (options.Threads > MAX_UNPACK_THREADS)
            {
                log.Error(string.Format("Can't have more threads than the max! ({0} > {1})", options.Threads, MAX_UNPACK_THREADS));
                log.Error("    Threads will be clamped to the max!");
                options.Threads = MAX_UNPACK_THREADS;
            }

            log.Info("Unpacking a bigfile to directory: \"" + options.Directory.FullName + "\"");

            options.Log(log);

            if (!options.Directory.Exists)
            {
                log.Info("Directory does not exist, creating it...");
                Directory.CreateDirectory(options.Directory.FullName);
            }

            GenerateYetiMetadataFile(options.Directory, bigFile);

            DirectoryInfo unpackDir = new DirectoryInfo(options.Directory.FullName + "\\" + BigFileConst.UNPACK_DIR);

            log.Info("Creating unpack dir: " + unpackDir.FullName);
            Directory.CreateDirectory(unpackDir.FullName);

            log.Info("Creating unpacked directories...");
            CreateDirectoriesFromTree(unpackDir, bigFile.RootFolder);

            log.Info("Creating renamed mapping file...");
            UnpackedRenamedFileMapping renamedMapping = CreateRenamedFileMapping(bigFile.RootFolder);
            UnpackedFileKeyMappingFile mappingFile    = new UnpackedFileKeyMappingFile(options.Directory);

            mappingFile.SaveMappingData(renamedMapping);
            log.Info("Mapping file saved!");

            stopwatch.Reset();
            stopwatch.Start();

            log.Info("Beginning extract...");

            verifyAndResetThreads(options.Threads);

            if ((options.Flags & BigFileFlags.UseThreading) != 0)
            {
                int dividedCount     = bigFile.FileMap.FilesList.Length / options.Threads;
                int dividedRemainder = bigFile.FileMap.FilesList.Length % options.Threads;
                log.Info("Divided files into " + options.Threads + " pools of " + dividedCount + " with " + dividedRemainder + " left over (to be tacked onto the last!)");

                List <UnpackThreadInfo> usingThreads = new List <UnpackThreadInfo>();
                for (int i = 0; i < options.Threads; i++)
                {
                    unpackThreads[i].options            = options;
                    unpackThreads[i].bigFile            = bigFile;
                    unpackThreads[i].fileMapping        = renamedMapping;
                    unpackThreads[i].startIndex         = i * dividedCount;
                    unpackThreads[i].count              = dividedCount;
                    unpackThreads[i].threadID           = i;
                    unpackThreads[i].OnWorkDoneCallback = internal_OnThreadFinished;
                }
                unpackThreads[options.Threads - 1].count += dividedRemainder; //add the remainder onto the last info

                for (int i = 0; i < options.Threads; i++)
                {
                    ThreadPool.QueueUserWorkItem(internal_UnpackFiles, unpackThreads[i]);
                    usingThreads.Add(unpackThreads[i]);
                }

                return(new BigFileUnpackOperationStatus(usingThreads));
            }
            else //use the function for threads even without one
            {
                unpackThreads[0].options            = options;
                unpackThreads[0].bigFile            = bigFile;
                unpackThreads[0].fileMapping        = renamedMapping;
                unpackThreads[0].startIndex         = 0;
                unpackThreads[0].count              = bigFile.FileMap.FilesList.Length;
                unpackThreads[0].threadID           = 0;
                unpackThreads[0].OnWorkDoneCallback = internal_OnThreadFinished;

                internal_UnpackFiles(unpackThreads[0]); //teehee

                diagData.WriteUnpackedFiles = stopwatch.ElapsedMilliseconds;
                stopwatch.Stop();

                log.Info("Extract complete!");

                diagData.DebugLog(log);

                log.Info("Unpack complete!");

                return(null);
            }
        }
Пример #6
0
        public UnpackedFolderMapAndFilesList CreateFolderTreeAndFilesListFromDirectory(DirectoryInfo dir, UnpackedRenamedFileMapping mapping, FileMappingData defaultMappingData)
        {
            log.Info("Creating folder tree and files list from directory " + dir.FullName);
            IBigFileFileInfo[]                fileInfos   = new IBigFileFileInfo[mapping.KeyMap.Count];
            List <IBigFileFolderInfo>         folderInfos = new List <IBigFileFolderInfo>();
            Dictionary <short, BigFileFolder> folderMap   = new Dictionary <short, BigFileFolder>();
            short folderCount = 0;
            int   fileCount   = 0;

            Dictionary <string, UnpackedRenamedFileMapping.RenamedFileMappingData> temp = new Dictionary <string, UnpackedRenamedFileMapping.RenamedFileMappingData>(mapping.RenamedMap);

            BigFileFolder recursion(DirectoryInfo directory, string dirName, BigFileFolder parentFolder)
            {
                IBigFileFolderInfo folderInfo = version.CreateFolderInfo();

                folderInfo.Unknown_01     = 0;
                folderInfo.PreviousFolder = parentFolder != null ? parentFolder.FolderIndex : (short)-1;
                folderInfo.NextFolder     = -1;
                folderInfo.Unknown_02     = 0;
                folderInfo.Name           = parentFolder == null ? //oh my lawdy what is this EDIT 4/5/2018: what the f**k
                                            "/".EncodeToBadString(length: 54) :
                                            directory.Name.EncodeToBadString(length: 54);
                folderInfos.Add(folderInfo);

                BigFileFolder thisFolder = new BigFileFolder(folderCount, folderInfo, folderMap);

                folderMap.Add(folderCount, thisFolder);

                foreach (FileInfo file in directory.GetFiles())
                {
                    if (file.Name.EndsWith(".header"))
                    {
                        continue;
                    }

                    string fileName = dirName + "//" + file.Name;
                    UnpackedRenamedFileMapping.RenamedFileMappingData mappingData = mapping[fileName];
                    temp.Remove(fileName);
                    IBigFileFileInfo fileInfo = version.CreateFileInfo();
                    defaultMappingData[mappingData.Key].FileInfo.Copy(fileInfo);
                    fileInfo.Key = mappingData.Key;
                    //fileInfo.FileNumber = fileCount;
                    fileInfo.Name   = mappingData.OriginalName.EncodeToBadString(length: 60);
                    fileInfo.Folder = folderCount;

                    log.Debug("Add file " + file.FullName);

                    fileInfos[fileCount] = fileInfo;
                    fileCount++;
                }

                folderCount++;

                foreach (DirectoryInfo dirInfo in directory.GetDirectories())
                {
                    if (parentFolder == null) //ONLY THE FIRST RECURSION, PREVENTS ADDING WRONG FOLDERS WHEN PACKING
                    {
                        thisFolder.SubFolders.Add(recursion(dirInfo, dirInfo.Name, thisFolder));
                    }
                    else
                    {
                        thisFolder.SubFolders.Add(recursion(dirInfo, dirName + "/" + dirInfo.Name, thisFolder));
                    }
                }

                return(thisFolder);
            }

            recursion(dir, "", null);

            if (fileCount != mapping.KeyMap.Count)
            {
                log.Error(string.Format("Missing {0} files!", temp.Count));
                foreach (KeyValuePair <string, UnpackedRenamedFileMapping.RenamedFileMappingData> kvp in temp)
                {
                    log.Error(string.Format("     >{0}", kvp.Value.FileName));
                }
            }

            return(new UnpackedFolderMapAndFilesList()
            {
                folderMap = folderMap,
                filesList = fileInfos,
                foldersList = folderInfos.ToArray(),
            });
        }