コード例 #1
0
        public void ExtractFile(string directory, PakEntry pakEntry, PakBinaryReader reader)
        {
            var currentPakEntry = reader.ReadFileLevelPakEntry();

            if (!currentPakEntry.Equals(pakEntry))
            {
                return;
            }

            string compoundName = directory + @"\" + pakEntry.Name.Replace(@"/", @"\");

            if (!compoundName.Contains(@"\"))
            {
                return;
            }

            Directory.CreateDirectory(Path.GetDirectoryName(compoundName));

            using (var fileStream = File.Open(compoundName, FileMode.Create))
            {
                using (var writer = new BinaryWriter(fileStream))
                {
                    switch (pakEntry.CompressionType)
                    {
                    case 0:
                        writer.Write(reader.ReadBytes((int)currentPakEntry.UncompressedSize));
                        break;

                    case 1:
                        foreach (var chunk in pakEntry.Chunks)
                        {
                            var compressedData = reader.ReadBytes((int)(chunk.ChunkEnd - chunk.ChunkOffset));
                            var decompressed   = ZlibStream.UncompressBuffer(compressedData);
                            writer.Write(decompressed);
                        }
                        break;

                    case 4:
                    case 16400:
                        var remainingSizeToUncompress = pakEntry.UncompressedSize;
                        foreach (var chunk in pakEntry.Chunks)
                        {
                            var decompressedSize = remainingSizeToUncompress > pakEntry.ChunkSize
                                    ? pakEntry.ChunkSize
                                    : remainingSizeToUncompress;
                            var compressedData = reader.ReadBytes((int)(chunk.ChunkEnd - chunk.ChunkOffset));
                            var decompressed   = OodleHandler.Decompress(compressedData, decompressedSize);
                            writer.Write(decompressed);
                            remainingSizeToUncompress -= pakEntry.ChunkSize;
                        }
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }
            }
        }
コード例 #2
0
        public void SaveDataEntry(PakBinaryReader reader, PakBinaryWriter writer, PakEntry pakEntry, bool usePadding)
        {
            if (pakEntry.Offset == -1)
            {
                return;
            }

            long originalOffset = pakEntry.Offset;

            pakEntry.Offset = writer.BaseStream.Position;

            if (Archive.Version < 7)
            {
                var offsetDifference = pakEntry.Offset - originalOffset;
                foreach (var chunk in pakEntry.Chunks)
                {
                    chunk.ChunkEnd    += offsetDifference;
                    chunk.ChunkOffset += offsetDifference;
                }
            }

            writer.Write(pakEntry, true);

            if (pakEntry.Import != null)
            {
                using (var importFileStream = File.Open(pakEntry.Import, FileMode.Open))
                {
                    var importReader = new PakBinaryReader(importFileStream);
                    writer.Write(importReader.ReadBytes((int)pakEntry.UncompressedSize));
                }
            }
            else
            {
                if (reader.BaseStream.Position != originalOffset)
                {
                    reader.BaseStream.Seek(originalOffset, SeekOrigin.Begin);
                }

                var importFilePakEntry = reader.ReadFileLevelPakEntry();
                if (!importFilePakEntry.Equals(pakEntry))
                {
                    return;
                }

                switch (pakEntry.CompressionType)
                {
                case 0:
                    writer.Write(reader.ReadBytes((int)pakEntry.UncompressedSize));
                    break;

                case 1:
                case 4:
                case 16400:
                    foreach (var chunk in pakEntry.Chunks)
                    {
                        var compressedData = reader.ReadBytes((int)(chunk.ChunkEnd - chunk.ChunkOffset));
                        writer.Write(compressedData);
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            if (usePadding && pakEntry.Padded)
            {
                var toWrite = 2048 - writer.BaseStream.Position % 2048;
                if (toWrite != 2048)
                {
                    writer.Write(new byte[toWrite]);
                }
            }
        }