public override void Load(ExtendedBinaryReader reader, bool keepOpen = false) { // Store the current reader _internalReader = reader; // Filename Section // This section contains an array of addresses to each of the file's name and the strings // itself right after, this section is only used for finding file indices from within game // This is a workaround for reading different versions of PCK files as some files seem to // have smaller padding (0x08 for Signatures, 0x04 for Padding) // while DAL: RR has larger padding (0x14 for Signatures, 0x08 for Padding) // This workaround works by checking the padding in the signature to determine the version int sigSize = reader.CheckDALSignature("Filename"); bool oldPCK = false; if (sigSize < 0x14) { oldPCK = true; } // The length of the Filename section int fileNameSectionSize = reader.ReadInt32(); // Address to the list of filenames int fileNameSectionAddress = (int)reader.BaseStream.Position; // Jump to the Pack section reader.JumpTo(fileNameSectionSize); // Makes sure the reader is aligned reader.FixPadding(oldPCK ? 0x04u : 0x08u); // Pack Section // This section contains an array of file information and then all of it's data // Check Signature string packSig = reader.ReadDALSignature("Pack"); if (packSig != "Pack" && packSig.Length <= 4) { throw new SignatureMismatchException("Pack", packSig); } // The length of the Pack section int packSectionSize = reader.ReadInt32(); int fileCount = reader.ReadInt32(); // Read file entries for (int i = 0; i < fileCount; ++i) { FileEntries.Add(new FileEntry()); FileEntries[i].DataPosition = reader.ReadInt32(); FileEntries[i].DataLength = reader.ReadInt32(); } // Jump back to the Filename section so we can get all of the file names reader.JumpTo(fileNameSectionAddress); // Reads all the file names for (int i = 0; i < fileCount; ++i) { int position = reader.ReadInt32() + (oldPCK ? 0xC : 0x18); FileEntries[i].FileName = reader.ReadStringElsewhere(position); } // Load all data into memory if the loader plans to close the stream if (!keepOpen) { Preload(); } }