Пример #1
0
 byte[] ReadBaseImage(IBinaryStream file, RctMetaData meta)
 {
     try
     {
         file.Position = meta.DataOffset;
         var    name     = file.ReadCString(meta.BaseNameLength);
         string dir_name = VFS.GetDirectoryName(meta.FileName);
         name = VFS.CombinePath(dir_name, name);
         if (VFS.FileExists(name))
         {
             using (var base_file = VFS.OpenBinaryStream(name))
             {
                 var base_info = ReadMetaData(base_file) as RctMetaData;
                 if (null != base_info &&
                     meta.Width == base_info.Width && meta.Height == base_info.Height)
                 {
                     base_info.BaseRecursionDepth = meta.BaseRecursionDepth + 1;
                     base_info.FileName           = name;
                     return(ReadPixelsData(base_file, base_info));
                 }
             }
         }
     }
     catch { /* ignore baseline image read errors */ }
     return(null);
 }
Пример #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (VFS.IsVirtual || !file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            var db_files = VFS.GetFiles(VFS.CombinePath(VFS.GetDirectoryName(file.Name), "*.db"));

            if (!db_files.Any())
            {
                return(null);
            }
            using (var igs = new IgsDbReader(file.Name))
            {
                foreach (var db_name in db_files.Select(e => e.Name))
                {
                    int arc_id;
                    if (igs.GetArchiveId(db_name, out arc_id))
                    {
                        var dir = igs.ReadIndex(arc_id);
                        if (0 == dir.Count)
                        {
                            return(null);
                        }
                        return(new ArcFile(file, this, dir));
                    }
                }
                return(null);
            }
        }
Пример #3
0
        public override ArcFile TryOpen(ArcView file)
        {
            var arc_name = Path.GetFileName(file.Name);
            var parsed   = ArcNameParser.ParseName(arc_name);

            if (null == parsed)
            {
                return(null);
            }
            var toc_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), parsed.Item1);
            var toc      = ReadToc(toc_name, 4);

            if (null == toc)
            {
                return(null);
            }

            bool has_images = false;
            var  dir        = new List <Entry>();

            using (var toc_stream = new MemoryStream(toc))
                using (var index = new StreamReader(toc_stream))
                {
                    string line;
                    while ((line = index.ReadLine()) != null)
                    {
                        var fields = line.Split(',');
                        if (fields.Length != 5)
                        {
                            return(null);
                        }
                        var    name = Path.ChangeExtension(fields[0], fields[4]);
                        string type = "";
                        if ("b" == fields[4])
                        {
                            type       = "image";
                            has_images = true;
                        }
                        else if ("k" == fields[4] || "j" == fields[4])
                        {
                            type = "audio";
                        }
                        var entry = new PackedEntry
                        {
                            Name         = name,
                            Type         = type,
                            Offset       = UInt32.Parse(fields[3]),
                            Size         = UInt32.Parse(fields[2]),
                            UnpackedSize = UInt32.Parse(fields[1]),
                        };
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        entry.IsPacked = entry.UnpackedSize != entry.Size;
                        dir.Add(entry);
                    }
                }
            return(ArchiveFromDir(file, dir, has_images));
        }
Пример #4
0
        public Dictionary <string, ArcView> GenerateResourceMap(List <Entry> dir)
        {
            var res_map   = new Dictionary <string, ArcView>();
            var asset_dir = VFS.GetDirectoryName(m_res_name);

            foreach (AssetEntry entry in dir)
            {
                if (null == entry.Bundle)
                {
                    continue;
                }
                if (res_map.ContainsKey(entry.Bundle.Name))
                {
                    continue;
                }
                var bundle_name = VFS.CombinePath(asset_dir, entry.Bundle.Name);
                if (!VFS.FileExists(bundle_name))
                {
                    entry.Bundle = null;
                    entry.Offset = entry.AssetObject.Offset;
                    entry.Size   = entry.AssetObject.Size;
                    continue;
                }
                res_map[entry.Bundle.Name] = VFS.OpenView(bundle_name);
            }
            return(res_map);
        }
Пример #5
0
 void ReadBaseImage()
 {
     try
     {
         string dir_name  = VFS.GetDirectoryName(m_info.FileName);
         string base_name = Path.ChangeExtension(m_info.BaseName, "qnt");
         base_name = VFS.CombinePath(dir_name, base_name);
         using (var base_file = VFS.OpenBinaryStream(base_name))
         {
             var base_info = Qnt.ReadMetaData(base_file) as QntMetaData;
             if (null != base_info && m_info.Width == base_info.Width && m_info.Height == base_info.Height)
             {
                 base_info.FileName = base_name;
                 var reader = new QntFormat.Reader(base_file.AsStream, base_info);
                 reader.Unpack();
                 m_base_bpp = reader.BPP;
                 m_base     = reader.Data;
             }
         }
     }
     catch (Exception X)
     {
         Trace.WriteLine(X.Message, "[DCF]");
     }
 }
Пример #6
0
        IList <string> GetFileNames(string arc_name)
        {
            var dir_name = VFS.GetDirectoryName(arc_name);
            var lst_name = Path.ChangeExtension(arc_name, ".lst");

            if (VFS.FileExists(lst_name))
            {
                return(ReadListFile(lst_name));
            }

            var lists_lst_name = VFS.CombinePath(dir_name, "lists.lst");

            if (!VFS.FileExists(lists_lst_name))
            {
                return(null);
            }
            var base_name = Path.GetFileNameWithoutExtension(arc_name);
            var arcs      = ReadListFile(lists_lst_name);
            var arc_no    = arcs.IndexOf(base_name);

            if (-1 == arc_no)
            {
                return(null);
            }
            var lists_bin_name = VFS.CombinePath(dir_name, "lists.bin");

            using (var lists_bin = VFS.OpenView(lists_bin_name))
                return(ReadFileNames(lists_bin, arc_no));
        }
Пример #7
0
        public override ArcFile TryOpen(ArcView file)
        {
            var arc_name = Path.GetFileName(file.Name);
            var parsed   = OldDatOpener.ArcNameParser.ParseName(arc_name);

            if (null == parsed)
            {
                return(null);
            }
            var toc_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), parsed.Item1);
            var toc      = ReadToc(toc_name, 4);

            if (null == toc)
            {
                return(null);
            }
            using (var index = new DatIndexReader(toc, file))
            {
                if (!index.Read())
                {
                    return(null);
                }
                return(ArchiveFromDir(file, index.Dir, index.HasImages));
            }
        }
Пример #8
0
 byte[] ReadBaseImage(Stream file, RctMetaData meta)
 {
     file.Position = meta.DataOffset;
     byte[] name_bin = new byte[meta.AddSize];
     if (name_bin.Length != file.Read(name_bin, 0, name_bin.Length))
     {
         throw new EndOfStreamException();
     }
     try
     {
         string name     = Encodings.cp932.GetString(name_bin, 0, name_bin.Length - 1);
         string dir_name = Path.GetDirectoryName(meta.FileName);
         name = VFS.CombinePath(dir_name, name);
         if (VFS.FileExists(name))
         {
             using (var base_file = VFS.OpenSeekableStream(name))
             {
                 var base_info = ReadMetaData(base_file) as RctMetaData;
                 if (null != base_info && 0 == base_info.AddSize &&
                     meta.Width == base_info.Width && meta.Height == base_info.Height)
                 {
                     base_info.FileName = name;
                     return(ReadPixelsData(base_file, base_info));
                 }
             }
         }
     }
     catch { /* ignore baseline image read errors */ }
     return(null);
 }
Пример #9
0
        byte[] ReadBaseImage(string filename, AkbMetaData overlay_info)
        {
            var pattern = Path.GetFileNameWithoutExtension(filename) + ".*";

            pattern = VFS.CombinePath(VFS.GetDirectoryName(filename), pattern);
            foreach (var entry in VFS.GetFiles(pattern))
            {
                if (entry.Name == overlay_info.FileName)
                {
                    continue;
                }
                using (var base_file = VFS.OpenBinaryStream(entry))
                {
                    var base_info = ReadMetaData(base_file) as AkbMetaData;
                    if (null != base_info && base_info.BPP == overlay_info.BPP &&
                        base_info.Width == overlay_info.Width && base_info.Height == overlay_info.Height)
                    {
                        // FIXME what if baseline image is incremental itself?
                        var reader = new AkbReader(base_file.AsStream, base_info);
                        return(reader.Unpack());
                    }
                }
            }
            return(null);
        }
Пример #10
0
        /// <summary>
        /// Look for 'key.fkey' file within nearby directories specified by KeyLocations.
        /// </summary>
        static byte[] FindKeyFile(ArcView arc_file)
        {
            // QLIE archives with key could be opened at the physical file system level only
            if (VFS.IsVirtual)
            {
                return(null);
            }
            var dir_name = Path.GetDirectoryName(arc_file.Name);

            foreach (var path in KeyLocations)
            {
                var name = Path.Combine(dir_name, path, "key.fkey");
                if (File.Exists(name))
                {
                    Trace.WriteLine("reading key from " + name, "[QLIE]");
                    return(File.ReadAllBytes(name));
                }
            }
            var pattern = VFS.CombinePath(dir_name, @"..\*.exe");

            foreach (var exe_file in VFS.GetFiles(pattern))
            {
                using (var exe = new ExeFile.ResourceAccessor(exe_file.Name))
                {
                    var reskey = exe.GetResource("RESKEY", "#10");
                    if (reskey != null)
                    {
                        return(reskey);
                    }
                }
            }
            return(null);
        }
Пример #11
0
        uint GetContentKey(ArcView file, List <Entry> dir, EncryptionScheme scheme)
        {
            if (null != scheme.ContentKey)
            {
                return(scheme.ContentKey.Value);
            }

            if (VFS.IsPathEqualsToFileName(file.Name, "system.arc"))
            {
                return(ReadSysenvSeed(file, dir, scheme.IndexKey));
            }
            else
            {
                var system_arc = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "system.arc");
                using (var arc = VFS.OpenView(system_arc))
                {
                    var header = arc.View.ReadBytes(0, 0x30);
                    Decrypt(header, 0, scheme.IndexKey);
                    using (var arc_file = ReadIndex(arc, header, scheme))
                    {
                        return(ReadSysenvSeed(arc, arc_file.Dir, scheme.IndexKey));
                    }
                }
            }
        }
Пример #12
0
        internal EriReader ReadImageData(IBinaryStream stream, EriMetaData meta)
        {
            stream.Position = meta.StreamPos;
            Color[] palette = null;
            using (var input = new EriFile(stream.AsStream))
            {
                for (;;) // ReadSection throws an exception in case of EOF
                {
                    var section = input.ReadSection();
                    if ("Stream  " == section.Id)
                    {
                        continue;
                    }
                    if ("ImageFrm" == section.Id)
                    {
                        break;
                    }
                    if ("Palette " == section.Id && meta.BPP <= 8 && section.Length <= 0x400)
                    {
                        palette = ReadPalette(stream.AsStream, (int)section.Length);
                        continue;
                    }
                    input.BaseStream.Seek(section.Length, SeekOrigin.Current);
                }
            }
            var reader = new EriReader(stream.AsStream, meta, palette);

            reader.DecodeImage();

            if (!string.IsNullOrEmpty(meta.Description))
            {
                var    tags = ParseTagInfo(meta.Description);
                string ref_file;
                if (tags.TryGetValue("reference-file", out ref_file))
                {
                    ref_file = ref_file.TrimEnd(null);
                    if (!string.IsNullOrEmpty(ref_file))
                    {
                        if ((meta.BPP + 7) / 8 < 3)
                        {
                            throw new InvalidFormatException();
                        }

                        ref_file = VFS.CombinePath(VFS.GetDirectoryName(meta.FileName), ref_file);
                        using (var ref_src = VFS.OpenBinaryStream(ref_file))
                        {
                            var ref_info = ReadMetaData(ref_src) as EriMetaData;
                            if (null == ref_info)
                            {
                                throw new FileNotFoundException("Referenced image not found", ref_file);
                            }
                            ref_info.FileName = ref_file;
                            var ref_reader = ReadImageData(ref_src, ref_info);
                            reader.AddImageBuffer(ref_reader);
                        }
                    }
                }
            }
            return(reader);
        }
Пример #13
0
        Stream OpenLstIndex(ArcView file, string dat_name, HibikiDatScheme scheme)
        {
            var lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (VFS.FileExists(lst_name))
            {
                return(VFS.OpenStream(lst_name));
            }
            else if ("init.dat" == dat_name)
            {
                return(file.CreateStream());
            }
            // try to open 'init.dat' archive in the same directory
            var init_dat = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "init.dat");

            if (!VFS.FileExists(init_dat))
            {
                return(file.CreateStream());
            }
            try
            {
                using (var init = VFS.OpenView(init_dat))
                    using (var init_arc = TryOpenWithScheme(init, ReadCount(init), scheme))
                    {
                        lst_name = Path.GetFileName(lst_name);
                        var lst_entry = init_arc.Dir.First(e => e.Name == lst_name);
                        return(init_arc.OpenEntry(lst_entry));
                    }
            }
            catch
            {
                return(file.CreateStream());
            }
        }
Пример #14
0
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            var meta = (RctMetaData)info;

            byte[] base_image = null;
            if (meta.FileName != null && meta.AddSize > 0 && OverlayFrames)
            {
                base_image = ReadBaseImage(file, meta);
            }

            var pixels = ReadPixelsData(file, meta);

            if (base_image != null)
            {
                pixels = CombineImage(base_image, pixels);
            }

            if (ApplyMask)
            {
                var base_name = Path.GetFileNameWithoutExtension(meta.FileName);
                var mask_name = base_name + "_.rc8";
                mask_name = VFS.CombinePath(VFS.GetDirectoryName(meta.FileName), mask_name);
                if (VFS.FileExists(mask_name))
                {
                    try
                    {
                        return(ApplyMaskToImage(meta, pixels, mask_name));
                    }
                    catch { /* ignore mask read errors */ }
                }
            }
            return(ImageData.Create(meta, PixelFormats.Bgr24, null, pixels, (int)meta.Width * 3));
        }
Пример #15
0
        byte[] QueryKey(string arc_name)
        {
            if (VFS.IsVirtual)
            {
                return(null);
            }
            var dir        = VFS.GetDirectoryName(arc_name);
            var parent_dir = Directory.GetParent(dir).FullName;
            var exe_files  = VFS.GetFiles(VFS.CombinePath(parent_dir, "*.exe")).Concat(VFS.GetFiles(VFS.CombinePath(dir, "*.exe")));

            foreach (var exe_entry in exe_files)
            {
                try
                {
                    using (var exe = new ExeFile.ResourceAccessor(exe_entry.Name))
                    {
                        var code = exe.GetResource("CIPHERCODE", "CODE");
                        if (null == code)
                        {
                            continue;
                        }
                        if (20 == code.Length)
                        {
                            code = new CowArray <byte> (code, 4, 16).ToArray();
                        }
                        return(code);
                    }
                }
                catch { /* ignore errors */ }
            }
            return(null);
        }
Пример #16
0
        void ImportKeys(string source_name)
        {
            var script_lpk = VFS.CombinePath(Path.GetDirectoryName(source_name), "SCRIPT.LPK");

            using (var script_file = VFS.OpenView(script_lpk))
                using (var script_arc = Open(ScriptName, script_file, CurrentScheme, null))
                {
                    if (null == script_arc)
                    {
                        throw new UnknownEncryptionScheme();
                    }
                    var entry = script_arc.Dir.FirstOrDefault(e => e.Name.Equals("gameinit.sob", StringComparison.InvariantCultureIgnoreCase));
                    if (null == entry)
                    {
                        throw new FileNotFoundException("Missing 'gameinit.sob' entry in SCRIPT.LPK");
                    }
                    using (var gameinit = script_arc.OpenEntry(entry))
                    {
                        var init_data = new byte[gameinit.Length];
                        gameinit.Read(init_data, 0, init_data.Length);
                        if (!ParseGameInit(init_data))
                        {
                            throw new UnknownEncryptionScheme();
                        }
                    }
                }
        }
Пример #17
0
        public override ImageData Read(IBinaryStream stream, ImageMetaData info)
        {
            var           meta     = (PgdIncMetaData)info;
            string        dir_name = VFS.GetDirectoryName(meta.FileName);
            string        name     = VFS.CombinePath(dir_name, meta.BaseName);
            PgdGeMetaData base_info;

            byte[]      image, overlay;
            PixelFormat format;

            using (var base_file = VFS.OpenBinaryStream(name))
            {
                base_info = PalFormat.Value.ReadMetaData(base_file) as PgdGeMetaData;
                if (null == base_info)
                {
                    throw new InvalidFormatException("Invalid baseline image format");
                }
                if (meta.OffsetX + meta.Width > base_info.Width ||
                    meta.OffsetY + meta.Height > base_info.Height)
                {
                    throw new InvalidFormatException("Incompatible baseline image dimensions");
                }
                base_info.FileName = name;
                using (var reader = new PgdReader(base_file, base_info))
                {
                    image  = reader.UnpackGE();
                    format = reader.Format;
                }
            }
            using (var reader = new PgdReader(stream, meta))
                overlay = reader.UnpackOverlay();

            int  overlay_bpp = meta.BPP / 8;
            int  base_bpp    = format.BitsPerPixel / 8;
            int  dst         = (meta.OffsetY * (int)base_info.Width + meta.OffsetX) * base_bpp;
            int  gap         = (int)(base_info.Width - meta.Width) * base_bpp;
            int  src         = 0;
            bool apply_alpha = overlay_bpp == 4 && base_bpp == 4;

            for (uint y = 0; y < meta.Height; ++y)
            {
                for (uint x = 0; x < meta.Width; ++x)
                {
                    image[dst]     ^= overlay[src];
                    image[dst + 1] ^= overlay[src + 1];
                    image[dst + 2] ^= overlay[src + 2];
                    if (apply_alpha)
                    {
                        image[dst + 3] ^= overlay[src + 3];
                    }
                    dst += base_bpp;
                    src += overlay_bpp;
                }
                dst += gap;
            }
            base_info.FileName = meta.FileName;
            return(ImageData.Create(base_info, format, null, image));
        }
Пример #18
0
        }                                                                 // 'Divided Picture'

        public override ImageMetaData ReadMetaData(IBinaryStream file)
        {
            var header = file.ReadHeader(0x30);

            if (!header.AsciiEqual("Divided Picture") || header.ToInt32(0x10) != 1)
            {
                return(null);
            }
            int version = header.ToInt32(0x14);

            if (version != 1 && version != 2)
            {
                return(null);
            }
            int info_pos = header.ToInt32(0x18);

            if (header.ToInt32(0x1C) < 4)
            {
                return(null);
            }
            int name_table_pos  = header.ToInt32(0x20);
            int name_table_size = header.ToInt32(0x24);
            int layout_pos      = header.ToInt32(0x28);

            file.Position = info_pos;
            ushort width  = file.ReadUInt16();
            ushort height = file.ReadUInt16();

            file.Position = name_table_pos;
            int name_count = file.ReadUInt16();

            if (name_count * 32 + 2 != name_table_size)
            {
                return(null);
            }
            var dir_name = VFS.GetDirectoryName(file.Name);
            var files    = new List <string> (name_count);

            for (int i = 0; i < name_count; ++i)
            {
                var name = file.ReadCString(0x20);
                if (name.StartsWith(@".\"))
                {
                    name = name.Substring(2);
                }
                name = VFS.CombinePath(dir_name, name);
                files.Add(name);
            }
            return(new DpoMetaData {
                Width = width,
                Height = height,
                BPP = 32,
                Version = version,
                LayoutOffset = layout_pos,
                Files = files,
            });
        }
Пример #19
0
        /// <summary>
        /// Look for control block within specified TPM plugin file.
        /// </summary>

        public override void Init(ArcFile arc)
        {
            if (ControlBlock != null)
            {
                return;
            }
            if (string.IsNullOrEmpty(TpmFileName))
            {
                throw new InvalidEncryptionScheme();
            }

            var dir_name = VFS.GetDirectoryName(arc.File.Name);
            var tpm_name = VFS.CombinePath(dir_name, TpmFileName);

            using (var tpm = VFS.OpenView(tpm_name))
            {
                if (tpm.MaxOffset < 0x1000 || tpm.MaxOffset > uint.MaxValue)
                {
                    throw new InvalidEncryptionScheme("Invalid KiriKiri TPM plugin");
                }
                using (var view = tpm.CreateViewAccessor(0, (uint)tpm.MaxOffset))
                    unsafe
                    {
                        byte *begin = view.GetPointer(0);
                        byte *end   = begin + (((uint)tpm.MaxOffset - 0x1000u) & ~0x3u);
                        try {
                            while (begin < end)
                            {
                                int i;
                                for (i = 0; i < s_ctl_block_signature.Length; ++i)
                                {
                                    if (begin[i] != s_ctl_block_signature[i])
                                    {
                                        break;
                                    }
                                }
                                if (s_ctl_block_signature.Length == i)
                                {
                                    ControlBlock = new uint[0x400];
                                    uint *src = (uint *)begin;
                                    for (i = 0; i < ControlBlock.Length; ++i)
                                    {
                                        ControlBlock[i] = ~src[i];
                                    }
                                    return;
                                }
                                begin += 4; // control block expected to be on a dword boundary
                            }
                            throw new InvalidEncryptionScheme("No control block found inside TPM plugin");
                        }
                        finally {
                            view.SafeMemoryMappedViewHandle.ReleasePointer();
                        }
                    }
            }
        }
Пример #20
0
        internal List <Entry> ReadDirectory(ArcView file, long base_offset, long max_offset, string base_dir)
        {
            uint dir_size = file.View.ReadUInt32(base_offset + 4);
            int  count    = file.View.ReadInt32(base_offset + 8);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            long data_offset = base_offset + dir_size + 12;

            if (dir_size >= max_offset || data_offset >= max_offset)
            {
                return(null);
            }

            file.View.Reserve(base_offset, (uint)(data_offset - base_offset));
            long cur_offset = base_offset + 12;

            var dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                if (cur_offset + 40 > data_offset)
                {
                    return(null);
                }
                string       name         = file.View.ReadString(cur_offset, 32);
                var          entry_offset = data_offset + file.View.ReadUInt32(cur_offset + 32);
                var          entry_size   = file.View.ReadUInt32(cur_offset + 36);
                List <Entry> subdir       = null;
                name = VFS.CombinePath(base_dir, name);
                if (name.HasExtension(".xfl") && file.View.ReadUInt32(entry_offset) == Signature)
                {
                    subdir = ReadDirectory(file, entry_offset, entry_offset + entry_size, name);
                }
                if (subdir != null && subdir.Count > 0)
                {
                    dir.AddRange(subdir);
                }
                else
                {
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = entry_offset;
                    entry.Size   = entry_size;
                    if (!entry.CheckPlacement(max_offset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                cur_offset += 40;
            }
            return(dir);
        }
Пример #21
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(0, "PF"))
            {
                return(null);
            }
            var base_name = Path.GetFileName(file.Name);

            if (!base_name.Equals("data02", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            var index_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "data01");

            if (!VFS.FileExists(index_name))
            {
                return(null);
            }
            using (var index = VFS.OpenView(index_name))
            {
                if (!index.View.AsciiEqual(0, "IF"))
                {
                    return(null);
                }
                int count = index.View.ReadInt16(2);
                if (!IsSaneCount(count) || 4 + 0x18 * count > index.MaxOffset)
                {
                    return(null);
                }

                uint index_offset = 4;
                var  dir          = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    var name  = index.View.ReadString(index_offset, 0x10);
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = index.View.ReadUInt32(index_offset + 0x10);
                    entry.Size   = index.View.ReadUInt32(index_offset + 0x14);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x18;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #22
0
        public virtual LinkEncryption GetEncryption()
        {
            var params_dir = VFS.GetDirectoryName(m_input.Name);
            var params_dat = VFS.CombinePath(params_dir, "params.dat");

            if (!VFS.FileExists(params_dat))
            {
                return(null);
            }

            using (var input = VFS.OpenBinaryStream(params_dat))
            {
                var param = ParamsDeserializer.Create(input);
                return(param.GetEncryption());
            }
        }
Пример #23
0
        BinScheme FindScheme(ArcView bin_file)
        {
            var bin_name = Path.GetFileName(bin_file.Name).ToUpperInvariant();

            foreach (var game in KnownSchemes.Values)
            {
                BinScheme scheme;
                if (game.TryGetValue(bin_name, out scheme) && bin_file.MaxOffset == scheme.Size)
                {
                    return(scheme);
                }
            }
            if (bin_file.MaxOffset >= uint.MaxValue)
            {
                return(null);
            }
            var bin_dir   = VFS.GetDirectoryName(bin_file.Name);
            var game_dir  = Directory.GetParent(bin_dir).FullName;
            var exe_files = VFS.GetFiles(VFS.CombinePath(game_dir, "*.exe"));

            if (!exe_files.Any())
            {
                return(null);
            }
            var last_idx = new byte[12];

            LittleEndian.Pack((uint)bin_file.MaxOffset, last_idx, 0);
            LittleEndian.Pack((uint)bin_file.MaxOffset, last_idx, 4);
            foreach (var exe_entry in exe_files)
            {
                using (var exe_file = VFS.OpenView(exe_entry))
                {
                    var exe = new ExeFile(exe_file);
                    if (!exe.ContainsSection(".data"))
                    {
                        continue;
                    }
                    var data_section = exe.Sections[".data"];
                    var idx_pos      = exe.FindString(data_section, last_idx, 4);
                    if (idx_pos > 0)
                    {
                        return(ParseIndexTable(exe_file, data_section, idx_pos, bin_name));
                    }
                }
            }
            return(null);
        }
Пример #24
0
        public override ArcFile TryOpen(ArcView file)
        {
            var base_dir  = VFS.GetDirectoryName(file.Name);
            var base_name = Path.GetFileNameWithoutExtension(file.Name);
            var list_file = VFS.CombinePath(base_dir, base_name + "l.dat");

            if (!VFS.FileExists(list_file))
            {
                return(null);
            }
            string index;

            using (var ls = VFS.OpenStream(list_file))
                using (var zls = new ZLibStream(ls, CompressionMode.Decompress))
                    using (var reader = new StreamReader(zls, Encodings.cp932))
                    {
                        index = reader.ReadToEnd();
                    }
            if (string.IsNullOrEmpty(index))
            {
                return(null);
            }

            var dir   = new List <Entry>();
            var match = IndexEntryRe.Match(index);

            while (match.Success)
            {
                var entry = new Entry {
                    Name   = match.Groups[1].Value,
                    Offset = UInt32.Parse(match.Groups[3].Value),
                    Size   = UInt32.Parse(match.Groups[2].Value),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                match = match.NextMatch();
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }
Пример #25
0
        public override ArcFile TryOpen(ArcView file)
        {
            string dir_name  = Path.GetDirectoryName(file.Name);
            string file_name = Path.GetFileName(file.Name);

            foreach (var ini_name in GetIndexNames(file_name))
            {
                string ini_path = VFS.CombinePath(dir_name, ini_name);
                if (VFS.FileExists(ini_path))
                {
                    var dir = ReadIndex(ini_path, file_name);
                    if (null != dir)
                    {
                        return(new ArcFile(file, this, dir));
                    }
                }
            }
            return(null);
        }
Пример #26
0
 string ReadBaseName(IBinaryStream input, AgfMetaData info)
 {
     input.Position = info.DataOffset + info.BaseNameOffset;
     using (var reader = new BinaryReader(input.AsStream, Encoding.Unicode, true))
     {
         var name = new StringBuilder();
         for (;;)
         {
             char c = reader.ReadChar();
             if (0 == c)
             {
                 break;
             }
             name.Append(c);
         }
         var dir_name = VFS.GetDirectoryName(info.FileName);
         return(VFS.CombinePath(dir_name, name.ToString()));
     }
 }
Пример #27
0
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            var         meta = (IptMetaData)info;
            PixelFormat format;

            if ("cut" == meta.Mode)
            {
                format = PixelFormats.Bgra32;
            }
            else if ("diff" == meta.Mode)
            {
                format = PixelFormats.Bgr32;
            }
            else
            {
                throw new InvalidFormatException(string.Format("Not supported IPT tile mode '{0}'.", meta.Mode));
            }
            var canvas = new WriteableBitmap(meta.iWidth, meta.iHeight, ImageData.DefaultDpiX,
                                             ImageData.DefaultDpiY, format, null);
            var base_dir = VFS.GetDirectoryName(file.Name);

            try
            {
                canvas.Lock();
                if ("diff" == meta.Mode)
                {
                    var base_name = VFS.CombinePath(base_dir, meta.BaseName + ".png");
                    ReadIntoCanvas(base_name, canvas, 0, 0);
                }
                foreach (var tile in meta.Tiles)
                {
                    var tile_name = VFS.CombinePath(base_dir, tile.FileName + ".png");
                    ReadIntoCanvas(tile_name, canvas, tile.X, tile.Y, true);
                }
            }
            finally
            {
                canvas.Unlock();
            }
            canvas.Freeze();
            return(new ImageData(canvas, meta));
        }
Пример #28
0
        IList <string> GetFileNames(string dir_name, string base_name)
        {
            var lists_lst_name = VFS.CombinePath(dir_name, "lists.lst");

            if (!VFS.FileExists(lists_lst_name))
            {
                return(null);
            }
            var arcs   = GetArcNames(lists_lst_name);
            var arc_no = arcs.IndexOf(base_name);

            if (-1 == arc_no)
            {
                return(null);
            }
            var lists_bin_name = VFS.CombinePath(dir_name, "lists.bin");

            using (var lists_bin = VFS.OpenView(lists_bin_name))
                return(ReadFileNames(lists_bin, arc_no));
        }
Пример #29
0
        string ExtractNoaPassword(string arc_name)
        {
            if (VFS.IsVirtual)
            {
                return(null);
            }
            var dir        = VFS.GetDirectoryName(arc_name);
            var noa_name   = Path.GetFileName(arc_name);
            var parent_dir = Directory.GetParent(dir).FullName;
            var exe_files  = VFS.GetFiles(VFS.CombinePath(parent_dir, "*.exe")).Concat(VFS.GetFiles(VFS.CombinePath(dir, "*.exe")));

            foreach (var exe_entry in exe_files)
            {
                try
                {
                    using (var exe = new ExeFile.ResourceAccessor(exe_entry.Name))
                    {
                        var cotomi = exe.GetResource("IDR_COTOMI", "#10");
                        if (null == cotomi)
                        {
                            continue;
                        }
                        using (var res = new MemoryStream(cotomi))
                            using (var input = new ErisaNemesisStream(res))
                            {
                                var xml = new XmlDocument();
                                xml.Load(input);
                                var password = XmlFindArchiveKey(xml, noa_name);
                                if (password != null)
                                {
                                    Trace.WriteLine(string.Format("{0}: found password \"{1}\"", noa_name, password), "[NOA]");
                                    return(password);
                                }
                            }
                    }
                }
                catch { /* ignore errors */ }
            }
            return(null);
        }
Пример #30
0
        public override ArcFile TryOpen(ArcView file)
        {
            var    arc_name            = Path.GetFileName(file.Name);
            var    dir_name            = VFS.GetDirectoryName(file.Name);
            string game_name           = arc_name != "Arc06.dat" ? TryParseMeta(VFS.CombinePath(dir_name, "Arc06.dat")) : null;
            Tuple <string, int> parsed = null;

            if (string.IsNullOrEmpty(game_name))
            {
                game_name = TryParseMeta(VFS.CombinePath(dir_name, "Arc00.dat"));
                parsed    = s_name_parsers.Select(p => p.ParseName(arc_name)).FirstOrDefault(p => p != null);
            }
            else // Shukujo no Tsuyagoto special case
            {
                parsed = OldDatOpener.ArcNameParser.ParseName(arc_name);
            }
            if (null == parsed)
            {
                return(null);
            }
            string toc_name = parsed.Item1;
            int    arc_idx  = parsed.Item2;

            toc_name = VFS.CombinePath(dir_name, toc_name);
            var toc = ReadToc(toc_name, 8);

            if (null == toc)
            {
                return(null);
            }
            using (var index = new ArcIndexReader(toc, file, arc_idx, game_name))
            {
                if (!index.Read())
                {
                    return(null);
                }
                return(ArchiveFromDir(file, index.Dir, index.HasImages));
            }
        }