ArcFile Open(byte[] basename, ArcView file, EncryptionScheme scheme, Key key) { uint key1 = scheme.BaseKey.Key1; uint key2 = scheme.BaseKey.Key2; for (int b = 0, e = basename.Length - 1; e >= 0; ++b, --e) { key1 ^= basename[e]; key2 ^= basename[b]; key1 = Binary.RotR(key1, 7); key2 = Binary.RotL(key2, 7); } if (null != key) { key1 ^= key.Key1; key2 ^= key.Key2; } uint code = file.View.ReadUInt32(4) ^ key2; int index_size = (int)(code & 0xffffff); byte flags = (byte)(code >> 24); if (0 != (flags & 1)) { index_size = (index_size << 11) - 8; } if (index_size < 5 || index_size >= file.MaxOffset) { return(null); } var index = new byte[index_size]; if (index_size != file.View.Read(8, index, 0, (uint)index_size)) { return(null); } scheme.DecryptIndex(index, index_size, key2); var lpk_info = new LpkInfo { AlignedOffset = 0 != (flags & 1), Flag1 = 0 != (flags & 2), IsEncrypted = 0 != (flags & 4), PackedEntries = 0 != (flags & 8), WholeCrypt = 0 != (flags & 0x10), Key = key1 }; var reader = new IndexReader(lpk_info); var dir = reader.Read(index); if (null == dir) { return(null); } // this condition is fishy, probably patch files have additional bitflag set if (lpk_info.WholeCrypt && Binary.AsciiEqual(basename, "PATCH")) { lpk_info.WholeCrypt = false; } return(new LuciArchive(file, this, dir, scheme, reader.Info)); }