/// <summary> /// Parses the WzDirectory /// <paramref name="lazyParse">Only parses the first directory</paramref> /// </summary> internal void ParseDirectory(bool lazyParse = false) { //Debug.WriteLine(HexTool.ToString( reader.ReadBytes(20))); //reader.BaseStream.Position = reader.BaseStream.Position - 20; long available = reader.Available(); if (available == 0) { return; } int entryCount = reader.ReadCompressedInt(); if (entryCount < 0 || entryCount > 100000) // probably nothing > 100k folders for now. { throw new Exception("Invalid wz version used for decryption, try parsing other version numbers."); } for (int i = 0; i < entryCount; i++) { byte type = reader.ReadByte(); string fname = null; int fsize; int checksum; uint offset; long rememberPos = 0; switch (type) { case 1: //01 XX 00 00 00 00 00 OFFSET (4 bytes) { int unknown = reader.ReadInt32(); reader.ReadInt16(); uint offs = reader.ReadOffset(); continue; } case 2: { int stringOffset = reader.ReadInt32(); rememberPos = reader.BaseStream.Position; reader.BaseStream.Position = reader.Header.FStart + stringOffset; type = reader.ReadByte(); fname = reader.ReadString(); break; } case 3: case 4: { fname = reader.ReadString(); rememberPos = reader.BaseStream.Position; break; } default: { throw new Exception("[WzDirectory] Unknown directory. type = " + type); } } reader.BaseStream.Position = rememberPos; fsize = reader.ReadCompressedInt(); checksum = reader.ReadCompressedInt(); offset = reader.ReadOffset(); // IWzArchive::Getposition(pArchive) if (type == 3) { WzDirectory subDir = new WzDirectory(reader, fname, hash, WzIv, wzFile) { BlockSize = fsize, Checksum = checksum, Offset = offset, Parent = this }; subDirs.Add(subDir); if (lazyParse) { break; } } else { WzImage img = new WzImage(fname, reader, checksum) { BlockSize = fsize, Offset = offset, Parent = this }; images.Add(img); if (lazyParse) { break; } } } foreach (WzDirectory subdir in subDirs) { if (subdir.Checksum != 0) { reader.BaseStream.Position = subdir.offset; subdir.ParseDirectory(); } } }