Example #1
0
        /// <summary>
        /// Extract the root directory files from Base-{OS}.MPQ
        /// </summary>
        /// <returns></returns>
        private bool ExtractBaseMPQ()
        {
            Program.Log("Extracting Base MPQ...");

            string baseMPQ     = $"Base-{MFILDownloader.CurrentSession.OS}.mpq";
            string baseMPQpath = Path.Combine(_dataDirectory, baseMPQ);

            if (!File.Exists(baseMPQpath))
            {
                Program.Log($"{baseMPQ} not found!", ConsoleColor.Red);
                return(false);
            }

            using (var mpq = new MpqArchive(baseMPQpath, FileAccess.Read))
            {
                if (!TryGetFileList(mpq, true, out var files))
                {
                    Program.Log($"{baseMPQ} missing ListFile, manual extraction required.", ConsoleColor.Red);
                    return(false);
                }

                foreach (var file in files)
                {
                    mpq.ExtractFile(file, Path.Combine(_repo.DefaultDirectory, file));
                }
            }

            return(true);
        }
Example #2
0
        public static void ExtractListfiles(string to)
        {
            DirectoryInfo directory = new DirectoryInfo(ConfigurationManager.GameDir + "\\data\\");

            FileInfo[] Archives = directory.GetFiles("*.mpq");
            foreach (FileInfo fileinfo in Archives)
            {
                if (!File.Exists(to + "\\" + fileinfo.Name.Replace(".MPQ", ".txt")))
                {
                    using (MpqArchive archive = new MpqArchive(fileinfo.FullName, FileAccess.Read))
                    {
                        archive.ExtractFile("(listfile)", to + "\\" + fileinfo.Name.Replace(".MPQ", ".txt"));
                    }
                }
            }

            if (ConfigurationManager.Profile != 1) //Anything else than vanilla
            {
                if (!File.Exists(to + "\\" + "locale1.txt"))
                {
                    using (MpqArchive archive = new MpqArchive(ConfigurationManager.GameDir + "\\data\\" + locale + "\\" + "locale-" + locale + ".mpq", FileAccess.Read))
                    {
                        archive.ExtractFile("(listfile)", to + "\\" + "locale1.txt");
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Moves the files from the chunked archive to a flat file one
        /// </summary>
        /// <param name="archivename"></param>
        /// <param name="block"></param>
        private void DoFileSwap(string archivename, string block)
        {
            Directory.CreateDirectory("Temp");

            string filename = Path.GetFileName(archivename);

            using (var mpq = MpqArchive.CreateNew(archivename, MpqArchiveVersion.Version3))
                using (var tmp = new MpqArchive(block, FileAccess.Read, OpenArchiveFlags.BLOCK4))
                {
                    if (TryGetFileList(tmp, false, out var lf))
                    {
                        _progressBar.Start();

                        string tempPath;
                        for (int i = 0; i < lf.Count; i++)
                        {
                            using (var fs = tmp.OpenFile(lf[i]))
                            {
                                // incremental patch files can't be written directly with StormLib SFileCreateFile?
                                if ((fs.TFileEntry.dwFlags & 0x100000u) != 0x100000u)
                                {
                                    mpq.AddFileFromStream(fs);
                                }
                                else
                                {
                                    tempPath = Path.Combine("Temp", lf[i]);
                                    Directory.CreateDirectory(Path.GetDirectoryName(tempPath));

                                    tmp.ExtractFile(lf[i], tempPath);
                                    mpq.AddFileFromDisk(tempPath, lf[i], fs.TFileEntry.dwFlags);
                                }
                            }

                            _progressBar.Update(filename, i / (float)lf.Count);

                            if (i % 10000 == 0)
                            {
                                mpq.Flush();
                            }
                        }
                    }
                }

            Console.WriteLine("Emptying Temp Folder...");
            DeleteDirectory("Temp");
            _progressBar.Stop();
        }
    void BuildDataFiles()
    {
        using (var master = new MpqArchive(MasterPath, FileAccess.Read)) {
            using (var locale = new MpqArchive(LocalePath, FileAccess.Read)) {
                for (int i = 0; i < DataFiles.Length; i++)
                {
                    string
                        file      = DataFiles[i],
                        pathInMpq = $"UI\\{file}",
                        tmpPath   = $"{TempFolder}\\{file}",
                        dataPath  = $"{UmswePath}\\Data\\{file}",
                        patch     = $"{dataPath}.patch",
                        addon     = $"{dataPath}.addon";

                    //Why HasFile doesn't work?

                    /*if(locale.HasFile(pathInMpq)) {
                     *  locale.ExtractFile(pathInMpq, tmpPath);
                     * } else if(master.HasFile(pathInMpq)) {
                     *  master.ExtractFile(pathInMpq, tmpPath);
                     * }*/

                    try {
                        locale.ExtractFile(pathInMpq, tmpPath);
                    } catch {
                        master.ExtractFile(pathInMpq, tmpPath);
                    }

                    var data = new DataFile(tmpPath);
                    if (File.Exists(patch))
                    {
                        data.ApplyPatch(patch, PatchMode.Patch);
                    }
                    if (File.Exists(addon))
                    {
                        data.ApplyPatch(addon, PatchMode.Addon);
                    }

                    data.SaveAs(tmpPath);
                }
            }
        }
    }
Example #5
0
 /**
  * Extracts file to disk
  * Overwrites disk file if needed
  * It extrats to "out/" folder
  */
 private void Extract(String filename, MpqArchive archive)
 {
     try
     {
         Console.WriteLine("Extracting file: " + filename);
         if (!archive.HasFile(filename))
         {
             Console.WriteLine("File did not exist in MPQ archive: " + filename + " skipping. . .");
             return;
         }
         string destination = filename.Substring(1 + filename.LastIndexOf("\\"));
         archive.ExtractFile(filename, destination);
         if (File.Exists("out/" + filename))
         {
             File.Delete("out/" + filename);
             Console.WriteLine("Overwrote existing file...");
         }
         System.IO.Directory.CreateDirectory("out/" + filename);
         System.IO.Directory.Delete("out/" + filename);
         if (!File.Exists(destination))
         {
             Console.WriteLine("Expected that extracted file exists, but extraction failed!");
             return;
         }
         File.Copy(destination, "out/" + filename);
         if (!File.Exists("out/" + filename))
         {
             Console.WriteLine("Expected that copied file exists, but copy failed!");
             return;
         }
         File.Delete(destination);
         if (File.Exists(filename))
         {
             Console.WriteLine("Failed to delete origin file!");
             return;
         }
         Console.WriteLine("Extracted successfully to: " + filename);
     } catch (Exception ex)
     {
         Console.WriteLine("Failed to extract file " + filename + ": " + ex.Message);
     }
 }
Example #6
0
        // TODO: Add stream opening support
        /// <inheritdoc/>
        public Dictionary <string, List <string> > Scan(Scanner scanner, Stream stream, string file)
        {
            // If the mpq file itself fails
            try
            {
                string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                Directory.CreateDirectory(tempPath);

                using (MpqArchive mpqArchive = new MpqArchive(file, FileAccess.Read))
                {
                    // Try to open the listfile
                    string        listfile   = null;
                    MpqFileStream listStream = mpqArchive.OpenFile("(listfile)");

                    // If we can't read the listfile, we just return
                    if (!listStream.CanRead)
                    {
                        return(null);
                    }

                    // Read the listfile in for processing
                    using (StreamReader sr = new StreamReader(listStream))
                    {
                        listfile = sr.ReadToEnd();
                    }

                    // Split the listfile by newlines
                    string[] listfileLines = listfile.Replace("\r\n", "\n").Split('\n');

                    // Loop over each entry
                    foreach (string sub in listfileLines)
                    {
                        // If an individual entry fails
                        try
                        {
                            string tempFile = Path.Combine(tempPath, sub);
                            Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
                            mpqArchive.ExtractFile(sub, tempFile);
                        }
                        catch { }
                    }
                }

                // Collect and format all found protections
                var protections = scanner.GetProtections(tempPath);

                // If temp directory cleanup fails
                try
                {
                    Directory.Delete(tempPath, true);
                }
                catch { }

                // Remove temporary path references
                Utilities.StripFromKeys(protections, tempPath);

                return(protections);
            }
            catch { }

            return(null);
        }
Example #7
0
        public static void UnpackMap(string inputMapPath, string outputFolderPath)
        {
            if (!File.Exists(inputMapPath))
            {
                throw new FileNotFoundException(String.Format("Input map at {0} does not exist.", inputMapPath));
            }

            if (Directory.Exists(outputFolderPath) && Directory.EnumerateFileSystemEntries(outputFolderPath).Any())
            {
                throw new IOException(String.Format("Output folder at {0} is not empty.", outputFolderPath));
            }


            // Strategy is as follows:
            // Copy map to the target location. Then extract all files, but convert the map into a container by deleting all the files inside.
            // Goal is that we are left with the MPQ container which contains all the other misc information which we are currently unable to manage.
            // In future, we might be able to generate the MPQ from scratch, but for now we will keep a big chunk of "unmanaged" data and focus
            // on the files we are able to manage.

            string containerPath = Path.Combine(outputFolderPath, FILENAME_CONTAINER);

            Directory.CreateDirectory(outputFolderPath);

            // Copy map to target location in preparation to convert it into a container
            File.Copy(inputMapPath, containerPath);

            string listFile = null;

            // Extract all files from the map and remove them from the container
            using (MpqArchive container = new MpqArchive(containerPath, FileAccess.ReadWrite))
                using (MpqArchive archive = new MpqArchive(inputMapPath, FileAccess.Read))
                {
                    // Check if somebody is trying to unpack a container - lets avoid creating Matroshchkas
                    if (archive.HasFile(DUMMY_FILENAME))
                    {
                        throw new Exception("Input map seems to be a container rather than a packed map.");
                    }

                    using (MpqFileStream file = archive.OpenFile(MPQ_LISTFILE))
                        using (StreamReader sr = new StreamReader(file))
                        {
                            listFile = sr.ReadToEnd();
                        }

                    // We have to add a dummy file as otherwise the listfile gets deleted and somehow doesnt get restored...
                    if (!container.HasFile(DUMMY_FILENAME))
                    {
                        string dummyFilePath = Path.GetTempFileName();
                        try
                        {
                            using (StreamWriter listFileHandle = new StreamWriter(dummyFilePath))
                            {
                                listFileHandle.WriteLine("Dummy file");
                            }
                            container.AddFileFromDiskEx(dummyFilePath, DUMMY_FILENAME, MpqFileAddFileExFlags.MPQ_FILE_COMPRESS, MpqFileAddFileExCompression.MPQ_COMPRESSION_BZIP2, MpqFileAddFileExCompression.MPQ_COMPRESSION_NEXT_SAME);
                        }
                        finally
                        {
                            File.Delete(dummyFilePath);
                        }
                    }

                    using (StringReader reader = new StringReader(listFile))
                    {
                        string currentArchiveFile = string.Empty;
                        do
                        {
                            currentArchiveFile = reader.ReadLine();
                            if (currentArchiveFile != null)
                            {
                                if (currentArchiveFile == DUMMY_FILENAME)
                                {
                                    continue;
                                }

                                string targetPath = Path.Combine(outputFolderPath, currentArchiveFile.Trim('\\'));

                                Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                                archive.ExtractFile(currentArchiveFile, targetPath);

                                container.RemoveFile(currentArchiveFile);
                            }
                        } while (currentArchiveFile != null);
                    }

                    container.Compact(MPQ_LISTFILE);
                }
        }