static void Main(string[] args) { MPQE mpqe = new MPQE(); Console.Write("MPQ-Extractor v{0} by WRS", mpqe.version); try { Console.WriteLine(" powered by {0}", SFmpq.MpqGetVersionString()); } catch (Exception e) { Console.WriteLine(); Console.WriteLine("Fatal: Could not locate SFmpq.dll " + e.Message); return; } Console.WriteLine(); if (args.Length == 0) { mpqe.helper(); return; } for (int i = 0; i < args.Length; ++i) { if (args[i].StartsWith("/")) { switch (args[i]) { case "/p": // use patch files if available Console.WriteLine("Using patch MPQ archives if available: Enabled"); mpqe.option_usepatchfiles = true; break; case "/l": Console.WriteLine("Lowercase output: Enabled"); mpqe.option_lowercase = true; break; case "/v": Console.WriteLine("Verbose output: Enabled"); mpqe.option_verbose = true; break; case "/d": if (i + 1 >= args.Length) { Console.WriteLine("Fatal: No output directory specified for /d"); mpqe.helper(); return; } ; ++i; Console.WriteLine("Output directory: {0}", args[i]); mpqe.option_outdir = args[i]; break; default: Console.WriteLine("Fatal: Unknown option {0}", args[i]); mpqe.helper(); return; } ; } else { if (mpqe.option_baseMPQ == null) { mpqe.option_baseMPQ = args[i]; } else { mpqe.option_searchglob = args[i]; } }; } if (mpqe.option_baseMPQ == null) { Console.WriteLine("Fatal: Did not provide MPQ file for extraction!"); mpqe.helper(); return; } ; mpqe.worker(); }
private void mpqExtract(string fileMPQ) { Console.WriteLine("Extracting from " + fileMPQ); if (SFmpq.SFileOpenArchive(fileMPQ, 0, 0, ref hMPQ) != 1) { Console.WriteLine("Error: Could not open {0}", fileMPQ); return; } ; if (SFmpq.SFileOpenFileEx(hMPQ, "(listfile)", 0, ref hFile) != 1) { SFmpq.SFileCloseArchive(hMPQ); Console.WriteLine("Error: Could not find (listfile) in " + fileMPQ); return; } ; byte[] buffer; FileSize = SFmpq.SFileGetFileSize(hFile, ref FileSize); buffer = new byte[FileSize]; if (SFmpq.SFileReadFile(hFile, buffer, (uint)FileSize, ref FileRead, IntPtr.Zero) != 1) { SFmpq.SFileCloseFile(hFile); SFmpq.SFileCloseArchive(hMPQ); Console.WriteLine("Error: Could not read (listfile) in " + fileMPQ); return; } ; SFmpq.SFileCloseFile(hFile); System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); string list = enc.GetString(buffer); string[] segs; string dirpath; foreach (string file in list.Split('\n')) { if (file == "") { return; } if (this.extractedFiles.Contains(file)) { continue; } segs = file.Split('\\'); dirpath = String.Join("\\", segs, 0, segs.Length - 1); if (option_lowercase) { dirpath = dirpath.ToLower(); } if (this.option_searchglob != null && !Match(option_searchglob, file.Trim(), false)) { continue; } if (SFmpq.SFileOpenFileEx(hMPQ, file.Trim(), 0, ref hFile) != 1) { Console.WriteLine("Error: Could not find " + file.Trim() + " in " + fileMPQ); continue; } ; FileSize = SFmpq.SFileGetFileSize(hFile, ref FileSize); if (FileSize == 0) { if (option_verbose) { Console.WriteLine("Skipping: {0} (NULL)", file.Trim()); } continue; } buffer = new byte[FileSize]; if (SFmpq.SFileReadFile(hFile, buffer, (uint)FileSize, ref FileRead, IntPtr.Zero) != 1) { SFmpq.SFileCloseFile(hFile); Console.WriteLine("Error: Could not read " + file.Trim() + " in " + fileMPQ); continue; } ; if (!Directory.Exists(option_outdir + Path.DirectorySeparatorChar + dirpath)) { Directory.CreateDirectory(option_outdir + Path.DirectorySeparatorChar + dirpath); } FileStream fs; if (option_lowercase) { fs = new FileStream(option_outdir + Path.DirectorySeparatorChar + file.Trim().ToLower(), FileMode.Create, FileAccess.Write); } else { fs = new FileStream(option_outdir + Path.DirectorySeparatorChar + file.Trim(), FileMode.Create, FileAccess.Write); } fs.Write(buffer, 0, FileSize); fs.Flush(); fs.Close(); if (option_verbose) { Console.WriteLine("Extracted: {0} ({1})", file.Trim(), bytes2text(FileSize)); } this.extractedFiles.Add(file); } ; SFmpq.SFileCloseArchive(hMPQ); }