private void ReadChunks(Stream s) { try { DebugLog.PrintLn("Reading Chunks..."); for (int i = 0; i < Header.Chunks.Count; i++) { if (verbose) { DebugLog.PrintLn("Reading Chunk(" + i + ") Header..."); } CompressedChunk c = Header.Chunks[i]; s.Seek(c.CompOffset, 0); c.Magic = ReadUInt(s); if (c.Magic != 0x9E2A83C1) { throw new Exception("Not a valid Chunkheader, wrong magic!(#" + i + ")"); } c.BlockSize = ReadUInt(s); ReadUInt(s); ReadUInt(s); uint count = (c.UnCompSize + c.BlockSize - 1) / c.BlockSize; c.Blocks = new List <CompressedChunkBlock>(); if (verbose) { DebugLog.PrintLn("Reading Chunk(" + i + ") Blocks..."); } for (int j = 0; j < count; j++) { CompressedChunkBlock b = new CompressedChunkBlock(); b.CompSize = ReadUInt(s); b.UnCompSize = ReadUInt(s); b.loaded = false; c.Blocks.Add(b); } Header.Chunks[i] = c; } if (Header.Chunks.Count != 0) { uint FullSize = Header.Chunks[Header.Chunks.Count - 1].UnCompOffset + Header.Chunks[Header.Chunks.Count - 1].UnCompSize; Header.DeCompBuffer = new MemoryStream(new byte[FullSize]); Header.DeCompBuffer.Seek(0, 0); Source.Seek(0, 0); byte[] buff = new byte[Header._offsetCompFlagEnd]; Source.Read(buff, 0, (int)Header._offsetCompFlagEnd); Header.DeCompBuffer.Write(buff, 0, (int)Header._offsetCompFlagEnd); Header.DeCompBuffer.Write(BitConverter.GetBytes(0), 0, 4); Header.DeCompBuffer.Write(BitConverter.GetBytes(Header.unk7), 0, 4); Header.DeCompBuffer.Write(BitConverter.GetBytes(Header.unk8), 0, 4); Header.DeCompBuffer.Seek(Header._offsetFlag, 0); uint newFlags = (Header.Flags ^ 0x02000000); Header.DeCompBuffer.Write(BitConverter.GetBytes(newFlags), 0, 4); } } catch (Exception ex) { DebugLog.PrintLn("PCCPACKAGE::READCHUNKS ERROR:\n" + ex.Message); } }
private void UncompressRange(uint offset, uint size) { try { int startchunk = 0; int endchunk = -1; for (int i = 0; i < Header.Chunks.Count; i++) { if (Header.Chunks[i].UnCompOffset > offset) { break; } startchunk = i; } for (int i = 0; i < Header.Chunks.Count; i++) { if (Header.Chunks[i].UnCompOffset >= offset + size) { break; } endchunk = i; } if (startchunk == -1 || endchunk == -1) { return; } for (int i = startchunk; i <= endchunk; i++) { CompressedChunk c = Header.Chunks[i]; Header.DeCompBuffer.Seek(c.UnCompOffset, 0); for (int j = 0; j < c.Blocks.Count; j++) { CompressedChunkBlock b = c.Blocks[j]; uint startblock = (uint)Header.DeCompBuffer.Position; uint endblock = (uint)Header.DeCompBuffer.Position + b.UnCompSize; if (((startblock >= offset && startblock < offset + size) || (endblock >= offset && endblock < offset + size) || (offset >= startblock && offset < endblock) || (offset + size > startblock && offset + size <= endblock)) && !b.loaded) { Header.DeCompBuffer.Write(UncompressBlock(i, j), 0, (int)b.UnCompSize); b.loaded = true; c.Blocks[j] = b; Header.Chunks[i] = c; } else { Header.DeCompBuffer.Seek(b.UnCompSize, SeekOrigin.Current); } } } } catch (Exception ex) { DebugLog.PrintLn("PCCPACKAGE::UNCOMPRESSRANGE ERROR:\n" + ex.Message); } }
private byte[] UncompressBlock(int ChunkIdx, int BlockIdx) { try { CompressedChunk c = Header.Chunks[ChunkIdx]; Source.Seek(c.CompOffset, 0); Source.Seek(0x10 + 0x08 * c.Blocks.Count, SeekOrigin.Current); for (int i = 0; i < BlockIdx; i++) { Source.Seek(c.Blocks[i].CompSize, SeekOrigin.Current); } return(UncompressBlock(Source, c.Blocks[BlockIdx].CompSize, c.Blocks[BlockIdx].UnCompSize)); } catch (Exception ex) { DebugLog.PrintLn("PCCPACKAGE::UNCOMPRESSBLOCK ERROR:\n" + ex.Message); return(new byte[0]); } }
public void Parse(BinaryReader br) { Version = br.ReadInt32(); HeaderSize = br.ReadInt32(); FolderNameLength = br.ReadInt32(); FolderName = Encoding.UTF8.GetString(br.ReadBytes(FolderNameLength)); PackageFlags = br.ReadInt32(); NameCount = br.ReadInt32(); NameOffset = br.ReadInt32(); ExportCount = br.ReadInt32(); ExportOffset = br.ReadInt32(); ImportCount = br.ReadInt32(); ImportOffset = br.ReadInt32(); DependsOffset = br.ReadInt32(); SerialOffset = br.ReadInt32(); Unknown2 = br.ReadInt32(); Unknown3 = br.ReadInt32(); Unknown4 = br.ReadInt32(); FGuid = $"{br.ReadInt32()}.{br.ReadInt32()}.{br.ReadInt32()}.{br.ReadInt32()}"; GenerationsCount = br.ReadInt32(); for (int i = 0; i < GenerationsCount; i++) { var generation = new Generation(); generation.Parse(br); Generations.Add(generation); } EngineVersion = br.ReadInt32(); CookerVersion = br.ReadInt32(); CompressionFlags = br.ReadInt32(); NumCompressedChunks = br.ReadInt32(); for (int i = 0; i < NumCompressedChunks; i++) { var compressedChunk = new CompressedChunk(); compressedChunk.Parse(br); CompressedChunks.Add(compressedChunk); } }
private void ReadHeader(Stream s) { try { s.Seek(0, 0); //DebugLog.PrintLn("Reading Package Summary..."); var h = new HeaderInfo { magic = ReadUInt(s) }; if (h.magic != 0x9E2A83C1) { throw new Exception("Not a valid PCC Package, wrong magic!"); } h.ver1 = ReadUInt16(s); h.ver2 = ReadUInt16(s); h.HeaderLength = ReadUInt(s); h.Group = ReadUString(s); h._offsetFlag = (uint)s.Position; h.Flags = ReadUInt(s); GeneralInfo.compressed = (h.Flags & 0x02000000) != 0; //DebugLog.PrintLn("Is Compressed : " + GeneralInfo.compressed); h.unk1 = ReadUInt(s); if (h.unk1 != 0) { throw new Exception("Not a valid PCC Package, Unk1 != 0"); } h.NameCount = ReadUInt(s); h.NameOffset = ReadUInt(s); h.ExportCount = ReadUInt(s); h.ExportOffset = ReadUInt(s); h.ImportCount = ReadUInt(s); h.ImportOffset = ReadUInt(s); h.FreeZoneStart = ReadUInt(s); h.FreeZoneEnd = ReadUInt(s); h.unk2 = ReadUInt(s); h.unk3 = ReadUInt(s); h.unk4 = ReadUInt(s); h.GUID = new byte[16]; s.Read(h.GUID, 0, 16); var count = ReadInt(s); //DebugLog.PrintLn("Reading Generations..."); h.Generations = new List <Generation>(); for (var i = 0; i < count; i++) { var g = new Generation(); g.ExportCount = ReadUInt(s); g.ImportCount = ReadUInt(s); g.NetObjCount = ReadUInt(s); h.Generations.Add(g); } //DebugLog.PrintLn("Done."); h.EngineVersion = ReadUInt(s); h.CookerVersion = ReadUInt(s); h.unk5 = ReadUInt(s); h.unk6 = ReadUInt(s); h.CompressionFlag = ReadUInt(s); h._offsetCompFlagEnd = (uint)s.Position; count = ReadInt(s); h.Chunks = new List <CompressedChunk>(); if (GeneralInfo.compressed) { //DebugLog.PrintLn("Reading Chunktable..."); for (var i = 0; i < count; i++) { var c = new CompressedChunk(); c.UnCompOffset = ReadUInt(s); c.UnCompSize = ReadUInt(s); c.CompOffset = ReadUInt(s); c.CompSize = ReadUInt(s); h.Chunks.Add(c); } h.DeCompBuffer = new MemoryStream(); //DebugLog.PrintLn("Done."); } h.unk7 = ReadUInt(s); h.unk8 = ReadUInt(s); Header = h; if (GeneralInfo.compressed) { ReadChunks(s); } //DebugLog.PrintLn("Done."); } catch (Exception ex) { //DebugLog.PrintLn("PCCPACKAGE::READHEADER ERROR:\n" + ex.Message); } }
public void Execute(DecompressCommandData commandData) { if (!File.Exists(commandData.InputFileName)) { throw new InvalidOperationException($"File '{commandData.InputFileName}' doesn't exists"); } using (var fileStream = new FileStream(commandData.InputFileName, FileMode.Open, FileAccess.Read)) { var size = sizeof(int); var buffer = new byte[size]; var bytesRead = fileStream.Read(buffer, 0, size); if (bytesRead == 0) { return; } numberOfChunks = BitConverter.ToInt32(buffer, 0); totalNumberOfChunks = numberOfChunks; bytesRead = fileStream.Read(buffer, 0, size); if (bytesRead == 0) { return; } chunkSize = BitConverter.ToInt32(buffer, 0); waitHandler = new ManualResetEvent(false); var headerBuffer = new byte[3 * size]; bytesRead = fileStream.Read(headerBuffer, 0, 3 * size); if (bytesRead > 0) { CreateDecompressionThreads(commandData); CreateWriterThread(commandData); StartThreads(); } while (bytesRead > 0) { var compressed = new CompressedChunk { Number = BitConverter.ToInt32(headerBuffer, 0), InitialSize = BitConverter.ToInt32(headerBuffer, size), Size = BitConverter.ToInt32(headerBuffer, 2 * size) }; compressed.Data = new byte[compressed.Size]; bytesRead = fileStream.Read(compressed.Data, 0, compressed.Size); if (bytesRead == 0) { return; } compressedChunksQueue.Enqueue(compressed); headerBuffer = new byte[3 * size]; bytesRead = fileStream.Read(headerBuffer, 0, 3 * size); } } waitHandler.WaitOne(); Console.WriteLine($"\rDone."); }
private void ReadHeader(Stream s) { try { s.Seek(0, 0); DebugLog.PrintLn("Reading Package Summary..."); HeaderInfo h = new HeaderInfo(); h.magic = ReadUInt(s); if (h.magic != 0x9E2A83C1) throw new Exception("Not a valid PCC Package, wrong magic!"); h.ver1 = ReadUInt16(s); h.ver2 = ReadUInt16(s); h.HeaderLength = ReadUInt(s); h.Group = ReadUString(s); h._offsetFlag = (uint)s.Position; h.Flags = ReadUInt(s); GeneralInfo.compressed = (h.Flags & 0x02000000) != 0; DebugLog.PrintLn("Is Compressed : " + GeneralInfo.compressed); h.unk1 = ReadUInt(s); if(h.unk1 > 1) throw new Exception("Not a valid PCC Package, Unknown 1 (offset 30) > 0"); h.NameCount = ReadUInt(s); h.NameOffset = ReadUInt(s); h.ExportCount = ReadUInt(s); h.ExportOffset = ReadUInt(s); h.ImportCount = ReadUInt(s); h.ImportOffset = ReadUInt(s); h.FreeZoneStart = ReadUInt(s); h.FreeZoneEnd = ReadUInt(s); h.unk2 = ReadUInt(s); h.unk3 = ReadUInt(s); h.unk4 = ReadUInt(s); h.GUID = new byte[16]; s.Read(h.GUID, 0, 16); int count = ReadInt(s); DebugLog.PrintLn("Reading Generations..."); h.Generations = new List<Generation>(); for (int i = 0; i < count; i++) { Generation g = new Generation(); g.ExportCount = ReadUInt(s); g.ImportCount = ReadUInt(s); g.NetObjCount = ReadUInt(s); h.Generations.Add(g); } DebugLog.PrintLn("Done."); h.EngineVersion = ReadUInt(s); h.CookerVersion = ReadUInt(s); h.unk5 = ReadUInt(s); h.unk6 = ReadUInt(s); h.CompressionFlag = ReadUInt(s); h._offsetCompFlagEnd = (uint)s.Position; count = ReadInt(s); h.Chunks = new List<CompressedChunk>(); if (GeneralInfo.compressed) { DebugLog.PrintLn("Reading Chunktable..."); for (int i = 0; i < count; i++) { CompressedChunk c = new CompressedChunk(); c.UnCompOffset = ReadUInt(s); c.UnCompSize = ReadUInt(s); c.CompOffset = ReadUInt(s); c.CompSize = ReadUInt(s); h.Chunks.Add(c); } h.DeCompBuffer = new MemoryStream(); DebugLog.PrintLn("Done."); } h.unk7 = ReadUInt(s); h.unk8 = ReadUInt(s); Header = h; if (GeneralInfo.compressed) ReadChunks(s); DebugLog.PrintLn("Done."); } catch (Exception ex) { DebugLog.PrintLn("PCCPACKAGE::READHEADER ERROR:\n" + ex.Message); } }