Beispiel #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            string lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (lst_name == file.Name || !VFS.FileExists(lst_name))
            {
                return(null);
            }
            var lst_entry = VFS.FindFile(lst_name);
            int count     = (int)(lst_entry.Size / 0x16);

            if (count > 0xffff || count * 0x16 != lst_entry.Size)
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lst_entry))
            {
                var  dir          = new List <Entry> (count);
                uint index_offset = 0;
                for (int i = 0; i < count; ++i)
                {
                    string name  = lst.View.ReadString(index_offset, 14);
                    var    entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = lst.View.ReadUInt32(index_offset + 14);
                    entry.Size   = lst.View.ReadUInt32(index_offset + 18);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x16;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Beispiel #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".lay"))
            {
                return(null);
            }
            int tile_count  = file.View.ReadInt32(0);
            int coord_count = file.View.ReadInt32(4);

            if (!IsSaneCount(tile_count) || !IsSaneCount(coord_count))
            {
                return(null);
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name).TrimEnd('_');
            var png_name  = VFS.ChangeFileName(file.Name, base_name + ".png");

            if (!VFS.FileExists(png_name))
            {
                return(null);
            }
            ImageData image;
            var       png_entry = VFS.FindFile(png_name);

            using (var decoder = VFS.OpenImage(png_entry))
                image = decoder.Image;
            using (var input = file.CreateStream())
                using (var index = new BinaryReader(input))
                {
                    input.Position = 8;
                    var dir = new List <Entry> (tile_count);
                    for (int i = 0; i < tile_count; ++i)
                    {
                        uint id    = index.ReadUInt32();
                        int  first = index.ReadInt32();
                        int  count = index.ReadInt32();
                        var  name  = string.Format("{0}#{1:X8}", base_name, id);
                        var  entry = new LayEntry {
                            Name = name, Type = "image", Offset = 0,
                            Id   = id, First = first, Count = count
                        };
                        dir.Add(entry);
                    }
                    var tiles = new List <LayCoord> (coord_count);
                    for (int i = 0; i < coord_count; ++i)
                    {
                        var tile = new LayCoord();
                        tile.TargetX = index.ReadSingle() + 1;
                        tile.TargetY = index.ReadSingle() + 1;
                        tile.SourceX = index.ReadSingle() - 1;
                        tile.SourceY = index.ReadSingle() - 1;
                        tiles.Add(tile);
                    }
                    return(new LayArchive(file, this, dir, image.Bitmap, tiles));
                }
        }
Beispiel #3
0
        public override ArcFile TryOpen(ArcView file)
        {
            var  arc_list   = new List <Entry>();
            long max_offset = file.MaxOffset;

            for (int i = 1; i < 100; ++i)
            {
                var part_name = Path.ChangeExtension(file.Name, string.Format("a{0:D02}", i));
                if (!VFS.FileExists(part_name))
                {
                    break;
                }
                var part = VFS.FindFile(part_name);
                arc_list.Add(part);
                max_offset += part.Size;
            }
            uint index_length = file.View.ReadUInt32(8);
            uint data_offset  = file.View.ReadUInt32(0x10);

            using (var zindex = file.CreateStream(0x20, index_length))
                using (var uindex = new ZLibStream(zindex, CompressionMode.Decompress))
                    using (var index = new BinaryStream(uindex, file.Name))
                    {
                        var buffer = new byte[500];
                        var dir    = new List <Entry>();
                        while (index.PeekByte() != -1)
                        {
                            int entry_length = index.ReadInt32();
                            if (entry_length <= 528)
                            {
                                return(null);
                            }
                            bool is_deleted = index.ReadUInt32() != 0;
                            var  entry      = new PackedEntry();
                            entry.Offset = index.ReadInt64() + data_offset;
                            index.ReadUInt32();
                            entry.Size         = index.ReadUInt32();
                            entry.UnpackedSize = index.ReadUInt32();
                            entry.IsPacked     = entry.Size != entry.UnpackedSize;
                            index.Read(buffer, 0, 500);
                            int name_length = index.Read(buffer, 0, entry_length - 528);
                            if (!is_deleted && entry.CheckPlacement(max_offset))
                            {
                                entry.Name = Encoding.Unicode.GetString(buffer, 0, name_length);
                                entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                                dir.Add(entry);
                            }
                        }
                        return(new Mpf2Archive(file, this, dir, arc_list));
                    }
        }
Beispiel #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            string index_name = Path.ChangeExtension(file.Name, ".dll");

            if (index_name == file.Name || !VFS.FileExists(index_name))
            {
                return(null);
            }
            var index_entry = VFS.FindFile(index_name);

            if (index_entry.Size < 12)
            {
                return(null);
            }
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count) || (count & 0xFFFF) == 0x5A4D)  // 'MZ'
            {
                return(null);
            }

            var base_name = Path.GetFileNameWithoutExtension(file.Name);

            using (var idx = VFS.OpenView(index_entry))
            {
                var  dir          = new List <Entry> (count);
                uint index_offset = 4;
                int  i            = 0;
                uint last_offset  = 3;
                while (index_offset + 8 <= idx.MaxOffset)
                {
                    uint offset = idx.View.ReadUInt32(index_offset);
                    if (offset <= last_offset)
                    {
                        return(null);
                    }
                    var name  = string.Format("{0}#{1:D5}", base_name, i++);
                    var entry = AutoEntry.Create(file, offset, name);
                    entry.Size = idx.View.ReadUInt32(index_offset + 4);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    last_offset   = offset;
                    index_offset += 8;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Beispiel #5
0
 DirectoryViewModel GetNewViewModel(string path)
 {
     if (!string.IsNullOrEmpty(path))
     {
         if (!VFS.IsVirtual)
         {
             path = Path.GetFullPath(path);
         }
         var entry = VFS.FindFile(path);
         if (!(entry is SubDirEntry))
         {
             SetBusyState();
         }
         VFS.ChDir(entry);
     }
     return(new DirectoryViewModel(VFS.FullPath, VFS.GetFiles(), VFS.IsVirtual));
 }
Beispiel #6
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".vpk"))
            {
                return(null);
            }
            var vtb_name = Path.ChangeExtension(file.Name, "vtb");

            if (!VFS.FileExists(vtb_name))
            {
                return(null);
            }
            var vtb_entry = VFS.FindFile(vtb_name);
            int count     = (int)(vtb_entry.Size / 0x0C) - 1;

            if (!IsSaneCount(count))
            {
                return(null);
            }

            using (var vtb = VFS.OpenView(vtb_entry))
            {
                vtb.View.Reserve(0, (uint)vtb.MaxOffset);
                uint index_offset = 0;
                uint next_offset  = vtb.View.ReadUInt32(8);
                var  dir          = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    string name  = vtb.View.ReadString(index_offset, 8) + ".vaw";
                    var    entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset  = next_offset;
                    index_offset += 0xC;
                    next_offset   = vtb.View.ReadUInt32(index_offset + 8);
                    entry.Size    = next_offset - (uint)entry.Offset;
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                return(new ArcFile(file, this, dir));
            }
        }
Beispiel #7
0
        public override IImageDecoder OpenImage(ArcFile arc, Entry entry)
        {
            var input  = arc.OpenBinaryEntry(entry);
            int length = (int)(input.Length - 0x10);

            if ((length & 3) != 0)
            {
                return(ImageFormatDecoder.Create(input));
            }
            uint width      = input.ReadUInt32();
            uint height     = input.ReadUInt32();
            int  buf_width  = input.ReadInt32();
            int  buf_height = input.ReadInt32();
            var  info       = new ImageMetaData {
                Width = width, Height = height, BPP = 32
            };

            if (DefaultVisualMap.Value.ContainsKey(entry.Name))
            {
                var diff_info = DefaultVisualMap.Value[entry.Name];
                if (VFS.FileExists(diff_info.BaseFileName))
                {
                    var base_entry = VFS.FindFile(diff_info.BaseFileName);
                    using (var visbase = VFS.OpenImage(base_entry))
                    {
                        var base_decoder = visbase as Gx4ImageDecoder;
                        if (base_decoder != null)
                        {
                            info.OffsetX = diff_info.PosX;
                            info.OffsetY = diff_info.PosY;
                            var pixels = base_decoder.ReadPixels();
                            return(new Gx4OverlayDecoder(pixels, base_decoder.Info, input, info));
                        }
                    }
                }
            }
            return(new Gx4ImageDecoder(input, info));
        }
Beispiel #8
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(0, "EPK "))
            {
                return(null);
            }
            uint index_size = file.View.ReadUInt32(4) - 0x20;
            int  count      = file.View.ReadInt32(0x18);

            if (!IsSaneCount(count) || index_size >= file.MaxOffset)
            {
                return(null);
            }
            uint index_offset = 0x20;

            if (index_size > file.View.Reserve(index_offset, index_size))
            {
                return(null);
            }

            var arc_list = new List <Entry>();
            var arc_dir  = VFS.GetDirectoryName(file.Name);
            var arc_name = Path.GetFileNameWithoutExtension(file.Name);

            for (int i = 1; i < 10; ++i)
            {
                var part_name = string.Format("{0}.e{1:D02}", arc_name, i);
                part_name = VFS.CombinePath(arc_dir, part_name);
                if (!VFS.FileExists(part_name))
                {
                    break;
                }
                arc_list.Add(VFS.FindFile(part_name));
            }

            var name_buffer = new byte[0x40];
            var dir         = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint name_offset = file.View.ReadUInt32(index_offset + 8);
                int  name_length = file.View.ReadInt32(name_offset);
                if (name_length <= 0 || name_length >= index_size)
                {
                    return(null);
                }
                if (name_length > name_buffer.Length)
                {
                    name_buffer = new byte[name_length];
                }
                file.View.Read(name_offset + 4, name_buffer, 0, (uint)name_length);
                for (int j = 0; j < name_length; ++j)
                {
                    name_buffer[j] ^= 0xFF;
                }
                var name = Encodings.cp932.GetString(name_buffer, 0, name_length);

                var entry = FormatCatalog.Instance.Create <EpkEntry> (name);
                entry.Offset = file.View.ReadInt64(index_offset + 0x10);
                entry.Size   = file.View.ReadUInt32(index_offset + 0x18);
                dir.Add(entry);
                index_offset += 0x28;
            }
            var arc_set = new List <ArcView> (arc_list.Count);

            try
            {
                long max_offset = file.MaxOffset;
                var  bounds     = new List <long> (arc_list.Count + 1);
                bounds.Add(max_offset);
                foreach (var arc_entry in arc_list)
                {
                    var arc_file = VFS.OpenView(arc_entry);
                    arc_set.Add(arc_file);
                    max_offset += arc_file.MaxOffset;
                    bounds.Add(max_offset);
                }
                foreach (EpkEntry entry in dir)
                {
                    if (!entry.CheckPlacement(max_offset))
                    {
                        return(null);
                    }
                    entry.ArcNumber = bounds.FindIndex(x => x > entry.Offset);
                    if (entry.ArcNumber > 0)
                    {
                        entry.Offset -= bounds[entry.ArcNumber - 1];
                    }
                }
                var arc = new EpkArchive(file, this, dir, arc_set);
                arc_set = null;
                return(arc);
            }
            finally
            {
                if (arc_set != null)
                {
                    foreach (var arc in arc_set)
                    {
                        arc.Dispose();
                    }
                }
            }
        }
Beispiel #9
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".paz"))
            {
                return(null);
            }
            uint signature = file.View.ReadUInt32(0);
            // XXX encryption is queried for every .paz file
            var  scheme       = QueryEncryption(file.Name, signature);
            uint start_offset = scheme.Version > 0 ? 0x20u : 0u;
            uint index_size   = file.View.ReadUInt32(start_offset);

            start_offset += 4;
            byte xor_key = (byte)(index_size >> 24);

            if (xor_key != 0)
            {
                index_size ^= (uint)(xor_key << 24 | xor_key << 16 | xor_key << 8 | xor_key);
            }
            if (0 != (index_size & 7) || index_size + start_offset >= file.MaxOffset)
            {
                return(null);
            }

            var  arc_list   = new List <Entry>();
            var  arc_dir    = VFS.GetDirectoryName(file.Name);
            long max_offset = file.MaxOffset;

            for (char suffix = 'A'; suffix <= 'Z'; ++suffix)
            {
                var part_name = VFS.CombinePath(arc_dir, file.Name + suffix);
                if (!VFS.FileExists(part_name))
                {
                    break;
                }
                var part = VFS.FindFile(part_name);
                arc_list.Add(part);
                max_offset += part.Size;
            }
            var    arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant();
            bool   is_audio = AudioPazNames.Contains(arc_name);
            bool   is_video = VideoPazNames.Contains(arc_name);
            Stream input    = file.CreateStream(start_offset, index_size);

            byte[]       video_key = null;
            List <Entry> dir;

            try
            {
                if (xor_key != 0)
                {
                    input = new XoredStream(input, xor_key);
                }
                var enc = new Blowfish(scheme.ArcKeys[arc_name].IndexKey);
                input = new InputCryptoStream(input, enc.CreateDecryptor());
                using (var index = new ArcView.Reader(input))
                {
                    int count = index.ReadInt32();
                    if (!IsSaneCount(count))
                    {
                        return(null);
                    }
                    if (is_video)
                    {
                        video_key = index.ReadBytes(0x100);
                    }

                    dir = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        var name  = index.BaseStream.ReadCString();
                        var entry = FormatCatalog.Instance.Create <PazEntry> (name);
                        entry.Offset       = index.ReadInt64();
                        entry.UnpackedSize = index.ReadUInt32();
                        entry.Size         = index.ReadUInt32();
                        entry.AlignedSize  = index.ReadUInt32();
                        if (!entry.CheckPlacement(max_offset))
                        {
                            return(null);
                        }
                        entry.IsPacked = index.ReadInt32() != 0;
                        if (string.IsNullOrEmpty(entry.Type) && is_audio)
                        {
                            entry.Type = "audio";
                        }
                        if (scheme.Version > 0)
                        {
                            string password = "";
                            if (!entry.IsPacked && scheme.TypeKeys != null)
                            {
                                password = scheme.GetTypePassword(name, is_audio);
                            }
                            if (!string.IsNullOrEmpty(password) || is_video)
                            {
                                password  = string.Format("{0} {1:X08} {2}", name.ToLowerInvariant(), entry.UnpackedSize, password);
                                entry.Key = Encodings.cp932.GetBytes(password);
                            }
                        }
                        dir.Add(entry);
                    }
                }
            }
            finally
            {
                input.Dispose();
            }
            List <ArcView> parts = null;

            if (arc_list.Count > 0)
            {
                parts = new List <ArcView> (arc_list.Count);
                try
                {
                    foreach (var arc_entry in arc_list)
                    {
                        var arc_file = VFS.OpenView(arc_entry);
                        parts.Add(arc_file);
                    }
                }
                catch
                {
                    foreach (var part in parts)
                    {
                        part.Dispose();
                    }
                    throw;
                }
            }
            if (is_video)
            {
                if (scheme.Version < 1)
                {
                    var table = new byte[0x100];
                    for (int i = 0; i < 0x100; ++i)
                    {
                        table[video_key[i]] = (byte)i;
                    }
                    video_key = table;
                }
                return(new MovPazArchive(file, this, dir, scheme.Version, xor_key, video_key, parts));
            }
            return(new PazArchive(file, this, dir, scheme.Version, xor_key, scheme.ArcKeys[arc_name].DataKey, parts));
        }
Beispiel #10
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.Name.HasExtension(".idx"))
            {
                return(null);
            }
            string idx_name = Path.ChangeExtension(file.Name, ".idx");

            if (!VFS.FileExists(idx_name))
            {
                return(null);
            }
            var idx_entry = VFS.FindFile(idx_name);

            if (idx_entry.Size > 0xfffff || idx_entry.Size < 10000)
            {
                return(null);
            }

            byte[] index;
            using (var idx = VFS.OpenView(idx_entry))
                index = DecryptIndex(idx);
            int index_offset = 0;
            int entry_size   = index.Length / 10000;

            if (entry_size > 40)
            {
                entry_size = 40;
            }
            bool long_offsets = 40 == entry_size;
            int  name_size    = long_offsets ? 0x18 : 0x14;
            long first_offset = LittleEndian.ToUInt32(index, name_size);
            bool has_scripts  = false;
            var  dir          = new List <Entry>();

            while (index_offset < index.Length)
            {
                if (0 == index[index_offset])
                {
                    break;
                }
                var name = Binary.GetCString(index, index_offset, name_size);
                index_offset += name_size;
                var entry = FormatCatalog.Instance.Create <Entry> (name);
                if (name.HasExtension("dat"))
                {
                    entry.Type  = "script";
                    has_scripts = true;
                }
                if (long_offsets)
                {
                    entry.Offset  = LittleEndian.ToInt64(index, index_offset) - first_offset;
                    entry.Size    = LittleEndian.ToUInt32(index, index_offset + 8);
                    index_offset += 0x10;
                }
                else
                {
                    entry.Offset  = LittleEndian.ToUInt32(index, index_offset) - first_offset;
                    entry.Size    = LittleEndian.ToUInt32(index, index_offset + 4);
                    index_offset += 8;
                }
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            if (dir[0].Name.HasExtension("gr"))  // CG archive
            {
                var rng = DetectEncryptionScheme(file, dir[0]);
                return(new EaglsArchive(file, this, dir, new CgEncryption(rng)));
            }
            else if (has_scripts)
            {
                var enc = QueryEncryption();
                if (enc != null)
                {
                    return(new EaglsArchive(file, this, dir, enc));
                }
            }
            return(new ArcFile(file, this, dir));
        }
Beispiel #11
0
        public override ImageMetaData ReadMetaData(Stream stream)
        {
            var tex = VFS.FindFile("tex");

            if (!(tex is SubDirEntry))
            {
                return(null);
            }
            using (var reader = new StreamReader(stream, Encoding.UTF8, false, 2048, true))
            {
                reader.ReadLine(); // skip signature
                string line = reader.ReadLine();
                if (null == line)
                {
                    return(null);
                }
                var match = pair_re.Match(line);
                if (!match.Success)
                {
                    return(null);
                }
                uint width  = Convert.ToUInt16(match.Groups[1].Value);
                uint height = Convert.ToUInt16(match.Groups[2].Value);
                line = reader.ReadLine();
                if (null == line)
                {
                    return(null);
                }
                int count = Convert.ToInt16(line);
                if (0 == count)
                {
                    return(null);
                }
                var list = new List <IEnumerable <DziTile> > (count);
                for (int i = 0; i < count; ++i)
                {
                    line = reader.ReadLine();
                    if (null == line)
                    {
                        return(null);
                    }
                    match = pair_re.Match(line);
                    if (!match.Success)
                    {
                        return(null);
                    }
                    int block_w = Convert.ToUInt16(match.Groups[1].Value);
                    int block_h = Convert.ToUInt16(match.Groups[2].Value);
                    var tiles   = new List <DziTile> (block_w * block_h);
                    int y       = 0;
                    for (int j = 0; j < block_h; ++j)
                    {
                        int x = 0;
                        line = reader.ReadLine();
                        if (null == line)
                        {
                            return(null);
                        }
                        line = line.TrimEnd();
                        foreach (var file in line.Split(','))
                        {
                            if (!string.IsNullOrEmpty(file))
                            {
                                var filename = VFS.CombinePath(tex.Name, file);
                                tiles.Add(new DziTile {
                                    X = x, Y = y, FileName = filename
                                });
                            }
                            x += 256;
                        }
                        y += 256;
                    }
                    list.Add(tiles);
                }
                return(new DziMetaData
                {
                    Width = width,
                    Height = height,
                    BPP = 32,
                    Tiles = list,
                });
            }
        }
Beispiel #12
0
        public override ArcFile TryOpen(ArcView file)
        {
            string idx_name = Path.ChangeExtension(file.Name, ".idx");

            if (file.Name.Equals(idx_name, StringComparison.InvariantCultureIgnoreCase) ||
                !VFS.FileExists(idx_name))
            {
                return(null);
            }
            var idx_entry = VFS.FindFile(idx_name);

            if (idx_entry.Size > 0xfffff || idx_entry.Size < 10000)
            {
                return(null);
            }

            byte[] index;
            using (var idx = VFS.OpenView(idx_entry))
                index = DecryptIndex(idx);
            int  index_offset = 0;
            int  entry_size   = index.Length / 10000;
            bool long_offsets = 40 == entry_size;
            int  name_size    = long_offsets ? 0x18 : 0x14;
            long first_offset = LittleEndian.ToUInt32(index, name_size);
            var  dir          = new List <Entry>();

            while (index_offset < index.Length)
            {
                if (0 == index[index_offset])
                {
                    break;
                }
                var name = Binary.GetCString(index, index_offset, name_size);
                index_offset += name_size;
                var entry = FormatCatalog.Instance.Create <Entry> (name);
                if (name.EndsWith(".dat", StringComparison.InvariantCultureIgnoreCase))
                {
                    entry.Type = "script";
                }
                if (long_offsets)
                {
                    entry.Offset  = LittleEndian.ToInt64(index, index_offset) - first_offset;
                    entry.Size    = LittleEndian.ToUInt32(index, index_offset + 8);
                    index_offset += 0x10;
                }
                else
                {
                    entry.Offset  = LittleEndian.ToUInt32(index, index_offset) - first_offset;
                    entry.Size    = LittleEndian.ToUInt32(index, index_offset + 4);
                    index_offset += 8;
                }
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            if (dir[0].Name.EndsWith(".gr", StringComparison.InvariantCultureIgnoreCase))  // CG archive
            {
                return(new CgArchive(file, this, dir));
            }
            else
            {
                return(new ArcFile(file, this, dir));
            }
        }