public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(0, "EPK")) { return(null); } int flags = file.View.ReadByte(3); if (0 == (flags & 2)) { return(null); } var scheme = DefaultScheme; uint arc_key = scheme.BaseKey.Key1; uint index_key = scheme.BaseKey.Key2; var arc_info = new EpkInfo { AlignedOffset = 0 != (flags & 1), Flag1 = 0 != (flags & 2), WholeCrypt = 0 != (flags & 4), IsEncrypted = 0 != (flags & 8), IndexEncrypted = 0 != (flags & 0xF0), PackedEntries = true, }; uint index_size = file.View.ReadUInt32(4); if (arc_info.IndexEncrypted) { var base_name = Path.GetFileNameWithoutExtension(file.Name).ToUpperInvariant(); var name_bytes = Encodings.cp932.GetBytes(base_name); int back = name_bytes.Length - 1; for (int i = 0; i < name_bytes.Length; ++i) { arc_key ^= name_bytes[back - i]; index_key ^= name_bytes[i]; arc_key = Binary.RotR(arc_key, 8); index_key = Binary.RotL(index_key, 8); } index_size ^= index_key; } arc_info.Key = arc_key; if (arc_info.AlignedOffset) { index_size <<= 11; } if (!arc_info.IndexEncrypted || arc_info.AlignedOffset) { index_size -= 8; } if (index_size >= file.MaxOffset) { return(null); } var index = file.View.ReadBytes(8, index_size); if (arc_info.IndexEncrypted) { scheme.DecryptIndex(index, index.Length, index_key); } var reader = new EpkIndexReader(arc_info); var dir = reader.Read(index); if (null == dir) { return(null); } if (arc_info.IndexEncrypted) { return(new LuciArchive(file, this, dir, scheme, arc_info)); } else { return(new ArcFile(file, this, dir)); } }
public EpkIndexReader(EpkInfo info) { m_info = info; }