public ABheader(Stream reader) { CachedReader = reader; reader.Position = 0; byte[] buf = reader.ReadBytes(0x40); ReaderBE rbr = new ReaderBE(buf); signature = rbr.rStr(); version = rbr.ru4c(); VerLow = rbr.rStr(); VerUp = rbr.rStr(); size = rbr.ri8c(); compressedBlocksInfoSize = rbr.ri4c(); int uncompressedBlocksInfoSize = rbr.ri4c(); uint flags = rbr.ru4c(); int toBlo = rbr.seek; ABHsize = toBlo + compressedBlocksInfoSize; rbr.Clear(); reader.Position = 0; buf = reader.ReadBytes(ABHsize); rbr.Reload(buf); rbr.seek = toBlo; ReFillrbr(rbr, uncompressedBlocksInfoSize, flags); if (compressedblocks != null) { ABHsize = 0; Compressed = true; CachedReader.Close(); //CachedReader = new memreader~ } if (Files.Length == 2) { resSraw = Files[1].Offset; } //reader.Position = ABHsize; //if ram, ABHsize=0; }
unsafe void ReFillrbr(ReaderBE rbr, int uncompsize, uint flags) { byte[] buf; switch (flags & 0x3F) { default: //None break; case 1: buf = new byte[uncompsize]; break; case 2: //LZ4 case 3: //LZ4HC buf = new byte[uncompsize]; using (var decoder = new Lz4DecoderStream(new MemoryStream(rbr.Bas, rbr.seek, rbr.Bas.Length - rbr.seek))) decoder.Read(buf, 0, uncompsize); rbr.Reload(buf); break; } rbr.seek += 0x10; //uncompressedDataHash int blocksInfoCount = rbr.ri4c(); CompressedBlocks cb0 = *(CompressedBlocks *)rbr.ReadTc(0); if (blocksInfoCount == 1 && cb0.compressedSize == cb0.uncompressedSize) { } else { compressedblocks = new CompressedBlocks[blocksInfoCount]; fixed(byte *srcbb = &rbr.Bas[rbr.seek]) { for (int i = 0; i < blocksInfoCount; i++) { compressedblocks[i] = *(CompressedBlocks *)(srcbb + 0xA * i); } } } rbr.seek += blocksInfoCount * 0xA; blocksInfoCount = rbr.ri4c(); Files = new PackedFiles[blocksInfoCount]; for (int i = 0; i < blocksInfoCount; i++) { Files[i] = new PackedFiles { Offset = rbr.ru8c(), Size = rbr.ru8c(), flags = rbr.ru4c(), Name = rbr.rStr() }; } rbr.Clear(); }