Пример #1
0
        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;
                    }
                }
            }
        }
Пример #2
0
        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;
            }
        }