예제 #1
0
        public void ExtractData(Stream stream)
        {
            int magic = reader.ReadInt32(); // BLTE (raw)

            if (magic != 0x45544c42)
            {
                throw new InvalidDataException("BLTEHandler: magic");
            }

            int frameHeaderSize = reader.ReadInt32BE();
            int chunkCount      = 0;
            int totalSize       = 0;

            if (frameHeaderSize == 0)
            {
                totalSize = size - 8;// - 38;

                chunkCount = 1;
            }
            else
            {
                byte unk1 = reader.ReadByte(); // byte

                if (unk1 != 0x0F)
                {
                    throw new InvalidDataException("unk1 != 0x0F");
                }

                byte v1 = reader.ReadByte();
                byte v2 = reader.ReadByte();
                byte v3 = reader.ReadByte();
                chunkCount = v1 << 16 | v2 << 8 | v3 << 0; // 3-byte
            }

            if (chunkCount < 0)
            {
                throw new InvalidDataException(String.Format("Possible error ({0}) at offset: 0x" + reader.BaseStream.Position.ToString("X"), chunkCount));
            }

            var chunks = new List <BLTEChunk>(chunkCount);

            for (int i = 0; i < chunkCount; ++i)
            {
                var chunk = new BLTEChunk();
                if (frameHeaderSize != 0)
                {
                    chunk.CompSize   = reader.ReadInt32BE();
                    chunk.DecompSize = reader.ReadInt32BE();
                    chunk.Hash       = reader.ReadBytes(16);
                }
                else
                {
                    chunk.CompSize   = totalSize;
                    chunk.DecompSize = totalSize - 1;
                    chunk.Hash       = null;
                }
                chunks.Add(chunk);
            }

            foreach (var chunk in chunks)
            {
                chunk.Data = reader.ReadBytes(chunk.CompSize);

                if (chunk.Data.Length != chunk.CompSize)
                {
                    throw new Exception("chunks[i].data.Length != chunks[i].compSize");
                }

                if (frameHeaderSize != 0)
                {
                    byte[] hh = md5.ComputeHash(chunk.Data);

                    if (!hh.EqualsTo(chunk.Hash))
                    {
                        throw new InvalidDataException("MD5 missmatch!");
                    }
                }

                switch (chunk.Data[0])
                {
                //case 0x45: // E
                //    break;
                //case 0x46: // F
                //    break;
                case 0x4E:     // N
                    if (chunk.Data.Length - 1 != chunk.DecompSize)
                    {
                        throw new InvalidDataException("Possible error (1) !");
                    }
                    stream.Write(chunk.Data, 1, chunk.DecompSize);
                    break;

                case 0x5A:     // Z
                    Decompress(stream, chunk.Data);
                    break;

                default:
                    throw new InvalidDataException("Unknown byte at switch case!");
                }
            }
        }
예제 #2
0
        public void ExtractData(Stream stream)
        {
            int magic = reader.ReadInt32(); // BLTE (raw)

            if (magic != 0x45544c42)
                throw new InvalidDataException("BLTEHandler: magic");

            int frameHeaderSize = reader.ReadInt32BE();
            int chunkCount = 0;
            int totalSize = 0;

            if (frameHeaderSize == 0)
            {
                totalSize = size - 8;// - 38;

                chunkCount = 1;
            }
            else
            {
                byte unk1 = reader.ReadByte(); // byte

                if (unk1 != 0x0F)
                    throw new InvalidDataException("unk1 != 0x0F");

                byte v1 = reader.ReadByte();
                byte v2 = reader.ReadByte();
                byte v3 = reader.ReadByte();
                chunkCount = v1 << 16 | v2 << 8 | v3 << 0; // 3-byte
            }

            if (chunkCount < 0)
                throw new InvalidDataException(String.Format("Possible error ({0}) at offset: 0x" + reader.BaseStream.Position.ToString("X"), chunkCount));

            var chunks = new List<BLTEChunk>(chunkCount);

            for (int i = 0; i < chunkCount; ++i)
            {
                var chunk = new BLTEChunk();
                if (frameHeaderSize != 0)
                {
                    chunk.CompSize = reader.ReadInt32BE();
                    chunk.DecompSize = reader.ReadInt32BE();
                    chunk.Hash = reader.ReadBytes(16);
                }
                else
                {
                    chunk.CompSize = totalSize;
                    chunk.DecompSize = totalSize - 1;
                    chunk.Hash = null;
                }
                chunks.Add(chunk);
            }

            foreach (var chunk in chunks)
            {
                chunk.Data = reader.ReadBytes(chunk.CompSize);

                if (chunk.Data.Length != chunk.CompSize)
                    throw new Exception("chunks[i].data.Length != chunks[i].compSize");

                if (frameHeaderSize != 0)
                {
                    byte[] hh = md5.ComputeHash(chunk.Data);

                    if (!hh.EqualsTo(chunk.Hash))
                        throw new InvalidDataException("MD5 missmatch!");
                }

                switch (chunk.Data[0])
                {
                    //case 0x45: // E
                    //    break;
                    //case 0x46: // F
                    //    break;
                    case 0x4E: // N
                        if (chunk.Data.Length - 1 != chunk.DecompSize)
                            throw new InvalidDataException("Possible error (1) !");
                        stream.Write(chunk.Data, 1, chunk.DecompSize);
                        break;
                    case 0x5A: // Z
                        Decompress(stream, chunk.Data);
                        break;
                    default:
                        throw new InvalidDataException("Unknown byte at switch case!");
                }
            }
        }