public void Save(string pathToGgpkNew, Action <string> output)
        {
            if (output != null)
            {
                output("Saving GGPK..." + Environment.NewLine);
            }

            FileStream readStream;
            FileStream writeStream;

            using (readStream = File.OpenRead(_pathToGppk))
                using (writeStream = File.OpenWrite(pathToGgpkNew))
                {
                    var reader = new BinaryReader(readStream);
                    var writer = new BinaryWriter(writeStream);

                    var ggpkRecord = RecordOffsets[0] as GgpkRecord;
                    if (ggpkRecord == null)
                    {
                        throw new Exception("First record isn't GGPK record");
                    }

                    // Skip GGPK record for now
                    writer.Seek((int)ggpkRecord.Length, SeekOrigin.Begin);

                    // recursively write files and folders records
                    var changedOffsets          = new Dictionary <long, long>();
                    var previousPercentComplete = 0.0;
                    var fileCopied = 0.0;
                    DirectoryTreeNode.TraverseTreePostorder(
                        DirectoryRoot,
                        dir => dir.Record.Write(writer, changedOffsets),
                        file =>
                    {
                        var data = file.ReadFileContent(reader);
                        file.Write(writer, changedOffsets);
                        writer.Write(data);

                        fileCopied++;
                        var percentComplete = fileCopied / _files.Count;
                        if (!(percentComplete - previousPercentComplete >= 0.05f))
                        {
                            return;
                        }

                        if (output != null)
                        {
                            output(String.Format("  {0:00.00}%", 100.0 * percentComplete));
                        }
                        previousPercentComplete = percentComplete;
                    });
                    if (output != null)
                    {
                        output("  100%");
                    }

                    // write root directory
                    var rootDirectoryOffset = writer.BaseStream.Position;
                    DirectoryRoot.Record.Write(writer, changedOffsets);

                    // write single Free record
                    var firstFreeRecordOffset = writer.BaseStream.Position;
                    var freeRecord            = new FreeRecord(16, firstFreeRecordOffset, 0);
                    freeRecord.Write(writer, null);

                    // write GGPK record
                    writer.Seek(0, SeekOrigin.Begin);
                    var ggpkRecordNew = new GgpkRecord(ggpkRecord.Length);
                    ggpkRecordNew.RecordOffsets[0] = rootDirectoryOffset;
                    ggpkRecordNew.RecordOffsets[1] = firstFreeRecordOffset;
                    ggpkRecordNew.Write(writer, changedOffsets);
                    if (output != null)
                    {
                        output("Finished !!!");
                    }
                }
        }
Exemplo n.º 2
0
        private void Write(BinaryWriter bw, FreeRecord freeRecord)
        {
            bw.BaseStream.Position = freeRecord.RecordBegin;

            freeRecord.Write(bw, null);
        }