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); } } } }
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; } }
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)); }