예제 #1
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);
        }
예제 #2
0
        public override ImageData Read(Stream stream, ImageMetaData info)
        {
            var         meta   = (DziMetaData)info;
            PixelFormat format = PixelFormats.Bgra32;
            var         bitmap = new WriteableBitmap((int)meta.Width, (int)meta.Height, ImageData.DefaultDpiX,
                                                     ImageData.DefaultDpiY, format, null);
            int actual_width  = 0;
            int actual_height = 0;

            byte[] pixels = null;
            foreach (var tile in meta.Tiles.First())
            {
                var image_entry = VFS.GetFiles(tile.FileName + ".*").FirstOrDefault();
                if (null == image_entry)
                {
                    throw new FileNotFoundException("Tile not found", tile.FileName);
                }
                using (var input = VFS.OpenStream(image_entry))
                {
                    var image = Read(image_entry.Name, input);
                    if (null == image)
                    {
                        throw new FileFormatException("Unknown DZI tile format");
                    }
                    var converted = image.Bitmap;
                    if (converted.Format != format)
                    {
                        converted = new FormatConvertedBitmap(converted, format, null, 0);
                    }
                    int stride    = converted.PixelWidth * 4;
                    int tile_size = stride * converted.PixelHeight;
                    if (null == pixels || pixels.Length < tile_size)
                    {
                        pixels = new byte[tile_size];
                    }
                    converted.CopyPixels(pixels, stride, 0);
                    var width  = Math.Min(converted.PixelWidth, bitmap.PixelWidth - tile.X);
                    var height = Math.Min(converted.PixelHeight, bitmap.PixelHeight - tile.Y);
                    var rect   = new Int32Rect(tile.X, tile.Y, width, height);
                    bitmap.WritePixels(rect, pixels, stride, 0);
                    if (tile.X + width > actual_width)
                    {
                        actual_width = tile.X + width;
                    }
                    if (tile.Y + height > actual_height)
                    {
                        actual_height = tile.Y + height;
                    }
                }
            }
            BitmapSource result = bitmap;

            if (actual_width < bitmap.PixelWidth || actual_height < bitmap.PixelHeight)
            {
                var rect = new Int32Rect(0, 0, actual_width, actual_height);
                result = new CroppedBitmap(bitmap, rect);
            }
            result.Freeze();
            return(new ImageData(result, meta));
        }
예제 #3
0
파일: PlarfGame.cs 프로젝트: myblindy/plarf
        private void LoadGameData()
        {
            ResourceClasses = new List <ResourceClass>();
            foreach (var resfile in VFS.GetFiles(@"ResourceClasses", "*.dat"))
            {
                using (var resfilestream = VFS.OpenStream(resfile))
                    ResourceClasses.Add(new ResourceClass(new DataFile(resfilestream)));
            }

            ResourceTemplates = new Dictionary <string, Resource>();
            foreach (var resfile in VFS.GetFiles(@"Resources", "*.dat"))
            {
                using (var resfilestream = VFS.OpenStream(resfile))
                {
                    var res = new Resource(new DataFile(resfilestream));
                    ResourceTemplates.Add(res.Name, res);
                }
            }

            using (var hfilestream = VFS.OpenStream("human.dat"))
                HumanTemplate = new Human(new DataFile(hfilestream));

            BuildingClasses = new Dictionary <string, Building>();
            foreach (var bfile in VFS.GetFiles(@"Buildings", "*.dat"))
            {
                using (var bfilestream = VFS.OpenStream(bfile))
                {
                    var b = Building.FromDataFile(new DataFile(bfilestream));
                    BuildingClasses.Add(b.Name, b);
                }
            }

            WorkerTypes = BuildingClasses.Values.Select(b => b.WorkerType).Where(t => t != null).ToList();
        }
예제 #4
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);
            }
        }
예제 #5
0
파일: ArcGPK.cs 프로젝트: zxc120/GARbro
        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);
        }
예제 #6
0
 private void OpenFile(string filename)
 {
     if (filename == CurrentPath || string.IsNullOrEmpty(filename))
     {
         return;
     }
     try
     {
         if (File.Exists(filename))
         {
             VFS.FullPath = new string[] { filename, "" }
         }
         ;
         else
         {
             VFS.FullPath = new string[] { filename }
         };
         var vm = new DirectoryViewModel(VFS.FullPath, VFS.GetFiles(), VFS.IsVirtual);
         PushViewModel(vm);
         if (null != VFS.CurrentArchive)
         {
             SetStatusText(VFS.CurrentArchive.Description);
         }
         lv_SelectItem(0);
     }
     catch (OperationCanceledException X)
     {
         SetStatusText(X.Message);
     }
     catch (Exception X)
     {
         PopupError(string.Format("{0}:\n{1}", filename, X.Message), guiStrings.MsgErrorOpening);
     }
 }
예제 #7
0
파일: ImageAKB.cs 프로젝트: zxc120/GARbro
        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);
        }
예제 #8
0
        void Run(string[] args)
        {
            int argn = 0;

            if (args[argn].Equals("-l"))
            {
                ListFormats();
                return;
            }
            if (args[argn].Equals("-t"))
            {
                TestArc(args);
                return;
            }
            if (args[argn].Equals("-x"))
            {
                ++argn;
                if (args.Length < 2)
                {
                    Usage();
                    return;
                }
            }
            DeserializeGameData();
            foreach (var file in VFS.GetFiles(args[argn]))
            {
                m_arc_name = file.Name;
                var arc = ArcFile.TryOpen(file);
                if (null == arc)
                {
                    Console.Error.WriteLine("{0}: unknown format", m_arc_name);
                    continue;
                }
                using (arc)
                {
                    if (args.Length > argn + 1)
                    {
                        for (int i = argn + 1; i < args.Length; ++i)
                        {
                            ExtractFile(arc, args[i]);
                        }
                    }
                    else if (args[0].Equals("-x"))
                    {
                        ExtractAll(arc);
                    }
                    else
                    {
                        foreach (var entry in arc.Dir.OrderBy(e => e.Offset))
                        {
                            Console.WriteLine("{0,9} [{2:X8}] {1}", entry.Size, entry.Name, entry.Offset);
                        }
                    }
                }
            }
        }
예제 #9
0
        public override ImageMetaData ReadMetaData(Stream stream)
        {
            var header = new byte[0x7C];

            if (header.Length != stream.Read(header, 0, header.Length))
            {
                return(null);
            }
            var base_name = Binary.GetCString(header, 4, 100);

            if (string.IsNullOrEmpty(base_name))
            {
                return(null);
            }
            var files = VFS.GetFiles(base_name + ".*");

            if (!files.Any())
            {
                throw new FileNotFoundException(string.Format("Base image '{0}' not found", base_name));
            }
            var base_entry = files.First();

            using (var input = VFS.OpenSeekableStream(base_entry))
            {
                // ReadMetaData isn't supplied with a filename being processed, so infinite recursion can't be
                // prevented here unless we save state in a static member.
                var format = ImageFormat.FindFormat(input, base_entry.Name);
                if (null == format)
                {
                    throw new InvalidFormatException(string.Format("Unable to interpret base image '{0}'", base_name));
                }
                format.Item2.FileName = base_entry.Name;
                return(new DifMetaData
                {
                    Width = format.Item2.Width,
                    Height = format.Item2.Height,
                    BPP = 24,
                    BaseEntry = base_entry,
                    BaseFormat = format.Item1,
                    BaseInfo = format.Item2,
                    PackedIndexSize = LittleEndian.ToInt32(header, 0x68),
                    IndexSize = LittleEndian.ToInt32(header, 0x6C),
                    PackedDiffSize = LittleEndian.ToInt32(header, 0x70),
                    DiffDataSize = LittleEndian.ToInt32(header, 0x74),
                    DiffCount = LittleEndian.ToInt32(header, 0x78),
                });
            }
        }
예제 #10
0
파일: ArcBIN.cs 프로젝트: zxc120/GARbro
        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);
        }
예제 #11
0
        public override ImageMetaData ReadMetaData(IBinaryStream stream)
        {
            var header    = stream.ReadHeader(0x7C);
            var base_name = header.GetCString(4, 100);

            if (string.IsNullOrEmpty(base_name))
            {
                return(null);
            }
            var files = VFS.GetFiles(base_name + ".*");

            if (!files.Any())
            {
                throw new FileNotFoundException(string.Format("Base image '{0}' not found", base_name));
            }
            var base_entry = files.First();

            if (base_entry.Name.Equals(stream.Name, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new InvalidFormatException("DIF image references itself");
            }
            using (var input = VFS.OpenBinaryStream(base_entry))
            {
                // infinite recursion still possible in case of two files referencing each other.
                var format = ImageFormat.FindFormat(input);
                if (null == format)
                {
                    throw new InvalidFormatException(string.Format("Unable to interpret base image '{0}'", base_name));
                }
                format.Item2.FileName = base_entry.Name;
                return(new DifMetaData
                {
                    Width = format.Item2.Width,
                    Height = format.Item2.Height,
                    BPP = 24,
                    BaseEntry = base_entry,
                    BaseFormat = format.Item1,
                    BaseInfo = format.Item2,
                    PackedIndexSize = header.ToInt32(0x68),
                    IndexSize = header.ToInt32(0x6C),
                    PackedDiffSize = header.ToInt32(0x70),
                    DiffDataSize = header.ToInt32(0x74),
                    DiffCount = header.ToInt32(0x78),
                });
            }
        }
예제 #12
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));
 }
예제 #13
0
파일: ArcNOA.cs 프로젝트: zxc120/GARbro
        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);
        }
예제 #14
0
        byte[] GuessKeyData(string arc_name)
        {
            if (VFS.IsVirtual)
            {
                return(null);
            }
            // XXX add button to query dialog like with CatSystem?
            var pattern = VFS.CombinePath(VFS.GetDirectoryName(arc_name), @"..\*.exe");

            foreach (var file in VFS.GetFiles(pattern))
            {
                try
                {
                    var key = GetKeyDataFromExe(file.Name);
                    if (key != null)
                    {
                        return(key);
                    }
                }
                catch { /* ignore errors */ }
            }
            return(null);
        }
예제 #15
0
        void Run(string[] args)
        {
            int argn = 0;

            while (argn < args.Length)
            {
                if (args[argn].Equals("-l"))
                {
                    ListFormats();
                    return;
                }
                else if (args[argn].Equals("-t"))
                {
                    TestArc(args);
                    return;
                }
                else if (args[argn].Equals("-c"))
                {
                    if (argn + 1 >= args.Length)
                    {
                        Usage();
                        return;
                    }
                    var tag = args[argn + 1];
                    m_image_format = ImageConverter.FindFormat(tag);
                    if (null == m_image_format)
                    {
                        Console.Error.WriteLine("{0}: unknown format specified", tag);
                        return;
                    }
                    argn += 2;
                }
                else if (args[argn].Equals("-x"))
                {
                    m_extract_all = true;
                    ++argn;
                    if (args.Length <= argn)
                    {
                        Usage();
                        return;
                    }
                }
                else
                {
                    break;
                }
            }
            if (argn >= args.Length)
            {
                Usage();
                return;
            }
            DeserializeGameData();
            foreach (var file in VFS.GetFiles(args[argn]))
            {
                m_arc_name = file.Name;
                try
                {
                    VFS.ChDir(m_arc_name);
                }
                catch (Exception X)
                {
                    Console.Error.WriteLine("{0}: unknown format", m_arc_name);
                    continue;
                }
                var arc = (ArchiveFileSystem)VFS.Top;
                if (args.Length > argn + 1)
                {
                    for (int i = argn + 1; i < args.Length; ++i)
                    {
                        ExtractFile(arc.Source, args[i]);
                    }
                }
                else if (m_extract_all)
                {
                    ExtractAll(arc.Source);
                }
                else
                {
                    foreach (var entry in arc.Source.Dir.OrderBy(e => e.Offset))
                    {
                        Console.WriteLine("{0,9} [{2:X8}] {1}", entry.Size, entry.Name, entry.Offset);
                    }
                }
            }
        }