예제 #1
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 = ImageFormat.FindByTag(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)
                {
                    Console.Error.WriteLine("{0}: unknown format", m_arc_name);
                    continue;
                }
                var arc = ((ArchiveFileSystem)VFS.Top).Source;
                if (args.Length > argn + 1)
                {
                    for (int i = argn + 1; i < args.Length; ++i)
                    {
                        ExtractFile(arc, args[i]);
                    }
                }
                else if (m_extract_all)
                {
                    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);
                    }
                }
            }
        }
예제 #2
0
        void Run(string[] args)
        {
            var command = args.Length < 1? "h": args[0];

            switch (command)
            {
            case "h":
            case "-h":
            case "--help":
            case "/?":
            case "-?":
                Usage();
                return;

            case "f":
                ListFormats();
                return;
            }

            if (command.Length != 1)
            {
                PrintError(File.Exists(command)? "No command specified. Use -h command line parameter to show help.": "Invalid command: " + command);
                return;
            }
            if (args.Length < 2)
            {
                PrintError("No archive file specified");
                return;
            }

            var inputFile = args[args.Length - 1];

            if (!File.Exists(inputFile))
            {
                PrintError("Input file " + inputFile + " does not exist");
                return;
            }

            var argLength = args.Length - 1;

            outputDirectory = Directory.GetCurrentDirectory();
            for (var i = 1; i < argLength; i++)
            {
                switch (args[i])
                {
                case "-o":
                    i++;
                    if (i >= argLength)
                    {
                        PrintError("No output directory specified");
                        return;
                    }
                    outputDirectory = args[i];
                    if (File.Exists(outputDirectory))
                    {
                        PrintError("Invalid output directory");
                        return;
                    }

                    //Directory.SetCurrentDirectory(outputDirectory);
                    break;

                case "-f":
                    i++;
                    if (i >= argLength)
                    {
                        PrintError("No filter specified");
                        return;
                    }

                    try {
                        fileFilter = new Regex(args[i]);
                    }
                    catch (ArgumentException e) {
                        PrintError("Invalid filter: " + e.Message);
                        return;
                    }

                    break;

                case "-if":
                    i++;
                    var formatTag = args[i].ToUpper();
                    if (formatTag == "JPG")
                    {
                        formatTag = "JPEG";
                    }

                    imageFormat = ImageFormat.FindByTag(formatTag);
                    if (imageFormat == null)
                    {
                        PrintError("Unknown image format specified: " + args[i]);
                        return;
                    }
                    break;

                case "-ca":
                    convertAudio = true;
                    break;

                case "-na":
                    skipAudio = true;
                    break;

                case "-ni":
                    skipImages = true;
                    break;

                case "-ns":
                    skipScript = true;
                    break;

                case "-aio":
                    adjustImageOffset = true;
                    break;

                case "-ocu":
                    autoImageFormat = true;
                    break;

                default:
                    Console.WriteLine("Warning: Unknown command line parameter: " + args[i]);
                    return;
                }
            }

            if (autoImageFormat && imageFormat == null)
            {
                PrintError("The parameter -ocu requires the image format (-if parameter) to be set");
                return;
            }

            DeserializeGameData();

            try {
                VFS.ChDir(inputFile);
            }
            catch (Exception) {
                PrintError("Input file has an unknown format");
                return;
            }

            var m_fs     = (ArchiveFileSystem)VFS.Top;
            var fileList = m_fs.GetFilesRecursive().Where(e => e.Offset >= 0);

            if (skipImages || skipScript || skipAudio || fileFilter != null)
            {
                fileList = fileList.Where(f => !(skipImages && f.Type == "image") &&
                                          !(skipScript && f.Type == "script") &&
                                          !(skipAudio && f.Type == "audio") &&
                                          (fileFilter == null || fileFilter.IsMatch(f.Name)));
            }

            if (!fileList.Any())
            {
                var hasFilter = skipAudio || skipImages || skipScript || fileFilter != null;
                PrintError(hasFilter? "No files match the given filter": "Archive is empty");
                return;
            }

            var fileArray = fileList.OrderBy(e => e.Offset).ToArray();

            Console.WriteLine(fileArray[0].Offset);

            switch (command)
            {
            case "i":
                Console.WriteLine(m_fs.Source.Tag);
                break;

            case "l":
                ListFiles(fileArray);
                break;

            case "x":
                ExtractFiles(fileArray, m_fs.Source);
                break;
            }
        }
예제 #3
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint file_size = file.View.ReadUInt32(4);

            if (file_size != file.MaxOffset)
            {
                return(null);
            }
            int count = file.View.ReadInt32(8);

            if (count <= 0 || count > 0xfffff)
            {
                return(null);
            }
            int  dir_level    = file.View.ReadByte(0x0d);
            int  dir_entries  = file.View.ReadUInt16(0x0e);
            uint index_offset = 0x10;
            uint index_size   = (uint)(count * 0x18 + dir_entries * 8);

            if (index_size > file.View.Reserve(index_offset, index_size))
            {
                return(null);
            }
            List <DirEntry> folders = null;

            if (0 != dir_entries && 2 == dir_level)
            {
                folders = new List <DirEntry> (dir_entries);
                uint dir_offset = index_offset + (uint)count * 0x18;
                for (int i = 0; i < dir_entries; ++i)
                {
                    folders.Add(new DirEntry {
                        Name  = file.View.ReadString(dir_offset, 4),
                        Index = file.View.ReadInt32(dir_offset + 4)
                    });
                    dir_offset += 8;
                }
            }
            bool   is_mask_arc    = "mask.arc" == Path.GetFileName(file.Name).ToLowerInvariant();
            var    dir            = new List <Entry> (count);
            int    next_folder    = null == folders ? count : folders[0].Index;
            int    folder         = 0;
            string current_folder = "";

            for (int i = 0; i < count; ++i)
            {
                while (i >= next_folder && folder < folders.Count)
                {
                    current_folder = folders[folder++].Name;
                    if (folders.Count == folder)
                    {
                        next_folder = count;
                    }
                    else
                    {
                        next_folder = folders[folder].Index;
                    }
                }
                string name = file.View.ReadString(index_offset, 0x10);
                if (0 == name.Length)
                {
                    return(null);
                }
                var offset = file.View.ReadUInt32(index_offset + 0x10);
                var entry  = new AutoEntry(Path.Combine(current_folder, name), () => {
                    uint signature = file.View.ReadUInt32(offset);
                    if (is_mask_arc)
                    {
                        return(ImageFormat.FindByTag("MSK/MAI"));
                    }
                    else if (0x4d43 == (signature & 0xffff)) // 'CM'
                    {
                        return(ImageFormat.FindByTag("CM/MAI"));
                    }
                    else if (0x4d41 == (signature & 0xffff)) // 'AM'
                    {
                        return(ImageFormat.FindByTag("AM/MAI"));
                    }
                    else if (0x4d42 == (signature & 0xffff)) // 'BM'
                    {
                        return(ImageFormat.Bmp);
                    }
                    else if (signature != 0)
                    {
                        return(FormatCatalog.Instance.LookupSignature(signature).FirstOrDefault());
                    }
                    else
                    {
                        return(null);
                    }
                });
                entry.Offset = offset;
                entry.Size   = file.View.ReadUInt32(index_offset + 0x14);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x18;
            }
            return(new ArcFile(file, this, dir));
        }