Exemple #1
0
        public static Stream GetFile(string path)
        {
            if (File.Exists(path))
            {
                return(File.OpenRead(path));
            }
            else
            {
                // Assume file is contained in an mpq archive.
                var subPath  = path;
                var fullPath = new FileInfo(path).FullName;
                while (!File.Exists(subPath))
                {
                    subPath = new FileInfo(subPath).DirectoryName;
                }

                var relativePath = fullPath.Substring(subPath.Length + (subPath.EndsWith("\\") ? 0 : 1));

                var memoryStream = new MemoryStream();
                using (var archive = MpqArchive.Open(subPath))
                {
                    archive.OpenFile(relativePath).CopyTo(memoryStream);
                }

                memoryStream.Position = 0;
                return(memoryStream);
            }
        }
Exemple #2
0
        public static bool FileExists(MpqArchive archive, string path)
        {
            if (archive.FileExists(path))
            {
                return(true);
            }

            // Check if file is contained in an mpq archive.
            var subPath      = path;
            var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length;

            while (!archive.FileExists(subPath))
            {
                var directoryName = new FileInfo(subPath).DirectoryName;
                if (directoryName.Length <= ignoreLength)
                {
                    return(false);
                }

                subPath = directoryName.Substring(ignoreLength);
            }

            var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1));

            using var subArchiveStream = archive.OpenFile(subPath);
            using var subArchive       = MpqArchive.Open(subArchiveStream);
            return(FileExists(subArchive, relativePath));
        }
Exemple #3
0
        /// <exception cref="FileNotFoundException"></exception>
        public static Stream GetFile(string path)
        {
            if (File.Exists(path))
            {
                return(File.OpenRead(path));
            }

            // Assume file is contained in an mpq archive.
            var subPath  = path;
            var fullPath = new FileInfo(path).FullName;

            while (!File.Exists(subPath))
            {
                subPath = new FileInfo(subPath).DirectoryName;
                if (subPath is null)
                {
                    throw new FileNotFoundException($"File not found: {path}");
                }
            }

            var relativePath = fullPath.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1));

            using var archive = MpqArchive.Open(subPath);
            return(GetFile(archive, relativePath));
        }
Exemple #4
0
        /// <exception cref="FileNotFoundException"></exception>
        public static Stream GetFile(MpqArchive archive, string path)
        {
            if (archive.FileExists(path))
            {
                return(GetArchiveFileStream(archive, path));
            }

            // Assume file is contained in an mpq archive.
            var subPath      = path;
            var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length;

            while (!archive.FileExists(subPath))
            {
                var directoryName = new FileInfo(subPath).DirectoryName;
                if (directoryName.Length <= ignoreLength)
                {
                    throw new FileNotFoundException($"File not found: {path}");
                }

                subPath = directoryName.Substring(ignoreLength);
            }

            var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1));

            using var subArchiveStream = archive.OpenFile(subPath);
            using var subArchive       = MpqArchive.Open(subArchiveStream);
            return(GetArchiveFileStream(subArchive, relativePath));
        }
Exemple #5
0
        public static bool FileExists(string path)
        {
            if (File.Exists(path))
            {
                return(true);
            }

            // Check if file is contained in an mpq archive.
            var subPath  = path;
            var fullPath = new FileInfo(path).FullName;

            while (!File.Exists(subPath))
            {
                subPath = new FileInfo(subPath).DirectoryName;
                if (subPath is null)
                {
                    return(false);
                }
            }

            var relativePath = fullPath.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1));

            using var archive = MpqArchive.Open(subPath);
            return(FileExists(archive, relativePath));
        }
Exemple #6
0
        private static void OpenArchive()
        {
            var fileInfo = new FileInfo(_archiveInput.Text);

            if (fileInfo.Exists)
            {
                _archiveInput.Enabled             = false;
                _archiveInputBrowseButton.Enabled = false;
                _openCloseArchiveButton.Text      = "Close archive";
                _saveAsButton.Enabled             = true;

                _archive = MpqArchive.Open(fileInfo.FullName, true);
                _archive.DiscoverFileNames();

                var map = Map.Open(_archive);
                // _originScriptLanguage = map.Info.ScriptLanguage;

                var targetScriptLanguages = new HashSet <object>(new object[]
                {
                    // ScriptLanguage.Jass,
                    ScriptLanguage.Lua,
                });

                _targetScriptLanguagesComboBox.Items.AddRange(targetScriptLanguages.OrderByDescending(patch => (int)patch).ToArray());
                _targetScriptLanguagesComboBox.Enabled = true;
                if (_targetScriptLanguagesComboBox.Items.Count == 1)
                {
                    _targetScriptLanguagesComboBox.SelectedIndex = 0;
                }
            }
        }
Exemple #7
0
        private static IEnumerable <object[]> GetTestArchivesAttributes()
        {
            foreach (var archive in GetTestMaps())
            {
                using (var mpqArchive = MpqArchive.Open((string)archive[0]))
                {
                    if (!mpqArchive.FileExists(Attributes.FileName))
                    {
                        continue;
                    }
                }

                yield return(new object[] { archive[0] });
            }

            foreach (var archive in GetTestArchives())
            {
                using (var mpqArchive = MpqArchive.Open((string)archive[0]))
                {
                    if (!mpqArchive.FileExists(Attributes.FileName))
                    {
                        continue;
                    }
                }

                yield return(new object[] { archive[0] });
            }
        }
Exemple #8
0
        public void TestWithPreArchiveData()
        {
            var memoryStream = new MemoryStream();
            var randomData   = new byte[999];

            randomData[100] = 99;
            memoryStream.Write(randomData, 0, randomData.Length);

            var randomFiles = new List <MpqFile>();

            for (var i = 0; i < 35; i++)
            {
                var fileStream = new MemoryStream();
                fileStream.Write(randomData, 0, randomData.Length);
                fileStream.Position = 0;
                randomFiles.Add(MpqFile.New(fileStream, $"file{i}"));
            }

            using var a = MpqArchive.Create(memoryStream, randomFiles, new MpqArchiveCreateOptions()
            {
                ListFileCreateMode = MpqFileCreateMode.None, AttributesCreateMode = MpqFileCreateMode.None
            });

            memoryStream.Position = 0;
            var archive = MpqArchive.Open(memoryStream);

            foreach (var file in archive.GetMpqFiles())
            {
                file.MpqStream.Seek(100, SeekOrigin.Begin);
                Assert.AreEqual(99, file.MpqStream.ReadByte());
            }

            archive.Dispose();
        }
Exemple #9
0
        public void TestRecreatePKCompressed()
        {
            const string inputArchivePath = @"TestArchives\PKCompressed.w3x";

            using var inputArchive     = MpqArchive.Open(inputArchivePath);
            using var recreatedArchive = MpqArchive.Create(
                      (Stream?)null,
                      inputArchive.GetMpqFiles().ToArray(),
                      (ushort)inputArchive.Header.HashTableSize,
                      inputArchive.Header.BlockSize);

            for (var i = 0; i < inputArchive.Header.BlockTableSize; i++)
            {
                inputArchive.BaseStream.Position     = inputArchive[i].FilePosition;
                recreatedArchive.BaseStream.Position = recreatedArchive[i].FilePosition;

                var size1 = inputArchive[i].CompressedSize;
                var size2 = recreatedArchive[i].CompressedSize;
                StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, size1 > size2 ? size1 : size2);
            }

            inputArchive.BaseStream.Position     = 0;
            recreatedArchive.BaseStream.Position = 0;
            StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, MpqHeader.Size);
        }
Exemple #10
0
        public void TestStoreCompressedThenRetrieveFile(string filename)
        {
            var fileStream = File.OpenRead(filename);
            var mpqFile    = new MpqFile(fileStream, filename, MpqFileFlags.Exists | MpqFileFlags.Compressed, BlockSize);
            var archive    = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            });

            var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream  = openedArchive.OpenFile(filename);

            // Reload file, since the filestream gets disposed when the mpqfile is added to an mpqarchive.
            fileStream = File.OpenRead(filename);

            Assert.AreEqual(fileStream.Length, openedStream.Length);

            using (var fileStreamReader = new StreamReader(fileStream))
            {
                using (var openedStreamReader = new StreamReader(openedStream))
                {
                    StringAssert.Equals(fileStreamReader.ReadToEnd(), openedStreamReader.ReadToEnd());
                }
            }
        }
Exemple #11
0
 public static Campaign Open(string path)
 {
     if (File.Exists(path))
     {
         using var campaignArchive = MpqArchive.Open(path);
         return(new Campaign(campaignArchive));
     }
     else
     {
         throw new ArgumentException("Could not find a file at the specified path.");
     }
 }
Exemple #12
0
        public void TestWithPreArchiveDataAndNoFiles()
        {
            var memoryStream = new MemoryStream();
            var randomData   = new byte[999];

            memoryStream.Write(randomData, 0, randomData.Length);

            using var a = MpqArchive.Create(memoryStream, Array.Empty <MpqFile>(), new MpqArchiveCreateOptions());

            memoryStream.Position = 0;
            MpqArchive.Open(memoryStream).Dispose();
        }
Exemple #13
0
 public bool OpenMapFile(string path)
 {
     try
     {
         MapFile = MpqArchive.Open(path);
         return(true);
     }
     catch (Exception ex)
     {
         logger.Error("MPQ文件打开失败:" + ex.Message);
     }
     return(false);
 }
Exemple #14
0
        public void TestGetMpqFiles(string mpqFilePath)
        {
            Assert.IsTrue(TestDataProvider.IsArchiveFile(mpqFilePath, out _));

            using var archive = MpqArchive.Open(mpqFilePath, true);
            var mpqFiles = archive.GetMpqFiles();

            Assert.AreEqual(archive.Count, mpqFiles.Count());
            foreach (var mpqFile in mpqFiles)
            {
                Assert.IsNotNull(mpqFile);
            }
        }
Exemple #15
0
        private static IMpqArchive OpenTestArchive(string path, string expectedHash)
        {
            Assume.That(File.Exists(path));

            var fileBytes = File.ReadAllBytes(path);

            using (var sha = SHA1.Create())
            {
                var hash = Convert.ToBase64String(sha.ComputeHash(fileBytes));
                Assume.That(hash, Is.EqualTo(expectedHash));
            }

            return(MpqArchive.Open(path));
        }
Exemple #16
0
        public void TestStoreThenRetrieveFile(string filename)
        {
            var fileStream = File.OpenRead(filename);
            var mpqFile    = MpqFile.New(fileStream, filename, true);
            var archive    = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            });

            var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream  = openedArchive.OpenFile(filename);

            StreamAssert.AreEqual(fileStream, openedStream, true);
        }
Exemple #17
0
        private static IEnumerable <object[]> GetTestArchivesAttributes()
        {
            foreach (var archive in GetTestArchives())
            {
                using (var mpqArchive = MpqArchive.Open((string)archive[0]))
                {
                    if (!mpqArchive.TryAddFilename(Attributes.Key))
                    {
                        continue;
                    }
                }

                yield return(new object[] { archive[0] });
            }
        }
Exemple #18
0
        public void Open(string fileName)
        {
            mpqArchivePath = fileName;

            var copy = new MemoryStream();

            using (var filestream = File.OpenRead(fileName))
            {
                filestream.CopyTo(copy);
            }
            copy.Position = 0;

            originalMpqArchive = MpqArchive.Open(copy);
            mpqArchiveBuilder  = new CustomMpqArchiveBuilder(originalMpqArchive);
        }
Exemple #19
0
        public void TestStoreThenRetrieveFile(string filename)
        {
            var fileStream = File.OpenRead(filename);
            // var mpqFile = new MpqKnownFile(filename, fileStream, MpqFileFlags.Exists, MpqLocale.Neutral, true);
            var mpqFile = MpqFile.New(fileStream, filename);
            var archive = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            });

            var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream  = openedArchive.OpenFile(filename);

            fileStream.Position = 0;
            StreamAssert.AreEqual(fileStream, openedStream);
        }
Exemple #20
0
 /// <summary>
 /// Opens the map from the specified file or folder path.
 /// </summary>
 public static Map Open(string path)
 {
     if (File.Exists(path))
     {
         using var mapArchive = MpqArchive.Open(path);
         return(new Map(mapArchive));
     }
     else if (Directory.Exists(path))
     {
         return(new Map(path));
     }
     else
     {
         throw new ArgumentException("Could not find a file or folder at the specified path.");
     }
 }
Exemple #21
0
        public void TestStoreThenRetrieveEmptyFileWithFlags(MpqFileFlags flags)
        {
            const string FileName = "someRandomFile.empty";

            using var mpqFile   = MpqFile.New(null, FileName);
            mpqFile.TargetFlags = flags;
            using var archive   = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            }, new MpqArchiveCreateOptions { BlockSize = BlockSize });

            using var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream = openedArchive.OpenFile(FileName);

            Assert.IsTrue(openedStream.Length == 0);
        }
Exemple #22
0
        public void Passed_stream_is_not_disposed_when_archive_is_disposed()
        {
            var path = "TestArchives/Archive1.SC2Replay";

            Assume.That(File.Exists(path));

            using (var file = File.OpenRead(path))
            {
                var stream = new TestingStreamWrapper(file);
                using (MpqArchive.Open(stream))
                {
                }

                Assert.That(stream.IsDisposed, Is.False);
            }
        }
Exemple #23
0
        public void TestStoreThenRetrieveFileWithFlags(string fileName, MpqFileFlags flags)
        {
            using var fileStream = File.OpenRead(fileName);
            var mpqFile = MpqFile.New(fileStream, fileName, true);

            mpqFile.TargetFlags = flags;
            using var archive   = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            }, new MpqArchiveCreateOptions { BlockSize = BlockSize });

            using var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream = openedArchive.OpenFile(fileName);

            StreamAssert.AreEqual(fileStream, openedStream, true);
        }
Exemple #24
0
        public void TestDeleteFile()
        {
            var          inputArchivePath = TestDataProvider.GetFile(@"Maps\NewLuaMap.w3m");
            const string fileName         = "war3map.lua";

            using var inputArchive = MpqArchive.Open(inputArchivePath);
            var newFile = MpqFile.New(null, fileName);

            var mpqFiles = inputArchive.GetMpqFiles();
            var oldFile  = mpqFiles.FirstOrDefault(file => file.Equals(newFile)) ?? throw new FileNotFoundException($"File not found: {fileName}");
            var newFiles = mpqFiles.Select(file => ReferenceEquals(file, oldFile) ? newFile : file).ToArray();

            using var outputArchive = MpqArchive.Create((Stream?)null, newFiles, new MpqArchiveCreateOptions { BlockSize = inputArchive.Header.BlockSize, HashTableSize = (ushort)inputArchive.Header.HashTableSize, AttributesFlags = AttributesFlags.DateTime | AttributesFlags.Crc32 });

            Assert.IsTrue(outputArchive.FileExists(fileName, out var entryIndex));
            Assert.AreEqual(0U, outputArchive[entryIndex].FileSize);
        }
Exemple #25
0
        public void TestDeleteFile()
        {
            const string inputArchivePath = @".\TestArchives\NewLuaMap.w3m";
            const string fileName         = "war3map.lua";

            using var inputArchive = MpqArchive.Open(inputArchivePath);
            var newFile = MpqFile.New(null, fileName);

            var mpqFiles = inputArchive.GetMpqFiles();
            var oldFile  = mpqFiles.FirstOrDefault(file => file.IsSameAs(newFile)) ?? throw new FileNotFoundException($"File not found: {fileName}");
            var newFiles = mpqFiles.Select(file => ReferenceEquals(file, oldFile) ? newFile : file).ToArray();

            using var outputArchive = MpqArchive.Create((Stream?)null, newFiles, (ushort)inputArchive.Header.HashTableSize, inputArchive.Header.BlockSize);

            Assert.IsTrue(outputArchive.FileExists(fileName, out var entryIndex));
            Assert.AreEqual(0U, outputArchive[entryIndex].FileSize);
        }
Exemple #26
0
        public void TestStoreThenRetrieveEmptyFileWithFlags(MpqFileFlags flags)
        {
            const string FileName = "someRandomFile.empty";

            // var mpqFile = new MpqKnownFile(FileName, null, flags, MpqLocale.Neutral);
            var mpqFile = MpqFile.New(null, FileName);

            mpqFile.TargetFlags = flags;
            var archive = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            }, blockSize: BlockSize);

            var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream  = openedArchive.OpenFile(FileName);

            Assert.IsTrue(openedStream.Length == 0);
        }
Exemple #27
0
        public static IEnumerable <(string fileName, MpqLocale locale, Stream stream)> EnumerateFiles(string path)
        {
            if (File.Exists(path))
            {
                // Assume file at path is an mpq archive.
                var archive  = MpqArchive.Open(path);
                var listfile = archive.OpenFile(ListFile.Key);

                using (var reader = new StreamReader(listfile))
                {
                    while (!reader.EndOfStream)
                    {
                        var fileName     = reader.ReadLine();
                        var memoryStream = new MemoryStream();

                        archive.OpenFile(fileName).CopyTo(memoryStream);
                        memoryStream.Position = 0;

                        yield return(fileName, MpqLocale.Neutral, memoryStream);
                    }
                }

                archive.Dispose();
            }
            else if (Directory.Exists(path))
            {
                var pathPrefixLength = path.Length + (path.EndsWith("\\") ? 0 : 1);
                foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
                {
                    var fileName = new FileInfo(file).ToString().Substring(pathPrefixLength);
                    // var memoryStream = new MemoryStream();
                    // File.OpenRead(file).CopyTo(memoryStream);

                    var locale = MpqLocaleProvider.GetPathLocale(fileName, out var filePath);

                    yield return(filePath, locale, File.OpenRead(file));
                }
            }
        }
Exemple #28
0
        public void TestRecreatePKCompressed()
        {
            var inputArchivePath = TestDataProvider.GetPath(@"Maps\PKCompressed.w3x");

            using var inputArchive     = MpqArchive.Open(inputArchivePath);
            using var recreatedArchive = MpqArchive.Create((Stream?)null, inputArchive.GetMpqFiles().ToArray(), new MpqArchiveCreateOptions { BlockSize = inputArchive.Header.BlockSize, HashTableSize = (ushort)inputArchive.Header.HashTableSize, ListFileCreateMode = MpqFileCreateMode.None, AttributesCreateMode = MpqFileCreateMode.None });

            for (var i = 0; i < inputArchive.Header.BlockTableSize; i++)
            {
                inputArchive.BaseStream.Position     = inputArchive[i].FilePosition;
                recreatedArchive.BaseStream.Position = recreatedArchive[i].FilePosition;

                // var size1 = inputArchive[i].CompressedSize;
                // var size2 = recreatedArchive[i].CompressedSize;
                // StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, size1 > size2 ? size1 : size2);
                StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream);
            }

            inputArchive.BaseStream.Position     = 0;
            recreatedArchive.BaseStream.Position = 0;
            StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, MpqHeader.Size);
        }
Exemple #29
0
        private static void OpenArchive()
        {
            var fileInfo = new FileInfo(_archiveInput.Text);

            if (fileInfo.Exists)
            {
                _archiveInput.Enabled             = false;
                _archiveInputBrowseButton.Enabled = false;
                _openCloseArchiveButton.Text      = "Close archive";
                _saveAsButton.Enabled             = _filesToDecompileCheckBoxes.Any(checkBox => checkBox.Checked);

                _archive = MpqArchive.Open(fileInfo.FullName, true);
                _archive.DiscoverFileNames();

                _map = Map.Open(_archive);

                _autoDetectFilesToDecompileButton.Enabled = true;
                foreach (var checkBox in _filesToDecompileCheckBoxes)
                {
                    checkBox.Enabled = true;
                }
            }
        }
Exemple #30
0
        public static IEnumerable <object[]> GetDynamicArchiveData(string fileName, SearchOption searchOption, params string[] directories)
        {
            foreach (var directory in GetTestDataDirectories(directories))
            {
                if (Directory.Exists(directory))
                {
                    foreach (var archiveFile in _archiveFileExtensions.SelectMany(ext => Directory.EnumerateFiles(directory, $"*{ext}", searchOption)))
                    {
                        using var archive = MpqArchive.Open(archiveFile);
                        if (archive.FileExists(fileName))
                        {
                            yield return(new[] { Path.Combine(archiveFile, fileName) });
                        }

                        // var file = Path.Combine(archive, fileName);
                        // if (FileProvider.FileExists(file))
                        // {
                        //     yield return new[] { file };
                        // }
                    }
                }
            }
        }