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; }
//static bswap bswapy; unsafe void MetaParse(Stream reader, bool isBE) { int cur = 5; byte[] buf = reader.ReadBytes(cur); ReaderLE drd; if (isBE) { drd = new ReaderBE(buf); } else { drd = new ReaderLE(buf); } if (Header.m_Version >= 8) { cur -= 4; m_TargetPlatform = (BuildTarget)drd.ri4c(); } if (Header.m_Version >= 13) { cur -= 1; m_EnableTypeTree = (buf[4] > 0); } if (cur != 0) { reader.Position -= cur; } cur = 0; buf = reader.ReadBytes((int)(Header.m_MetadataSize + rStart[0] - reader.Position)); fixed(byte *srcbb = &buf[0]) { drd.Reload(srcbb); int typCount = drd.ri4cp(); m_Types = new SerializedType[typCount]; for (int i = 0; i < typCount; i++) { m_Types[i] = TypeParse(drd); } int bigIDEnabled = 0; if (Header.m_Version >= 7 && Header.m_Version < 14) { bigIDEnabled = drd.ri4cp(); } int objectCount = drd.ri4cp(); rStart[1] = (int)(reader.Position - buf.Length - rStart[0] + drd.seek); cur = Extensionnyaa.mod4less(rStart[1]); drd.seek += cur; rStart[1] += cur; // rstart[0]+rstart[1] = abs offset to metas long vprs = Header.m_DataOffset; if (isAB != null) { vprs += isAB.ABHsize; } int syz = 0x14; cur = 0; if (Header.m_Version >= 22) { syz = 0x18; cur = 2; //u20 } else if (Header.m_Version < 16) { cur = 1; //u4 } byte *du = drd.ReadTcp(0); if (cur == 0) { for (int i = 0; i < objectCount; i++) { uMetaStruct ynfo = *(uMetaStruct *)du; var meta = GetNewuMeta(ynfo.PathID); meta.Offset = ynfo.Offset + vprs; meta.Size = ynfo.Size; meta.MB_type = m_Types[ynfo.TypeID]; meta.ClassID = meta.MB_type.classID; du += syz; } } else { for (int i = 0; i < objectCount; i++) { uMetaStruct ynfo = *(uMetaStruct *)du; if (cur == 1) { var meta = GetNewuMeta((long)ynfo.PathID_u4); meta.Offset = ynfo.Offset_u4 + vprs; meta.Size = ynfo.Size_u4; //meta.MB_type = m_Types[ynfo.TypeID]; meta.ClassID = (ClassIDType)ynfo.ClassID_u4; } else if (cur == 2) { var meta = GetNewuMeta(ynfo.PathID); meta.Offset = ynfo.Offset_u20 + vprs; meta.Size = ynfo.Size_u20; meta.MB_type = m_Types[ynfo.TypeID_u20]; meta.ClassID = meta.MB_type.classID; } du += syz; } } drd.seek += syz * objectCount; if (Header.m_Version >= 11) { syz = 0xc; objectCount = drd.ri4cp(); m_ScriptTypes = new LocalSerializedObjectIdentifierStruct[objectCount]; for (int i = 0; i < objectCount; i++) { m_ScriptTypes[i] = *(LocalSerializedObjectIdentifierStruct *)drd.ReadTcp(syz); } drd.seek += syz * objectCount; } objectCount = drd.ri4cp(); Dependency = new SerializedFile[objectCount]; for (int i = 0; i < objectCount; i++) { string nzstr = drd.rStrp(); yGUID yg = *(yGUID *)drd.ReadTcp(16); int tpp = drd.ri4cp(); SerializedFile dp = MakeDependency(drd.rStrp()); dp.setLinked(nzstr, tpp, yg); Dependency[i] = dp; } } }
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(); }