Пример #1
0
        private void Parse(byte[] md5)
        {
            int size = (int)_reader.BaseStream.Length;

            if (size < 8)
                throw new BLTEDecoderException("not enough data: {0}", 8);

            int magic = _reader.ReadInt32();

            if (magic != BLTE_MAGIC)
                throw new BLTEDecoderException("frame header mismatch (bad BLTE file)");

            int headerSize = _reader.ReadInt32BE();

            if (CASCConfig.ValidateData)
            {
                long oldPos = _reader.BaseStream.Position;

                _reader.BaseStream.Position = 0;

                byte[] newHash = _md5.ComputeHash(_reader.ReadBytes(headerSize > 0 ? headerSize : size));

                if (!newHash.EqualsTo(md5))
                    throw new Exception("data corrupted");

                _reader.BaseStream.Position = oldPos;
            }

            int numBlocks = 1;

            if (headerSize > 0)
            {
                if (size < 12)
                    throw new BLTEDecoderException("not enough data: {0}", 12);

                byte[] fcbytes = _reader.ReadBytes(4);

                numBlocks = fcbytes[1] << 16 | fcbytes[2] << 8 | fcbytes[3] << 0;

                if (fcbytes[0] != 0x0F || numBlocks == 0)
                    throw new BLTEDecoderException("bad table format 0x{0:x2}, numBlocks {1}", fcbytes[0], numBlocks);

                int frameHeaderSize = 24 * numBlocks + 12;

                if (headerSize != frameHeaderSize)
                    throw new BLTEDecoderException("header size mismatch");

                if (size < frameHeaderSize)
                    throw new BLTEDecoderException("not enough data: {0}", frameHeaderSize);
            }

            DataBlock[] blocks = new DataBlock[numBlocks];

            for (int i = 0; i < numBlocks; i++)
            {
                DataBlock block = new DataBlock();

                if (headerSize != 0)
                {
                    block.CompSize = _reader.ReadInt32BE();
                    block.DecompSize = _reader.ReadInt32BE();
                    block.Hash = _reader.ReadBytes(16);
                }
                else
                {
                    block.CompSize = size - 8;
                    block.DecompSize = size - 8 - 1;
                    block.Hash = null;
                }

                blocks[i] = block;
            }

            _memStream = new MemoryStream(blocks.Sum(b => b.DecompSize));

            for (int i = 0; i < blocks.Length; i++)
            {
                DataBlock block = blocks[i];

                block.Data = _reader.ReadBytes(block.CompSize);

                if (block.Hash != null && CASCConfig.ValidateData)
                {
                    byte[] blockHash = _md5.ComputeHash(block.Data);

                    if (!blockHash.EqualsTo(block.Hash))
                        throw new BLTEDecoderException("MD5 mismatch");
                }

                HandleDataBlock(block.Data, i);
            }
        }
Пример #2
0
        private void Parse(MD5Hash md5)
        {
            int size = (int)_reader.BaseStream.Length;

            if (size < 8)
            {
                throw new BLTEDecoderException("not enough data: {0}", 8);
            }

            int magic = _reader.ReadInt32();

            if (magic != BLTE_MAGIC)
            {
                throw new BLTEDecoderException("frame header mismatch (bad BLTE file)");
            }

            int headerSize = _reader.ReadInt32BE();

            if (CASCConfig.ValidateData)
            {
                long oldPos = _reader.BaseStream.Position;

                _reader.BaseStream.Position = 0;

                byte[] newHash = _md5.ComputeHash(_reader.ReadBytes(headerSize > 0 ? headerSize : size));

                if (!md5.EqualsTo(newHash))
                {
                    throw new BLTEDecoderException("data corrupted");
                }

                _reader.BaseStream.Position = oldPos;
            }

            int numBlocks = 1;

            if (headerSize > 0)
            {
                if (size < 12)
                {
                    throw new BLTEDecoderException("not enough data: {0}", 12);
                }

                byte[] fcbytes = _reader.ReadBytes(4);

                numBlocks = fcbytes[1] << 16 | fcbytes[2] << 8 | fcbytes[3] << 0;

                if (fcbytes[0] != 0x0F || numBlocks == 0)
                {
                    throw new BLTEDecoderException("bad table format 0x{0:x2}, numBlocks {1}", fcbytes[0], numBlocks);
                }

                int frameHeaderSize = 24 * numBlocks + 12;

                if (headerSize != frameHeaderSize)
                {
                    throw new BLTEDecoderException("header size mismatch");
                }

                if (size < frameHeaderSize)
                {
                    throw new BLTEDecoderException("not enough data: {0}", frameHeaderSize);
                }
            }

            DataBlock[] blocks = new DataBlock[numBlocks];

            for (int i = 0; i < numBlocks; i++)
            {
                DataBlock block = new DataBlock();

                if (headerSize != 0)
                {
                    block.CompSize   = _reader.ReadInt32BE();
                    block.DecompSize = _reader.ReadInt32BE();
                    block.Hash       = _reader.Read <MD5Hash>();
                }
                else
                {
                    block.CompSize   = size - 8;
                    block.DecompSize = size - 8 - 1;
                    block.Hash       = default(MD5Hash);
                }

                blocks[i] = block;
            }

            _memStream = new MemoryStream(blocks.Sum(b => b.DecompSize));

            for (int i = 0; i < blocks.Length; i++)
            {
                DataBlock block = blocks[i];

                block.Data = _reader.ReadBytes(block.CompSize);

                if (!block.Hash.IsZeroed() && CASCConfig.ValidateData)
                {
                    byte[] blockHash = _md5.ComputeHash(block.Data);

                    if (!block.Hash.EqualsTo(blockHash))
                    {
                        throw new BLTEDecoderException("MD5 mismatch");
                    }
                }

                HandleDataBlock(block.Data, i);
            }
        }
Пример #3
0
        private void Parse(MD5Hash md5)
        {
            int size = (int)_reader.BaseStream.Length;

            if (size < 8)
                throw new BLTEDecoderException("not enough data: {0}", 8);

            int magic = _reader.ReadInt32();

            if (magic != BLTE_MAGIC)
                throw new BLTEDecoderException("frame header mismatch (bad BLTE file)");

            int headerSize = _reader.ReadInt32BE();

            if (CASCConfig.ValidateData)
            {
                long oldPos = _reader.BaseStream.Position;

                _reader.BaseStream.Position = 0;

                byte[] newHash = _md5.ComputeHash(_reader.ReadBytes(headerSize > 0 ? headerSize : size));

                if (!md5.EqualsTo(newHash))
                    throw new BLTEDecoderException("data corrupted");

                _reader.BaseStream.Position = oldPos;
            }

            int numBlocks = 1;

            if (headerSize > 0)
            {
                if (size < 12)
                    throw new BLTEDecoderException("not enough data: {0}", 12);

                byte[] fcbytes = _reader.ReadBytes(4);

                numBlocks = fcbytes[1] << 16 | fcbytes[2] << 8 | fcbytes[3] << 0;

                if (fcbytes[0] != 0x0F || numBlocks == 0)
                    throw new BLTEDecoderException("bad table format 0x{0:x2}, numBlocks {1}", fcbytes[0], numBlocks);

                int frameHeaderSize = 24 * numBlocks + 12;

                if (headerSize != frameHeaderSize)
                    throw new BLTEDecoderException("header size mismatch");

                if (size < frameHeaderSize)
                    throw new BLTEDecoderException("not enough data: {0}", frameHeaderSize);
            }

            _dataBlocks = new DataBlock[numBlocks];

            for (int i = 0; i < numBlocks; i++)
            {
                DataBlock block = new DataBlock();

                if (headerSize != 0)
                {
                    block.CompSize = _reader.ReadInt32BE();
                    block.DecompSize = _reader.ReadInt32BE();
                    block.Hash = _reader.Read<MD5Hash>();
                }
                else
                {
                    block.CompSize = size - 8;
                    block.DecompSize = size - 8 - 1;
                    block.Hash = default(MD5Hash);
                }

                _dataBlocks[i] = block;
            }

            _memStream = new MemoryStream(_dataBlocks.Sum(b => b.DecompSize));

            ProcessNextBlock();

            _length = headerSize == 0 ? _memStream.Length : _memStream.Capacity;

            //for (int i = 0; i < _dataBlocks.Length; i++)
            //{
            //    ProcessNextBlock();
            //}
        }