Exemple #1
0
 /**
  * Imports a file to the archive.
  * Deletes/imports to overwrite.
  * It imports from "in/" folder
  */
 private void Import(String filename, MpqArchive archive)
 {
     try
     {
         Console.WriteLine("Importing file: in/" + filename);
         if (!File.Exists("in/" + filename))
         {
             Console.WriteLine("File does not exist: in/" + filename + " skipping. . .");
             return;
         }
         if (archive.HasFile(filename))
         {
             // We need to delete because stormlib doesn't overwrite
             Console.WriteLine("File already exists, deleting");
             archive.DeleteFile(filename);
         }
         Console.WriteLine("Inserting file");
         archive.AddFileFromDisk("in/" + filename, filename);
         if (!archive.HasFile(filename))
         {
             Console.WriteLine("Expected import file exists, but did not!");
             return;
         }
         Console.WriteLine("Successfully imported in/" + filename + " as " + filename);
     }
     catch (Exception ex)
     {
         Console.WriteLine("Failed to import file " + filename + ": " + ex.Message);
     }
 }
Exemple #2
0
        /// <summary>
        /// Attempts to read the listfile if present
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="filteredlist"></param>
        /// <returns></returns>
        private bool TryGetListFile(MpqArchive mpq, out List <string> filteredlist)
        {
            filteredlist = new List <string>();

            if (mpq.HasFile(LISTFILE_NAME))
            {
                using (var file = mpq.OpenFile(LISTFILE_NAME))
                    using (var sr = new StreamReader(file))
                    {
                        if (!file.CanRead || file.Length <= 1)
                        {
                            return(false);
                        }

                        while (!sr.EndOfStream)
                        {
                            filteredlist.Add(sr.ReadLine().WoWNormalise());
                        }
                    }

                // remove the MPQ documentation files
                filteredlist.RemoveAll(RemoveUnwantedFiles);
                filteredlist.TrimExcess();

                return(filteredlist.Count > 0);
            }

            return(false);
        }
Exemple #3
0
        /// <summary>
        /// Attempts to return a list of all files in the archive
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="files"></param>
        /// <returns></returns>
        private bool TryGetFileList(MpqArchive mpq, bool removeLists, out List <string> files)
        {
            files = new List <string>();

            if (!mpq.HasFile("(ListFile)"))
            {
                return(false);
            }

            using (var file = mpq.OpenFile("(ListFile)"))
                using (var sr = new StreamReader(file))
                {
                    if (!file.CanRead || file.Length == 0)
                    {
                        return(false);
                    }

                    string[] filenames = sr.ReadToEnd().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    files.AddRange(filenames);
                }

            if (removeLists)
            {
                files.RemoveAll(x => x.EndsWith(".lst"));
            }

            return(files.Count > 0);
        }
Exemple #4
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);
     }
 }
Exemple #5
0
        /// <summary>
        /// Some alpha MPQs are hotswappable and only contain a single file and it's checksum
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="archivename"></param>
        private bool TryReadAlpha(MpqArchive mpq, string archivename)
        {
            // strip the local path and extension to get the filename
            var file = Path.ChangeExtension(GetInternalPath(archivename), null).WoWNormalise();

            if (FileList.ContainsKey(file))
            {
                return(true);
            }

            // add the filename as the listfile
            var internalname = Path.GetFileName(file);

            mpq.AddListFile(internalname);

            // read file if known
            if (mpq.HasFile(internalname))
            {
                using var fs = mpq.OpenFile(internalname);

                if (fs.CanRead && fs.Length > 0)
                {
                    var map = BlockTableEncoder.GetEMapFromExtension(file, fs.Length);

                    if (!EncodingCache.TryGetRecord(MD5Hash.Parse(fs.GetMD5Hash()), file, out var record))
                    {
                        record = BlockTableEncoder.EncodeAndExport(fs, map, Options.TempDirectory, file);
                        EncodingCache.AddOrUpdate(record);
                    }

                    record.EBlock.EncodingMap = map;
                    FileList.TryAdd(file, record);
                    return(true);
                }
            }

            return(false);
        }
Exemple #6
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);
                }
        }