public PakCatalog(ILogger logger) { _logger = logger; _fileName = ConfigurationManager.AppSettings["sharperbot.PakCatalog"]; _entries = new List<PakEntry>(); _logger.Debug("Loading PAK catalog - filename={0}", _fileName); if (!File.Exists(_fileName)) { _logger.Error("File not found - filename={0}", _fileName); throw new FileNotFoundException(_fileName); } var buffer = File.ReadAllBytes(_fileName); for (int i = 0; i < buffer.Length; i++) { buffer[i] ^= PakKey; } using (var ms = new MemoryStream(buffer)) { using (var br = new BinaryReader(ms)) { // Validate header var expectedHeader = new byte[] { 0xc0, 0x4a, 0xc0, 0xba }; for (int i = 0; i < 4; i++) { var actual = br.ReadByte(); if (actual != expectedHeader[i]) { _logger.Error("Invalid PAK header - filename={0}", _fileName); throw new FormatException("Invalid PAK header"); } } // Read TOC ms.Seek(9, SeekOrigin.Begin); long offset; while (true) { var entry = new PakEntry(); byte fileNameLength = br.ReadByte(); entry.Name = Encoding.ASCII.GetString(br.ReadBytes(fileNameLength)); entry.Length = br.ReadUInt32(); br.ReadBytes(8); // skip _entries.Add(entry); byte flag = br.ReadByte(); if (flag == EndOfContents) { // Entry contents start here offset = ms.Position; break; } } // Calculate offsets foreach (var item in _entries) { item.Offset = offset; offset += item.Length; } } } }
private byte[] GetEntryBytes(PakEntry entry) { _logger.Debug( "Reading PAK entry - filename={0}, entry={1}, offset={2}, bytes={3}", _fileName, entry.Name, entry.Offset, entry.Length); using (var file = File.OpenRead(_fileName)) { file.Seek((int)entry.Offset, SeekOrigin.Begin); var buffer = new byte[entry.Length]; file.Read(buffer, 0, (int)entry.Length); for (int i = 0; i < buffer.Length; i++) { buffer[i] ^= PakKey; } return buffer; } }