public void ReadRootPac(byte[] buffer, string splitName = "") { using (var reader = new FileReader(new System.IO.MemoryStream(buffer))) { var header3 = reader.ReadStruct <HeaderV3>(); PacNodeTree tree = new PacNodeTree(); tree.Read(reader, header3); var rootNode = tree.RootNode; LoadTree(rootNode, splitName); if (header3.SplitCount != 0) { //Read the split data if present reader.SeekBegin(48 + header3.NodesSize); ulong splitCount = reader.ReadUInt64(); ulong splitEntriesOffset = reader.ReadUInt64(); reader.SeekBegin(splitEntriesOffset); for (int i = 0; i < (int)splitCount; i++) { SplitEntry entry = new SplitEntry(); entry.SplitNameOffset = reader.ReadUInt64(); entry.SplitCompressedSize = reader.ReadUInt32(); entry.SplitUncompressedSize = reader.ReadUInt32(); entry.SplitOffset = reader.ReadUInt32(); entry.SplitChunkCount = reader.ReadUInt32(); entry.SplitChunksOffset = reader.ReadUInt64(); using (reader.TemporarySeek((long)entry.SplitNameOffset, System.IO.SeekOrigin.Begin)) { entry.Name = reader.ReadZeroTerminatedString(); } using (reader.TemporarySeek((long)entry.SplitChunksOffset, System.IO.SeekOrigin.Begin)) { entry.Chunks = reader.ReadMultipleStructs <Chunk>(entry.SplitChunkCount); } SplitEntries.Add(entry); Console.WriteLine("SplitName " + entry.Name); Console.WriteLine("SplitCompressedSize " + entry.SplitCompressedSize); Console.WriteLine("SplitUncompressedSize " + entry.SplitUncompressedSize); Console.WriteLine("SplitOffset " + entry.SplitOffset); Console.WriteLine("SplitChunkCount " + entry.SplitChunkCount); Console.WriteLine("SplitChunksOffset " + entry.SplitChunksOffset); } } } }
public void Load(System.IO.Stream stream) { using (var reader = new FileReader(stream)) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; IsVersion4 = reader.CheckSignature(8, "PACx402L"); if (IsVersion4) { var header = reader.ReadStruct <HeaderV4>(); var chunks = reader.ReadMultipleStructs <Chunk>(header.ChunkCount); Checksum = header.PacID; //Decompress each chunk now reader.SeekBegin(header.RootOffset); ReadRootPac(DecompressChunks(reader, chunks)); //Read splits from root pac if (SplitEntries.Count > 0) { foreach (var pacSplit in SplitEntries) { ReadSplitPac(reader, pacSplit); } } } else { var header3 = reader.ReadStruct <HeaderV3>(); PacNodeTree tree = new PacNodeTree(); tree.Read(reader, header3); var rootNode = tree.RootNode; LoadTree(rootNode); } } }
public void Read(FileReader reader) { ulong nameOffset = reader.ReadUInt64(); ulong dataOffset = reader.ReadUInt64(); ulong childIndicesOffset = reader.ReadUInt64(); int parentIndex = reader.ReadInt32(); int index = reader.ReadInt32(); int dataIndex = reader.ReadInt32(); ushort childCount = reader.ReadUInt16(); HasData = reader.ReadBoolean(); byte fullPathSize = reader.ReadByte(); Console.WriteLine($"nameOffset {nameOffset}"); Console.WriteLine($"dataOffset {dataOffset}"); Console.WriteLine($"childIndicesOffset {childIndicesOffset}"); Console.WriteLine($"parentIndex {parentIndex}"); Console.WriteLine($"index {index}"); Console.WriteLine($"dataIndex {dataIndex}"); Console.WriteLine($"childCount {childCount}"); Console.WriteLine($"HasData {HasData}"); if (nameOffset != 0) { reader.SeekBegin((long)nameOffset); Name = reader.ReadZeroTerminatedString(); } if (dataOffset != 0) { reader.SeekBegin((long)dataOffset); uint PacID = reader.ReadUInt32(); //Detecting data in v4 is a pain //Check if the offset is set within the data section var dataPos = 48 + PacFile.NodesSize + PacFile.SplitsInfoSize; if (PacID == PacFile.PacID || IsVersion4 && dataOffset >= dataPos) { ulong dataSize = reader.ReadUInt64(); uint padding = reader.ReadUInt32(); ulong dataBlockOffset = reader.ReadUInt64(); ulong padding2 = reader.ReadUInt64(); ulong extensionOffset = reader.ReadUInt64(); DataType = reader.ReadEnum <DataType>(false); if (extensionOffset != 0) { reader.SeekBegin((long)extensionOffset); string extension = reader.ReadZeroTerminatedString(); Name += extension; } if (dataBlockOffset != 0) { reader.SeekBegin((long)dataBlockOffset); Data = reader.ReadBytes((int)dataSize); } } else { reader.SeekBegin((long)dataOffset); PacNodeTree tree = new PacNodeTree(); tree.Read(reader, PacFile); Children.Add(tree.RootNode); } } if (childIndicesOffset != 0) { reader.SeekBegin((long)childIndicesOffset); int[] Indices = reader.ReadInt32s(childCount); for (int i = 0; i < childCount; i++) { int childIndex = Indices[i]; reader.SeekBegin((uint)ParentTree.rootNodeOffset + (childIndex * 40)); PacNode node = new PacNode(PacFile, ParentTree); node.Read(reader); Children.Add(node); } } }
public PacNode(HeaderV3 pac, PacNodeTree tree) { PacFile = pac; ParentTree = tree; }
public void Load(System.IO.Stream stream) { using (var reader = new FileReader(stream)) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; string signature = reader.ReadString(4, Encoding.ASCII); string version = reader.ReadString(3, Encoding.ASCII); if (!ushort.TryParse(version, out Version)) { } char bom = reader.ReadChar(); IsBigEndian = bom == 'B'; reader.SetByteOrder(IsBigEndian); reader.Position = 0; IsVersion4 = Version > 400; if (IsVersion4) { var header = reader.ReadStruct <HeaderV4>(); var chunks = reader.ReadMultipleStructs <Chunk>(header.ChunkCount); Checksum = header.PacID; //Decompress each chunk now reader.SeekBegin(header.RootOffset); ReadRootPac(DecompressChunks(reader, chunks)); //Read splits from root pac if (SplitEntries.Count > 0) { foreach (var pacSplit in SplitEntries) { ReadSplitPac(reader, pacSplit); } } } else { if (Version > 300) { var header3 = reader.ReadStruct <HeaderV3>(); PacNodeTree tree = new PacNodeTree(); tree.Read(reader, header3); LoadTree(tree); } else { var header2 = reader.ReadStruct <HeaderV2>(); for (int i = 0; i < header2.FileExtensions; i++) { reader.SeekBegin(header2.FileExtensionsTblOffset + (i * 8)); uint offset = reader.ReadUInt32(); if (offset != 0) { reader.SeekBegin(offset); uint fileExtOffset = reader.ReadUInt32(); uint fileTblOffset = reader.ReadUInt32(); reader.SeekBegin(fileExtOffset); string ext = reader.ReadZeroTerminatedString(); reader.SeekBegin(fileTblOffset); uint fileCount = reader.ReadUInt32(); } } reader.SeekBegin(header2.OffsetTableSize); } } } }
public void LoadTree(PacNodeTree nodeTree) { LoadNode(nodeTree.RootNode, string.Empty); }