Beispiel #1
0
        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));
            }
        }
Beispiel #2
0
 public EpkIndexReader(EpkInfo info)
 {
     m_info = info;
 }